diff --git a/README.md b/README.md
index 9a6f40db8017097b09e3dd6dd9273160f418ba8a..fc13316d1ce18d107cb4f62a3f9becf27cdc5c58 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,10 @@ Matrix SDK for Android, extracted from the Element Android application.
 
 The SDK is still in beta, and replaces the [legacy Matrix Android SDK](https://github.com/matrix-org/matrix-android-sdk) provided by Matrix.org
 
+## Important notice
+
+<b>For now, this project is an extract of the Matrix SDK module from Element Android. Please do not open a pull request on this project. If you want to propose a change on the SDK, please open a PR on https://github.com/vector-im/element-android. Thanks!</b>
+
 ## About
 
 This repository contains the matrix-android-sdk extracted from the project [Element Android](https://github.com/vector-im/element-android)
diff --git a/build.gradle b/build.gradle
index 19a244554cc574e28dfec831df83e59110432f8e..f8730fb59ed71055c2b27e3faf8a8f2a1651d04b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,8 +1,9 @@
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
 
 buildscript {
-    ext.kotlin_version = '1.4.20'
-    ext.kotlin_coroutines_version = "1.4.1"
+    // Ref: https://kotlinlang.org/releases.html
+    ext.kotlin_version = '1.4.31'
+    ext.kotlin_coroutines_version = "1.4.2"
     repositories {
         google()
         jcenter()
@@ -11,7 +12,7 @@ buildscript {
         }
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:4.1.1'
+        classpath 'com.android.tools.build:gradle:4.1.2'
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
 
         // NOTE: Do not place your application dependencies here; they belong
@@ -31,10 +32,6 @@ allprojects {
                 includeGroupByRegex "com\\.github\\.Zhuinden"
             }
         }
-        // Jitsi repo
-        maven {
-            url "https://github.com/vector-im/jitsi_libre_maven/raw/master/android-sdk-2.9.3"
-        }
         google()
         jcenter()
     }
diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle
index fd10ea31153f54d0fad27f5b12b2773c601d2d2d..7053e7f1baa7e65eccd1fa323a44cd6ce63407f7 100644
--- a/matrix-sdk-android/build.gradle
+++ b/matrix-sdk-android/build.gradle
@@ -9,7 +9,7 @@ buildscript {
         jcenter()
     }
     dependencies {
-        classpath "io.realm:realm-gradle-plugin:10.1.2"
+        classpath "io.realm:realm-gradle-plugin:10.3.1"
     }
 }
 
@@ -21,7 +21,7 @@ android {
         minSdkVersion 21
         targetSdkVersion 30
         versionCode 1
-        versionName "1.0.16"
+        versionName "1.1.1"
         // Multidex is useful for tests
         multiDexEnabled true
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -112,9 +112,9 @@ dependencies {
     def lifecycle_version = '2.2.0'
     def arch_version = '2.1.0'
     def markwon_version = '3.1.0'
-    def daggerVersion = '2.31'
-    def work_version = '2.4.0'
-    def retrofit_version = '2.6.2'
+    def daggerVersion = '2.33'
+    def work_version = '2.5.0'
+    def retrofit_version = '2.9.0'
 
     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
     implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
@@ -130,7 +130,7 @@ dependencies {
     implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
     implementation "com.squareup.retrofit2:converter-moshi:$retrofit_version"
 
-    implementation(platform("com.squareup.okhttp3:okhttp-bom:4.8.1"))
+    implementation(platform("com.squareup.okhttp3:okhttp-bom:4.9.1"))
     implementation 'com.squareup.okhttp3:okhttp'
     implementation 'com.squareup.okhttp3:logging-interceptor'
     implementation 'com.squareup.okhttp3:okhttp-urlconnection'
@@ -141,11 +141,11 @@ dependencies {
     implementation "ru.noties.markwon:core:$markwon_version"
 
     // Image
-    implementation 'androidx.exifinterface:exifinterface:1.3.1'
+    implementation 'androidx.exifinterface:exifinterface:1.3.2'
 
     // Database
     implementation 'com.github.Zhuinden:realm-monarchy:0.7.1'
-    kapt 'dk.ilios:realmfieldnameshelper:1.1.1'
+    kapt 'dk.ilios:realmfieldnameshelper:2.0.0'
 
     // Work
     implementation "androidx.work:work-runtime-ktx:$work_version"
@@ -155,7 +155,7 @@ dependencies {
     implementation "io.arrow-kt:arrow-instances-core:$arrow_version"
 
     // olm lib is now hosted by jitpack: https://jitpack.io/#org.matrix.gitlab.matrix-org/olm
-    implementation 'org.matrix.gitlab.matrix-org:olm:3.1.2'
+    implementation 'org.matrix.gitlab.matrix-org:olm:3.2.2'
 
     // DI
     implementation "com.google.dagger:dagger:$daggerVersion"
@@ -166,20 +166,14 @@ dependencies {
     implementation 'com.facebook.stetho:stetho-okhttp3:1.5.1'
 
     // Phone number https://github.com/google/libphonenumber
-    implementation 'com.googlecode.libphonenumber:libphonenumber:8.10.23'
+    implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.19'
 
-    // Web RTC
-    // org.webrtc:google-webrtc is for development purposes only. See http://webrtc.github.io/webrtc-org/native-code/android/
-    // implementation 'org.webrtc:google-webrtc:1.0.+'
-    // Use the same WebRTC library than the one used by Jitsi library
-    implementation('com.facebook.react:react-native-webrtc:1.84.0-jitsi-5112273@aar')
-
-    testImplementation 'junit:junit:4.13'
-    testImplementation 'org.robolectric:robolectric:4.3'
+    testImplementation 'junit:junit:4.13.2'
+    testImplementation 'org.robolectric:robolectric:4.5.1'
     //testImplementation 'org.robolectric:shadows-support-v4:3.0'
     // Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281
-    testImplementation 'io.mockk:mockk:1.9.2.kotlin12'
-    testImplementation 'org.amshove.kluent:kluent-android:1.61'
+    testImplementation 'io.mockk:mockk:1.10.6'
+    testImplementation 'org.amshove.kluent:kluent-android:1.65'
     testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
     // Plant Timber tree for test
     testImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1'
@@ -192,7 +186,7 @@ dependencies {
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
     androidTestImplementation 'org.amshove.kluent:kluent-android:1.61'
     // Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281
-    androidTestImplementation 'io.mockk:mockk-android:1.9.2.kotlin12'
+    androidTestImplementation 'io.mockk:mockk-android:1.10.6'
     androidTestImplementation "androidx.arch.core:core-testing:$arch_version"
     androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
     // Plant Timber tree for test
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/DeactivateAccountTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/DeactivateAccountTest.kt
index b0df6fcb44ba66b82ca490721e01584d667a0539..01c4f8ccb3b0e76285b4f9790bfe68dcce072add 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/DeactivateAccountTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/DeactivateAccountTest.kt
@@ -26,15 +26,12 @@ import org.matrix.android.sdk.InstrumentedTest
 import org.matrix.android.sdk.api.auth.UIABaseAuth
 import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
 import org.matrix.android.sdk.api.auth.UserPasswordAuth
-import org.matrix.android.sdk.api.auth.data.LoginFlowResult
 import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
-import org.matrix.android.sdk.api.auth.registration.RegistrationResult
 import org.matrix.android.sdk.api.failure.Failure
 import org.matrix.android.sdk.api.failure.MatrixError
 import org.matrix.android.sdk.common.CommonTestHelper
 import org.matrix.android.sdk.common.SessionTestParams
 import org.matrix.android.sdk.common.TestConstants
-import org.matrix.android.sdk.common.TestMatrixCallback
 import kotlin.coroutines.Continuation
 import kotlin.coroutines.resume
 
@@ -46,12 +43,13 @@ class DeactivateAccountTest : InstrumentedTest {
 
     @Test
     fun deactivateAccountTest() {
-        val session = commonTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(withInitialSync = false))
+        val session = commonTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(withInitialSync = true))
 
         // Deactivate the account
         commonTestHelper.runBlockingTest {
             session.deactivateAccount(
-                    object : UserInteractiveAuthInterceptor {
+                    eraseAllData = false,
+                    userInteractiveAuthInterceptor = object : UserInteractiveAuthInterceptor {
                         override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
                             promise.resume(
                                     UserPasswordAuth(
@@ -61,7 +59,8 @@ class DeactivateAccountTest : InstrumentedTest {
                                     )
                             )
                         }
-                    }, false)
+                    }
+            )
         }
 
         // Try to login on the previous account, it will fail (M_USER_DEACTIVATED)
@@ -75,23 +74,23 @@ class DeactivateAccountTest : InstrumentedTest {
         // Try to create an account with the deactivate account user id, it will fail (M_USER_IN_USE)
         val hs = commonTestHelper.createHomeServerConfig()
 
-        commonTestHelper.doSync<LoginFlowResult> {
-            commonTestHelper.matrix.authenticationService.getLoginFlow(hs, it)
+        commonTestHelper.runBlockingTest {
+            commonTestHelper.matrix.authenticationService.getLoginFlow(hs)
         }
 
         var accountCreationError: Throwable? = null
-        commonTestHelper.waitWithLatch {
-            commonTestHelper.matrix.authenticationService
-                    .getRegistrationWizard()
-                    .createAccount(session.myUserId.substringAfter("@").substringBefore(":"),
-                            TestConstants.PASSWORD,
-                            null,
-                            object : TestMatrixCallback<RegistrationResult>(it, false) {
-                                override fun onFailure(failure: Throwable) {
-                                    accountCreationError = failure
-                                    super.onFailure(failure)
-                                }
-                            })
+        commonTestHelper.runBlockingTest {
+            try {
+                commonTestHelper.matrix.authenticationService
+                        .getRegistrationWizard()
+                        .createAccount(
+                                session.myUserId.substringAfter("@").substringBefore(":"),
+                                TestConstants.PASSWORD,
+                                null
+                        )
+            } catch (failure: Throwable) {
+                accountCreationError = failure
+            }
         }
 
         // Test the error
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt
index a4dbd70b116bbf97e14ff3ed58e31a7e6445d613..287a4233d990715176a0655c767a60a30cbf3bfc 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt
@@ -19,11 +19,19 @@ package org.matrix.android.sdk.common
 import android.content.Context
 import android.net.Uri
 import androidx.lifecycle.Observer
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withTimeout
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertTrue
 import org.matrix.android.sdk.api.Matrix
 import org.matrix.android.sdk.api.MatrixCallback
 import org.matrix.android.sdk.api.MatrixConfiguration
 import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
-import org.matrix.android.sdk.api.auth.data.LoginFlowResult
 import org.matrix.android.sdk.api.auth.registration.RegistrationResult
 import org.matrix.android.sdk.api.session.Session
 import org.matrix.android.sdk.api.session.events.model.EventType
@@ -35,15 +43,6 @@ import org.matrix.android.sdk.api.session.room.timeline.Timeline
 import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
 import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
 import org.matrix.android.sdk.api.session.sync.SyncState
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.withTimeout
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertNotNull
-import org.junit.Assert.assertTrue
 import java.util.ArrayList
 import java.util.UUID
 import java.util.concurrent.CountDownLatch
@@ -60,7 +59,13 @@ class CommonTestHelper(context: Context) {
     fun getTestInterceptor(session: Session): MockOkHttpInterceptor? = TestNetworkModule.interceptorForSession(session.sessionId) as? MockOkHttpInterceptor
 
     init {
-        Matrix.initialize(context, MatrixConfiguration("TestFlavor"))
+        Matrix.initialize(
+                context,
+                MatrixConfiguration(
+                        applicationFlavor = "TestFlavor",
+                        roomDisplayNameFallbackProvider = TestRoomDisplayNameFallbackProvider()
+                )
+        )
         matrix = Matrix.getInstance(context)
     }
 
@@ -210,22 +215,21 @@ class CommonTestHelper(context: Context) {
                                      sessionTestParams: SessionTestParams): Session {
         val hs = createHomeServerConfig()
 
-        doSync<LoginFlowResult> {
-            matrix.authenticationService
-                    .getLoginFlow(hs, it)
+        runBlockingTest {
+            matrix.authenticationService.getLoginFlow(hs)
         }
 
-        doSync<RegistrationResult>(timeout = 60_000) {
+        runBlockingTest(timeout = 60_000) {
             matrix.authenticationService
                     .getRegistrationWizard()
-                    .createAccount(userName, password, null, it)
+                    .createAccount(userName, password, null)
         }
 
         // Perform dummy step
-        val registrationResult = doSync<RegistrationResult>(timeout = 60_000) {
+        val registrationResult = runBlockingTest(timeout = 60_000) {
             matrix.authenticationService
                     .getRegistrationWizard()
-                    .dummy(it)
+                    .dummy()
         }
 
         assertTrue(registrationResult is RegistrationResult.Success)
@@ -249,15 +253,14 @@ class CommonTestHelper(context: Context) {
                                   sessionTestParams: SessionTestParams): Session {
         val hs = createHomeServerConfig()
 
-        doSync<LoginFlowResult> {
-            matrix.authenticationService
-                    .getLoginFlow(hs, it)
+        runBlockingTest {
+            matrix.authenticationService.getLoginFlow(hs)
         }
 
-        val session = doSync<Session> {
+        val session = runBlockingTest {
             matrix.authenticationService
                     .getLoginWizard()
-                    .login(userName, password, "myDevice", it)
+                    .login(userName, password, "myDevice")
         }
 
         if (sessionTestParams.withInitialSync) {
@@ -277,21 +280,19 @@ class CommonTestHelper(context: Context) {
                             password: String): Throwable {
         val hs = createHomeServerConfig()
 
-        doSync<LoginFlowResult> {
-            matrix.authenticationService
-                    .getLoginFlow(hs, it)
+        runBlockingTest {
+            matrix.authenticationService.getLoginFlow(hs)
         }
 
         var requestFailure: Throwable? = null
-        waitWithLatch { latch ->
-            matrix.authenticationService
-                    .getLoginWizard()
-                    .login(userName, password, "myDevice", object : TestMatrixCallback<Session>(latch, onlySuccessful = false) {
-                        override fun onFailure(failure: Throwable) {
-                            requestFailure = failure
-                            super.onFailure(failure)
-                        }
-                    })
+        runBlockingTest {
+            try {
+                matrix.authenticationService
+                        .getLoginWizard()
+                        .login(userName, password, "myDevice")
+            } catch (failure: Throwable) {
+                requestFailure = failure
+            }
         }
 
         assertNotNull(requestFailure)
@@ -390,8 +391,8 @@ fun List<TimelineEvent>.checkSendOrder(baseTextMessage: String, numberOfMessages
     return drop(startIndex)
             .take(numberOfMessages)
             .foldRightIndexed(true) { index, timelineEvent, acc ->
-        val body = timelineEvent.root.content.toModel<MessageContent>()?.body
-        val currentMessageSuffix = numberOfMessages - index
-        acc && (body == null || body.startsWith(baseTextMessage) && body.endsWith("#$currentMessageSuffix"))
-    }
+                val body = timelineEvent.root.content.toModel<MessageContent>()?.body
+                val currentMessageSuffix = numberOfMessages - index
+                acc && (body == null || body.startsWith(baseTextMessage) && body.endsWith("#$currentMessageSuffix"))
+            }
 }
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestRoomDisplayNameFallbackProvider.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestRoomDisplayNameFallbackProvider.kt
new file mode 100644
index 0000000000000000000000000000000000000000..7a1d4604f05e4bdfc6006137b93ff3e7af79d5bf
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestRoomDisplayNameFallbackProvider.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.common
+
+import org.matrix.android.sdk.api.RoomDisplayNameFallbackProvider
+
+class TestRoomDisplayNameFallbackProvider() : RoomDisplayNameFallbackProvider {
+
+    override fun getNameForRoomInvite() =
+            "Room invite"
+
+    override fun getNameForEmptyRoom() =
+            "Empty room"
+
+    override fun getNameFor2members(name1: String?, name2: String?) =
+            "$name1 and $name2"
+
+    override fun getNameFor3members(name1: String?, name2: String?, name3: String?) =
+            "$name1, $name2 and $name3"
+
+    override fun getNameFor4members(name1: String?, name2: String?, name3: String?, name4: String?) =
+            "$name1, $name2, $name3 and $name4"
+
+    override fun getNameFor4membersAndMore(name1: String?, name2: String?, name3: String?, remainingCount: Int) =
+            "$name1, $name2, $name3 and $remainingCount others"
+}
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/PreShareKeysTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/PreShareKeysTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..122584142e57fc5c03a6bca2d5eac3452150d287
--- /dev/null
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/PreShareKeysTest.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.crypto
+
+import android.util.Log
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.matrix.android.sdk.InstrumentedTest
+import org.matrix.android.sdk.api.session.events.model.EventType
+import org.matrix.android.sdk.api.session.events.model.toModel
+import org.matrix.android.sdk.common.CommonTestHelper
+import org.matrix.android.sdk.common.CryptoTestHelper
+import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent
+import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyContent
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+
+@RunWith(AndroidJUnit4::class)
+@FixMethodOrder(MethodSorters.JVM)
+class PreShareKeysTest : InstrumentedTest {
+
+    private val mTestHelper = CommonTestHelper(context())
+    private val mCryptoTestHelper = CryptoTestHelper(mTestHelper)
+
+    @Test
+    fun ensure_outbound_session_happy_path() {
+        val testData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true)
+        val e2eRoomID = testData.roomId
+        val aliceSession = testData.firstSession
+        val bobSession = testData.secondSession!!
+
+        // clear any outbound session
+        aliceSession.cryptoService().discardOutboundSession(e2eRoomID)
+
+        val preShareCount = bobSession.cryptoService().getGossipingEvents().count {
+            it.senderId == aliceSession.myUserId
+                    && it.getClearType() == EventType.ROOM_KEY
+        }
+
+        assertEquals(0, preShareCount, "Bob should not have receive any key from alice at this point")
+        Log.d("#Test", "Room Key Received from alice $preShareCount")
+
+        // Force presharing of new outbound key
+        mTestHelper.doSync<Unit> {
+            aliceSession.cryptoService().prepareToEncrypt(e2eRoomID, it)
+        }
+
+        mTestHelper.waitWithLatch { latch ->
+            mTestHelper.retryPeriodicallyWithLatch(latch) {
+                val newGossipCount = bobSession.cryptoService().getGossipingEvents().count {
+                    it.senderId == aliceSession.myUserId
+                            && it.getClearType() == EventType.ROOM_KEY
+                }
+                newGossipCount > preShareCount
+            }
+        }
+
+        val latest = bobSession.cryptoService().getGossipingEvents().lastOrNull {
+            it.senderId == aliceSession.myUserId
+                    && it.getClearType() == EventType.ROOM_KEY
+        }
+
+        val content = latest?.getClearContent().toModel<RoomKeyContent>()
+        assertNotNull(content, "Bob should have received and decrypted a room key event from alice")
+        assertEquals(e2eRoomID, content.roomId, "Wrong room")
+        val megolmSessionId = content.sessionId!!
+
+        val sharedIndex = aliceSession.cryptoService().getSharedWithInfo(e2eRoomID, megolmSessionId)
+                .getObject(bobSession.myUserId, bobSession.sessionParams.deviceId)
+
+        assertEquals(0, sharedIndex, "The session received by bob should match what alice sent")
+
+        // Just send a real message as test
+        val sentEvent = mTestHelper.sendTextMessage(aliceSession.getRoom(e2eRoomID)!!, "Allo", 1).first()
+
+        assertEquals(megolmSessionId, sentEvent.root.content.toModel<EncryptedEventContent>()?.sessionId, "Unexpected megolm session")
+        mTestHelper.waitWithLatch { latch ->
+            mTestHelper.retryPeriodicallyWithLatch(latch) {
+                bobSession.getRoom(e2eRoomID)?.getTimeLineEvent(sentEvent.eventId)?.root?.getClearType() == EventType.MESSAGE
+            }
+        }
+
+        mTestHelper.signOutAndClose(aliceSession)
+        mTestHelper.signOutAndClose(bobSession)
+    }
+}
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt
index 80cc14fcb69e1c4eb8171128152110daf84a985d..b2516ea2beec915103843d2b62c66b8091888d2a 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt
@@ -51,7 +51,7 @@ class WithHeldTests : InstrumentedTest {
         // =============================
 
         val aliceSession = mTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true))
-        val bobSession = mTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true))
+        val bobSession = mTestHelper.createAccount(TestConstants.USER_BOB, SessionTestParams(true))
 
         // Initialize cross signing on both
         mCryptoTestHelper.initializeCrossSigning(aliceSession)
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/search/SearchMessagesTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/search/SearchMessagesTest.kt
index ae300c936d89acf552e9ee3db5aad25b21d3c695..cadb83ca00bc05fbf53ebc0b389e4e8b59eca4af 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/search/SearchMessagesTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/search/SearchMessagesTest.kt
@@ -61,7 +61,7 @@ class SearchMessagesTest : InstrumentedTest {
                 2)
 
         run {
-            var lock = CountDownLatch(1)
+            val lock = CountDownLatch(1)
 
             val eventListener = commonTestHelper.createEventListener(lock) { snapshot ->
                 snapshot.count { it.root.content.toModel<MessageContent>()?.body?.startsWith(MESSAGE).orFalse() } == 2
@@ -70,7 +70,6 @@ class SearchMessagesTest : InstrumentedTest {
             aliceTimeline.addListener(eventListener)
             commonTestHelper.await(lock)
 
-            lock = CountDownLatch(1)
             val data = commonTestHelper.runBlockingTest {
                 aliceSession
                         .searchService()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt
index 725fd08d3b4ced867f193c5ba3dd67d6aa44f22d..ed809cdb04520d353eb0ab3febbc1a41cc8fc3f8 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt
@@ -35,7 +35,15 @@ data class MatrixConfiguration(
          * Optional proxy to connect to the matrix servers
          * You can create one using for instance Proxy(proxyType, InetSocketAddress.createUnresolved(hostname, port)
          */
-        val proxy: Proxy? = null
+        val proxy: Proxy? = null,
+        /**
+         * True to advertise support for call transfers to other parties on Matrix calls.
+         */
+        val supportsCallTransfer: Boolean = false,
+        /**
+         * RoomDisplayNameFallbackProvider to provide default room display name.
+         */
+        val roomDisplayNameFallbackProvider: RoomDisplayNameFallbackProvider
 ) {
 
     /**
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/RoomDisplayNameFallbackProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/RoomDisplayNameFallbackProvider.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4ac14d5f63afb92d1d552c108db7f25317df7b51
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/RoomDisplayNameFallbackProvider.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api
+
+interface RoomDisplayNameFallbackProvider {
+    fun getNameForRoomInvite(): String
+    fun getNameForEmptyRoom(): String
+    fun getNameFor2members(name1: String?, name2: String?): String
+    fun getNameFor3members(name1: String?, name2: String?, name3: String?): String
+    fun getNameFor4members(name1: String?, name2: String?, name3: String?, name4: String?): String
+    fun getNameFor4membersAndMore(name1: String?, name2: String?, name3: String?, remainingCount: Int): String
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt
index bf21941e0c99c5ee5715bcc26b3212420a57ff00..a7f5163774517dbe0ff588741568028f171a65e9 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt
@@ -16,7 +16,6 @@
 
 package org.matrix.android.sdk.api.auth
 
-import org.matrix.android.sdk.api.MatrixCallback
 import org.matrix.android.sdk.api.auth.data.Credentials
 import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
 import org.matrix.android.sdk.api.auth.data.LoginFlowResult
@@ -24,7 +23,6 @@ import org.matrix.android.sdk.api.auth.login.LoginWizard
 import org.matrix.android.sdk.api.auth.registration.RegistrationWizard
 import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
 import org.matrix.android.sdk.api.session.Session
-import org.matrix.android.sdk.api.util.Cancelable
 
 /**
  * This interface defines methods to authenticate or to create an account to a matrix server.
@@ -32,14 +30,14 @@ import org.matrix.android.sdk.api.util.Cancelable
 interface AuthenticationService {
     /**
      * Request the supported login flows for this homeserver.
-     * This is the first method to call to be able to get a wizard to login or the create an account
+     * This is the first method to call to be able to get a wizard to login or to create an account
      */
-    fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig, callback: MatrixCallback<LoginFlowResult>): Cancelable
+    suspend fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult
 
     /**
      * Request the supported login flows for the corresponding sessionId.
      */
-    fun getLoginFlowOfSession(sessionId: String, callback: MatrixCallback<LoginFlowResult>): Cancelable
+    suspend fun getLoginFlowOfSession(sessionId: String): LoginFlowResult
 
     /**
      * Get a SSO url
@@ -69,12 +67,12 @@ interface AuthenticationService {
     /**
      * Cancel pending login or pending registration
      */
-    fun cancelPendingLoginOrRegistration()
+    suspend fun cancelPendingLoginOrRegistration()
 
     /**
      * Reset all pending settings, including current HomeServerConnectionConfig
      */
-    fun reset()
+    suspend fun reset()
 
     /**
      * Check if there is an authenticated [Session].
@@ -91,24 +89,21 @@ interface AuthenticationService {
     /**
      * Create a session after a SSO successful login
      */
-    fun createSessionFromSso(homeServerConnectionConfig: HomeServerConnectionConfig,
-                             credentials: Credentials,
-                             callback: MatrixCallback<Session>): Cancelable
+    suspend fun createSessionFromSso(homeServerConnectionConfig: HomeServerConnectionConfig,
+                                     credentials: Credentials): Session
 
     /**
      * Perform a wellknown request, using the domain from the matrixId
      */
-    fun getWellKnownData(matrixId: String,
-                         homeServerConnectionConfig: HomeServerConnectionConfig?,
-                         callback: MatrixCallback<WellknownResult>): Cancelable
+    suspend fun getWellKnownData(matrixId: String,
+                                 homeServerConnectionConfig: HomeServerConnectionConfig?): WellknownResult
 
     /**
      * Authenticate with a matrixId and a password
      * Usually call this after a successful call to getWellKnownData()
      */
-    fun directAuthentication(homeServerConnectionConfig: HomeServerConnectionConfig,
-                             matrixId: String,
-                             password: String,
-                             initialDeviceName: String,
-                             callback: MatrixCallback<Session>): Cancelable
+    suspend fun directAuthentication(homeServerConnectionConfig: HomeServerConnectionConfig,
+                                     matrixId: String,
+                                     password: String,
+                                     initialDeviceName: String): Session
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt
index 48705ee7b7dbfbb6c602dca5409ea433bfb018df..9c96cba40c7710ef6edf79ec60e7ba2763ed0f41 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt
@@ -16,7 +16,6 @@
 
 package org.matrix.android.sdk.api.auth.login
 
-import org.matrix.android.sdk.api.MatrixCallback
 import org.matrix.android.sdk.api.session.Session
 import org.matrix.android.sdk.api.util.Cancelable
 
@@ -29,26 +28,23 @@ interface LoginWizard {
      * @param callback  the matrix callback on which you'll receive the result of authentication.
      * @return a [Cancelable]
      */
-    fun login(login: String,
-              password: String,
-              deviceName: String,
-              callback: MatrixCallback<Session>): Cancelable
+    suspend fun login(login: String,
+                      password: String,
+                      deviceName: String): Session
 
     /**
      * Exchange a login token to an access token
      */
-    fun loginWithToken(loginToken: String,
-                       callback: MatrixCallback<Session>): Cancelable
+    suspend fun loginWithToken(loginToken: String): Session
 
     /**
      * Reset user password
      */
-    fun resetPassword(email: String,
-                      newPassword: String,
-                      callback: MatrixCallback<Unit>): Cancelable
+    suspend fun resetPassword(email: String,
+                              newPassword: String)
 
     /**
-     * Confirm the new password, once the user has checked his email
+     * Confirm the new password, once the user has checked their email
      */
-    fun resetPasswordMailConfirmed(callback: MatrixCallback<Unit>): Cancelable
+    suspend fun resetPasswordMailConfirmed()
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationWizard.kt
index ed7b249f1e67c21f6ecb305cf3687ea893912864..d00c9a0c8211c01b1dafbbdbf47d97db8f731681 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationWizard.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationWizard.kt
@@ -16,28 +16,25 @@
 
 package org.matrix.android.sdk.api.auth.registration
 
-import org.matrix.android.sdk.api.MatrixCallback
-import org.matrix.android.sdk.api.util.Cancelable
-
 interface RegistrationWizard {
 
-    fun getRegistrationFlow(callback: MatrixCallback<RegistrationResult>): Cancelable
+    suspend fun getRegistrationFlow(): RegistrationResult
 
-    fun createAccount(userName: String, password: String, initialDeviceDisplayName: String?, callback: MatrixCallback<RegistrationResult>): Cancelable
+    suspend fun createAccount(userName: String, password: String, initialDeviceDisplayName: String?): RegistrationResult
 
-    fun performReCaptcha(response: String, callback: MatrixCallback<RegistrationResult>): Cancelable
+    suspend fun performReCaptcha(response: String): RegistrationResult
 
-    fun acceptTerms(callback: MatrixCallback<RegistrationResult>): Cancelable
+    suspend fun acceptTerms(): RegistrationResult
 
-    fun dummy(callback: MatrixCallback<RegistrationResult>): Cancelable
+    suspend fun dummy(): RegistrationResult
 
-    fun addThreePid(threePid: RegisterThreePid, callback: MatrixCallback<RegistrationResult>): Cancelable
+    suspend fun addThreePid(threePid: RegisterThreePid): RegistrationResult
 
-    fun sendAgainThreePid(callback: MatrixCallback<RegistrationResult>): Cancelable
+    suspend fun sendAgainThreePid(): RegistrationResult
 
-    fun handleValidateThreePid(code: String, callback: MatrixCallback<RegistrationResult>): Cancelable
+    suspend fun handleValidateThreePid(code: String): RegistrationResult
 
-    fun checkIfEmailHasBeenValidated(delayMillis: Long, callback: MatrixCallback<RegistrationResult>): Cancelable
+    suspend fun checkIfEmailHasBeenValidated(delayMillis: Long): RegistrationResult
 
     val currentThreePid: String?
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/VerificationState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/VerificationState.kt
new file mode 100644
index 0000000000000000000000000000000000000000..54276a6b51e3cab57d89c05dca9b8e28c6094f7d
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/VerificationState.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api.crypto
+
+enum class VerificationState {
+    REQUEST,
+    WAITING,
+    CANCELED_BY_ME,
+    CANCELED_BY_OTHER,
+    DONE
+}
+
+fun VerificationState.isCanceled(): Boolean {
+    return this == VerificationState.CANCELED_BY_ME || this == VerificationState.CANCELED_BY_OTHER
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt
index c06cdd9e23a4efdf8e399259419b3101d1052bcd..e0ee9f36ba8f9b9387afa7dd523e2609abf8e16e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt
@@ -53,22 +53,24 @@ fun Throwable.isInvalidUIAAuth(): Boolean {
  * Try to convert to a RegistrationFlowResponse. Return null in the cases it's not possible
  */
 fun Throwable.toRegistrationFlowResponse(): RegistrationFlowResponse? {
-    return if (this is Failure.OtherServerError && this.httpCode == 401) {
+    return if (this is Failure.OtherServerError && httpCode == 401) {
         tryOrNull {
             MoshiProvider.providesMoshi()
                     .adapter(RegistrationFlowResponse::class.java)
-                    .fromJson(this.errorBody)
+                    .fromJson(errorBody)
         }
-    } else if (this is Failure.ServerError && this.httpCode == 401 && this.error.code == MatrixError.M_FORBIDDEN) {
+    } else if (this is Failure.ServerError && httpCode == 401 && error.code == MatrixError.M_FORBIDDEN) {
         // This happens when the submission for this stage was bad (like bad password)
-        if (this.error.session != null && this.error.flows != null) {
+        if (error.session != null && error.flows != null) {
             RegistrationFlowResponse(
-                    flows = this.error.flows,
-                    session = this.error.session,
-                    completedStages = this.error.completedStages,
-                    params = this.error.params
+                    flows = error.flows,
+                    session = error.session,
+                    completedStages = error.completedStages,
+                    params = error.params
             )
-        } else null
+        } else {
+            null
+        }
     } else {
         null
     }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/federation/FederationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/federation/FederationService.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0761ef8d21a6fb731ceb2d1fe1acf0b72078429e
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/federation/FederationService.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api.federation
+
+interface FederationService {
+    /**
+     * Get information about the homeserver
+     */
+    suspend fun getFederationVersion(): FederationVersion
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/federation/FederationVersion.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/federation/FederationVersion.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2ed3f848b6af0af4202b824cd031cf9327291d6d
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/federation/FederationVersion.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api.federation
+
+/**
+ * Ref: https://matrix.org/docs/spec/server_server/latest#get-matrix-federation-v1-version
+ */
+data class FederationVersion(
+        /**
+         * Arbitrary name that identify this implementation.
+         */
+        val name: String?,
+        /**
+         * Version of this implementation. The version format depends on the implementation.
+         */
+        val version: String?
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt
index ff7c9f0521c6d698c59e202f98b105e7207755b4..7a24ccac111224013585540df912b5f6bb4324dc 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt
@@ -21,6 +21,7 @@ import androidx.lifecycle.LiveData
 import okhttp3.OkHttpClient
 import org.matrix.android.sdk.api.auth.data.SessionParams
 import org.matrix.android.sdk.api.failure.GlobalError
+import org.matrix.android.sdk.api.federation.FederationService
 import org.matrix.android.sdk.api.pushrules.PushRuleService
 import org.matrix.android.sdk.api.session.account.AccountService
 import org.matrix.android.sdk.api.session.accountdata.AccountDataService
@@ -34,6 +35,7 @@ import org.matrix.android.sdk.api.session.file.FileService
 import org.matrix.android.sdk.api.session.group.GroupService
 import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
 import org.matrix.android.sdk.api.session.identity.IdentityService
+import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
 import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
 import org.matrix.android.sdk.api.session.media.MediaService
 import org.matrix.android.sdk.api.session.permalinks.PermalinkService
@@ -48,6 +50,7 @@ import org.matrix.android.sdk.api.session.signout.SignOutService
 import org.matrix.android.sdk.api.session.sync.FilterService
 import org.matrix.android.sdk.api.session.sync.SyncState
 import org.matrix.android.sdk.api.session.terms.TermsService
+import org.matrix.android.sdk.api.session.thirdparty.ThirdPartyService
 import org.matrix.android.sdk.api.session.typing.TypingUsersTracker
 import org.matrix.android.sdk.api.session.user.UserService
 import org.matrix.android.sdk.api.session.widgets.WidgetService
@@ -212,6 +215,16 @@ interface Session :
      */
     fun searchService(): SearchService
 
+    /**
+     * Returns the federation service associated with the session
+     */
+    fun federationService(): FederationService
+
+    /**
+     * Returns the third party service associated with the session
+     */
+    fun thirdPartyService(): ThirdPartyService
+
     /**
      * Add a listener to the session.
      * @param listener the listener to add.
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/account/AccountService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/account/AccountService.kt
index eb327dfd56c18b6df0e75db011a8f6eabce9561f..1f28dbd8afbef2c21b0e9aaee1d080c44b4ae3a9 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/account/AccountService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/account/AccountService.kt
@@ -27,7 +27,8 @@ interface AccountService {
      * @param password Current password.
      * @param newPassword New password
      */
-    suspend fun changePassword(password: String, newPassword: String)
+    suspend fun changePassword(password: String,
+                               newPassword: String)
 
     /**
      * Deactivate the account.
@@ -41,9 +42,10 @@ interface AccountService {
      * be shared with any new or unregistered users, but registered users who already have access to these messages will still
      * have access to their copy.
      *
-     * @param password the account password
      * @param eraseAllData set to true to forget all messages that have been sent. Warning: this will cause future users to see
      * an incomplete view of conversations
+     * @param userInteractiveAuthInterceptor see [UserInteractiveAuthInterceptor]
      */
-    suspend fun deactivateAccount(userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor, eraseAllData: Boolean)
+    suspend fun deactivateAccount(eraseAllData: Boolean,
+                                  userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor)
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallsListener.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallListener.kt
similarity index 67%
rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallsListener.kt
rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallListener.kt
index 37ab198487b555ff90561ac6da64b0fbbd1b0bf7..303add747f1715fb538978ea3998e45c3e1e8675 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallsListener.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallListener.kt
@@ -20,8 +20,11 @@ import org.matrix.android.sdk.api.session.room.model.call.CallAnswerContent
 import org.matrix.android.sdk.api.session.room.model.call.CallCandidatesContent
 import org.matrix.android.sdk.api.session.room.model.call.CallHangupContent
 import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent
+import org.matrix.android.sdk.api.session.room.model.call.CallNegotiateContent
+import org.matrix.android.sdk.api.session.room.model.call.CallRejectContent
+import org.matrix.android.sdk.api.session.room.model.call.CallSelectAnswerContent
 
-interface CallsListener {
+interface CallListener {
     /**
      * Called when there is an incoming call within the room.
      */
@@ -39,5 +42,23 @@ interface CallsListener {
      */
     fun onCallHangupReceived(callHangupContent: CallHangupContent)
 
+    /**
+     * Called when a called has been rejected
+     */
+    fun onCallRejectReceived(callRejectContent: CallRejectContent)
+
+    /**
+     * Called when an answer has been selected
+     */
+    fun onCallSelectAnswerReceived(callSelectAnswerContent: CallSelectAnswerContent)
+
+    /**
+     * Called when a negotiation is sent
+     */
+    fun onCallNegotiateReceived(callNegotiateContent: CallNegotiateContent)
+
+    /**
+     * Called when the call has been managed by an other session
+     */
     fun onCallManagedByOtherSession(callId: String)
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt
index e28c1fa595aeee1a1912094084799a7b22978380..dc67aa536afd0a5b295ed52dae2255c181a7095d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt
@@ -16,21 +16,20 @@
 
 package org.matrix.android.sdk.api.session.call
 
-import org.matrix.android.sdk.api.MatrixCallback
-import org.matrix.android.sdk.api.util.Cancelable
-
 interface CallSignalingService {
 
-    fun getTurnServer(callback: MatrixCallback<TurnServerResponse>): Cancelable
+    suspend fun getTurnServer(): TurnServerResponse
+
+    fun getPSTNProtocolChecker(): PSTNProtocolChecker
 
     /**
      * Create an outgoing call
      */
     fun createOutgoingCall(roomId: String, otherUserId: String, isVideoCall: Boolean): MxCall
 
-    fun addCallListener(listener: CallsListener)
+    fun addCallListener(listener: CallListener)
 
-    fun removeCallListener(listener: CallsListener)
+    fun removeCallListener(listener: CallListener)
 
     fun getCallWithId(callId: String): MxCall?
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallState.kt
index 757a09fb3f27089f85d7165a4b4a3cd35c13cdc0..2dbd1c9b01bf03bac7a6176552e69cb279fc8c46 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallState.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallState.kt
@@ -16,13 +16,16 @@
 
 package org.matrix.android.sdk.api.session.call
 
-import org.webrtc.PeerConnection
-
 sealed class CallState {
 
     /** Idle, setting up objects */
     object Idle : CallState()
 
+    /**
+     * CreateOffer. Intermediate state between Idle and Dialing.
+     */
+    object CreateOffer: CallState()
+
     /** Dialing.  Outgoing call is signaling the remote peer */
     object Dialing : CallState()
 
@@ -36,8 +39,8 @@ sealed class CallState {
      * Connected. Incoming/Outgoing call, ice layer connecting or connected
      * Notice that the PeerState failed is not always final, if you switch network, new ice candidtates
      * could be exchanged, and the connection could go back to connected
-     */
-    data class Connected(val iceConnectionState: PeerConnection.PeerConnectionState) : CallState()
+     * */
+    data class Connected(val iceConnectionState: MxPeerConnectionState) : CallState()
 
     /** Terminated.  Incoming/Outgoing call, the call is terminated */
     object Terminated : CallState()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/EglUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/EglUtils.kt
deleted file mode 100644
index 131779a4dcee7b4d52a4901496c7fe6174c26a3d..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/EglUtils.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2020 The Matrix.org Foundation C.I.C.
- *
- * 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 org.matrix.android.sdk.api.session.call
-
-import org.webrtc.EglBase
-import timber.log.Timber
-
-/**
- * The root [EglBase] instance shared by the entire application for
- * the sake of reducing the utilization of system resources (such as EGL
- * contexts)
- * by performing a runtime check.
- */
-object EglUtils {
-
-    // TODO how do we release that?
-
-    /**
-     * Lazily creates and returns the one and only [EglBase] which will
-     * serve as the root for all contexts that are needed.
-     */
-    @get:Synchronized var rootEglBase: EglBase? = null
-        get() {
-            if (field == null) {
-                val configAttributes = EglBase.CONFIG_PLAIN
-                try {
-                    field = EglBase.createEgl14(configAttributes)
-                            ?: EglBase.createEgl10(configAttributes) // Fall back to EglBase10.
-                } catch (ex: Throwable) {
-                    Timber.e(ex, "Failed to create EglBase")
-                }
-            }
-            return field
-        }
-        private set
-
-    val rootEglBaseContext: EglBase.Context?
-        get() {
-            val eglBase = rootEglBase
-            return eglBase?.eglBaseContext
-        }
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/MxCall.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/MxCall.kt
index a1ab687894c3f3b61b7ba43ee650ad89947f6bd4..7533619eb074b111279a771e1b211b0357195b58 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/MxCall.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/MxCall.kt
@@ -16,14 +16,17 @@
 
 package org.matrix.android.sdk.api.session.call
 
-import org.webrtc.IceCandidate
-import org.webrtc.SessionDescription
+import org.matrix.android.sdk.api.session.room.model.call.CallCandidate
+import org.matrix.android.sdk.api.session.room.model.call.CallCapabilities
+import org.matrix.android.sdk.api.session.room.model.call.CallHangupContent
+import org.matrix.android.sdk.api.session.room.model.call.SdpType
+import org.matrix.android.sdk.api.util.Optional
 
 interface MxCallDetail {
     val callId: String
     val isOutgoing: Boolean
     val roomId: String
-    val otherUserId: String
+    val opponentUserId: String
     val isVideoCall: Boolean
 }
 
@@ -32,40 +35,64 @@ interface MxCallDetail {
  */
 interface MxCall : MxCallDetail {
 
+    companion object {
+        const val VOIP_PROTO_VERSION = 1
+    }
+
+    val ourPartyId: String
+    var opponentPartyId: Optional<String>?
+    var opponentVersion: Int
+
+    var capabilities: CallCapabilities?
+
     var state: CallState
 
     /**
      * Pick Up the incoming call
      * It has no effect on outgoing call
      */
-    fun accept(sdp: SessionDescription)
+    fun accept(sdpString: String)
+
+    /**
+     * SDP negotiation for media pause, hold/resume, ICE restarts and voice/video call up/downgrading
+     */
+    fun negotiate(sdpString: String, type: SdpType)
+
+    /**
+     * This has to be sent by the caller's client once it has chosen an answer.
+     */
+    fun selectAnswer()
 
     /**
      * Reject an incoming call
-     * It's an alias to hangUp
      */
-    fun reject() = hangUp()
+    fun reject()
 
     /**
      * End the call
      */
-    fun hangUp()
+    fun hangUp(reason: CallHangupContent.Reason? = null)
 
     /**
      * Start a call
      * Send offer SDP to the other participant.
      */
-    fun offerSdp(sdp: SessionDescription)
+    fun offerSdp(sdpString: String)
 
     /**
-     * Send Ice candidate to the other participant.
+     * Send Call candidate to the other participant.
      */
-    fun sendLocalIceCandidates(candidates: List<IceCandidate>)
+    fun sendLocalCallCandidates(candidates: List<CallCandidate>)
 
     /**
      * Send removed ICE candidates to the other participant.
      */
-    fun sendLocalIceCandidateRemovals(candidates: List<IceCandidate>)
+    fun sendLocalIceCandidateRemovals(candidates: List<CallCandidate>)
+
+    /**
+     * Send a m.call.replaces event to initiate call transfer.
+     */
+    suspend fun transfer(targetUserId: String, targetRoomId: String?)
 
     fun addListener(listener: StateListener)
     fun removeListener(listener: StateListener)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/MxPeerConnectionState.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/MxPeerConnectionState.java
new file mode 100644
index 0000000000000000000000000000000000000000..7ea0765809cd10ff6a83c3f1fbbaebb40a20cad4
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/MxPeerConnectionState.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api.session.call;
+
+/**
+ * This is a copy of https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState
+ * to avoid having the dependency over WebRtc library on sdk.
+ */
+public enum MxPeerConnectionState {
+    NEW,
+    CONNECTING,
+    CONNECTED,
+    DISCONNECTED,
+    FAILED,
+    CLOSED
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/PSTNProtocolChecker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/PSTNProtocolChecker.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6627f62e24afff5b0685273986888cc2b082bba2
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/PSTNProtocolChecker.kt
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api.session.call
+
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import org.matrix.android.sdk.api.extensions.tryOrNull
+import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
+import org.matrix.android.sdk.internal.session.SessionScope
+import org.matrix.android.sdk.internal.session.thirdparty.GetThirdPartyProtocolsTask
+import org.matrix.android.sdk.internal.task.TaskExecutor
+import timber.log.Timber
+import java.util.concurrent.atomic.AtomicBoolean
+import javax.inject.Inject
+
+private const val PSTN_VECTOR_KEY = "im.vector.protocol.pstn"
+private const val PSTN_MATRIX_KEY = "m.protocol.pstn"
+
+/**
+ * This class is responsible for checking if the HS support the PSTN protocol.
+ * As long as the request succeed, it'll check only once by session.
+ */
+@SessionScope
+class PSTNProtocolChecker @Inject internal constructor(private val taskExecutor: TaskExecutor,
+                                                       private val getThirdPartyProtocolsTask: GetThirdPartyProtocolsTask) {
+
+    interface Listener {
+        fun onPSTNSupportUpdated()
+    }
+
+    private var alreadyChecked = AtomicBoolean(false)
+
+    private val pstnSupportListeners = mutableListOf<Listener>()
+
+    fun addListener(listener: Listener) {
+        pstnSupportListeners.add(listener)
+    }
+
+    fun removeListener(listener: Listener) {
+        pstnSupportListeners.remove(listener)
+    }
+
+    var supportedPSTNProtocol: String? = null
+        private set
+
+    fun checkForPSTNSupportIfNeeded() {
+        if (alreadyChecked.get()) return
+        taskExecutor.executorScope.checkForPSTNSupport()
+    }
+
+    private fun CoroutineScope.checkForPSTNSupport() = launch {
+        try {
+            supportedPSTNProtocol = getSupportedPSTN(3)
+            alreadyChecked.set(true)
+            if (supportedPSTNProtocol != null) {
+                pstnSupportListeners.forEach {
+                    tryOrNull { it.onPSTNSupportUpdated() }
+                }
+            }
+        } catch (failure: Throwable) {
+            Timber.v("Fail to get supported PSTN, will check again next time.")
+        }
+    }
+
+    private suspend fun getSupportedPSTN(maxTries: Int): String? {
+        val thirdPartyProtocols: Map<String, ThirdPartyProtocol> = try {
+            getThirdPartyProtocolsTask.execute(Unit)
+        } catch (failure: Throwable) {
+            if (maxTries == 1) {
+                throw failure
+            } else {
+                // Wait for 10s before trying again
+                delay(10_000L)
+                return getSupportedPSTN(maxTries - 1)
+            }
+        }
+        return when {
+            thirdPartyProtocols.containsKey(PSTN_VECTOR_KEY) -> PSTN_VECTOR_KEY
+            thirdPartyProtocols.containsKey(PSTN_MATRIX_KEY) -> PSTN_MATRIX_KEY
+            else                                             -> null
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt
index fa5ea359e8ff9ff7849bb91f5015fbdca97c10f1..1b7a5243e2ba00d191f21f6849f399ce164d9ef0 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt
@@ -56,8 +56,6 @@ interface CryptoService {
 
     fun deleteDevice(deviceId: String, userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor, callback: MatrixCallback<Unit>)
 
-    fun deleteDeviceWithUserPassword(deviceId: String, authSession: String?, password: String, callback: MatrixCallback<Unit>)
-
     fun getCryptoVersion(context: Context, longFormat: Boolean): String
 
     fun isCryptoEnabled(): Boolean
@@ -158,4 +156,10 @@ interface CryptoService {
     fun getWithHeldMegolmSession(roomId: String, sessionId: String): RoomKeyWithHeldContent?
 
     fun logDbUsageInfo()
+
+    /**
+     * Perform any background tasks that can be done before a message is ready to
+     * send, in order to speed up sending of the message.
+     */
+    fun prepareToEncrypt(roomId: String, callback: MatrixCallback<Unit>)
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt
index 8f9f409b745f85264937dc9903fa0e944dff9f46..844e8dbbab575abfde48aa878390234f65b1087d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt
@@ -66,7 +66,7 @@ inline fun <reified T> T.toContent(): Content {
  */
 @JsonClass(generateAdapter = true)
 data class Event(
-        @Json(name = "type") val type: String,
+        @Json(name = "type") val type: String? = null,
         @Json(name = "event_id") val eventId: String? = null,
         @Json(name = "content") val content: Content? = null,
         @Json(name = "prev_content") val prevContent: Content? = null,
@@ -98,6 +98,19 @@ data class Event(
     @Transient
     var ageLocalTs: Long? = null
 
+    /**
+     * Copy all fields, including transient fields
+     */
+    fun copyAll(): Event {
+        return copy().also {
+            it.mxDecryptionResult = mxDecryptionResult
+            it.mCryptoError = mCryptoError
+            it.mCryptoErrorReason = mCryptoErrorReason
+            it.sendState = sendState
+            it.ageLocalTs = ageLocalTs
+        }
+    }
+
     /**
      * Check if event is a state event.
      * @return true if event is state event.
@@ -135,7 +148,7 @@ data class Event(
      * @return the event type
      */
     fun getClearType(): String {
-        return mxDecryptionResult?.payload?.get("type")?.toString() ?: type
+        return mxDecryptionResult?.payload?.get("type")?.toString() ?: type ?: EventType.MISSING_TYPE
     }
 
     /**
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt
index 68874a1fb1ae975c712096de8c273b2c5bb80691..905e18b8e8b95cef884fca97ba468b14454e900f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt
@@ -20,6 +20,8 @@ package org.matrix.android.sdk.api.session.events.model
  * Constants defining known event types from Matrix specifications.
  */
 object EventType {
+    // Used when the type is missing, which should not happen
+    const val MISSING_TYPE = "org.matrix.android.sdk.missing_type"
 
     const val PRESENCE = "m.presence"
     const val MESSAGE = "m.room.message"
@@ -68,7 +70,12 @@ object EventType {
     const val CALL_INVITE = "m.call.invite"
     const val CALL_CANDIDATES = "m.call.candidates"
     const val CALL_ANSWER = "m.call.answer"
+    const val CALL_SELECT_ANSWER = "m.call.select_answer"
+    const val CALL_NEGOTIATE = "m.call.negotiate"
+    const val CALL_REJECT = "m.call.reject"
     const val CALL_HANGUP = "m.call.hangup"
+    // This type is not processed by the client, just sent to the server
+    const val CALL_REPLACES = "m.call.replaces"
 
     // Key share events
     const val ROOM_KEY_REQUEST = "m.room_key_request"
@@ -98,5 +105,9 @@ object EventType {
                 || type == CALL_CANDIDATES
                 || type == CALL_ANSWER
                 || type == CALL_HANGUP
+                || type == CALL_SELECT_ANSWER
+                || type == CALL_NEGOTIATE
+                || type == CALL_REJECT
+                || type == CALL_REPLACES
     }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilitiesService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilitiesService.kt
index 2c9121ce4ad62847985f2c7f88ed54cae10a2a66..f12cbcd6db12b79a7a8dabf6436447bc5317869e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilitiesService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilitiesService.kt
@@ -21,6 +21,11 @@ package org.matrix.android.sdk.api.session.homeserver
  */
 interface HomeServerCapabilitiesService {
 
+    /**
+     * Force a refresh of the stored data
+     */
+    suspend fun refreshHomeServerCapabilities()
+
     /**
      * Get the HomeServer capabilities
      */
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/InitSyncStep.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/InitSyncStep.kt
new file mode 100644
index 0000000000000000000000000000000000000000..901c1b2ffbc756fee00d912d7c2eb51e3523b840
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/InitSyncStep.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api.session.initsync
+
+enum class InitSyncStep {
+    ServerComputing,
+    Downloading,
+    ImportingAccount,
+    ImportingAccountCrypto,
+    ImportingAccountRoom,
+    ImportingAccountGroups,
+    ImportingAccountData,
+    ImportingAccountJoinedRooms,
+    ImportingAccountInvitedRooms,
+    ImportingAccountLeftRooms
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/InitialSyncProgressService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/InitialSyncProgressService.kt
similarity index 83%
rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/InitialSyncProgressService.kt
rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/InitialSyncProgressService.kt
index 09c6b8e94cc06e189532e0efcafacf34bb96253a..b5d4ef4dbb4a55abe9e713b00ac156111b0d2415 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/InitialSyncProgressService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/InitialSyncProgressService.kt
@@ -5,7 +5,7 @@
  * 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
+ *     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,
@@ -13,9 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.matrix.android.sdk.api.session
+package org.matrix.android.sdk.api.session.initsync
 
-import androidx.annotation.StringRes
 import androidx.lifecycle.LiveData
 
 interface InitialSyncProgressService {
@@ -25,7 +24,7 @@ interface InitialSyncProgressService {
     sealed class Status {
         object Idle : Status()
         data class Progressing(
-                @StringRes val statusText: Int,
+                val initSyncStep: InitSyncStep,
                 val percentProgress: Int = 0
         ) : Status()
     }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomDirectoryService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomDirectoryService.kt
index 61970ce848cb2c424cedc83182897b562a5ca5e9..176de8e408be3108d8307c5736a8e0c49bdacf4f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomDirectoryService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomDirectoryService.kt
@@ -16,12 +16,9 @@
 
 package org.matrix.android.sdk.api.session.room
 
-import org.matrix.android.sdk.api.MatrixCallback
 import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
 import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsParams
 import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsResponse
-import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
-import org.matrix.android.sdk.api.util.Cancelable
 
 /**
  * This interface defines methods to get and join public rooms. It's implemented at the session level.
@@ -31,15 +28,8 @@ interface RoomDirectoryService {
     /**
      * Get rooms from directory
      */
-    fun getPublicRooms(server: String?,
-                       publicRoomsParams: PublicRoomsParams,
-                       callback: MatrixCallback<PublicRoomsResponse>): Cancelable
-
-    /**
-     * Fetches the overall metadata about protocols supported by the homeserver.
-     * Includes both the available protocols and all fields required for queries against each protocol.
-     */
-    fun getThirdPartyProtocol(callback: MatrixCallback<Map<String, ThirdPartyProtocol>>): Cancelable
+    suspend fun getPublicRooms(server: String?,
+                               publicRoomsParams: PublicRoomsParams): PublicRoomsResponse
 
     /**
      * Get the visibility of a room in the directory
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt
index 1251fd985732308b13c86872c7b549660d4d5868..6581247b90a69dcedda5984209486747e589a3fc 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt
@@ -30,4 +30,10 @@ interface RoomCryptoService {
      * Enable encryption of the room
      */
     suspend fun enableEncryption(algorithm: String = MXCRYPTO_ALGORITHM_MEGOLM)
+
+    /**
+     * Ensures all members of the room are loaded and outbound session keys are shared.
+     * If this method is not called, CryptoService will ensure it before sending events.
+     */
+    suspend fun prepareToEncrypt()
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/EditAggregatedSummary.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/EditAggregatedSummary.kt
index 10fb81dc7f55ac8af1bf11ab0fe8069a59b5d707..67bab626cbcabed9130097f5b1203bfb4899b964 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/EditAggregatedSummary.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/EditAggregatedSummary.kt
@@ -18,7 +18,7 @@ package org.matrix.android.sdk.api.session.room.model
 import org.matrix.android.sdk.api.session.events.model.Content
 
 data class EditAggregatedSummary(
-        val aggregatedContent: Content? = null,
+        val latestContent: Content? = null,
         // The list of the eventIDs used to build the summary (might be out of sync if chunked received from message chunk)
         val sourceEvents: List<String>,
         val localEchos: List<String>,
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/ReferencesAggregatedContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/ReferencesAggregatedContent.kt
index 0947c96bb0fa52a6d13d22786d0e8cbbd452d5ed..664d042e186f482774af3109af410fa078481076 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/ReferencesAggregatedContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/ReferencesAggregatedContent.kt
@@ -17,7 +17,7 @@ package org.matrix.android.sdk.api.session.room.model
 
 import com.squareup.moshi.Json
 import com.squareup.moshi.JsonClass
-import org.matrix.android.sdk.internal.session.room.VerificationState
+import org.matrix.android.sdk.api.crypto.VerificationState
 
 /**
  * Contains an aggregated summary info of the references.
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomThirdPartyInviteContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomThirdPartyInviteContent.kt
index 776acbd8eaa3640d6a263e47e79ce67091781682..56503e3e35624a1b1008c2ab88d9c32c56409085 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomThirdPartyInviteContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomThirdPartyInviteContent.kt
@@ -30,24 +30,24 @@ data class RoomThirdPartyInviteContent(
          * This should not contain the user's third party ID, as otherwise when the invite
          * is accepted it would leak the association between the matrix ID and the third party ID.
          */
-        @Json(name = "display_name") val displayName: String,
+        @Json(name = "display_name") val displayName: String?,
 
         /**
          * Required. A URL which can be fetched, with querystring public_key=public_key, to validate
          * whether the key has been revoked. The URL must return a JSON object containing a boolean property named 'valid'.
          */
-        @Json(name = "key_validity_url") val keyValidityUrl: String,
+        @Json(name = "key_validity_url") val keyValidityUrl: String?,
 
         /**
          * Required. A base64-encoded ed25519 key with which token must be signed (though a signature from any entry in
          * public_keys is also sufficient). This exists for backwards compatibility.
          */
-        @Json(name = "public_key") val publicKey: String,
+        @Json(name = "public_key") val publicKey: String?,
 
         /**
          * Keys with which the token may be signed.
          */
-        @Json(name = "public_keys") val publicKeys: List<PublicKeys> = emptyList()
+        @Json(name = "public_keys") val publicKeys: List<PublicKeys>? = emptyList()
 )
 
 @JsonClass(generateAdapter = true)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt
index c4d1f6486f2e19a9a33cbe380b223a5b91f5cae2..45a54bb379b58187445595641724fece2263a823 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt
@@ -27,16 +27,24 @@ data class CallAnswerContent(
         /**
          * Required. The ID of the call this event relates to.
          */
-        @Json(name = "call_id") val callId: String,
+        @Json(name = "call_id") override val callId: String,
+        /**
+         * Required. ID to let user identify remote echo of their own events
+         */
+        @Json(name = "party_id") override val partyId: String? = null,
         /**
          * Required. The session description object
          */
         @Json(name = "answer") val answer: Answer,
         /**
-         * Required. The version of the VoIP specification this messages adheres to. This specification is version 0.
+         * Required. The version of the VoIP specification this messages adheres to.
+         */
+        @Json(name = "version") override val version: String?,
+        /**
+         * Capability advertisement.
          */
-        @Json(name = "version") val version: Int = 0
-) {
+        @Json(name = "capabilities") val capabilities: CallCapabilities? = null
+): CallSignallingContent  {
 
     @JsonClass(generateAdapter = true)
     data class Answer(
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidate.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidate.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ace8c5a7570f0ecbc1d9338899255fd3fde241bf
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidate.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api.session.room.model.call
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = true)
+data class CallCandidate(
+        /**
+         * Required. The SDP media type this candidate is intended for.
+         */
+        @Json(name = "sdpMid") val sdpMid: String? = null,
+        /**
+         * Required. The index of the SDP 'm' line this candidate is intended for.
+         */
+        @Json(name = "sdpMLineIndex") val sdpMLineIndex: Int = 0,
+        /**
+         * Required. The SDP 'a' line of the candidate.
+         */
+        @Json(name = "candidate") val candidate: String? = null
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt
index cad2356c2db56da9d3c35b20f670ce321428af36..7bfe7a97acbdd6260c8d3eb183d83ae9599863b5 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt
@@ -28,30 +28,17 @@ data class CallCandidatesContent(
         /**
          * Required. The ID of the call this event relates to.
          */
-        @Json(name = "call_id") val callId: String,
+        @Json(name = "call_id") override val callId: String,
+        /**
+         * Required. ID to let user identify remote echo of their own events
+         */
+        @Json(name = "party_id") override val partyId: String? = null,
         /**
          * Required. Array of objects describing the candidates.
          */
-        @Json(name = "candidates") val candidates: List<Candidate> = emptyList(),
+        @Json(name = "candidates") val candidates: List<CallCandidate> = emptyList(),
         /**
-         * Required. The version of the VoIP specification this messages adheres to. This specification is version 0.
+         * Required. The version of the VoIP specification this messages adheres to.
          */
-        @Json(name = "version") val version: Int = 0
-) {
-
-    @JsonClass(generateAdapter = true)
-    data class Candidate(
-            /**
-             * Required. The SDP media type this candidate is intended for.
-             */
-            @Json(name = "sdpMid") val sdpMid: String,
-            /**
-             * Required. The index of the SDP 'm' line this candidate is intended for.
-             */
-            @Json(name = "sdpMLineIndex") val sdpMLineIndex: Int,
-            /**
-             * Required. The SDP 'a' line of the candidate.
-             */
-            @Json(name = "candidate") val candidate: String
-    )
-}
+        @Json(name = "version") override val version: String?
+): CallSignallingContent
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCapabilities.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCapabilities.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d911ca3b88927bd8b5f6608019d83d1af0cedff7
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCapabilities.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api.session.room.model.call
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+import org.matrix.android.sdk.api.extensions.orFalse
+
+@JsonClass(generateAdapter = true)
+data class CallCapabilities(
+        /**
+         * If set to true, states that the sender of the event supports the m.call.replaces event and therefore supports
+         * being transferred to another destination
+         */
+        @Json(name = "m.call.transferee") val transferee: Boolean? = null
+)
+
+fun CallCapabilities?.supportCallTransfer() = this?.transferee.orFalse()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallHangupContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallHangupContent.kt
index d30441df4b6567f363d0f30c103572d79b8527e7..0acc409053d714d561e6077ee9f6820c4500560f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallHangupContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallHangupContent.kt
@@ -28,24 +28,41 @@ data class CallHangupContent(
         /**
          * Required. The ID of the call this event relates to.
          */
-        @Json(name = "call_id") val callId: String,
+        @Json(name = "call_id") override val callId: String,
         /**
-         * Required. The version of the VoIP specification this message adheres to. This specification is version 0.
+         * Required. ID to let user identify remote echo of their own events
          */
-        @Json(name = "version") val version: Int = 0,
+        @Json(name = "party_id") override val partyId: String? = null,
+        /**
+         * Required. The version of the VoIP specification this message adheres to.
+         */
+        @Json(name = "version") override val version: String?,
         /**
          * Optional error reason for the hangup. This should not be provided when the user naturally ends or rejects the call.
          * When there was an error in the call negotiation, this should be `ice_failed` for when ICE negotiation fails
-         * or `invite_timeout` for when the other party did not answer in time. One of: ["ice_failed", "invite_timeout"]
+         * or `invite_timeout` for when the other party did not answer in time.
+         * One of: ["ice_failed", "invite_timeout"]
          */
         @Json(name = "reason") val reason: Reason? = null
-) {
+) : CallSignallingContent {
     @JsonClass(generateAdapter = false)
     enum class Reason {
         @Json(name = "ice_failed")
         ICE_FAILED,
 
+        @Json(name = "ice_timeout")
+        ICE_TIMEOUT,
+
+        @Json(name = "user_hangup")
+        USER_HANGUP,
+
+        @Json(name = "user_media_failed")
+        USER_MEDIA_FAILED,
+
         @Json(name = "invite_timeout")
-        INVITE_TIMEOUT
+        INVITE_TIMEOUT,
+
+        @Json(name = "unknown_error")
+        UNKWOWN_ERROR
     }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt
index b961a6f654b478ea0d8f76a673cb3a10323c19e0..42489bc0ceb199000cf65471444f35ac4c81b111 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt
@@ -27,22 +27,35 @@ data class CallInviteContent(
         /**
          * Required. A unique identifier for the call.
          */
-        @Json(name = "call_id") val callId: String?,
+        @Json(name = "call_id") override val callId: String?,
+        /**
+         * Required. ID to let user identify remote echo of their own events
+         */
+        @Json(name = "party_id") override val partyId: String? = null,
         /**
          * Required. The session description object
          */
         @Json(name = "offer") val offer: Offer?,
         /**
-         * Required. The version of the VoIP specification this message adheres to. This specification is version 0.
+         * Required. The version of the VoIP specification this message adheres to.
          */
-        @Json(name = "version") val version: Int? = 0,
+        @Json(name = "version") override val version: String?,
         /**
          * Required. The time in milliseconds that the invite is valid for.
          * Once the invite age exceeds this value, clients should discard it.
          * They should also no longer show the call as awaiting an answer in the UI.
          */
-        @Json(name = "lifetime") val lifetime: Int?
-) {
+        @Json(name = "lifetime") val lifetime: Int?,
+        /**
+         * The field should be added for all invites where the target is a specific user
+         */
+        @Json(name = "invitee") val invitee: String? = null,
+        /**
+         * Capability advertisement.
+         */
+        @Json(name = "capabilities") val capabilities: CallCapabilities? = null
+
+): CallSignallingContent  {
     @JsonClass(generateAdapter = true)
     data class Offer(
             /**
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallNegotiateContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallNegotiateContent.kt
new file mode 100644
index 0000000000000000000000000000000000000000..040993bb51dda98cba50c5730173e9d43ba6d68a
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallNegotiateContent.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api.session.room.model.call
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+/**
+ * This introduces SDP negotiation semantics for media pause, hold/resume, ICE restarts and voice/video call up/downgrading.
+ */
+@JsonClass(generateAdapter = true)
+data class CallNegotiateContent(
+        /**
+         * Required. The ID of the call this event relates to.
+         */
+        @Json(name = "call_id") override val callId: String,
+        /**
+         * Required. ID to let user identify remote echo of their own events
+         */
+        @Json(name = "party_id") override val partyId: String? = null,
+        /**
+         * Required. The time in milliseconds that the negotiation is valid for. Once exceeded the sender
+         * of the negotiate event should consider the negotiation failed (timed out) and the recipient should ignore it.
+         **/
+        @Json(name = "lifetime") val lifetime: Int?,
+        /**
+         * Required. The session description object
+         */
+        @Json(name = "description") val description: Description? = null,
+
+        /**
+         * Required. The version of the VoIP specification this message adheres to.
+         */
+        @Json(name = "version") override val version: String?
+
+        ): CallSignallingContent  {
+    @JsonClass(generateAdapter = true)
+    data class Description(
+            /**
+             * Required. The type of session description.
+             */
+            @Json(name = "type") val type: SdpType?,
+            /**
+             * Required. The SDP text of the session description.
+             */
+            @Json(name = "sdp") val sdp: String?
+    )
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallRejectContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallRejectContent.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1da229b1799715ca934bf6f4c7b28dda909061ea
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallRejectContent.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api.session.room.model.call
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+/**
+ * Sent by either party to signal their termination of the call. This can be sent either once
+ * the call has been established or before to abort the call.
+ */
+@JsonClass(generateAdapter = true)
+data class CallRejectContent(
+        /**
+         * Required. The ID of the call this event relates to.
+         */
+        @Json(name = "call_id") override val callId: String,
+        /**
+         * Required. ID to let user identify remote echo of their own events
+         */
+        @Json(name = "party_id") override val partyId: String? = null,
+        /**
+         * Required. The version of the VoIP specification this message adheres to.
+         */
+        @Json(name = "version") override val version: String?
+) : CallSignallingContent
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallReplacesContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallReplacesContent.kt
new file mode 100644
index 0000000000000000000000000000000000000000..97a3b8c7a72e576c5956852f1f2870e834275667
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallReplacesContent.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api.session.room.model.call
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+/**
+ * This event is sent to signal the intent of a participant in a call to replace the call with another,
+ * such that the other participant ends up in a call with a new user.
+ */
+@JsonClass(generateAdapter = true)
+data class CallReplacesContent(
+        /**
+         * Required. The ID of the call this event relates to.
+         */
+        @Json(name = "call_id") override val callId: String,
+        /**
+         * Required. ID to let user identify remote echo of their own events
+         */
+        @Json(name = "party_id") override val partyId: String? = null,
+        /**
+         * An identifier for the call replacement itself, generated by the transferor.
+         */
+        @Json(name = "replacement_id") val replacementId: String? = null,
+        /**
+         *  Optional. If specified, the transferee client waits for an invite to this room and joins it
+         *  (possibly waiting for user confirmation) and then continues the transfer in this room.
+         *  If absent, the transferee contacts the Matrix User ID given in the target_user field in a room of its choosing.
+         */
+        @Json(name = "target_room") val targerRoomId: String? = null,
+        /**
+         *  An object giving information about the transfer target
+         */
+        @Json(name = "target_user") val targetUser: TargetUser? = null,
+        /**
+         *  If specified, gives the call ID for the transferee's client to use when placing the replacement call.
+         *  Mutually exclusive with await_call
+         */
+        @Json(name = "create_call") val createCall: String? = null,
+        /**
+         *  If specified, gives the call ID that the transferee's client should wait for.
+         *  Mutually exclusive with create_call.
+         */
+        @Json(name = "await_call") val awaitCall: String? = null,
+        /**
+         * Required. The version of the VoIP specification this messages adheres to.
+         */
+        @Json(name = "version") override val version: String?
+): CallSignallingContent  {
+
+    @JsonClass(generateAdapter = true)
+    data class TargetUser(
+            /**
+             * Required. The matrix user ID of the transfer target
+             */
+            @Json(name = "id") val id: String,
+            /**
+             * Optional. The display name of the transfer target.
+             */
+            @Json(name = "display_name") val displayName: String?,
+            /**
+             * Optional. The avatar URL of the transfer target.
+             */
+            @Json(name = "avatar_url") val avatarUrl: String?
+
+    )
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSelectAnswerContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSelectAnswerContent.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6ea70ac990589b46bd456e3d37ed0a24a67df773
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSelectAnswerContent.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api.session.room.model.call
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+/**
+ * This event is sent by the callee when they wish to answer the call.
+ */
+@JsonClass(generateAdapter = true)
+data class CallSelectAnswerContent(
+        /**
+         * Required. The ID of the call this event relates to.
+         */
+        @Json(name = "call_id") override val callId: String,
+        /**
+         * Required. ID to let user identify remote echo of their own events
+         */
+        @Json(name = "party_id") override val partyId: String? = null,
+        /**
+         * Required. Indicates the answer user has chosen.
+         */
+        @Json(name = "selected_party_id") val selectedPartyId: String? = null,
+
+        /**
+         * Required. The version of the VoIP specification this message adheres to.
+         */
+        @Json(name = "version") override val version: String?
+): CallSignallingContent
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSignallingContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSignallingContent.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f8d8c2a5e82d777f55cb33ca982c44eb4a2a0cab
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSignallingContent.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.api.session.room.model.call
+
+interface CallSignallingContent {
+    /**
+     * Required. A unique identifier for the call.
+     */
+    val callId: String?
+
+    /**
+     * Required. ID to let user identify remote echo of their own events
+     */
+    val partyId: String?
+
+    /**
+     * Required. The version of the VoIP specification this message adheres to. This specification is version 0.
+     */
+    val version: String?
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/SdpType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/SdpType.kt
index ff393135ea85e2b3f8d700bfcba000e8a6eb9092..9b55ab80c754bbc9cd64e09df9f16415491ceff7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/SdpType.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/SdpType.kt
@@ -25,5 +25,5 @@ enum class SdpType {
     OFFER,
 
     @Json(name = "answer")
-    ANSWER
+    ANSWER;
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/relation/RelationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/relation/RelationService.kt
index 49aa95924c8cb58bc681ae4b9995baf11f7622d2..59d84ef40fd82c6f458baba55fe856904b502ac1 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/relation/RelationService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/relation/RelationService.kt
@@ -16,7 +16,6 @@
 package org.matrix.android.sdk.api.session.room.model.relation
 
 import androidx.lifecycle.LiveData
-import org.matrix.android.sdk.api.MatrixCallback
 import org.matrix.android.sdk.api.session.events.model.Event
 import org.matrix.android.sdk.api.session.room.model.EventAnnotationsSummary
 import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
@@ -67,11 +66,11 @@ interface RelationService {
 
     /**
      * Edit a text message body. Limited to "m.text" contentType
-     * @param targetEventId The event to edit
+     * @param targetEvent The event to edit
      * @param newBodyText The edited body
      * @param compatibilityBodyText The text that will appear on clients that don't support yet edition
      */
-    fun editTextMessage(targetEventId: String,
+    fun editTextMessage(targetEvent: TimelineEvent,
                         msgType: String,
                         newBodyText: CharSequence,
                         newBodyAutoMarkdown: Boolean,
@@ -92,8 +91,11 @@ interface RelationService {
 
     /**
      * Get the edit history of the given event
+     * The return list will contain the original event and all the editions of this event, done by the
+     * same sender, sorted in the reverse order (so the original event is the latest element, and the
+     * latest edition is the first element of the list)
      */
-    fun fetchEditHistory(eventId: String, callback: MatrixCallback<List<Event>>)
+    suspend fun fetchEditHistory(eventId: String): List<Event>
 
     /**
      * Reply to an event in the timeline (must be in same room)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/Role.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/Role.kt
index ecfddad0a4727b21bfcadc5f61826013117ca10e..5fe9bf6993a6c0afde6470782e8c0a3aca69269c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/Role.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/Role.kt
@@ -17,14 +17,11 @@
 
 package org.matrix.android.sdk.api.session.room.powerlevels
 
-import androidx.annotation.StringRes
-import org.matrix.android.sdk.R
-
-sealed class Role(open val value: Int, @StringRes val res: Int) : Comparable<Role> {
-    object Admin : Role(100, R.string.power_level_admin)
-    object Moderator : Role(50, R.string.power_level_moderator)
-    object Default : Role(0, R.string.power_level_default)
-    data class Custom(override val value: Int) : Role(value, R.string.power_level_custom)
+sealed class Role(open val value: Int) : Comparable<Role> {
+    object Admin : Role(100)
+    object Moderator : Role(50)
+    object Default : Role(0)
+    data class Custom(override val value: Int) : Role(value)
 
     override fun compareTo(other: Role): Int {
         return value.compareTo(other.value)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt
index 152a018e78a56c9394d2fafab4784a46b0b45b42..6ae42de90cdd7573cf240f4b134e4d7ec2bc25d0 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt
@@ -132,4 +132,9 @@ interface SendService {
      * Resend all failed messages one by one (and keep order)
      */
     fun resendAllFailedMessages()
+
+    /**
+     * Cancel all failed messages
+     */
+    fun cancelAllFailedMessages()
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/sender/SenderInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/sender/SenderInfo.kt
index 1b4368e3da5ee0b9f0a307e6a5cef686f285d26e..9b73136fc3792237b77013c38a776ccedc349f49 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/sender/SenderInfo.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/sender/SenderInfo.kt
@@ -16,6 +16,8 @@
 
 package org.matrix.android.sdk.api.session.room.sender
 
+import org.matrix.android.sdk.internal.util.replaceSpaceChars
+
 data class SenderInfo(
         val userId: String,
         /**
@@ -27,8 +29,9 @@ data class SenderInfo(
 ) {
     val disambiguatedDisplayName: String
         get() = when {
-            displayName.isNullOrBlank() -> userId
-            isUniqueDisplayName         -> displayName
-            else                        -> "$displayName ($userId)"
+            displayName == null                       -> userId
+            displayName.replaceSpaceChars().isBlank() -> "$displayName ($userId)"
+            isUniqueDisplayName                       -> displayName
+            else                                      -> "$displayName ($userId)"
         }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt
index 444366e9128fa876a9aa147fe993fbfc73fa387e..e614ea91d649b8cd712926d78c0a1a6176bdb2a8 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt
@@ -65,13 +65,30 @@ interface StateService {
      */
     suspend fun deleteAvatar()
 
+    /**
+     * Send a state event to the room
+     */
     suspend fun sendStateEvent(eventType: String, stateKey: String?, body: JsonDict)
 
+    /**
+     * Get a state event of the room
+     */
     fun getStateEvent(eventType: String, stateKey: QueryStringValue = QueryStringValue.NoCondition): Event?
 
+    /**
+     * Get a live state event of the room
+     */
     fun getStateEventLive(eventType: String, stateKey: QueryStringValue = QueryStringValue.NoCondition): LiveData<Optional<Event>>
 
+    /**
+     * Get state events of the room
+     * @param eventTypes Set of eventType. If empty, all state events will be returned
+     */
     fun getStateEvents(eventTypes: Set<String>, stateKey: QueryStringValue = QueryStringValue.NoCondition): List<Event>
 
+    /**
+     * Get live state events of the room
+     * @param eventTypes Set of eventType to observe. If empty, all state events will be observed
+     */
     fun getStateEventsLive(eventTypes: Set<String>, stateKey: QueryStringValue = QueryStringValue.NoCondition): LiveData<List<Event>>
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomSummaryConstants.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomSummaryConstants.kt
index dcaf5f32768df57b7d66ae37798617b8ebd6703f..ef6300eae2ac011939a0b384a8e319711aeeb87f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomSummaryConstants.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomSummaryConstants.kt
@@ -20,11 +20,15 @@ import org.matrix.android.sdk.api.session.events.model.EventType
 
 object RoomSummaryConstants {
 
+    /**
+     *
+     */
     val PREVIEWABLE_TYPES = listOf(
             // TODO filter message type (KEY_VERIFICATION_READY, etc.)
             EventType.MESSAGE,
             EventType.CALL_INVITE,
             EventType.CALL_HANGUP,
+            EventType.CALL_REJECT,
             EventType.CALL_ANSWER,
             EventType.ENCRYPTED,
             EventType.STICKER,
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt
index b10fb540e112e44c8fb5917251661cb10d9e2dcd..32f6b94cd8d7a6c903df4e00739e942a2fc1c31e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt
@@ -38,6 +38,9 @@ import org.matrix.android.sdk.api.util.ContentUtils.extractUsefulTextFromReply
  */
 data class TimelineEvent(
         val root: Event,
+        /**
+         * Uniquely identify an event, computed locally by the sdk
+         */
         val localId: Long,
         val eventId: String,
         val displayIndex: Int,
@@ -52,6 +55,8 @@ data class TimelineEvent(
         }
     }
 
+    val roomId = root.roomId ?: ""
+
     val metadata = HashMap<String, Any>()
 
     /**
@@ -121,8 +126,7 @@ fun TimelineEvent.getLastMessageContent(): MessageContent? {
     return if (root.getClearType() == EventType.STICKER) {
         root.getClearContent().toModel<MessageStickerContent>()
     } else {
-        annotations?.editSummary?.aggregatedContent?.toModel()
-                ?: root.getClearContent().toModel()
+        (annotations?.editSummary?.latestContent ?: root.getClearContent()).toModel()
     }
 }
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineService.kt
index 2876ec69e56c817d4ba2133f47669ee1fe60487e..3c021384e13a6773465939996ce146aa414b9aa9 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineService.kt
@@ -36,9 +36,23 @@ interface TimelineService {
      */
     fun createTimeline(eventId: String?, settings: TimelineSettings): Timeline
 
+    /**
+     * Returns a snapshot of TimelineEvent event with eventId.
+     * At the opposite of getTimeLineEventLive which will be updated when local echo event is synced, it will return null in this case.
+     * @param eventId the eventId to get the TimelineEvent
+     */
     fun getTimeLineEvent(eventId: String): TimelineEvent?
 
+    /**
+     * Creates a LiveData of Optional TimelineEvent event with eventId.
+     * If the eventId is a local echo eventId, it will make the LiveData be updated with the synced TimelineEvent when coming through the sync.
+     * In this case, makes sure to use the new synced eventId from the TimelineEvent class if you want to interact, as the local echo is removed from the SDK.
+     * @param eventId the eventId to listen for TimelineEvent
+     */
     fun getTimeLineEventLive(eventId: String): LiveData<Optional<TimelineEvent>>
 
+    /**
+     * Returns a snapshot list of TimelineEvent with EventType.MESSAGE and MessageType.MSGTYPE_IMAGE or MessageType.MSGTYPE_VIDEO.
+     */
     fun getAttachmentMessages(): List<TimelineEvent>
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/FilterService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/FilterService.kt
index 70de026857618a4e496f5dd235aef4464cd09a7e..6d1d12f1bc68857d84cfea3951a4449e3f4982ee 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/FilterService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/FilterService.kt
@@ -22,9 +22,9 @@ interface FilterService {
         NoFilter,
 
         /**
-         * Filter for Riot, will include only known event type
+         * Filter for Element, will include only known event type
          */
-        RiotFilter
+        ElementFilter
     }
 
     /**
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/thirdparty/ThirdPartyService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/thirdparty/ThirdPartyService.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2ae4562b0b50a47eb36679d4193fd0f036d010c9
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/thirdparty/ThirdPartyService.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C
+ *
+ * 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 org.matrix.android.sdk.api.session.thirdparty
+
+import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
+import org.matrix.android.sdk.api.session.thirdparty.model.ThirdPartyUser
+
+/**
+ * See https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-thirdparty-protocols
+ */
+interface ThirdPartyService {
+
+    /**
+     * Fetches the overall metadata about protocols supported by the homeserver.
+     * Includes both the available protocols and all fields required for queries against each protocol.
+     */
+    suspend fun getThirdPartyProtocols(): Map<String, ThirdPartyProtocol>
+
+    /**
+     * Retrieve a Matrix User ID linked to a user on the third party service, given a set of user parameters.
+     * @param protocol Required. The name of the protocol.
+     * @param fields One or more custom fields that are passed to the AS to help identify the user.
+     */
+    suspend fun getThirdPartyUser(protocol: String, fields: Map<String, String> = emptyMap()): List<ThirdPartyUser>
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/thirdparty/model/ThirdPartyUser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/thirdparty/model/ThirdPartyUser.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d77dfcfe358e5ea79c1115ade71b0f42203750cf
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/thirdparty/model/ThirdPartyUser.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C
+ *
+ * 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 org.matrix.android.sdk.api.session.thirdparty.model
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+import org.matrix.android.sdk.api.util.JsonDict
+
+@JsonClass(generateAdapter = true)
+data class ThirdPartyUser(
+        /*
+            Required. A Matrix User ID represting a third party user.
+         */
+        @Json(name = "userid") val userId: String,
+        /*
+            Required. The protocol ID that the third party location is a part of.
+         */
+        @Json(name = "protocol") val protocol: String,
+        /*
+            Required. Information used to identify this third party location.
+         */
+        @Json(name = "fields") val fields: JsonDict
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetService.kt
index 037cd22b8758005cb988b92111881d98ff75c29f..bf3ff8959dc21d5e99fe39d9c21ea08d8a9557ff 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetService.kt
@@ -56,6 +56,11 @@ interface WidgetService {
             excludedTypes: Set<String>? = null
     ): List<Widget>
 
+    /**
+     * Return the computed URL of a widget
+     */
+    fun getWidgetComputedUrl(widget: Widget, isLightTheme: Boolean): String?
+
     /**
      * Returns the live room widgets so you can listen to them.
      * Some widgets can be deactivated, so be sure to check for isActive.
@@ -97,10 +102,11 @@ interface WidgetService {
     ): LiveData<List<Widget>>
 
     /**
-     * Creates a new widget in a room. It makes sure you have the rights to handle this.
+     * Creates and send a new widget in a room. It makes sure you have the rights to handle this.
      *
-     * @param roomId: the room where you want to deactivate the widget.
-     * @param widgetId: the widget to deactivate.
+     * @param roomId the room where you want to create the widget.
+     * @param widgetId the widget to create.
+     * @param content the content of the widget
      * @param callback the matrix callback to listen for result.
      * @return Cancelable
      */
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/model/Widget.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/model/Widget.kt
index c8465d4d2e6dff51685e1c7e0f3da4d3031c45e8..86aaba7f6fcb5f87186bcb3202b5479a6479125c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/model/Widget.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/model/Widget.kt
@@ -25,7 +25,6 @@ data class Widget(
         val widgetId: String,
         val senderInfo: SenderInfo?,
         val isAddedByMe: Boolean,
-        val computedUrl: String?,
         val type: WidgetType
 ) {
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/ContentUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/ContentUtils.kt
index c82a929ee0bc2c9af9a7b196c101239c2353bfc6..1a00b85ff4e3d04934ae448f65ddeb3e849f7895 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/ContentUtils.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/ContentUtils.kt
@@ -20,7 +20,7 @@ object ContentUtils {
         val lines = repliedBody.lines()
         var wellFormed = repliedBody.startsWith(">")
         var endOfPreviousFound = false
-        val usefullines = ArrayList<String>()
+        val usefulLines = ArrayList<String>()
         lines.forEach {
             if (it == "") {
                 endOfPreviousFound = true
@@ -29,10 +29,10 @@ object ContentUtils {
             if (!endOfPreviousFound) {
                 wellFormed = wellFormed && it.startsWith(">")
             } else {
-                usefullines.add(it)
+                usefulLines.add(it)
             }
         }
-        return usefullines.joinToString("\n").takeIf { wellFormed } ?: repliedBody
+        return usefulLines.joinToString("\n").takeIf { wellFormed } ?: repliedBody
     }
 
     fun extractUsefulTextFromHtmlReply(repliedBody: String): String {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/UrlExtensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/UrlExtensions.kt
index 17f27b251491c227c80df9d2f398fc09a384f9ac..d40de1a0df282c4c6b531dec0c3df980997c73f4 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/UrlExtensions.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/UrlExtensions.kt
@@ -35,3 +35,10 @@ fun StringBuilder.appendParamToUrl(param: String, value: String): StringBuilder
 
     return this
 }
+
+fun StringBuilder.appendParamsToUrl(params: Map<String, String>): StringBuilder {
+    params.forEach { (param, value) ->
+        appendParamToUrl(param, value)
+    }
+    return this
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthModule.kt
index 2ec8900f7c08295800856e9e2fa193ed8a92fe76..bb62dbbfe92cfe8771d7ac173a24d3366077a913 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthModule.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthModule.kt
@@ -20,7 +20,9 @@ import android.content.Context
 import dagger.Binds
 import dagger.Module
 import dagger.Provides
+import io.realm.RealmConfiguration
 import org.matrix.android.sdk.api.auth.AuthenticationService
+import org.matrix.android.sdk.api.auth.HomeServerHistoryService
 import org.matrix.android.sdk.api.legacy.LegacySessionImporter
 import org.matrix.android.sdk.internal.auth.db.AuthRealmMigration
 import org.matrix.android.sdk.internal.auth.db.AuthRealmModule
@@ -32,8 +34,6 @@ import org.matrix.android.sdk.internal.database.RealmKeysUtils
 import org.matrix.android.sdk.internal.di.AuthDatabase
 import org.matrix.android.sdk.internal.legacy.DefaultLegacySessionImporter
 import org.matrix.android.sdk.internal.wellknown.WellknownModule
-import io.realm.RealmConfiguration
-import org.matrix.android.sdk.api.auth.HomeServerHistoryService
 import java.io.File
 
 @Module(includes = [WellknownModule::class])
@@ -82,6 +82,9 @@ internal abstract class AuthModule {
     @Binds
     abstract fun bindDirectLoginTask(task: DefaultDirectLoginTask): DirectLoginTask
 
+    @Binds
+    abstract fun bindIsValidClientServerApiTask(task: DefaultIsValidClientServerApiTask): IsValidClientServerApiTask
+
     @Binds
     abstract fun bindHomeServerHistoryService(service: DefaultHomeServerHistoryService): HomeServerHistoryService
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt
index c99e9bd81c88b1c314a1c5fa3abeae4b7cf233c0..4f3451cf307dc9ce85c1b03a29ae3055665c28a7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt
@@ -18,10 +18,7 @@ package org.matrix.android.sdk.internal.auth
 
 import android.net.Uri
 import dagger.Lazy
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
 import okhttp3.OkHttpClient
-import org.matrix.android.sdk.api.MatrixCallback
 import org.matrix.android.sdk.api.auth.AuthenticationService
 import org.matrix.android.sdk.api.auth.data.Credentials
 import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
@@ -32,8 +29,6 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationWizard
 import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
 import org.matrix.android.sdk.api.failure.Failure
 import org.matrix.android.sdk.api.session.Session
-import org.matrix.android.sdk.api.util.Cancelable
-import org.matrix.android.sdk.api.util.NoOpCancellable
 import org.matrix.android.sdk.api.util.appendParamToUrl
 import org.matrix.android.sdk.internal.SessionManager
 import org.matrix.android.sdk.internal.auth.data.LoginFlowResponse
@@ -50,11 +45,6 @@ import org.matrix.android.sdk.internal.network.RetrofitFactory
 import org.matrix.android.sdk.internal.network.executeRequest
 import org.matrix.android.sdk.internal.network.httpclient.addSocketFactory
 import org.matrix.android.sdk.internal.network.ssl.UnrecognizedCertificateException
-import org.matrix.android.sdk.internal.task.TaskExecutor
-import org.matrix.android.sdk.internal.task.configureWith
-import org.matrix.android.sdk.internal.task.launchToCallback
-import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
-import org.matrix.android.sdk.internal.util.toCancelable
 import org.matrix.android.sdk.internal.wellknown.GetWellknownTask
 import javax.inject.Inject
 import javax.net.ssl.HttpsURLConnection
@@ -63,14 +53,12 @@ internal class DefaultAuthenticationService @Inject constructor(
         @Unauthenticated
         private val okHttpClient: Lazy<OkHttpClient>,
         private val retrofitFactory: RetrofitFactory,
-        private val coroutineDispatchers: MatrixCoroutineDispatchers,
         private val sessionParamsStore: SessionParamsStore,
         private val sessionManager: SessionManager,
         private val sessionCreator: SessionCreator,
         private val pendingSessionStore: PendingSessionStore,
         private val getWellknownTask: GetWellknownTask,
-        private val directLoginTask: DirectLoginTask,
-        private val taskExecutor: TaskExecutor
+        private val directLoginTask: DirectLoginTask
 ) : AuthenticationService {
 
     private var pendingSessionData: PendingSessionData? = pendingSessionStore.getPendingSessionData()
@@ -89,15 +77,11 @@ internal class DefaultAuthenticationService @Inject constructor(
         }
     }
 
-    override fun getLoginFlowOfSession(sessionId: String, callback: MatrixCallback<LoginFlowResult>): Cancelable {
+    override suspend fun getLoginFlowOfSession(sessionId: String): LoginFlowResult {
         val homeServerConnectionConfig = sessionParamsStore.get(sessionId)?.homeServerConnectionConfig
+                ?: throw IllegalStateException("Session not found")
 
-        return if (homeServerConnectionConfig == null) {
-            callback.onFailure(IllegalStateException("Session not found"))
-            NoOpCancellable
-        } else {
-            getLoginFlow(homeServerConnectionConfig, callback)
-        }
+        return getLoginFlow(homeServerConnectionConfig)
     }
 
     override fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?): String? {
@@ -146,70 +130,70 @@ internal class DefaultAuthenticationService @Inject constructor(
                 ?.trim { it == '/' }
     }
 
-    override fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig, callback: MatrixCallback<LoginFlowResult>): Cancelable {
+    /**
+     * This is the entry point of the authentication service.
+     * homeServerConnectionConfig contains a homeserver URL probably entered by the user, which can be a
+     * valid homeserver API url, the url of Element Web, or anything else.
+     */
+    override suspend fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
         pendingSessionData = null
 
-        return taskExecutor.executorScope.launch(coroutineDispatchers.main) {
-            pendingSessionStore.delete()
+        pendingSessionStore.delete()
 
-            val result = runCatching {
-                getLoginFlowInternal(homeServerConnectionConfig)
-            }
-            result.fold(
-                    {
-                        if (it is LoginFlowResult.Success) {
-                            // The homeserver exists and up to date, keep the config
-                            // Homeserver url may have been changed, if it was a Riot url
-                            val alteredHomeServerConnectionConfig = homeServerConnectionConfig.copy(
-                                    homeServerUri = Uri.parse(it.homeServerUrl)
-                            )
-
-                            pendingSessionData = PendingSessionData(alteredHomeServerConnectionConfig)
-                                    .also { data -> pendingSessionStore.savePendingSessionData(data) }
-                        }
-                        callback.onSuccess(it)
-                    },
-                    {
-                        if (it is UnrecognizedCertificateException) {
-                            callback.onFailure(Failure.UnrecognizedCertificateFailure(homeServerConnectionConfig.homeServerUri.toString(), it.fingerprint))
-                        } else {
-                            callback.onFailure(it)
-                        }
-                    }
-            )
+        val result = runCatching {
+            getLoginFlowInternal(homeServerConnectionConfig)
         }
-                .toCancelable()
+        return result.fold(
+                {
+                    if (it is LoginFlowResult.Success) {
+                        // The homeserver exists and up to date, keep the config
+                        // Homeserver url may have been changed, if it was a Riot url
+                        val alteredHomeServerConnectionConfig = homeServerConnectionConfig.copy(
+                                homeServerUri = Uri.parse(it.homeServerUrl)
+                        )
+
+                        pendingSessionData = PendingSessionData(alteredHomeServerConnectionConfig)
+                                .also { data -> pendingSessionStore.savePendingSessionData(data) }
+                    }
+                    it
+                },
+                {
+                    if (it is UnrecognizedCertificateException) {
+                        throw Failure.UnrecognizedCertificateFailure(homeServerConnectionConfig.homeServerUri.toString(), it.fingerprint)
+                    } else {
+                        throw it
+                    }
+                }
+        )
     }
 
     private suspend fun getLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
-        return withContext(coroutineDispatchers.io) {
-            val authAPI = buildAuthAPI(homeServerConnectionConfig)
+        val authAPI = buildAuthAPI(homeServerConnectionConfig)
 
-            // First check the homeserver version
-            runCatching {
-                executeRequest<Versions>(null) {
-                    apiCall = authAPI.versions()
-                }
+        // First check the homeserver version
+        return runCatching {
+            executeRequest<Versions>(null) {
+                apiCall = authAPI.versions()
             }
-                    .map { versions ->
-                        // Ok, it seems that the homeserver url is valid
-                        getLoginFlowResult(authAPI, versions, homeServerConnectionConfig.homeServerUri.toString())
-                    }
-                    .fold(
-                            {
-                                it
-                            },
-                            {
-                                if (it is Failure.OtherServerError
-                                        && it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
-                                    // It's maybe a Riot url?
-                                    getRiotDomainLoginFlowInternal(homeServerConnectionConfig)
-                                } else {
-                                    throw it
-                                }
-                            }
-                    )
         }
+                .map { versions ->
+                    // Ok, it seems that the homeserver url is valid
+                    getLoginFlowResult(authAPI, versions, homeServerConnectionConfig.homeServerUri.toString())
+                }
+                .fold(
+                        {
+                            it
+                        },
+                        {
+                            if (it is Failure.OtherServerError
+                                    && it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
+                                // It's maybe a Riot url?
+                                getRiotDomainLoginFlowInternal(homeServerConnectionConfig)
+                            } else {
+                                throw it
+                            }
+                        }
+                )
     }
 
     private suspend fun getRiotDomainLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
@@ -338,12 +322,9 @@ internal class DefaultAuthenticationService @Inject constructor(
                 ?: let {
                     pendingSessionData?.homeServerConnectionConfig?.let {
                         DefaultRegistrationWizard(
-                                buildClient(it),
-                                retrofitFactory,
-                                coroutineDispatchers,
+                                buildAuthAPI(it),
                                 sessionCreator,
-                                pendingSessionStore,
-                                taskExecutor.executorScope
+                                pendingSessionStore
                         ).also {
                             currentRegistrationWizard = it
                         }
@@ -359,12 +340,9 @@ internal class DefaultAuthenticationService @Inject constructor(
                 ?: let {
                     pendingSessionData?.homeServerConnectionConfig?.let {
                         DefaultLoginWizard(
-                                buildClient(it),
-                                retrofitFactory,
-                                coroutineDispatchers,
+                                buildAuthAPI(it),
                                 sessionCreator,
-                                pendingSessionStore,
-                                taskExecutor.executorScope
+                                pendingSessionStore
                         ).also {
                             currentLoginWizard = it
                         }
@@ -372,7 +350,7 @@ internal class DefaultAuthenticationService @Inject constructor(
                 }
     }
 
-    override fun cancelPendingLoginOrRegistration() {
+    override suspend fun cancelPendingLoginOrRegistration() {
         currentLoginWizard = null
         currentRegistrationWizard = null
 
@@ -381,61 +359,39 @@ internal class DefaultAuthenticationService @Inject constructor(
         pendingSessionData = pendingSessionData?.homeServerConnectionConfig
                 ?.let { PendingSessionData(it) }
                 .also {
-                    taskExecutor.executorScope.launch(coroutineDispatchers.main) {
-                        if (it == null) {
-                            // Should not happen
-                            pendingSessionStore.delete()
-                        } else {
-                            pendingSessionStore.savePendingSessionData(it)
-                        }
+                    if (it == null) {
+                        // Should not happen
+                        pendingSessionStore.delete()
+                    } else {
+                        pendingSessionStore.savePendingSessionData(it)
                     }
                 }
     }
 
-    override fun reset() {
+    override suspend fun reset() {
         currentLoginWizard = null
         currentRegistrationWizard = null
 
         pendingSessionData = null
 
-        taskExecutor.executorScope.launch(coroutineDispatchers.main) {
-            pendingSessionStore.delete()
-        }
+        pendingSessionStore.delete()
     }
 
-    override fun createSessionFromSso(homeServerConnectionConfig: HomeServerConnectionConfig,
-                                      credentials: Credentials,
-                                      callback: MatrixCallback<Session>): Cancelable {
-        return taskExecutor.executorScope.launchToCallback(coroutineDispatchers.main, callback) {
-            createSessionFromSso(credentials, homeServerConnectionConfig)
-        }
+    override suspend fun createSessionFromSso(homeServerConnectionConfig: HomeServerConnectionConfig,
+                                              credentials: Credentials): Session {
+        return sessionCreator.createSession(credentials, homeServerConnectionConfig)
     }
 
-    override fun getWellKnownData(matrixId: String,
-                                  homeServerConnectionConfig: HomeServerConnectionConfig?,
-                                  callback: MatrixCallback<WellknownResult>): Cancelable {
-        return getWellknownTask
-                .configureWith(GetWellknownTask.Params(matrixId, homeServerConnectionConfig)) {
-                    this.callback = callback
-                }
-                .executeBy(taskExecutor)
-    }
-
-    override fun directAuthentication(homeServerConnectionConfig: HomeServerConnectionConfig,
-                                      matrixId: String,
-                                      password: String,
-                                      initialDeviceName: String,
-                                      callback: MatrixCallback<Session>): Cancelable {
-        return directLoginTask
-                .configureWith(DirectLoginTask.Params(homeServerConnectionConfig, matrixId, password, initialDeviceName)) {
-                    this.callback = callback
-                }
-                .executeBy(taskExecutor)
+    override suspend fun getWellKnownData(matrixId: String,
+                                          homeServerConnectionConfig: HomeServerConnectionConfig?): WellknownResult {
+        return getWellknownTask.execute(GetWellknownTask.Params(matrixId, homeServerConnectionConfig))
     }
 
-    private suspend fun createSessionFromSso(credentials: Credentials,
-                                             homeServerConnectionConfig: HomeServerConnectionConfig): Session = withContext(coroutineDispatchers.computation) {
-        sessionCreator.createSession(credentials, homeServerConnectionConfig)
+    override suspend fun directAuthentication(homeServerConnectionConfig: HomeServerConnectionConfig,
+                                              matrixId: String,
+                                              password: String,
+                                              initialDeviceName: String): Session {
+        return directLoginTask.execute(DirectLoginTask.Params(homeServerConnectionConfig, matrixId, password, initialDeviceName))
     }
 
     private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/IsValidClientServerApiTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/IsValidClientServerApiTask.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b8416d69bfef0c1fa87f3c268392f940a0553f77
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/IsValidClientServerApiTask.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.auth
+
+import dagger.Lazy
+import okhttp3.OkHttpClient
+import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
+import org.matrix.android.sdk.api.failure.Failure
+import org.matrix.android.sdk.internal.auth.data.LoginFlowResponse
+import org.matrix.android.sdk.internal.di.Unauthenticated
+import org.matrix.android.sdk.internal.network.RetrofitFactory
+import org.matrix.android.sdk.internal.network.executeRequest
+import org.matrix.android.sdk.internal.network.httpclient.addSocketFactory
+import org.matrix.android.sdk.internal.task.Task
+import javax.inject.Inject
+import javax.net.ssl.HttpsURLConnection
+
+internal interface IsValidClientServerApiTask : Task<IsValidClientServerApiTask.Params, Boolean> {
+    data class Params(
+            val homeServerConnectionConfig: HomeServerConnectionConfig
+    )
+}
+
+internal class DefaultIsValidClientServerApiTask @Inject constructor(
+        @Unauthenticated
+        private val okHttpClient: Lazy<OkHttpClient>,
+        private val retrofitFactory: RetrofitFactory
+) : IsValidClientServerApiTask {
+
+    override suspend fun execute(params: IsValidClientServerApiTask.Params): Boolean {
+        val client = buildClient(params.homeServerConnectionConfig)
+        val homeServerUrl = params.homeServerConnectionConfig.homeServerUri.toString()
+
+        val authAPI = retrofitFactory.create(client, homeServerUrl)
+                .create(AuthAPI::class.java)
+
+        return try {
+            executeRequest<LoginFlowResponse>(null) {
+                apiCall = authAPI.getLoginFlows()
+            }
+            // We get a response, so the API is valid
+            true
+        } catch (failure: Throwable) {
+            if (failure is Failure.OtherServerError
+                    && failure.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
+                // Probably not valid
+                false
+            } else {
+                // Other error
+                throw failure
+            }
+        }
+    }
+
+    private fun buildClient(homeServerConnectionConfig: HomeServerConnectionConfig): OkHttpClient {
+        return okHttpClient.get()
+                .newBuilder()
+                .addSocketFactory(homeServerConnectionConfig)
+                .build()
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/SessionCreator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/SessionCreator.kt
index 6743e7336e65f8609b0a294a3001cb93f292fd4d..7c4a0c38ec5d3aed2cbdbe36ca2a6ccd899c8049 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/SessionCreator.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/SessionCreator.kt
@@ -20,6 +20,7 @@ import android.net.Uri
 import org.matrix.android.sdk.api.auth.data.Credentials
 import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
 import org.matrix.android.sdk.api.auth.data.SessionParams
+import org.matrix.android.sdk.api.extensions.tryOrNull
 import org.matrix.android.sdk.api.session.Session
 import org.matrix.android.sdk.internal.SessionManager
 import timber.log.Timber
@@ -32,7 +33,8 @@ internal interface SessionCreator {
 internal class DefaultSessionCreator @Inject constructor(
         private val sessionParamsStore: SessionParamsStore,
         private val sessionManager: SessionManager,
-        private val pendingSessionStore: PendingSessionStore
+        private val pendingSessionStore: PendingSessionStore,
+        private val isValidClientServerApiTask: IsValidClientServerApiTask
 ) : SessionCreator {
 
     /**
@@ -43,16 +45,28 @@ internal class DefaultSessionCreator @Inject constructor(
         // We can cleanup the pending session params
         pendingSessionStore.delete()
 
+        val overriddenUrl = credentials.discoveryInformation?.homeServer?.baseURL
+                // remove trailing "/"
+                ?.trim { it == '/' }
+                ?.takeIf { it.isNotBlank() }
+                ?.also { Timber.d("Overriding homeserver url to $it (will check if valid)") }
+                ?.let { Uri.parse(it) }
+                ?.takeIf {
+                    // Validate the URL, if the configuration is wrong server side, do not override
+                    tryOrNull {
+                        isValidClientServerApiTask.execute(
+                                IsValidClientServerApiTask.Params(
+                                        homeServerConnectionConfig.copy(homeServerUri = it)
+                                )
+                        )
+                                .also { Timber.d("Overriding homeserver url: $it") }
+                    } ?: true // In case of other error (no network, etc.), consider it is valid...
+                }
+
         val sessionParams = SessionParams(
                 credentials = credentials,
                 homeServerConnectionConfig = homeServerConnectionConfig.copy(
-                        homeServerUri = credentials.discoveryInformation?.homeServer?.baseURL
-                                // remove trailing "/"
-                                ?.trim { it == '/' }
-                                ?.takeIf { it.isNotBlank() }
-                                ?.also { Timber.d("Overriding homeserver url to $it") }
-                                ?.let { Uri.parse(it) }
-                                ?: homeServerConnectionConfig.homeServerUri,
+                        homeServerUri = overriddenUrl ?: homeServerConnectionConfig.homeServerUri,
                         identityServerUri = credentials.discoveryInformation?.identityServer?.baseURL
                                 // remove trailing "/"
                                 ?.trim { it == '/' }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt
index 108d0d4a420ba05778591f13ab0883447f184cf1..41678758497352821957812b5397c1a35254dbd9 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt
@@ -17,13 +17,10 @@
 package org.matrix.android.sdk.internal.auth.login
 
 import android.util.Patterns
-import org.matrix.android.sdk.api.MatrixCallback
 import org.matrix.android.sdk.api.auth.data.Credentials
 import org.matrix.android.sdk.api.auth.login.LoginWizard
 import org.matrix.android.sdk.api.auth.registration.RegisterThreePid
 import org.matrix.android.sdk.api.session.Session
-import org.matrix.android.sdk.api.util.Cancelable
-import org.matrix.android.sdk.api.util.NoOpCancellable
 import org.matrix.android.sdk.internal.auth.AuthAPI
 import org.matrix.android.sdk.internal.auth.PendingSessionStore
 import org.matrix.android.sdk.internal.auth.SessionCreator
@@ -34,56 +31,19 @@ import org.matrix.android.sdk.internal.auth.db.PendingSessionData
 import org.matrix.android.sdk.internal.auth.registration.AddThreePidRegistrationParams
 import org.matrix.android.sdk.internal.auth.registration.AddThreePidRegistrationResponse
 import org.matrix.android.sdk.internal.auth.registration.RegisterAddThreePidTask
-import org.matrix.android.sdk.internal.network.RetrofitFactory
 import org.matrix.android.sdk.internal.network.executeRequest
-import org.matrix.android.sdk.internal.task.launchToCallback
-import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.withContext
-import okhttp3.OkHttpClient
 
 internal class DefaultLoginWizard(
-        okHttpClient: OkHttpClient,
-        retrofitFactory: RetrofitFactory,
-        private val coroutineDispatchers: MatrixCoroutineDispatchers,
+        private val authAPI: AuthAPI,
         private val sessionCreator: SessionCreator,
-        private val pendingSessionStore: PendingSessionStore,
-        private val coroutineScope: CoroutineScope
+        private val pendingSessionStore: PendingSessionStore
 ) : LoginWizard {
 
     private var pendingSessionData: PendingSessionData = pendingSessionStore.getPendingSessionData() ?: error("Pending session data should exist here")
 
-    private val authAPI = retrofitFactory.create(okHttpClient, pendingSessionData.homeServerConnectionConfig.homeServerUri.toString())
-            .create(AuthAPI::class.java)
-
-    override fun login(login: String,
-                       password: String,
-                       deviceName: String,
-                       callback: MatrixCallback<Session>): Cancelable {
-        return coroutineScope.launchToCallback(coroutineDispatchers.main, callback) {
-            loginInternal(login, password, deviceName)
-        }
-    }
-
-    /**
-     * Ref: https://matrix.org/docs/spec/client_server/latest#handling-the-authentication-endpoint
-     */
-    override fun loginWithToken(loginToken: String, callback: MatrixCallback<Session>): Cancelable {
-        return coroutineScope.launchToCallback(coroutineDispatchers.main, callback) {
-            val loginParams = TokenLoginParams(
-                    token = loginToken
-            )
-            val credentials = executeRequest<Credentials>(null) {
-                apiCall = authAPI.login(loginParams)
-            }
-
-            sessionCreator.createSession(credentials, pendingSessionData.homeServerConnectionConfig)
-        }
-    }
-
-    private suspend fun loginInternal(login: String,
-                                      password: String,
-                                      deviceName: String) = withContext(coroutineDispatchers.computation) {
+    override suspend fun login(login: String,
+                               password: String,
+                               deviceName: String): Session {
         val loginParams = if (Patterns.EMAIL_ADDRESS.matcher(login).matches()) {
             PasswordLoginParams.thirdPartyIdentifier(ThreePidMedium.EMAIL, login, password, deviceName)
         } else {
@@ -93,16 +53,24 @@ internal class DefaultLoginWizard(
             apiCall = authAPI.login(loginParams)
         }
 
-        sessionCreator.createSession(credentials, pendingSessionData.homeServerConnectionConfig)
+        return sessionCreator.createSession(credentials, pendingSessionData.homeServerConnectionConfig)
     }
 
-    override fun resetPassword(email: String, newPassword: String, callback: MatrixCallback<Unit>): Cancelable {
-        return coroutineScope.launchToCallback(coroutineDispatchers.main, callback) {
-            resetPasswordInternal(email, newPassword)
+    /**
+     * Ref: https://matrix.org/docs/spec/client_server/latest#handling-the-authentication-endpoint
+     */
+    override suspend fun loginWithToken(loginToken: String): Session {
+        val loginParams = TokenLoginParams(
+                token = loginToken
+        )
+        val credentials = executeRequest<Credentials>(null) {
+            apiCall = authAPI.login(loginParams)
         }
+
+        return sessionCreator.createSession(credentials, pendingSessionData.homeServerConnectionConfig)
     }
 
-    private suspend fun resetPasswordInternal(email: String, newPassword: String) {
+    override suspend fun resetPassword(email: String, newPassword: String) {
         val param = RegisterAddThreePidTask.Params(
                 RegisterThreePid.Email(email),
                 pendingSessionData.clientSecret,
@@ -120,21 +88,14 @@ internal class DefaultLoginWizard(
                 .also { pendingSessionStore.savePendingSessionData(it) }
     }
 
-    override fun resetPasswordMailConfirmed(callback: MatrixCallback<Unit>): Cancelable {
-        val safeResetPasswordData = pendingSessionData.resetPasswordData ?: run {
-            callback.onFailure(IllegalStateException("developer error, no reset password in progress"))
-            return NoOpCancellable
-        }
-        return coroutineScope.launchToCallback(coroutineDispatchers.main, callback) {
-            resetPasswordMailConfirmedInternal(safeResetPasswordData)
-        }
-    }
+    override suspend fun resetPasswordMailConfirmed() {
+        val safeResetPasswordData = pendingSessionData.resetPasswordData
+                ?: throw IllegalStateException("developer error, no reset password in progress")
 
-    private suspend fun resetPasswordMailConfirmedInternal(resetPasswordData: ResetPasswordData) {
         val param = ResetPasswordMailConfirmed.create(
                 pendingSessionData.clientSecret,
-                resetPasswordData.addThreePidRegistrationResponse.sid,
-                resetPasswordData.newPassword
+                safeResetPasswordData.addThreePidRegistrationResponse.sid,
+                safeResetPasswordData.newPassword
         )
 
         executeRequest<Unit>(null) {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt
index 163009d9184866f1046a81c3275417a999588cb7..91e414e689771e8f6939eb60d817ada4a82bcb55 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt
@@ -16,10 +16,7 @@
 
 package org.matrix.android.sdk.internal.auth.registration
 
-import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.delay
-import okhttp3.OkHttpClient
-import org.matrix.android.sdk.api.MatrixCallback
 import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
 import org.matrix.android.sdk.api.auth.registration.RegisterThreePid
 import org.matrix.android.sdk.api.auth.registration.RegistrationResult
@@ -27,31 +24,22 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationWizard
 import org.matrix.android.sdk.api.auth.registration.toFlowResult
 import org.matrix.android.sdk.api.failure.Failure
 import org.matrix.android.sdk.api.failure.Failure.RegistrationFlowError
-import org.matrix.android.sdk.api.util.Cancelable
-import org.matrix.android.sdk.api.util.NoOpCancellable
 import org.matrix.android.sdk.internal.auth.AuthAPI
 import org.matrix.android.sdk.internal.auth.PendingSessionStore
 import org.matrix.android.sdk.internal.auth.SessionCreator
 import org.matrix.android.sdk.internal.auth.db.PendingSessionData
-import org.matrix.android.sdk.internal.network.RetrofitFactory
-import org.matrix.android.sdk.internal.task.launchToCallback
-import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
 
 /**
  * This class execute the registration request and is responsible to keep the session of interactive authentication
  */
 internal class DefaultRegistrationWizard(
-        private val okHttpClient: OkHttpClient,
-        private val retrofitFactory: RetrofitFactory,
-        private val coroutineDispatchers: MatrixCoroutineDispatchers,
+        authAPI: AuthAPI,
         private val sessionCreator: SessionCreator,
-        private val pendingSessionStore: PendingSessionStore,
-        private val coroutineScope: CoroutineScope
+        private val pendingSessionStore: PendingSessionStore
 ) : RegistrationWizard {
 
     private var pendingSessionData: PendingSessionData = pendingSessionStore.getPendingSessionData() ?: error("Pending session data should exist here")
 
-    private val authAPI = buildAuthAPI()
     private val registerTask = DefaultRegisterTask(authAPI)
     private val registerAddThreePidTask = DefaultRegisterAddThreePidTask(authAPI)
     private val validateCodeTask = DefaultValidateCodeTask(authAPI)
@@ -71,70 +59,54 @@ internal class DefaultRegistrationWizard(
     override val isRegistrationStarted: Boolean
         get() = pendingSessionData.isRegistrationStarted
 
-    override fun getRegistrationFlow(callback: MatrixCallback<RegistrationResult>): Cancelable {
+    override suspend fun getRegistrationFlow(): RegistrationResult {
         val params = RegistrationParams()
-        return coroutineScope.launchToCallback(coroutineDispatchers.main, callback) {
-            performRegistrationRequest(params)
-        }
+        return performRegistrationRequest(params)
     }
 
-    override fun createAccount(userName: String,
-                               password: String,
-                               initialDeviceDisplayName: String?,
-                               callback: MatrixCallback<RegistrationResult>): Cancelable {
+    override suspend fun createAccount(userName: String,
+                                       password: String,
+                                       initialDeviceDisplayName: String?): RegistrationResult {
         val params = RegistrationParams(
                 username = userName,
                 password = password,
                 initialDeviceDisplayName = initialDeviceDisplayName
         )
-        return coroutineScope.launchToCallback(coroutineDispatchers.main, callback) {
-            performRegistrationRequest(params)
-                    .also {
-                        pendingSessionData = pendingSessionData.copy(isRegistrationStarted = true)
-                                .also { pendingSessionStore.savePendingSessionData(it) }
-                    }
-        }
+        return performRegistrationRequest(params)
+                .also {
+                    pendingSessionData = pendingSessionData.copy(isRegistrationStarted = true)
+                            .also { pendingSessionStore.savePendingSessionData(it) }
+                }
     }
 
-    override fun performReCaptcha(response: String, callback: MatrixCallback<RegistrationResult>): Cancelable {
-        val safeSession = pendingSessionData.currentSession ?: run {
-            callback.onFailure(IllegalStateException("developer error, call createAccount() method first"))
-            return NoOpCancellable
-        }
+    override suspend fun performReCaptcha(response: String): RegistrationResult {
+        val safeSession = pendingSessionData.currentSession
+                ?: throw IllegalStateException("developer error, call createAccount() method first")
+
         val params = RegistrationParams(auth = AuthParams.createForCaptcha(safeSession, response))
-        return coroutineScope.launchToCallback(coroutineDispatchers.main, callback) {
-            performRegistrationRequest(params)
-        }
+        return performRegistrationRequest(params)
     }
 
-    override fun acceptTerms(callback: MatrixCallback<RegistrationResult>): Cancelable {
-        val safeSession = pendingSessionData.currentSession ?: run {
-            callback.onFailure(IllegalStateException("developer error, call createAccount() method first"))
-            return NoOpCancellable
-        }
+    override suspend fun acceptTerms(): RegistrationResult {
+        val safeSession = pendingSessionData.currentSession
+                ?: throw IllegalStateException("developer error, call createAccount() method first")
+
         val params = RegistrationParams(auth = AuthParams(type = LoginFlowTypes.TERMS, session = safeSession))
-        return coroutineScope.launchToCallback(coroutineDispatchers.main, callback) {
-            performRegistrationRequest(params)
-        }
+        return performRegistrationRequest(params)
     }
 
-    override fun addThreePid(threePid: RegisterThreePid, callback: MatrixCallback<RegistrationResult>): Cancelable {
-        return coroutineScope.launchToCallback(coroutineDispatchers.main, callback) {
-            pendingSessionData = pendingSessionData.copy(currentThreePidData = null)
-                    .also { pendingSessionStore.savePendingSessionData(it) }
+    override suspend fun addThreePid(threePid: RegisterThreePid): RegistrationResult {
+        pendingSessionData = pendingSessionData.copy(currentThreePidData = null)
+                .also { pendingSessionStore.savePendingSessionData(it) }
 
-            sendThreePid(threePid)
-        }
+        return sendThreePid(threePid)
     }
 
-    override fun sendAgainThreePid(callback: MatrixCallback<RegistrationResult>): Cancelable {
-        val safeCurrentThreePid = pendingSessionData.currentThreePidData?.threePid ?: run {
-            callback.onFailure(IllegalStateException("developer error, call createAccount() method first"))
-            return NoOpCancellable
-        }
-        return coroutineScope.launchToCallback(coroutineDispatchers.main, callback) {
-            sendThreePid(safeCurrentThreePid)
-        }
+    override suspend fun sendAgainThreePid(): RegistrationResult {
+        val safeCurrentThreePid = pendingSessionData.currentThreePidData?.threePid
+                ?: throw IllegalStateException("developer error, call createAccount() method first")
+
+        return sendThreePid(safeCurrentThreePid)
     }
 
     private suspend fun sendThreePid(threePid: RegisterThreePid): RegistrationResult {
@@ -173,20 +145,15 @@ internal class DefaultRegistrationWizard(
         return performRegistrationRequest(params)
     }
 
-    override fun checkIfEmailHasBeenValidated(delayMillis: Long, callback: MatrixCallback<RegistrationResult>): Cancelable {
-        val safeParam = pendingSessionData.currentThreePidData?.registrationParams ?: run {
-            callback.onFailure(IllegalStateException("developer error, no pending three pid"))
-            return NoOpCancellable
-        }
-        return coroutineScope.launchToCallback(coroutineDispatchers.main, callback) {
-            performRegistrationRequest(safeParam, delayMillis)
-        }
+    override suspend fun checkIfEmailHasBeenValidated(delayMillis: Long): RegistrationResult {
+        val safeParam = pendingSessionData.currentThreePidData?.registrationParams
+                ?: throw IllegalStateException("developer error, no pending three pid")
+
+        return performRegistrationRequest(safeParam, delayMillis)
     }
 
-    override fun handleValidateThreePid(code: String, callback: MatrixCallback<RegistrationResult>): Cancelable {
-        return coroutineScope.launchToCallback(coroutineDispatchers.main, callback) {
-            validateThreePid(code)
-        }
+    override suspend fun handleValidateThreePid(code: String): RegistrationResult {
+        return validateThreePid(code)
     }
 
     private suspend fun validateThreePid(code: String): RegistrationResult {
@@ -210,15 +177,12 @@ internal class DefaultRegistrationWizard(
         }
     }
 
-    override fun dummy(callback: MatrixCallback<RegistrationResult>): Cancelable {
-        val safeSession = pendingSessionData.currentSession ?: run {
-            callback.onFailure(IllegalStateException("developer error, call createAccount() method first"))
-            return NoOpCancellable
-        }
-        return coroutineScope.launchToCallback(coroutineDispatchers.main, callback) {
-            val params = RegistrationParams(auth = AuthParams(type = LoginFlowTypes.DUMMY, session = safeSession))
-            performRegistrationRequest(params)
-        }
+    override suspend fun dummy(): RegistrationResult {
+        val safeSession = pendingSessionData.currentSession
+                ?: throw IllegalStateException("developer error, call createAccount() method first")
+
+        val params = RegistrationParams(auth = AuthParams(type = LoginFlowTypes.DUMMY, session = safeSession))
+        return performRegistrationRequest(params)
     }
 
     private suspend fun performRegistrationRequest(registrationParams: RegistrationParams,
@@ -239,9 +203,4 @@ internal class DefaultRegistrationWizard(
         val session = sessionCreator.createSession(credentials, pendingSessionData.homeServerConnectionConfig)
         return RegistrationResult.Success(session)
     }
-
-    private fun buildAuthAPI(): AuthAPI {
-        val retrofit = retrofitFactory.create(okHttpClient, pendingSessionData.homeServerConnectionConfig.homeServerUri.toString())
-        return retrofit.create(AuthAPI::class.java)
-    }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/UIAExt.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/UIAExt.kt
index 1a0383cb220a8d031d80aca9a54a4ce9eff9148b..da0866a5fd56b3e8e7ec58f907c930d78ce74bb4 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/UIAExt.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/UIAExt.kt
@@ -16,14 +16,25 @@
 
 package org.matrix.android.sdk.internal.auth.registration
 
+import org.matrix.android.sdk.api.auth.UIABaseAuth
 import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
 import org.matrix.android.sdk.api.failure.Failure
 import org.matrix.android.sdk.api.failure.toRegistrationFlowResponse
-import org.matrix.android.sdk.api.auth.UIABaseAuth
 import timber.log.Timber
 import kotlin.coroutines.suspendCoroutine
 
-internal suspend fun handleUIA(failure: Throwable, interceptor: UserInteractiveAuthInterceptor, retryBlock: suspend (UIABaseAuth) -> Unit): Boolean {
+/**
+ * Handle a UIA challenge
+ *
+ * @param failure the failure to handle
+ * @param interceptor see doc in [UserInteractiveAuthInterceptor]
+ * @param retryBlock called at the end of the process, in this block generally retry executing the task, with
+ * provided authUpdate
+ * @return true if UIA is handled without error
+ */
+internal suspend fun handleUIA(failure: Throwable,
+                               interceptor: UserInteractiveAuthInterceptor,
+                               retryBlock: suspend (UIABaseAuth) -> Unit): Boolean {
     Timber.d("## UIA: check error ${failure.message}")
     val flowResponse = failure.toRegistrationFlowResponse()
             ?: return false.also {
@@ -38,16 +49,16 @@ internal suspend fun handleUIA(failure: Throwable, interceptor: UserInteractiveA
         suspendCoroutine<UIABaseAuth> { continuation ->
             interceptor.performStage(flowResponse, (failure as? Failure.ServerError)?.error?.code, continuation)
         }
-    } catch (failure: Throwable) {
-        Timber.w(failure, "## UIA: failed to participate")
+    } catch (failure2: Throwable) {
+        Timber.w(failure2, "## UIA: failed to participate")
         return false
     }
 
-    Timber.d("## UIA: updated auth $authUpdate")
+    Timber.d("## UIA: updated auth")
     return try {
         retryBlock(authUpdate)
         true
-    } catch (failure: Throwable) {
-        handleUIA(failure, interceptor, retryBlock)
+    } catch (failure3: Throwable) {
+        handleUIA(failure3, interceptor, retryBlock)
     }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt
index a786ebd4b2baaa7d7efa738d47f4dea307623694..e114f86a9956c614497337875f91df73eb6cf452 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt
@@ -61,7 +61,6 @@ import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreModule
 import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask
 import org.matrix.android.sdk.internal.crypto.tasks.DefaultClaimOneTimeKeysForUsersDevice
 import org.matrix.android.sdk.internal.crypto.tasks.DefaultDeleteDeviceTask
-import org.matrix.android.sdk.internal.crypto.tasks.DefaultDeleteDeviceWithUserPasswordTask
 import org.matrix.android.sdk.internal.crypto.tasks.DefaultDownloadKeysForUsers
 import org.matrix.android.sdk.internal.crypto.tasks.DefaultEncryptEventTask
 import org.matrix.android.sdk.internal.crypto.tasks.DefaultGetDeviceInfoTask
@@ -75,7 +74,6 @@ import org.matrix.android.sdk.internal.crypto.tasks.DefaultUploadKeysTask
 import org.matrix.android.sdk.internal.crypto.tasks.DefaultUploadSignaturesTask
 import org.matrix.android.sdk.internal.crypto.tasks.DefaultUploadSigningKeysTask
 import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask
-import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceWithUserPasswordTask
 import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask
 import org.matrix.android.sdk.internal.crypto.tasks.EncryptEventTask
 import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask
@@ -240,9 +238,6 @@ internal abstract class CryptoModule {
     @Binds
     abstract fun bindClaimOneTimeKeysForUsersDeviceTask(task: DefaultClaimOneTimeKeysForUsersDevice): ClaimOneTimeKeysForUsersDeviceTask
 
-    @Binds
-    abstract fun bindDeleteDeviceWithUserPasswordTask(task: DefaultDeleteDeviceWithUserPasswordTask): DeleteDeviceWithUserPasswordTask
-
     @Binds
     abstract fun bindCrossSigningService(service: DefaultCrossSigningService): CrossSigningService
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt
index 678bc9819f12dc8bc2ba4d7be820b1d8e6481fb0..17d25736ebd52b105cd70295eab5dc5f8a64a7d5 100755
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt
@@ -53,6 +53,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
 import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter
 import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction
 import org.matrix.android.sdk.internal.crypto.algorithms.IMXEncrypting
+import org.matrix.android.sdk.internal.crypto.algorithms.IMXGroupEncryption
 import org.matrix.android.sdk.internal.crypto.algorithms.IMXWithHeldExtension
 import org.matrix.android.sdk.internal.crypto.algorithms.megolm.MXMegolmEncryptionFactory
 import org.matrix.android.sdk.internal.crypto.algorithms.olm.MXOlmEncryptionFactory
@@ -75,7 +76,6 @@ import org.matrix.android.sdk.internal.crypto.model.toRest
 import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository
 import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
 import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask
-import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceWithUserPasswordTask
 import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask
 import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask
 import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask
@@ -98,7 +98,6 @@ import org.matrix.olm.OlmManager
 import timber.log.Timber
 import java.util.concurrent.atomic.AtomicBoolean
 import javax.inject.Inject
-import kotlin.jvm.Throws
 import kotlin.math.max
 
 /**
@@ -153,9 +152,8 @@ internal class DefaultCryptoService @Inject constructor(
         // Repository
         private val megolmEncryptionFactory: MXMegolmEncryptionFactory,
         private val olmEncryptionFactory: MXOlmEncryptionFactory,
-        private val deleteDeviceTask: DeleteDeviceTask,
-        private val deleteDeviceWithUserPasswordTask: DeleteDeviceWithUserPasswordTask,
         // Tasks
+        private val deleteDeviceTask: DeleteDeviceTask,
         private val getDevicesTask: GetDevicesTask,
         private val getDeviceInfoTask: GetDeviceInfoTask,
         private val setDeviceNameTask: SetDeviceNameTask,
@@ -217,15 +215,6 @@ internal class DefaultCryptoService @Inject constructor(
                 .executeBy(taskExecutor)
     }
 
-    override fun deleteDeviceWithUserPassword(deviceId: String, authSession: String?, password: String, callback: MatrixCallback<Unit>) {
-        deleteDeviceWithUserPasswordTask
-                .configureWith(DeleteDeviceWithUserPasswordTask.Params(deviceId, authSession, password)) {
-                    this.executionThread = TaskThread.CRYPTO
-                    this.callback = callback
-                }
-                .executeBy(taskExecutor)
-    }
-
     override fun getCryptoVersion(context: Context, longFormat: Boolean): String {
         return if (longFormat) olmManager.getDetailedVersion(context) else olmManager.version
     }
@@ -678,7 +667,12 @@ internal class DefaultCryptoService @Inject constructor(
 
     override fun discardOutboundSession(roomId: String) {
         cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
-            roomEncryptorsStore.get(roomId)?.discardSessionKey()
+            val roomEncryptor = roomEncryptorsStore.get(roomId)
+            if (roomEncryptor is IMXGroupEncryption) {
+                roomEncryptor.discardSessionKey()
+            } else {
+                Timber.e("## CRYPTO | discardOutboundSession() for:$roomId: Unable to handle IMXGroupEncryption")
+            }
         }
     }
 
@@ -714,7 +708,7 @@ internal class DefaultCryptoService @Inject constructor(
      */
     @Throws(MXCryptoError::class)
     private fun internalDecryptEvent(event: Event, timeline: String): MXEventDecryptionResult {
-       return eventDecryptor.decryptEvent(event, timeline)
+        return eventDecryptor.decryptEvent(event, timeline)
     }
 
     /**
@@ -1301,6 +1295,43 @@ internal class DefaultCryptoService @Inject constructor(
         cryptoStore.logDbUsageInfo()
     }
 
+    override fun prepareToEncrypt(roomId: String, callback: MatrixCallback<Unit>) {
+        cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
+            Timber.d("## CRYPTO | prepareToEncrypt() : Check room members up to date")
+            // Ensure to load all room members
+            try {
+                loadRoomMembersTask.execute(LoadRoomMembersTask.Params(roomId))
+            } catch (failure: Throwable) {
+                Timber.e("## CRYPTO | prepareToEncrypt() : Failed to load room members")
+                callback.onFailure(failure)
+                return@launch
+            }
+
+            val userIds = getRoomUserIds(roomId)
+            val alg = roomEncryptorsStore.get(roomId)
+                    ?: getEncryptionAlgorithm(roomId)
+                            ?.let { setEncryptionInRoom(roomId, it, false, userIds) }
+                            ?.let { roomEncryptorsStore.get(roomId) }
+
+            if (alg == null) {
+                val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON, MXCryptoError.NO_MORE_ALGORITHM_REASON)
+                Timber.e("## CRYPTO | prepareToEncrypt() : $reason")
+                callback.onFailure(IllegalArgumentException("Missing algorithm"))
+                return@launch
+            }
+
+            runCatching {
+                (alg as? IMXGroupEncryption)?.preshareKey(userIds)
+            }.fold(
+                    { callback.onSuccess(Unit) },
+                    {
+                        Timber.e("## CRYPTO | prepareToEncrypt() failed.")
+                        callback.onFailure(it)
+                    }
+            )
+        }
+    }
+
     /* ==========================================================================================
      * For test only
      * ========================================================================================== */
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt
index 92b77288909132f34d5b37724f2c937a7c7689ad..32324896fa3acd7868cb3cfadd83e4003f9e95df 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt
@@ -105,7 +105,7 @@ internal class EventDecryptor @Inject constructor(
                 try {
                     return alg.decryptEvent(event, timeline)
                 } catch (mxCryptoError: MXCryptoError) {
-                    Timber.d("## CRYPTO | internalDecryptEvent : Failed to decrypt ${event.eventId} reason: $mxCryptoError")
+                    Timber.v("## CRYPTO | internalDecryptEvent : Failed to decrypt ${event.eventId} reason: $mxCryptoError")
                     if (algorithm == MXCRYPTO_ALGORITHM_OLM) {
                         if (mxCryptoError is MXCryptoError.Base
                                 && mxCryptoError.errorType == MXCryptoError.ErrorType.BAD_ENCRYPTED_MESSAGE) {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt
index c075c90eb9f09718941be100bab94b54e4673015..4a0a274f4f369e825d194b1f71fd261d021000ee 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt
@@ -28,6 +28,7 @@ import org.matrix.android.sdk.api.session.crypto.keyshare.GossipingRequestListen
 import org.matrix.android.sdk.api.session.events.model.Event
 import org.matrix.android.sdk.api.session.events.model.EventType
 import org.matrix.android.sdk.api.session.events.model.toModel
+import org.matrix.android.sdk.internal.crypto.algorithms.IMXGroupEncryption
 import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding
 import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey
 import org.matrix.android.sdk.internal.crypto.model.rest.GossipingDefaultContent
@@ -290,12 +291,16 @@ internal class IncomingGossipingRequestManager @Inject constructor(
                 .also { cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED) }
 
         cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
-            val isSuccess = roomEncryptor.reshareKey(sessionId, userId, deviceId, senderKey)
+            if (roomEncryptor is IMXGroupEncryption) {
+                val isSuccess = roomEncryptor.reshareKey(sessionId, userId, deviceId, senderKey)
 
-            if (isSuccess) {
-                cryptoStore.updateGossipingRequestState(request, GossipingRequestState.ACCEPTED)
+                if (isSuccess) {
+                    cryptoStore.updateGossipingRequestState(request, GossipingRequestState.ACCEPTED)
+                } else {
+                    cryptoStore.updateGossipingRequestState(request, GossipingRequestState.UNABLE_TO_PROCESS)
+                }
             } else {
-                cryptoStore.updateGossipingRequestState(request, GossipingRequestState.UNABLE_TO_PROCESS)
+                Timber.e("## CRYPTO | handleKeyRequestFromOtherUser() from:$userId: Unable to handle IMXGroupEncryption.reshareKey for $alg")
             }
         }
         cryptoStore.updateGossipingRequestState(request, GossipingRequestState.RE_REQUESTED)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXEncrypting.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXEncrypting.kt
index fc3ea08a2160bfb8126196e8b677a4c6db73f081..5294429198a81868ee0914bc824466afe89321a4 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXEncrypting.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXEncrypting.kt
@@ -32,34 +32,4 @@ internal interface IMXEncrypting {
      * @return the encrypted content
      */
     suspend fun encryptEventContent(eventContent: Content, eventType: String, userIds: List<String>): Content
-
-    /**
-     * In Megolm, each recipient maintains a record of the ratchet value which allows
-     * them to decrypt any messages sent in the session after the corresponding point
-     * in the conversation. If this value is compromised, an attacker can similarly
-     * decrypt past messages which were encrypted by a key derived from the
-     * compromised or subsequent ratchet values. This gives 'partial' forward
-     * secrecy.
-     *
-     * To mitigate this issue, the application should offer the user the option to
-     * discard historical conversations, by winding forward any stored ratchet values,
-     * or discarding sessions altogether.
-     */
-    fun discardSessionKey()
-
-    /**
-     * Re-shares a session key with devices if the key has already been
-     * sent to them.
-     *
-     * @param sessionId The id of the outbound session to share.
-     * @param userId The id of the user who owns the target device.
-     * @param deviceId The id of the target device.
-     * @param senderKey The key of the originating device for the session.
-     *
-     * @return true in case of success
-     */
-    suspend fun reshareKey(sessionId: String,
-                           userId: String,
-                           deviceId: String,
-                           senderKey: String): Boolean
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXGroupEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXGroupEncryption.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1fd5061a65c8e1b99c8aca3c064d153c4275a029
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXGroupEncryption.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.crypto.algorithms
+
+internal interface IMXGroupEncryption {
+
+    /**
+     * In Megolm, each recipient maintains a record of the ratchet value which allows
+     * them to decrypt any messages sent in the session after the corresponding point
+     * in the conversation. If this value is compromised, an attacker can similarly
+     * decrypt past messages which were encrypted by a key derived from the
+     * compromised or subsequent ratchet values. This gives 'partial' forward
+     * secrecy.
+     *
+     * To mitigate this issue, the application should offer the user the option to
+     * discard historical conversations, by winding forward any stored ratchet values,
+     * or discarding sessions altogether.
+     */
+    fun discardSessionKey()
+
+    suspend fun preshareKey(userIds: List<String>)
+
+    /**
+     * Re-shares a session key with devices if the key has already been
+     * sent to them.
+     *
+     * @param sessionId The id of the outbound session to share.
+     * @param userId The id of the user who owns the target device.
+     * @param deviceId The id of the target device.
+     * @param senderKey The key of the originating device for the session.
+     *
+     * @return true in case of success
+     */
+    suspend fun reshareKey(sessionId: String,
+                           userId: String,
+                           deviceId: String,
+                           senderKey: String): Boolean
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt
index fa8acafb83fabd4dcaffb55b8018bc79a4da536d..6b91c0b859adf52242d2b77713f7fa49d934bbea 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt
@@ -18,8 +18,6 @@ package org.matrix.android.sdk.internal.crypto.algorithms.megolm
 
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
-import org.matrix.android.sdk.api.MatrixCallback
-import org.matrix.android.sdk.api.auth.data.Credentials
 import org.matrix.android.sdk.api.session.crypto.MXCryptoError
 import org.matrix.android.sdk.api.session.events.model.Content
 import org.matrix.android.sdk.api.session.events.model.Event
@@ -30,6 +28,7 @@ import org.matrix.android.sdk.internal.crypto.MXOlmDevice
 import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevicesAction
 import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter
 import org.matrix.android.sdk.internal.crypto.algorithms.IMXEncrypting
+import org.matrix.android.sdk.internal.crypto.algorithms.IMXGroupEncryption
 import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService
 import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
 import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
@@ -39,8 +38,6 @@ import org.matrix.android.sdk.internal.crypto.model.forEach
 import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository
 import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
 import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask
-import org.matrix.android.sdk.internal.task.TaskExecutor
-import org.matrix.android.sdk.internal.task.configureWith
 import org.matrix.android.sdk.internal.util.JsonCanonicalizer
 import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
 import org.matrix.android.sdk.internal.util.convertToUTF8
@@ -54,14 +51,14 @@ internal class MXMegolmEncryption(
         private val cryptoStore: IMXCryptoStore,
         private val deviceListManager: DeviceListManager,
         private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
-        private val credentials: Credentials,
+        private val userId: String,
+        private val deviceId: String,
         private val sendToDeviceTask: SendToDeviceTask,
         private val messageEncrypter: MessageEncrypter,
         private val warnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository,
-        private val taskExecutor: TaskExecutor,
         private val coroutineDispatchers: MatrixCoroutineDispatchers,
         private val cryptoCoroutineScope: CoroutineScope
-) : IMXEncrypting {
+) : IMXEncrypting, IMXGroupEncryption {
 
     // OutboundSessionInfo. Null if we haven't yet started setting one up. Note
     // that even if this is non-null, it may not be ready for use (in which
@@ -93,6 +90,7 @@ internal class MXMegolmEncryption(
                     // annoyingly we have to serialize again the saved outbound session to store message index :/
                     // if not we would see duplicate message index errors
                     olmDevice.storeOutboundGroupSessionForRoom(roomId, outboundSession.sessionId)
+                    Timber.v("## CRYPTO | encryptEventContent: Finished in ${System.currentTimeMillis() - ts} millis")
                 }
     }
 
@@ -117,6 +115,16 @@ internal class MXMegolmEncryption(
         olmDevice.discardOutboundGroupSessionForRoom(roomId)
     }
 
+    override suspend fun preshareKey(userIds: List<String>) {
+        val ts = System.currentTimeMillis()
+        Timber.v("## CRYPTO | preshareKey : getDevicesInRoom")
+        val devices = getDevicesInRoom(userIds)
+        val outboundSession = ensureOutboundSession(devices.allowedDevices)
+
+        notifyWithheldForSession(devices.withHeldDevices, outboundSession)
+
+        Timber.v("## CRYPTO | preshareKey ${System.currentTimeMillis() - ts} millis")
+    }
     /**
      * Prepare a new session.
      *
@@ -252,7 +260,7 @@ internal class MXMegolmEncryption(
 
                     continue
                 }
-                Timber.i("## CRYPTO | shareUserDevicesKey() : Sharing keys with device $userId:$deviceID")
+                Timber.i("## CRYPTO | shareUserDevicesKey() : Add to share keys contentMap for $userId:$deviceID")
                 contentMap.setObject(userId, deviceID, messageEncrypter.encryptMessage(payload, listOf(sessionResult.deviceInfo)))
                 haveTargets = true
             }
@@ -263,12 +271,14 @@ internal class MXMegolmEncryption(
         // attempted to share with) rather than the contentMap (those we did
         // share with), because we don't want to try to claim a one-time-key
         // for dead devices on every message.
+        val gossipingEventBuffer = arrayListOf<Event>()
         for ((userId, devicesToShareWith) in devicesByUser) {
             for ((deviceId) in devicesToShareWith) {
                 session.sharedWithHelper.markedSessionAsShared(userId, deviceId, chainIndex)
-                cryptoStore.saveGossipingEvent(Event(
+                gossipingEventBuffer.add(
+                        Event(
                         type = EventType.ROOM_KEY,
-                        senderId = credentials.userId,
+                        senderId = this.userId,
                         content = submap.apply {
                             this["session_key"] = ""
                             // we add a fake key for trail
@@ -278,6 +288,8 @@ internal class MXMegolmEncryption(
             }
         }
 
+        cryptoStore.saveGossipingEvents(gossipingEventBuffer)
+
         if (haveTargets) {
             t0 = System.currentTimeMillis()
             Timber.i("## CRYPTO | shareUserDevicesKey() ${session.sessionId} : has target")
@@ -294,8 +306,11 @@ internal class MXMegolmEncryption(
         }
     }
 
-    private fun notifyKeyWithHeld(targets: List<UserDevice>, sessionId: String, senderKey: String?, code: WithHeldCode) {
-        Timber.i("## CRYPTO | notifyKeyWithHeld() :sending withheld key for $targets session:$sessionId ")
+    private suspend fun notifyKeyWithHeld(targets: List<UserDevice>,
+                                          sessionId: String,
+                                          senderKey: String?,
+                                          code: WithHeldCode) {
+        Timber.i("## CRYPTO | notifyKeyWithHeld() :sending withheld key for $targets session:$sessionId and code $code")
         val withHeldContent = RoomKeyWithHeldContent(
                 roomId = roomId,
                 senderKey = senderKey,
@@ -311,13 +326,11 @@ internal class MXMegolmEncryption(
                     }
                 }
         )
-        sendToDeviceTask.configureWith(params) {
-            callback = object : MatrixCallback<Unit> {
-                override fun onFailure(failure: Throwable) {
-                    Timber.e("## CRYPTO | notifyKeyWithHeld() : Failed to notify withheld key for $targets session: $sessionId ")
-                }
-            }
-        }.executeBy(taskExecutor)
+        try {
+            sendToDeviceTask.execute(params)
+        } catch (failure: Throwable) {
+            Timber.e("## CRYPTO | notifyKeyWithHeld() : Failed to notify withheld key for $targets session: $sessionId ")
+        }
     }
 
     /**
@@ -343,7 +356,7 @@ internal class MXMegolmEncryption(
 
         // Include our device ID so that recipients can send us a
         // m.new_device message if they don't have our session key.
-        map["device_id"] = credentials.deviceId!!
+        map["device_id"] = deviceId
         session.useCount++
         return map
     }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryptionFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryptionFactory.kt
index f0cc15fb63cc89c99e79bb8e6dbfa5cf0b5c2182..9f6312ea97804478bdd3d8cdbaf1e80ab4dead1e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryptionFactory.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryptionFactory.kt
@@ -17,7 +17,6 @@
 package org.matrix.android.sdk.internal.crypto.algorithms.megolm
 
 import kotlinx.coroutines.CoroutineScope
-import org.matrix.android.sdk.api.auth.data.Credentials
 import org.matrix.android.sdk.internal.crypto.DeviceListManager
 import org.matrix.android.sdk.internal.crypto.MXOlmDevice
 import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevicesAction
@@ -26,7 +25,8 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupServic
 import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository
 import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
 import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask
-import org.matrix.android.sdk.internal.task.TaskExecutor
+import org.matrix.android.sdk.internal.di.DeviceId
+import org.matrix.android.sdk.internal.di.UserId
 import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
 import javax.inject.Inject
 
@@ -36,29 +36,29 @@ internal class MXMegolmEncryptionFactory @Inject constructor(
         private val cryptoStore: IMXCryptoStore,
         private val deviceListManager: DeviceListManager,
         private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
-        private val credentials: Credentials,
+        @UserId private val userId: String,
+        @DeviceId private val deviceId: String?,
         private val sendToDeviceTask: SendToDeviceTask,
         private val messageEncrypter: MessageEncrypter,
         private val warnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository,
-        private val taskExecutor: TaskExecutor,
         private val coroutineDispatchers: MatrixCoroutineDispatchers,
         private val cryptoCoroutineScope: CoroutineScope) {
 
     fun create(roomId: String): MXMegolmEncryption {
         return MXMegolmEncryption(
-                roomId,
-                olmDevice,
-                defaultKeysBackupService,
-                cryptoStore,
-                deviceListManager,
-                ensureOlmSessionsForDevicesAction,
-                credentials,
-                sendToDeviceTask,
-                messageEncrypter,
-                warnOnUnknownDevicesRepository,
-                taskExecutor,
-                coroutineDispatchers,
-                cryptoCoroutineScope
+                roomId = roomId,
+                olmDevice = olmDevice,
+                defaultKeysBackupService = defaultKeysBackupService,
+                cryptoStore = cryptoStore,
+                deviceListManager = deviceListManager,
+                ensureOlmSessionsForDevicesAction = ensureOlmSessionsForDevicesAction,
+                userId = userId,
+                deviceId = deviceId!!,
+                sendToDeviceTask = sendToDeviceTask,
+                messageEncrypter = messageEncrypter,
+                warnOnUnknownDevicesRepository = warnOnUnknownDevicesRepository,
+                coroutineDispatchers = coroutineDispatchers,
+                cryptoCoroutineScope = cryptoCoroutineScope
         )
     }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt
index 9acc9bc1b2e3043a2f88f8fcddb9f2a782f3d16e..65f78e11f0291b0f4b8a29f59da2b480cc1c0658 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt
@@ -76,13 +76,4 @@ internal class MXOlmEncryption(
         deviceListManager.downloadKeys(users, false)
         ensureOlmSessionsForUsersAction.handle(users)
     }
-
-    override fun discardSessionKey() {
-        // No need for olm
-    }
-
-    override suspend fun reshareKey(sessionId: String, userId: String, deviceId: String, senderKey: String): Boolean {
-        // No need for olm
-        return false
-    }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/Extensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/Extensions.kt
index e494cb5b3136fd90b50830872ec64116d1bcfc5c..cf2d6aa2693a4e5561f59e8e8ba58172b9990c1f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/Extensions.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/Extensions.kt
@@ -21,11 +21,11 @@ import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
 import org.matrix.android.sdk.internal.util.JsonCanonicalizer
 import timber.log.Timber
 
-fun CryptoDeviceInfo.canonicalSignable(): String {
+internal fun CryptoDeviceInfo.canonicalSignable(): String {
     return JsonCanonicalizer.getCanonicalJson(Map::class.java, signalableJSONDictionary())
 }
 
-fun CryptoCrossSigningKey.canonicalSignable(): String {
+internal fun CryptoCrossSigningKey.canonicalSignable(): String {
     return JsonCanonicalizer.getCanonicalJson(Map::class.java, signalableJSONDictionary())
 }
 
@@ -40,7 +40,7 @@ fun String.fromBase64(): ByteArray {
 /**
  * Decode the base 64. Return null in case of bad format. Should be used when parsing received data from external source
  */
-fun String.fromBase64Safe(): ByteArray? {
+internal fun String.fromBase64Safe(): ByteArray? {
     return try {
         Base64.decode(this, Base64.DEFAULT)
     } catch (throwable: Throwable) {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoCrossSigningKey.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoCrossSigningKey.kt
index 202aa55624fa53ec9f00b6d985081626ea966144..606d2e3fc0c99a01ddb666336e62c36ab079d060 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoCrossSigningKey.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoCrossSigningKey.kt
@@ -63,7 +63,7 @@ data class CryptoCrossSigningKey(
         )
     }
 
-    data class Builder(
+    internal data class Builder(
             val userId: String,
             val usage: KeyUsage,
             private var base64Pkey: String? = null,
@@ -97,7 +97,7 @@ data class CryptoCrossSigningKey(
     }
 }
 
-enum class KeyUsage(val value: String) {
+internal enum class KeyUsage(val value: String) {
     MASTER("master"),
     SELF_SIGNING("self_signing"),
     USER_SIGNING("user_signing")
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt
index 369a4976c9683a7799f8809e44584a8896bfe97c..b9213ba758297549950996c724cdfb279e5f87bb 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt
@@ -83,6 +83,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity
 import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields
 import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntity
 import org.matrix.android.sdk.internal.crypto.store.db.model.createPrimaryKey
+import org.matrix.android.sdk.internal.crypto.store.db.model.deleteOnCascade
 import org.matrix.android.sdk.internal.crypto.store.db.query.create
 import org.matrix.android.sdk.internal.crypto.store.db.query.delete
 import org.matrix.android.sdk.internal.crypto.store.db.query.get
@@ -94,6 +95,7 @@ import org.matrix.android.sdk.internal.di.CryptoDatabase
 import org.matrix.android.sdk.internal.di.DeviceId
 import org.matrix.android.sdk.internal.di.MoshiProvider
 import org.matrix.android.sdk.internal.di.UserId
+import org.matrix.android.sdk.internal.extensions.clearWith
 import org.matrix.android.sdk.internal.session.SessionScope
 import org.matrix.olm.OlmAccount
 import org.matrix.olm.OlmException
@@ -293,7 +295,7 @@ internal class RealmCryptoStore @Inject constructor(
                                 realm.insertOrUpdate(entity)
                             }
                             // Ensure all other devices are deleted
-                            u.devices.deleteAllFromRealm()
+                            u.devices.clearWith { it.deleteOnCascade() }
                             u.devices.addAll(new)
                         }
             }
@@ -309,7 +311,7 @@ internal class RealmCryptoStore @Inject constructor(
                     .let { userEntity ->
                         if (masterKey == null || selfSigningKey == null) {
                             // The user has disabled cross signing?
-                            userEntity.crossSigningInfoEntity?.deleteFromRealm()
+                            userEntity.crossSigningInfoEntity?.deleteOnCascade()
                             userEntity.crossSigningInfoEntity = null
                         } else {
                             var shouldResetMyDevicesLocalTrust = false
@@ -1633,7 +1635,7 @@ internal class RealmCryptoStore @Inject constructor(
         } else {
             // Just override existing, caller should check and untrust id needed
             val existing = CrossSigningInfoEntity.getOrCreate(realm, userId)
-            existing.crossSigningKeys.deleteAllFromRealm()
+            existing.crossSigningKeys.clearWith { it.deleteOnCascade() }
             existing.crossSigningKeys.addAll(
                     info.crossSigningKeys.map {
                         crossSigningKeysMapper.map(it)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CrossSigningInfoEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CrossSigningInfoEntity.kt
index fdd3e947545300f3a4f0862a0be35fce12d20a44..8599c972e9cedeb7d17c76928a6a25705526f178 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CrossSigningInfoEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CrossSigningInfoEntity.kt
@@ -16,10 +16,11 @@
 
 package org.matrix.android.sdk.internal.crypto.store.db.model
 
-import org.matrix.android.sdk.internal.crypto.model.KeyUsage
 import io.realm.RealmList
 import io.realm.RealmObject
 import io.realm.annotations.PrimaryKey
+import org.matrix.android.sdk.internal.crypto.model.KeyUsage
+import org.matrix.android.sdk.internal.extensions.clearWith
 
 internal open class CrossSigningInfoEntity(
         @PrimaryKey
@@ -56,3 +57,8 @@ internal open class CrossSigningInfoEntity(
         info?.let { crossSigningKeys.add(it) }
     }
 }
+
+internal fun CrossSigningInfoEntity.deleteOnCascade() {
+    crossSigningKeys.clearWith { it.deleteOnCascade() }
+    deleteFromRealm()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/DeviceInfoEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/DeviceInfoEntity.kt
index 571b9bb05f3d02d9ab57e9526333b36cb8fd1d66..61870ec486a52ca403a83a20e03e0c220a79e157 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/DeviceInfoEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/DeviceInfoEntity.kt
@@ -47,3 +47,8 @@ internal open class DeviceInfoEntity(
 
     companion object
 }
+
+internal fun DeviceInfoEntity.deleteOnCascade() {
+    trustLevelEntity?.deleteFromRealm()
+    deleteFromRealm()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/KeyInfoEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/KeyInfoEntity.kt
index 8f2357223ed686881ee79ff8a9380e42a2bf1f91..9133413589c83a7e2ce68c707a62799be2fac5b6 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/KeyInfoEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/KeyInfoEntity.kt
@@ -30,3 +30,8 @@ internal open class KeyInfoEntity(
         var signatures: String? = null,
         var trustLevelEntity: TrustLevelEntity? = null
 ) : RealmObject()
+
+internal fun KeyInfoEntity.deleteOnCascade() {
+    trustLevelEntity?.deleteFromRealm()
+    deleteFromRealm()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/UserEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/UserEntity.kt
index 52c30a27cc49d3fce3a8f4b269c7aec355b1805d..df9482bf9615cc9196566cef5d18515da0ec2b35 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/UserEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/UserEntity.kt
@@ -19,13 +19,20 @@ package org.matrix.android.sdk.internal.crypto.store.db.model
 import io.realm.RealmList
 import io.realm.RealmObject
 import io.realm.annotations.PrimaryKey
+import org.matrix.android.sdk.internal.extensions.clearWith
 
 internal open class UserEntity(
         @PrimaryKey var userId: String? = null,
         var devices: RealmList<DeviceInfoEntity> = RealmList(),
         var crossSigningInfoEntity: CrossSigningInfoEntity? = null,
-        var deviceTrackingStatus: Int = 0)
-    : RealmObject() {
+        var deviceTrackingStatus: Int = 0
+) : RealmObject() {
 
     companion object
 }
+
+internal fun UserEntity.deleteOnCascade() {
+    devices.clearWith { it.deleteOnCascade() }
+    crossSigningInfoEntity?.deleteOnCascade()
+    deleteFromRealm()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/UserEntitiesQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/UserEntitiesQueries.kt
index a1f8bd72621da4aae1da62fa634c4e99a83296ac..5a3b8e53975c4f45891b7b8d4ddd1915804a4366 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/UserEntitiesQueries.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/UserEntitiesQueries.kt
@@ -16,11 +16,12 @@
 
 package org.matrix.android.sdk.internal.crypto.store.db.query
 
-import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity
-import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields
 import io.realm.Realm
 import io.realm.kotlin.createObject
 import io.realm.kotlin.where
+import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity
+import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields
+import org.matrix.android.sdk.internal.crypto.store.db.model.deleteOnCascade
 
 /**
  * Get or create a user
@@ -39,5 +40,5 @@ internal fun UserEntity.Companion.delete(realm: Realm, userId: String) {
     realm.where<UserEntity>()
             .equalTo(UserEntityFields.USER_ID, userId)
             .findFirst()
-            ?.deleteFromRealm()
+            ?.deleteOnCascade()
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceTask.kt
index ff25ac0f66d16e5d0021ba92a766f82833bbe234..61596bb5b6a58c30c32160d413dee4175ca55e3a 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceTask.kt
@@ -47,12 +47,16 @@ internal class DefaultDeleteDeviceTask @Inject constructor(
             }
         } catch (throwable: Throwable) {
             if (params.userInteractiveAuthInterceptor == null
-                    || !handleUIA(throwable, params.userInteractiveAuthInterceptor) { auth ->
-                        execute(params.copy(userAuthParam = auth))
-                    }
+                    || !handleUIA(
+                            failure = throwable,
+                            interceptor = params.userInteractiveAuthInterceptor,
+                            retryBlock = { authUpdate ->
+                                execute(params.copy(userAuthParam = authUpdate))
+                            }
+                    )
             ) {
                 Timber.d("## UIA: propagate failure")
-                throw  throwable
+                throw throwable
             }
         }
     }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceWithUserPasswordTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceWithUserPasswordTask.kt
deleted file mode 100644
index dc0077425ed58b6cf89650fc54ca13677cce5e3d..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceWithUserPasswordTask.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2020 The Matrix.org Foundation C.I.C.
- *
- * 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 org.matrix.android.sdk.internal.crypto.tasks
-
-import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
-import org.matrix.android.sdk.internal.crypto.api.CryptoApi
-import org.matrix.android.sdk.internal.crypto.model.rest.DeleteDeviceParams
-import org.matrix.android.sdk.api.auth.UserPasswordAuth
-import org.matrix.android.sdk.internal.di.UserId
-import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
-import org.matrix.android.sdk.internal.network.executeRequest
-import org.matrix.android.sdk.internal.task.Task
-import javax.inject.Inject
-
-internal interface DeleteDeviceWithUserPasswordTask : Task<DeleteDeviceWithUserPasswordTask.Params, Unit> {
-    data class Params(
-            val deviceId: String,
-            val authSession: String?,
-            val password: String
-    )
-}
-
-internal class DefaultDeleteDeviceWithUserPasswordTask @Inject constructor(
-        private val cryptoApi: CryptoApi,
-        @UserId private val userId: String,
-        private val globalErrorReceiver: GlobalErrorReceiver
-) : DeleteDeviceWithUserPasswordTask {
-
-    override suspend fun execute(params: DeleteDeviceWithUserPasswordTask.Params) {
-        return executeRequest(globalErrorReceiver) {
-            apiCall = cryptoApi.deleteDevice(params.deviceId,
-                    DeleteDeviceParams(
-                            auth = UserPasswordAuth(
-                                    type = LoginFlowTypes.PASSWORD,
-                                    session = params.authSession,
-                                    user = userId,
-                                    password = params.password
-                            ).asMap()
-                    )
-            )
-        }
-    }
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt
index 56b267decdcc9d1c2231770231551f65da40528b..627352f5680f2193a7b5452518966d90edf5da83 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt
@@ -45,7 +45,7 @@ internal class DefaultEncryptEventTask @Inject constructor(
         // don't want to wait for any query
         // if (!params.crypto.isRoomEncrypted(params.roomId)) return params.event
         val localEvent = params.event
-        if (localEvent.eventId == null) {
+        if (localEvent.eventId == null || localEvent.type == null) {
             throw IllegalArgumentException()
         }
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt
index ef31130f55c48f862f2502b1baeb26735ed1e683..f8a8354e482e0c4ad2aa3b5c144c8e767545d541 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt
@@ -126,11 +126,16 @@ internal class DefaultInitializeCrossSigningTask @Inject constructor(
                 uploadSigningKeysTask.execute(uploadSigningKeysParams)
             } catch (failure: Throwable) {
                 if (params.interactiveAuthInterceptor == null
-                        || !handleUIA(failure, params.interactiveAuthInterceptor) { authUpdate ->
-                            uploadSigningKeysTask.execute(uploadSigningKeysParams.copy(userAuthParam = authUpdate))
-                        }) {
+                        || !handleUIA(
+                                failure = failure,
+                                interceptor = params.interactiveAuthInterceptor,
+                                retryBlock = { authUpdate ->
+                                    uploadSigningKeysTask.execute(uploadSigningKeysParams.copy(userAuthParam = authUpdate))
+                                }
+                        )
+                ) {
                     Timber.d("## UIA: propagate failure")
-                    throw  failure
+                    throw failure
                 }
             }
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt
index b772bfbce227e365833162ee89f097d88613f6f9..573f2c3a5495a414a8971045b4fe1630b167ec72 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt
@@ -51,14 +51,13 @@ internal class DefaultSendEventTask @Inject constructor(
 
             val event = handleEncryption(params)
             val localId = event.eventId!!
-
             localEchoRepository.updateSendState(localId, params.event.roomId, SendState.SENDING)
             val executeRequest = executeRequest<SendResponse>(globalErrorReceiver) {
                 apiCall = roomAPI.send(
                         localId,
                         roomId = event.roomId ?: "",
                         content = event.content,
-                        eventType = event.type
+                        eventType = event.type ?: ""
                 )
             }
             localEchoRepository.updateSendState(localId, params.event.roomId, SendState.SENT)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt
index c39dfb101668ed56ad6ace386a61395ac36de769..ab125135bb393392b4b8cf3d1329c76f34ff6c14 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt
@@ -50,7 +50,7 @@ internal class DefaultSendVerificationMessageTask @Inject constructor(
                         localId,
                         roomId = event.roomId ?: "",
                         content = event.content,
-                        eventType = event.type
+                        eventType = event.type ?: ""
                 )
             }
             localEchoRepository.updateSendState(localId, event.roomId, SendState.SENT)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tools/Tools.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tools/Tools.kt
index 4c1e896a2156979b194dfaf885fe39501c05dfd9..052b3f4e7272fc69d3459134dcc99b70e359996d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tools/Tools.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tools/Tools.kt
@@ -21,7 +21,7 @@ import org.matrix.olm.OlmPkEncryption
 import org.matrix.olm.OlmPkSigning
 import org.matrix.olm.OlmUtility
 
-fun <T> withOlmEncryption(block: (OlmPkEncryption) -> T): T {
+internal fun <T> withOlmEncryption(block: (OlmPkEncryption) -> T): T {
     val olmPkEncryption = OlmPkEncryption()
     try {
         return block(olmPkEncryption)
@@ -30,7 +30,7 @@ fun <T> withOlmEncryption(block: (OlmPkEncryption) -> T): T {
     }
 }
 
-fun <T> withOlmDecryption(block: (OlmPkDecryption) -> T): T {
+internal fun <T> withOlmDecryption(block: (OlmPkDecryption) -> T): T {
     val olmPkDecryption = OlmPkDecryption()
     try {
         return block(olmPkDecryption)
@@ -39,7 +39,7 @@ fun <T> withOlmDecryption(block: (OlmPkDecryption) -> T): T {
     }
 }
 
-fun <T> withOlmSigning(block: (OlmPkSigning) -> T): T {
+internal fun <T> withOlmSigning(block: (OlmPkSigning) -> T): T {
     val olmPkSigning = OlmPkSigning()
     try {
         return block(olmPkSigning)
@@ -48,7 +48,7 @@ fun <T> withOlmSigning(block: (OlmPkSigning) -> T): T {
     }
 }
 
-fun <T> withOlmUtility(block: (OlmUtility) -> T): T {
+internal fun <T> withOlmUtility(block: (OlmUtility) -> T): T {
     val olmUtility = OlmUtility()
     try {
         return block(olmUtility)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationStateExt.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationStateExt.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0617f32c2424b7637796cc91b488f58cf82adfac
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationStateExt.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.crypto.verification
+
+import org.matrix.android.sdk.api.crypto.VerificationState
+import org.matrix.android.sdk.api.crypto.isCanceled
+
+// State transition with control
+internal fun VerificationState?.toState(newState: VerificationState): VerificationState {
+    // Cancel is always prioritary ?
+    // Eg id i found that mac or keys mismatch and send a cancel and the other send a done, i have to
+    // consider as canceled
+    if (newState.isCanceled()) {
+        return newState
+    }
+    // never move out of cancel
+    if (this?.isCanceled() == true) {
+        return this
+    }
+    return newState
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessage.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessage.kt
index a447e659f5943012b8bd3c90452fe404b69873c8..ad490bcd277febb624a2feb19ae189a4339efcac 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessage.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessage.kt
@@ -24,7 +24,6 @@ import androidx.work.WorkInfo
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
-import org.matrix.android.sdk.R
 import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
 import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest
 import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
@@ -46,23 +45,16 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageVerification
 import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
 import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE
 import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS
-import org.matrix.android.sdk.internal.di.DeviceId
-import org.matrix.android.sdk.internal.di.SessionId
-import org.matrix.android.sdk.internal.di.UserId
 import org.matrix.android.sdk.internal.di.WorkManagerProvider
 import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory
-import org.matrix.android.sdk.internal.task.TaskExecutor
-import org.matrix.android.sdk.internal.util.StringProvider
 import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker
 import org.matrix.android.sdk.internal.worker.WorkerParamsFactory
 import timber.log.Timber
 import java.util.UUID
 import java.util.concurrent.TimeUnit
-import javax.inject.Inject
 
 internal class VerificationTransportRoomMessage(
         private val workManagerProvider: WorkManagerProvider,
-        private val stringProvider: StringProvider,
         private val sessionId: String,
         private val userId: String,
         private val userDeviceId: String?,
@@ -167,7 +159,8 @@ internal class VerificationTransportRoomMessage(
         )
 
         val info = MessageVerificationRequestContent(
-                body = stringProvider.getString(R.string.key_verification_request_fallback_message, userId),
+                body = "$userId is requesting to verify your key, but your client does not support in-chat key verification." +
+                        " You will need to use legacy key verification to verify keys.",
                 fromDevice = validInfo.fromDevice,
                 toUserId = otherUserId,
                 timestamp = validInfo.timestamp,
@@ -387,29 +380,3 @@ internal class VerificationTransportRoomMessage(
         Timber.w("## SAS ignored verification ready with methods: ${keyReq.methods}")
     }
 }
-
-internal class VerificationTransportRoomMessageFactory @Inject constructor(
-        private val workManagerProvider: WorkManagerProvider,
-        private val stringProvider: StringProvider,
-        @SessionId
-        private val sessionId: String,
-        @UserId
-        private val userId: String,
-        @DeviceId
-        private val deviceId: String?,
-        private val localEchoEventFactory: LocalEchoEventFactory,
-        private val taskExecutor: TaskExecutor
-) {
-
-    fun createTransport(roomId: String, tx: DefaultVerificationTransaction?): VerificationTransportRoomMessage {
-        return VerificationTransportRoomMessage(workManagerProvider,
-                stringProvider,
-                sessionId,
-                userId,
-                deviceId,
-                roomId,
-                localEchoEventFactory,
-                tx,
-                taskExecutor.executorScope)
-    }
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessageFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessageFactory.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f89127273b8d0ced5ada3d5277155bf986290425
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessageFactory.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.crypto.verification
+
+import org.matrix.android.sdk.internal.di.DeviceId
+import org.matrix.android.sdk.internal.di.SessionId
+import org.matrix.android.sdk.internal.di.UserId
+import org.matrix.android.sdk.internal.di.WorkManagerProvider
+import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory
+import org.matrix.android.sdk.internal.task.TaskExecutor
+import javax.inject.Inject
+
+internal class VerificationTransportRoomMessageFactory @Inject constructor(
+        private val workManagerProvider: WorkManagerProvider,
+        @SessionId
+        private val sessionId: String,
+        @UserId
+        private val userId: String,
+        @DeviceId
+        private val deviceId: String?,
+        private val localEchoEventFactory: LocalEchoEventFactory,
+        private val taskExecutor: TaskExecutor
+) {
+
+    fun createTransport(roomId: String, tx: DefaultVerificationTransaction?): VerificationTransportRoomMessage {
+        return VerificationTransportRoomMessage(workManagerProvider,
+                sessionId,
+                userId,
+                deviceId,
+                roomId,
+                localEchoEventFactory,
+                tx,
+                taskExecutor.executorScope)
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt
index 5fd1c5d650ef5cc037a975ed0fa60eed5a7091a3..0dbbe656c71bb7fac8e473c4e8ee8ab04bba1d7a 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt
@@ -16,8 +16,8 @@
 package org.matrix.android.sdk.internal.crypto.verification
 
 import org.matrix.android.sdk.api.MatrixCallback
-import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest
 import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
+import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest
 import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
 import org.matrix.android.sdk.api.session.events.model.EventType
 import org.matrix.android.sdk.api.session.room.model.message.MessageType
@@ -33,11 +33,9 @@ import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationStart
 import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE
 import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS
 import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask
-import org.matrix.android.sdk.internal.di.DeviceId
 import org.matrix.android.sdk.internal.task.TaskExecutor
 import org.matrix.android.sdk.internal.task.configureWith
 import timber.log.Timber
-import javax.inject.Inject
 
 internal class VerificationTransportToDevice(
         private var tx: DefaultVerificationTransaction?,
@@ -248,13 +246,3 @@ internal class VerificationTransportToDevice(
         )
     }
 }
-
-internal class VerificationTransportToDeviceFactory @Inject constructor(
-        private val sendToDeviceTask: SendToDeviceTask,
-        @DeviceId val myDeviceId: String?,
-        private val taskExecutor: TaskExecutor) {
-
-    fun createTransport(tx: DefaultVerificationTransaction?): VerificationTransportToDevice {
-        return VerificationTransportToDevice(tx, sendToDeviceTask, myDeviceId, taskExecutor)
-    }
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDeviceFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDeviceFactory.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e9a2c65ef753323b04414257d5cd3275a5ad7b2d
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDeviceFactory.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.crypto.verification
+
+import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask
+import org.matrix.android.sdk.internal.di.DeviceId
+import org.matrix.android.sdk.internal.task.TaskExecutor
+import javax.inject.Inject
+
+internal class VerificationTransportToDeviceFactory @Inject constructor(
+        private val sendToDeviceTask: SendToDeviceTask,
+        @DeviceId val myDeviceId: String?,
+        private val taskExecutor: TaskExecutor) {
+
+    fun createTransport(tx: DefaultVerificationTransaction?): VerificationTransportToDevice {
+        return VerificationTransportToDevice(tx, sendToDeviceTask, myDeviceId, taskExecutor)
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/DatabaseCleaner.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/DatabaseCleaner.kt
index e305c7ea38c77a77db0dfeb3534ea8e7c88ea5b2..f11ecc5d75f8b6209b0739bca723e0e034318881 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/DatabaseCleaner.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/DatabaseCleaner.kt
@@ -16,6 +16,10 @@
 
 package org.matrix.android.sdk.internal.database
 
+import io.realm.Realm
+import io.realm.RealmConfiguration
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
 import org.matrix.android.sdk.internal.database.helper.nextDisplayIndex
 import org.matrix.android.sdk.internal.database.model.ChunkEntity
 import org.matrix.android.sdk.internal.database.model.ChunkEntityFields
@@ -23,14 +27,11 @@ import org.matrix.android.sdk.internal.database.model.EventEntity
 import org.matrix.android.sdk.internal.database.model.RoomEntity
 import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
 import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
+import org.matrix.android.sdk.internal.database.model.deleteOnCascade
 import org.matrix.android.sdk.internal.di.SessionDatabase
 import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
 import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection
 import org.matrix.android.sdk.internal.task.TaskExecutor
-import io.realm.Realm
-import io.realm.RealmConfiguration
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
 import timber.log.Timber
 import javax.inject.Inject
 
@@ -46,7 +47,7 @@ private const val MIN_NUMBER_OF_EVENTS_BY_CHUNK = 300
 internal class DatabaseCleaner @Inject constructor(@SessionDatabase private val realmConfiguration: RealmConfiguration,
                                                    private val taskExecutor: TaskExecutor) : SessionLifecycleObserver {
 
-    override fun onStart() {
+    override fun onSessionStarted() {
         taskExecutor.executorScope.launch(Dispatchers.Default) {
             awaitTransaction(realmConfiguration) { realm ->
                 val allRooms = realm.where(RoomEntity::class.java).findAll()
@@ -56,7 +57,7 @@ internal class DatabaseCleaner @Inject constructor(@SessionDatabase private val
         }
     }
 
-    private suspend fun cleanUp(realm: Realm, threshold: Long) {
+    private fun cleanUp(realm: Realm, threshold: Long) {
         val numberOfEvents = realm.where(EventEntity::class.java).findAll().size
         val numberOfTimelineEvents = realm.where(TimelineEventEntity::class.java).findAll().size
         Timber.v("Number of events in db: $numberOfEvents | Number of timeline events in db: $numberOfTimelineEvents")
@@ -76,20 +77,7 @@ internal class DatabaseCleaner @Inject constructor(@SessionDatabase private val
                 chunk.numberOfTimelineEvents = chunk.numberOfTimelineEvents - eventsToRemove.size
                 eventsToRemove.forEach {
                     val canDeleteRoot = it.root?.stateKey == null
-                    if (canDeleteRoot) {
-                        it.root?.deleteFromRealm()
-                    }
-                    it.readReceipts?.readReceipts?.deleteAllFromRealm()
-                    it.readReceipts?.deleteFromRealm()
-                    it.annotations?.apply {
-                        editSummary?.deleteFromRealm()
-                        pollResponseSummary?.deleteFromRealm()
-                        referencesSummaryEntity?.deleteFromRealm()
-                        reactionsSummary.deleteAllFromRealm()
-                    }
-                    it.annotations?.deleteFromRealm()
-                    it.readReceipts?.deleteFromRealm()
-                    it.deleteFromRealm()
+                    it.deleteOnCascade(canDeleteRoot)
                 }
                 // We reset the prevToken so we will need to fetch again.
                 chunk.prevToken = null
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt
index 71f978c03cfd0097113b6daed321b1ec378f1000..88aa432fb30db27f758b781ae37287a75bf488d9 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt
@@ -71,7 +71,6 @@ internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase real
                         return@forEach
                     }
                     val domainEvent = event.asDomain()
-//                    decryptIfNeeded(domainEvent)
                     processors.filter {
                         it.shouldProcess(eventId, domainEvent.getClearType(), eventInsert.insertType)
                     }.forEach {
@@ -83,6 +82,7 @@ internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase real
                         .findAll()
                         .deleteAllFromRealm()
             }
+            processors.forEach { it.onPostProcess() }
         }
     }
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmLiveEntityObserver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmLiveEntityObserver.kt
index 3e2160e666bfeed3dfc9a44f81de02168bf4e571..2a0cd963b2506c5a1f8547993661766a1899bad5 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmLiveEntityObserver.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmLiveEntityObserver.kt
@@ -46,7 +46,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
     private val backgroundRealm = AtomicReference<Realm>()
     private lateinit var results: AtomicReference<RealmResults<T>>
 
-    override fun onStart() {
+    override fun onSessionStarted() {
         if (isStarted.compareAndSet(false, true)) {
             BACKGROUND_HANDLER.post {
                 val realm = Realm.getInstance(realmConfiguration)
@@ -58,7 +58,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
         }
     }
 
-    override fun onStop() {
+    override fun onSessionStopped() {
         if (isStarted.compareAndSet(true, false)) {
             BACKGROUND_HANDLER.post {
                 results.getAndSet(null).removeAllChangeListeners()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionProvider.kt
index 1947cc83e37cf8d18cc889fb0350a7c04154fcd9..f8d5d323a5a4f9015709cbd84773b6cea57ae682 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionProvider.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionProvider.kt
@@ -44,14 +44,14 @@ internal class RealmSessionProvider @Inject constructor(@SessionDatabase private
     }
 
     @MainThread
-    override fun onStart() {
+    override fun onSessionStarted() {
         realmThreadLocal.getOrSet {
             Realm.getInstance(monarchy.realmConfiguration)
         }
     }
 
     @MainThread
-    override fun onStop() {
+    override fun onSessionStopped() {
         realmThreadLocal.get()?.close()
         realmThreadLocal.remove()
     }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt
index 57002b5a600b622eed6a8af4c67567c0f45746f4..c7fe7ab447fb55f1242ca3d0a3db3a288a2e62cc 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt
@@ -18,6 +18,8 @@ package org.matrix.android.sdk.internal.database
 
 import io.realm.DynamicRealm
 import io.realm.RealmMigration
+import org.matrix.android.sdk.internal.database.model.EditAggregatedSummaryEntityFields
+import org.matrix.android.sdk.internal.database.model.EditionOfEventFields
 import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields
 import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields
 import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityFields
@@ -30,7 +32,7 @@ import javax.inject.Inject
 class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
 
     companion object {
-        const val SESSION_STORE_SCHEMA_VERSION = 7L
+        const val SESSION_STORE_SCHEMA_VERSION = 8L
     }
 
     override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
@@ -43,6 +45,7 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
         if (oldVersion <= 4) migrateTo5(realm)
         if (oldVersion <= 5) migrateTo6(realm)
         if (oldVersion <= 6) migrateTo7(realm)
+        if (oldVersion <= 7) migrateTo8(realm)
     }
 
     private fun migrateTo1(realm: DynamicRealm) {
@@ -122,4 +125,28 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
                 }
                 ?.removeField("areAllMembersLoaded")
     }
+
+    private fun migrateTo8(realm: DynamicRealm) {
+        Timber.d("Step 7 -> 8")
+
+        val editionOfEventSchema = realm.schema.create("EditionOfEvent")
+                .apply {
+                    // setEmbedded does not return `this`...
+                    isEmbedded = true
+                }
+                .addField(EditionOfEventFields.CONTENT, String::class.java)
+                .addField(EditionOfEventFields.EVENT_ID, String::class.java)
+                .setRequired(EditionOfEventFields.EVENT_ID, true)
+                .addField(EditionOfEventFields.SENDER_ID, String::class.java)
+                .setRequired(EditionOfEventFields.SENDER_ID, true)
+                .addField(EditionOfEventFields.TIMESTAMP, Long::class.java)
+                .addField(EditionOfEventFields.IS_LOCAL_ECHO, Boolean::class.java)
+
+        realm.schema.get("EditAggregatedSummaryEntity")
+                ?.removeField("aggregatedContent")
+                ?.removeField("sourceEvents")
+                ?.removeField("lastEditTs")
+                ?.removeField("sourceLocalEchoEvents")
+                ?.addRealmListField(EditAggregatedSummaryEntityFields.EDITIONS.`$`, editionOfEventSchema)
+    }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt
index f764c4da4b0960b1d1b917a39ac8a238cad784b7..e262b40419466b4435f5a687d7ce5340a3388f39 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt
@@ -38,12 +38,6 @@ import io.realm.Sort
 import io.realm.kotlin.createObject
 import timber.log.Timber
 
-internal fun ChunkEntity.deleteOnCascade() {
-    assertIsManaged()
-    this.timelineEvents.deleteAllFromRealm()
-    this.deleteFromRealm()
-}
-
 internal fun ChunkEntity.merge(roomId: String, chunkToMerge: ChunkEntity, direction: PaginationDirection) {
     assertIsManaged()
     val localRealm = this.realm
@@ -103,7 +97,8 @@ internal fun ChunkEntity.addTimelineEvent(roomId: String,
         this.root = eventEntity
         this.eventId = eventId
         this.roomId = roomId
-        this.annotations = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst()
+        this.annotations = EventAnnotationsSummaryEntity.where(realm, roomId, eventId).findFirst()
+                ?.also { it.cleanUp(eventEntity.sender) }
         this.readReceipts = readReceiptsSummaryEntity
         this.displayIndex = displayIndex
         val roomMemberContent = roomMemberContentsByUser[senderId]
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/RoomEntityHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/RoomEntityHelper.kt
index a4108f0966ba98d0d0728112483f1771b2c5e628..724f307e3bda3648bf01b53cb11e5dd7c4f7bb80 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/RoomEntityHelper.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/RoomEntityHelper.kt
@@ -19,12 +19,7 @@ package org.matrix.android.sdk.internal.database.helper
 import org.matrix.android.sdk.internal.database.model.ChunkEntity
 import org.matrix.android.sdk.internal.database.model.RoomEntity
 
-internal fun RoomEntity.deleteOnCascade(chunkEntity: ChunkEntity) {
-    chunks.remove(chunkEntity)
-    chunkEntity.deleteOnCascade()
-}
-
-internal fun RoomEntity.addOrUpdate(chunkEntity: ChunkEntity) {
+internal fun RoomEntity.addIfNecessary(chunkEntity: ChunkEntity) {
     if (!chunks.contains(chunkEntity)) {
         chunks.add(chunkEntity)
     }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/TimelineEventEntityHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/TimelineEventEntityHelper.kt
index 6f4dac182c54314caa63369d1a810e96b1829fe9..90e867749ee05bf4404cc512fb755de8930d99cc 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/TimelineEventEntityHelper.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/TimelineEventEntityHelper.kt
@@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.database.helper
 
 import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
 import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
-import org.matrix.android.sdk.internal.extensions.assertIsManaged
 import io.realm.Realm
 
 internal fun TimelineEventEntity.Companion.nextId(realm: Realm): Long {
@@ -29,11 +28,3 @@ internal fun TimelineEventEntity.Companion.nextId(realm: Realm): Long {
         currentIdNum.toLong() + 1
     }
 }
-
-internal fun TimelineEventEntity.deleteOnCascade() {
-    assertIsManaged()
-    root?.deleteFromRealm()
-    annotations?.deleteFromRealm()
-    readReceipts?.deleteFromRealm()
-    deleteFromRealm()
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/EventAnnotationsSummaryMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/EventAnnotationsSummaryMapper.kt
index 9ed2664068f266803ef40e3cd5495a6db091cf50..4a26b4c4bf940c94c7b9d25037cefc15d3d81899 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/EventAnnotationsSummaryMapper.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/EventAnnotationsSummaryMapper.kt
@@ -20,11 +20,7 @@ import org.matrix.android.sdk.api.session.room.model.EditAggregatedSummary
 import org.matrix.android.sdk.api.session.room.model.EventAnnotationsSummary
 import org.matrix.android.sdk.api.session.room.model.ReactionAggregatedSummary
 import org.matrix.android.sdk.api.session.room.model.ReferencesAggregatedSummary
-import org.matrix.android.sdk.internal.database.model.EditAggregatedSummaryEntity
 import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity
-import org.matrix.android.sdk.internal.database.model.ReactionAggregatedSummaryEntity
-import org.matrix.android.sdk.internal.database.model.ReferencesAggregatedSummaryEntity
-import io.realm.RealmList
 
 internal object EventAnnotationsSummaryMapper {
     fun map(annotationsSummary: EventAnnotationsSummaryEntity): EventAnnotationsSummary {
@@ -40,14 +36,18 @@ internal object EventAnnotationsSummaryMapper {
                             it.sourceLocalEcho.toList()
                     )
                 },
-                editSummary = annotationsSummary.editSummary?.let {
-                    EditAggregatedSummary(
-                            ContentMapper.map(it.aggregatedContent),
-                            it.sourceEvents.toList(),
-                            it.sourceLocalEchoEvents.toList(),
-                            it.lastEditTs
-                    )
-                },
+                editSummary = annotationsSummary.editSummary
+                        ?.let {
+                            val latestEdition = it.editions.maxByOrNull { editionOfEvent -> editionOfEvent.timestamp } ?: return@let null
+                            EditAggregatedSummary(
+                                    latestContent = ContentMapper.map(latestEdition.content),
+                                    sourceEvents = it.editions.filter { editionOfEvent -> !editionOfEvent.isLocalEcho }
+                                            .map { editionOfEvent -> editionOfEvent.eventId },
+                                    localEchos = it.editions.filter { editionOfEvent -> editionOfEvent.isLocalEcho }
+                                            .map { editionOfEvent -> editionOfEvent.eventId },
+                                    lastEditTs = latestEdition.timestamp
+                            )
+                        },
                 referencesAggregatedSummary = annotationsSummary.referencesSummaryEntity?.let {
                     ReferencesAggregatedSummary(
                             it.eventId,
@@ -62,46 +62,6 @@ internal object EventAnnotationsSummaryMapper {
 
         )
     }
-
-    fun map(annotationsSummary: EventAnnotationsSummary, roomId: String): EventAnnotationsSummaryEntity {
-        val eventAnnotationsSummaryEntity = EventAnnotationsSummaryEntity()
-        eventAnnotationsSummaryEntity.eventId = annotationsSummary.eventId
-        eventAnnotationsSummaryEntity.roomId = roomId
-        eventAnnotationsSummaryEntity.editSummary = annotationsSummary.editSummary?.let {
-            EditAggregatedSummaryEntity(
-                    ContentMapper.map(it.aggregatedContent),
-                    RealmList<String>().apply { addAll(it.sourceEvents) },
-                    RealmList<String>().apply { addAll(it.localEchos) },
-                    it.lastEditTs
-            )
-        }
-        eventAnnotationsSummaryEntity.reactionsSummary = annotationsSummary.reactionsSummary.let {
-            RealmList<ReactionAggregatedSummaryEntity>().apply {
-                addAll(it.map {
-                    ReactionAggregatedSummaryEntity(
-                            it.key,
-                            it.count,
-                            it.addedByMe,
-                            it.firstTimestamp,
-                            RealmList<String>().apply { addAll(it.sourceEvents) },
-                            RealmList<String>().apply { addAll(it.localEchoEvents) }
-                    )
-                })
-            }
-        }
-        eventAnnotationsSummaryEntity.referencesSummaryEntity = annotationsSummary.referencesAggregatedSummary?.let {
-            ReferencesAggregatedSummaryEntity(
-                    it.eventId,
-                    ContentMapper.map(it.content),
-                    RealmList<String>().apply { addAll(it.sourceEvents) },
-                    RealmList<String>().apply { addAll(it.localEchos) }
-            )
-        }
-        eventAnnotationsSummaryEntity.pollResponseSummary = annotationsSummary.pollResponseSummary?.let {
-            PollResponseAggregatedSummaryEntityMapper.map(it)
-        }
-        return eventAnnotationsSummaryEntity
-    }
 }
 
 internal fun EventAnnotationsSummaryEntity.asDomain(): EventAnnotationsSummary {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/EventMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/EventMapper.kt
index 66eccdfba0e7f3e869ed8185544e2c8816af0cdf..a4a2fadd21d9045e7fefe5eab3a7f132cfcce6d7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/EventMapper.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/EventMapper.kt
@@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.database.mapper
 import com.squareup.moshi.JsonDataException
 import org.matrix.android.sdk.api.session.crypto.MXCryptoError
 import org.matrix.android.sdk.api.session.events.model.Event
+import org.matrix.android.sdk.api.session.events.model.EventType
 import org.matrix.android.sdk.api.session.events.model.UnsignedData
 import org.matrix.android.sdk.api.session.room.send.SendState
 import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult
@@ -29,8 +30,6 @@ import timber.log.Timber
 internal object EventMapper {
 
     fun map(event: Event, roomId: String): EventEntity {
-        val uds = if (event.unsignedData == null) null
-        else MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).toJson(event.unsignedData)
         val eventEntity = EventEntity()
         // TODO change this as we shouldn't use event everywhere
         eventEntity.eventId = event.eventId ?: "$$roomId-${System.currentTimeMillis()}-${event.hashCode()}"
@@ -39,14 +38,16 @@ internal object EventMapper {
         eventEntity.prevContent = ContentMapper.map(event.resolvedPrevContent())
         eventEntity.isUseless = IsUselessResolver.isUseless(event)
         eventEntity.stateKey = event.stateKey
-        eventEntity.type = event.type
+        eventEntity.type = event.type ?: EventType.MISSING_TYPE
         eventEntity.sender = event.senderId
         eventEntity.originServerTs = event.originServerTs
         eventEntity.redacts = event.redacts
         eventEntity.age = event.unsignedData?.age ?: event.originServerTs
-        eventEntity.unsignedData = uds
+        eventEntity.unsignedData = event.unsignedData?.let {
+            MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).toJson(it)
+        }
         eventEntity.decryptionResultJson = event.mxDecryptionResult?.let {
-            MoshiProvider.providesMoshi().adapter<OlmDecryptionResult>(OlmDecryptionResult::class.java).toJson(it)
+            MoshiProvider.providesMoshi().adapter(OlmDecryptionResult::class.java).toJson(it)
         }
         eventEntity.decryptionErrorReason = event.mCryptoErrorReason
         eventEntity.decryptionErrorCode = event.mCryptoError?.name
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/ChunkEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/ChunkEntity.kt
index 9770352a9553bb01b18bb2e481848dac9df8487c..68533a3c1995f6da4f0da25f620b76297bcd4954 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/ChunkEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/ChunkEntity.kt
@@ -21,6 +21,8 @@ import io.realm.RealmObject
 import io.realm.RealmResults
 import io.realm.annotations.Index
 import io.realm.annotations.LinkingObjects
+import org.matrix.android.sdk.internal.extensions.assertIsManaged
+import org.matrix.android.sdk.internal.extensions.clearWith
 
 internal open class ChunkEntity(@Index var prevToken: String? = null,
         // Because of gaps we can have several chunks with nextToken == null
@@ -43,3 +45,12 @@ internal open class ChunkEntity(@Index var prevToken: String? = null,
 
     companion object
 }
+
+internal fun ChunkEntity.deleteOnCascade(deleteStateEvents: Boolean, canDeleteRoot: Boolean) {
+    assertIsManaged()
+    if (deleteStateEvents) {
+        stateEvents.deleteAllFromRealm()
+    }
+    timelineEvents.clearWith { it.deleteOnCascade(canDeleteRoot) }
+    deleteFromRealm()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EditAggregatedSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EditAggregatedSummaryEntity.kt
index 604afc1ab1e2df450803845b1e211d414ce1b466..0ed927a6b8618c64cb9655956e395e5cd2be9eb9 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EditAggregatedSummaryEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EditAggregatedSummaryEntity.kt
@@ -17,17 +17,24 @@ package org.matrix.android.sdk.internal.database.model
 
 import io.realm.RealmList
 import io.realm.RealmObject
+import io.realm.annotations.RealmClass
 
 /**
- * Keep the latest state of edition of a message
+ * Keep all the editions of a message
  */
 internal open class EditAggregatedSummaryEntity(
-        var aggregatedContent: String? = null,
-        // The list of the eventIDs used to build the summary (might be out of sync if chunked received from message chunk)
-        var sourceEvents: RealmList<String> = RealmList(),
-        var sourceLocalEchoEvents: RealmList<String> = RealmList(),
-        var lastEditTs: Long = 0
+        // The list of the editions used to build the summary (might be out of sync if chunked received from message chunk)
+        var editions: RealmList<EditionOfEvent> = RealmList()
 ) : RealmObject() {
 
     companion object
 }
+
+@RealmClass(embedded = true)
+internal open class EditionOfEvent(
+        var senderId: String = "",
+        var eventId: String = "",
+        var content: String? = null,
+        var timestamp: Long = 0,
+        var isLocalEcho: Boolean = false
+) : RealmObject()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventAnnotationsSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventAnnotationsSummaryEntity.kt
index 3e5e27761386c64db14b5b3ded6e801da031167a..3e8813042004e6fd9c31c33449b185b2923e2d50 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventAnnotationsSummaryEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventAnnotationsSummaryEntity.kt
@@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.database.model
 import io.realm.RealmList
 import io.realm.RealmObject
 import io.realm.annotations.PrimaryKey
+import timber.log.Timber
 
 internal open class EventAnnotationsSummaryEntity(
         @PrimaryKey
@@ -29,5 +30,28 @@ internal open class EventAnnotationsSummaryEntity(
         var pollResponseSummary: PollResponseAggregatedSummaryEntity? = null
 ) : RealmObject() {
 
+    /**
+     * Cleanup undesired editions, done by users different from the originalEventSender
+     */
+    fun cleanUp(originalEventSenderId: String?) {
+        originalEventSenderId ?: return
+
+        editSummary?.editions?.filter {
+            it.senderId != originalEventSenderId
+        }
+                ?.forEach {
+                    Timber.w("Deleting an edition from ${it.senderId} of event sent by $originalEventSenderId")
+                    it.deleteFromRealm()
+                }
+    }
+
     companion object
 }
+
+internal fun EventAnnotationsSummaryEntity.deleteOnCascade() {
+    reactionsSummary.deleteAllFromRealm()
+    editSummary?.deleteFromRealm()
+    referencesSummaryEntity?.deleteFromRealm()
+    pollResponseSummary?.deleteFromRealm()
+    deleteFromRealm()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventInsertType.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventInsertType.kt
similarity index 88%
rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventInsertType.java
rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventInsertType.kt
index 05153c5734e1a16e3f5603222e03191414493983..463ccb2f46c1c936251c7d4f16b1bcba4b0e633f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventInsertType.java
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventInsertType.kt
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package org.matrix.android.sdk.internal.database.model;
+package org.matrix.android.sdk.internal.database.model
 
-public enum EventInsertType {
+internal enum class EventInsertType {
     INITIAL_SYNC,
     INCREMENTAL_SYNC,
     PAGINATION,
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRuleEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRuleEntity.kt
index 85375c8064be35ac8137d8820c6b58ebb469298d..5bfe2833f8ad0371319d5a0a316e0dafcc3bafab 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRuleEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRuleEntity.kt
@@ -40,3 +40,8 @@ internal open class PushRuleEntity(
 
     companion object
 }
+
+internal fun PushRuleEntity.deleteOnCascade() {
+    conditions?.deleteAllFromRealm()
+    deleteFromRealm()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRulesEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRulesEntity.kt
index 21e3510cd2eb699322b370c4fca6b1ee43a7a8a4..571bc71c273425ecb87630239ffd420f8cecac07 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRulesEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRulesEntity.kt
@@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.database.model
 import org.matrix.android.sdk.api.pushrules.RuleKind
 import io.realm.RealmList
 import io.realm.RealmObject
+import org.matrix.android.sdk.internal.extensions.clearWith
 
 internal open class PushRulesEntity(
         var scope: String = "",
@@ -35,3 +36,8 @@ internal open class PushRulesEntity(
 
     companion object
 }
+
+internal fun PushRulesEntity.deleteOnCascade() {
+    pushRules.clearWith { it.deleteOnCascade() }
+    deleteFromRealm()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PusherEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PusherEntity.kt
index f85c01c48aff1bbffa0ad630ddce38fb3431a345..af8e4f2d370ee62c03e1234a6b666846d921c9f9 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PusherEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PusherEntity.kt
@@ -15,8 +15,8 @@
  */
 package org.matrix.android.sdk.internal.database.model
 
-import org.matrix.android.sdk.api.session.pushers.PusherState
 import io.realm.RealmObject
+import org.matrix.android.sdk.api.session.pushers.PusherState
 
 // TODO
 //        at java.lang.Thread.run(Thread.java:764)
@@ -54,3 +54,8 @@ internal open class PusherEntity(
 
     companion object
 }
+
+internal fun PusherEntity.deleteOnCascade() {
+    data?.deleteFromRealm()
+    deleteFromRealm()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/ReadReceiptsSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/ReadReceiptsSummaryEntity.kt
index 98b4329076798ce9b57950a0a0e7282de4faa5c9..9ca4adc33ed255345903be44a34b11d526c5e046 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/ReadReceiptsSummaryEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/ReadReceiptsSummaryEntity.kt
@@ -34,3 +34,8 @@ internal open class ReadReceiptsSummaryEntity(
 
     companion object
 }
+
+internal fun ReadReceiptsSummaryEntity.deleteOnCascade() {
+    readReceipts.deleteAllFromRealm()
+    deleteFromRealm()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt
index bca2c42c9eba97c445442015bb0850b42f9c01a3..6e6096cf8a62111742d2306224ff91a125830b97 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt
@@ -43,6 +43,7 @@ import io.realm.annotations.RealmModule
             EventAnnotationsSummaryEntity::class,
             ReactionAggregatedSummaryEntity::class,
             EditAggregatedSummaryEntity::class,
+            EditionOfEvent::class,
             PollResponseAggregatedSummaryEntity::class,
             ReferencesAggregatedSummaryEntity::class,
             PushRulesEntity::class,
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/TimelineEventEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/TimelineEventEntity.kt
index 7bd0dbbb8f3f50160396095e397dd26e37c7af46..30bbde70c2e4c6a201dce560bde2b9a8e6eeec61 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/TimelineEventEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/TimelineEventEntity.kt
@@ -20,6 +20,7 @@ import io.realm.RealmObject
 import io.realm.RealmResults
 import io.realm.annotations.Index
 import io.realm.annotations.LinkingObjects
+import org.matrix.android.sdk.internal.extensions.assertIsManaged
 
 internal open class TimelineEventEntity(var localId: Long = 0,
                                         @Index var eventId: String = "",
@@ -39,3 +40,13 @@ internal open class TimelineEventEntity(var localId: Long = 0,
 
     companion object
 }
+
+internal fun TimelineEventEntity.deleteOnCascade(canDeleteRoot: Boolean) {
+    assertIsManaged()
+    if (canDeleteRoot) {
+        root?.deleteFromRealm()
+    }
+    annotations?.deleteOnCascade()
+    readReceipts?.deleteOnCascade()
+    deleteFromRealm()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt
index 6028697054c0f94c2bc8b2544cade3f20180edb9..f7d2823303bf3199ef9711c0c251616159423e5f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt
@@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.database.query
 
 import org.matrix.android.sdk.internal.database.model.ChunkEntity
 import org.matrix.android.sdk.internal.database.model.ChunkEntityFields
-import org.matrix.android.sdk.internal.database.model.RoomEntityFields
 import io.realm.Realm
 import io.realm.RealmQuery
 import io.realm.RealmResults
@@ -27,7 +26,7 @@ import io.realm.kotlin.where
 
 internal fun ChunkEntity.Companion.where(realm: Realm, roomId: String): RealmQuery<ChunkEntity> {
     return realm.where<ChunkEntity>()
-            .equalTo("${ChunkEntityFields.ROOM}.${RoomEntityFields.ROOM_ID}", roomId)
+            .equalTo(ChunkEntityFields.ROOM.ROOM_ID, roomId)
 }
 
 internal fun ChunkEntity.Companion.find(realm: Realm, roomId: String, prevToken: String? = null, nextToken: String? = null): ChunkEntity? {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventAnnotationsSummaryEntityQuery.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventAnnotationsSummaryEntityQuery.kt
index 9a298b7e79c18f32c172bfefd67c2e7ace938f17..c3cae3d2685677fb898cda0a0e1574ff7eb6b21c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventAnnotationsSummaryEntityQuery.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventAnnotationsSummaryEntityQuery.kt
@@ -23,18 +23,10 @@ import io.realm.Realm
 import io.realm.RealmQuery
 import io.realm.kotlin.where
 
-internal fun EventAnnotationsSummaryEntity.Companion.where(realm: Realm, eventId: String): RealmQuery<EventAnnotationsSummaryEntity> {
-    val query = realm.where<EventAnnotationsSummaryEntity>()
-    query.equalTo(EventAnnotationsSummaryEntityFields.EVENT_ID, eventId)
-    return query
-}
-
-internal fun EventAnnotationsSummaryEntity.Companion.whereInRoom(realm: Realm, roomId: String?): RealmQuery<EventAnnotationsSummaryEntity> {
-    val query = realm.where<EventAnnotationsSummaryEntity>()
-    if (roomId != null) {
-        query.equalTo(EventAnnotationsSummaryEntityFields.ROOM_ID, roomId)
-    }
-    return query
+internal fun EventAnnotationsSummaryEntity.Companion.where(realm: Realm, roomId: String, eventId: String): RealmQuery<EventAnnotationsSummaryEntity> {
+    return realm.where<EventAnnotationsSummaryEntity>()
+            .equalTo(EventAnnotationsSummaryEntityFields.ROOM_ID, roomId)
+            .equalTo(EventAnnotationsSummaryEntityFields.EVENT_ID, eventId)
 }
 
 internal fun EventAnnotationsSummaryEntity.Companion.create(realm: Realm, roomId: String, eventId: String): EventAnnotationsSummaryEntity {
@@ -49,6 +41,6 @@ internal fun EventAnnotationsSummaryEntity.Companion.create(realm: Realm, roomId
 }
 
 internal fun EventAnnotationsSummaryEntity.Companion.getOrCreate(realm: Realm, roomId: String, eventId: String): EventAnnotationsSummaryEntity {
-    return EventAnnotationsSummaryEntity.where(realm, eventId).findFirst()
-            ?: EventAnnotationsSummaryEntity.create(realm, roomId, eventId).apply { this.roomId = roomId }
+    return EventAnnotationsSummaryEntity.where(realm, roomId, eventId).findFirst()
+            ?: EventAnnotationsSummaryEntity.create(realm, roomId, eventId)
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/PushersQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/PushersQueries.kt
index d78bda23170dfc64009db952fd3940346a598301..359b25684435fb323243aad5b804ce90b0fda724 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/PushersQueries.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/PushersQueries.kt
@@ -48,6 +48,6 @@ internal fun PushRuleEntity.Companion.where(realm: Realm,
                                             scope: String,
                                             ruleId: String): RealmQuery<PushRuleEntity> {
     return realm.where<PushRuleEntity>()
-            .equalTo("${PushRuleEntityFields.PARENT}.${PushRulesEntityFields.SCOPE}", scope)
+            .equalTo(PushRuleEntityFields.PARENT.SCOPE, scope)
             .equalTo(PushRuleEntityFields.RULE_ID, ruleId)
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/UserDraftsEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/UserDraftsEntityQueries.kt
index 35f317f192b323cf873018cbe1c76712c59c7241..4af4da0a22a998331e75ce4ee8fd4e7b67f76a41 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/UserDraftsEntityQueries.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/UserDraftsEntityQueries.kt
@@ -16,7 +16,6 @@
 
 package org.matrix.android.sdk.internal.database.query
 
-import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
 import org.matrix.android.sdk.internal.database.model.UserDraftsEntity
 import org.matrix.android.sdk.internal.database.model.UserDraftsEntityFields
 import io.realm.Realm
@@ -26,7 +25,7 @@ import io.realm.kotlin.where
 internal fun UserDraftsEntity.Companion.where(realm: Realm, roomId: String? = null): RealmQuery<UserDraftsEntity> {
     val query = realm.where<UserDraftsEntity>()
     if (roomId != null) {
-        query.equalTo(UserDraftsEntityFields.ROOM_SUMMARY_ENTITY + "." + RoomSummaryEntityFields.ROOM_ID, roomId)
+        query.equalTo(UserDraftsEntityFields.ROOM_SUMMARY_ENTITY.ROOM_ID, roomId)
     }
     return query
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MoshiProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MoshiProvider.kt
index 48fa41b35070bc5e2d62537837de4afdeee325dd..074f8dc43e193e5eba72fe38d008bf89f9796223 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MoshiProvider.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MoshiProvider.kt
@@ -36,6 +36,7 @@ import org.matrix.android.sdk.internal.network.parsing.ForceToBooleanJsonAdapter
 import org.matrix.android.sdk.internal.network.parsing.RuntimeJsonAdapterFactory
 import org.matrix.android.sdk.internal.network.parsing.TlsVersionMoshiAdapter
 import org.matrix.android.sdk.internal.network.parsing.UriMoshiAdapter
+import org.matrix.android.sdk.internal.session.sync.parsing.DefaultLazyRoomSyncEphemeralJsonAdapter
 
 object MoshiProvider {
 
@@ -44,6 +45,8 @@ object MoshiProvider {
             .add(ForceToBooleanJsonAdapter())
             .add(CipherSuiteMoshiAdapter())
             .add(TlsVersionMoshiAdapter())
+            // Use addLast here so we can inject a SplitLazyRoomSyncJsonAdapter later to override the default parsing.
+            .addLast(DefaultLazyRoomSyncEphemeralJsonAdapter())
             .add(RuntimeJsonAdapterFactory.of(MessageContent::class.java, "msgtype", MessageDefaultContent::class.java)
                     .registerSubtype(MessageTextContent::class.java, MessageType.MSGTYPE_TEXT)
                     .registerSubtype(MessageNoticeContent::class.java, MessageType.MSGTYPE_NOTICE)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/RealmExtensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/RealmExtensions.kt
index 0718096fd57556048bd1afc8f3c8fd3970e7fa2f..e52e32e16ad0ea2f280478fc96b24fd43a425917 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/RealmExtensions.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/RealmExtensions.kt
@@ -16,8 +16,18 @@
 
 package org.matrix.android.sdk.internal.extensions
 
+import io.realm.RealmList
 import io.realm.RealmObject
 
 internal fun RealmObject.assertIsManaged() {
     check(isManaged) { "${javaClass.simpleName} entity should be managed to use this function" }
 }
+
+/**
+ * Clear a RealmList by deleting all its items calling the provided lambda
+ */
+internal fun <T> RealmList<T>.clearWith(delete: (T) -> Unit) {
+    while (!isEmpty()) {
+        first()?.let { delete.invoke(it) }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/DefaultFederationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/DefaultFederationService.kt
new file mode 100644
index 0000000000000000000000000000000000000000..862a4855cc0902ba116f3b0c986698d970097a50
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/DefaultFederationService.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.federation
+
+import org.matrix.android.sdk.api.federation.FederationService
+import org.matrix.android.sdk.api.federation.FederationVersion
+import javax.inject.Inject
+
+internal class DefaultFederationService @Inject constructor(
+        private val getFederationVersionTask: GetFederationVersionTask
+) : FederationService {
+    override suspend fun getFederationVersion(): FederationVersion {
+        return getFederationVersionTask.execute(Unit)
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/FederationAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/FederationAPI.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1816616336c9a683a0605b91daf9da666989a625
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/FederationAPI.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.federation
+
+import org.matrix.android.sdk.internal.network.NetworkConstants
+import retrofit2.Call
+import retrofit2.http.GET
+
+internal interface FederationAPI {
+    @GET(NetworkConstants.URI_FEDERATION_PATH + "version")
+    fun getVersion(): Call<FederationGetVersionResult>
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/FederationGetVersionResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/FederationGetVersionResult.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3d84008be6ce56febc92c8becc5b4bc438b21e1a
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/FederationGetVersionResult.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.federation
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+/**
+ * Ref: https://matrix.org/docs/spec/server_server/latest#get-matrix-federation-v1-version
+ */
+@JsonClass(generateAdapter = true)
+internal data class FederationGetVersionResult(
+        @Json(name = "server")
+        val server: FederationGetVersionServer?
+)
+
+@JsonClass(generateAdapter = true)
+internal data class FederationGetVersionServer(
+        /**
+         * Arbitrary name that identify this implementation.
+         */
+        @Json(name = "name")
+        val name: String?,
+        /**
+         * Version of this implementation. The version format depends on the implementation.
+         */
+        @Json(name = "version")
+        val version: String?
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/FederationModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/FederationModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..320bf1d4454df3ec98294597e50191480671d707
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/FederationModule.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.federation
+
+import dagger.Binds
+import dagger.Lazy
+import dagger.Module
+import dagger.Provides
+import okhttp3.OkHttpClient
+import org.matrix.android.sdk.api.auth.data.SessionParams
+import org.matrix.android.sdk.api.federation.FederationService
+import org.matrix.android.sdk.internal.di.Unauthenticated
+import org.matrix.android.sdk.internal.network.RetrofitFactory
+
+@Module
+internal abstract class FederationModule {
+
+    @Module
+    companion object {
+        @Provides
+        @JvmStatic
+        fun providesFederationAPI(@Unauthenticated okHttpClient: Lazy<OkHttpClient>,
+                                  sessionParams: SessionParams,
+                                  retrofitFactory: RetrofitFactory): FederationAPI {
+            return retrofitFactory.create(okHttpClient, sessionParams.homeServerUrl).create(FederationAPI::class.java)
+        }
+    }
+
+    @Binds
+    abstract fun bindFederationService(service: DefaultFederationService): FederationService
+
+    @Binds
+    abstract fun bindGetFederationVersionTask(task: DefaultGetFederationVersionTask): GetFederationVersionTask
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/GetFederationVersionTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/GetFederationVersionTask.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ce35e48f6b53f13e6d9c37f4f59a2df515a7fc98
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/federation/GetFederationVersionTask.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.federation
+
+import org.matrix.android.sdk.api.federation.FederationVersion
+import org.matrix.android.sdk.internal.network.executeRequest
+import org.matrix.android.sdk.internal.task.Task
+import javax.inject.Inject
+
+internal interface GetFederationVersionTask : Task<Unit, FederationVersion>
+
+internal class DefaultGetFederationVersionTask @Inject constructor(
+        private val federationAPI: FederationAPI
+) : GetFederationVersionTask {
+
+    override suspend fun execute(params: Unit): FederationVersion {
+        val result = executeRequest<FederationGetVersionResult>(null) {
+            apiCall = federationAPI.getVersion()
+        }
+
+        return FederationVersion(
+                name = result.server?.name,
+                version = result.server?.version
+        )
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConstants.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConstants.kt
index a14c86efb62e2bc48cc763dd22a4f32424a03fa1..99c12255cd337a92f404aa40231171fef8c8886b 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConstants.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConstants.kt
@@ -36,4 +36,7 @@ internal object NetworkConstants {
 
     // Integration
     const val URI_INTEGRATION_MANAGER_PATH = "_matrix/integrations/v1/"
+
+    // Federation
+    const val URI_FEDERATION_PATH = "_matrix/federation/v1/"
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultInitialSyncProgressService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultInitialSyncProgressService.kt
deleted file mode 100644
index 9918e83fbc13da9e199ce8ce13f928e2053ef668..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultInitialSyncProgressService.kt
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 2020 The Matrix.org Foundation C.I.C.
- *
- * 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 org.matrix.android.sdk.internal.session
-
-import androidx.annotation.StringRes
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
-import org.matrix.android.sdk.api.session.InitialSyncProgressService
-import timber.log.Timber
-import javax.inject.Inject
-
-@SessionScope
-class DefaultInitialSyncProgressService @Inject constructor() : InitialSyncProgressService {
-
-    private val status = MutableLiveData<InitialSyncProgressService.Status>()
-
-    private var rootTask: TaskInfo? = null
-
-    override fun getInitialSyncProgressStatus(): LiveData<InitialSyncProgressService.Status> {
-        return status
-    }
-
-    fun startTask(@StringRes nameRes: Int, totalProgress: Int, parentWeight: Float = 1f) {
-        // Create a rootTask, or add a child to the leaf
-        if (rootTask == null) {
-            rootTask = TaskInfo(nameRes, totalProgress)
-        } else {
-            val currentLeaf = rootTask!!.leaf()
-
-            val newTask = TaskInfo(nameRes,
-                    totalProgress,
-                    currentLeaf,
-                    parentWeight)
-
-            currentLeaf.child = newTask
-        }
-        reportProgress(0)
-    }
-
-    fun reportProgress(progress: Int) {
-        rootTask?.leaf()?.setProgress(progress)
-    }
-
-    fun endTask(nameRes: Int) {
-        val endedTask = rootTask?.leaf()
-        if (endedTask?.nameRes == nameRes) {
-            // close it
-            val parent = endedTask.parent
-            parent?.child = null
-            parent?.setProgress(endedTask.offset + (endedTask.totalProgress * endedTask.parentWeight).toInt())
-        }
-        if (endedTask?.parent == null) {
-            status.postValue(InitialSyncProgressService.Status.Idle)
-        }
-    }
-
-    fun endAll() {
-        rootTask = null
-        status.postValue(InitialSyncProgressService.Status.Idle)
-    }
-
-    private inner class TaskInfo(@StringRes var nameRes: Int,
-                                 var totalProgress: Int,
-                                 var parent: TaskInfo? = null,
-                                 var parentWeight: Float = 1f,
-                                 var offset: Int = parent?.currentProgress ?: 0) {
-        var child: TaskInfo? = null
-        var currentProgress: Int = 0
-
-        /**
-         * Get the further child
-         */
-        fun leaf(): TaskInfo {
-            var last = this
-            while (last.child != null) {
-                last = last.child!!
-            }
-            return last
-        }
-
-        /**
-         * Set progress of the parent if any (which will post value), or post the value
-         */
-        fun setProgress(progress: Int) {
-            currentProgress = progress
-//            val newProgress = Math.min(currentProgress + progress, totalProgress)
-            parent?.let {
-                val parentProgress = (currentProgress * parentWeight).toInt()
-                it.setProgress(offset + parentProgress)
-            } ?: run {
-                Timber.v("--- ${leaf().nameRes}: $currentProgress")
-                status.postValue(InitialSyncProgressService.Status.Progressing(leaf().nameRes, currentProgress))
-            }
-        }
-    }
-}
-
-inline fun <T> reportSubtask(reporter: DefaultInitialSyncProgressService?,
-                             @StringRes nameRes: Int,
-                             totalProgress: Int,
-                             parentWeight: Float = 1f,
-                             block: () -> T): T {
-    reporter?.startTask(nameRes, totalProgress, parentWeight)
-    return block().also {
-        reporter?.endTask(nameRes)
-    }
-}
-
-inline fun <K, V, R> Map<out K, V>.mapWithProgress(reporter: DefaultInitialSyncProgressService?,
-                                                   taskId: Int,
-                                                   weight: Float,
-                                                   transform: (Map.Entry<K, V>) -> R): List<R> {
-    val total = count().toFloat()
-    var current = 0
-    reporter?.startTask(taskId, 100, weight)
-    return map {
-        reporter?.reportProgress((current / total * 100).toInt())
-        current++
-        transform.invoke(it)
-    }.also {
-        reporter?.endTask(taskId)
-    }
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt
index e09c051c81a25d3c1cf2be408ac3662a3daa7305..45fcc5af2d90042a7e3fd21f1924f1bfc99f00b0 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt
@@ -22,8 +22,9 @@ import io.realm.RealmConfiguration
 import okhttp3.OkHttpClient
 import org.matrix.android.sdk.api.auth.data.SessionParams
 import org.matrix.android.sdk.api.failure.GlobalError
+import org.matrix.android.sdk.api.federation.FederationService
 import org.matrix.android.sdk.api.pushrules.PushRuleService
-import org.matrix.android.sdk.api.session.InitialSyncProgressService
+import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
 import org.matrix.android.sdk.api.session.Session
 import org.matrix.android.sdk.api.session.account.AccountService
 import org.matrix.android.sdk.api.session.accountdata.AccountDataService
@@ -49,6 +50,7 @@ import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageServi
 import org.matrix.android.sdk.api.session.signout.SignOutService
 import org.matrix.android.sdk.api.session.sync.FilterService
 import org.matrix.android.sdk.api.session.terms.TermsService
+import org.matrix.android.sdk.api.session.thirdparty.ThirdPartyService
 import org.matrix.android.sdk.api.session.typing.TypingUsersTracker
 import org.matrix.android.sdk.api.session.user.UserService
 import org.matrix.android.sdk.api.session.widgets.WidgetService
@@ -63,7 +65,6 @@ import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificate
 import org.matrix.android.sdk.internal.di.WorkManagerProvider
 import org.matrix.android.sdk.internal.network.GlobalErrorHandler
 import org.matrix.android.sdk.internal.session.identity.DefaultIdentityService
-import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
 import org.matrix.android.sdk.internal.session.sync.SyncTokenStore
 import org.matrix.android.sdk.internal.session.sync.job.SyncThread
 import org.matrix.android.sdk.internal.session.sync.job.SyncWorker
@@ -87,6 +88,7 @@ internal class DefaultSession @Inject constructor(
         private val groupService: Lazy<GroupService>,
         private val userService: Lazy<UserService>,
         private val filterService: Lazy<FilterService>,
+        private val federationService: Lazy<FederationService>,
         private val cacheService: Lazy<CacheService>,
         private val signOutService: Lazy<SignOutService>,
         private val pushRuleService: Lazy<PushRuleService>,
@@ -114,10 +116,10 @@ internal class DefaultSession @Inject constructor(
         private val accountService: Lazy<AccountService>,
         private val defaultIdentityService: DefaultIdentityService,
         private val integrationManagerService: IntegrationManagerService,
+        private val thirdPartyService: Lazy<ThirdPartyService>,
         private val callSignalingService: Lazy<CallSignalingService>,
         @UnauthenticatedWithCertificate
-        private val unauthenticatedWithCertificateOkHttpClient: Lazy<OkHttpClient>,
-        private val eventSenderProcessor: EventSenderProcessor
+        private val unauthenticatedWithCertificateOkHttpClient: Lazy<OkHttpClient>
 ) : Session,
         RoomService by roomService.get(),
         RoomDirectoryService by roomDirectoryService.get(),
@@ -154,10 +156,9 @@ internal class DefaultSession @Inject constructor(
         isOpen = true
         cryptoService.get().ensureDevice()
         uiHandler.post {
-            lifecycleObservers.forEach { it.onStart() }
+            lifecycleObservers.forEach { it.onSessionStarted() }
         }
         globalErrorHandler.listener = this
-        eventSenderProcessor.start()
     }
 
     override fun requireBackgroundSync() {
@@ -196,12 +197,11 @@ internal class DefaultSession @Inject constructor(
         stopSync()
         // timelineEventDecryptor.destroy()
         uiHandler.post {
-            lifecycleObservers.forEach { it.onStop() }
+            lifecycleObservers.forEach { it.onSessionStopped() }
         }
         cryptoService.get().close()
         isOpen = false
         globalErrorHandler.listener = null
-        eventSenderProcessor.interrupt()
     }
 
     override fun getSyncStateLive() = getSyncThread().liveState()
@@ -258,6 +258,10 @@ internal class DefaultSession @Inject constructor(
 
     override fun searchService(): SearchService = searchService.get()
 
+    override fun federationService(): FederationService = federationService.get()
+
+    override fun thirdPartyService(): ThirdPartyService = thirdPartyService.get()
+
     override fun getOkHttpClient(): OkHttpClient {
         return unauthenticatedWithCertificateOkHttpClient.get()
     }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/EventInsertLiveProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/EventInsertLiveProcessor.kt
index 53b1a735447cbc899e5c9fba83cbe1d10bea87a0..7a687b774bfdfc745e0b1bd045738ecfa98d2c0b 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/EventInsertLiveProcessor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/EventInsertLiveProcessor.kt
@@ -25,4 +25,12 @@ internal interface EventInsertLiveProcessor {
     fun shouldProcess(eventId: String, eventType: String, insertType: EventInsertType): Boolean
 
     suspend fun process(realm: Realm, event: Event)
+
+    /**
+     * Called after transaction.
+     * Maybe you prefer to process the events outside of the realm transaction.
+     */
+    suspend fun onPostProcess() {
+        // Noop by default
+    }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt
index f5eade1704e06669b5b3fb76181052f56d3a5946..7e1e3d0f7097b89daefecebc24c5fd3d89a0c0fe 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt
@@ -27,6 +27,7 @@ import org.matrix.android.sdk.internal.crypto.SendGossipWorker
 import org.matrix.android.sdk.internal.crypto.crosssigning.UpdateTrustWorker
 import org.matrix.android.sdk.internal.crypto.verification.SendVerificationMessageWorker
 import org.matrix.android.sdk.internal.di.MatrixComponent
+import org.matrix.android.sdk.internal.federation.FederationModule
 import org.matrix.android.sdk.internal.network.NetworkConnectivityChecker
 import org.matrix.android.sdk.internal.session.account.AccountModule
 import org.matrix.android.sdk.internal.session.cache.CacheModule
@@ -56,6 +57,7 @@ import org.matrix.android.sdk.internal.session.sync.SyncTask
 import org.matrix.android.sdk.internal.session.sync.SyncTokenStore
 import org.matrix.android.sdk.internal.session.sync.job.SyncWorker
 import org.matrix.android.sdk.internal.session.terms.TermsModule
+import org.matrix.android.sdk.internal.session.thirdparty.ThirdPartyModule
 import org.matrix.android.sdk.internal.session.user.UserModule
 import org.matrix.android.sdk.internal.session.user.accountdata.AccountDataModule
 import org.matrix.android.sdk.internal.session.widgets.WidgetModule
@@ -86,8 +88,10 @@ import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
             AccountDataModule::class,
             ProfileModule::class,
             AccountModule::class,
+            FederationModule::class,
             CallModule::class,
-            SearchModule::class
+            SearchModule::class,
+            ThirdPartyModule::class
         ]
 )
 @SessionScope
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionLifecycleObserver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionLifecycleObserver.kt
index d26e9861d03421a9f3f41231e51ff0f6623d2a32..cb37fbec75054ad2eff7be0f5ccf8585034865db 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionLifecycleObserver.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionLifecycleObserver.kt
@@ -27,7 +27,7 @@ internal interface SessionLifecycleObserver {
     Called when the session is opened
      */
     @MainThread
-    fun onStart() {
+    fun onSessionStarted() {
         // noop
     }
 
@@ -43,7 +43,7 @@ internal interface SessionLifecycleObserver {
     Called when the session is closed
      */
     @MainThread
-    fun onStop() {
+    fun onSessionStopped() {
         // noop
     }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt
index 468c193ad3c55649fe0df57a7e0599f987a9d43e..f10eb67921d03d1c4398ed5f5bb250518d8955ab 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt
@@ -32,7 +32,7 @@ import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
 import org.matrix.android.sdk.api.auth.data.SessionParams
 import org.matrix.android.sdk.api.auth.data.sessionId
 import org.matrix.android.sdk.api.crypto.MXCryptoConfig
-import org.matrix.android.sdk.api.session.InitialSyncProgressService
+import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
 import org.matrix.android.sdk.api.session.Session
 import org.matrix.android.sdk.api.session.accountdata.AccountDataService
 import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
@@ -77,11 +77,14 @@ import org.matrix.android.sdk.internal.session.call.CallEventProcessor
 import org.matrix.android.sdk.internal.session.download.DownloadProgressInterceptor
 import org.matrix.android.sdk.internal.session.homeserver.DefaultHomeServerCapabilitiesService
 import org.matrix.android.sdk.internal.session.identity.DefaultIdentityService
+import org.matrix.android.sdk.internal.session.initsync.DefaultInitialSyncProgressService
 import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager
 import org.matrix.android.sdk.internal.session.permalinks.DefaultPermalinkService
 import org.matrix.android.sdk.internal.session.room.EventRelationsAggregationProcessor
 import org.matrix.android.sdk.internal.session.room.create.RoomCreateEventProcessor
 import org.matrix.android.sdk.internal.session.room.prune.RedactionEventProcessor
+import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
+import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessorCoroutine
 import org.matrix.android.sdk.internal.session.room.tombstone.RoomTombstoneEventProcessor
 import org.matrix.android.sdk.internal.session.securestorage.DefaultSecureStorageService
 import org.matrix.android.sdk.internal.session.typing.DefaultTypingUsersTracker
@@ -338,6 +341,10 @@ internal abstract class SessionModule {
     @IntoSet
     abstract fun bindRealmSessionProvider(provider: RealmSessionProvider): SessionLifecycleObserver
 
+    @Binds
+    @IntoSet
+    abstract fun bindEventSenderProcessorAsSessionLifecycleObserver(processor: EventSenderProcessorCoroutine): SessionLifecycleObserver
+
     @Binds
     abstract fun bindInitialSyncProgressService(service: DefaultInitialSyncProgressService): InitialSyncProgressService
 
@@ -361,4 +368,7 @@ internal abstract class SessionModule {
 
     @Binds
     abstract fun bindRedactEventTask(task: DefaultRedactEventTask): RedactEventTask
+
+    @Binds
+    abstract fun bindEventSenderProcessor(processor: EventSenderProcessorCoroutine): EventSenderProcessor
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DeactivateAccountTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DeactivateAccountTask.kt
index d67b21567e8a752bab63d2e96723b409a7d91b21..ca6b0554a94c2d7d10329030d71f315c2341ea59 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DeactivateAccountTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DeactivateAccountTask.kt
@@ -16,10 +16,9 @@
 
 package org.matrix.android.sdk.internal.session.account
 
+import org.matrix.android.sdk.api.auth.UIABaseAuth
 import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
 import org.matrix.android.sdk.internal.auth.registration.handleUIA
-import org.matrix.android.sdk.api.auth.UIABaseAuth
-import org.matrix.android.sdk.internal.di.UserId
 import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
 import org.matrix.android.sdk.internal.network.executeRequest
 import org.matrix.android.sdk.internal.session.cleanup.CleanupSession
@@ -30,8 +29,8 @@ import javax.inject.Inject
 
 internal interface DeactivateAccountTask : Task<DeactivateAccountTask.Params, Unit> {
     data class Params(
-            val userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor,
             val eraseAllData: Boolean,
+            val userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor,
             val userAuthParam: UIABaseAuth? = null
     )
 }
@@ -39,7 +38,6 @@ internal interface DeactivateAccountTask : Task<DeactivateAccountTask.Params, Un
 internal class DefaultDeactivateAccountTask @Inject constructor(
         private val accountAPI: AccountAPI,
         private val globalErrorReceiver: GlobalErrorReceiver,
-        @UserId private val userId: String,
         private val identityDisconnectTask: IdentityDisconnectTask,
         private val cleanupSession: CleanupSession
 ) : DeactivateAccountTask {
@@ -47,23 +45,33 @@ internal class DefaultDeactivateAccountTask @Inject constructor(
     override suspend fun execute(params: DeactivateAccountTask.Params) {
         val deactivateAccountParams = DeactivateAccountParams.create(params.userAuthParam, params.eraseAllData)
 
-        try {
+        val canCleanup = try {
             executeRequest<Unit>(globalErrorReceiver) {
                 apiCall = accountAPI.deactivate(deactivateAccountParams)
             }
+            true
         } catch (throwable: Throwable) {
-            if (!handleUIA(throwable, params.userInteractiveAuthInterceptor) { auth ->
-                        execute(params.copy(userAuthParam = auth))
-                    }
+            if (!handleUIA(
+                            failure = throwable,
+                            interceptor = params.userInteractiveAuthInterceptor,
+                            retryBlock = { authUpdate ->
+                                execute(params.copy(userAuthParam = authUpdate))
+                            }
+                    )
             ) {
                 Timber.d("## UIA: propagate failure")
-                throw  throwable
+                throw throwable
+            } else {
+                false
             }
         }
-        // Logout from identity server if any, ignoring errors
-        runCatching { identityDisconnectTask.execute(Unit) }
-                .onFailure { Timber.w(it, "Unable to disconnect identity server") }
 
-        cleanupSession.handle()
+        if (canCleanup) {
+            // Logout from identity server if any, ignoring errors
+            runCatching { identityDisconnectTask.execute(Unit) }
+                    .onFailure { Timber.w(it, "Unable to disconnect identity server") }
+
+            cleanupSession.handle()
+        }
     }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DefaultAccountService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DefaultAccountService.kt
index 25b67159a9fa1cf4f61dda94139f61501bacab03..dc77d7bffb07b5fcf85120e35e90df3613f4628d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DefaultAccountService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DefaultAccountService.kt
@@ -27,7 +27,7 @@ internal class DefaultAccountService @Inject constructor(private val changePassw
         changePasswordTask.execute(ChangePasswordTask.Params(password, newPassword))
     }
 
-    override suspend fun deactivateAccount(userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor, eraseAllData: Boolean) {
-        deactivateAccountTask.execute(DeactivateAccountTask.Params(userInteractiveAuthInterceptor, eraseAllData))
+    override suspend fun deactivateAccount(eraseAllData: Boolean, userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor) {
+        deactivateAccountTask.execute(DeactivateAccountTask.Params(eraseAllData, userInteractiveAuthInterceptor))
     }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt
index f789a6450059ec6b370cbbc0904739126cf0d5b6..4887351709ffde85aa2ccdb66e03cca66de8ce1a 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt
@@ -16,28 +16,30 @@
 
 package org.matrix.android.sdk.internal.session.call
 
+import io.realm.Realm
 import org.matrix.android.sdk.api.session.events.model.Event
 import org.matrix.android.sdk.api.session.events.model.EventType
 import org.matrix.android.sdk.internal.database.model.EventInsertType
-import org.matrix.android.sdk.internal.di.UserId
 import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor
-import io.realm.Realm
 import timber.log.Timber
 import javax.inject.Inject
 
-internal class CallEventProcessor @Inject constructor(
-        @UserId private val userId: String,
-        private val callService: DefaultCallSignalingService
-) : EventInsertLiveProcessor {
+internal class CallEventProcessor @Inject constructor(private val callSignalingHandler: CallSignalingHandler)
+    : EventInsertLiveProcessor {
 
     private val allowedTypes = listOf(
             EventType.CALL_ANSWER,
+            EventType.CALL_SELECT_ANSWER,
+            EventType.CALL_REJECT,
+            EventType.CALL_NEGOTIATE,
             EventType.CALL_CANDIDATES,
             EventType.CALL_INVITE,
             EventType.CALL_HANGUP,
             EventType.ENCRYPTED
     )
 
+    private val eventsToPostProcess = mutableListOf<Event>()
+
     override fun shouldProcess(eventId: String, eventType: String, insertType: EventInsertType): Boolean {
         if (insertType != EventInsertType.INCREMENTAL_SYNC) {
             return false
@@ -46,10 +48,17 @@ internal class CallEventProcessor @Inject constructor(
     }
 
     override suspend fun process(realm: Realm, event: Event) {
-        update(realm, event)
+        eventsToPostProcess.add(event)
     }
 
-    private fun update(realm: Realm, event: Event) {
+    override suspend fun onPostProcess() {
+        eventsToPostProcess.forEach {
+            dispatchToCallSignalingHandlerIfNeeded(it)
+        }
+        eventsToPostProcess.clear()
+    }
+
+    private fun dispatchToCallSignalingHandlerIfNeeded(event: Event) {
         val now = System.currentTimeMillis()
         // TODO might check if an invite is not closed (hangup/answsered) in the same event batch?
         event.roomId ?: return Unit.also {
@@ -60,10 +69,6 @@ internal class CallEventProcessor @Inject constructor(
             // To old to ring?
             return
         }
-        event.ageLocalTs
-        if (EventType.isCallEvent(event.getClearType())) {
-            callService.onCallEvent(event)
-        }
-        Timber.v("$realm : $userId")
+        callSignalingHandler.onCallEvent(event)
     }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallListenersDispatcher.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallListenersDispatcher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1de2d8a106e66beeb21fec80d3abc7d85d88e2dd
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallListenersDispatcher.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.call
+
+import org.matrix.android.sdk.api.extensions.tryOrNull
+import org.matrix.android.sdk.api.session.call.CallListener
+import org.matrix.android.sdk.api.session.call.MxCall
+import org.matrix.android.sdk.api.session.room.model.call.CallAnswerContent
+import org.matrix.android.sdk.api.session.room.model.call.CallCandidatesContent
+import org.matrix.android.sdk.api.session.room.model.call.CallHangupContent
+import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent
+import org.matrix.android.sdk.api.session.room.model.call.CallNegotiateContent
+import org.matrix.android.sdk.api.session.room.model.call.CallRejectContent
+import org.matrix.android.sdk.api.session.room.model.call.CallSelectAnswerContent
+
+/**
+ * Dispatch each method safely to all listeners.
+ */
+internal class CallListenersDispatcher(private val listeners: Set<CallListener>) : CallListener {
+
+    override fun onCallInviteReceived(mxCall: MxCall, callInviteContent: CallInviteContent) = dispatch {
+        it.onCallInviteReceived(mxCall, callInviteContent)
+    }
+
+    override fun onCallIceCandidateReceived(mxCall: MxCall, iceCandidatesContent: CallCandidatesContent) = dispatch {
+        it.onCallIceCandidateReceived(mxCall, iceCandidatesContent)
+    }
+
+    override fun onCallAnswerReceived(callAnswerContent: CallAnswerContent) = dispatch {
+        it.onCallAnswerReceived(callAnswerContent)
+    }
+
+    override fun onCallHangupReceived(callHangupContent: CallHangupContent) = dispatch {
+        it.onCallHangupReceived(callHangupContent)
+    }
+
+    override fun onCallRejectReceived(callRejectContent: CallRejectContent) = dispatch {
+        it.onCallRejectReceived(callRejectContent)
+    }
+
+    override fun onCallManagedByOtherSession(callId: String) = dispatch {
+        it.onCallManagedByOtherSession(callId)
+    }
+
+    override fun onCallSelectAnswerReceived(callSelectAnswerContent: CallSelectAnswerContent) = dispatch {
+        it.onCallSelectAnswerReceived(callSelectAnswerContent)
+    }
+
+    override fun onCallNegotiateReceived(callNegotiateContent: CallNegotiateContent) = dispatch {
+        it.onCallNegotiateReceived(callNegotiateContent)
+    }
+
+    private fun dispatch(lambda: (CallListener) -> Unit) {
+        listeners.toList().forEach {
+            tryOrNull {
+                lambda(it)
+            }
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt
new file mode 100644
index 0000000000000000000000000000000000000000..7e54301f63e7d27522e52bd1532bfc7a99d0b8d0
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.call
+
+import org.matrix.android.sdk.api.session.call.CallListener
+import org.matrix.android.sdk.api.session.call.CallState
+import org.matrix.android.sdk.api.session.call.MxCall
+import org.matrix.android.sdk.api.session.events.model.Event
+import org.matrix.android.sdk.api.session.events.model.EventType
+import org.matrix.android.sdk.api.session.events.model.toModel
+import org.matrix.android.sdk.api.session.room.model.call.CallAnswerContent
+import org.matrix.android.sdk.api.session.room.model.call.CallCandidatesContent
+import org.matrix.android.sdk.api.session.room.model.call.CallCapabilities
+import org.matrix.android.sdk.api.session.room.model.call.CallHangupContent
+import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent
+import org.matrix.android.sdk.api.session.room.model.call.CallNegotiateContent
+import org.matrix.android.sdk.api.session.room.model.call.CallRejectContent
+import org.matrix.android.sdk.api.session.room.model.call.CallSelectAnswerContent
+import org.matrix.android.sdk.api.session.room.model.call.CallSignallingContent
+import org.matrix.android.sdk.api.util.Optional
+import org.matrix.android.sdk.internal.di.UserId
+import org.matrix.android.sdk.internal.session.SessionScope
+import timber.log.Timber
+import java.math.BigDecimal
+import javax.inject.Inject
+
+@SessionScope
+internal class CallSignalingHandler @Inject constructor(private val activeCallHandler: ActiveCallHandler,
+                                                        private val mxCallFactory: MxCallFactory,
+                                                        @UserId private val userId: String) {
+
+    private val callListeners = mutableSetOf<CallListener>()
+    private val callListenersDispatcher = CallListenersDispatcher(callListeners)
+
+    fun addCallListener(listener: CallListener) {
+        callListeners.add(listener)
+    }
+
+    fun removeCallListener(listener: CallListener) {
+        callListeners.remove(listener)
+    }
+
+    fun onCallEvent(event: Event) {
+        when (event.getClearType()) {
+            EventType.CALL_ANSWER -> {
+                handleCallAnswerEvent(event)
+            }
+            EventType.CALL_INVITE -> {
+                handleCallInviteEvent(event)
+            }
+            EventType.CALL_HANGUP -> {
+                handleCallHangupEvent(event)
+            }
+            EventType.CALL_REJECT -> {
+                handleCallRejectEvent(event)
+            }
+            EventType.CALL_CANDIDATES -> {
+                handleCallCandidatesEvent(event)
+            }
+            EventType.CALL_SELECT_ANSWER -> {
+                handleCallSelectAnswerEvent(event)
+            }
+            EventType.CALL_NEGOTIATE -> {
+                handleCallNegotiateEvent(event)
+            }
+        }
+    }
+
+    private fun handleCallNegotiateEvent(event: Event) {
+        val content = event.getClearContent().toModel<CallNegotiateContent>() ?: return
+        val call = content.getCall() ?: return
+        if (call.ourPartyId == content.partyId) {
+            // Ignore remote echo
+            return
+        }
+        callListenersDispatcher.onCallNegotiateReceived(content)
+    }
+
+    private fun handleCallSelectAnswerEvent(event: Event) {
+        val content = event.getClearContent().toModel<CallSelectAnswerContent>() ?: return
+        val call = content.getCall() ?: return
+        if (call.ourPartyId == content.partyId) {
+            // Ignore remote echo
+            return
+        }
+        if (call.isOutgoing) {
+            Timber.v("Got selectAnswer for an outbound call: ignoring")
+            return
+        }
+        val selectedPartyId = content.selectedPartyId
+        if (selectedPartyId == null) {
+            Timber.w("Got nonsensical select_answer with null selected_party_id: ignoring")
+            return
+        }
+        callListenersDispatcher.onCallSelectAnswerReceived(content)
+    }
+
+    private fun handleCallCandidatesEvent(event: Event) {
+        val content = event.getClearContent().toModel<CallCandidatesContent>() ?: return
+        val call = content.getCall() ?: return
+        if (call.ourPartyId == content.partyId) {
+            // Ignore remote echo
+            return
+        }
+        if (call.opponentPartyId != null && !call.partyIdsMatches(content)) {
+            Timber.v("Ignoring candidates from party ID ${content.partyId} we have chosen party ID ${call.opponentPartyId}")
+            return
+        }
+        callListenersDispatcher.onCallIceCandidateReceived(call, content)
+    }
+
+    private fun handleCallRejectEvent(event: Event) {
+        val content = event.getClearContent().toModel<CallRejectContent>() ?: return
+        val call = content.getCall() ?: return
+        if (call.ourPartyId == content.partyId) {
+            // Ignore remote echo
+            return
+        }
+        activeCallHandler.removeCall(content.callId)
+        if (event.senderId == userId) {
+            // discard current call, it's rejected by another of my session
+            callListenersDispatcher.onCallManagedByOtherSession(content.callId)
+            return
+        }
+        // No need to check party_id for reject because if we'd received either
+        // an answer or reject, we wouldn't be in state InviteSent
+        if (call.state != CallState.Dialing) {
+            return
+        }
+        callListenersDispatcher.onCallRejectReceived(content)
+    }
+
+    private fun handleCallHangupEvent(event: Event) {
+        val content = event.getClearContent().toModel<CallHangupContent>() ?: return
+        val call = content.getCall() ?: return
+        // party ID must match (our chosen partner hanging up the call) or be undefined (we haven't chosen
+        // a partner yet but we're treating the hangup as a reject as per VoIP v0)
+        if (call.opponentPartyId != null && !call.partyIdsMatches(content)) {
+            Timber.v("Ignoring hangup from party ID ${content.partyId} we have chosen party ID ${call.opponentPartyId}")
+            return
+        }
+        if (call.state != CallState.Terminated) {
+            activeCallHandler.removeCall(content.callId)
+            callListenersDispatcher.onCallHangupReceived(content)
+        }
+    }
+
+    private fun handleCallInviteEvent(event: Event) {
+        if (event.senderId == userId) {
+            // ignore invites you send
+            return
+        }
+        if (event.roomId == null || event.senderId == null) {
+            return
+        }
+        val content = event.getClearContent().toModel<CallInviteContent>() ?: return
+        val incomingCall = mxCallFactory.createIncomingCall(
+                roomId = event.roomId,
+                opponentUserId = event.senderId,
+                content = content
+        ) ?: return
+        activeCallHandler.addCall(incomingCall)
+        callListenersDispatcher.onCallInviteReceived(incomingCall, content)
+    }
+
+    private fun handleCallAnswerEvent(event: Event) {
+        val content = event.getClearContent().toModel<CallAnswerContent>() ?: return
+        val call = content.getCall() ?: return
+        if (call.ourPartyId == content.partyId) {
+            // Ignore remote echo
+            return
+        }
+        if (event.senderId == userId) {
+            // discard current call, it's answered by another of my session
+            activeCallHandler.removeCall(call.callId)
+            callListenersDispatcher.onCallManagedByOtherSession(content.callId)
+        } else {
+            if (call.opponentPartyId != null) {
+                Timber.v("Ignoring answer from party ID ${content.partyId} we already have an answer from ${call.opponentPartyId}")
+                return
+            }
+            call.apply {
+                opponentPartyId = Optional.from(content.partyId)
+                opponentVersion = content.version?.let { BigDecimal(it).intValueExact() } ?: MxCall.VOIP_PROTO_VERSION
+                capabilities = content.capabilities ?: CallCapabilities()
+            }
+            callListenersDispatcher.onCallAnswerReceived(content)
+        }
+    }
+
+    private fun MxCall.partyIdsMatches(contentSignallingContent: CallSignallingContent): Boolean {
+        return opponentPartyId?.getOrNull() == contentSignallingContent.partyId
+    }
+
+    private fun CallSignallingContent.getCall(): MxCall? {
+        val currentCall = callId?.let {
+            activeCallHandler.getCallWithId(it)
+        }
+        if (currentCall == null) {
+            Timber.v("Call with id $callId is null")
+        }
+        return currentCall
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt
index 019da27d27efc20511c2f2e8eb4bba50cfeba2c8..7d046cb6422e15e0028653e16fa395ed27770919 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt
@@ -16,106 +16,44 @@
 
 package org.matrix.android.sdk.internal.session.call
 
-import android.os.SystemClock
-import org.matrix.android.sdk.api.MatrixCallback
-import org.matrix.android.sdk.api.extensions.tryOrNull
+import org.matrix.android.sdk.api.session.call.CallListener
 import org.matrix.android.sdk.api.session.call.CallSignalingService
-import org.matrix.android.sdk.api.session.call.CallState
-import org.matrix.android.sdk.api.session.call.CallsListener
 import org.matrix.android.sdk.api.session.call.MxCall
+import org.matrix.android.sdk.api.session.call.PSTNProtocolChecker
 import org.matrix.android.sdk.api.session.call.TurnServerResponse
-import org.matrix.android.sdk.api.session.events.model.Event
-import org.matrix.android.sdk.api.session.events.model.EventType
-import org.matrix.android.sdk.api.session.events.model.toModel
-import org.matrix.android.sdk.api.session.room.model.call.CallAnswerContent
-import org.matrix.android.sdk.api.session.room.model.call.CallCandidatesContent
-import org.matrix.android.sdk.api.session.room.model.call.CallHangupContent
-import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent
-import org.matrix.android.sdk.api.util.Cancelable
-import org.matrix.android.sdk.api.util.NoOpCancellable
-import org.matrix.android.sdk.internal.di.UserId
 import org.matrix.android.sdk.internal.session.SessionScope
-import org.matrix.android.sdk.internal.session.call.model.MxCallImpl
-import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
-import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory
-import org.matrix.android.sdk.internal.task.TaskExecutor
-import org.matrix.android.sdk.internal.task.configureWith
 import timber.log.Timber
-import java.util.UUID
 import javax.inject.Inject
 
 @SessionScope
 internal class DefaultCallSignalingService @Inject constructor(
-        @UserId
-        private val userId: String,
+        private val callSignalingHandler: CallSignalingHandler,
+        private val mxCallFactory: MxCallFactory,
         private val activeCallHandler: ActiveCallHandler,
-        private val localEchoEventFactory: LocalEchoEventFactory,
-        private val eventSenderProcessor: EventSenderProcessor,
-        private val taskExecutor: TaskExecutor,
-        private val turnServerTask: GetTurnServerTask
+        private val turnServerDataSource: TurnServerDataSource,
+        private val pstnProtocolChecker: PSTNProtocolChecker
 ) : CallSignalingService {
 
-    private val callListeners = mutableSetOf<CallsListener>()
-
-    private val cachedTurnServerResponse = object {
-        // Keep one minute safe to avoid considering the data is valid and then actually it is not when effectively using it.
-        private val MIN_TTL = 60
-
-        private val now = { SystemClock.elapsedRealtime() / 1000 }
-
-        private var expiresAt: Long = 0
-
-        var data: TurnServerResponse? = null
-            get() = if (expiresAt > now()) field else null
-            set(value) {
-                expiresAt = now() + (value?.ttl ?: 0) - MIN_TTL
-                field = value
-            }
+    override suspend fun getTurnServer(): TurnServerResponse {
+        return turnServerDataSource.getTurnServer()
     }
 
-    override fun getTurnServer(callback: MatrixCallback<TurnServerResponse>): Cancelable {
-        if (cachedTurnServerResponse.data != null) {
-            cachedTurnServerResponse.data?.let { callback.onSuccess(it) }
-            return NoOpCancellable
-        }
-        return turnServerTask
-                .configureWith(GetTurnServerTask.Params) {
-                    this.callback = object : MatrixCallback<TurnServerResponse> {
-                        override fun onSuccess(data: TurnServerResponse) {
-                            cachedTurnServerResponse.data = data
-                            callback.onSuccess(data)
-                        }
-
-                        override fun onFailure(failure: Throwable) {
-                            callback.onFailure(failure)
-                        }
-                    }
-                }
-                .executeBy(taskExecutor)
+    override fun getPSTNProtocolChecker(): PSTNProtocolChecker {
+        return pstnProtocolChecker
     }
 
     override fun createOutgoingCall(roomId: String, otherUserId: String, isVideoCall: Boolean): MxCall {
-        val call = MxCallImpl(
-                callId = UUID.randomUUID().toString(),
-                isOutgoing = true,
-                roomId = roomId,
-                userId = userId,
-                otherUserId = otherUserId,
-                isVideoCall = isVideoCall,
-                localEchoEventFactory = localEchoEventFactory,
-                eventSenderProcessor = eventSenderProcessor
-        )
-        activeCallHandler.addCall(call).also {
-            return call
+        return mxCallFactory.createOutgoingCall(roomId, otherUserId, isVideoCall).also {
+            activeCallHandler.addCall(it)
         }
     }
 
-    override fun addCallListener(listener: CallsListener) {
-        callListeners.add(listener)
+    override fun addCallListener(listener: CallListener) {
+        callSignalingHandler.addCallListener(listener)
     }
 
-    override fun removeCallListener(listener: CallsListener) {
-        callListeners.remove(listener)
+    override fun removeCallListener(listener: CallListener) {
+        callSignalingHandler.removeCallListener(listener)
     }
 
     override fun getCallWithId(callId: String): MxCall? {
@@ -127,129 +65,6 @@ internal class DefaultCallSignalingService @Inject constructor(
         return activeCallHandler.getActiveCallsLiveData().value?.isNotEmpty() == true
     }
 
-    internal fun onCallEvent(event: Event) {
-        when (event.getClearType()) {
-            EventType.CALL_ANSWER     -> {
-                event.getClearContent().toModel<CallAnswerContent>()?.let {
-                    if (event.senderId == userId) {
-                        // ok it's an answer from me.. is it remote echo or other session
-                        val knownCall = getCallWithId(it.callId)
-                        if (knownCall == null) {
-                            Timber.d("## VOIP onCallEvent ${event.getClearType()} id ${it.callId} send by me")
-                        } else if (!knownCall.isOutgoing) {
-                            // incoming call
-                            // if it was anwsered by this session, the call state would be in Answering(or connected) state
-                            if (knownCall.state == CallState.LocalRinging) {
-                                // discard current call, it's answered by another of my session
-                                onCallManageByOtherSession(it.callId)
-                            }
-                        }
-                        return
-                    }
-
-                    onCallAnswer(it)
-                }
-            }
-            EventType.CALL_INVITE     -> {
-                if (event.senderId == userId) {
-                    // Always ignore local echos of invite
-                    return
-                }
-
-                event.getClearContent().toModel<CallInviteContent>()?.let { content ->
-                    val incomingCall = MxCallImpl(
-                            callId = content.callId ?: return@let,
-                            isOutgoing = false,
-                            roomId = event.roomId ?: return@let,
-                            userId = userId,
-                            otherUserId = event.senderId ?: return@let,
-                            isVideoCall = content.isVideo(),
-                            localEchoEventFactory = localEchoEventFactory,
-                            eventSenderProcessor = eventSenderProcessor
-                    )
-                    activeCallHandler.addCall(incomingCall)
-                    onCallInvite(incomingCall, content)
-                }
-            }
-            EventType.CALL_HANGUP     -> {
-                event.getClearContent().toModel<CallHangupContent>()?.let { content ->
-
-                    if (event.senderId == userId) {
-                        // ok it's an answer from me.. is it remote echo or other session
-                        val knownCall = getCallWithId(content.callId)
-                        if (knownCall == null) {
-                            Timber.d("## VOIP onCallEvent ${event.getClearType()} id ${content.callId} send by me")
-                        } else if (!knownCall.isOutgoing) {
-                            // incoming call
-                            if (knownCall.state == CallState.LocalRinging) {
-                                // discard current call, it's answered by another of my session
-                                onCallManageByOtherSession(content.callId)
-                            }
-                        }
-                        return
-                    }
-
-                    activeCallHandler.removeCall(content.callId)
-                    onCallHangup(content)
-                }
-            }
-            EventType.CALL_CANDIDATES -> {
-                if (event.senderId == userId) {
-                    // Always ignore local echos of invite
-                    return
-                }
-                event.getClearContent().toModel<CallCandidatesContent>()?.let { content ->
-                    activeCallHandler.getCallWithId(content.callId)?.let {
-                        onCallIceCandidate(it, content)
-                    }
-                }
-            }
-        }
-    }
-
-    private fun onCallHangup(hangup: CallHangupContent) {
-        callListeners.toList().forEach {
-            tryOrNull {
-                it.onCallHangupReceived(hangup)
-            }
-        }
-    }
-
-    private fun onCallAnswer(answer: CallAnswerContent) {
-        callListeners.toList().forEach {
-            tryOrNull {
-                it.onCallAnswerReceived(answer)
-            }
-        }
-    }
-
-    private fun onCallManageByOtherSession(callId: String) {
-        callListeners.toList().forEach {
-            tryOrNull {
-                it.onCallManagedByOtherSession(callId)
-            }
-        }
-    }
-
-    private fun onCallInvite(incomingCall: MxCall, invite: CallInviteContent) {
-        // Ignore the invitation from current user
-        if (incomingCall.otherUserId == userId) return
-
-        callListeners.toList().forEach {
-            tryOrNull {
-                it.onCallInviteReceived(incomingCall, invite)
-            }
-        }
-    }
-
-    private fun onCallIceCandidate(incomingCall: MxCall, candidates: CallCandidatesContent) {
-        callListeners.toList().forEach {
-            tryOrNull {
-                it.onCallIceCandidateReceived(incomingCall, candidates)
-            }
-        }
-    }
-
     companion object {
         const val CALL_TIMEOUT_MS = 120_000
     }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/MxCallFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/MxCallFactory.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b14cdca63c5c6e059600b8e635019afdc6248a82
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/MxCallFactory.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.call
+
+import org.matrix.android.sdk.api.MatrixConfiguration
+import org.matrix.android.sdk.api.session.call.MxCall
+import org.matrix.android.sdk.api.session.room.model.call.CallCapabilities
+import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent
+import org.matrix.android.sdk.api.util.Optional
+import org.matrix.android.sdk.internal.di.DeviceId
+import org.matrix.android.sdk.internal.di.UserId
+import org.matrix.android.sdk.internal.session.call.model.MxCallImpl
+import org.matrix.android.sdk.internal.session.profile.GetProfileInfoTask
+import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory
+import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
+import java.math.BigDecimal
+import java.util.UUID
+import javax.inject.Inject
+
+internal class MxCallFactory @Inject constructor(
+        @DeviceId private val deviceId: String?,
+        private val localEchoEventFactory: LocalEchoEventFactory,
+        private val eventSenderProcessor: EventSenderProcessor,
+        private val matrixConfiguration: MatrixConfiguration,
+        private val getProfileInfoTask: GetProfileInfoTask,
+        @UserId private val userId: String
+) {
+
+    fun createIncomingCall(roomId: String, opponentUserId: String, content: CallInviteContent): MxCall? {
+        content.callId ?: return null
+        return MxCallImpl(
+                callId = content.callId,
+                isOutgoing = false,
+                roomId = roomId,
+                userId = userId,
+                ourPartyId = deviceId ?: "",
+                opponentUserId = opponentUserId,
+                isVideoCall = content.isVideo(),
+                localEchoEventFactory = localEchoEventFactory,
+                eventSenderProcessor = eventSenderProcessor,
+                matrixConfiguration = matrixConfiguration,
+                getProfileInfoTask = getProfileInfoTask
+        ).apply {
+            opponentPartyId = Optional.from(content.partyId)
+            opponentVersion = content.version?.let { BigDecimal(it).intValueExact() } ?: MxCall.VOIP_PROTO_VERSION
+            capabilities = content.capabilities ?: CallCapabilities()
+        }
+    }
+
+    fun createOutgoingCall(roomId: String, opponentUserId: String, isVideoCall: Boolean): MxCall {
+        return MxCallImpl(
+                callId = UUID.randomUUID().toString(),
+                isOutgoing = true,
+                roomId = roomId,
+                userId = userId,
+                ourPartyId = deviceId ?: "",
+                opponentUserId = opponentUserId,
+                isVideoCall = isVideoCall,
+                localEchoEventFactory = localEchoEventFactory,
+                eventSenderProcessor = eventSenderProcessor,
+                matrixConfiguration = matrixConfiguration,
+                getProfileInfoTask = getProfileInfoTask
+        )
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/TurnServerDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/TurnServerDataSource.kt
new file mode 100644
index 0000000000000000000000000000000000000000..8e2ac5e17e7626dc04ef64d1285d08d1d8cbc24c
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/TurnServerDataSource.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.call
+
+import android.os.SystemClock
+import org.matrix.android.sdk.api.session.call.TurnServerResponse
+import javax.inject.Inject
+
+internal class TurnServerDataSource @Inject constructor(private val turnServerTask: GetTurnServerTask) {
+
+    private val cachedTurnServerResponse = object {
+        // Keep one minute safe to avoid considering the data is valid and then actually it is not when effectively using it.
+        private val MIN_TTL = 60
+
+        private val now = { SystemClock.elapsedRealtime() / 1000 }
+
+        private var expiresAt: Long = 0
+
+        var data: TurnServerResponse? = null
+            get() = if (expiresAt > now()) field else null
+            set(value) {
+                expiresAt = now() + (value?.ttl ?: 0) - MIN_TTL
+                field = value
+            }
+    }
+
+    suspend fun getTurnServer(): TurnServerResponse {
+        return cachedTurnServerResponse.data ?: turnServerTask.execute(GetTurnServerTask.Params).also {
+            cachedTurnServerResponse.data = it
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/model/MxCallImpl.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/model/MxCallImpl.kt
index 6c0d437a60103d9d4d79a6f08218e2e15d84324a..88fba0ea859a3ed43c5fa91d73fbf159912a6303 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/model/MxCallImpl.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/model/MxCallImpl.kt
@@ -16,6 +16,7 @@
 
 package org.matrix.android.sdk.internal.session.call.model
 
+import org.matrix.android.sdk.api.MatrixConfiguration
 import org.matrix.android.sdk.api.session.call.CallState
 import org.matrix.android.sdk.api.session.call.MxCall
 import org.matrix.android.sdk.api.session.events.model.Content
@@ -24,28 +25,44 @@ import org.matrix.android.sdk.api.session.events.model.EventType
 import org.matrix.android.sdk.api.session.events.model.LocalEcho
 import org.matrix.android.sdk.api.session.events.model.UnsignedData
 import org.matrix.android.sdk.api.session.events.model.toContent
+import org.matrix.android.sdk.api.session.profile.ProfileService
 import org.matrix.android.sdk.api.session.room.model.call.CallAnswerContent
+import org.matrix.android.sdk.api.session.room.model.call.CallCandidate
 import org.matrix.android.sdk.api.session.room.model.call.CallCandidatesContent
+import org.matrix.android.sdk.api.session.room.model.call.CallCapabilities
 import org.matrix.android.sdk.api.session.room.model.call.CallHangupContent
 import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent
+import org.matrix.android.sdk.api.session.room.model.call.CallNegotiateContent
+import org.matrix.android.sdk.api.session.room.model.call.CallRejectContent
+import org.matrix.android.sdk.api.session.room.model.call.CallReplacesContent
+import org.matrix.android.sdk.api.session.room.model.call.CallSelectAnswerContent
+import org.matrix.android.sdk.api.session.room.model.call.SdpType
+import org.matrix.android.sdk.api.util.Optional
 import org.matrix.android.sdk.internal.session.call.DefaultCallSignalingService
-import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
+import org.matrix.android.sdk.internal.session.profile.GetProfileInfoTask
 import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory
-import org.webrtc.IceCandidate
-import org.webrtc.SessionDescription
+import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
 import timber.log.Timber
+import java.util.UUID
 
 internal class MxCallImpl(
         override val callId: String,
         override val isOutgoing: Boolean,
         override val roomId: String,
         private val userId: String,
-        override val otherUserId: String,
+        override val opponentUserId: String,
         override val isVideoCall: Boolean,
+        override val ourPartyId: String,
         private val localEchoEventFactory: LocalEchoEventFactory,
-        private val eventSenderProcessor: EventSenderProcessor
+        private val eventSenderProcessor: EventSenderProcessor,
+        private val matrixConfiguration: MatrixConfiguration,
+        private val getProfileInfoTask: GetProfileInfoTask
 ) : MxCall {
 
+    override var opponentPartyId: Optional<String>? = null
+    override var opponentVersion: Int = MxCall.VOIP_PROTO_VERSION
+    override var capabilities: CallCapabilities? = null
+
     override var state: CallState = CallState.Idle
         set(value) {
             field = value
@@ -81,60 +98,135 @@ internal class MxCallImpl(
         }
     }
 
-    override fun offerSdp(sdp: SessionDescription) {
+    override fun offerSdp(sdpString: String) {
         if (!isOutgoing) return
         Timber.v("## VOIP offerSdp $callId")
         state = CallState.Dialing
         CallInviteContent(
                 callId = callId,
+                partyId = ourPartyId,
                 lifetime = DefaultCallSignalingService.CALL_TIMEOUT_MS,
-                offer = CallInviteContent.Offer(sdp = sdp.description)
+                offer = CallInviteContent.Offer(sdp = sdpString),
+                version = MxCall.VOIP_PROTO_VERSION.toString(),
+                capabilities = buildCapabilities()
         )
                 .let { createEventAndLocalEcho(type = EventType.CALL_INVITE, roomId = roomId, content = it.toContent()) }
                 .also { eventSenderProcessor.postEvent(it) }
     }
 
-    override fun sendLocalIceCandidates(candidates: List<IceCandidate>) {
+    override fun sendLocalCallCandidates(candidates: List<CallCandidate>) {
+        Timber.v("Send local call canditates $callId: $candidates")
         CallCandidatesContent(
                 callId = callId,
-                candidates = candidates.map {
-                    CallCandidatesContent.Candidate(
-                            sdpMid = it.sdpMid,
-                            sdpMLineIndex = it.sdpMLineIndex,
-                            candidate = it.sdp
-                    )
-                }
+                partyId = ourPartyId,
+                candidates = candidates,
+                version = MxCall.VOIP_PROTO_VERSION.toString()
         )
                 .let { createEventAndLocalEcho(type = EventType.CALL_CANDIDATES, roomId = roomId, content = it.toContent()) }
                 .also { eventSenderProcessor.postEvent(it) }
     }
 
-    override fun sendLocalIceCandidateRemovals(candidates: List<IceCandidate>) {
+    override fun sendLocalIceCandidateRemovals(candidates: List<CallCandidate>) {
         // For now we don't support this flow
     }
 
-    override fun hangUp() {
+    override fun reject() {
+        if (opponentVersion < 1) {
+            Timber.v("Opponent version is less than 1 ($opponentVersion): sending hangup instead of reject")
+            hangUp()
+            return
+        }
+        Timber.v("## VOIP reject $callId")
+        CallRejectContent(
+                callId = callId,
+                partyId = ourPartyId,
+                version = MxCall.VOIP_PROTO_VERSION.toString()
+        )
+                .let { createEventAndLocalEcho(type = EventType.CALL_REJECT, roomId = roomId, content = it.toContent()) }
+                .also { eventSenderProcessor.postEvent(it) }
+        state = CallState.Terminated
+    }
+
+    override fun hangUp(reason: CallHangupContent.Reason?) {
         Timber.v("## VOIP hangup $callId")
         CallHangupContent(
-                callId = callId
+                callId = callId,
+                partyId = ourPartyId,
+                reason = reason ?: CallHangupContent.Reason.USER_HANGUP,
+                version = MxCall.VOIP_PROTO_VERSION.toString()
         )
                 .let { createEventAndLocalEcho(type = EventType.CALL_HANGUP, roomId = roomId, content = it.toContent()) }
                 .also { eventSenderProcessor.postEvent(it) }
         state = CallState.Terminated
     }
 
-    override fun accept(sdp: SessionDescription) {
+    override fun accept(sdpString: String) {
         Timber.v("## VOIP accept $callId")
         if (isOutgoing) return
         state = CallState.Answering
         CallAnswerContent(
                 callId = callId,
-                answer = CallAnswerContent.Answer(sdp = sdp.description)
+                partyId = ourPartyId,
+                answer = CallAnswerContent.Answer(sdp = sdpString),
+                version = MxCall.VOIP_PROTO_VERSION.toString(),
+                capabilities = buildCapabilities()
         )
                 .let { createEventAndLocalEcho(type = EventType.CALL_ANSWER, roomId = roomId, content = it.toContent()) }
                 .also { eventSenderProcessor.postEvent(it) }
     }
 
+    override fun negotiate(sdpString: String, type: SdpType) {
+        Timber.v("## VOIP negotiate $callId")
+        CallNegotiateContent(
+                callId = callId,
+                partyId = ourPartyId,
+                lifetime = DefaultCallSignalingService.CALL_TIMEOUT_MS,
+                description = CallNegotiateContent.Description(sdp = sdpString, type = type),
+                version = MxCall.VOIP_PROTO_VERSION.toString()
+        )
+                .let { createEventAndLocalEcho(type = EventType.CALL_NEGOTIATE, roomId = roomId, content = it.toContent()) }
+                .also { eventSenderProcessor.postEvent(it) }
+    }
+
+    override fun selectAnswer() {
+        Timber.v("## VOIP select answer $callId")
+        if (isOutgoing) return
+        state = CallState.Answering
+        CallSelectAnswerContent(
+                callId = callId,
+                partyId = ourPartyId,
+                selectedPartyId = opponentPartyId?.getOrNull(),
+                version = MxCall.VOIP_PROTO_VERSION.toString()
+        )
+                .let { createEventAndLocalEcho(type = EventType.CALL_SELECT_ANSWER, roomId = roomId, content = it.toContent()) }
+                .also { eventSenderProcessor.postEvent(it) }
+    }
+
+    override suspend fun transfer(targetUserId: String, targetRoomId: String?) {
+        val profileInfoParams = GetProfileInfoTask.Params(targetUserId)
+        val profileInfo = try {
+            getProfileInfoTask.execute(profileInfoParams)
+        } catch (failure: Throwable) {
+            Timber.v("Fail fetching profile info of $targetUserId while transferring call")
+            null
+        }
+        CallReplacesContent(
+                callId = callId,
+                partyId = ourPartyId,
+                replacementId = UUID.randomUUID().toString(),
+                version = MxCall.VOIP_PROTO_VERSION.toString(),
+                targetUser = CallReplacesContent.TargetUser(
+                        id = targetUserId,
+                        displayName = profileInfo?.get(ProfileService.DISPLAY_NAME_KEY) as? String,
+                        avatarUrl = profileInfo?.get(ProfileService.AVATAR_URL_KEY) as? String
+                ),
+                targerRoomId = targetRoomId,
+                createCall = UUID.randomUUID().toString()
+        )
+                .let { createEventAndLocalEcho(type = EventType.CALL_REPLACES, roomId = roomId, content = it.toContent()) }
+                .also { eventSenderProcessor.postEvent(it) }
+    }
+
     private fun createEventAndLocalEcho(localId: String = LocalEcho.createLocalEchoId(), type: String, roomId: String, content: Content): Event {
         return Event(
                 roomId = roomId,
@@ -147,4 +239,12 @@ internal class MxCallImpl(
         )
                 .also { localEchoEventFactory.createLocalEcho(it) }
     }
+
+    private fun buildCapabilities(): CallCapabilities? {
+        return if (matrixConfiguration.supportsCallTransfer) {
+            CallCapabilities(true)
+        } else {
+            null
+        }
+    }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterFactory.kt
index 2eac0a5059ca147819aacc3dd05bd28c89cfa495..7415b988a43eadd878a12006e35328445aea2da5 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterFactory.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterFactory.kt
@@ -33,11 +33,11 @@ internal object FilterFactory {
         return FilterUtil.enableLazyLoading(Filter(), true)
     }
 
-    fun createRiotFilter(): Filter {
+    fun createElementFilter(): Filter {
         return Filter(
                 room = RoomFilter(
-                        timeline = createRiotTimelineFilter(),
-                        state = createRiotStateFilter()
+                        timeline = createElementTimelineFilter(),
+                        state = createElementStateFilter()
                 )
         )
     }
@@ -48,7 +48,7 @@ internal object FilterFactory {
         )
     }
 
-    fun createRiotRoomFilter(): RoomEventFilter {
+    fun createElementRoomFilter(): RoomEventFilter {
         return RoomEventFilter(
                 lazyLoadMembers = true
                 // TODO Enable this for optimization
@@ -56,26 +56,26 @@ internal object FilterFactory {
         )
     }
 
-    private fun createRiotTimelineFilter(): RoomEventFilter {
-        return RoomEventFilter().apply {
+    private fun createElementTimelineFilter(): RoomEventFilter? {
+        return null // RoomEventFilter().apply {
             // TODO Enable this for optimization
             // types = listOfSupportedEventTypes.toMutableList()
-        }
+        // }
     }
 
-    private fun createRiotStateFilter(): RoomEventFilter {
+    private fun createElementStateFilter(): RoomEventFilter {
         return RoomEventFilter(
                 lazyLoadMembers = true
         )
     }
 
-    // Get only managed types by Riot
+    // Get only managed types by Element
     private val listOfSupportedEventTypes = listOf(
             // TODO Complete the list
             EventType.MESSAGE
     )
 
-    // Get only managed types by Riot
+    // Get only managed types by Element
     private val listOfSupportedStateEventTypes = listOf(
             // TODO Complete the list
             EventType.STATE_ROOM_MEMBER
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/SaveFilterTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/SaveFilterTask.kt
index da747934e2676173cc23d067b41e75d58dbc1853..d42962d54ace83a4874b7cc3707fec818b3eb7c5 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/SaveFilterTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/SaveFilterTask.kt
@@ -42,18 +42,18 @@ internal class DefaultSaveFilterTask @Inject constructor(
 
     override suspend fun execute(params: SaveFilterTask.Params) {
         val filterBody = when (params.filterPreset) {
-            FilterService.FilterPreset.RiotFilter -> {
-                FilterFactory.createRiotFilter()
+            FilterService.FilterPreset.ElementFilter -> {
+                FilterFactory.createElementFilter()
             }
-            FilterService.FilterPreset.NoFilter   -> {
+            FilterService.FilterPreset.NoFilter      -> {
                 FilterFactory.createDefaultFilter()
             }
         }
         val roomFilter = when (params.filterPreset) {
-            FilterService.FilterPreset.RiotFilter -> {
-                FilterFactory.createRiotRoomFilter()
+            FilterService.FilterPreset.ElementFilter -> {
+                FilterFactory.createElementRoomFilter()
             }
-            FilterService.FilterPreset.NoFilter   -> {
+            FilterService.FilterPreset.NoFilter      -> {
                 FilterFactory.createDefaultRoomFilter()
             }
         }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/DefaultHomeServerCapabilitiesService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/DefaultHomeServerCapabilitiesService.kt
index 27396aac80137c1beb0d730b9d350da7f2445055..0ed690d972e829f85798daa7b27f8efc84e85e57 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/DefaultHomeServerCapabilitiesService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/DefaultHomeServerCapabilitiesService.kt
@@ -17,16 +17,23 @@
 package org.matrix.android.sdk.internal.session.homeserver
 
 import com.zhuinden.monarchy.Monarchy
+import io.realm.Realm
 import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
 import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
 import org.matrix.android.sdk.internal.database.mapper.HomeServerCapabilitiesMapper
 import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntity
 import org.matrix.android.sdk.internal.database.query.get
 import org.matrix.android.sdk.internal.di.SessionDatabase
-import io.realm.Realm
 import javax.inject.Inject
 
-internal class DefaultHomeServerCapabilitiesService @Inject constructor(@SessionDatabase private val monarchy: Monarchy) : HomeServerCapabilitiesService {
+internal class DefaultHomeServerCapabilitiesService @Inject constructor(
+        @SessionDatabase private val monarchy: Monarchy,
+        private val getHomeServerCapabilitiesTask: GetHomeServerCapabilitiesTask
+) : HomeServerCapabilitiesService {
+
+    override suspend fun refreshHomeServerCapabilities() {
+        getHomeServerCapabilitiesTask.execute(GetHomeServerCapabilitiesTask.Params(forceRefresh = true))
+    }
 
     override fun getHomeServerCapabilities(): HomeServerCapabilities {
         return Realm.getInstance(monarchy.realmConfiguration).use { realm ->
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt
index 845cfb392e5730b1af63e50e85b30df97cc804a5..84c9132d6136d7051b8ede3ce2904a9cd94d1cb1 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt
@@ -38,7 +38,11 @@ import timber.log.Timber
 import java.util.Date
 import javax.inject.Inject
 
-internal interface GetHomeServerCapabilitiesTask : Task<Unit, Unit>
+internal interface GetHomeServerCapabilitiesTask : Task<GetHomeServerCapabilitiesTask.Params, Unit> {
+    data class Params(
+            val forceRefresh: Boolean
+    )
+}
 
 internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
         private val capabilitiesAPI: CapabilitiesAPI,
@@ -52,12 +56,14 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
         private val userId: String
 ) : GetHomeServerCapabilitiesTask {
 
-    override suspend fun execute(params: Unit) {
-        var doRequest = false
-        monarchy.awaitTransaction { realm ->
-            val homeServerCapabilitiesEntity = HomeServerCapabilitiesEntity.getOrCreate(realm)
+    override suspend fun execute(params: GetHomeServerCapabilitiesTask.Params) {
+        var doRequest = params.forceRefresh
+        if (!doRequest) {
+            monarchy.awaitTransaction { realm ->
+                val homeServerCapabilitiesEntity = HomeServerCapabilitiesEntity.getOrCreate(realm)
 
-            doRequest = homeServerCapabilitiesEntity.lastUpdatedTimestamp + MIN_DELAY_BETWEEN_TWO_REQUEST_MILLIS < Date().time
+                doRequest = homeServerCapabilitiesEntity.lastUpdatedTimestamp + MIN_DELAY_BETWEEN_TWO_REQUEST_MILLIS < Date().time
+            }
         }
 
         if (!doRequest) {
@@ -123,7 +129,7 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
     }
 
     companion object {
-        // 8 hours like on Riot Web
+        // 8 hours like on Element Web
         private const val MIN_DELAY_BETWEEN_TWO_REQUEST_MILLIS = 8 * 60 * 60 * 1000
     }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt
index c6fb34151c8dbba34843129168fae7ea63b996b7..948e387cb18c47a607e2a11a77470a4e60dda6bb 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt
@@ -92,7 +92,7 @@ internal class DefaultIdentityService @Inject constructor(
 
     private val listeners = mutableSetOf<IdentityServiceListener>()
 
-    override fun onStart() {
+    override fun onSessionStarted() {
         lifecycleRegistry.currentState = Lifecycle.State.STARTED
         // Observe the account data change
         accountDataDataSource
@@ -117,7 +117,7 @@ internal class DefaultIdentityService @Inject constructor(
         }
     }
 
-    override fun onStop() {
+    override fun onSessionStopped() {
         lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
     }
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/DefaultInitialSyncProgressService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/DefaultInitialSyncProgressService.kt
new file mode 100644
index 0000000000000000000000000000000000000000..eb3e3066b128ee15d6e5af97ad01eef954ece171
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/DefaultInitialSyncProgressService.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.initsync
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import org.matrix.android.sdk.api.session.initsync.InitSyncStep
+import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
+import org.matrix.android.sdk.internal.session.SessionScope
+import javax.inject.Inject
+
+@SessionScope
+internal class DefaultInitialSyncProgressService @Inject constructor()
+    : InitialSyncProgressService,
+        ProgressReporter {
+
+    private val status = MutableLiveData<InitialSyncProgressService.Status>()
+
+    private var rootTask: TaskInfo? = null
+
+    override fun getInitialSyncProgressStatus(): LiveData<InitialSyncProgressService.Status> {
+        return status
+    }
+
+    /**
+     * Create a rootTask
+     */
+    fun startRoot(initSyncStep: InitSyncStep,
+                  totalProgress: Int) {
+        endAll()
+        rootTask = TaskInfo(initSyncStep, totalProgress, null, 1F)
+        reportProgress(0F)
+    }
+
+    /**
+     * Add a child to the leaf
+     */
+    override fun startTask(initSyncStep: InitSyncStep,
+                           totalProgress: Int,
+                           parentWeight: Float) {
+        val currentLeaf = rootTask?.leaf() ?: return
+        currentLeaf.child = TaskInfo(
+                initSyncStep = initSyncStep,
+                totalProgress = totalProgress,
+                parent = currentLeaf,
+                parentWeight = parentWeight
+        )
+        reportProgress(0F)
+    }
+
+    override fun reportProgress(progress: Float) {
+        rootTask?.let { root ->
+            root.leaf().let { leaf ->
+                // Update the progress of the leaf and all its parents
+                leaf.setProgress(progress)
+                // Then update the live data using leaf wording and root progress
+                status.postValue(InitialSyncProgressService.Status.Progressing(leaf.initSyncStep, root.currentProgress.toInt()))
+            }
+        }
+    }
+
+    override fun endTask() {
+        rootTask?.leaf()?.let { endedTask ->
+            // Ensure the task progress is complete
+            reportProgress(endedTask.totalProgress.toFloat())
+            endedTask.parent?.child = null
+
+            if (endedTask.parent != null) {
+                // And close it
+                endedTask.parent.child = null
+            } else {
+                status.postValue(InitialSyncProgressService.Status.Idle)
+            }
+        }
+    }
+
+    fun endAll() {
+        rootTask = null
+        status.postValue(InitialSyncProgressService.Status.Idle)
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/Extensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/Extensions.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b40b1a56bfefd4c1a81271ef36477386b3129c95
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/Extensions.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.initsync
+
+import org.matrix.android.sdk.api.session.initsync.InitSyncStep
+
+internal inline fun <T> reportSubtask(reporter: ProgressReporter?,
+                                      initSyncStep: InitSyncStep,
+                                      totalProgress: Int,
+                                      parentWeight: Float,
+                                      block: () -> T): T {
+    reporter?.startTask(initSyncStep, totalProgress, parentWeight)
+    return block().also {
+        reporter?.endTask()
+    }
+}
+
+internal inline fun <K, V, R> Map<out K, V>.mapWithProgress(reporter: ProgressReporter?,
+                                                            initSyncStep: InitSyncStep,
+                                                            parentWeight: Float,
+                                                            transform: (Map.Entry<K, V>) -> R): List<R> {
+    var current = 0F
+    reporter?.startTask(initSyncStep, count() + 1, parentWeight)
+    return map {
+        reporter?.reportProgress(current)
+        current++
+        transform.invoke(it)
+    }.also {
+        reporter?.endTask()
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/ProgressReporter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/ProgressReporter.kt
new file mode 100644
index 0000000000000000000000000000000000000000..8a7b26b4b8fbe6d9791e044a44af83fa2e4352f7
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/ProgressReporter.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.initsync
+
+import org.matrix.android.sdk.api.session.initsync.InitSyncStep
+
+internal interface ProgressReporter {
+    fun startTask(initSyncStep: InitSyncStep,
+                  totalProgress: Int,
+                  parentWeight: Float)
+
+    fun reportProgress(progress: Float)
+
+    fun endTask()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/TaskInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/TaskInfo.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3e4cce2e1fbbc79bbddf8ecebe2c246673ecb655
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/TaskInfo.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.initsync
+
+import org.matrix.android.sdk.api.session.initsync.InitSyncStep
+import timber.log.Timber
+
+internal class TaskInfo(val initSyncStep: InitSyncStep,
+                        val totalProgress: Int,
+                        val parent: TaskInfo?,
+                        val parentWeight: Float) {
+    var child: TaskInfo? = null
+    var currentProgress = 0F
+        private set
+    private val offset = parent?.currentProgress ?: 0F
+
+    /**
+     * Get the further child
+     */
+    fun leaf(): TaskInfo {
+        var last = this
+        while (last.child != null) {
+            last = last.child!!
+        }
+        return last
+    }
+
+    /**
+     * Set progress of this task and update the parent progress iteratively
+     */
+    fun setProgress(progress: Float) {
+        Timber.v("setProgress: $progress / $totalProgress")
+        currentProgress = progress
+
+        parent?.let {
+            val parentProgress = (currentProgress / totalProgress) * (parentWeight * it.totalProgress)
+            it.setProgress(offset + parentProgress)
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt
index ebd57ce657a95cb169665eb9a48722ac803d1f80..e34615d269dd8e097115f45ba8c3893908dace55 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt
@@ -37,7 +37,6 @@ import org.matrix.android.sdk.internal.session.user.accountdata.AccountDataDataS
 import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask
 import org.matrix.android.sdk.internal.session.widgets.helper.WidgetFactory
 import org.matrix.android.sdk.internal.session.widgets.helper.extractWidgetSequence
-import org.matrix.android.sdk.internal.task.TaskExecutor
 import timber.log.Timber
 import javax.inject.Inject
 
@@ -55,7 +54,6 @@ import javax.inject.Inject
  */
 @SessionScope
 internal class IntegrationManager @Inject constructor(matrixConfiguration: MatrixConfiguration,
-                                                      private val taskExecutor: TaskExecutor,
                                                       @SessionDatabase private val monarchy: Monarchy,
                                                       private val updateUserAccountDataTask: UpdateUserAccountDataTask,
                                                       private val accountDataDataSource: AccountDataDataSource,
@@ -79,7 +77,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
         currentConfigs.add(defaultConfig)
     }
 
-    override fun onStart() {
+    override fun onSessionStarted() {
         lifecycleRegistry.currentState = Lifecycle.State.STARTED
         observeWellknownConfig()
         accountDataDataSource
@@ -107,7 +105,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
                 }
     }
 
-    override fun onStop() {
+    override fun onSessionStopped() {
         lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
     }
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/GetPreviewUrlTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/GetPreviewUrlTask.kt
index a218f3f93cd6862061179a9d329ccec90095f5d4..d85e471f1d1945ef42a87793c928df6f488a76c8 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/GetPreviewUrlTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/GetPreviewUrlTask.kt
@@ -28,6 +28,7 @@ import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
 import org.matrix.android.sdk.internal.network.executeRequest
 import org.matrix.android.sdk.internal.task.Task
 import org.matrix.android.sdk.internal.util.awaitTransaction
+import org.matrix.android.sdk.internal.util.unescapeHtml
 import java.util.Date
 import javax.inject.Inject
 
@@ -73,9 +74,9 @@ internal class DefaultGetPreviewUrlTask @Inject constructor(
     private fun JsonDict.toPreviewUrlData(url: String): PreviewUrlData {
         return PreviewUrlData(
                 url = (get("og:url") as? String) ?: url,
-                siteName = get("og:site_name") as? String,
-                title = get("og:title") as? String,
-                description = get("og:description") as? String,
+                siteName = (get("og:site_name") as? String)?.unescapeHtml(),
+                title = (get("og:title") as? String)?.unescapeHtml(),
+                description = (get("og:description") as? String)?.unescapeHtml(),
                 mxcUrl = get("og:image") as? String
         )
     }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/UrlsExtractor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/UrlsExtractor.kt
index 6137b4152cb48582d06ae80eac6fdb6aca3b8fdb..d1fb5b98ffacd0ec5ddf05cc374bec2372301b07 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/UrlsExtractor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/UrlsExtractor.kt
@@ -21,6 +21,8 @@ import org.matrix.android.sdk.api.session.events.model.EventType
 import org.matrix.android.sdk.api.session.room.model.message.MessageType
 import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
 import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent
+import org.matrix.android.sdk.api.session.room.timeline.isReply
+import org.matrix.android.sdk.api.util.ContentUtils
 import javax.inject.Inject
 
 internal class UrlsExtractor @Inject constructor() {
@@ -35,7 +37,14 @@ internal class UrlsExtractor @Inject constructor() {
                             || it.msgType == MessageType.MSGTYPE_NOTICE
                             || it.msgType == MessageType.MSGTYPE_EMOTE
                 }
-                ?.body
+                ?.let { messageContent ->
+                    if (event.isReply()) {
+                        // This is a reply, strip the reply fallback
+                        ContentUtils.extractUsefulTextFromReply(messageContent.body)
+                    } else {
+                        messageContent.body
+                    }
+                }
                 ?.let { urlRegex.findAll(it) }
                 ?.map { it.value }
                 ?.filter { it.startsWith("https://") || it.startsWith("http://") }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt
index 7763251a01f056abdf01b951fe49952af80f9e0e..54883b51e663a0672d3500d00050780d90e1675f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt
@@ -80,7 +80,7 @@ internal class DefaultProcessEventForPushTask @Inject constructor(
 
         val allRedactedEvents = params.syncResponse.join
                 .asSequence()
-                .mapNotNull { (_, value) -> value.timeline?.events }
+                .mapNotNull { it.value.timeline?.events }
                 .flatten()
                 .filter { it.type == EventType.REDACTION }
                 .mapNotNull { it.redacts }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/FinalizeAddingThreePidTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/FinalizeAddingThreePidTask.kt
index 916a6029360f7e7503aa15e2e15d08f2842bc747..c2a38af0938a17ed1e64335191a375912c5de5d2 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/FinalizeAddingThreePidTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/FinalizeAddingThreePidTask.kt
@@ -26,7 +26,6 @@ import org.matrix.android.sdk.api.auth.UIABaseAuth
 import org.matrix.android.sdk.internal.database.model.PendingThreePidEntity
 import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields
 import org.matrix.android.sdk.internal.di.SessionDatabase
-import org.matrix.android.sdk.internal.di.UserId
 import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
 import org.matrix.android.sdk.internal.network.executeRequest
 import org.matrix.android.sdk.internal.task.Task
@@ -47,11 +46,12 @@ internal class DefaultFinalizeAddingThreePidTask @Inject constructor(
         private val profileAPI: ProfileAPI,
         @SessionDatabase private val monarchy: Monarchy,
         private val pendingThreePidMapper: PendingThreePidMapper,
-        @UserId private val userId: String,
         private val globalErrorReceiver: GlobalErrorReceiver) : FinalizeAddingThreePidTask() {
 
     override suspend fun execute(params: Params) {
-        if (params.userWantsToCancel.not()) {
+        val canCleanup = if (params.userWantsToCancel) {
+            true
+        } else {
             // Get the required pending data
             val pendingThreePids = monarchy.fetchAllMappedSync(
                     { it.where(PendingThreePidEntity::class.java) },
@@ -69,21 +69,30 @@ internal class DefaultFinalizeAddingThreePidTask @Inject constructor(
                     )
                     apiCall = profileAPI.finalizeAddThreePid(body)
                 }
+                true
             } catch (throwable: Throwable) {
                 if (params.userInteractiveAuthInterceptor == null
-                        || !handleUIA(throwable, params.userInteractiveAuthInterceptor) { auth ->
-                            execute(params.copy(userAuthParam = auth))
-                        }
+                        || !handleUIA(
+                                failure = throwable,
+                                interceptor = params.userInteractiveAuthInterceptor,
+                                retryBlock = { authUpdate ->
+                                    execute(params.copy(userAuthParam = authUpdate))
+                                }
+                        )
                 ) {
                     Timber.d("## UIA: propagate failure")
-                    throw  throwable.toRegistrationFlowResponse()
+                    throw throwable.toRegistrationFlowResponse()
                             ?.let { Failure.RegistrationFlowError(it) }
                             ?: throwable
+                } else {
+                    false
                 }
             }
         }
 
-        cleanupDatabase(params)
+        if (canCleanup) {
+            cleanupDatabase(params)
+        }
     }
 
     private suspend fun cleanupDatabase(params: Params) {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/GetPushersTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/GetPushersTask.kt
index 4c7d370446ec41ed82efdf4dcefa52b45022993b..125c8f0022d6dad1301fbfb9eb3049ca6baa1a89 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/GetPushersTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/GetPushersTask.kt
@@ -19,6 +19,7 @@ import com.zhuinden.monarchy.Monarchy
 import org.matrix.android.sdk.api.session.pushers.PusherState
 import org.matrix.android.sdk.internal.database.mapper.toEntity
 import org.matrix.android.sdk.internal.database.model.PusherEntity
+import org.matrix.android.sdk.internal.database.model.deleteOnCascade
 import org.matrix.android.sdk.internal.di.SessionDatabase
 import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
 import org.matrix.android.sdk.internal.network.executeRequest
@@ -41,7 +42,8 @@ internal class DefaultGetPushersTask @Inject constructor(
         monarchy.awaitTransaction { realm ->
             // clear existings?
             realm.where(PusherEntity::class.java)
-                    .findAll().deleteAllFromRealm()
+                    .findAll()
+                    .forEach { it.deleteOnCascade() }
             response.pushers?.forEach { jsonPusher ->
                 jsonPusher.toEntity().also {
                     it.state = PusherState.REGISTERED
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/SavePushRulesTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/SavePushRulesTask.kt
index 6ba769a3b75bfd72aeb79aafb454599e81b816c6..6a4b891ecffe36b6735b68ace3354e9425939da5 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/SavePushRulesTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/SavePushRulesTask.kt
@@ -21,6 +21,7 @@ import org.matrix.android.sdk.api.pushrules.RuleSetKey
 import org.matrix.android.sdk.api.pushrules.rest.GetPushRulesResponse
 import org.matrix.android.sdk.internal.database.mapper.PushRulesMapper
 import org.matrix.android.sdk.internal.database.model.PushRulesEntity
+import org.matrix.android.sdk.internal.database.model.deleteOnCascade
 import org.matrix.android.sdk.internal.di.SessionDatabase
 import org.matrix.android.sdk.internal.task.Task
 import org.matrix.android.sdk.internal.util.awaitTransaction
@@ -40,7 +41,7 @@ internal class DefaultSavePushRulesTask @Inject constructor(@SessionDatabase pri
             // clear current push rules
             realm.where(PushRulesEntity::class.java)
                     .findAll()
-                    .deleteAllFromRealm()
+                    .forEach { it.deleteOnCascade() }
 
             // Save only global rules for the moment
             val globalRules = params.pushRules.global
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt
index 7a819250cfda39f0c7735e468667c7cd20351355..8e817ec31a0dcb4537bbf4a4422207bfaefd16fd 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt
@@ -45,6 +45,7 @@ import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSourc
 import org.matrix.android.sdk.internal.session.search.SearchTask
 import org.matrix.android.sdk.internal.task.TaskExecutor
 import org.matrix.android.sdk.internal.task.configureWith
+import org.matrix.android.sdk.internal.util.awaitCallback
 import java.security.InvalidParameterException
 import javax.inject.Inject
 
@@ -104,6 +105,12 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
         return cryptoService.shouldEncryptForInvitedMembers(roomId)
     }
 
+    override suspend fun prepareToEncrypt() {
+        awaitCallback<Unit> {
+            cryptoService.prepareToEncrypt(roomId, it)
+        }
+    }
+
     override suspend fun enableEncryption(algorithm: String) {
         when {
             isEncrypted()                          -> {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomDirectoryService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomDirectoryService.kt
index 0d41c6f35eb256b8f54ef0bf8a6b92a56deadcbd..218d846afb5cf3e9452826f7512c02177093eec7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomDirectoryService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomDirectoryService.kt
@@ -16,44 +16,24 @@
 
 package org.matrix.android.sdk.internal.session.room
 
-import org.matrix.android.sdk.api.MatrixCallback
 import org.matrix.android.sdk.api.session.room.RoomDirectoryService
 import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
 import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsParams
 import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsResponse
-import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
-import org.matrix.android.sdk.api.util.Cancelable
 import org.matrix.android.sdk.internal.session.room.directory.GetPublicRoomTask
 import org.matrix.android.sdk.internal.session.room.directory.GetRoomDirectoryVisibilityTask
-import org.matrix.android.sdk.internal.session.room.directory.GetThirdPartyProtocolsTask
 import org.matrix.android.sdk.internal.session.room.directory.SetRoomDirectoryVisibilityTask
-import org.matrix.android.sdk.internal.task.TaskExecutor
-import org.matrix.android.sdk.internal.task.configureWith
 import javax.inject.Inject
 
 internal class DefaultRoomDirectoryService @Inject constructor(
         private val getPublicRoomTask: GetPublicRoomTask,
-        private val getThirdPartyProtocolsTask: GetThirdPartyProtocolsTask,
         private val getRoomDirectoryVisibilityTask: GetRoomDirectoryVisibilityTask,
-        private val setRoomDirectoryVisibilityTask: SetRoomDirectoryVisibilityTask,
-        private val taskExecutor: TaskExecutor) : RoomDirectoryService {
+        private val setRoomDirectoryVisibilityTask: SetRoomDirectoryVisibilityTask
+) : RoomDirectoryService {
 
-    override fun getPublicRooms(server: String?,
-                                publicRoomsParams: PublicRoomsParams,
-                                callback: MatrixCallback<PublicRoomsResponse>): Cancelable {
-        return getPublicRoomTask
-                .configureWith(GetPublicRoomTask.Params(server, publicRoomsParams)) {
-                    this.callback = callback
-                }
-                .executeBy(taskExecutor)
-    }
-
-    override fun getThirdPartyProtocol(callback: MatrixCallback<Map<String, ThirdPartyProtocol>>): Cancelable {
-        return getThirdPartyProtocolsTask
-                .configureWith {
-                    this.callback = callback
-                }
-                .executeBy(taskExecutor)
+    override suspend fun getPublicRooms(server: String?,
+                                        publicRoomsParams: PublicRoomsParams): PublicRoomsResponse {
+        return getPublicRoomTask.execute(GetPublicRoomTask.Params(server, publicRoomsParams))
     }
 
     override suspend fun getRoomDirectoryVisibility(roomId: String): RoomDirectoryVisibility {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt
index d090ba5296dad810416bbffc5137bf2cf36aade4..60440c6359f54dffa16e99f743db07724f53c4ae 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt
@@ -16,6 +16,7 @@
 package org.matrix.android.sdk.internal.session.room
 
 import io.realm.Realm
+import org.matrix.android.sdk.api.crypto.VerificationState
 import org.matrix.android.sdk.api.session.events.model.AggregatedAnnotation
 import org.matrix.android.sdk.api.session.events.model.Event
 import org.matrix.android.sdk.api.session.events.model.EventType
@@ -31,9 +32,11 @@ import org.matrix.android.sdk.api.session.room.model.message.MessagePollResponse
 import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent
 import org.matrix.android.sdk.api.session.room.model.relation.ReactionContent
 import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent
+import org.matrix.android.sdk.internal.crypto.verification.toState
 import org.matrix.android.sdk.internal.database.mapper.ContentMapper
 import org.matrix.android.sdk.internal.database.mapper.EventMapper
 import org.matrix.android.sdk.internal.database.model.EditAggregatedSummaryEntity
+import org.matrix.android.sdk.internal.database.model.EditionOfEvent
 import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity
 import org.matrix.android.sdk.internal.database.model.EventEntity
 import org.matrix.android.sdk.internal.database.model.EventInsertType
@@ -50,33 +53,6 @@ import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor
 import timber.log.Timber
 import javax.inject.Inject
 
-enum class VerificationState {
-    REQUEST,
-    WAITING,
-    CANCELED_BY_ME,
-    CANCELED_BY_OTHER,
-    DONE
-}
-
-fun VerificationState.isCanceled(): Boolean {
-    return this == VerificationState.CANCELED_BY_ME || this == VerificationState.CANCELED_BY_OTHER
-}
-
-// State transition with control
-private fun VerificationState?.toState(newState: VerificationState): VerificationState {
-    // Cancel is always prioritary ?
-    // Eg id i found that mac or keys mismatch and send a cancel and the other send a done, i have to
-    // consider as canceled
-    if (newState.isCanceled()) {
-        return newState
-    }
-    // never move out of cancel
-    if (this?.isCanceled() == true) {
-        return this
-    }
-    return newState
-}
-
 internal class EventRelationsAggregationProcessor @Inject constructor(@UserId private val userId: String)
     : EventInsertLiveProcessor {
 
@@ -118,13 +94,11 @@ internal class EventRelationsAggregationProcessor @Inject constructor(@UserId pr
                         Timber.v("###REACTION Agreggation in room $roomId for event ${event.eventId}")
                         handleInitialAggregatedRelations(event, roomId, event.unsignedData.relations.annotations, realm)
 
-                        EventAnnotationsSummaryEntity.where(realm, event.eventId
-                                ?: "").findFirst()?.let {
-                            TimelineEventEntity.where(realm, roomId = roomId, eventId = event.eventId
-                                    ?: "").findFirst()?.let { tet ->
-                                tet.annotations = it
-                            }
-                        }
+                        EventAnnotationsSummaryEntity.where(realm, roomId, event.eventId ?: "").findFirst()
+                                ?.let {
+                                    TimelineEventEntity.where(realm, roomId = roomId, eventId = event.eventId ?: "").findFirst()
+                                            ?.let { tet -> tet.annotations = it }
+                                }
                     }
 
                     val content: MessageContent? = event.content.toModel()
@@ -216,63 +190,78 @@ internal class EventRelationsAggregationProcessor @Inject constructor(@UserId pr
     // OPT OUT serer aggregation until API mature enough
     private val SHOULD_HANDLE_SERVER_AGREGGATION = false
 
-    private fun handleReplace(realm: Realm, event: Event, content: MessageContent, roomId: String, isLocalEcho: Boolean, relatedEventId: String? = null) {
+    private fun handleReplace(realm: Realm,
+                              event: Event,
+                              content: MessageContent,
+                              roomId: String,
+                              isLocalEcho: Boolean,
+                              relatedEventId: String? = null) {
         val eventId = event.eventId ?: return
         val targetEventId = relatedEventId ?: content.relatesTo?.eventId ?: return
         val newContent = content.newContent ?: return
+
+        // Check that the sender is the same
+        val editedEvent = EventEntity.where(realm, targetEventId).findFirst()
+        if (editedEvent == null) {
+            // We do not know yet about the edited event
+        } else if (editedEvent.sender != event.senderId) {
+            // Edited by someone else, ignore
+            Timber.w("Ignore edition by someone else")
+            return
+        }
+
         // ok, this is a replace
-        val existing = EventAnnotationsSummaryEntity.getOrCreate(realm, roomId, targetEventId)
+        val eventAnnotationsSummaryEntity = EventAnnotationsSummaryEntity.getOrCreate(realm, roomId, targetEventId)
 
         // we have it
-        val existingSummary = existing.editSummary
+        val existingSummary = eventAnnotationsSummaryEntity.editSummary
         if (existingSummary == null) {
             Timber.v("###REPLACE new edit summary for $targetEventId, creating one (localEcho:$isLocalEcho)")
             // create the edit summary
-            val editSummary = realm.createObject(EditAggregatedSummaryEntity::class.java)
-            editSummary.aggregatedContent = ContentMapper.map(newContent)
-            if (isLocalEcho) {
-                editSummary.lastEditTs = 0
-                editSummary.sourceLocalEchoEvents.add(eventId)
-            } else {
-                editSummary.lastEditTs = event.originServerTs ?: 0
-                editSummary.sourceEvents.add(eventId)
-            }
-
-            existing.editSummary = editSummary
+            eventAnnotationsSummaryEntity.editSummary = realm.createObject(EditAggregatedSummaryEntity::class.java)
+                    .also { editSummary ->
+                        editSummary.editions.add(
+                                EditionOfEvent(
+                                        senderId = event.senderId ?: "",
+                                        eventId = event.eventId,
+                                        content = ContentMapper.map(newContent),
+                                        timestamp = if (isLocalEcho) 0 else event.originServerTs ?: 0,
+                                        isLocalEcho = isLocalEcho
+                                )
+                        )
+                    }
         } else {
-            if (existingSummary.sourceEvents.contains(eventId)) {
+            if (existingSummary.editions.any { it.eventId == eventId }) {
                 // ignore this event, we already know it (??)
                 Timber.v("###REPLACE ignoring event for summary, it's known $eventId")
                 return
             }
             val txId = event.unsignedData?.transactionId
             // is it a remote echo?
-            if (!isLocalEcho && existingSummary.sourceLocalEchoEvents.contains(txId)) {
+            if (!isLocalEcho && existingSummary.editions.any { it.eventId == txId }) {
                 // ok it has already been managed
                 Timber.v("###REPLACE Receiving remote echo of edit (edit already done)")
-                existingSummary.sourceLocalEchoEvents.remove(txId)
-                existingSummary.sourceEvents.add(event.eventId)
-            } else if (
-                    isLocalEcho // do not rely on ts for local echo, take it
-                    || event.originServerTs ?: 0 >= existingSummary.lastEditTs
-            ) {
-                Timber.v("###REPLACE Computing aggregated edit summary (isLocalEcho:$isLocalEcho)")
-                if (!isLocalEcho) {
-                    // Do not take local echo originServerTs here, could mess up ordering (keep old ts)
-                    existingSummary.lastEditTs = event.originServerTs ?: System.currentTimeMillis()
-                }
-                existingSummary.aggregatedContent = ContentMapper.map(newContent)
-                if (isLocalEcho) {
-                    existingSummary.sourceLocalEchoEvents.add(eventId)
-                } else {
-                    existingSummary.sourceEvents.add(eventId)
+                existingSummary.editions.firstOrNull { it.eventId == txId }?.let {
+                    it.eventId = event.eventId
+                    it.timestamp = event.originServerTs ?: System.currentTimeMillis()
+                    it.isLocalEcho = false
                 }
             } else {
-                // ignore this event for the summary (back paginate)
-                if (!isLocalEcho) {
-                    existingSummary.sourceEvents.add(eventId)
-                }
-                Timber.v("###REPLACE ignoring event for summary, it's to old $eventId")
+                Timber.v("###REPLACE Computing aggregated edit summary (isLocalEcho:$isLocalEcho)")
+                existingSummary.editions.add(
+                        EditionOfEvent(
+                                senderId = event.senderId ?: "",
+                                eventId = event.eventId,
+                                content = ContentMapper.map(newContent),
+                                timestamp = if (isLocalEcho) {
+                                    System.currentTimeMillis()
+                                } else {
+                                    // Do not take local echo originServerTs here, could mess up ordering (keep old ts)
+                                    event.originServerTs ?: System.currentTimeMillis()
+                                },
+                                isLocalEcho = isLocalEcho
+                        )
+                )
             }
         }
     }
@@ -290,7 +279,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor(@UserId pr
         val eventTimestamp = event.originServerTs ?: return
 
         // ok, this is a poll response
-        var existing = EventAnnotationsSummaryEntity.where(realm, targetEventId).findFirst()
+        var existing = EventAnnotationsSummaryEntity.where(realm, roomId, targetEventId).findFirst()
         if (existing == null) {
             Timber.v("## POLL creating new relation summary for $targetEventId")
             existing = EventAnnotationsSummaryEntity.create(realm, roomId, targetEventId)
@@ -370,7 +359,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor(@UserId pr
             aggregation.chunk?.forEach {
                 if (it.type == EventType.REACTION) {
                     val eventId = event.eventId ?: ""
-                    val existing = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst()
+                    val existing = EventAnnotationsSummaryEntity.where(realm, roomId, eventId).findFirst()
                     if (existing == null) {
                         val eventSummary = EventAnnotationsSummaryEntity.create(realm, roomId, eventId)
                         val sum = realm.createObject(ReactionAggregatedSummaryEntity::class.java)
@@ -454,46 +443,29 @@ internal class EventRelationsAggregationProcessor @Inject constructor(@UserId pr
      */
     private fun handleRedactionOfReplace(redacted: EventEntity, relatedEventId: String, realm: Realm) {
         Timber.d("Handle redaction of m.replace")
-        val eventSummary = EventAnnotationsSummaryEntity.where(realm, relatedEventId).findFirst()
+        val eventSummary = EventAnnotationsSummaryEntity.where(realm, redacted.roomId, relatedEventId).findFirst()
         if (eventSummary == null) {
             Timber.w("Redaction of a replace targeting an unknown event $relatedEventId")
             return
         }
-        val sourceEvents = eventSummary.editSummary?.sourceEvents
-        val sourceToDiscard = sourceEvents?.indexOf(redacted.eventId)
+        val sourceToDiscard = eventSummary.editSummary?.editions?.firstOrNull { it.eventId == redacted.eventId }
         if (sourceToDiscard == null) {
             Timber.w("Redaction of a replace that was not known in aggregation $sourceToDiscard")
             return
         }
-        // Need to remove this event from the redaction list and compute new aggregation state
-        sourceEvents.removeAt(sourceToDiscard)
-        val previousEdit = sourceEvents.mapNotNull { EventEntity.where(realm, it).findFirst() }.sortedBy { it.originServerTs }.lastOrNull()
-        if (previousEdit == null) {
-            // revert to original
-            eventSummary.editSummary?.deleteFromRealm()
-        } else {
-            // I have the last event
-            ContentMapper.map(previousEdit.content)?.toModel<MessageContent>()?.newContent?.let { newContent ->
-                eventSummary.editSummary?.lastEditTs = previousEdit.originServerTs
-                        ?: System.currentTimeMillis()
-                eventSummary.editSummary?.aggregatedContent = ContentMapper.map(newContent)
-            } ?: run {
-                Timber.e("Failed to udate edited summary")
-                // TODO how to reccover that
-            }
-        }
+        // Need to remove this event from the edition list
+        sourceToDiscard.deleteFromRealm()
     }
 
-    fun handleReactionRedact(eventToPrune: EventEntity, realm: Realm, userId: String) {
+    private fun handleReactionRedact(eventToPrune: EventEntity, realm: Realm, userId: String) {
         Timber.v("REDACTION of reaction ${eventToPrune.eventId}")
         // delete a reaction, need to update the annotation summary if any
-        val reactionContent: ReactionContent = EventMapper.map(eventToPrune).content.toModel()
-                ?: return
+        val reactionContent: ReactionContent = EventMapper.map(eventToPrune).content.toModel() ?: return
         val eventThatWasReacted = reactionContent.relatesTo?.eventId ?: return
 
         val reactionKey = reactionContent.relatesTo.key
         Timber.v("REMOVE reaction for key $reactionKey")
-        val summary = EventAnnotationsSummaryEntity.where(realm, eventThatWasReacted).findFirst()
+        val summary = EventAnnotationsSummaryEntity.where(realm, eventToPrune.roomId, eventThatWasReacted).findFirst()
         if (summary != null) {
             summary.reactionsSummary.where()
                     .equalTo(ReactionAggregatedSummaryEntityFields.KEY, reactionKey)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt
index aa92c1cb3b3bef7c7e238bde1ddf071fbd4cbc9a..20cb49ee8a8e771840b8ff4a5c3258bff5f62d35 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt
@@ -20,7 +20,6 @@ import org.matrix.android.sdk.api.session.events.model.Content
 import org.matrix.android.sdk.api.session.events.model.Event
 import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsParams
 import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsResponse
-import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
 import org.matrix.android.sdk.api.util.JsonDict
 import org.matrix.android.sdk.internal.network.NetworkConstants
 import org.matrix.android.sdk.internal.session.room.alias.GetAliasesResponse
@@ -50,14 +49,6 @@ import retrofit2.http.Query
 
 internal interface RoomAPI {
 
-    /**
-     * Get the third party server protocols.
-     *
-     * Ref: https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-thirdparty-protocols
-     */
-    @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "thirdparty/protocols")
-    fun thirdPartyProtocols(): Call<Map<String, ThirdPartyProtocol>>
-
     /**
      * Lists the public rooms on the server, with optional filter.
      * This API returns paginated responses. The rooms are ordered by the number of joined members, with the largest rooms first.
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt
index 92f4ea2aea03b7385b082c2e96e091f416100f9f..66b727236077cb25f132323659fa9092891e711e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt
@@ -39,11 +39,9 @@ import org.matrix.android.sdk.internal.session.room.create.CreateRoomTask
 import org.matrix.android.sdk.internal.session.room.create.DefaultCreateRoomTask
 import org.matrix.android.sdk.internal.session.room.directory.DefaultGetPublicRoomTask
 import org.matrix.android.sdk.internal.session.room.directory.DefaultGetRoomDirectoryVisibilityTask
-import org.matrix.android.sdk.internal.session.room.directory.DefaultGetThirdPartyProtocolsTask
 import org.matrix.android.sdk.internal.session.room.directory.DefaultSetRoomDirectoryVisibilityTask
 import org.matrix.android.sdk.internal.session.room.directory.GetPublicRoomTask
 import org.matrix.android.sdk.internal.session.room.directory.GetRoomDirectoryVisibilityTask
-import org.matrix.android.sdk.internal.session.room.directory.GetThirdPartyProtocolsTask
 import org.matrix.android.sdk.internal.session.room.directory.SetRoomDirectoryVisibilityTask
 import org.matrix.android.sdk.internal.session.room.membership.DefaultLoadRoomMembersTask
 import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask
@@ -153,9 +151,6 @@ internal abstract class RoomModule {
     @Binds
     abstract fun bindSetRoomDirectoryVisibilityTask(task: DefaultSetRoomDirectoryVisibilityTask): SetRoomDirectoryVisibilityTask
 
-    @Binds
-    abstract fun bindGetThirdPartyProtocolsTask(task: DefaultGetThirdPartyProtocolsTask): GetThirdPartyProtocolsTask
-
     @Binds
     abstract fun bindInviteTask(task: DefaultInviteTask): InviteTask
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt
index 2be90bf8e3aa21618acc985d9e031c9787182343..97cfcdaa443bc285080dcd84a9fedf080b1f6113 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt
@@ -105,12 +105,17 @@ internal class DefaultLoadRoomMembersTask @Inject constructor(
                     ?: realm.createObject(roomId)
             val now = System.currentTimeMillis()
             for (roomMemberEvent in response.roomMemberEvents) {
-                if (roomMemberEvent.eventId == null || roomMemberEvent.stateKey == null) {
+                if (roomMemberEvent.eventId == null || roomMemberEvent.stateKey == null || roomMemberEvent.type == null) {
                     continue
                 }
                 val ageLocalTs = roomMemberEvent.unsignedData?.age?.let { now - it }
                 val eventEntity = roomMemberEvent.toEntity(roomId, SendState.SYNCED, ageLocalTs).copyToRealmOrIgnore(realm, EventInsertType.PAGINATION)
-                CurrentStateEventEntity.getOrCreate(realm, roomId, roomMemberEvent.stateKey, roomMemberEvent.type).apply {
+                CurrentStateEventEntity.getOrCreate(
+                        realm,
+                        roomId,
+                        roomMemberEvent.stateKey,
+                        roomMemberEvent.type
+                ).apply {
                     eventId = roomMemberEvent.eventId
                     root = eventEntity
                 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt
index 784b610af706f94192edecd3d87a9ee5a21ed18f..0e18e30b130ab73a6551f1087f50e94c63853c9a 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt
@@ -17,7 +17,7 @@
 package org.matrix.android.sdk.internal.session.room.membership
 
 import io.realm.Realm
-import org.matrix.android.sdk.R
+import org.matrix.android.sdk.api.MatrixConfiguration
 import org.matrix.android.sdk.api.session.events.model.EventType
 import org.matrix.android.sdk.api.session.events.model.toModel
 import org.matrix.android.sdk.api.session.room.model.Membership
@@ -32,17 +32,18 @@ import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
 import org.matrix.android.sdk.internal.database.query.getOrNull
 import org.matrix.android.sdk.internal.database.query.where
 import org.matrix.android.sdk.internal.di.UserId
-import org.matrix.android.sdk.internal.util.StringProvider
 import javax.inject.Inject
 
 /**
  * This class computes room display name
  */
 internal class RoomDisplayNameResolver @Inject constructor(
-        private val stringProvider: StringProvider,
+        matrixConfiguration: MatrixConfiguration,
         @UserId private val userId: String
 ) {
 
+    private val roomDisplayNameFallbackProvider = matrixConfiguration.roomDisplayNameFallbackProvider
+
     /**
      * Compute the room display name
      *
@@ -82,7 +83,7 @@ internal class RoomDisplayNameResolver @Inject constructor(
                         .findFirst()
                         ?.displayName
             } else {
-                stringProvider.getString(R.string.room_displayname_room_invite)
+                roomDisplayNameFallbackProvider.getNameForRoomInvite()
             }
         } else if (roomEntity?.membership == Membership.JOIN) {
             val roomSummary = RoomSummaryEntity.where(realm, roomId).findFirst()
@@ -104,25 +105,25 @@ internal class RoomDisplayNameResolver @Inject constructor(
             val otherMembersCount = otherMembersSubset.count()
             name = when (otherMembersCount) {
                 0    -> {
-                    stringProvider.getString(R.string.room_displayname_empty_room)
+                    roomDisplayNameFallbackProvider.getNameForEmptyRoom()
                     // TODO (was xx and yyy) ...
                 }
                 1    -> resolveRoomMemberName(otherMembersSubset[0], roomMembers)
                 2    -> {
-                    stringProvider.getString(R.string.room_displayname_two_members,
+                    roomDisplayNameFallbackProvider.getNameFor2members(
                             resolveRoomMemberName(otherMembersSubset[0], roomMembers),
                             resolveRoomMemberName(otherMembersSubset[1], roomMembers)
                     )
                 }
                 3    -> {
-                    stringProvider.getString(R.string.room_displayname_3_members,
+                    roomDisplayNameFallbackProvider.getNameFor3members(
                             resolveRoomMemberName(otherMembersSubset[0], roomMembers),
                             resolveRoomMemberName(otherMembersSubset[1], roomMembers),
                             resolveRoomMemberName(otherMembersSubset[2], roomMembers)
                     )
                 }
                 4    -> {
-                    stringProvider.getString(R.string.room_displayname_4_members,
+                    roomDisplayNameFallbackProvider.getNameFor4members(
                             resolveRoomMemberName(otherMembersSubset[0], roomMembers),
                             resolveRoomMemberName(otherMembersSubset[1], roomMembers),
                             resolveRoomMemberName(otherMembersSubset[2], roomMembers),
@@ -131,9 +132,7 @@ internal class RoomDisplayNameResolver @Inject constructor(
                 }
                 else -> {
                     val remainingCount = invitedCount + joinedCount - otherMembersCount + 1
-                    stringProvider.getQuantityString(
-                            R.plurals.room_displayname_four_and_more_members,
-                            remainingCount,
+                    roomDisplayNameFallbackProvider.getNameFor4membersAndMore(
                             resolveRoomMemberName(otherMembersSubset[0], roomMembers),
                             resolveRoomMemberName(otherMembersSubset[1], roomMembers),
                             resolveRoomMemberName(otherMembersSubset[2], roomMembers),
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt
index 5a82d74537040b8c97fb5b56f2b6ecae398a120f..5b211c505fe5b48a9bd2d665db1b52c82880cf1a 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt
@@ -17,6 +17,7 @@
 package org.matrix.android.sdk.internal.session.room.peeking
 
 import org.matrix.android.sdk.api.MatrixPatterns
+import org.matrix.android.sdk.api.extensions.tryOrNull
 import org.matrix.android.sdk.api.session.events.model.EventType
 import org.matrix.android.sdk.api.session.events.model.toModel
 import org.matrix.android.sdk.api.session.room.model.RoomAvatarContent
@@ -65,23 +66,29 @@ internal class DefaultPeekRoomTask @Inject constructor(
         }
 
         // Is it a public room?
-        val publicRepoResult = when (getRoomDirectoryVisibilityTask.execute(GetRoomDirectoryVisibilityTask.Params(roomId))) {
-            RoomDirectoryVisibility.PRIVATE -> {
-                // We cannot resolve this room :/
-                null
-            }
-            RoomDirectoryVisibility.PUBLIC  -> {
+        val visibilityRes = tryOrNull("## PEEK: failed to get visibility") {
+            getRoomDirectoryVisibilityTask.execute(GetRoomDirectoryVisibilityTask.Params(roomId))
+        }
+        val publicRepoResult = when (visibilityRes) {
+            RoomDirectoryVisibility.PUBLIC -> {
                 // Try to find it in directory
                 val filter = if (isAlias) PublicRoomsFilter(searchTerm = params.roomIdOrAlias.substring(1))
                 else null
 
-                getPublicRoomTask.execute(GetPublicRoomTask.Params(
-                        server = serverList.firstOrNull(),
-                        publicRoomsParams = PublicRoomsParams(
-                                filter = filter,
-                                limit = 20.takeIf { filter != null } ?: 100
-                        )
-                )).chunk?.firstOrNull { it.roomId == roomId }
+                tryOrNull("## PEEK: failed to GetPublicRoomTask") {
+                    getPublicRoomTask.execute(GetPublicRoomTask.Params(
+                            server = serverList.firstOrNull(),
+                            publicRoomsParams = PublicRoomsParams(
+                                    filter = filter,
+                                    limit = 20.takeIf { filter != null } ?: 100
+                            )
+                    ))
+                }?.chunk?.firstOrNull { it.roomId == roomId }
+            }
+            else                           -> {
+                // RoomDirectoryVisibility.PRIVATE or null
+                // We cannot resolve this room :/
+                null
             }
         }
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt
index b7caf62865ab6c26216f9486ae91282766b8a282..9693e56ff0768a133c195bf494f829fdf430f7a7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt
@@ -17,14 +17,13 @@ package org.matrix.android.sdk.internal.session.room.relation
 
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.Transformations
+import com.zhuinden.monarchy.Monarchy
 import dagger.assisted.Assisted
-import dagger.assisted.AssistedInject
 import dagger.assisted.AssistedFactory
-import com.zhuinden.monarchy.Monarchy
+import dagger.assisted.AssistedInject
 import org.matrix.android.sdk.api.MatrixCallback
 import org.matrix.android.sdk.api.session.events.model.Event
 import org.matrix.android.sdk.api.session.room.model.EventAnnotationsSummary
-import org.matrix.android.sdk.api.session.room.model.message.MessageType
 import org.matrix.android.sdk.api.session.room.model.relation.RelationService
 import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
 import org.matrix.android.sdk.api.util.Cancelable
@@ -47,6 +46,7 @@ import timber.log.Timber
 
 internal class DefaultRelationService @AssistedInject constructor(
         @Assisted private val roomId: String,
+        private val eventEditor: EventEditor,
         private val eventSenderProcessor: EventSenderProcessor,
         private val eventFactory: LocalEchoEventFactory,
         private val cryptoSessionInfoProvider: CryptoSessionInfoProvider,
@@ -112,41 +112,23 @@ internal class DefaultRelationService @AssistedInject constructor(
                 .executeBy(taskExecutor)
     }
 
-    override fun editTextMessage(targetEventId: String,
+    override fun editTextMessage(targetEvent: TimelineEvent,
                                  msgType: String,
                                  newBodyText: CharSequence,
                                  newBodyAutoMarkdown: Boolean,
                                  compatibilityBodyText: String): Cancelable {
-        val event = eventFactory
-                .createReplaceTextEvent(roomId, targetEventId, newBodyText, newBodyAutoMarkdown, msgType, compatibilityBodyText)
-                .also { saveLocalEcho(it) }
-        return eventSenderProcessor.postEvent(event, cryptoSessionInfoProvider.isRoomEncrypted(roomId))
+        return eventEditor.editTextMessage(targetEvent, msgType, newBodyText, newBodyAutoMarkdown, compatibilityBodyText)
     }
 
     override fun editReply(replyToEdit: TimelineEvent,
                            originalTimelineEvent: TimelineEvent,
                            newBodyText: String,
                            compatibilityBodyText: String): Cancelable {
-        val event = eventFactory.createReplaceTextOfReply(
-                roomId,
-                replyToEdit,
-                originalTimelineEvent,
-                newBodyText,
-                true,
-                MessageType.MSGTYPE_TEXT,
-                compatibilityBodyText
-        )
-                .also { saveLocalEcho(it) }
-        return eventSenderProcessor.postEvent(event, cryptoSessionInfoProvider.isRoomEncrypted(roomId))
+        return eventEditor.editReply(replyToEdit, originalTimelineEvent, newBodyText, compatibilityBodyText)
     }
 
-    override fun fetchEditHistory(eventId: String, callback: MatrixCallback<List<Event>>) {
-        val params = FetchEditHistoryTask.Params(roomId, eventId)
-        fetchEditHistoryTask
-                .configureWith(params) {
-                    this.callback = callback
-                }
-                .executeBy(taskExecutor)
+    override suspend fun fetchEditHistory(eventId: String): List<Event> {
+        return fetchEditHistoryTask.execute(FetchEditHistoryTask.Params(roomId, eventId))
     }
 
     override fun replyToMessage(eventReplied: TimelineEvent, replyText: CharSequence, autoMarkdown: Boolean): Cancelable? {
@@ -159,7 +141,7 @@ internal class DefaultRelationService @AssistedInject constructor(
 
     override fun getEventAnnotationsSummary(eventId: String): EventAnnotationsSummary? {
         return monarchy.fetchCopyMap(
-                { EventAnnotationsSummaryEntity.where(it, eventId).findFirst() },
+                { EventAnnotationsSummaryEntity.where(it, roomId, eventId).findFirst() },
                 { entity, _ ->
                     entity.asDomain()
                 }
@@ -168,7 +150,7 @@ internal class DefaultRelationService @AssistedInject constructor(
 
     override fun getEventAnnotationsSummaryLive(eventId: String): LiveData<Optional<EventAnnotationsSummary>> {
         val liveData = monarchy.findAllMappedWithChanges(
-                { EventAnnotationsSummaryEntity.where(it, eventId) },
+                { EventAnnotationsSummaryEntity.where(it, roomId, eventId) },
                 { it.asDomain() }
         )
         return Transformations.map(liveData) { results ->
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/EventEditor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/EventEditor.kt
new file mode 100644
index 0000000000000000000000000000000000000000..5fe06287d277aea08a8d68a1ec3ecfd8a20f1d1c
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/EventEditor.kt
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.room.relation
+
+import org.matrix.android.sdk.api.session.events.model.Event
+import org.matrix.android.sdk.api.session.room.model.message.MessageType
+import org.matrix.android.sdk.api.session.room.send.SendState
+import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
+import org.matrix.android.sdk.api.util.Cancelable
+import org.matrix.android.sdk.api.util.NoOpCancellable
+import org.matrix.android.sdk.internal.crypto.CryptoSessionInfoProvider
+import org.matrix.android.sdk.internal.database.mapper.toEntity
+import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory
+import org.matrix.android.sdk.internal.session.room.send.LocalEchoRepository
+import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
+import timber.log.Timber
+import javax.inject.Inject
+
+internal class EventEditor @Inject constructor(private val eventSenderProcessor: EventSenderProcessor,
+                                               private val eventFactory: LocalEchoEventFactory,
+                                               private val cryptoSessionInfoProvider: CryptoSessionInfoProvider,
+                                               private val localEchoRepository: LocalEchoRepository) {
+
+    fun editTextMessage(targetEvent: TimelineEvent,
+                        msgType: String,
+                        newBodyText: CharSequence,
+                        newBodyAutoMarkdown: Boolean,
+                        compatibilityBodyText: String): Cancelable {
+        val roomId = targetEvent.roomId
+        if (targetEvent.root.sendState.hasFailed()) {
+            // We create a new in memory event for the EventSenderProcessor but we keep the eventId of the failed event.
+            val editedEvent = eventFactory.createTextEvent(roomId, msgType, newBodyText, newBodyAutoMarkdown).copy(
+                    eventId = targetEvent.eventId
+            )
+            updateFailedEchoWithEvent(roomId, targetEvent.eventId, editedEvent)
+            return eventSenderProcessor.postEvent(editedEvent, cryptoSessionInfoProvider.isRoomEncrypted(roomId))
+        } else if (targetEvent.root.sendState.isSent()) {
+            val event = eventFactory
+                    .createReplaceTextEvent(roomId, targetEvent.eventId, newBodyText, newBodyAutoMarkdown, msgType, compatibilityBodyText)
+                    .also { localEchoRepository.createLocalEcho(it) }
+            return eventSenderProcessor.postEvent(event, cryptoSessionInfoProvider.isRoomEncrypted(roomId))
+        } else {
+            // Should we throw?
+            Timber.w("Can't edit a sending event")
+            return NoOpCancellable
+        }
+    }
+
+    fun editReply(replyToEdit: TimelineEvent,
+                  originalTimelineEvent: TimelineEvent,
+                  newBodyText: String,
+                  compatibilityBodyText: String): Cancelable {
+        val roomId = replyToEdit.roomId
+        if (replyToEdit.root.sendState.hasFailed()) {
+            // We create a new in memory event for the EventSenderProcessor but we keep the eventId of the failed event.
+            val editedEvent = eventFactory.createReplyTextEvent(roomId, originalTimelineEvent, newBodyText, false)?.copy(
+                    eventId = replyToEdit.eventId
+            ) ?: return NoOpCancellable
+            updateFailedEchoWithEvent(roomId, replyToEdit.eventId, editedEvent)
+            return eventSenderProcessor.postEvent(editedEvent, cryptoSessionInfoProvider.isRoomEncrypted(roomId))
+        } else if (replyToEdit.root.sendState.isSent()) {
+            val event = eventFactory.createReplaceTextOfReply(
+                    roomId,
+                    replyToEdit,
+                    originalTimelineEvent,
+                    newBodyText,
+                    true,
+                    MessageType.MSGTYPE_TEXT,
+                    compatibilityBodyText
+            )
+                    .also { localEchoRepository.createLocalEcho(it) }
+            return eventSenderProcessor.postEvent(event, cryptoSessionInfoProvider.isRoomEncrypted(roomId))
+        } else {
+            // Should we throw?
+            Timber.w("Can't edit a sending event")
+            return NoOpCancellable
+        }
+    }
+
+    private fun updateFailedEchoWithEvent(roomId: String, failedEchoEventId: String, editedEvent: Event) {
+        val editedEventEntity = editedEvent.toEntity(roomId, SendState.UNSENT, System.currentTimeMillis())
+        localEchoRepository.updateEchoAsync(failedEchoEventId) { _, entity ->
+            entity.content = editedEventEntity.content
+            entity.ageLocalTs = editedEventEntity.ageLocalTs
+            entity.age = editedEventEntity.age
+            entity.originServerTs = editedEventEntity.originServerTs
+            entity.sendState = editedEventEntity.sendState
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FetchEditHistoryTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FetchEditHistoryTask.kt
index 854585ca2935654197edb19b83363f75df2b6d56..f9fd5f9348755bc43f58b5cf80f009ec045791cc 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FetchEditHistoryTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FetchEditHistoryTask.kt
@@ -49,8 +49,11 @@ internal class DefaultFetchEditHistoryTask @Inject constructor(
             )
         }
 
-        val events = response.chunks.toMutableList()
-        response.originalEvent?.let { events.add(it) }
-        return events
+        // Filter out edition form other users, and redacted editions
+        val originalSenderId = response.originalEvent?.senderId
+        val events = response.chunks
+                .filter { it.senderId == originalSenderId }
+                .filter { !it.isRedacted() }
+        return events + listOfNotNull(response.originalEvent)
     }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FindReactionEventForUndoTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FindReactionEventForUndoTask.kt
index fa6db2ee3749483287bd031dd0a4df316733ebf4..863ae4f5ce7a0c6b77331ebdbc9e0fd5dbadc8c7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FindReactionEventForUndoTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FindReactionEventForUndoTask.kt
@@ -45,16 +45,16 @@ internal class DefaultFindReactionEventForUndoTask @Inject constructor(
 
     override suspend fun execute(params: FindReactionEventForUndoTask.Params): FindReactionEventForUndoTask.Result {
         val eventId = Realm.getInstance(monarchy.realmConfiguration).use { realm ->
-            getReactionToRedact(realm, params.reaction, params.eventId)?.eventId
+            getReactionToRedact(realm, params)?.eventId
         }
         return FindReactionEventForUndoTask.Result(eventId)
     }
 
-    private fun getReactionToRedact(realm: Realm, reaction: String, eventId: String): EventEntity? {
-        val summary = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst() ?: return null
+    private fun getReactionToRedact(realm: Realm, params: FindReactionEventForUndoTask.Params): EventEntity? {
+        val summary = EventAnnotationsSummaryEntity.where(realm, params.roomId, params.eventId).findFirst() ?: return null
 
         val rase = summary.reactionsSummary.where()
-                .equalTo(ReactionAggregatedSummaryEntityFields.KEY, reaction)
+                .equalTo(ReactionAggregatedSummaryEntityFields.KEY, params.reaction)
                 .findFirst() ?: return null
 
         // want to find the event originated by me!
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/SendRelationWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/SendRelationWorker.kt
index c12597bea0a44d7efeac40ea7039a787727c8578..403aa274fed8e541cb0f3eabf8495bfb64b25699 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/SendRelationWorker.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/SendRelationWorker.kt
@@ -89,7 +89,7 @@ internal class SendRelationWorker(context: Context, params: WorkerParameters)
                     roomId = roomId,
                     parentId = relatedEventId,
                     relationType = relationType,
-                    eventType = localEvent.type,
+                    eventType = localEvent.type!!,
                     content = localEvent.content
             )
         }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/UpdateQuickReactionTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/UpdateQuickReactionTask.kt
index 1f68a700ad0715bed10b8ee548139b89c9d07569..32d6c5aa7eebbbf6ce723f6722110d2acc743c4d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/UpdateQuickReactionTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/UpdateQuickReactionTask.kt
@@ -47,22 +47,22 @@ internal class DefaultUpdateQuickReactionTask @Inject constructor(@SessionDataba
     override suspend fun execute(params: UpdateQuickReactionTask.Params): UpdateQuickReactionTask.Result {
         var res: Pair<String?, List<String>?>? = null
         monarchy.doWithRealm { realm ->
-            res = updateQuickReaction(realm, params.reaction, params.oppositeReaction, params.eventId)
+            res = updateQuickReaction(realm, params)
         }
         return UpdateQuickReactionTask.Result(res?.first, res?.second.orEmpty())
     }
 
-    private fun updateQuickReaction(realm: Realm, reaction: String, oppositeReaction: String, eventId: String): Pair<String?, List<String>?> {
+    private fun updateQuickReaction(realm: Realm, params: UpdateQuickReactionTask.Params): Pair<String?, List<String>?> {
         // the emoji reaction has been selected, we need to check if we have reacted it or not
-        val existingSummary = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst()
-                ?: return Pair(reaction, null)
+        val existingSummary = EventAnnotationsSummaryEntity.where(realm, params.roomId, params.eventId).findFirst()
+                ?: return Pair(params.reaction, null)
 
         // Ok there is already reactions on this event, have we reacted to it
         val aggregationForReaction = existingSummary.reactionsSummary.where()
-                .equalTo(ReactionAggregatedSummaryEntityFields.KEY, reaction)
+                .equalTo(ReactionAggregatedSummaryEntityFields.KEY, params.reaction)
                 .findFirst()
         val aggregationForOppositeReaction = existingSummary.reactionsSummary.where()
-                .equalTo(ReactionAggregatedSummaryEntityFields.KEY, oppositeReaction)
+                .equalTo(ReactionAggregatedSummaryEntityFields.KEY, params.oppositeReaction)
                 .findFirst()
 
         if (aggregationForReaction == null || !aggregationForReaction.addedByMe) {
@@ -72,7 +72,7 @@ internal class DefaultUpdateQuickReactionTask @Inject constructor(@SessionDataba
                 val entity = EventEntity.where(realm, it).findFirst()
                 if (entity?.sender == userId) entity.eventId else null
             }
-            return Pair(reaction, toRedact)
+            return Pair(params.reaction, toRedact)
         } else {
             // I already added it, so i need to undo it (like a toggle)
             // find all m.redaction coming from me to readact them
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt
index a12962b51ffeda75b2fe8006cd4451ced1b0a03a..c5b8b42b3c48916acb37e1d5460ec044217d2074 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt
@@ -232,6 +232,14 @@ internal class DefaultSendService @AssistedInject constructor(
         }
     }
 
+    override fun cancelAllFailedMessages() {
+        taskExecutor.executorScope.launch {
+            localEchoRepository.getAllFailedEventsToResend(roomId).forEach { event ->
+                cancelSend(event.eventId)
+            }
+        }
+    }
+
     override fun sendMedia(attachment: ContentAttachmentData,
                            compressBeforeSending: Boolean,
                            roomIds: Set<String>): Cancelable {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt
index c01923055b14bec3194707a31d6f2da9944e1f14..432a4af062046896c48ea15929b4e971ad67a1f9 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt
@@ -20,7 +20,6 @@ import android.content.Context
 import android.graphics.Bitmap
 import android.media.MediaMetadataRetriever
 import androidx.exifinterface.media.ExifInterface
-import org.matrix.android.sdk.R
 import org.matrix.android.sdk.api.session.content.ContentAttachmentData
 import org.matrix.android.sdk.api.session.events.model.Content
 import org.matrix.android.sdk.api.session.events.model.Event
@@ -42,7 +41,6 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageOptionsConte
 import org.matrix.android.sdk.api.session.room.model.message.MessagePollResponseContent
 import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent
 import org.matrix.android.sdk.api.session.room.model.message.MessageType
-import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationRequestContent
 import org.matrix.android.sdk.api.session.room.model.message.MessageVideoContent
 import org.matrix.android.sdk.api.session.room.model.message.OPTION_TYPE_POLL
 import org.matrix.android.sdk.api.session.room.model.message.OptionItem
@@ -59,7 +57,6 @@ import org.matrix.android.sdk.internal.di.UserId
 import org.matrix.android.sdk.internal.session.content.ThumbnailExtractor
 import org.matrix.android.sdk.internal.session.permalinks.PermalinkFactory
 import org.matrix.android.sdk.internal.session.room.send.pills.TextPillsUtils
-import org.matrix.android.sdk.internal.util.StringProvider
 import javax.inject.Inject
 
 /**
@@ -74,7 +71,6 @@ import javax.inject.Inject
 internal class LocalEchoEventFactory @Inject constructor(
         private val context: Context,
         @UserId private val userId: String,
-        private val stringProvider: StringProvider,
         private val markdownParser: MarkdownParser,
         private val textPillsUtils: TextPillsUtils,
         private val localEchoRepository: LocalEchoRepository,
@@ -334,25 +330,6 @@ internal class LocalEchoEventFactory @Inject constructor(
         )
     }
 
-    fun createVerificationRequest(roomId: String, fromDevice: String, toUserId: String, methods: List<String>): Event {
-        val localId = LocalEcho.createLocalEchoId()
-        return Event(
-                roomId = roomId,
-                originServerTs = dummyOriginServerTs(),
-                senderId = userId,
-                eventId = localId,
-                type = EventType.MESSAGE,
-                content = MessageVerificationRequestContent(
-                        body = stringProvider.getString(R.string.key_verification_request_fallback_message, userId),
-                        fromDevice = fromDevice,
-                        toUserId = toUserId,
-                        timestamp = System.currentTimeMillis(),
-                        methods = methods
-                ).toContent(),
-                unsignedData = UnsignedData(age = null, transactionId = localId)
-        )
-    }
-
     private fun dummyOriginServerTs(): Long {
         return System.currentTimeMillis()
     }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoRepository.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoRepository.kt
index f742271fa703a20f42f60f7451daf93bdf139691..70245cbd5e49eead24cd825787ecc5bad2588016 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoRepository.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoRepository.kt
@@ -27,7 +27,6 @@ import org.matrix.android.sdk.api.session.room.send.SendState
 import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
 import org.matrix.android.sdk.internal.database.RealmSessionProvider
 import org.matrix.android.sdk.internal.database.asyncTransaction
-import org.matrix.android.sdk.internal.database.helper.nextId
 import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
 import org.matrix.android.sdk.internal.database.mapper.asDomain
 import org.matrix.android.sdk.internal.database.mapper.toEntity
@@ -45,6 +44,7 @@ import org.matrix.android.sdk.internal.session.room.timeline.TimelineInput
 import org.matrix.android.sdk.internal.task.TaskExecutor
 import org.matrix.android.sdk.internal.util.awaitTransaction
 import timber.log.Timber
+import java.util.UUID
 import javax.inject.Inject
 
 internal class LocalEchoRepository @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
@@ -56,15 +56,15 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private
 
     fun createLocalEcho(event: Event) {
         val roomId = event.roomId ?: throw IllegalStateException("You should have set a roomId for your event")
-        val senderId = event.senderId ?: throw IllegalStateException("You should have set a senderIf for your event")
-        if (event.eventId == null) {
-            throw IllegalStateException("You should have set an eventId for your event")
-        }
+        val senderId = event.senderId ?: throw IllegalStateException("You should have set a senderId for your event")
+        event.eventId ?: throw IllegalStateException("You should have set an eventId for your event")
+        event.type ?: throw IllegalStateException("You should have set a type for your event")
+
         val timelineEventEntity = realmSessionProvider.withRealm { realm ->
             val eventEntity = event.toEntity(roomId, SendState.UNSENT, System.currentTimeMillis())
             val roomMemberHelper = RoomMemberHelper(realm, roomId)
             val myUser = roomMemberHelper.getLastRoomMember(senderId)
-            val localId = TimelineEventEntity.nextId(realm)
+            val localId = UUID.randomUUID().mostSignificantBits
             TimelineEventEntity(localId).also {
                 it.root = eventEntity
                 it.eventId = event.eventId
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt
index 5014d945582da3739d477e220a8c9387fd5d7e88..8bafa5f882c7f7d32c41664b3554cf15ca8113a0 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt
@@ -1,11 +1,11 @@
 /*
- * Copyright 2020 The Matrix.org Foundation C.I.C.
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
  *
  * 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
+ *     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,
@@ -16,234 +16,21 @@
 
 package org.matrix.android.sdk.internal.session.room.send.queue
 
-import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-import org.matrix.android.sdk.api.auth.data.SessionParams
-import org.matrix.android.sdk.api.auth.data.sessionId
-import org.matrix.android.sdk.api.extensions.tryOrNull
-import org.matrix.android.sdk.api.failure.Failure
-import org.matrix.android.sdk.api.failure.MatrixError
-import org.matrix.android.sdk.api.failure.isTokenError
-import org.matrix.android.sdk.api.session.crypto.CryptoService
 import org.matrix.android.sdk.api.session.events.model.Event
-import org.matrix.android.sdk.api.session.sync.SyncState
 import org.matrix.android.sdk.api.util.Cancelable
-import org.matrix.android.sdk.internal.session.SessionScope
-import org.matrix.android.sdk.internal.task.TaskExecutor
-import timber.log.Timber
-import java.io.IOException
-import java.net.InetAddress
-import java.net.InetSocketAddress
-import java.net.Socket
-import java.util.Timer
-import java.util.TimerTask
-import java.util.concurrent.LinkedBlockingQueue
-import javax.inject.Inject
-import kotlin.concurrent.schedule
+import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
 
-/**
- * A simple ever running thread unique for that session responsible of sending events in order.
- * Each send is retried 3 times, if there is no network (e.g if cannot ping home server) it will wait and
- * periodically test reachability before resume (does not count as a retry)
- *
- * If the app is killed before all event were sent, on next wakeup the scheduled events will be re posted
- */
-@SessionScope
-internal class EventSenderProcessor @Inject constructor(
-        private val cryptoService: CryptoService,
-        private val sessionParams: SessionParams,
-        private val queuedTaskFactory: QueuedTaskFactory,
-        private val taskExecutor: TaskExecutor,
-        private val memento: QueueMemento
-) : Thread("SENDER_THREAD_SID_${sessionParams.credentials.sessionId()}") {
-
-    private fun markAsManaged(task: QueuedTask) {
-        memento.track(task)
-    }
-
-    private fun markAsFinished(task: QueuedTask) {
-        memento.unTrack(task)
-    }
-
-    // API
-    fun postEvent(event: Event): Cancelable {
-        return postEvent(event, event.roomId?.let { cryptoService.isRoomEncrypted(it) } ?: false)
-    }
-
-    override fun start() {
-        super.start()
-        // We should check for sending events not handled because app was killed
-        // But we should be careful of only took those that was submitted to us, because if it's
-        // for example it's a media event it is handled by some worker and he will handle it
-        // This is a bit fragile :/
-        // also some events cannot be retried manually by users, e.g reactions
-        // they were previously relying on workers to do the work :/ and was expected to always finally succeed
-        // Also some echos are not to be resent like redaction echos (fake event created for aggregation)
-
-        tryOrNull {
-            taskExecutor.executorScope.launch {
-                Timber.d("## Send relaunched pending events on restart")
-                memento.restoreTasks(this@EventSenderProcessor)
-            }
-        }
-    }
-
-    fun postEvent(event: Event, encrypt: Boolean): Cancelable {
-        val task = queuedTaskFactory.createSendTask(event, encrypt)
-        return postTask(task)
-    }
-
-    fun postRedaction(redactionLocalEcho: Event, reason: String?): Cancelable {
-        return postRedaction(redactionLocalEcho.eventId!!, redactionLocalEcho.redacts!!, redactionLocalEcho.roomId!!, reason)
-    }
-
-    fun postRedaction(redactionLocalEchoId: String, eventToRedactId: String, roomId: String, reason: String?): Cancelable {
-        val task = queuedTaskFactory.createRedactTask(redactionLocalEchoId, eventToRedactId, roomId, reason)
-        return postTask(task)
-    }
-
-    fun postTask(task: QueuedTask): Cancelable {
-        // non blocking add to queue
-        sendingQueue.add(task)
-        markAsManaged(task)
-        return task
-    }
-
-    fun cancel(eventId: String, roomId: String) {
-        (currentTask as? SendEventQueuedTask)
-                ?.takeIf { it -> it.event.eventId == eventId && it.event.roomId == roomId }
-                ?.cancel()
-    }
-
-    companion object {
-        private const val RETRY_WAIT_TIME_MS = 10_000L
-    }
-
-    private var currentTask: QueuedTask? = null
-
-    private var sendingQueue = LinkedBlockingQueue<QueuedTask>()
+internal interface EventSenderProcessor: SessionLifecycleObserver {
 
-    private var networkAvailableLock = Object()
-    private var canReachServer = true
-    private var retryNoNetworkTask: TimerTask? = null
+    fun postEvent(event: Event): Cancelable
 
-    override fun run() {
-        Timber.v("## SendThread started ts:${System.currentTimeMillis()}")
-        try {
-            while (!isInterrupted) {
-                Timber.v("## SendThread wait for task to process")
-                val task = sendingQueue.take()
-                        .also { currentTask = it }
-                Timber.v("## SendThread Found task to process $task")
+    fun postEvent(event: Event, encrypt: Boolean): Cancelable
 
-                if (task.isCancelled()) {
-                    Timber.v("## SendThread send cancelled for $task")
-                    // we do not execute this one
-                    continue
-                }
-                // we check for network connectivity
-                while (!canReachServer) {
-                    Timber.v("## SendThread cannot reach server, wait ts:${System.currentTimeMillis()}")
-                    // schedule to retry
-                    waitForNetwork()
-                    // if thread as been killed meanwhile
-//                    if (state == State.KILLING) break
-                }
-                Timber.v("## Server is Reachable")
-                // so network is available
+    fun postRedaction(redactionLocalEcho: Event, reason: String?): Cancelable
 
-                runBlocking {
-                    retryLoop@ while (task.retryCount < 3) {
-                        try {
-                            // SendPerformanceProfiler.startStage(task.event.eventId!!, SendPerformanceProfiler.Stages.SEND_WORKER)
-                            Timber.v("## SendThread retryLoop for $task retryCount ${task.retryCount}")
-                            task.execute()
-                            // sendEventTask.execute(SendEventTask.Params(task.event, task.encrypt, cryptoService))
-                            // SendPerformanceProfiler.stopStage(task.event.eventId, SendPerformanceProfiler.Stages.SEND_WORKER)
-                            break@retryLoop
-                        } catch (exception: Throwable) {
-                            when {
-                                exception is IOException || exception is Failure.NetworkConnection                         -> {
-                                    canReachServer = false
-                                    task.retryCount++
-                                    if (task.retryCount >= 3) task.onTaskFailed()
-                                    while (!canReachServer) {
-                                        Timber.v("## SendThread retryLoop cannot reach server, wait ts:${System.currentTimeMillis()}")
-                                        // schedule to retry
-                                        waitForNetwork()
-                                    }
-                                }
-                                (exception is Failure.ServerError && exception.error.code == MatrixError.M_LIMIT_EXCEEDED) -> {
-                                    task.retryCount++
-                                    if (task.retryCount >= 3) task.onTaskFailed()
-                                    Timber.v("## SendThread retryLoop retryable error for $task reason: ${exception.localizedMessage}")
-                                    // wait a bit
-                                    // Todo if its a quota exception can we get timout?
-                                    sleep(3_000)
-                                    continue@retryLoop
-                                }
-                                exception.isTokenError()                                                                   -> {
-                                    Timber.v("## SendThread retryLoop retryable TOKEN error, interrupt")
-                                    // we can exit the loop
-                                    task.onTaskFailed()
-                                    throw InterruptedException()
-                                }
-                                exception is CancellationException                                                         -> {
-                                    Timber.v("## SendThread task has been cancelled")
-                                    break@retryLoop
-                                }
-                                else                                                                                       -> {
-                                    Timber.v("## SendThread retryLoop Un-Retryable error, try next task")
-                                    // this task is in error, check next one?
-                                    break@retryLoop
-                                }
-                            }
-                        }
-                    }
-                }
-                markAsFinished(task)
-            }
-        } catch (interruptionException: InterruptedException) {
-            // will be thrown is thread is interrupted while seeping
-            interrupt()
-            Timber.v("## InterruptedException!! ${interruptionException.localizedMessage}")
-        }
-//        state = State.KILLED
-        // is this needed?
-        retryNoNetworkTask?.cancel()
-        Timber.w("## SendThread finished ${System.currentTimeMillis()}")
-    }
+    fun postRedaction(redactionLocalEchoId: String, eventToRedactId: String, roomId: String, reason: String?): Cancelable
 
-    private fun waitForNetwork() {
-        retryNoNetworkTask = Timer(SyncState.NoNetwork.toString(), false).schedule(RETRY_WAIT_TIME_MS) {
-            synchronized(networkAvailableLock) {
-                canReachServer = checkHostAvailable().also {
-                    Timber.v("## SendThread checkHostAvailable $it")
-                }
-                networkAvailableLock.notify()
-            }
-        }
-        synchronized(networkAvailableLock) { networkAvailableLock.wait() }
-    }
+    fun postTask(task: QueuedTask): Cancelable
 
-    /**
-     * Check if homeserver is reachable.
-     */
-    private fun checkHostAvailable(): Boolean {
-        val host = sessionParams.homeServerConnectionConfig.homeServerUri.host ?: return false
-        val port = sessionParams.homeServerConnectionConfig.homeServerUri.port.takeIf { it != -1 } ?: 80
-        val timeout = 30_000
-        try {
-            Socket().use { socket ->
-                val inetAddress: InetAddress = InetAddress.getByName(host)
-                val inetSocketAddress = InetSocketAddress(inetAddress, port)
-                socket.connect(inetSocketAddress, timeout)
-                return true
-            }
-        } catch (e: IOException) {
-            Timber.v("## EventSender isHostAvailable failure ${e.localizedMessage}")
-            return false
-        }
-    }
+    fun cancel(eventId: String, roomId: String)
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt
new file mode 100644
index 0000000000000000000000000000000000000000..297233298956f176a8494dc0182e68ea853ff21f
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.room.send.queue
+
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import org.matrix.android.sdk.api.auth.data.SessionParams
+import org.matrix.android.sdk.api.failure.Failure
+import org.matrix.android.sdk.api.failure.MatrixError
+import org.matrix.android.sdk.api.session.crypto.CryptoService
+import org.matrix.android.sdk.api.session.events.model.Event
+import org.matrix.android.sdk.api.util.Cancelable
+import org.matrix.android.sdk.internal.session.SessionScope
+import org.matrix.android.sdk.internal.task.CoroutineSequencer
+import org.matrix.android.sdk.internal.task.SemaphoreCoroutineSequencer
+import org.matrix.android.sdk.internal.task.TaskExecutor
+import org.matrix.android.sdk.internal.util.toCancelable
+import timber.log.Timber
+import java.io.IOException
+import java.util.concurrent.ConcurrentHashMap
+import java.util.concurrent.atomic.AtomicBoolean
+import javax.inject.Inject
+import kotlin.coroutines.cancellation.CancellationException
+
+private const val RETRY_WAIT_TIME_MS = 10_000L
+private const val MAX_RETRY_COUNT = 3
+
+/**
+ * This class is responsible for sending events in order in each room. It uses the QueuedTask.queueIdentifier to execute tasks sequentially.
+ * Each send is retried 3 times, if there is no network (e.g if cannot ping home server) it will wait and
+ * periodically test reachability before resume (does not count as a retry)
+ *
+ * If the app is killed before all event were sent, on next wakeup the scheduled events will be re posted
+ *
+ */
+@SessionScope
+internal class EventSenderProcessorCoroutine @Inject constructor(
+        private val cryptoService: CryptoService,
+        private val sessionParams: SessionParams,
+        private val queuedTaskFactory: QueuedTaskFactory,
+        private val taskExecutor: TaskExecutor,
+        private val memento: QueueMemento
+) : EventSenderProcessor {
+
+    private val waitForNetworkSequencer = SemaphoreCoroutineSequencer()
+
+    /**
+     * sequencers use QueuedTask.queueIdentifier as key
+     */
+    private val sequencers = ConcurrentHashMap<String, CoroutineSequencer>()
+
+    /**
+     * cancelableBag use QueuedTask.taskIdentifier as key
+     */
+    private val cancelableBag = ConcurrentHashMap<String, Cancelable>()
+
+    override fun onSessionStarted() {
+        // We should check for sending events not handled because app was killed
+        // But we should be careful of only took those that was submitted to us, because if it's
+        // for example it's a media event it is handled by some worker and he will handle it
+        // This is a bit fragile :/
+        // also some events cannot be retried manually by users, e.g reactions
+        // they were previously relying on workers to do the work :/ and was expected to always finally succeed
+        // Also some echos are not to be resent like redaction echos (fake event created for aggregation)
+        taskExecutor.executorScope.launch {
+            Timber.d("## Send relaunched pending events on restart")
+            try {
+                memento.restoreTasks(this@EventSenderProcessorCoroutine)
+            } catch (failure: Throwable) {
+                Timber.e(failure, "Fail restoring send tasks")
+            }
+        }
+    }
+
+    override fun postEvent(event: Event): Cancelable {
+        return postEvent(event, event.roomId?.let { cryptoService.isRoomEncrypted(it) } ?: false)
+    }
+
+    override fun postEvent(event: Event, encrypt: Boolean): Cancelable {
+        val task = queuedTaskFactory.createSendTask(event, encrypt)
+        return postTask(task)
+    }
+
+    override fun postRedaction(redactionLocalEcho: Event, reason: String?): Cancelable {
+        return postRedaction(redactionLocalEcho.eventId!!, redactionLocalEcho.redacts!!, redactionLocalEcho.roomId!!, reason)
+    }
+
+    override fun postRedaction(redactionLocalEchoId: String, eventToRedactId: String, roomId: String, reason: String?): Cancelable {
+        val task = queuedTaskFactory.createRedactTask(redactionLocalEchoId, eventToRedactId, roomId, reason)
+        return postTask(task)
+    }
+
+    override fun postTask(task: QueuedTask): Cancelable {
+        markAsManaged(task)
+        val sequencer = sequencers.getOrPut(task.queueIdentifier) {
+            SemaphoreCoroutineSequencer()
+        }
+        Timber.v("## post $task")
+        return taskExecutor.executorScope
+                .launchWith(sequencer) {
+                    executeTask(task)
+                }.toCancelable()
+                .also {
+                    cancelableBag[task.taskIdentifier] = it
+                }
+    }
+
+    override fun cancel(eventId: String, roomId: String) {
+        // eventId is most likely the taskIdentifier
+        cancelableBag[eventId]?.cancel()
+    }
+
+    private fun CoroutineScope.launchWith(sequencer: CoroutineSequencer, block: suspend CoroutineScope.() -> Unit) = launch {
+        sequencer.post {
+            block()
+        }
+    }
+
+    private suspend fun executeTask(task: QueuedTask) {
+        try {
+            if (task.isCancelled()) {
+                Timber.v("## $task has been cancelled, try next task")
+                return
+            }
+            task.waitForNetwork()
+            task.execute()
+        } catch (exception: Throwable) {
+            when {
+                exception is IOException || exception is Failure.NetworkConnection                         -> {
+                    canReachServer.set(false)
+                    task.markAsFailedOrRetry(exception, 0)
+                }
+                (exception is Failure.ServerError && exception.error.code == MatrixError.M_LIMIT_EXCEEDED) -> {
+                    val delay = exception.error.retryAfterMillis?.plus(100) ?: 3_000
+                    task.markAsFailedOrRetry(exception, delay)
+                }
+                exception is CancellationException                                                         -> {
+                    Timber.v("## $task has been cancelled, try next task")
+                }
+                else                                                                                       -> {
+                    Timber.v("## un-retryable error for $task, try next task")
+                    // this task is in error, check next one?
+                    task.onTaskFailed()
+                }
+            }
+        }
+        markAsFinished(task)
+    }
+
+    private suspend fun QueuedTask.markAsFailedOrRetry(failure: Throwable, retryDelay: Long) {
+        if (retryCount.incrementAndGet() >= MAX_RETRY_COUNT) {
+            onTaskFailed()
+        } else {
+            Timber.v("## retryable error for $this reason: ${failure.localizedMessage}")
+            // Wait if necessary
+            delay(retryDelay)
+            // And then retry
+            executeTask(this)
+        }
+    }
+
+    private fun markAsManaged(task: QueuedTask) {
+        memento.track(task)
+    }
+
+    private fun markAsFinished(task: QueuedTask) {
+        cancelableBag.remove(task.taskIdentifier)
+        memento.unTrack(task)
+    }
+
+    private val canReachServer = AtomicBoolean(true)
+
+    private suspend fun QueuedTask.waitForNetwork() = waitForNetworkSequencer.post {
+        while (!canReachServer.get()) {
+            Timber.v("## $this cannot reach server wait ts:${System.currentTimeMillis()}")
+            delay(RETRY_WAIT_TIME_MS)
+            withContext(Dispatchers.IO) {
+                val hostAvailable = HomeServerAvailabilityChecker(sessionParams).check()
+                canReachServer.set(hostAvailable)
+            }
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorThread.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorThread.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b79a86dd7e0ce8392171d1aa560112b5587b9bbc
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorThread.kt
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.room.send.queue
+
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import org.matrix.android.sdk.api.auth.data.SessionParams
+import org.matrix.android.sdk.api.auth.data.sessionId
+import org.matrix.android.sdk.api.extensions.tryOrNull
+import org.matrix.android.sdk.api.failure.Failure
+import org.matrix.android.sdk.api.failure.MatrixError
+import org.matrix.android.sdk.api.failure.isTokenError
+import org.matrix.android.sdk.api.session.crypto.CryptoService
+import org.matrix.android.sdk.api.session.events.model.Event
+import org.matrix.android.sdk.api.session.sync.SyncState
+import org.matrix.android.sdk.api.util.Cancelable
+import org.matrix.android.sdk.internal.session.SessionScope
+import org.matrix.android.sdk.internal.task.TaskExecutor
+import timber.log.Timber
+import java.io.IOException
+import java.util.Timer
+import java.util.TimerTask
+import java.util.concurrent.LinkedBlockingQueue
+import javax.inject.Inject
+import kotlin.concurrent.schedule
+
+/**
+ * A simple ever running thread unique for that session responsible of sending events in order.
+ * Each send is retried 3 times, if there is no network (e.g if cannot ping home server) it will wait and
+ * periodically test reachability before resume (does not count as a retry)
+ *
+ * If the app is killed before all event were sent, on next wakeup the scheduled events will be re posted
+ */
+@Deprecated("You should know use EventSenderProcessorCoroutine instead")
+@SessionScope
+internal class EventSenderProcessorThread @Inject constructor(
+        private val cryptoService: CryptoService,
+        private val sessionParams: SessionParams,
+        private val queuedTaskFactory: QueuedTaskFactory,
+        private val taskExecutor: TaskExecutor,
+        private val memento: QueueMemento
+) : Thread("SENDER_THREAD_SID_${sessionParams.credentials.sessionId()}"), EventSenderProcessor {
+
+    private fun markAsManaged(task: QueuedTask) {
+        memento.track(task)
+    }
+
+    private fun markAsFinished(task: QueuedTask) {
+        memento.unTrack(task)
+    }
+
+    override fun onSessionStarted() {
+        start()
+    }
+
+    override fun onSessionStopped() {
+        interrupt()
+    }
+
+    override fun start() {
+        super.start()
+        // We should check for sending events not handled because app was killed
+        // But we should be careful of only took those that was submitted to us, because if it's
+        // for example it's a media event it is handled by some worker and he will handle it
+        // This is a bit fragile :/
+        // also some events cannot be retried manually by users, e.g reactions
+        // they were previously relying on workers to do the work :/ and was expected to always finally succeed
+        // Also some echos are not to be resent like redaction echos (fake event created for aggregation)
+
+        tryOrNull {
+            taskExecutor.executorScope.launch {
+                Timber.d("## Send relaunched pending events on restart")
+                memento.restoreTasks(this@EventSenderProcessorThread)
+            }
+        }
+    }
+
+    // API
+    override fun postEvent(event: Event): Cancelable {
+        return postEvent(event, event.roomId?.let { cryptoService.isRoomEncrypted(it) } ?: false)
+    }
+
+    override fun postEvent(event: Event, encrypt: Boolean): Cancelable {
+        val task = queuedTaskFactory.createSendTask(event, encrypt)
+        return postTask(task)
+    }
+
+    override fun postRedaction(redactionLocalEcho: Event, reason: String?): Cancelable {
+        return postRedaction(redactionLocalEcho.eventId!!, redactionLocalEcho.redacts!!, redactionLocalEcho.roomId!!, reason)
+    }
+
+    override fun postRedaction(redactionLocalEchoId: String, eventToRedactId: String, roomId: String, reason: String?): Cancelable {
+        val task = queuedTaskFactory.createRedactTask(redactionLocalEchoId, eventToRedactId, roomId, reason)
+        return postTask(task)
+    }
+
+    override fun postTask(task: QueuedTask): Cancelable {
+        // non blocking add to queue
+        sendingQueue.add(task)
+        markAsManaged(task)
+        return task
+    }
+
+    override fun cancel(eventId: String, roomId: String) {
+        (currentTask as? SendEventQueuedTask)
+                ?.takeIf { it -> it.event.eventId == eventId && it.event.roomId == roomId }
+                ?.cancel()
+    }
+
+    companion object {
+        private const val RETRY_WAIT_TIME_MS = 10_000L
+    }
+
+    private var currentTask: QueuedTask? = null
+
+    private var sendingQueue = LinkedBlockingQueue<QueuedTask>()
+
+    private var networkAvailableLock = Object()
+    private var canReachServer = true
+    private var retryNoNetworkTask: TimerTask? = null
+
+    override fun run() {
+        Timber.v("## SendThread started ts:${System.currentTimeMillis()}")
+        try {
+            while (!isInterrupted) {
+                Timber.v("## SendThread wait for task to process")
+                val task = sendingQueue.take()
+                        .also { currentTask = it }
+                Timber.v("## SendThread Found task to process $task")
+
+                if (task.isCancelled()) {
+                    Timber.v("## SendThread send cancelled for $task")
+                    // we do not execute this one
+                    continue
+                }
+                // we check for network connectivity
+                while (!canReachServer) {
+                    Timber.v("## SendThread cannot reach server, wait ts:${System.currentTimeMillis()}")
+                    // schedule to retry
+                    waitForNetwork()
+                    // if thread as been killed meanwhile
+//                    if (state == State.KILLING) break
+                }
+                Timber.v("## Server is Reachable")
+                // so network is available
+
+                runBlocking {
+                    retryLoop@ while (task.retryCount.get() < 3) {
+                        try {
+                            // SendPerformanceProfiler.startStage(task.event.eventId!!, SendPerformanceProfiler.Stages.SEND_WORKER)
+                            Timber.v("## SendThread retryLoop for $task retryCount ${task.retryCount}")
+                            task.execute()
+                            // sendEventTask.execute(SendEventTask.Params(task.event, task.encrypt, cryptoService))
+                            // SendPerformanceProfiler.stopStage(task.event.eventId, SendPerformanceProfiler.Stages.SEND_WORKER)
+                            break@retryLoop
+                        } catch (exception: Throwable) {
+                            when {
+                                exception is IOException || exception is Failure.NetworkConnection                         -> {
+                                    canReachServer = false
+                                    if (task.retryCount.getAndIncrement() >= 3) task.onTaskFailed()
+                                    while (!canReachServer) {
+                                        Timber.v("## SendThread retryLoop cannot reach server, wait ts:${System.currentTimeMillis()}")
+                                        // schedule to retry
+                                        waitForNetwork()
+                                    }
+                                }
+                                (exception is Failure.ServerError && exception.error.code == MatrixError.M_LIMIT_EXCEEDED) -> {
+                                    if (task.retryCount.getAndIncrement() >= 3) task.onTaskFailed()
+                                    Timber.v("## SendThread retryLoop retryable error for $task reason: ${exception.localizedMessage}")
+                                    // wait a bit
+                                    // Todo if its a quota exception can we get timout?
+                                    sleep(3_000)
+                                    continue@retryLoop
+                                }
+                                exception.isTokenError()                                                                   -> {
+                                    Timber.v("## SendThread retryLoop retryable TOKEN error, interrupt")
+                                    // we can exit the loop
+                                    task.onTaskFailed()
+                                    throw InterruptedException()
+                                }
+                                exception is CancellationException                                                         -> {
+                                    Timber.v("## SendThread task has been cancelled")
+                                    break@retryLoop
+                                }
+                                else                                                                                       -> {
+                                    Timber.v("## SendThread retryLoop Un-Retryable error, try next task")
+                                    // this task is in error, check next one?
+                                    task.onTaskFailed()
+                                    break@retryLoop
+                                }
+                            }
+                        }
+                    }
+                }
+                markAsFinished(task)
+            }
+        } catch (interruptionException: InterruptedException) {
+            // will be thrown is thread is interrupted while seeping
+            interrupt()
+            Timber.v("## InterruptedException!! ${interruptionException.localizedMessage}")
+        }
+//        state = State.KILLED
+        // is this needed?
+        retryNoNetworkTask?.cancel()
+        Timber.w("## SendThread finished ${System.currentTimeMillis()}")
+    }
+
+    private fun waitForNetwork() {
+        retryNoNetworkTask = Timer(SyncState.NoNetwork.toString(), false).schedule(RETRY_WAIT_TIME_MS) {
+            synchronized(networkAvailableLock) {
+                canReachServer = HomeServerAvailabilityChecker(sessionParams).check().also {
+                    Timber.v("## SendThread checkHostAvailable $it")
+                }
+                networkAvailableLock.notify()
+            }
+        }
+        synchronized(networkAvailableLock) { networkAvailableLock.wait() }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/HomeServerAvailabilityChecker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/HomeServerAvailabilityChecker.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2d53699917b03c819fd0ac04882a61edf7fea8ca
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/HomeServerAvailabilityChecker.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.room.send.queue
+
+import org.matrix.android.sdk.api.auth.data.SessionParams
+import timber.log.Timber
+import java.io.IOException
+import java.net.InetAddress
+import java.net.InetSocketAddress
+import java.net.Socket
+
+internal class HomeServerAvailabilityChecker(val sessionParams: SessionParams) {
+
+    fun check(): Boolean {
+        val host = sessionParams.homeServerConnectionConfig.homeServerUri.host ?: return false
+        val port = sessionParams.homeServerConnectionConfig.homeServerUri.port.takeIf { it != -1 } ?: 80
+        val timeout = 30_000
+        try {
+            Socket().use { socket ->
+                val inetAddress: InetAddress = InetAddress.getByName(host)
+                val inetSocketAddress = InetSocketAddress(inetAddress, port)
+                socket.connect(inetSocketAddress, timeout)
+                return true
+            }
+        } catch (e: IOException) {
+            Timber.v("## EventSender isHostAvailable failure ${e.localizedMessage}")
+            return false
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueueMemento.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueueMemento.kt
index dfbac347d94f5b5d638a58f91c33fa15d5ab40ec..116c8d5c6b6c8a0ddf6e2ffff9b2e02c09c7e019 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueueMemento.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueueMemento.kt
@@ -32,6 +32,9 @@ import javax.inject.Inject
  * It is just used to remember what events/localEchos was managed by the event sender in order to
  * reschedule them (and only them) on next restart
  */
+
+private const val PERSISTENCE_KEY = "ManagedBySender"
+
 internal class QueueMemento @Inject constructor(context: Context,
                                                 @SessionId sessionId: String,
                                                 private val queuedTaskFactory: QueuedTaskFactory,
@@ -39,50 +42,49 @@ internal class QueueMemento @Inject constructor(context: Context,
                                                 private val cryptoService: CryptoService) {
 
     private val storage = context.getSharedPreferences("QueueMemento_$sessionId", Context.MODE_PRIVATE)
-    private val managedTaskInfos = mutableListOf<QueuedTask>()
+    private val trackedTasks = mutableListOf<QueuedTask>()
 
-    fun track(task: QueuedTask) {
-        synchronized(managedTaskInfos) {
-            managedTaskInfos.add(task)
-            persist()
-        }
+    fun track(task: QueuedTask) = synchronized(trackedTasks) {
+        trackedTasks.add(task)
+        persist()
     }
 
-    fun unTrack(task: QueuedTask) {
-        managedTaskInfos.remove(task)
+    fun unTrack(task: QueuedTask) = synchronized(trackedTasks) {
+        trackedTasks.remove(task)
         persist()
     }
 
+    fun trackedTasks() = synchronized(trackedTasks) {
+    }
+
     private fun persist() {
-        managedTaskInfos.mapIndexedNotNull { index, queuedTask ->
+        trackedTasks.mapIndexedNotNull { index, queuedTask ->
             toTaskInfo(queuedTask, index)?.let { TaskInfo.map(it) }
         }.toSet().let { set ->
             storage.edit()
-                    .putStringSet("ManagedBySender", set)
+                    .putStringSet(PERSISTENCE_KEY, set)
                     .apply()
         }
     }
 
     private fun toTaskInfo(task: QueuedTask, order: Int): TaskInfo? {
-        synchronized(managedTaskInfos) {
-            return when (task) {
-                is SendEventQueuedTask -> SendEventTaskInfo(
-                        localEchoId = task.event.eventId ?: "",
-                        encrypt = task.encrypt,
-                        order = order
-                )
-                is RedactQueuedTask    -> RedactEventTaskInfo(
-                        redactionLocalEcho = task.redactionLocalEchoId,
-                        order = order
-                )
-                else                   -> null
-            }
+        return when (task) {
+            is SendEventQueuedTask -> SendEventTaskInfo(
+                    localEchoId = task.event.eventId ?: "",
+                    encrypt = task.encrypt,
+                    order = order
+            )
+            is RedactQueuedTask -> RedactEventTaskInfo(
+                    redactionLocalEcho = task.redactionLocalEchoId,
+                    order = order
+            )
+            else                   -> null
         }
     }
 
     suspend fun restoreTasks(eventProcessor: EventSenderProcessor) {
         // events should be restarted in correct order
-        storage.getStringSet("ManagedBySender", null)?.let { pending ->
+        storage.getStringSet(PERSISTENCE_KEY, null)?.let { pending ->
             Timber.d("## Send - Recovering unsent events $pending")
             pending.mapNotNull { tryOrNull { TaskInfo.map(it) } }
         }
@@ -90,7 +92,7 @@ internal class QueueMemento @Inject constructor(context: Context,
                 ?.forEach { info ->
                     try {
                         when (info) {
-                            is SendEventTaskInfo   -> {
+                            is SendEventTaskInfo -> {
                                 localEchoRepository.getUpToDateEcho(info.localEchoId)?.let {
                                     if (it.sendState.isSending() && it.eventId != null && it.roomId != null) {
                                         localEchoRepository.updateSendState(it.eventId, it.roomId, SendState.UNSENT)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueuedTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueuedTask.kt
index 9a7fcd8d9148ea6860542ddaf0dc356a75aac0dd..948786677d4803cb43a040b5c75f1ab77b7fdc1f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueuedTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueuedTask.kt
@@ -17,15 +17,29 @@
 package org.matrix.android.sdk.internal.session.room.send.queue
 
 import org.matrix.android.sdk.api.util.Cancelable
+import timber.log.Timber
+import java.util.concurrent.atomic.AtomicInteger
 
-abstract class QueuedTask : Cancelable {
-    var retryCount = 0
+/**
+ * @param queueIdentifier String value to identify a unique Queue
+ * @param taskIdentifier String value to identify a unique Task. Should be different from queueIdentifier
+ */
+internal abstract class QueuedTask(
+        val queueIdentifier: String,
+        val taskIdentifier: String
+) : Cancelable {
+
+    override fun toString() = "${javaClass.simpleName} queueIdentifier: $queueIdentifier, taskIdentifier:  $taskIdentifier)"
+
+    var retryCount = AtomicInteger(0)
 
     private var hasBeenCancelled: Boolean = false
 
     suspend fun execute() {
         if (!isCancelled()) {
+            Timber.v("Execute: $this start")
             doExecute()
+            Timber.v("Execute: $this finish")
         }
     }
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/RedactQueuedTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/RedactQueuedTask.kt
index 8e7ba2f15525486f6bb44e3a67b723ea66ee63a3..0e3d88aa792f9ab1156bcfbf4e56f257bbf17069 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/RedactQueuedTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/RedactQueuedTask.kt
@@ -29,9 +29,7 @@ internal class RedactQueuedTask(
         private val redactEventTask: RedactEventTask,
         private val localEchoRepository: LocalEchoRepository,
         private val cancelSendTracker: CancelSendTracker
-) : QueuedTask() {
-
-    override fun toString() = "[RedactQueuedTask $redactionLocalEchoId]"
+) : QueuedTask(queueIdentifier = roomId, taskIdentifier = redactionLocalEchoId) {
 
     override suspend fun doExecute() {
         redactEventTask.execute(RedactEventTask.Params(redactionLocalEchoId, roomId, toRedactEventId, reason))
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/SendEventQueuedTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/SendEventQueuedTask.kt
index ea097082c71abdecd0e1dab3819d9ff8c483bb6e..49492e79907dd44fc1735b760b7ccd5f63772403 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/SendEventQueuedTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/SendEventQueuedTask.kt
@@ -31,9 +31,7 @@ internal class SendEventQueuedTask(
         val cryptoService: CryptoService,
         val localEchoRepository: LocalEchoRepository,
         val cancelSendTracker: CancelSendTracker
-) : QueuedTask() {
-
-    override fun toString() = "[SendEventQueuedTask ${event.eventId}]"
+) : QueuedTask(queueIdentifier = event.roomId!!, taskIdentifier = event.eventId!!) {
 
     override suspend fun doExecute() {
         sendEventTask.execute(SendEventTask.Params(event, encrypt))
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/TaskInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/TaskInfo.kt
index 87c6299c4d86f9f34d627232283c338dee4e816c..a03ab778f68ca6980454402350094244b8dd1e64 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/TaskInfo.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/TaskInfo.kt
@@ -36,7 +36,7 @@ internal interface TaskInfo {
         const val TYPE_SEND = "TYPE_SEND"
         const val TYPE_REDACT = "TYPE_REDACT"
 
-        val moshi = Moshi.Builder()
+        private val moshi = Moshi.Builder()
                 .add(RuntimeJsonAdapterFactory.of(TaskInfo::class.java, "type", FallbackTaskInfo::class.java)
                         .registerSubtype(SendEventTaskInfo::class.java, TYPE_SEND)
                         .registerSubtype(RedactEventTaskInfo::class.java, TYPE_REDACT)
@@ -71,6 +71,6 @@ internal data class RedactEventTaskInfo(
 
 @JsonClass(generateAdapter = true)
 internal data class FallbackTaskInfo(
-        @Json(name = "type") override val type: String = TaskInfo.TYPE_REDACT,
+        @Json(name = "type") override val type: String = TaskInfo.TYPE_UNKNOWN,
         @Json(name = "order") override val order: Int
 ) : TaskInfo
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt
index d0f6f8050ec7ffb344a70c130ab0627e7fed3fd1..a25a362bfa5bbd08ec13ba9fb9bb2deb0637c129 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt
@@ -80,7 +80,11 @@ internal class StateEventDataSource @Inject constructor(@SessionDatabase private
     ): RealmQuery<CurrentStateEventEntity> {
         return realm.where<CurrentStateEventEntity>()
                 .equalTo(CurrentStateEventEntityFields.ROOM_ID, roomId)
-                .`in`(CurrentStateEventEntityFields.TYPE, eventTypes.toTypedArray())
+                .apply {
+                    if (eventTypes.isNotEmpty()) {
+                        `in`(CurrentStateEventEntityFields.TYPE, eventTypes.toTypedArray())
+                    }
+                }
                 .process(CurrentStateEventEntityFields.STATE_KEY, stateKey)
     }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt
index ae90282d52d2e49dad52cf82021c3b9c6bac8ea8..d0946abe28c1747ff705dc52d962ee169a1a31c1 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt
@@ -28,13 +28,7 @@ import org.matrix.android.sdk.api.NoOpMatrixCallback
 import org.matrix.android.sdk.api.extensions.orFalse
 import org.matrix.android.sdk.api.extensions.tryOrNull
 import org.matrix.android.sdk.api.session.events.model.EventType
-import org.matrix.android.sdk.api.session.events.model.RelationType
-import org.matrix.android.sdk.api.session.events.model.toModel
-import org.matrix.android.sdk.api.session.room.model.EventAnnotationsSummary
-import org.matrix.android.sdk.api.session.room.model.ReactionAggregatedSummary
 import org.matrix.android.sdk.api.session.room.model.ReadReceipt
-import org.matrix.android.sdk.api.session.room.model.message.MessageContent
-import org.matrix.android.sdk.api.session.room.model.relation.ReactionContent
 import org.matrix.android.sdk.api.session.room.send.SendState
 import org.matrix.android.sdk.api.session.room.timeline.Timeline
 import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
@@ -43,11 +37,9 @@ import org.matrix.android.sdk.api.util.CancelableBag
 import org.matrix.android.sdk.internal.database.RealmSessionProvider
 import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
 import org.matrix.android.sdk.internal.database.model.ChunkEntity
-import org.matrix.android.sdk.internal.database.model.ChunkEntityFields
 import org.matrix.android.sdk.internal.database.model.RoomEntity
 import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
 import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
-import org.matrix.android.sdk.internal.database.query.filterEvents
 import org.matrix.android.sdk.internal.database.query.findAllInRoomWithSendStates
 import org.matrix.android.sdk.internal.database.query.where
 import org.matrix.android.sdk.internal.database.query.whereRoomId
@@ -84,7 +76,8 @@ internal class DefaultTimeline(
         private val loadRoomMembersTask: LoadRoomMembersTask
 ) : Timeline,
         TimelineHiddenReadReceipts.Delegate,
-        TimelineInput.Listener {
+        TimelineInput.Listener,
+        UIEchoManager.Listener {
 
     companion object {
         val BACKGROUND_HANDLER = createBackgroundHandler("TIMELINE_DB_THREAD")
@@ -105,12 +98,12 @@ internal class DefaultTimeline(
     private var prevDisplayIndex: Int? = null
     private var nextDisplayIndex: Int? = null
 
-    private val uiEchoManager = UIEchoManager()
+    private val uiEchoManager = UIEchoManager(settings, this)
 
     private val builtEvents = Collections.synchronizedList<TimelineEvent>(ArrayList())
     private val builtEventsIdMap = Collections.synchronizedMap(HashMap<String, Int>())
-    private val backwardsState = AtomicReference(State())
-    private val forwardsState = AtomicReference(State())
+    private val backwardsState = AtomicReference(TimelineState())
+    private val forwardsState = AtomicReference(TimelineState())
 
     override val timelineID = UUID.randomUUID().toString()
 
@@ -169,13 +162,13 @@ internal class DefaultTimeline(
                 // are still used for ui echo (relation like reaction)
                 sendingEvents = roomEntity.sendingTimelineEvents.where()/*.filterEventsWithSettings()*/.findAll()
                 sendingEvents.addChangeListener { events ->
-                    uiEchoManager.sentEventsUpdated(events)
+                    uiEchoManager.onSentEventsInDatabase(events.map { it.eventId })
                     postSnapshot()
                 }
 
                 nonFilteredEvents = buildEventQuery(realm).sort(TimelineEventEntityFields.DISPLAY_INDEX, Sort.DESCENDING).findAll()
                 filteredEvents = nonFilteredEvents.where()
-                        .filterEventsWithSettings()
+                        .filterEventsWithSettings(settings)
                         .findAll()
                 nonFilteredEvents.addChangeListener(eventsChangeListener)
                 handleInitialLoad()
@@ -261,7 +254,9 @@ internal class DefaultTimeline(
                     .equalTo(TimelineEventEntityFields.EVENT_ID, eventId)
                     .findFirst()
 
-            val filteredEvents = nonFilteredEvents.where().filterEventsWithSettings().findAll()
+            val filteredEvents = nonFilteredEvents.where()
+                    .filterEventsWithSettings(settings)
+                    .findAll()
             val isEventInDb = nonFilteredEvent != null
 
             val isHidden = isEventInDb && filteredEvents.where()
@@ -327,20 +322,29 @@ internal class DefaultTimeline(
     }
 
     override fun onLocalEchoCreated(roomId: String, timelineEvent: TimelineEvent) {
-        if (uiEchoManager.onLocalEchoCreated(roomId, timelineEvent)) {
+        if (roomId != this.roomId || !isLive) return
+
+        val postSnapShot = uiEchoManager.onLocalEchoCreated(timelineEvent)
+
+        if (listOf(timelineEvent).filterEventsWithSettings(settings).isNotEmpty()) {
+            listeners.forEach {
+                it.onNewTimelineEvents(listOf(timelineEvent.eventId))
+            }
+        }
+
+        if (postSnapShot) {
             postSnapshot()
         }
     }
 
     override fun onLocalEchoUpdated(roomId: String, eventId: String, sendState: SendState) {
-        if (uiEchoManager.onLocalEchoUpdated(roomId, eventId, sendState)) {
+        if (roomId != this.roomId || !isLive) return
+        if (uiEchoManager.onSendStateUpdated(eventId, sendState)) {
             postSnapshot()
         }
     }
 
-// Private methods *****************************************************************************
-
-    private fun rebuildEvent(eventId: String, builder: (TimelineEvent) -> TimelineEvent?): Boolean {
+    override fun rebuildEvent(eventId: String, builder: (TimelineEvent) -> TimelineEvent?): Boolean {
         return tryOrNull {
             builtEventsIdMap[eventId]?.let { builtIndex ->
                 // Update the relation of existing event
@@ -360,6 +364,8 @@ internal class DefaultTimeline(
         } ?: false
     }
 
+// Private methods *****************************************************************************
+
     private fun hasMoreInCache(direction: Timeline.Direction) = getState(direction).hasMoreInCache
 
     private fun hasReachedEnd(direction: Timeline.Direction) = getState(direction).hasReachedEnd
@@ -412,35 +418,41 @@ internal class DefaultTimeline(
     }
 
     private fun buildSendingEvents(): List<TimelineEvent> {
-        val builtSendingEvents = ArrayList<TimelineEvent>()
+        val builtSendingEvents = mutableListOf<TimelineEvent>()
         if (hasReachedEnd(Timeline.Direction.FORWARDS) && !hasMoreInCache(Timeline.Direction.FORWARDS)) {
-            builtSendingEvents.addAll(uiEchoManager.getInMemorySendingEvents().filterEventsWithSettings())
+            uiEchoManager.getInMemorySendingEvents()
+                    .filterSendingEventsTo(builtSendingEvents)
             sendingEvents
-                    .map { timelineEventMapper.map(it) }
-                    // Filter out sending event that are not displayable!
-                    .filterEventsWithSettings()
-                    .forEach { timelineEvent ->
-                        if (builtSendingEvents.find { it.eventId == timelineEvent.eventId } == null) {
-                            uiEchoManager.updateSentStateWithUiEcho(timelineEvent)
-                            builtSendingEvents.add(timelineEvent)
-                        }
+                    .filter { timelineEvent ->
+                        builtSendingEvents.none { it.eventId == timelineEvent.eventId }
                     }
+                    .map { timelineEventMapper.map(it) }
+                    .filterSendingEventsTo(builtSendingEvents)
         }
         return builtSendingEvents
     }
 
+    private fun List<TimelineEvent>.filterSendingEventsTo(target: MutableList<TimelineEvent>) {
+        target.addAll(
+                // Filter out sending event that are not displayable!
+                filterEventsWithSettings(settings)
+                        // Get most up to date send state (in memory)
+                        .map { uiEchoManager.updateSentStateWithUiEcho(it) }
+        )
+    }
+
     private fun canPaginate(direction: Timeline.Direction): Boolean {
         return isReady.get() && !getState(direction).isPaginating && hasMoreToLoad(direction)
     }
 
-    private fun getState(direction: Timeline.Direction): State {
+    private fun getState(direction: Timeline.Direction): TimelineState {
         return when (direction) {
             Timeline.Direction.FORWARDS  -> forwardsState.get()
             Timeline.Direction.BACKWARDS -> backwardsState.get()
         }
     }
 
-    private fun updateState(direction: Timeline.Direction, update: (State) -> State) {
+    private fun updateState(direction: Timeline.Direction, update: (TimelineState) -> TimelineState) {
         val stateReference = when (direction) {
             Timeline.Direction.FORWARDS  -> forwardsState
             Timeline.Direction.BACKWARDS -> backwardsState
@@ -512,7 +524,7 @@ internal class DefaultTimeline(
             eventEntity?.eventId?.let { eventId ->
                 postSnapshot = rebuildEvent(eventId) {
                     val builtEvent = buildTimelineEvent(eventEntity)
-                    listOf(builtEvent).filterEventsWithSettings().firstOrNull()
+                    listOf(builtEvent).filterEventsWithSettings(settings).firstOrNull()
                 } || postSnapshot
             }
         }
@@ -688,11 +700,11 @@ internal class DefaultTimeline(
         return if (initialEventId == null) {
             TimelineEventEntity
                     .whereRoomId(realm, roomId = roomId)
-                    .equalTo("${TimelineEventEntityFields.CHUNK}.${ChunkEntityFields.IS_LAST_FORWARD}", true)
+                    .equalTo(TimelineEventEntityFields.CHUNK.IS_LAST_FORWARD, true)
         } else {
             TimelineEventEntity
                     .whereRoomId(realm, roomId = roomId)
-                    .`in`("${TimelineEventEntityFields.CHUNK}.${ChunkEntityFields.TIMELINE_EVENTS.EVENT_ID}", arrayOf(initialEventId))
+                    .`in`("${TimelineEventEntityFields.CHUNK.TIMELINE_EVENTS}.${TimelineEventEntityFields.EVENT_ID}", arrayOf(initialEventId))
         }
     }
 
@@ -745,8 +757,8 @@ internal class DefaultTimeline(
         nextDisplayIndex = null
         builtEvents.clear()
         builtEventsIdMap.clear()
-        backwardsState.set(State())
-        forwardsState.set(State())
+        backwardsState.set(TimelineState())
+        forwardsState.set(TimelineState())
     }
 
     private fun createPaginationCallback(limit: Int, direction: Timeline.Direction): MatrixCallback<TokenChunkEventPersistor.Result> {
@@ -780,191 +792,4 @@ internal class DefaultTimeline(
     private fun Timeline.Direction.toPaginationDirection(): PaginationDirection {
         return if (this == Timeline.Direction.BACKWARDS) PaginationDirection.BACKWARDS else PaginationDirection.FORWARDS
     }
-
-    private fun RealmQuery<TimelineEventEntity>.filterEventsWithSettings(): RealmQuery<TimelineEventEntity> {
-        return filterEvents(settings.filters)
-    }
-
-    private fun List<TimelineEvent>.filterEventsWithSettings(): List<TimelineEvent> {
-        return filter { event ->
-            val filterType = !settings.filters.filterTypes
-                    || settings.filters.allowedTypes.any { it.eventType == event.root.type && (it.stateKey == null || it.stateKey == event.root.senderId) }
-            if (!filterType) return@filter false
-
-            val filterEdits = if (settings.filters.filterEdits && event.root.getClearType() == EventType.MESSAGE) {
-                val messageContent = event.root.getClearContent().toModel<MessageContent>()
-                messageContent?.relatesTo?.type != RelationType.REPLACE && messageContent?.relatesTo?.type != RelationType.RESPONSE
-            } else {
-                true
-            }
-            if (!filterEdits) return@filter false
-
-            val filterRedacted = settings.filters.filterRedacted && event.root.isRedacted()
-            !filterRedacted
-        }
-    }
-
-    private data class State(
-            val hasReachedEnd: Boolean = false,
-            val hasMoreInCache: Boolean = true,
-            val isPaginating: Boolean = false,
-            val requestedPaginationCount: Int = 0
-    )
-
-    private data class ReactionUiEchoData(
-            val localEchoId: String,
-            val reactedOnEventId: String,
-            val reaction: String
-    )
-
-    inner class UIEchoManager {
-
-        private val inMemorySendingEvents = Collections.synchronizedList<TimelineEvent>(ArrayList())
-
-        fun getInMemorySendingEvents(): List<TimelineEvent> {
-            return inMemorySendingEvents.toList()
-        }
-
-        /**
-         * Due to lag of DB updates, we keep some UI echo of some properties to update timeline faster
-         */
-        private val inMemorySendingStates = Collections.synchronizedMap<String, SendState>(HashMap())
-
-        private val inMemoryReactions = Collections.synchronizedMap<String, MutableList<ReactionUiEchoData>>(HashMap())
-
-        fun sentEventsUpdated(events: RealmResults<TimelineEventEntity>) {
-            // Remove in memory as soon as they are known by database
-            events.forEach { te ->
-                inMemorySendingEvents.removeAll { te.eventId == it.eventId }
-            }
-            inMemorySendingStates.keys.removeAll { key ->
-                events.find { it.eventId == key } == null
-            }
-
-            inMemoryReactions.forEach { (_, uiEchoData) ->
-                uiEchoData.removeAll { data ->
-                    // I remove the uiEcho, when the related event is not anymore in the sending list
-                    // (means that it is synced)!
-                    events.find { it.eventId == data.localEchoId } == null
-                }
-            }
-        }
-
-        fun onLocalEchoUpdated(roomId: String, eventId: String, sendState: SendState): Boolean {
-            if (isLive && roomId == this@DefaultTimeline.roomId) {
-                val existingState = inMemorySendingStates[eventId]
-                inMemorySendingStates[eventId] = sendState
-                if (existingState != sendState) {
-                    return true
-                }
-            }
-            return false
-        }
-
-        // return true if should update
-        fun onLocalEchoCreated(roomId: String, timelineEvent: TimelineEvent): Boolean {
-            var postSnapshot = false
-            if (isLive && roomId == this@DefaultTimeline.roomId) {
-                // Manage some ui echos (do it before filter because actual event could be filtered out)
-                when (timelineEvent.root.getClearType()) {
-                    EventType.REDACTION -> {
-                    }
-                    EventType.REACTION  -> {
-                        val content = timelineEvent.root.content?.toModel<ReactionContent>()
-                        if (RelationType.ANNOTATION == content?.relatesTo?.type) {
-                            val reaction = content.relatesTo.key
-                            val relatedEventID = content.relatesTo.eventId
-                            inMemoryReactions.getOrPut(relatedEventID) { mutableListOf() }
-                                    .add(
-                                            ReactionUiEchoData(
-                                                    localEchoId = timelineEvent.eventId,
-                                                    reactedOnEventId = relatedEventID,
-                                                    reaction = reaction
-                                            )
-                                    )
-                            postSnapshot = rebuildEvent(relatedEventID) {
-                                decorateEventWithReactionUiEcho(it)
-                            } || postSnapshot
-                        }
-                    }
-                }
-
-                // do not add events that would have been filtered
-                if (listOf(timelineEvent).filterEventsWithSettings().isNotEmpty()) {
-                    listeners.forEach {
-                        it.onNewTimelineEvents(listOf(timelineEvent.eventId))
-                    }
-                    Timber.v("On local echo created: ${timelineEvent.eventId}")
-                    inMemorySendingEvents.add(0, timelineEvent)
-                    postSnapshot = true
-                }
-            }
-            return postSnapshot
-        }
-
-        fun decorateEventWithReactionUiEcho(timelineEvent: TimelineEvent): TimelineEvent? {
-            val relatedEventID = timelineEvent.eventId
-            val contents = inMemoryReactions[relatedEventID] ?: return null
-
-            var existingAnnotationSummary = timelineEvent.annotations ?: EventAnnotationsSummary(
-                    relatedEventID
-            )
-            val updateReactions = existingAnnotationSummary.reactionsSummary.toMutableList()
-
-            contents.forEach { uiEchoReaction ->
-                val existing = updateReactions.firstOrNull { it.key == uiEchoReaction.reaction }
-                if (existing == null) {
-                    // just add the new key
-                    ReactionAggregatedSummary(
-                            key = uiEchoReaction.reaction,
-                            count = 1,
-                            addedByMe = true,
-                            firstTimestamp = System.currentTimeMillis(),
-                            sourceEvents = emptyList(),
-                            localEchoEvents = listOf(uiEchoReaction.localEchoId)
-                    ).let { updateReactions.add(it) }
-                } else {
-                    // update Existing Key
-                    if (!existing.localEchoEvents.contains(uiEchoReaction.localEchoId)) {
-                        updateReactions.remove(existing)
-                        // only update if echo is not yet there
-                        ReactionAggregatedSummary(
-                                key = existing.key,
-                                count = existing.count + 1,
-                                addedByMe = true,
-                                firstTimestamp = existing.firstTimestamp,
-                                sourceEvents = existing.sourceEvents,
-                                localEchoEvents = existing.localEchoEvents + uiEchoReaction.localEchoId
-
-                        ).let { updateReactions.add(it) }
-                    }
-                }
-            }
-
-            existingAnnotationSummary = existingAnnotationSummary.copy(
-                    reactionsSummary = updateReactions
-            )
-            return timelineEvent.copy(
-                    annotations = existingAnnotationSummary
-            )
-        }
-
-        fun updateSentStateWithUiEcho(element: TimelineEvent) {
-            inMemorySendingStates[element.eventId]?.let {
-                // Timber.v("## ${System.currentTimeMillis()} Send event refresh echo with live state ${it} from state ${element.root.sendState}")
-                element.root.sendState = element.root.sendState.takeIf { it == SendState.SENT } ?: it
-            }
-        }
-
-        fun onSyncedEvent(transactionId: String?) {
-            val sendingEvent = inMemorySendingEvents.find {
-                it.eventId == transactionId
-            }
-            inMemorySendingEvents.remove(sendingEvent)
-            // Is it too early to clear it? will be done when removed from sending anyway?
-            inMemoryReactions.forEach { (_, u) ->
-                u.filterNot { it.localEchoId == transactionId }
-            }
-        }
-    }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt
index ef890db79e75947032a4208da4096ff0a7d24ed0..d000bbeb5027b17fcf08512053fa03980caf49e7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt
@@ -17,7 +17,6 @@
 package org.matrix.android.sdk.internal.session.room.timeline
 
 import androidx.lifecycle.LiveData
-import androidx.lifecycle.Transformations
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedInject
 import dagger.assisted.AssistedFactory
@@ -31,7 +30,6 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
 import org.matrix.android.sdk.api.session.room.timeline.TimelineService
 import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
 import org.matrix.android.sdk.api.util.Optional
-import org.matrix.android.sdk.api.util.toOptional
 import org.matrix.android.sdk.internal.database.RealmSessionProvider
 import org.matrix.android.sdk.internal.database.mapper.ReadReceiptsSummaryMapper
 import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
@@ -89,13 +87,7 @@ internal class DefaultTimelineService @AssistedInject constructor(@Assisted priv
     }
 
     override fun getTimeLineEventLive(eventId: String): LiveData<Optional<TimelineEvent>> {
-        val liveData = monarchy.findAllMappedWithChanges(
-                { TimelineEventEntity.where(it, roomId = roomId, eventId = eventId) },
-                { timelineEventMapper.map(it) }
-        )
-        return Transformations.map(liveData) { events ->
-            events.firstOrNull().toOptional()
-        }
+        return LiveTimelineEvent(timelineInput, monarchy, taskExecutor.executorScope, timelineEventMapper, roomId, eventId)
     }
 
     override fun getAttachmentMessages(): List<TimelineEvent> {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/Extensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/Extensions.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b2c8021f3b49487f3d705369c0b18c4db9709bc6
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/Extensions.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.room.timeline
+
+import io.realm.RealmQuery
+import org.matrix.android.sdk.api.session.events.model.EventType
+import org.matrix.android.sdk.api.session.events.model.RelationType
+import org.matrix.android.sdk.api.session.events.model.toModel
+import org.matrix.android.sdk.api.session.room.model.message.MessageContent
+import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
+import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
+import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
+import org.matrix.android.sdk.internal.database.query.filterEvents
+
+internal fun RealmQuery<TimelineEventEntity>.filterEventsWithSettings(settings: TimelineSettings): RealmQuery<TimelineEventEntity> {
+    return filterEvents(settings.filters)
+}
+
+internal fun List<TimelineEvent>.filterEventsWithSettings(settings: TimelineSettings): List<TimelineEvent> {
+    return filter { event ->
+        val filterType = !settings.filters.filterTypes
+                || settings.filters.allowedTypes.any { it.eventType == event.root.type && (it.stateKey == null || it.stateKey == event.root.senderId) }
+        if (!filterType) return@filter false
+
+        val filterEdits = if (settings.filters.filterEdits && event.root.getClearType() == EventType.MESSAGE) {
+            val messageContent = event.root.getClearContent().toModel<MessageContent>()
+            messageContent?.relatesTo?.type != RelationType.REPLACE && messageContent?.relatesTo?.type != RelationType.RESPONSE
+        } else {
+            true
+        }
+        if (!filterEdits) return@filter false
+
+        val filterRedacted = settings.filters.filterRedacted && event.root.isRedacted()
+        !filterRedacted
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LiveTimelineEvent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LiveTimelineEvent.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3c0f101e11da4f0a3dd3c892f12a508c31b565fd
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LiveTimelineEvent.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.room.timeline
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MediatorLiveData
+import androidx.lifecycle.Transformations
+import com.zhuinden.monarchy.Monarchy
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import org.matrix.android.sdk.api.session.events.model.LocalEcho
+import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
+import org.matrix.android.sdk.api.util.Optional
+import org.matrix.android.sdk.api.util.toOptional
+import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
+import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
+import org.matrix.android.sdk.internal.database.query.where
+import java.util.concurrent.atomic.AtomicBoolean
+
+/**
+ * This class takes care of handling case where local echo is replaced by the synced event in the db.
+ */
+internal class LiveTimelineEvent(private val timelineInput: TimelineInput,
+                                 private val monarchy: Monarchy,
+                                 private val coroutineScope: CoroutineScope,
+                                 private val timelineEventMapper: TimelineEventMapper,
+                                 private val roomId: String,
+                                 private val eventId: String)
+    : TimelineInput.Listener,
+        MediatorLiveData<Optional<TimelineEvent>>() {
+
+    private var queryLiveData: LiveData<Optional<TimelineEvent>>? = null
+
+    // If we are listening to local echo, we want to be aware when event is synced
+    private var shouldObserveSync = AtomicBoolean(LocalEcho.isLocalEchoId(eventId))
+
+    init {
+        buildAndObserveQuery(eventId)
+    }
+
+    // Makes sure it's made on the main thread
+    private fun buildAndObserveQuery(eventIdToObserve: String) = coroutineScope.launch(Dispatchers.Main) {
+        queryLiveData?.also {
+            removeSource(it)
+        }
+        val liveData = monarchy.findAllMappedWithChanges(
+                { TimelineEventEntity.where(it, roomId = roomId, eventId = eventIdToObserve) },
+                { timelineEventMapper.map(it) }
+        )
+        queryLiveData = Transformations.map(liveData) { events ->
+            events.firstOrNull().toOptional()
+        }.also {
+            addSource(it) { newValue -> value = newValue }
+        }
+    }
+
+    override fun onLocalEchoSynced(roomId: String, localEchoEventId: String, syncedEventId: String) {
+        if (this.roomId == roomId && localEchoEventId == this.eventId) {
+            timelineInput.listeners.remove(this)
+            shouldObserveSync.set(false)
+            // rebuild the query with the new eventId
+            buildAndObserveQuery(syncedEventId)
+        }
+    }
+
+    override fun onActive() {
+        super.onActive()
+        if (shouldObserveSync.get()) {
+            timelineInput.listeners.add(this)
+        }
+    }
+
+    override fun onInactive() {
+        super.onInactive()
+        if (shouldObserveSync.get()) {
+            timelineInput.listeners.remove(this)
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/ReactionUiEchoData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/ReactionUiEchoData.kt
new file mode 100644
index 0000000000000000000000000000000000000000..521120c4157bd075d9bd4b2d8c44d6a8beba0a93
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/ReactionUiEchoData.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.room.timeline
+
+internal data class ReactionUiEchoData(
+        val localEchoId: String,
+        val reactedOnEventId: String,
+        val reaction: String
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineHiddenReadReceipts.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineHiddenReadReceipts.kt
index fa517bebf2b1b3325f5f9ec1d7354d1c6ee55ac5..0ade8ad3b8e6f2a9d55f2f02541dde714b1e7e62 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineHiddenReadReceipts.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineHiddenReadReceipts.kt
@@ -24,6 +24,7 @@ import io.realm.RealmResults
 import org.matrix.android.sdk.api.session.room.model.ReadReceipt
 import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
 import org.matrix.android.sdk.internal.database.mapper.ReadReceiptsSummaryMapper
+import org.matrix.android.sdk.internal.database.model.EventEntityFields
 import org.matrix.android.sdk.internal.database.model.ReadReceiptsSummaryEntity
 import org.matrix.android.sdk.internal.database.model.ReadReceiptsSummaryEntityFields
 import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
@@ -121,7 +122,7 @@ internal class TimelineHiddenReadReceipts constructor(private val readReceiptsSu
         // We are looking for read receipts set on hidden events.
         // We only accept those with a timelineEvent (so coming from pagination/sync).
         this.hiddenReadReceipts = ReadReceiptsSummaryEntity.whereInRoom(realm, roomId)
-                .isNotEmpty(ReadReceiptsSummaryEntityFields.TIMELINE_EVENT)
+                .isNotEmpty(ReadReceiptsSummaryEntityFields.TIMELINE_EVENT.`$`)
                 .isNotEmpty(ReadReceiptsSummaryEntityFields.READ_RECEIPTS.`$`)
                 .filterReceiptsWithSettings()
                 .findAllAsync()
@@ -157,12 +158,12 @@ internal class TimelineHiddenReadReceipts constructor(private val readReceiptsSu
             // Result: D, F, H, I
             settings.filters.allowedTypes.forEachIndexed { index, filter ->
                 if (filter.stateKey == null) {
-                    notEqualTo("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.TYPE}", filter.eventType)
+                    notEqualTo("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT.ROOT}.${EventEntityFields.TYPE}", filter.eventType)
                 } else {
                     beginGroup()
-                    notEqualTo("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.TYPE}", filter.eventType)
+                    notEqualTo("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT.ROOT}.${EventEntityFields.TYPE}", filter.eventType)
                     or()
-                    notEqualTo("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.STATE_KEY}", filter.stateKey)
+                    notEqualTo("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT.ROOT}.${EventEntityFields.STATE_KEY}", filter.stateKey)
                     endGroup()
                 }
                 if (index != settings.filters.allowedTypes.size - 1) {
@@ -174,19 +175,19 @@ internal class TimelineHiddenReadReceipts constructor(private val readReceiptsSu
         }
         if (settings.filters.filterUseless) {
             if (needOr) or()
-            equalTo("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.IS_USELESS}", true)
+            equalTo("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT.ROOT}.${EventEntityFields.IS_USELESS}", true)
             needOr = true
         }
         if (settings.filters.filterEdits) {
             if (needOr) or()
-            like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.CONTENT}", TimelineEventFilter.Content.EDIT)
+            like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT.ROOT}.${EventEntityFields.CONTENT}", TimelineEventFilter.Content.EDIT)
             or()
-            like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.CONTENT}", TimelineEventFilter.Content.RESPONSE)
+            like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT.ROOT}.${EventEntityFields.CONTENT}", TimelineEventFilter.Content.RESPONSE)
             needOr = true
         }
         if (settings.filters.filterRedacted) {
             if (needOr) or()
-            like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.UNSIGNED_DATA}", TimelineEventFilter.Unsigned.REDACTED)
+            like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT.ROOT}.${EventEntityFields.UNSIGNED_DATA}", TimelineEventFilter.Unsigned.REDACTED)
         }
         endGroup()
         return this
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineInput.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineInput.kt
index 002ab1dd8a17fe41aec312fcf90c3a8f88725bea..8911f265d57367d56fdb1706981b57c9e53ee825 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineInput.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineInput.kt
@@ -35,11 +35,16 @@ internal class TimelineInput @Inject constructor() {
         listeners.toSet().forEach { it.onNewTimelineEvents(roomId, eventIds) }
     }
 
+    fun onLocalEchoSynced(roomId: String, localEchoEventId: String, syncEventId: String) {
+        listeners.toSet().forEach { it.onLocalEchoSynced(roomId, localEchoEventId, syncEventId) }
+    }
+
     val listeners = mutableSetOf<Listener>()
 
     internal interface Listener {
-        fun onLocalEchoCreated(roomId: String, timelineEvent: TimelineEvent)
-        fun onLocalEchoUpdated(roomId: String, eventId: String, sendState: SendState)
-        fun onNewTimelineEvents(roomId: String, eventIds: List<String>)
+        fun onLocalEchoCreated(roomId: String, timelineEvent: TimelineEvent) = Unit
+        fun onLocalEchoUpdated(roomId: String, eventId: String, sendState: SendState) = Unit
+        fun onNewTimelineEvents(roomId: String, eventIds: List<String>) = Unit
+        fun onLocalEchoSynced(roomId: String, localEchoEventId: String, syncedEventId: String) = Unit
     }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineState.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0143d9bab3d21498b03c9bb1f2f23d6f48609a6d
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineState.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.room.timeline
+
+internal data class TimelineState(
+        val hasReachedEnd: Boolean = false,
+        val hasMoreInCache: Boolean = true,
+        val isPaginating: Boolean = false,
+        val requestedPaginationCount: Int = 0
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt
index 1a497b883555a75d24759a9a6a037d8753b3cf5c..c38dcd00a73387e3ec1fe0697a607ef2bd8141ed 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt
@@ -22,16 +22,16 @@ import org.matrix.android.sdk.api.session.events.model.EventType
 import org.matrix.android.sdk.api.session.events.model.toModel
 import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
 import org.matrix.android.sdk.api.session.room.send.SendState
-import org.matrix.android.sdk.internal.database.helper.addOrUpdate
+import org.matrix.android.sdk.internal.database.helper.addIfNecessary
 import org.matrix.android.sdk.internal.database.helper.addStateEvent
 import org.matrix.android.sdk.internal.database.helper.addTimelineEvent
-import org.matrix.android.sdk.internal.database.helper.deleteOnCascade
 import org.matrix.android.sdk.internal.database.helper.merge
 import org.matrix.android.sdk.internal.database.mapper.toEntity
 import org.matrix.android.sdk.internal.database.model.ChunkEntity
 import org.matrix.android.sdk.internal.database.model.EventInsertType
 import org.matrix.android.sdk.internal.database.model.RoomEntity
 import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
+import org.matrix.android.sdk.internal.database.model.deleteOnCascade
 import org.matrix.android.sdk.internal.database.query.copyToRealmOrIgnore
 import org.matrix.android.sdk.internal.database.query.create
 import org.matrix.android.sdk.internal.database.query.find
@@ -172,7 +172,7 @@ internal class TokenChunkEventPersistor @Inject constructor(@SessionDatabase pri
             val currentLastForwardChunk = ChunkEntity.findLastForwardChunkOfRoom(realm, roomId)
             if (currentChunk != currentLastForwardChunk) {
                 currentChunk.isLastForward = true
-                currentLastForwardChunk?.deleteOnCascade()
+                currentLastForwardChunk?.deleteOnCascade(deleteStateEvents = false, canDeleteRoot = false)
                 RoomSummaryEntity.where(realm, roomId).findFirst()?.apply {
                     latestPreviewableEvent = RoomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId)
                 }
@@ -235,7 +235,7 @@ internal class TokenChunkEventPersistor @Inject constructor(@SessionDatabase pri
             }
         }
         chunksToDelete.forEach {
-            it.deleteOnCascade()
+            it.deleteOnCascade(deleteStateEvents = false, canDeleteRoot = false)
         }
         val roomSummaryEntity = RoomSummaryEntity.getOrCreate(realm, roomId)
         val shouldUpdateSummary = roomSummaryEntity.latestPreviewableEvent == null
@@ -244,7 +244,7 @@ internal class TokenChunkEventPersistor @Inject constructor(@SessionDatabase pri
             roomSummaryEntity.latestPreviewableEvent = RoomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId)
         }
         if (currentChunk.isValid) {
-            RoomEntity.where(realm, roomId).findFirst()?.addOrUpdate(currentChunk)
+            RoomEntity.where(realm, roomId).findFirst()?.addIfNecessary(currentChunk)
         }
     }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/UIEchoManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/UIEchoManager.kt
new file mode 100644
index 0000000000000000000000000000000000000000..67d0d90d7705d31d43a3c247aa26d48c19c770c3
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/UIEchoManager.kt
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.room.timeline
+
+import org.matrix.android.sdk.api.session.events.model.EventType
+import org.matrix.android.sdk.api.session.events.model.RelationType
+import org.matrix.android.sdk.api.session.events.model.toModel
+import org.matrix.android.sdk.api.session.room.model.EventAnnotationsSummary
+import org.matrix.android.sdk.api.session.room.model.ReactionAggregatedSummary
+import org.matrix.android.sdk.api.session.room.model.relation.ReactionContent
+import org.matrix.android.sdk.api.session.room.send.SendState
+import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
+import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
+import timber.log.Timber
+import java.util.Collections
+
+internal class UIEchoManager(
+        private val settings: TimelineSettings,
+        private val listener: Listener
+) {
+
+    interface Listener {
+        fun rebuildEvent(eventId: String, builder: (TimelineEvent) -> TimelineEvent?): Boolean
+    }
+
+    private val inMemorySendingEvents = Collections.synchronizedList<TimelineEvent>(ArrayList())
+
+    fun getInMemorySendingEvents(): List<TimelineEvent> {
+        return inMemorySendingEvents.toList()
+    }
+
+    /**
+     * Due to lag of DB updates, we keep some UI echo of some properties to update timeline faster
+     */
+    private val inMemorySendingStates = Collections.synchronizedMap<String, SendState>(HashMap())
+
+    private val inMemoryReactions = Collections.synchronizedMap<String, MutableList<ReactionUiEchoData>>(HashMap())
+
+    fun onSentEventsInDatabase(eventIds: List<String>) {
+        // Remove in memory as soon as they are known by database
+        eventIds.forEach { eventId ->
+            inMemorySendingEvents.removeAll { eventId == it.eventId }
+        }
+        inMemoryReactions.forEach { (_, uiEchoData) ->
+            uiEchoData.removeAll { data ->
+                // I remove the uiEcho, when the related event is not anymore in the sending list
+                // (means that it is synced)!
+                eventIds.find { it == data.localEchoId } == null
+            }
+        }
+    }
+
+    fun onSendStateUpdated(eventId: String, sendState: SendState): Boolean {
+        val existingState = inMemorySendingStates[eventId]
+        inMemorySendingStates[eventId] = sendState
+        return existingState != sendState
+    }
+
+    // return true if should update
+    fun onLocalEchoCreated(timelineEvent: TimelineEvent): Boolean {
+        var postSnapshot = false
+
+        // Manage some ui echos (do it before filter because actual event could be filtered out)
+        when (timelineEvent.root.getClearType()) {
+            EventType.REDACTION -> {
+            }
+            EventType.REACTION  -> {
+                val content = timelineEvent.root.content?.toModel<ReactionContent>()
+                if (RelationType.ANNOTATION == content?.relatesTo?.type) {
+                    val reaction = content.relatesTo.key
+                    val relatedEventID = content.relatesTo.eventId
+                    inMemoryReactions.getOrPut(relatedEventID) { mutableListOf() }
+                            .add(
+                                    ReactionUiEchoData(
+                                            localEchoId = timelineEvent.eventId,
+                                            reactedOnEventId = relatedEventID,
+                                            reaction = reaction
+                                    )
+                            )
+                    postSnapshot = listener.rebuildEvent(relatedEventID) {
+                        decorateEventWithReactionUiEcho(it)
+                    } || postSnapshot
+                }
+            }
+        }
+
+        // do not add events that would have been filtered
+        if (listOf(timelineEvent).filterEventsWithSettings(settings).isNotEmpty()) {
+            Timber.v("On local echo created: ${timelineEvent.eventId}")
+            inMemorySendingEvents.add(0, timelineEvent)
+            postSnapshot = true
+        }
+
+        return postSnapshot
+    }
+
+    fun decorateEventWithReactionUiEcho(timelineEvent: TimelineEvent): TimelineEvent? {
+        val relatedEventID = timelineEvent.eventId
+        val contents = inMemoryReactions[relatedEventID] ?: return null
+
+        var existingAnnotationSummary = timelineEvent.annotations ?: EventAnnotationsSummary(
+                relatedEventID
+        )
+        val updateReactions = existingAnnotationSummary.reactionsSummary.toMutableList()
+
+        contents.forEach { uiEchoReaction ->
+            val existing = updateReactions.firstOrNull { it.key == uiEchoReaction.reaction }
+            if (existing == null) {
+                // just add the new key
+                ReactionAggregatedSummary(
+                        key = uiEchoReaction.reaction,
+                        count = 1,
+                        addedByMe = true,
+                        firstTimestamp = System.currentTimeMillis(),
+                        sourceEvents = emptyList(),
+                        localEchoEvents = listOf(uiEchoReaction.localEchoId)
+                ).let { updateReactions.add(it) }
+            } else {
+                // update Existing Key
+                if (!existing.localEchoEvents.contains(uiEchoReaction.localEchoId)) {
+                    updateReactions.remove(existing)
+                    // only update if echo is not yet there
+                    ReactionAggregatedSummary(
+                            key = existing.key,
+                            count = existing.count + 1,
+                            addedByMe = true,
+                            firstTimestamp = existing.firstTimestamp,
+                            sourceEvents = existing.sourceEvents,
+                            localEchoEvents = existing.localEchoEvents + uiEchoReaction.localEchoId
+
+                    ).let { updateReactions.add(it) }
+                }
+            }
+        }
+
+        existingAnnotationSummary = existingAnnotationSummary.copy(
+                reactionsSummary = updateReactions
+        )
+        return timelineEvent.copy(
+                annotations = existingAnnotationSummary
+        )
+    }
+
+    fun updateSentStateWithUiEcho(timelineEvent: TimelineEvent): TimelineEvent {
+        if (timelineEvent.root.sendState.isSent()) return timelineEvent
+        val inMemoryState = inMemorySendingStates[timelineEvent.eventId] ?: return timelineEvent
+        // Timber.v("## ${System.currentTimeMillis()} Send event refresh echo with live state $inMemoryState from state ${element.root.sendState}")
+        return timelineEvent.copy(
+                root = timelineEvent.root.copyAll()
+                        .also { it.sendState = inMemoryState }
+        )
+    }
+
+    fun onSyncedEvent(transactionId: String?) {
+        val sendingEvent = inMemorySendingEvents.find {
+            it.eventId == transactionId
+        }
+        inMemorySendingEvents.remove(sendingEvent)
+        // Is it too early to clear it? will be done when removed from sending anyway?
+        inMemoryReactions.forEach { (_, u) ->
+            u.filterNot { it.localEchoId == transactionId }
+        }
+        inMemorySendingStates.remove(transactionId)
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt
index fc476a3dd69699ece2a6c0709084367f90880fd9..ae60faf9057a9680c1575fd0dd31b68a7d15142f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt
@@ -26,7 +26,7 @@ import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult
 import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult
 import org.matrix.android.sdk.internal.crypto.model.event.OlmEventContent
 import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService
-import org.matrix.android.sdk.internal.session.DefaultInitialSyncProgressService
+import org.matrix.android.sdk.internal.session.initsync.ProgressReporter
 import org.matrix.android.sdk.internal.session.sync.model.SyncResponse
 import org.matrix.android.sdk.internal.session.sync.model.ToDeviceSyncResponse
 import timber.log.Timber
@@ -35,10 +35,10 @@ import javax.inject.Inject
 internal class CryptoSyncHandler @Inject constructor(private val cryptoService: DefaultCryptoService,
                                                      private val verificationService: DefaultVerificationService) {
 
-    fun handleToDevice(toDevice: ToDeviceSyncResponse, initialSyncProgressService: DefaultInitialSyncProgressService? = null) {
+    fun handleToDevice(toDevice: ToDeviceSyncResponse, progressReporter: ProgressReporter? = null) {
         val total = toDevice.events?.size ?: 0
         toDevice.events?.forEachIndexed { index, event ->
-            initialSyncProgressService?.reportProgress(((index / total.toFloat()) * 100).toInt())
+            progressReporter?.reportProgress(index * 100F / total)
             // Decrypt event if necessary
             Timber.i("## CRYPTO | To device event from ${event.senderId} of type:${event.type}")
             decryptToDeviceEvent(event, null)
@@ -75,7 +75,7 @@ internal class CryptoSyncHandler @Inject constructor(private val cryptoService:
                 // try to find device id to ease log reading
                 val deviceId = cryptoService.getCryptoDeviceInfo(event.senderId!!).firstOrNull {
                     it.identityKey() == senderKey
-                 }?.deviceId ?: senderKey
+                }?.deviceId ?: senderKey
                 Timber.e("## CRYPTO | Failed to decrypt to device event from ${event.senderId}|$deviceId reason:<${event.mCryptoError ?: exception}>")
             }
 
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/GroupSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/GroupSyncHandler.kt
index 135f711a6cca74a2833c752c9d5566de053b170a..02362bf050e5512af37b7716f072b93056446e5b 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/GroupSyncHandler.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/GroupSyncHandler.kt
@@ -16,17 +16,17 @@
 
 package org.matrix.android.sdk.internal.session.sync
 
-import org.matrix.android.sdk.R
+import io.realm.Realm
+import org.matrix.android.sdk.api.session.initsync.InitSyncStep
 import org.matrix.android.sdk.api.session.room.model.Membership
 import org.matrix.android.sdk.internal.database.model.GroupEntity
 import org.matrix.android.sdk.internal.database.model.GroupSummaryEntity
 import org.matrix.android.sdk.internal.database.query.getOrCreate
 import org.matrix.android.sdk.internal.database.query.where
-import org.matrix.android.sdk.internal.session.DefaultInitialSyncProgressService
-import org.matrix.android.sdk.internal.session.mapWithProgress
+import org.matrix.android.sdk.internal.session.initsync.ProgressReporter
+import org.matrix.android.sdk.internal.session.initsync.mapWithProgress
 import org.matrix.android.sdk.internal.session.sync.model.GroupsSyncResponse
 import org.matrix.android.sdk.internal.session.sync.model.InvitedGroupSync
-import io.realm.Realm
 import javax.inject.Inject
 
 internal class GroupSyncHandler @Inject constructor() {
@@ -37,11 +37,9 @@ internal class GroupSyncHandler @Inject constructor() {
         data class LEFT(val data: Map<String, Any>) : HandlingStrategy()
     }
 
-    fun handle(
-            realm: Realm,
-            roomsSyncResponse: GroupsSyncResponse,
-            reporter: DefaultInitialSyncProgressService? = null
-    ) {
+    fun handle(realm: Realm,
+               roomsSyncResponse: GroupsSyncResponse,
+               reporter: ProgressReporter? = null) {
         handleGroupSync(realm, HandlingStrategy.JOINED(roomsSyncResponse.join), reporter)
         handleGroupSync(realm, HandlingStrategy.INVITED(roomsSyncResponse.invite), reporter)
         handleGroupSync(realm, HandlingStrategy.LEFT(roomsSyncResponse.leave), reporter)
@@ -49,20 +47,20 @@ internal class GroupSyncHandler @Inject constructor() {
 
     // PRIVATE METHODS *****************************************************************************
 
-    private fun handleGroupSync(realm: Realm, handlingStrategy: HandlingStrategy, reporter: DefaultInitialSyncProgressService?) {
+    private fun handleGroupSync(realm: Realm, handlingStrategy: HandlingStrategy, reporter: ProgressReporter?) {
         val groups = when (handlingStrategy) {
             is HandlingStrategy.JOINED  ->
-                handlingStrategy.data.mapWithProgress(reporter, R.string.initial_sync_start_importing_account_groups, 0.6f) {
+                handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountGroups, 0.6f) {
                     handleJoinedGroup(realm, it.key)
                 }
 
             is HandlingStrategy.INVITED ->
-                handlingStrategy.data.mapWithProgress(reporter, R.string.initial_sync_start_importing_account_groups, 0.3f) {
+                handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountGroups, 0.3f) {
                     handleInvitedGroup(realm, it.key)
                 }
 
             is HandlingStrategy.LEFT    ->
-                handlingStrategy.data.mapWithProgress(reporter, R.string.initial_sync_start_importing_account_groups, 0.1f) {
+                handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountGroups, 0.1f) {
                     handleLeftGroup(realm, it.key)
                 }
         }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStatusRepository.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStatusRepository.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4b82ecc3e5878e450d47f2d7c63ea929ee287f63
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStatusRepository.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.sync
+
+import com.squareup.moshi.JsonClass
+import okio.buffer
+import okio.source
+import org.matrix.android.sdk.internal.di.MoshiProvider
+import timber.log.Timber
+import java.io.File
+
+@JsonClass(generateAdapter = true)
+internal data class InitialSyncStatus(
+        val step: Int = STEP_INIT,
+        val downloadedDate: Long = 0
+) {
+    companion object {
+        const val STEP_INIT = 0
+        const val STEP_DOWNLOADING = 1
+        const val STEP_DOWNLOADED = 2
+        const val STEP_PARSED = 3
+        const val STEP_SUCCESS = 4
+    }
+}
+
+internal interface InitialSyncStatusRepository {
+    fun getStep(): Int
+
+    fun setStep(step: Int)
+}
+
+/**
+ * This class handle the current status of an initial sync and persist it on the disk, to be robust against crash
+ */
+internal class FileInitialSyncStatusRepository(directory: File) : InitialSyncStatusRepository {
+
+    companion object {
+        // After 2 hours, we consider that the downloaded file is outdated:
+        // - if a problem occurs, it's for big accounts, and big accounts have lots of new events in 2 hours
+        // - For small accounts, there should be no problem, so 2 hours delay will never be used.
+        private const val INIT_SYNC_FILE_LIFETIME = 2 * 60 * 60 * 1_000L
+    }
+
+    private val file = File(directory, "status.json")
+    private val jsonAdapter = MoshiProvider.providesMoshi().adapter(InitialSyncStatus::class.java)
+
+    private var cache: InitialSyncStatus? = null
+
+    override fun getStep(): Int {
+        ensureCache()
+        val state = cache?.step ?: InitialSyncStatus.STEP_INIT
+        return if (state >= InitialSyncStatus.STEP_DOWNLOADED
+                && System.currentTimeMillis() > (cache?.downloadedDate ?: 0) + INIT_SYNC_FILE_LIFETIME) {
+            Timber.v("INIT_SYNC downloaded file is outdated, download it again")
+            // The downloaded file is outdated
+            setStep(InitialSyncStatus.STEP_INIT)
+            InitialSyncStatus.STEP_INIT
+        } else {
+            state
+        }
+    }
+
+    override fun setStep(step: Int) {
+        var newStatus = cache?.copy(step = step) ?: InitialSyncStatus(step = step)
+        if (step == InitialSyncStatus.STEP_DOWNLOADED) {
+            // Also store the downloaded date
+            newStatus = newStatus.copy(
+                    downloadedDate = System.currentTimeMillis()
+            )
+        }
+        cache = newStatus
+        writeFile()
+    }
+
+    private fun ensureCache() {
+        if (cache == null) readFile()
+    }
+
+    /**
+     * File -> Cache
+     */
+    private fun readFile() {
+        cache = file
+                .takeIf { it.exists() }
+                ?.let { jsonAdapter.fromJson(it.source().buffer()) }
+    }
+
+    /**
+     * Cache -> File
+     */
+    private fun writeFile() {
+        file.delete()
+        cache
+                ?.let { jsonAdapter.toJson(it) }
+                ?.let { file.writeText(it) }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStrategy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStrategy.kt
new file mode 100644
index 0000000000000000000000000000000000000000..297cc213ed704f6c76058d05d34901e40a074d32
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStrategy.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.sync
+
+var initialSyncStrategy: InitialSyncStrategy = InitialSyncStrategy.Optimized()
+
+sealed class InitialSyncStrategy {
+    /**
+     * Parse the result in its entirety
+     * Pros:
+     * - Faster to handle parsed data
+     * Cons:
+     * - Slower to download and parse data
+     * - big RAM usage
+     * - not robust to crash
+     */
+    object Legacy : InitialSyncStrategy()
+
+    /**
+     * Optimized.
+     * First store the request result in a file, to avoid doing it again in case of crash
+     */
+    data class Optimized(
+            /**
+             * Limit to reach to decide to split the init sync response into smaller files
+             * Empiric value: 1 megabytes
+             */
+            val minSizeToSplit: Long = 1024 * 1024,
+            /**
+             * Limit per room to reach to decide to store a join room ephemeral Events into a file
+             * Empiric value: 6 kilobytes
+             */
+            val minSizeToStoreInFile: Long = 6 * 1024,
+            /**
+             * Max number of rooms to insert at a time in database (to avoid too much RAM usage)
+             */
+            val maxRoomsToInsert: Int = 100
+    ) : InitialSyncStrategy()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt
index 456b0f9c2625224be559f61e3675967889e99347..336a83eaadd1d5a26b9f746f599c977c99a36b29 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt
@@ -18,11 +18,11 @@ package org.matrix.android.sdk.internal.session.sync
 
 import io.realm.Realm
 import io.realm.kotlin.createObject
-import org.matrix.android.sdk.R
 import org.matrix.android.sdk.api.session.crypto.MXCryptoError
 import org.matrix.android.sdk.api.session.events.model.Event
 import org.matrix.android.sdk.api.session.events.model.EventType
 import org.matrix.android.sdk.api.session.events.model.toModel
+import org.matrix.android.sdk.api.session.initsync.InitSyncStep
 import org.matrix.android.sdk.api.session.room.model.Membership
 import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
 import org.matrix.android.sdk.api.session.room.model.tag.RoomTagContent
@@ -30,9 +30,8 @@ import org.matrix.android.sdk.api.session.room.send.SendState
 import org.matrix.android.sdk.internal.crypto.DefaultCryptoService
 import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
 import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult
-import org.matrix.android.sdk.internal.database.helper.addOrUpdate
+import org.matrix.android.sdk.internal.database.helper.addIfNecessary
 import org.matrix.android.sdk.internal.database.helper.addTimelineEvent
-import org.matrix.android.sdk.internal.database.helper.deleteOnCascade
 import org.matrix.android.sdk.internal.database.mapper.asDomain
 import org.matrix.android.sdk.internal.database.mapper.toEntity
 import org.matrix.android.sdk.internal.database.model.ChunkEntity
@@ -40,6 +39,7 @@ import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
 import org.matrix.android.sdk.internal.database.model.EventInsertType
 import org.matrix.android.sdk.internal.database.model.RoomEntity
 import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity
+import org.matrix.android.sdk.internal.database.model.deleteOnCascade
 import org.matrix.android.sdk.internal.database.query.copyToRealmOrIgnore
 import org.matrix.android.sdk.internal.database.query.find
 import org.matrix.android.sdk.internal.database.query.findLastForwardChunkOfRoom
@@ -48,8 +48,10 @@ import org.matrix.android.sdk.internal.database.query.getOrNull
 import org.matrix.android.sdk.internal.database.query.where
 import org.matrix.android.sdk.internal.di.MoshiProvider
 import org.matrix.android.sdk.internal.di.UserId
-import org.matrix.android.sdk.internal.session.DefaultInitialSyncProgressService
-import org.matrix.android.sdk.internal.session.mapWithProgress
+import org.matrix.android.sdk.internal.extensions.clearWith
+import org.matrix.android.sdk.internal.session.initsync.ProgressReporter
+import org.matrix.android.sdk.internal.session.initsync.mapWithProgress
+import org.matrix.android.sdk.internal.session.initsync.reportSubtask
 import org.matrix.android.sdk.internal.session.room.membership.RoomChangeMembershipStateDataSource
 import org.matrix.android.sdk.internal.session.room.membership.RoomMemberEventHandler
 import org.matrix.android.sdk.internal.session.room.read.FullyReadContent
@@ -60,10 +62,10 @@ import org.matrix.android.sdk.internal.session.room.typing.TypingEventContent
 import org.matrix.android.sdk.internal.session.sync.model.InvitedRoomSync
 import org.matrix.android.sdk.internal.session.sync.model.RoomSync
 import org.matrix.android.sdk.internal.session.sync.model.RoomSyncAccountData
-import org.matrix.android.sdk.internal.session.sync.model.RoomSyncEphemeral
 import org.matrix.android.sdk.internal.session.sync.model.RoomsSyncResponse
 import timber.log.Timber
 import javax.inject.Inject
+import kotlin.math.ceil
 
 internal class RoomSyncHandler @Inject constructor(private val readReceiptHandler: ReadReceiptHandler,
                                                    private val roomSummaryUpdater: RoomSummaryUpdater,
@@ -82,21 +84,32 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
         data class LEFT(val data: Map<String, RoomSync>) : HandlingStrategy()
     }
 
-    fun handle(
-            realm: Realm,
-            roomsSyncResponse: RoomsSyncResponse,
-            isInitialSync: Boolean,
-            reporter: DefaultInitialSyncProgressService? = null
-    ) {
+    fun handle(realm: Realm,
+               roomsSyncResponse: RoomsSyncResponse,
+               isInitialSync: Boolean,
+               reporter: ProgressReporter? = null) {
         Timber.v("Execute transaction from $this")
         handleRoomSync(realm, HandlingStrategy.JOINED(roomsSyncResponse.join), isInitialSync, reporter)
         handleRoomSync(realm, HandlingStrategy.INVITED(roomsSyncResponse.invite), isInitialSync, reporter)
         handleRoomSync(realm, HandlingStrategy.LEFT(roomsSyncResponse.leave), isInitialSync, reporter)
     }
 
+    fun handleInitSyncEphemeral(realm: Realm,
+                                roomsSyncResponse: RoomsSyncResponse) {
+        roomsSyncResponse.join.forEach { roomSync ->
+            val ephemeralResult = roomSync.value.ephemeral
+                    ?.roomSyncEphemeral
+                    ?.events
+                    ?.takeIf { it.isNotEmpty() }
+                    ?.let { events -> handleEphemeral(realm, roomSync.key, events, true) }
+
+            roomTypingUsersHandler.handle(realm, roomSync.key, ephemeralResult)
+        }
+    }
+
     // PRIVATE METHODS *****************************************************************************
 
-    private fun handleRoomSync(realm: Realm, handlingStrategy: HandlingStrategy, isInitialSync: Boolean, reporter: DefaultInitialSyncProgressService?) {
+    private fun handleRoomSync(realm: Realm, handlingStrategy: HandlingStrategy, isInitialSync: Boolean, reporter: ProgressReporter?) {
         val insertType = if (isInitialSync) {
             EventInsertType.INITIAL_SYNC
         } else {
@@ -104,17 +117,24 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
         }
         val syncLocalTimeStampMillis = System.currentTimeMillis()
         val rooms = when (handlingStrategy) {
-            is HandlingStrategy.JOINED  ->
-                handlingStrategy.data.mapWithProgress(reporter, R.string.initial_sync_start_importing_account_joined_rooms, 0.6f) {
-                    handleJoinedRoom(realm, it.key, it.value, isInitialSync, insertType, syncLocalTimeStampMillis)
+            is HandlingStrategy.JOINED  -> {
+                if (isInitialSync && initialSyncStrategy is InitialSyncStrategy.Optimized) {
+                    insertJoinRoomsFromInitSync(realm, handlingStrategy, syncLocalTimeStampMillis, reporter)
+                    // Rooms are already inserted, return an empty list
+                    emptyList()
+                } else {
+                    handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountJoinedRooms, 0.6f) {
+                        handleJoinedRoom(realm, it.key, it.value, true, insertType, syncLocalTimeStampMillis)
+                    }
                 }
+            }
             is HandlingStrategy.INVITED ->
-                handlingStrategy.data.mapWithProgress(reporter, R.string.initial_sync_start_importing_account_invited_rooms, 0.1f) {
+                handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountInvitedRooms, 0.1f) {
                     handleInvitedRoom(realm, it.key, it.value, insertType, syncLocalTimeStampMillis)
                 }
 
             is HandlingStrategy.LEFT    -> {
-                handlingStrategy.data.mapWithProgress(reporter, R.string.initial_sync_start_importing_account_left_rooms, 0.3f) {
+                handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountLeftRooms, 0.3f) {
                     handleLeftRoom(realm, it.key, it.value, insertType, syncLocalTimeStampMillis)
                 }
             }
@@ -122,17 +142,60 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
         realm.insertOrUpdate(rooms)
     }
 
+    private fun insertJoinRoomsFromInitSync(realm: Realm,
+                                            handlingStrategy: HandlingStrategy.JOINED,
+                                            syncLocalTimeStampMillis: Long,
+                                            reporter: ProgressReporter?) {
+        val maxSize = (initialSyncStrategy as? InitialSyncStrategy.Optimized)?.maxRoomsToInsert ?: Int.MAX_VALUE
+        val listSize = handlingStrategy.data.keys.size
+        val numberOfChunks = ceil(listSize / maxSize.toDouble()).toInt()
+
+        if (numberOfChunks > 1) {
+            reportSubtask(reporter, InitSyncStep.ImportingAccountJoinedRooms, numberOfChunks, 0.6f) {
+                val chunkSize = listSize / numberOfChunks
+                Timber.v("INIT_SYNC $listSize rooms to insert, split into $numberOfChunks sublists of $chunkSize items")
+                // I cannot find a better way to chunk a map, so chunk the keys and then create new maps
+                handlingStrategy.data.keys
+                        .chunked(chunkSize)
+                        .forEachIndexed { index, roomIds ->
+                            val roomEntities = roomIds
+                                    .also { Timber.v("INIT_SYNC insert ${roomIds.size} rooms") }
+                                    .map {
+                                        handleJoinedRoom(
+                                                realm = realm,
+                                                roomId = it,
+                                                roomSync = handlingStrategy.data[it] ?: error("Should not happen"),
+                                                handleEphemeralEvents = false,
+                                                insertType = EventInsertType.INITIAL_SYNC,
+                                                syncLocalTimestampMillis = syncLocalTimeStampMillis
+                                        )
+                                    }
+                            realm.insertOrUpdate(roomEntities)
+                            reporter?.reportProgress(index + 1F)
+                        }
+            }
+        } else {
+            // No need to split
+            val rooms = handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountJoinedRooms, 0.6f) {
+                handleJoinedRoom(realm, it.key, it.value, false, EventInsertType.INITIAL_SYNC, syncLocalTimeStampMillis)
+            }
+            realm.insertOrUpdate(rooms)
+        }
+    }
+
     private fun handleJoinedRoom(realm: Realm,
                                  roomId: String,
                                  roomSync: RoomSync,
-                                 isInitialSync: Boolean,
+                                 handleEphemeralEvents: Boolean,
                                  insertType: EventInsertType,
                                  syncLocalTimestampMillis: Long): RoomEntity {
         Timber.v("Handle join sync for room $roomId")
 
         var ephemeralResult: EphemeralResult? = null
-        if (roomSync.ephemeral?.events?.isNotEmpty() == true) {
-            ephemeralResult = handleEphemeral(realm, roomId, roomSync.ephemeral, isInitialSync)
+        if (handleEphemeralEvents) {
+            ephemeralResult = roomSync.ephemeral?.roomSyncEphemeral?.events
+                    ?.takeIf { it.isNotEmpty() }
+                    ?.let { handleEphemeral(realm, roomId, it, insertType == EventInsertType.INITIAL_SYNC) }
         }
 
         if (roomSync.accountData?.events?.isNotEmpty() == true) {
@@ -149,7 +212,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
         // State event
         if (roomSync.state?.events?.isNotEmpty() == true) {
             for (event in roomSync.state.events) {
-                if (event.eventId == null || event.stateKey == null) {
+                if (event.eventId == null || event.stateKey == null || event.type == null) {
                     continue
                 }
                 val ageLocalTs = event.unsignedData?.age?.let { syncLocalTimestampMillis - it }
@@ -172,10 +235,9 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
                     roomSync.timeline.prevToken,
                     roomSync.timeline.limited,
                     insertType,
-                    syncLocalTimestampMillis,
-                    isInitialSync
+                    syncLocalTimestampMillis
             )
-            roomEntity.addOrUpdate(chunkEntity)
+            roomEntity.addIfNecessary(chunkEntity)
         }
         val hasRoomMember = roomSync.state?.events?.firstOrNull {
             it.type == EventType.STATE_ROOM_MEMBER
@@ -206,7 +268,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
         roomEntity.membership = Membership.INVITE
         if (roomSync.inviteState != null && roomSync.inviteState.events.isNotEmpty()) {
             roomSync.inviteState.events.forEach { event ->
-                if (event.stateKey == null) {
+                if (event.stateKey == null || event.type == null) {
                     return@forEach
                 }
                 val ageLocalTs = event.unsignedData?.age?.let { syncLocalTimestampMillis - it }
@@ -233,7 +295,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
                                syncLocalTimestampMillis: Long): RoomEntity {
         val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId)
         for (event in roomSync.state?.events.orEmpty()) {
-            if (event.eventId == null || event.stateKey == null) {
+            if (event.eventId == null || event.stateKey == null || event.type == null) {
                 continue
             }
             val ageLocalTs = event.unsignedData?.age?.let { syncLocalTimestampMillis - it }
@@ -245,7 +307,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
             roomMemberEventHandler.handle(realm, roomId, event)
         }
         for (event in roomSync.timeline?.events.orEmpty()) {
-            if (event.eventId == null || event.senderId == null) {
+            if (event.eventId == null || event.senderId == null || event.type == null) {
                 continue
             }
             val ageLocalTs = event.unsignedData?.age?.let { syncLocalTimestampMillis - it }
@@ -263,7 +325,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
         val leftMember = RoomMemberSummaryEntity.where(realm, roomId, userId).findFirst()
         val membership = leftMember?.membership ?: Membership.LEAVE
         roomEntity.membership = membership
-        roomEntity.chunks.deleteAllFromRealm()
+        roomEntity.chunks.clearWith { it.deleteOnCascade(deleteStateEvents = true, canDeleteRoot = true) }
         roomTypingUsersHandler.handle(realm, roomId, null)
         roomChangeMembershipStateDataSource.setMembershipFromSync(roomId, Membership.LEAVE)
         roomSummaryUpdater.update(realm, roomId, membership, roomSync.summary, roomSync.unreadNotifications)
@@ -277,8 +339,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
                                      prevToken: String? = null,
                                      isLimited: Boolean = true,
                                      insertType: EventInsertType,
-                                     syncLocalTimestampMillis: Long,
-                                     isInitialSync: Boolean): ChunkEntity {
+                                     syncLocalTimestampMillis: Long): ChunkEntity {
         val lastChunk = ChunkEntity.findLastForwardChunkOfRoom(realm, roomEntity.roomId)
         val chunkEntity = if (!isLimited && lastChunk != null) {
             lastChunk
@@ -293,12 +354,12 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
         val roomMemberContentsByUser = HashMap<String, RoomMemberContent?>()
 
         for (event in eventList) {
-            if (event.eventId == null || event.senderId == null) {
+            if (event.eventId == null || event.senderId == null || event.type == null) {
                 continue
             }
             eventIds.add(event.eventId)
 
-            if (event.isEncrypted() && !isInitialSync) {
+            if (event.isEncrypted() && insertType != EventInsertType.INITIAL_SYNC) {
                 decryptIfNeeded(event, roomId)
             }
 
@@ -339,8 +400,9 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
                             event.mxDecryptionResult = adapter.fromJson(json)
                         }
                     }
+                    timelineInput.onLocalEchoSynced(roomId, it, event.eventId)
                     // Finally delete the local echo
-                    sendingEventEntity.deleteOnCascade()
+                    sendingEventEntity.deleteOnCascade(true)
                 } else {
                     Timber.v("Can't find corresponding local echo for tx:$it")
                 }
@@ -374,10 +436,10 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
 
     private fun handleEphemeral(realm: Realm,
                                 roomId: String,
-                                ephemeral: RoomSyncEphemeral,
+                                ephemeralEvents: List<Event>,
                                 isInitialSync: Boolean): EphemeralResult {
         var result = EphemeralResult()
-        for (event in ephemeral.events) {
+        for (event in ephemeralEvents) {
             when (event.type) {
                 EventType.RECEIPT -> {
                     @Suppress("UNCHECKED_CAST")
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncAPI.kt
index 77289f04b43a21238b7e715948bfebf5bce6464a..8e3523bc5767ab44d773d1463770b8bb317a0e95 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncAPI.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncAPI.kt
@@ -16,6 +16,7 @@
 
 package org.matrix.android.sdk.internal.session.sync
 
+import okhttp3.ResponseBody
 import org.matrix.android.sdk.internal.network.NetworkConstants
 import org.matrix.android.sdk.internal.network.TimeOutInterceptor
 import org.matrix.android.sdk.internal.session.sync.model.SyncResponse
@@ -23,6 +24,7 @@ import retrofit2.Call
 import retrofit2.http.GET
 import retrofit2.http.Header
 import retrofit2.http.QueryMap
+import retrofit2.http.Streaming
 
 internal interface SyncAPI {
     /**
@@ -34,4 +36,15 @@ internal interface SyncAPI {
              @Header(TimeOutInterceptor.READ_TIMEOUT) readTimeOut: Long = TimeOutInterceptor.DEFAULT_LONG_TIMEOUT,
              @Header(TimeOutInterceptor.WRITE_TIMEOUT) writeTimeOut: Long = TimeOutInterceptor.DEFAULT_LONG_TIMEOUT
     ): Call<SyncResponse>
+
+    /**
+     * Set all the timeouts to 1 minute by default
+     */
+    @Streaming
+    @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "sync")
+    fun syncStream(@QueryMap params: Map<String, String>,
+                   @Header(TimeOutInterceptor.CONNECT_TIMEOUT) connectTimeOut: Long = TimeOutInterceptor.DEFAULT_LONG_TIMEOUT,
+                   @Header(TimeOutInterceptor.READ_TIMEOUT) readTimeOut: Long = TimeOutInterceptor.DEFAULT_LONG_TIMEOUT,
+                   @Header(TimeOutInterceptor.WRITE_TIMEOUT) writeTimeOut: Long = TimeOutInterceptor.DEFAULT_LONG_TIMEOUT
+    ): Call<ResponseBody>
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt
index a80b062427f78057d308bb3b2a16554ea6101b1f..d17a672485d7b4ceb077bc8f3bfe59bd4c8647eb 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt
@@ -18,17 +18,17 @@ package org.matrix.android.sdk.internal.session.sync
 
 import androidx.work.ExistingPeriodicWorkPolicy
 import com.zhuinden.monarchy.Monarchy
-import org.matrix.android.sdk.R
 import org.matrix.android.sdk.api.pushrules.PushRuleService
 import org.matrix.android.sdk.api.pushrules.RuleScope
+import org.matrix.android.sdk.api.session.initsync.InitSyncStep
 import org.matrix.android.sdk.internal.crypto.DefaultCryptoService
 import org.matrix.android.sdk.internal.di.SessionDatabase
 import org.matrix.android.sdk.internal.di.SessionId
 import org.matrix.android.sdk.internal.di.WorkManagerProvider
-import org.matrix.android.sdk.internal.session.DefaultInitialSyncProgressService
 import org.matrix.android.sdk.internal.session.group.GetGroupDataWorker
+import org.matrix.android.sdk.internal.session.initsync.ProgressReporter
+import org.matrix.android.sdk.internal.session.initsync.reportSubtask
 import org.matrix.android.sdk.internal.session.notification.ProcessEventForPushTask
-import org.matrix.android.sdk.internal.session.reportSubtask
 import org.matrix.android.sdk.internal.session.sync.model.GroupsSyncResponse
 import org.matrix.android.sdk.internal.session.sync.model.RoomsSyncResponse
 import org.matrix.android.sdk.internal.session.sync.model.SyncResponse
@@ -51,13 +51,13 @@ internal class SyncResponseHandler @Inject constructor(@SessionDatabase private
                                                        private val cryptoService: DefaultCryptoService,
                                                        private val tokenStore: SyncTokenStore,
                                                        private val processEventForPushTask: ProcessEventForPushTask,
-                                                       private val pushRuleService: PushRuleService,
-                                                       private val initialSyncProgressService: DefaultInitialSyncProgressService) {
+                                                       private val pushRuleService: PushRuleService) {
 
-    suspend fun handleResponse(syncResponse: SyncResponse, fromToken: String?) {
+    suspend fun handleResponse(syncResponse: SyncResponse,
+                               fromToken: String?,
+                               reporter: ProgressReporter?) {
         val isInitialSync = fromToken == null
         Timber.v("Start handling sync, is InitialSync: $isInitialSync")
-        val reporter = initialSyncProgressService.takeIf { isInitialSync }
 
         measureTimeMillis {
             if (!cryptoService.isStarted()) {
@@ -73,7 +73,7 @@ internal class SyncResponseHandler @Inject constructor(@SessionDatabase private
         // to ensure to decrypt them properly
         measureTimeMillis {
             Timber.v("Handle toDevice")
-            reportSubtask(reporter, R.string.initial_sync_start_importing_account_crypto, 100, 0.1f) {
+            reportSubtask(reporter, InitSyncStep.ImportingAccountCrypto, 100, 0.1f) {
                 if (syncResponse.toDevice != null) {
                     cryptoSyncHandler.handleToDevice(syncResponse.toDevice, reporter)
                 }
@@ -85,7 +85,7 @@ internal class SyncResponseHandler @Inject constructor(@SessionDatabase private
         monarchy.awaitTransaction { realm ->
             measureTimeMillis {
                 Timber.v("Handle rooms")
-                reportSubtask(reporter, R.string.initial_sync_start_importing_account_rooms, 100, 0.7f) {
+                reportSubtask(reporter, InitSyncStep.ImportingAccountRoom, 1, 0.7f) {
                     if (syncResponse.rooms != null) {
                         roomSyncHandler.handle(realm, syncResponse.rooms, isInitialSync, reporter)
                     }
@@ -95,7 +95,7 @@ internal class SyncResponseHandler @Inject constructor(@SessionDatabase private
             }
 
             measureTimeMillis {
-                reportSubtask(reporter, R.string.initial_sync_start_importing_account_groups, 100, 0.1f) {
+                reportSubtask(reporter, InitSyncStep.ImportingAccountGroups, 1, 0.1f) {
                     Timber.v("Handle groups")
                     if (syncResponse.groups != null) {
                         groupSyncHandler.handle(realm, syncResponse.groups, reporter)
@@ -106,7 +106,7 @@ internal class SyncResponseHandler @Inject constructor(@SessionDatabase private
             }
 
             measureTimeMillis {
-                reportSubtask(reporter, R.string.initial_sync_start_importing_account_data, 100, 0.1f) {
+                reportSubtask(reporter, InitSyncStep.ImportingAccountData, 1, 0.1f) {
                     Timber.v("Handle accountData")
                     userAccountDataSyncHandler.handle(realm, syncResponse.accountData)
                 }
@@ -128,6 +128,15 @@ internal class SyncResponseHandler @Inject constructor(@SessionDatabase private
         cryptoSyncHandler.onSyncCompleted(syncResponse)
     }
 
+    suspend fun handleInitSyncSecondTransaction(syncResponse: SyncResponse) {
+        // Start another transaction to handle the ephemeral events
+        monarchy.awaitTransaction { realm ->
+            if (syncResponse.rooms != null) {
+                roomSyncHandler.handleInitSyncEphemeral(realm, syncResponse.rooms)
+            }
+        }
+    }
+
     /**
      * At the moment we don't get any group data through the sync, so we poll where every hour.
      * You can also force to refetch group data using [Group] API.
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt
index 7c38230065ff8bb5c6ff3e5001bb0e95b0a5a64e..00060a33b11db2fee0dbcf34228b59520e651147 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt
@@ -16,18 +16,29 @@
 
 package org.matrix.android.sdk.internal.session.sync
 
-import org.matrix.android.sdk.R
+import okhttp3.ResponseBody
+import org.matrix.android.sdk.api.session.initsync.InitSyncStep
+import org.matrix.android.sdk.internal.di.SessionFilesDirectory
 import org.matrix.android.sdk.internal.di.UserId
 import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
 import org.matrix.android.sdk.internal.network.TimeOutInterceptor
 import org.matrix.android.sdk.internal.network.executeRequest
-import org.matrix.android.sdk.internal.session.DefaultInitialSyncProgressService
+import org.matrix.android.sdk.internal.network.toFailure
 import org.matrix.android.sdk.internal.session.filter.FilterRepository
 import org.matrix.android.sdk.internal.session.homeserver.GetHomeServerCapabilitiesTask
+import org.matrix.android.sdk.internal.session.initsync.DefaultInitialSyncProgressService
+import org.matrix.android.sdk.internal.session.initsync.reportSubtask
+import org.matrix.android.sdk.internal.session.sync.model.LazyRoomSyncEphemeral
 import org.matrix.android.sdk.internal.session.sync.model.SyncResponse
+import org.matrix.android.sdk.internal.session.sync.parsing.InitialSyncResponseParser
 import org.matrix.android.sdk.internal.session.user.UserStore
 import org.matrix.android.sdk.internal.task.Task
+import org.matrix.android.sdk.internal.util.logDuration
+import retrofit2.Response
+import retrofit2.awaitResponse
 import timber.log.Timber
+import java.io.File
+import java.net.SocketTimeoutException
 import javax.inject.Inject
 
 internal interface SyncTask : Task<SyncTask.Params, Unit> {
@@ -48,11 +59,19 @@ internal class DefaultSyncTask @Inject constructor(
         private val getHomeServerCapabilitiesTask: GetHomeServerCapabilitiesTask,
         private val userStore: UserStore,
         private val syncTaskSequencer: SyncTaskSequencer,
-        private val globalErrorReceiver: GlobalErrorReceiver
+        private val globalErrorReceiver: GlobalErrorReceiver,
+        @SessionFilesDirectory
+        private val fileDirectory: File,
+        private val syncResponseParser: InitialSyncResponseParser
 ) : SyncTask {
 
-    override suspend fun execute(params: SyncTask.Params) = syncTaskSequencer.post {
-        doSync(params)
+    private val workingDir = File(fileDirectory, "is")
+    private val initialSyncStatusRepository: InitialSyncStatusRepository = FileInitialSyncStatusRepository(workingDir)
+
+    override suspend fun execute(params: SyncTask.Params) {
+        syncTaskSequencer.post {
+            doSync(params)
+        }
     }
 
     private suspend fun doSync(params: SyncTask.Params) {
@@ -73,28 +92,136 @@ internal class DefaultSyncTask @Inject constructor(
         if (isInitialSync) {
             // We might want to get the user information in parallel too
             userStore.createOrUpdate(userId)
-            initialSyncProgressService.endAll()
-            initialSyncProgressService.startTask(R.string.initial_sync_start_importing_account, 100)
+            initialSyncProgressService.startRoot(InitSyncStep.ImportingAccount, 100)
         }
         // Maybe refresh the home server capabilities data we know
-        getHomeServerCapabilitiesTask.execute(Unit)
+        getHomeServerCapabilitiesTask.execute(GetHomeServerCapabilitiesTask.Params(forceRefresh = false))
 
         val readTimeOut = (params.timeout + TIMEOUT_MARGIN).coerceAtLeast(TimeOutInterceptor.DEFAULT_LONG_TIMEOUT)
 
-        val syncResponse = executeRequest<SyncResponse>(globalErrorReceiver) {
-            apiCall = syncAPI.sync(
-                    params = requestParams,
-                    readTimeOut = readTimeOut
-            )
-        }
-        syncResponseHandler.handleResponse(syncResponse, token)
         if (isInitialSync) {
+            Timber.v("INIT_SYNC with filter: ${requestParams["filter"]}")
+            val initSyncStrategy = initialSyncStrategy
+            var syncResp: SyncResponse? = null
+            logDuration("INIT_SYNC strategy: $initSyncStrategy") {
+                if (initSyncStrategy is InitialSyncStrategy.Optimized) {
+                    val file = downloadInitSyncResponse(requestParams)
+                    syncResp = reportSubtask(initialSyncProgressService, InitSyncStep.ImportingAccount, 1, 0.7F) {
+                        handleSyncFile(file, initSyncStrategy)
+                    }
+                } else {
+                    val syncResponse = logDuration("INIT_SYNC Request") {
+                        executeRequest<SyncResponse>(globalErrorReceiver) {
+                            apiCall = syncAPI.sync(
+                                    params = requestParams,
+                                    readTimeOut = readTimeOut
+                            )
+                        }
+                    }
+
+                    logDuration("INIT_SYNC Database insertion") {
+                        syncResponseHandler.handleResponse(syncResponse, token, initialSyncProgressService)
+                    }
+                }
+            }
             initialSyncProgressService.endAll()
+
+            if (initSyncStrategy is InitialSyncStrategy.Optimized) {
+                logDuration("INIT_SYNC Handle ephemeral") {
+                    syncResponseHandler.handleInitSyncSecondTransaction(syncResp!!)
+                }
+                initialSyncStatusRepository.setStep(InitialSyncStatus.STEP_SUCCESS)
+                // Delete all files
+                workingDir.deleteRecursively()
+            }
+        } else {
+            val syncResponse = executeRequest<SyncResponse>(globalErrorReceiver) {
+                apiCall = syncAPI.sync(
+                        params = requestParams,
+                        readTimeOut = readTimeOut
+                )
+            }
+            syncResponseHandler.handleResponse(syncResponse, token, null)
         }
         Timber.v("Sync task finished on Thread: ${Thread.currentThread().name}")
     }
 
+    private suspend fun downloadInitSyncResponse(requestParams: Map<String, String>): File {
+        workingDir.mkdirs()
+        val workingFile = File(workingDir, "initSync.json")
+        val status = initialSyncStatusRepository.getStep()
+        if (workingFile.exists() && status >= InitialSyncStatus.STEP_DOWNLOADED) {
+            Timber.v("INIT_SYNC file is already here")
+            reportSubtask(initialSyncProgressService, InitSyncStep.Downloading, 1, 0.3f) {
+                // Empty task
+            }
+        } else {
+            initialSyncStatusRepository.setStep(InitialSyncStatus.STEP_DOWNLOADING)
+            val syncResponse = logDuration("INIT_SYNC Perform server request") {
+                reportSubtask(initialSyncProgressService, InitSyncStep.ServerComputing, 1, 0.2f) {
+                    getSyncResponse(requestParams, MAX_NUMBER_OF_RETRY_AFTER_TIMEOUT)
+                }
+            }
+
+            if (syncResponse.isSuccessful) {
+                logDuration("INIT_SYNC Download and save to file") {
+                    reportSubtask(initialSyncProgressService, InitSyncStep.Downloading, 1, 0.1f) {
+                        syncResponse.body()?.byteStream()?.use { inputStream ->
+                            workingFile.outputStream().use { outputStream ->
+                                inputStream.copyTo(outputStream)
+                            }
+                        }
+                    }
+                }
+            } else {
+                throw syncResponse.toFailure(globalErrorReceiver)
+                        .also { Timber.w("INIT_SYNC request failure: $this") }
+            }
+            initialSyncStatusRepository.setStep(InitialSyncStatus.STEP_DOWNLOADED)
+        }
+        return workingFile
+    }
+
+    private suspend fun getSyncResponse(requestParams: Map<String, String>, maxNumberOfRetries: Int): Response<ResponseBody> {
+        var retry = maxNumberOfRetries
+        while (true) {
+            retry--
+            try {
+                return syncAPI.syncStream(
+                        params = requestParams
+                ).awaitResponse()
+            } catch (throwable: Throwable) {
+                if (throwable is SocketTimeoutException && retry > 0) {
+                    Timber.w("INIT_SYNC timeout retry left: $retry")
+                } else {
+                    Timber.e(throwable, "INIT_SYNC timeout, no retry left, or other error")
+                    throw throwable
+                }
+            }
+        }
+    }
+
+    private suspend fun handleSyncFile(workingFile: File, initSyncStrategy: InitialSyncStrategy.Optimized): SyncResponse {
+        return logDuration("INIT_SYNC handleSyncFile()") {
+            val syncResponse = logDuration("INIT_SYNC Read file and parse") {
+                syncResponseParser.parse(initSyncStrategy, workingFile)
+            }
+            initialSyncStatusRepository.setStep(InitialSyncStatus.STEP_PARSED)
+            // Log some stats
+            val nbOfJoinedRooms = syncResponse.rooms?.join?.size ?: 0
+            val nbOfJoinedRoomsInFile = syncResponse.rooms?.join?.values?.count { it.ephemeral is LazyRoomSyncEphemeral.Stored }
+            Timber.v("INIT_SYNC $nbOfJoinedRooms rooms, $nbOfJoinedRoomsInFile ephemeral stored into files")
+
+            logDuration("INIT_SYNC Database insertion") {
+                syncResponseHandler.handleResponse(syncResponse, null, initialSyncProgressService)
+            }
+            syncResponse
+        }
+    }
+
     companion object {
+        private const val MAX_NUMBER_OF_RETRY_AFTER_TIMEOUT = 50
+
         private const val TIMEOUT_MARGIN: Long = 10_000
     }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt
index 0e549172f30f275d08dfb7519568280f255bedf4..449d47abe5580670a8a245623b6210062fb3da81 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt
@@ -16,8 +16,10 @@
 
 package org.matrix.android.sdk.internal.session.sync
 
-import com.squareup.moshi.Moshi
 import com.zhuinden.monarchy.Monarchy
+import io.realm.Realm
+import io.realm.RealmList
+import io.realm.kotlin.where
 import org.matrix.android.sdk.api.pushrules.RuleScope
 import org.matrix.android.sdk.api.pushrules.RuleSetKey
 import org.matrix.android.sdk.api.pushrules.rest.GetPushRulesResponse
@@ -37,6 +39,7 @@ import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
 import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
 import org.matrix.android.sdk.internal.database.model.UserAccountDataEntity
 import org.matrix.android.sdk.internal.database.model.UserAccountDataEntityFields
+import org.matrix.android.sdk.internal.database.model.deleteOnCascade
 import org.matrix.android.sdk.internal.database.query.getDirectRooms
 import org.matrix.android.sdk.internal.database.query.getOrCreate
 import org.matrix.android.sdk.internal.database.query.where
@@ -50,9 +53,6 @@ import org.matrix.android.sdk.internal.session.sync.model.accountdata.IgnoredUse
 import org.matrix.android.sdk.internal.session.sync.model.accountdata.UserAccountDataSync
 import org.matrix.android.sdk.internal.session.user.accountdata.DirectChatsHelper
 import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask
-import io.realm.Realm
-import io.realm.RealmList
-import io.realm.kotlin.where
 import timber.log.Timber
 import javax.inject.Inject
 
@@ -60,7 +60,6 @@ internal class UserAccountDataSyncHandler @Inject constructor(
         @SessionDatabase private val monarchy: Monarchy,
         @UserId private val userId: String,
         private val directChatsHelper: DirectChatsHelper,
-        private val moshi: Moshi,
         private val updateUserAccountDataTask: UpdateUserAccountDataTask) {
 
     fun handle(realm: Realm, accountData: UserAccountDataSync?) {
@@ -113,7 +112,7 @@ internal class UserAccountDataSyncHandler @Inject constructor(
         val pushRules = event.content.toModel<GetPushRulesResponse>() ?: return
         realm.where(PushRulesEntity::class.java)
                 .findAll()
-                .deleteAllFromRealm()
+                .forEach { it.deleteOnCascade() }
 
         // Save only global rules for the moment
         val globalRules = pushRules.global
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/LazyRoomSyncEphemeral.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/LazyRoomSyncEphemeral.kt
new file mode 100644
index 0000000000000000000000000000000000000000..938168b5f4bb368c0863c763f6813cca5a79e078
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/LazyRoomSyncEphemeral.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.sync.model
+
+import com.squareup.moshi.JsonAdapter
+import com.squareup.moshi.JsonClass
+import com.squareup.moshi.JsonReader
+import okio.buffer
+import okio.source
+import java.io.File
+
+@JsonClass(generateAdapter = false)
+internal sealed class LazyRoomSyncEphemeral {
+    data class Parsed(val _roomSyncEphemeral: RoomSyncEphemeral) : LazyRoomSyncEphemeral()
+    data class Stored(val roomSyncEphemeralAdapter: JsonAdapter<RoomSyncEphemeral>, val file: File) : LazyRoomSyncEphemeral()
+
+    val roomSyncEphemeral: RoomSyncEphemeral
+        get() {
+            return when (this) {
+                is Parsed -> _roomSyncEphemeral
+                is Stored -> {
+                    // Parse the file now
+                    file.inputStream().use { pos ->
+                        roomSyncEphemeralAdapter.fromJson(JsonReader.of(pos.source().buffer()))!!
+                    }
+                }
+            }
+        }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSync.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSync.kt
index 212d319139601b09f76566d20d9e79535e20ad22..9aed0d37d688d6659fe649ead540323d18091759 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSync.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSync.kt
@@ -34,7 +34,7 @@ internal data class RoomSync(
         /**
          * The ephemeral events in the room that aren't recorded in the timeline or state of the room (e.g. typing, receipts).
          */
-        @Json(name = "ephemeral") val ephemeral: RoomSyncEphemeral? = null,
+        @Json(name = "ephemeral") val ephemeral: LazyRoomSyncEphemeral? = null,
 
         /**
          * The account data events for the room (e.g. tags).
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ef56802a668c2206d0d73f24f1be0732c098ec3c
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.sync.parsing
+
+import com.squareup.moshi.FromJson
+import com.squareup.moshi.JsonAdapter
+import com.squareup.moshi.JsonReader
+import com.squareup.moshi.JsonWriter
+import com.squareup.moshi.ToJson
+import org.matrix.android.sdk.internal.session.sync.InitialSyncStrategy
+import org.matrix.android.sdk.internal.session.sync.model.LazyRoomSyncEphemeral
+import org.matrix.android.sdk.internal.session.sync.model.RoomSyncEphemeral
+import timber.log.Timber
+import java.io.File
+import java.util.concurrent.atomic.AtomicInteger
+
+internal class DefaultLazyRoomSyncEphemeralJsonAdapter {
+
+    @FromJson
+    fun fromJson(reader: JsonReader, delegate: JsonAdapter<RoomSyncEphemeral>): LazyRoomSyncEphemeral? {
+        val roomSyncEphemeral = delegate.fromJson(reader) ?: return null
+        return LazyRoomSyncEphemeral.Parsed(roomSyncEphemeral)
+    }
+
+    @ToJson
+    fun toJson(writer: JsonWriter, value: LazyRoomSyncEphemeral?) {
+        // This Adapter is not supposed to serialize object
+        Timber.v("To json $value with $writer")
+        throw UnsupportedOperationException()
+    }
+}
+
+internal class SplitLazyRoomSyncJsonAdapter(
+        private val workingDirectory: File,
+        private val syncStrategy: InitialSyncStrategy.Optimized
+) {
+    private val atomicInteger = AtomicInteger(0)
+
+    private fun createFile(): File {
+        val index = atomicInteger.getAndIncrement()
+        return File(workingDirectory, "room_$index.json")
+    }
+
+    @FromJson
+    fun fromJson(reader: JsonReader, delegate: JsonAdapter<RoomSyncEphemeral>): LazyRoomSyncEphemeral? {
+        val path = reader.path
+        val json = reader.nextSource().inputStream().bufferedReader().use {
+            it.readText()
+        }
+        val limit = syncStrategy.minSizeToStoreInFile
+        return if (json.length > limit) {
+            Timber.v("INIT_SYNC $path content length: ${json.length} copy to a file")
+            // Copy the source to a file
+            val file = createFile()
+            file.writeText(json)
+            LazyRoomSyncEphemeral.Stored(delegate, file)
+        } else {
+            Timber.v("INIT_SYNC $path content length: ${json.length} parse it now")
+            val roomSync = delegate.fromJson(json) ?: return null
+            LazyRoomSyncEphemeral.Parsed(roomSync)
+        }
+    }
+
+    @ToJson
+    fun toJson(writer: JsonWriter, value: LazyRoomSyncEphemeral?) {
+        // This Adapter is not supposed to serialize object
+        Timber.v("To json $value with $writer")
+        throw UnsupportedOperationException()
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/InitialSyncResponseParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/InitialSyncResponseParser.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ae7b2a44681f2369b5301f6cd9eeaf5b1d8487d8
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/InitialSyncResponseParser.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.sync.parsing
+
+import com.squareup.moshi.Moshi
+import okio.buffer
+import okio.source
+import org.matrix.android.sdk.internal.session.sync.InitialSyncStrategy
+import org.matrix.android.sdk.internal.session.sync.model.SyncResponse
+import timber.log.Timber
+import java.io.File
+import javax.inject.Inject
+
+internal class InitialSyncResponseParser @Inject constructor(private val moshi: Moshi) {
+
+    fun parse(syncStrategy: InitialSyncStrategy.Optimized, workingFile: File): SyncResponse {
+        val syncResponseLength = workingFile.length().toInt()
+        Timber.v("INIT_SYNC Sync file size is $syncResponseLength bytes")
+        val shouldSplit = syncResponseLength >= syncStrategy.minSizeToSplit
+        Timber.v("INIT_SYNC should split in several files: $shouldSplit")
+        return getMoshi(syncStrategy, workingFile.parentFile!!, shouldSplit)
+                .adapter(SyncResponse::class.java)
+                .fromJson(workingFile.source().buffer())!!
+    }
+
+    private fun getMoshi(syncStrategy: InitialSyncStrategy.Optimized, workingDirectory: File, shouldSplit: Boolean): Moshi {
+        // If we don't have to split we'll rely on the already default moshi
+        if (!shouldSplit) return moshi
+        // Otherwise, we create a new adapter for handling Map of Lazy sync
+        return moshi.newBuilder()
+                .add(SplitLazyRoomSyncJsonAdapter(workingDirectory, syncStrategy))
+                .build()
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/DefaultThirdPartyService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/DefaultThirdPartyService.kt
new file mode 100644
index 0000000000000000000000000000000000000000..13829c400a19e3126a42b54b4ea9098886c92656
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/DefaultThirdPartyService.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2021 The Matrix.org Foundation C.I.C
+ *
+ * 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 org.matrix.android.sdk.internal.session.thirdparty
+
+import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
+import org.matrix.android.sdk.api.session.thirdparty.ThirdPartyService
+import org.matrix.android.sdk.api.session.thirdparty.model.ThirdPartyUser
+import javax.inject.Inject
+
+internal class DefaultThirdPartyService @Inject constructor(private val getThirdPartyProtocolTask: GetThirdPartyProtocolsTask,
+                                                            private val getThirdPartyUserTask: GetThirdPartyUserTask)
+    : ThirdPartyService {
+
+    override suspend fun getThirdPartyProtocols(): Map<String, ThirdPartyProtocol> {
+        return getThirdPartyProtocolTask.execute(Unit)
+    }
+
+    override suspend fun getThirdPartyUser(protocol: String, fields: Map<String, String>): List<ThirdPartyUser> {
+        val taskParams = GetThirdPartyUserTask.Params(
+                protocol = protocol,
+                fields = fields
+        )
+        return getThirdPartyUserTask.execute(taskParams)
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/directory/GetThirdPartyProtocolsTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/GetThirdPartyProtocolsTask.kt
similarity index 86%
rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/directory/GetThirdPartyProtocolsTask.kt
rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/GetThirdPartyProtocolsTask.kt
index 3477aa671ea6ba1283a598e31685e6ca2070a72c..fd1ed741e991b3f80506f4571abcab2c908ad394 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/directory/GetThirdPartyProtocolsTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/GetThirdPartyProtocolsTask.kt
@@ -14,25 +14,24 @@
  * limitations under the License.
  */
 
-package org.matrix.android.sdk.internal.session.room.directory
+package org.matrix.android.sdk.internal.session.thirdparty
 
 import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
 import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
 import org.matrix.android.sdk.internal.network.executeRequest
-import org.matrix.android.sdk.internal.session.room.RoomAPI
 import org.matrix.android.sdk.internal.task.Task
 import javax.inject.Inject
 
 internal interface GetThirdPartyProtocolsTask : Task<Unit, Map<String, ThirdPartyProtocol>>
 
 internal class DefaultGetThirdPartyProtocolsTask @Inject constructor(
-        private val roomAPI: RoomAPI,
+        private val thirdPartyAPI: ThirdPartyAPI,
         private val globalErrorReceiver: GlobalErrorReceiver
 ) : GetThirdPartyProtocolsTask {
 
     override suspend fun execute(params: Unit): Map<String, ThirdPartyProtocol> {
         return executeRequest(globalErrorReceiver) {
-            apiCall = roomAPI.thirdPartyProtocols()
+            apiCall = thirdPartyAPI.thirdPartyProtocols()
         }
     }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/GetThirdPartyUserTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/GetThirdPartyUserTask.kt
new file mode 100644
index 0000000000000000000000000000000000000000..01a8b576783c404f53409176ec48d6f5a48b6c6b
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/GetThirdPartyUserTask.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.thirdparty
+
+import org.matrix.android.sdk.api.session.thirdparty.model.ThirdPartyUser
+import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
+import org.matrix.android.sdk.internal.network.executeRequest
+import org.matrix.android.sdk.internal.task.Task
+import javax.inject.Inject
+
+internal interface GetThirdPartyUserTask : Task<GetThirdPartyUserTask.Params, List<ThirdPartyUser>> {
+
+    data class Params(
+            val protocol: String,
+            val fields: Map<String, String> = emptyMap()
+    )
+}
+
+internal class DefaultGetThirdPartyUserTask @Inject constructor(
+        private val thirdPartyAPI: ThirdPartyAPI,
+        private val globalErrorReceiver: GlobalErrorReceiver
+) : GetThirdPartyUserTask {
+
+    override suspend fun execute(params: GetThirdPartyUserTask.Params): List<ThirdPartyUser> {
+        return executeRequest(globalErrorReceiver) {
+            apiCall = thirdPartyAPI.getThirdPartyUser(params.protocol, params.fields)
+        }
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/ThirdPartyAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/ThirdPartyAPI.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0c60a27341239c661054f993e2cfbe757a735557
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/ThirdPartyAPI.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.thirdparty
+
+import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
+import org.matrix.android.sdk.api.session.thirdparty.model.ThirdPartyUser
+import org.matrix.android.sdk.internal.network.NetworkConstants
+import retrofit2.Call
+import retrofit2.http.GET
+import retrofit2.http.Path
+import retrofit2.http.QueryMap
+
+internal interface ThirdPartyAPI {
+
+    /**
+     * Get the third party server protocols.
+     *
+     * Ref: https://matrix.org/docs/spec/client_server/r0.6.1.html#get-matrix-client-r0-thirdparty-protocols
+     */
+    @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "thirdparty/protocols")
+    fun thirdPartyProtocols(): Call<Map<String, ThirdPartyProtocol>>
+
+    /**
+     * Retrieve a Matrix User ID linked to a user on the third party service, given a set of user parameters.
+     *
+     * Ref: https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-thirdparty-user-protocol
+     */
+    @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "thirdparty/protocols/user/{protocol}")
+    fun getThirdPartyUser(@Path("protocol") protocol: String, @QueryMap params: Map<String, String>?): Call<List<ThirdPartyUser>>
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/ThirdPartyModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/ThirdPartyModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d3acd7a9f34267e806c511d64149bb4aa1450b08
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/ThirdPartyModule.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.session.thirdparty
+
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+import org.matrix.android.sdk.api.session.thirdparty.ThirdPartyService
+import org.matrix.android.sdk.internal.session.SessionScope
+import retrofit2.Retrofit
+
+@Module
+internal abstract class ThirdPartyModule {
+
+    @Module
+    companion object {
+        @Provides
+        @JvmStatic
+        @SessionScope
+        fun providesThirdPartyAPI(retrofit: Retrofit): ThirdPartyAPI {
+            return retrofit.create(ThirdPartyAPI::class.java)
+        }
+    }
+
+    @Binds
+    abstract fun bindThirdPartyService(service: DefaultThirdPartyService): ThirdPartyService
+
+    @Binds
+    abstract fun bindGetThirdPartyProtocolsTask(task: DefaultGetThirdPartyProtocolsTask): GetThirdPartyProtocolsTask
+
+    @Binds
+    abstract fun bindGetThirdPartyUserTask(task: DefaultGetThirdPartyUserTask): GetThirdPartyUserTask
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetService.kt
index 3e4e430e3b81ea8377dacfb2de9aa631ee5c255b..9f5a9360ee9a54fed08196a7954b638e5302dcb4 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetService.kt
@@ -50,6 +50,10 @@ internal class DefaultWidgetService @Inject constructor(private val widgetManage
         return widgetManager.getRoomWidgets(roomId, widgetId, widgetTypes, excludedTypes)
     }
 
+    override fun getWidgetComputedUrl(widget: Widget, isLightTheme: Boolean): String? {
+        return widgetManager.getWidgetComputedUrl(widget, isLightTheme)
+    }
+
     override fun getRoomWidgetsLive(
             roomId: String,
             widgetId: QueryStringValue,
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetURLFormatter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetURLFormatter.kt
index 94dba75205c75ca109599b36194a7a042843cff5..0937f6d18be4255bd02d1dbcdf8ea04e36c847d4 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetURLFormatter.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetURLFormatter.kt
@@ -20,11 +20,12 @@ import org.matrix.android.sdk.api.MatrixConfiguration
 import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerConfig
 import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
 import org.matrix.android.sdk.api.session.widgets.WidgetURLFormatter
+import org.matrix.android.sdk.api.util.appendParamToUrl
+import org.matrix.android.sdk.api.util.appendParamsToUrl
 import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
 import org.matrix.android.sdk.internal.session.SessionScope
 import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager
 import org.matrix.android.sdk.internal.session.widgets.token.GetScalarTokenTask
-import java.net.URLEncoder
 import javax.inject.Inject
 
 @SessionScope
@@ -36,12 +37,12 @@ internal class DefaultWidgetURLFormatter @Inject constructor(private val integra
     private lateinit var currentConfig: IntegrationManagerConfig
     private var whiteListedUrls: List<String> = emptyList()
 
-    override fun onStart() {
+    override fun onSessionStarted() {
         setupWithConfiguration()
         integrationManager.addListener(this)
     }
 
-    override fun onStop() {
+    override fun onSessionStopped() {
         integrationManager.removeListener(this)
     }
 
@@ -90,25 +91,4 @@ internal class DefaultWidgetURLFormatter @Inject constructor(private val integra
         }
         return false
     }
-
-    private fun StringBuilder.appendParamsToUrl(params: Map<String, String>): StringBuilder {
-        params.forEach { (param, value) ->
-            appendParamToUrl(param, value)
-        }
-        return this
-    }
-
-    private fun StringBuilder.appendParamToUrl(param: String, value: String): StringBuilder {
-        if (contains("?")) {
-            append("&")
-        } else {
-            append("?")
-        }
-
-        append(param)
-        append("=")
-        append(URLEncoder.encode(value, "utf-8"))
-
-        return this
-    }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt
index 329903f15b5dbce1543720f9559ac6f5b43eb999..73a4cc697dc320bd03e401f2a943858fc3506144 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt
@@ -62,12 +62,12 @@ internal class WidgetManager @Inject constructor(private val integrationManager:
     private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry }
     private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(lifecycleOwner)
 
-    override fun onStart() {
+    override fun onSessionStarted() {
         lifecycleRegistry.currentState = Lifecycle.State.STARTED
         integrationManager.addListener(this)
     }
 
-    override fun onStop() {
+    override fun onSessionStopped() {
         integrationManager.removeListener(this)
         lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
     }
@@ -104,6 +104,10 @@ internal class WidgetManager @Inject constructor(private val integrationManager:
         return widgetEvents.mapEventsToWidgets(widgetTypes, excludedTypes)
     }
 
+    fun getWidgetComputedUrl(widget: Widget, isLightTheme: Boolean): String? {
+        return widgetFactory.computeURL(widget, isLightTheme)
+    }
+
     private fun List<Event>.mapEventsToWidgets(widgetTypes: Set<String>? = null,
                                                excludedTypes: Set<String>? = null): List<Widget> {
         val widgetEvents = this
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/WidgetFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/WidgetFactory.kt
index 000b9e38b9e8027774fb33329f48cffd4eafe5c5..a469a9fe976722907d8789558c0f22957e0c2d23 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/WidgetFactory.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/WidgetFactory.kt
@@ -16,6 +16,7 @@
 
 package org.matrix.android.sdk.internal.session.widgets.helper
 
+import org.matrix.android.sdk.api.session.content.ContentUrlResolver
 import org.matrix.android.sdk.api.session.events.model.Event
 import org.matrix.android.sdk.api.session.events.model.toModel
 import org.matrix.android.sdk.api.session.room.sender.SenderInfo
@@ -31,6 +32,7 @@ import javax.inject.Inject
 
 internal class WidgetFactory @Inject constructor(private val userDataSource: UserDataSource,
                                                  private val realmSessionProvider: RealmSessionProvider,
+                                                 private val urlResolver: ContentUrlResolver,
                                                  @UserId private val userId: String) {
 
     fun create(widgetEvent: Event): Widget? {
@@ -53,35 +55,47 @@ internal class WidgetFactory @Inject constructor(private val userDataSource: Use
             }
         }
         val isAddedByMe = widgetEvent.senderId == userId
-        val computedUrl = widgetContent.computeURL(widgetEvent.roomId, widgetId)
         return Widget(
                 widgetContent = widgetContent,
                 event = widgetEvent,
                 widgetId = widgetId,
                 senderInfo = senderInfo,
                 isAddedByMe = isAddedByMe,
-                computedUrl = computedUrl,
                 type = WidgetType.fromString(type)
         )
     }
 
-    private fun WidgetContent.computeURL(roomId: String?, widgetId: String): String? {
-        var computedUrl = url ?: return null
+    // Ref: https://github.com/matrix-org/matrix-widget-api/blob/master/src/templating/url-template.ts#L29-L33
+    fun computeURL(widget: Widget, isLightTheme: Boolean): String? {
+        var computedUrl = widget.widgetContent.url ?: return null
         val myUser = userDataSource.getUser(userId)
-        computedUrl = computedUrl
-                .replace("\$matrix_user_id", userId)
-                .replace("\$matrix_display_name", myUser?.displayName ?: userId)
-                .replace("\$matrix_avatar_url", myUser?.avatarUrl ?: "")
-                .replace("\$matrix_widget_id", widgetId)
 
-        if (roomId != null) {
-            computedUrl = computedUrl.replace("\$matrix_room_id", roomId)
-        }
-        for ((key, value) in data) {
-            if (value is String) {
-                computedUrl = computedUrl.replace("$$key", URLEncoder.encode(value, "utf-8"))
-            }
+        val keyValue = widget.widgetContent.data.mapKeys { "\$${it.key}" }.toMutableMap()
+
+        keyValue[WIDGET_PATTERN_MATRIX_USER_ID] = userId
+        keyValue[WIDGET_PATTERN_MATRIX_DISPLAY_NAME] = myUser?.getBestName() ?: userId
+        keyValue[WIDGET_PATTERN_MATRIX_AVATAR_URL] = urlResolver.resolveFullSize(myUser?.avatarUrl) ?: ""
+        keyValue[WIDGET_PATTERN_MATRIX_WIDGET_ID] = widget.widgetId
+        keyValue[WIDGET_PATTERN_MATRIX_ROOM_ID] = widget.event.roomId ?: ""
+        keyValue[WIDGET_PATTERN_THEME] = getTheme(isLightTheme)
+
+        for ((key, value) in keyValue) {
+            computedUrl = computedUrl.replace(key, URLEncoder.encode(value.toString(), "utf-8"))
         }
         return computedUrl
     }
+
+    private fun getTheme(isLightTheme: Boolean): String {
+        return if (isLightTheme) "light" else "dark"
+    }
+
+    companion object {
+        // Value to be replaced in URLS
+        const val WIDGET_PATTERN_MATRIX_USER_ID = "\$matrix_user_id"
+        const val WIDGET_PATTERN_MATRIX_DISPLAY_NAME = "\$matrix_display_name"
+        const val WIDGET_PATTERN_MATRIX_AVATAR_URL = "\$matrix_avatar_url"
+        const val WIDGET_PATTERN_MATRIX_WIDGET_ID = "\$matrix_widget_id"
+        const val WIDGET_PATTERN_MATRIX_ROOM_ID = "\$matrix_room_id"
+        const val WIDGET_PATTERN_THEME = "\$theme"
+    }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Html.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Html.kt
new file mode 100644
index 0000000000000000000000000000000000000000..329b100497e80a151e08508a58b664702dbf2c6d
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Html.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.util
+
+import androidx.core.text.HtmlCompat
+
+internal fun String.unescapeHtml(): String {
+    return HtmlCompat.fromHtml(this, HtmlCompat.FROM_HTML_MODE_LEGACY).toString()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/LogUtil.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/LogUtil.kt
new file mode 100644
index 0000000000000000000000000000000000000000..fe68b49a5c7712a6d85c7375f0e2d958cb71c4db
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/LogUtil.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2020 The Matrix.org Foundation C.I.C.
+ *
+ * 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 org.matrix.android.sdk.internal.util
+
+import org.matrix.android.sdk.BuildConfig
+import timber.log.Timber
+
+internal suspend fun <T> logDuration(message: String,
+                                     block: suspend () -> T): T {
+    Timber.v("$message -- BEGIN")
+    val start = System.currentTimeMillis()
+    val result = logRamUsage(message) {
+        block()
+    }
+    val duration = System.currentTimeMillis() - start
+    Timber.v("$message -- END duration: $duration ms")
+
+    return result
+}
+
+internal suspend fun <T> logRamUsage(message: String, block: suspend () -> T): T {
+    return if (BuildConfig.DEBUG) {
+        val runtime = Runtime.getRuntime()
+        runtime.gc()
+        val freeMemoryInMb = runtime.freeMemory() / 1048576L
+        val usedMemInMBStart = runtime.totalMemory() / 1048576L - freeMemoryInMb
+        Timber.v("$message -- BEGIN (free memory: $freeMemoryInMb MB)")
+        val result = block()
+        runtime.gc()
+        val usedMemInMBEnd = (runtime.totalMemory() - runtime.freeMemory()) / 1048576L
+        val usedMemInMBDiff = usedMemInMBEnd - usedMemInMBStart
+        Timber.v("$message -- END RAM usage: $usedMemInMBDiff MB")
+        result
+    } else {
+        block()
+    }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringProvider.kt
deleted file mode 100644
index 69d50680a71256a797c1fc82ea87607c6311d895..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringProvider.kt
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2020 The Matrix.org Foundation C.I.C.
- *
- * 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 org.matrix.android.sdk.internal.util
-
-import android.content.res.Resources
-import androidx.annotation.NonNull
-import androidx.annotation.PluralsRes
-import androidx.annotation.StringRes
-import dagger.Reusable
-import javax.inject.Inject
-
-@Reusable
-internal class StringProvider @Inject constructor(private val resources: Resources) {
-
-    /**
-     * Returns a localized string from the application's package's
-     * default string table.
-     *
-     * @param resId Resource id for the string
-     * @return The string data associated with the resource, stripped of styled
-     * text information.
-     */
-    @NonNull
-    fun getString(@StringRes resId: Int): String {
-        return resources.getString(resId)
-    }
-
-    /**
-     * Returns a localized formatted string from the application's package's
-     * default string table, substituting the format arguments as defined in
-     * [java.util.Formatter] and [java.lang.String.format].
-     *
-     * @param resId Resource id for the format string
-     * @param formatArgs The format arguments that will be used for
-     * substitution.
-     * @return The string data associated with the resource, formatted and
-     * stripped of styled text information.
-     */
-    @NonNull
-    fun getString(@StringRes resId: Int, vararg formatArgs: Any?): String {
-        return resources.getString(resId, *formatArgs)
-    }
-
-    @NonNull
-    fun getQuantityString(@PluralsRes resId: Int, quantity: Int, vararg formatArgs: Any?): String {
-        return resources.getQuantityString(resId, quantity, *formatArgs)
-    }
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt
index ecfbe311f1d8d3742922b8ae2e9805c65bd521b9..2fabca4be86e5f7a66c237788d3992fde700452f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt
@@ -71,3 +71,10 @@ fun String.caseInsensitiveFind(subString: String): Boolean {
 
     return false
 }
+
+internal val spaceChars = "[\u00A0\u2000-\u200B\u2800\u3000]".toRegex()
+
+/**
+ * Strip all the UTF-8 chars which are actually spaces
+ */
+internal fun String.replaceSpaceChars() = replace(spaceChars, "")
diff --git a/matrix-sdk-android/src/main/res/values-ar/strings.xml b/matrix-sdk-android/src/main/res/values-ar/strings.xml
deleted file mode 100644
index 0fc7bd1b49597ab4b3710c582b409d20fa4764d2..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-ar/strings.xml
+++ /dev/null
@@ -1,147 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-
-    <string name="summary_user_sent_image">أرسل ⁨%1$s⁩ صورة.</string>
-
-    <string name="notice_room_invite_no_invitee">دعوة من ⁨%s⁩</string>
-    <string name="notice_room_invite">دعى ⁨%1$s⁩ ⁨%2$s⁩</string>
-    <string name="notice_room_invite_you">دعاك ⁨%1$s⁩</string>
-    <string name="notice_room_join">انضمّ ⁨%1$s⁩ إلى الغرفة</string>
-    <string name="notice_room_leave">غادر ⁨%1$s⁩ الغرفة</string>
-    <string name="notice_room_reject">رفض ⁨%1$s⁩ الدعوة</string>
-    <string name="notice_room_kick">طرد ⁨%1$s⁩ ⁨%2$s⁩</string>
-    <string name="notice_room_unban">رفع ⁨%1$s⁩ المنع عن ⁨%2$s⁩</string>
-    <string name="notice_room_ban">منع ⁨%1$s⁩ ⁨%2$s⁩</string>
-    <string name="notice_avatar_url_changed">غيّر ⁨%1$s⁩ صورته</string>
-    <string name="notice_display_name_set">ضبط ⁨%1$s⁩ اسم العرض على ⁨%2$s⁩</string>
-    <string name="notice_display_name_changed_from">غيّر ⁨%1$s⁩ اسم العرض من ⁨%2$s⁩ إلى ⁨%3$s⁩</string>
-    <string name="notice_display_name_removed">أزال ⁨%1$s⁩ اسم العرض (⁨كان ⁨%2$s⁩)</string>
-    <string name="notice_room_topic_changed">غيّر ⁨%1$s⁩ الموضوع إلى: ⁨%2$s⁩</string>
-    <string name="notice_room_name_changed">غيّر ⁨%1$s⁩ اسم الغرفة إلى: ⁨%2$s⁩</string>
-    <string name="notice_answered_call">ردّ ⁨%s⁩ على المكالمة.</string>
-    <string name="notice_ended_call">أنهى ⁨%s⁩ المكالمة.</string>
-    <string name="notice_made_future_room_visibility">جعل ⁨%1$s⁩ تأريخ الغرفة مستقبلًا ظاهرًا على ⁨%2$s⁩</string>
-    <string name="notice_room_visibility_invited">كل أعضاء الغرفة من لحظة دعوتهم.</string>
-    <string name="notice_room_visibility_joined">كل أعضاء الغرفة من لحظة انضمامهم.</string>
-    <string name="notice_room_visibility_shared">كل أعضاء الغرفة.</string>
-    <string name="notice_room_visibility_world_readable">الكل.</string>
-    <string name="notice_room_visibility_unknown">المجهول (⁨%s⁩).</string>
-    <string name="notice_end_to_end">فعّل ⁨%1$s⁩ تعمية الطرفين (⁨%2$s⁩)</string>
-
-    <string name="notice_requested_voip_conference">طلب ⁨%1$s⁩ اجتماع VoIP</string>
-    <string name="notice_voip_started">بدأ اجتماع VoIP</string>
-    <string name="notice_voip_finished">انتهى اجتماع VoIP</string>
-
-    <string name="notice_room_name_removed">أزال ⁨%1$s⁩ اسم الغرفة</string>
-    <string name="notice_room_topic_removed">أزال ⁨%1$s⁩ موضوع الغرفة</string>
-    <string name="notice_profile_change_redacted">حدّث ⁨%1$s⁩ اللاحة ⁨%2$s⁩</string>
-    <string name="notice_room_third_party_invite">أرسل ⁨%1$s⁩ دعوة إلى ⁨%2$s⁩ للانضمام إلى الغرفة</string>
-    <string name="notice_crypto_unable_to_decrypt">** تعذّر فك التعمية: ⁨%s⁩ **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">لم يُرسل جهاز المرسل مفاتيح هذه الرسالة.</string>
-
-    <string name="unable_to_send_message">تعذّر إرسال الرسالة</string>
-
-    <string name="message_failed_to_upload">فشل رفع الصورة</string>
-
-    <string name="network_error">خطأ في الشبكة</string>
-    <string name="matrix_error">خطأ في «ماترِكس»</string>
-
-    <string name="room_error_join_failed_empty_room">لا يمكنك حاليًا الانضمام ثانيةً إلى غرفة فارغة.</string>
-
-    <string name="encrypted_message">رسالة معمّاة</string>
-
-    <string name="medium_email">عنوان البريد الإلكتروني</string>
-    <string name="medium_phone_number">رقم الهاتف</string>
-
-    <string name="summary_message">‏‏⁨%1$s⁩: ‏⁨%2$s⁩</string>
-    <string name="notice_room_withdraw">انسحب ⁨%1$s⁩ من دعوة ⁨%2$s⁩</string>
-    <string name="notice_placed_video_call">أجرى ⁨%s⁩ مكالمة مرئية.</string>
-    <string name="notice_placed_voice_call">أجرى ⁨%s⁩ مكالمة صوتية.</string>
-    <string name="notice_room_third_party_registered_invite">قَبِل ⁨%1$s⁩ دعوة ⁨%2$s⁩</string>
-
-    <string name="could_not_redact">تعذر التهذيب</string>
-    <string name="summary_user_sent_sticker">أرسل ⁨%1$s⁩ ملصقًا.</string>
-
-    <string name="notice_avatar_changed_too">(تغيّرت الصورة أيضا)</string>
-
-    <string name="room_displayname_invite_from">دعوة من ⁨%s⁩</string>
-    <string name="room_displayname_empty_room">غرفة فارغة</string>
-
-    <string name="room_displayname_two_members">‏⁨%1$s⁩ و ⁨%2$s⁩</string>
-    <string name="room_displayname_room_invite">دعوة إلى غرفة</string>
-
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="zero"></item>
-        <item quantity="one"></item>
-        <item quantity="two"></item>
-        <item quantity="few"></item>
-        <item quantity="many"></item>
-        <item quantity="other"></item>
-    </plurals>
-
-    <string name="summary_you_sent_image">أرسلت صورة.</string>
-    <string name="summary_you_sent_sticker">أرسلت ملصقًا.</string>
-
-    <string name="notice_room_invite_no_invitee_by_you">دعوة منك أنت</string>
-    <string name="notice_room_created">أنشأ ⁨%1$s⁩ الغرفة</string>
-    <string name="notice_room_created_by_you">أنشأت الغرفة</string>
-    <string name="notice_room_invite_by_you">دعوت ⁨%1$s⁩</string>
-    <string name="notice_room_join_by_you">انضممت إلى الغرفة</string>
-    <string name="notice_room_leave_by_you">غادرت الغرفة</string>
-    <string name="notice_room_reject_by_you">رفضت الدعوة</string>
-    <string name="notice_room_kick_by_you">طردت ⁨%1$s⁩</string>
-    <string name="notice_room_unban_by_you">رفعت المنع عن ⁨%1$s⁩</string>
-    <string name="notice_room_ban_by_you">منعت ⁨%1$s⁩</string>
-    <string name="notice_room_withdraw_by_you">انسحبت من دعوة ⁨%1$s⁩</string>
-    <string name="notice_avatar_url_changed_by_you">غيّرت صورتك</string>
-    <string name="notice_display_name_set_by_you">ضبطت اسم العرض على ⁨%1$s⁩</string>
-    <string name="notice_display_name_changed_from_by_you">غيّرت اسم العرض من ⁨%1$s⁩ إلى ⁨%2$s⁩</string>
-    <string name="notice_display_name_removed_by_you">أزلت اسم العرض (كان ⁨%1$s⁩)</string>
-    <string name="notice_room_topic_changed_by_you">غيّرت الموضوع إلى: ⁨%1$s⁩</string>
-    <string name="notice_room_avatar_changed">غيّر ⁨%1$s⁩ صورة الغرفة</string>
-    <string name="notice_room_avatar_changed_by_you">غيّرت صورة الغرفة</string>
-    <string name="notice_room_name_changed_by_you">غيّرت اسم الغرفة إلى: ⁨%1$s⁩</string>
-    <string name="notice_placed_video_call_by_you">أجريت مكالمة مرئية.</string>
-    <string name="notice_placed_voice_call_by_you">أجريت مكالمة صوتية.</string>
-    <string name="notice_call_candidates">أرسل ⁨%s⁩ البيانات لإعداد المكالمة.</string>
-    <string name="notice_call_candidates_by_you">أرسلت البيانات لإعداد المكالمة.</string>
-    <string name="notice_answered_call_by_you">رددت على المكالمة.</string>
-    <string name="notice_ended_call_by_you">أنهيت المكالمة.</string>
-    <string name="notice_made_future_room_visibility_by_you">جعلت تأريخ الغرفة مستقبلًا ظاهرًا على ⁨%1$s⁩</string>
-    <string name="notice_end_to_end_by_you">فعّلت تعمية الطرفين (⁨%1$s⁩)</string>
-    <string name="notice_room_update">رقّى ⁨%s⁩ هذه الغرفة.</string>
-    <string name="notice_room_update_by_you">رقّيت هذه الغرفة.</string>
-
-    <string name="notice_requested_voip_conference_by_you">طلبت اجتماع VoIP</string>
-    <string name="notice_room_name_removed_by_you">أزلت اسم الغرفة</string>
-    <string name="notice_room_topic_removed_by_you">أزلت موضوع الغرفة</string>
-    <string name="notice_room_avatar_removed">أزال ⁨%1$s⁩ صورة الغرفة</string>
-    <string name="notice_room_avatar_removed_by_you">أزلت صورة الغرفة</string>
-    <string name="notice_event_redacted">أُزيلت الرسالة</string>
-    <string name="notice_event_redacted_by">أزال ⁨%1$s⁩ الرسالة</string>
-    <string name="notice_event_redacted_with_reason">أُزيلت الرسالة [السبب: ⁨%1$s⁩]</string>
-    <string name="notice_event_redacted_by_with_reason">أزال ⁨%1$s⁩ الرسالة [السبب: ⁨%2$s⁩]</string>
-    <string name="notice_room_third_party_invite_by_you">أرسلت دعوة إلى ⁨%1$s⁩ للانضمام إلى الغرفة</string>
-    <string name="notice_room_third_party_revoked_invite">سحب ⁨%1$s⁩ دعوة ⁨%2$s⁩ للانضمام إلى الغرفة</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">سحبت دعوة ⁨%1$s⁩ للانضمام إلى الغرفة</string>
-    <string name="notice_room_third_party_registered_invite_by_you">قَبِلت دعوة ⁨%1$s⁩</string>
-
-    <string name="notice_widget_added">أضاف ⁨%1$s⁩ الودجة ⁨%2$s⁩</string>
-    <string name="notice_widget_added_by_you">أضفت الودجة ⁨%1$s⁩</string>
-    <string name="notice_widget_removed">أزال ⁨%1$s⁩ الودجة ⁨%2$s⁩</string>
-    <string name="notice_widget_removed_by_you">أزلت الودجة ⁨%1$s⁩</string>
-    <string name="notice_widget_modified">عدّل ⁨%1$s⁩ الودجة ⁨%2$s⁩</string>
-    <string name="notice_widget_modified_by_you">عدّلت الودجة ⁨%1$s⁩</string>
-
-    <string name="power_level_admin">مدير</string>
-    <string name="power_level_default">المبدئي</string>
-    <string name="power_level_custom">مخصّص (⁨%1$d⁩)</string>
-    <string name="power_level_custom_no_value">مخصّص</string>
-
-    <string name="notice_power_level_changed_by_you">غيّرت مستوى قوّة %1$s⁩.</string>
-    <string name="notice_power_level_changed">غيّر ⁨%1$s⁩ مستوى قوّة %2$s⁩.</string>
-    <string name="notice_power_level_diff">‏⁨%1$s⁩ من ⁨%2$s⁩ إلى ⁨%3$s⁩</string>
-
-    <string name="initial_sync_start_importing_account">المزامنة الأولية:
-\nيستورد الحساب…</string>
-</resources>
diff --git a/matrix-sdk-android/src/main/res/values-ar/strings_sas.xml b/matrix-sdk-android/src/main/res/values-ar/strings_sas.xml
new file mode 100644
index 0000000000000000000000000000000000000000..423a8332bfd1a45312da061b7d3e8498fc715637
--- /dev/null
+++ b/matrix-sdk-android/src/main/res/values-ar/strings_sas.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- Generated file, do not edit -->
+    <string name="verification_emoji_dog">كَلب</string>
+    <string name="verification_emoji_cat">هِرَّة</string>
+    <string name="verification_emoji_lion">أَسَد</string>
+    <string name="verification_emoji_horse">حِصَان</string>
+    <string name="verification_emoji_unicorn">حِصَانٌ بِقَرن</string>
+    <string name="verification_emoji_pig">خِنزِير</string>
+    <string name="verification_emoji_elephant">فِيل</string>
+    <string name="verification_emoji_rabbit">أَرنَب</string>
+    <string name="verification_emoji_panda">باندَا</string>
+    <string name="verification_emoji_rooster">دِيك</string>
+    <string name="verification_emoji_penguin">بِطريق</string>
+    <string name="verification_emoji_turtle">سُلحفاة</string>
+    <string name="verification_emoji_fish">سَمَكَة</string>
+    <string name="verification_emoji_octopus">أُخطُبُوط</string>
+    <string name="verification_emoji_butterfly">فَرَاشَة</string>
+    <string name="verification_emoji_flower">زَهرَة</string>
+    <string name="verification_emoji_tree">شَجَرَة</string>
+    <string name="verification_emoji_cactus">صبار</string>
+    <string name="verification_emoji_mushroom">فُطر</string>
+    <string name="verification_emoji_globe">كُرَةٌ أرضِيَّة</string>
+    <string name="verification_emoji_moon">قَمَر</string>
+    <string name="verification_emoji_cloud">سَحابَة</string>
+    <string name="verification_emoji_fire">نار</string>
+    <string name="verification_emoji_banana">مَوزَة</string>
+    <string name="verification_emoji_apple">تُفَّاحَة</string>
+    <string name="verification_emoji_strawberry">فَراوِلَة</string>
+    <string name="verification_emoji_corn">ذُرَة</string>
+    <string name="verification_emoji_pizza">بِيتزا</string>
+    <string name="verification_emoji_cake">كَعكَة</string>
+    <string name="verification_emoji_heart">قَلب</string>
+    <string name="verification_emoji_smiley">اِبتِسَامَة</string>
+    <string name="verification_emoji_robot">رُوبُوت</string>
+    <string name="verification_emoji_hat">قُبَّعَة</string>
+    <string name="verification_emoji_glasses">نَظَّارَة</string>
+    <string name="verification_emoji_spanner">مِفتَاحُ رَبط</string>
+    <string name="verification_emoji_santa">سانتا</string>
+    <string name="verification_emoji_thumbs_up">رَفعُ إِبهَام</string>
+    <string name="verification_emoji_umbrella">مِظَلَّة</string>
+    <string name="verification_emoji_hourglass">سَاعَةٌ رَملِيَّة</string>
+    <string name="verification_emoji_clock">سَاعَة</string>
+    <string name="verification_emoji_gift">هَدِيَّة</string>
+    <string name="verification_emoji_light_bulb">مِصبَاح</string>
+    <string name="verification_emoji_book">كِتَاب</string>
+    <string name="verification_emoji_pencil">قَلَمُ رَصاص</string>
+    <string name="verification_emoji_paperclip">مِشبَكُ وَرَق</string>
+    <string name="verification_emoji_scissors">مِقَصّ</string>
+    <string name="verification_emoji_lock">قُفل</string>
+    <string name="verification_emoji_key">مِفتَاح</string>
+    <string name="verification_emoji_hammer">مِطرَقَة</string>
+    <string name="verification_emoji_telephone">تِلِفُون</string>
+    <string name="verification_emoji_flag">عَلَم</string>
+    <string name="verification_emoji_train">قِطَار</string>
+    <string name="verification_emoji_bicycle">دَرّاجَة</string>
+    <string name="verification_emoji_aeroplane">طَائِرة</string>
+    <string name="verification_emoji_rocket">صَارُوخ</string>
+    <string name="verification_emoji_trophy">كَأسُ النَّصر</string>
+    <string name="verification_emoji_ball">كُرَة</string>
+    <string name="verification_emoji_guitar">غيتار</string>
+    <string name="verification_emoji_trumpet">بُوق</string>
+    <string name="verification_emoji_bell">جَرَس</string>
+    <string name="verification_emoji_anchor">مِرسَاة</string>
+    <string name="verification_emoji_headphones">سَمّاعَة رَأس</string>
+    <string name="verification_emoji_folder">مُجَلَّد</string>
+    <string name="verification_emoji_pin">دَبُّوس</string>
+</resources>
diff --git a/matrix-sdk-android/src/main/res/values-az/strings.xml b/matrix-sdk-android/src/main/res/values-az/strings.xml
deleted file mode 100644
index 1f366c647f1632b8d9e8ae9d41abcd648f549a3a..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-az/strings.xml
+++ /dev/null
@@ -1,116 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s şəkil göndərdi.</string>
-    <string name="summary_user_sent_sticker">%1$s stiker göndərdi.</string>
-
-    <string name="notice_room_invite_no_invitee">%s-nin dəvəti</string>
-    <string name="notice_room_invite">%1$s dəvət etdi %2$s</string>
-    <string name="notice_room_invite_you">%1$s sizi dəvət etdi</string>
-    <string name="notice_room_join">%1$s qoÅŸuldu</string>
-    <string name="notice_room_leave">%1$s qalıb</string>
-    <string name="notice_room_reject">%1$s dəvəti rədd etdi</string>
-    <string name="notice_room_kick">%1$s %2$s-i xaric etdi</string>
-    <string name="notice_room_unban">%1$s %2$s-i blokdan açdı</string>
-    <string name="notice_room_ban">%1$s %2$s-i blokladı</string>
-    <string name="notice_room_withdraw">%1$s %2$s-in dəvətini geri götürdü</string>
-    <string name="notice_avatar_url_changed">%1$s avatarı dəyişdi</string>
-    <string name="notice_display_name_set">%1$s ekran adını %2$s olaraq təyin etdi</string>
-    <string name="notice_display_name_changed_from">%1$s ekran adını %2$s-dan %3$s-ya dəyişdi</string>
-    <string name="notice_display_name_removed">%1$s onların göstərilən adlarını sildi (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s mövzunu dəyişdi: %2$s</string>
-    <string name="notice_room_name_changed">%1$s otaq adını dəyişdirdi: %2$s</string>
-    <string name="notice_placed_video_call">%s video zəng etdi.</string>
-    <string name="notice_placed_voice_call">%s səsli zəng etdi.</string>
-    <string name="notice_answered_call">%s zəngə cavab verdi.</string>
-    <string name="notice_ended_call">%s zəng başa çatdı.</string>
-    <string name="notice_made_future_room_visibility">"%1$s gələcək otaq tarixçəsini %2$s-ə  görünən etdi"</string>
-    <string name="notice_room_visibility_invited">bütün otaq üzvləri, dəvət olunduğu andan.</string>
-    <string name="notice_room_visibility_joined">bütün otaq üzvləri, qoşulduğu andan.</string>
-    <string name="notice_room_visibility_shared">bütün otaq üzvləri.</string>
-    <string name="notice_room_visibility_world_readable">hər kəs.</string>
-    <string name="notice_room_visibility_unknown">naməlum (%s).</string>
-    <string name="notice_end_to_end">%1$s sondan-sona şifrələmə açdı (%2$s)</string>
-    <string name="notice_room_update">%s bu otağı təkmilləşdirdi.</string>
-
-    <string name="notice_requested_voip_conference">%1$s VoIP konfrans istədi</string>
-    <string name="notice_voip_started">VoIP konfransı başladı</string>
-    <string name="notice_voip_finished">VoIP konfransı başa çatdı</string>
-
-    <string name="notice_avatar_changed_too">(avatar da dəyişdirilib)</string>
-    <string name="notice_room_name_removed">%1$s otaq adını sildi</string>
-    <string name="notice_room_topic_removed">%1$s otaq mövzusunu sildi</string>
-    <string name="notice_event_redacted">Mesaj silindi</string>
-    <string name="notice_event_redacted_by">Mesaj %1$s tərəfindən silindi</string>
-    <string name="notice_event_redacted_with_reason">Mesaj silindi [səbəb: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Mesaj %1$s tərəfindən qaldırıldı [səbəb: %2$s]</string>
-    <string name="notice_profile_change_redacted">%1$s profilini %2$s yenilədi</string>
-    <string name="notice_room_third_party_invite">%1$s otağa qoşulmaq üçün %2$s dəvətnamə göndərdi</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s otağa qoşulmaq üçün %2$s dəvətini ləğv etdi</string>
-    <string name="notice_room_third_party_registered_invite">%1$s %2$s üçün dəvəti qəbul etdi</string>
-
-    <string name="notice_crypto_unable_to_decrypt">** Şifrəni aça bilmir: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Göndərənin cihazı bu mesaj üçün açarları bizə göndərməyib.</string>
-
-    <string name="could_not_redact">Redaktə etmək olmur</string>
-    <string name="unable_to_send_message">Mesaj göndərmək olmur</string>
-
-    <string name="message_failed_to_upload">Şəkil yükləmək olmur</string>
-
-    <string name="network_error">Şəbəkə xətası</string>
-    <string name="matrix_error">Matris xətası</string>
-
-    <string name="room_error_join_failed_empty_room">Boş bir otağa yenidən qoşulmaq hazırda mümkün deyil.</string>
-
-    <string name="encrypted_message">Şifrəli mesaj</string>
-
-    <string name="medium_email">Elektron poçt ünvanı</string>
-    <string name="medium_phone_number">Telefon nömrəsi</string>
-
-    <string name="room_displayname_invite_from">%s-dən dəvət</string>
-    <string name="room_displayname_room_invite">Otağa dəvət</string>
-
-    <string name="room_displayname_two_members">%1$s vÉ™ %2$s</string>
-
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s və 1 digər</item>
-        <item quantity="other">%1$s və %2$d digərləri</item>
-    </plurals>
-
-    <string name="room_displayname_empty_room">BoÅŸ otaq</string>
-
-    <string name="initial_sync_start_importing_account">Ä°lkin sinxronizasiya:
-\nHesab idxal olunur…</string>
-    <string name="initial_sync_start_importing_account_crypto">Ä°lkin sinxronizasiya:
-\nKriptografiyanın idxalı</string>
-    <string name="initial_sync_start_importing_account_rooms">Ä°lkin sinxronizasiya:
-\nOtaqlar idxalı</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Ä°lkin sinxronizasiya:
-\nOtaqlara daxil olmaq</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Ä°lkin sinxronizasiya:
-\nDəvət olunmuş otaqların idxalı</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Ä°lkin sinxronizasiya:
-\nTərk olunmuş otaqların idxalı</string>
-    <string name="initial_sync_start_importing_account_groups">Ä°lkin sinxronizasiya:
-\nİcmaların idxalı</string>
-    <string name="initial_sync_start_importing_account_data">Ä°lkin sinxronizasiya:
-\nHesab məlumatlarının idxalı</string>
-
-    <string name="event_status_sending_message">Mesaj göndərilir…</string>
-    <string name="clear_timeline_send_queue">Göndərmə növbəsini təmizləyin</string>
-
-    <string name="notice_room_invite_no_invitee_with_reason">%1$s-nin dəvəti. Səbəb: %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s dəvət olunmuş %2$s. Səbəb: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s sizi dəvət etdi. Səbəb: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s qoşuldu. Səbəb: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s qalıb. Səbəb: %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s dəvəti rədd etdi. Səbəb: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s %2$s-i xaric etdi. Səbəb: %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s blokdan açdı %2$s. Səbəb: %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s blokladı %2$s. Səbəb: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s otağa qoşulmaq üçün %2$s dəvətnamə göndərdi. Səbəb: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s otağa qoşulmaq üçün %2$s dəvətini ləğv etdi. Səbəb: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s %2$s üçün dəvəti qəbul etdi. Səbəb: %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s %2$s dəvətini geri götürdü. Səbəb: %3$s</string>
-
-</resources>
diff --git a/matrix-sdk-android/src/main/res/values-bg/strings.xml b/matrix-sdk-android/src/main/res/values-bg/strings.xml
deleted file mode 100644
index c3a5f3be8291dcb9b0012ca849281f99ef31ba43..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-bg/strings.xml
+++ /dev/null
@@ -1,216 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s изпрати снимка.</string>
-    <string name="notice_room_invite_no_invitee">Поканата на %s</string>
-    <string name="notice_room_invite">%1$s покани %2$s</string>
-    <string name="notice_room_invite_you">%1$s Ви покани</string>
-    <string name="notice_room_join">%1$s се присъедини в стаята</string>
-    <string name="notice_room_leave">%1$s напусна стаята</string>
-    <string name="notice_room_reject">%1$s отхвърли поканата</string>
-    <string name="notice_room_kick">%1$s изгони %2$s</string>
-    <string name="notice_room_unban">%1$s отблокира %2$s</string>
-    <string name="notice_room_ban">%1$s блокира %2$s</string>
-    <string name="notice_room_withdraw">%1$s оттегли поканата си за %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s смени своята профилна снимка</string>
-    <string name="notice_display_name_set">%1$s си сложи име %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s смени своето име от %2$s на %3$s</string>
-    <string name="notice_display_name_removed">%1$s премахна своето име (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s смени темата на: %2$s</string>
-    <string name="notice_room_name_changed">%1$s смени името на стаята на: %2$s</string>
-    <string name="notice_placed_video_call">%s започна видео разговор.</string>
-    <string name="notice_placed_voice_call">%s започна гласов разговор.</string>
-    <string name="notice_answered_call">%s отговори на обаждането.</string>
-    <string name="notice_ended_call">%s прекрати разговора.</string>
-    <string name="notice_made_future_room_visibility">%1$s направи бъдещата история на стаята видима за %2$s</string>
-    <string name="notice_room_visibility_invited">всички членове, от момента на поканването им в нея.</string>
-    <string name="notice_room_visibility_joined">всички членове, от момента на присъединяването им в нея.</string>
-    <string name="notice_room_visibility_shared">всички членове в нея.</string>
-    <string name="notice_room_visibility_world_readable">всеки.</string>
-    <string name="notice_room_visibility_unknown">непозната (%s).</string>
-    <string name="notice_end_to_end">%1$s включи шифроване от край до край (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s заяви VoIP групов разговор</string>
-    <string name="notice_voip_started">Започна VoIP групов разговор</string>
-    <string name="notice_voip_finished">Груповият разговор приключи</string>
-    <string name="notice_avatar_changed_too">(профилната снимка също беше сменена)</string>
-    <string name="notice_room_name_removed">%1$s премахна името на стаята</string>
-    <string name="notice_room_topic_removed">%1$s премахна темата на стаята</string>
-    <string name="notice_profile_change_redacted">%1$s обнови своя профил %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s изпрати покана на %2$s да се присъедини към стаята</string>
-    <string name="notice_room_third_party_registered_invite">%1$s прие поканата за %2$s</string>
-    <string name="notice_crypto_unable_to_decrypt">** Неуспешно разшифроване: %s **</string>
-    <string name="could_not_redact">Неуспешно премахване</string>
-    <string name="unable_to_send_message">Неуспешно изпращане на съобщението</string>
-    <string name="message_failed_to_upload">Неуспешно качване на снимката</string>
-    <string name="network_error">Грешка в мрежата</string>
-    <string name="matrix_error">Matrix грешка</string>
-    <string name="room_error_join_failed_empty_room">В момента не е възможно да се присъедините отново към празна стая.</string>
-    <string name="encrypted_message">Шифровано съобщение</string>
-    <string name="medium_email">Имейл адрес</string>
-    <string name="medium_phone_number">Телефонен номер</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Устройството на подателя не изпрати ключовете за това съобщение.</string>
-    <string name="summary_user_sent_sticker">%1$s изпрати стикер.</string>
-    <string name="room_displayname_invite_from">Покана от %s</string>
-    <string name="room_displayname_room_invite">Покана за стая</string>
-    <string name="room_displayname_two_members">%1$s и %2$s</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s и 1 друг</item>
-        <item quantity="other">%1$s и %2$d други</item>
-    </plurals>
-    <string name="room_displayname_empty_room">Празна стая</string>
-    <string name="notice_event_redacted">Премахнато съобщение</string>
-    <string name="notice_event_redacted_by">Съобщение премахнато от %1$s</string>
-    <string name="notice_event_redacted_with_reason">Премахнато съобщение [причина: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Съобщение премахнато от %1$s [причина: %2$s]</string>
-    <string name="initial_sync_start_importing_account">Начална синхронизация:
-\nИмпортиране на профил…</string>
-    <string name="initial_sync_start_importing_account_crypto">Начална синхронизация:
-\nИмпортиране на данни за шифроване</string>
-    <string name="initial_sync_start_importing_account_rooms">Начална синхронизация:
-\nИмпортиране на стаи</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Начална синхронизация:
-\nИмпортиране на стаи, от които съм част</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Начална синхронизация:
-\nИмпортиране на стаи, към които съм поканен</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Начална синхронизация:
-\nИмпортиране на стаи, които съм напуснал</string>
-    <string name="initial_sync_start_importing_account_groups">Начална синхронизация:
-\nИмпортиране на общности</string>
-    <string name="initial_sync_start_importing_account_data">Начална синхронизация:
-\nИмпортиране на данни за профила</string>
-    <string name="notice_room_update">%s обнови тази стая.</string>
-    <string name="event_status_sending_message">Изпращане на съобщение…</string>
-    <string name="clear_timeline_send_queue">Изчисти опашката за изпращане</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s оттегли поканата за присъединяване на %2$s към стаята</string>
-    <string name="notice_room_invite_no_invitee_with_reason">поканата на %1$s. Причина: %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s покани %2$s. Причина: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s ви покани. Причина: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s се присъедини в стаята. Причина: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s напусна стаята. Причина: %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s отхвърли поканата. Причина: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s изгони %2$s. Причина: %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s блокира %2$s. Причина: %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s блокира %2$s. Причина: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s изпрати покана до %2$s да се присъедини в стаята. Причина: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s премахна поканата за присъединяване на %2$s в стаята. Причина: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s прие поканата за %2$s. Причина: %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s оттегли поканата на %2$s. Причина: %3$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s добави %2$s като адрес за тази стая.</item>
-        <item quantity="other">%1$s добави %2$s като адреси за тази стая.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s премахна %2$s като адрес за тази стая.</item>
-        <item quantity="other">%1$s премахна %2$s като адреси за тази стая.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s добави %2$s и премахна %3$s като адреси за тази стая.</string>
-    <string name="notice_room_canonical_alias_set">%1$s настрой %2$s като основен адрес за тази стая.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s премахна основния адрес за тази стая.</string>
-    <string name="notice_room_guest_access_can_join">%1$s разреши на гости да се присъединяват в стаята.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s предотврати присъединяването на гости в стаята.</string>
-    <string name="notice_end_to_end_ok">%1$s включи шифроване от-край-до-край.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s включи шифроване от-край-до-край (неразпознат алгоритъм %2$s).</string>
-    <string name="key_verification_request_fallback_message">%s изпрати запитване за потвърждение на ключа ви, но клиентът ви не поддържа верифициране посредством чат. Ще трябва да използвате стария метод за верифициране на ключове.</string>
-    <string name="notice_room_created">%1$s създаде стаята</string>
-    <string name="summary_you_sent_image">Изпратихте снимка.</string>
-    <string name="summary_you_sent_sticker">Изпратихте стикер.</string>
-    <string name="notice_room_invite_no_invitee_by_you">Ваша покана</string>
-    <string name="notice_room_created_by_you">Създадохте стаята</string>
-    <string name="notice_room_invite_by_you">Поканихте %1$s</string>
-    <string name="notice_room_join_by_you">Присъединихте се в стаята</string>
-    <string name="notice_room_leave_by_you">Напуснахте стаята</string>
-    <string name="notice_room_reject_by_you">Отхвърлихте поканата</string>
-    <string name="notice_room_kick_by_you">Изгонихте %1$s</string>
-    <string name="notice_room_unban_by_you">Отблокирахте %1$s</string>
-    <string name="notice_room_ban_by_you">Блокирахте %1$s</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Включихте шифроване от-край-до-край (непознат алгоритъм: %1$s).</string>
-    <string name="notice_end_to_end_ok_by_you">Включихте шифроване от-край-до-край.</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">Спряхте възможността гости да се присъединяват в стаята.</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s спря възможността гости да се присъединяват в стаята.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">Спряхте възможността гости да се присъединяват в стаята.</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">Позволихте на гости да се присъединяват тук.</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s позволи на гости да се присъединяват тук.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Позволихте на гости да се присъединяват към стаята.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Премахнахте основния адрес на стаята.</string>
-    <string name="notice_room_canonical_alias_set_by_you">Зададохте %1$s като основен адрес на стаята.</string>
-    <string name="notice_room_aliases_added_and_removed_by_you">Добавихте %1$s и премахнахте %2$s от адресите за стаята.</string>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">Премахнахте %1$s от адресите на стаята.</item>
-        <item quantity="other">Премахнахте %1$s от адресите на стаята.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">Добавихте %1$s като адрес за тази стая.</item>
-        <item quantity="other">Добавихте %1$s като адреси за тази стая.</item>
-    </plurals>
-    <string name="notice_room_withdraw_with_reason_by_you">Оттеглихте поканата на %1$s. Причина: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Приехте поканата за %1$s. Причина: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Оттеглихте поканата за присъединяване в стаята от %1$s. Причина: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Изпратихте покана към %1$s за присъединяване в стаята. Причина: %2$s</string>
-    <string name="notice_room_ban_with_reason_by_you">Блокирахте %1$s. Причина: %2$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Отблокирахте %1$s. Причина: %2$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Изгонихте %1$s. Причина: %2$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Отхвърлихте поканата. Причина: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">Напуснахте. Причина: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s напусна. Причина: %2$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Напуснахте стаята. Причина: %1$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">Присъединихте се. Причина: %1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s се присъедини. Причина: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">Присъединихте се в стаята. Причина: %1$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Поканихте %1$s. Причина: %2$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">Ваша покана. Причина: %1$s</string>
-    <string name="notice_power_level_diff">%1$s от %2$s на %3$s</string>
-    <string name="notice_power_level_changed">%1$s промени нивото на достъп на %2$s.</string>
-    <string name="notice_power_level_changed_by_you">Променихте нивото на достъп на %1$s.</string>
-    <string name="power_level_custom_no_value">Собствено ниво</string>
-    <string name="power_level_custom">Собствено ниво (%1$d)</string>
-    <string name="power_level_default">По подразбиране</string>
-    <string name="power_level_moderator">Модератор</string>
-    <string name="power_level_admin">Администратор</string>
-    <string name="notice_widget_modified_by_you">Променихте %1$s приспособлението</string>
-    <string name="notice_widget_modified">%1$s промени %2$s приспособлението</string>
-    <string name="notice_widget_removed_by_you">Премахнахте %1$s приспособлението</string>
-    <string name="notice_widget_removed">%1$s премахна %2$s приспособлението</string>
-    <string name="notice_widget_added_by_you">Добавихте %1$s приспособление</string>
-    <string name="notice_widget_added">%1$s добави %2$s приспособление</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Приехте поканата за %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">Оттеглихте поканата от %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s оттегли поканата от %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Оттеглихте поканата за присъединяване в стаята от %1$s</string>
-    <string name="notice_direct_room_third_party_invite_by_you">Поканихте %1$s</string>
-    <string name="notice_direct_room_third_party_invite">%1$s покани %2$s</string>
-    <string name="notice_room_third_party_invite_by_you">Изпратихте покана към %1$s за присъединяване в стаята</string>
-    <string name="notice_profile_change_redacted_by_you">Обновихте профила си %1$s</string>
-    <string name="notice_room_avatar_removed_by_you">Премахнахте снимката на стаята</string>
-    <string name="notice_room_avatar_removed">%1$s премахна снимката на стаята</string>
-    <string name="notice_room_topic_removed_by_you">Премахнахте темата на стаята</string>
-    <string name="notice_room_name_removed_by_you">Премахнахте името на стаята</string>
-    <string name="notice_requested_voip_conference_by_you">Заявихте VoIP конференция</string>
-    <string name="notice_direct_room_update_by_you">Обновихте чата.</string>
-    <string name="notice_direct_room_update">%s обнови чата.</string>
-    <string name="notice_room_update_by_you">Обновихте стаята.</string>
-    <string name="notice_end_to_end_by_you">Включихте шифроване от-край-до-край (%1$s)</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">Направихте бъдещите съобщения видими за %1$s</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s направи бъдещите съобщения видими за %2$s</string>
-    <string name="notice_made_future_room_visibility_by_you">Направихте бъдещата история на стаята видима за %1$s</string>
-    <string name="notice_ended_call_by_you">Прекратихте разговора.</string>
-    <string name="notice_placed_video_call_by_you">Започнахте видео разговор.</string>
-    <string name="notice_answered_call_by_you">Отговорихте на обаждането.</string>
-    <string name="notice_call_candidates_by_you">Изпратихте данни за настройка на разговора.</string>
-    <string name="notice_call_candidates">%s изпрати данни за настройка на разговора.</string>
-    <string name="notice_placed_voice_call_by_you">Започнахте гласов разговор.</string>
-    <string name="notice_room_name_changed_by_you">Променихте името на стаята на: %1$s</string>
-    <string name="notice_room_avatar_changed_by_you">Променихте снимката на стаята</string>
-    <string name="notice_room_avatar_changed">%1$s промени снимката на стаята</string>
-    <string name="notice_room_topic_changed_by_you">Променихте темата на: %1$s</string>
-    <string name="notice_display_name_removed_by_you">Премахнахте името си (%1$s)</string>
-    <string name="notice_display_name_changed_from_by_you">Променихте името си от %1$s на %2$s</string>
-    <string name="notice_display_name_set_by_you">Променихте името си на %1$s</string>
-    <string name="notice_avatar_url_changed_by_you">Променихте снимката си</string>
-    <string name="notice_room_withdraw_by_you">Оттеглихте поканата от %1$s</string>
-    <string name="notice_direct_room_leave_by_you">Напуснахте стаята</string>
-    <string name="notice_direct_room_leave">%1$s напусна стаята</string>
-    <string name="notice_direct_room_join_by_you">Присъединихте се</string>
-    <string name="notice_direct_room_join">%1$s се присъедини</string>
-    <string name="notice_direct_room_created_by_you">Създадохте дискусията</string>
-    <string name="notice_direct_room_created">%1$s създаде дискусията</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-bn-rIN/strings.xml b/matrix-sdk-android/src/main/res/values-bn-rIN/strings.xml
deleted file mode 100644
index 35f8feaf0f36843de13131a25cbddb88d758d50a..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-bn-rIN/strings.xml
+++ /dev/null
@@ -1,194 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_user_sent_image">%1$s একটি ফটো পাঠিয়েছে।</string>
-    <string name="summary_user_sent_sticker">%1$s একটি স্তিকার পাঠিয়েছে।</string>
-    <string name="notice_room_invite_no_invitee">%s এর আমন্ত্রণ</string>
-    <string name="notice_room_invite">%1$s %2$s কে আমন্ত্রণ করেছে</string>
-    <string name="notice_room_invite_you">%1$s আপনাকে আমন্ত্রণ করেছে</string>
-    <string name="notice_room_join">%1$s রুম এ যোগ দিয়েছে</string>
-    <string name="notice_room_leave">%1$s রুম ছেড়ে দিয়েছে</string>
-    <string name="notice_room_reject">%1$s আমন্ত্রণ টি বাতিল করেছে</string>
-    <string name="notice_room_kick">%1$s %2$s কে কিক করেছে</string>
-    <string name="notice_room_unban">%1$s %2$s কে নিষিদ্ধ তালিকা থেকে মুক্ত করেছে</string>
-    <string name="notice_room_ban">%1$s %2$s কে নিষিদ্ধ করেছে</string>
-    <string name="notice_room_withdraw">%1$s %2$s এর আমন্ত্রণ ফেরত নিয়েছে</string>
-    <string name="notice_avatar_url_changed">%1$s নিজের অবতার পরিবর্তন করেছে</string>
-    <string name="notice_display_name_set">%1$s নিজের প্রদর্শন নাম %2$s রেখেছে</string>
-    <string name="notice_display_name_changed_from">%1$s নিজের প্রদর্শন নাম %2$s থেকে %3$s তে পরিবর্তন করেছে</string>
-    <string name="notice_display_name_removed">%1$s নিজের প্রদর্শন নাম মুছে দিয়েছে (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s বিষয় টি এতে পরিবর্তন করেছে: %2$s</string>
-    <string name="notice_room_name_changed">%1$s রুম এর নাম এতে পরিবর্তন করেছে: %2$s</string>
-    <string name="notice_placed_video_call">%s একটি ভিডিও কল স্থাপন করেছিল।</string>
-    <string name="notice_placed_voice_call">%s একটি ভয়েস কল দিয়েছে।</string>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_you_sent_image">আপনি একটি ছবি প্রেরণ করেছেন।</string>
-    <string name="summary_you_sent_sticker">আপনি একটি স্তিকার পাঠিয়েছেন।</string>
-    <string name="notice_room_invite_no_invitee_by_you">আপনার আমন্ত্রণ</string>
-    <string name="notice_room_created">%1$s কক্ষটি তৈরি করেছেন</string>
-    <string name="notice_room_created_by_you">আপনি কক্ষটি তৈরি করেছেন</string>
-    <string name="notice_room_invite_by_you">আপনি %1$s কে আমন্ত্রিত করেছেন</string>
-    <string name="notice_room_join_by_you">আপনি কক্ষে যোগ দিয়েছেন</string>
-    <string name="notice_room_leave_by_you">আপনি কক্ষ ছেড়ে দিয়েছেন</string>
-    <string name="notice_room_reject_by_you">আপনি আমন্ত্রণটি বাতিল করেছেন</string>
-    <string name="notice_room_kick_by_you">আপনি %1$s কে কীক করেছেন</string>
-    <string name="notice_room_unban_by_you">আপনি %1$s কে নিষিদ্ধ মুক্ত করেছেন</string>
-    <string name="notice_room_ban_by_you">আপনি %1$s কে নিষিদ্ধ করেছেন</string>
-    <string name="notice_room_withdraw_by_you">আপনি %1$s এর আমন্ত্রণ প্রত্যাহার করেছেন</string>
-    <string name="notice_avatar_url_changed_by_you">আপনি আপনার অবতারটি পরিবর্তন করেছেন</string>
-    <string name="notice_display_name_set_by_you">আপনি আপনার প্রদর্শনের নামটি %1$s তে সেট করেছেন</string>
-    <string name="notice_display_name_changed_from_by_you">আপনি আপনার প্রদর্শনের নামটি %1$s থেকে %2$s এ পরিবর্তন করেছেন</string>
-    <string name="notice_display_name_removed_by_you">আপনি আপনার প্রদর্শনের নামটি সরিয়ে দিয়েছেন (যেটা ছিল %1$s)</string>
-    <string name="notice_room_topic_changed_by_you">আপনি বিষয়টিকে এতে পরিবর্তন করেছেন: %1$s</string>
-    <string name="notice_room_avatar_changed">%1$s কক্ষের অবতারটি পরিবর্তন করেছে</string>
-    <string name="notice_room_avatar_changed_by_you">আপনি কক্ষের অবতারটি পরিবর্তন করেছেন</string>
-    <string name="notice_room_name_changed_by_you">আপনি কক্ষের নাম এতে পরিবর্তন করেছেন:%1$s</string>
-    <string name="notice_placed_video_call_by_you">আপনি একটি ভিডিও কল করেছেন।</string>
-    <string name="notice_placed_voice_call_by_you">আপনি একটি ভয়েস কল দিয়েছেন।</string>
-    <string name="notice_call_candidates">কল সেটআপ করার জন্য %s ডেটা প্রেরণ করেছে।</string>
-    <string name="notice_call_candidates_by_you">আপনি কল সেটআপ করার জন্য ডেটা প্রেরণ করেছেন।</string>
-    <string name="notice_answered_call">%s কলটির উত্তর দিয়েছে।</string>
-    <string name="notice_answered_call_by_you">আপনি কলটি উত্তর দিয়েছেন।</string>
-    <string name="notice_ended_call">%s কলটি শেষ করেছেন।</string>
-    <string name="notice_ended_call_by_you">আপনি কলটি শেষ করেছেন।</string>
-    <string name="notice_made_future_room_visibility">%1$s ভবিষ্যতের ঘরের ইতিহাস %2$s এর কাছে দৃশ্যমান করে তুলেছে</string>
-    <string name="notice_made_future_room_visibility_by_you">আপনি ভবিষ্যতের কক্ষ ইতিহাস %1$s এর কাছে দৃশ্যমান করেছেন</string>
-    <string name="notice_room_visibility_invited">কক্ষের সমস্ত সদস্য, যখন থেকে তারা আমন্ত্রিত।</string>
-    <string name="notice_room_visibility_joined">কক্ষের সমস্ত সদস্য, যখন থেকে তারা যোগদান করেছিল।</string>
-    <string name="notice_room_visibility_shared">সমস্ত কক্ষের সদস্য।</string>
-    <string name="notice_room_visibility_world_readable">যে কেউ।</string>
-    <string name="notice_room_visibility_unknown">অজানা (%s)।</string>
-    <string name="notice_end_to_end">%1$s এন্ড-টু-এন্ড এনক্রিপশন চালু করেছে (%2$s)</string>
-    <string name="notice_end_to_end_by_you">আপনি শেষ-থেকে-শেষ এনক্রিপশন চালু করেছেন (%1$s)</string>
-    <string name="notice_room_update">%s এই কক্ষটিকে আপগ্রেড করেছে।</string>
-    <string name="notice_room_update_by_you">আপনি এই কক্ষটি আপগ্রেড করেছেন।</string>
-    <string name="notice_requested_voip_conference">%1$s একটি ভিওআইপি সম্মেলনের জন্য অনুরোধ করেছে</string>
-    <string name="notice_requested_voip_conference_by_you">আপনি একটি ভিওআইপি সম্মেলনের অনুরোধ করেছেন</string>
-    <string name="notice_voip_started">ভিওআইপি সম্মেলন শুরু হয়েছে</string>
-    <string name="notice_voip_finished">ভিওআইপি সম্মেলন শেষ হয়েছে</string>
-    <string name="notice_avatar_changed_too">(আবতারটিও পরিবর্তন করা হয়েছিল)</string>
-    <string name="notice_room_name_removed">%1$s কক্ষের নাম সরিয়েছে</string>
-    <string name="notice_room_name_removed_by_you">আপনি কক্ষের নাম সরিয়েছেন</string>
-    <string name="notice_room_topic_removed">%1$s কক্ষের বিষয় মুছে ফেলেছে</string>
-    <string name="notice_room_topic_removed_by_you">আপনি কক্ষের বিষয়টিকে সরিয়ে দিয়েছেন</string>
-    <string name="notice_room_avatar_removed">%1$s কক্ষের অবতার সরিয়ে নিয়েছে</string>
-    <string name="notice_room_avatar_removed_by_you">আপনি কক্ষের অবতার সরিয়েছেন</string>
-    <string name="notice_event_redacted">বার্তা সরানো হয়েছে</string>
-    <string name="notice_event_redacted_by">%1$s দ্বারা বার্তা সরানো হয়েছে</string>
-    <string name="notice_event_redacted_with_reason">বার্তা সরানো হয়েছে [কারণ:%1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">%1$s দ্বারা বার্তা সরানো হয়েছে [কারণ: %2$s]</string>
-    <string name="notice_profile_change_redacted">%1$s তাদের প্রোফাইল %2$s আপডেট করেছে</string>
-    <string name="notice_profile_change_redacted_by_you">আপনি আপনার প্রোফাইল %1$s আপডেট করেছেন</string>
-    <string name="notice_room_third_party_invite">%1$s %2$s কে ঘরে যোগদানের জন্য একটি আমন্ত্রণ পাঠিয়েছে</string>
-    <string name="notice_room_third_party_invite_by_you">আপনি %1$s কে ঘরে যোগদানের জন্য একটি আমন্ত্রণ প্রেরণ করেছেন</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s %2$s এর কক্ষে যোগদানের আমন্ত্রণ বাতিল করে দিয়েছিল</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">আপনি %1$s এর কক্ষে যোগদানের জন্য আমন্ত্রণটি বাতিল করেছেন</string>
-    <string name="notice_room_third_party_registered_invite">%1$s %2$s এর জন্য আমন্ত্রণটি গ্রহণ করেছে</string>
-    <string name="notice_room_third_party_registered_invite_by_you">আপনি %1$s এর জন্য আমন্ত্রণটি গ্রহণ করেছেন</string>
-    <string name="notice_widget_added">%1$s %2$s উইজেট যুক্ত করেছে</string>
-    <string name="notice_widget_added_by_you">আপনি %1$s উইজেট যুক্ত করেছেন</string>
-    <string name="notice_widget_removed">%1$s %2$s উইজেট সরিয়ে দিয়েছেন</string>
-    <string name="notice_widget_removed_by_you">আপনি %1$s উইজেট সরিয়েছেন</string>
-    <string name="notice_widget_modified">%1$s %2$s উইজেট পরিবর্তন করেছেন</string>
-    <string name="notice_widget_modified_by_you">আপনি %1$s উইজেট পরিবর্তন করেছেন</string>
-    <string name="power_level_admin">অ্যাডমিন</string>
-    <string name="power_level_moderator">নিয়ামক</string>
-    <string name="power_level_default">ডিফল্ট</string>
-    <string name="power_level_custom">কাস্টম (%1$d)</string>
-    <string name="power_level_custom_no_value">কাস্টম</string>
-    <string name="notice_power_level_changed_by_you">আপনি %1$s এর পাওয়ার স্তর পরিবর্তন করেছেন।</string>
-    <string name="notice_power_level_changed">%1$s %2$s এর পাওয়ার স্তর পরিবর্তন করেছে।</string>
-    <string name="notice_power_level_diff">%1$s %2$s থেকে %3$s পর্যন্ত</string>
-    <string name="notice_crypto_unable_to_decrypt">** ডিক্রিপ্ট করতে অক্ষম: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">প্রেরকের ডিভাইস আমাদের এই বার্তার জন্য কীগুলি প্রেরণ করেনি।</string>
-    <string name="could_not_redact">পুনরায় প্রতিক্রিয়া করতে পারেনি</string>
-    <string name="unable_to_send_message">বার্তা পাঠাতে অক্ষম</string>
-    <string name="message_failed_to_upload">চিত্র আপলোড করতে ব্যর্থ</string>
-    <string name="network_error">নেটওয়ার্ক ত্রুটি</string>
-    <string name="matrix_error">ম্যাট্রিক্স ত্রুটি</string>
-    <string name="room_error_join_failed_empty_room">খালি কক্ষে পুনরায় যোগদান করা বর্তমানে সম্ভব নয়।</string>
-    <string name="encrypted_message">এনক্রিপ্ট করা বার্তা</string>
-    <string name="medium_email">ইমেল ঠিকানা</string>
-    <string name="medium_phone_number">ফোন নম্বর</string>
-    <string name="room_displayname_invite_from">%s থেকে আমন্ত্রণ করুন</string>
-    <string name="room_displayname_room_invite">কক্ষ আমন্ত্রণ</string>
-    <string name="room_displayname_two_members">%1$s এবং %2$s</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s এবং অন্য ১ জন</item>
-        <item quantity="other">%1$s এবং অন্যান্য %2$d জন</item>
-    </plurals>
-    <string name="room_displayname_empty_room">খালি কক্ষ</string>
-    <string name="initial_sync_start_importing_account">প্রাথমিক সিঙ্ক:
-\nঅ্যাকাউন্ট আমদানি করা হচ্ছে…</string>
-    <string name="initial_sync_start_importing_account_crypto">প্রাথমিক সিঙ্ক:
-\nক্রিপ্টো আমদানি হচ্ছে</string>
-    <string name="initial_sync_start_importing_account_rooms">প্রাথমিক সিঙ্ক:
-\nকক্ষগুলি আমদানি করা হচ্ছে</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">প্রাথমিক সিঙ্ক:
-\nযোগ করা কক্ষগুলিতে আমদানি করা হিচ্ছে</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">প্রাথমিক সিঙ্ক:
-\nআমন্ত্রিত করা কক্ষগুলিতে আমদানি করা হিচ্ছে</string>
-    <string name="initial_sync_start_importing_account_left_rooms">প্রাথমিক সিঙ্ক:
-\nছেড়ে দেওয়া কক্ষগুলিতে আমদানি করা হিচ্ছে</string>
-    <string name="initial_sync_start_importing_account_groups">প্রাথমিক সিঙ্ক:
-\nসম্প্রদায়গুলি আমদানি করা হচ্ছে</string>
-    <string name="initial_sync_start_importing_account_data">প্রাথমিক সিঙ্ক:
-\nঅ্যাকাউন্ট ডেটা আমদানি করা হচ্ছে</string>
-    <string name="event_status_sending_message">বার্তা প্রেরণ করা হচ্ছে …</string>
-    <string name="clear_timeline_send_queue">প্রেরণ সারি পরিষ্কার করুন</string>
-    <string name="notice_room_invite_no_invitee_with_reason">%1$s এর আমন্ত্রণ। কারণ: %2$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">আপনার আমন্ত্রণ। কারণ: %1$s</string>
-    <string name="notice_room_invite_with_reason">%1$s আমন্ত্রিত করেছেন %2$s কে। কারণ: %3$s</string>
-    <string name="notice_room_invite_with_reason_by_you">আপনি %1$s কে আমন্ত্রিত করেছেন। কারণ: %2$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s আপনাকে আমন্ত্রণ করেছে। কারণ: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s রুম এ যোগ দিয়েছে। কারণ: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">আপনি কক্ষে যোগ দিয়েছেন। কারণ: %1$s</string>
-    <string name="notice_room_leave_with_reason">%1$s রুম ছেড়ে দিয়েছে। কারণ: %2$s</string>
-    <string name="notice_room_leave_with_reason_by_you">আপনি কক্ষ ছেড়ে দিয়েছেন। কারণ: %1$s</string>
-    <string name="notice_room_reject_with_reason">%1$s আমন্ত্রণ বাতিল করেছেন। কারণ: %2$s</string>
-    <string name="notice_room_reject_with_reason_by_you">আপনি আমন্ত্রণটি বাতিল করেছেন। কারণ: %1$s</string>
-    <string name="notice_room_kick_with_reason">%1$s %2$s কে কিক করেছে। কারণ: %3$s</string>
-    <string name="notice_room_kick_with_reason_by_you">আপনি %1$s কে কীক করেছেন। কারণ: %2$s</string>
-    <string name="notice_room_unban_with_reason">%1$s %2$s কে নিষিদ্ধ তালিকা থেকে মুক্ত করেছে। কারণ: %3$s</string>
-    <string name="notice_room_unban_with_reason_by_you">আপনি %1$s কে নিষিদ্ধ মুক্ত করেছেন। কারণ: %2$s</string>
-    <string name="notice_room_ban_with_reason">%1$s %2$s কে নিষিদ্ধ করেছে। কারণ: %3$s</string>
-    <string name="notice_room_ban_with_reason_by_you">আপনি %1$s কে নিষিদ্ধ করেছেন। কারণ: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s রুমের সাথে যোগ দিতে %2$s কে একটি আমন্ত্রণ পাঠিয়েছেন। কারণ: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">আপনি %1$s কে ঘরে যোগদানের জন্য একটি আমন্ত্রণ প্রেরণ করেছেন। কারণ: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s %2$s এর কক্ষে যোগদানের আমন্ত্রণ বাতিল করে দিয়েছিল। কারণ: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">আপনি %1$s এর কক্ষে যোগদানের জন্য আমন্ত্রণটি বাতিল করেছেন। কারণ: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s %2$s এর জন্য আমন্ত্রণ গ্রহণ করেছেন। কারণ: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">আপনি %1$s এর জন্য আমন্ত্রণটি গ্রহণ করেছেন। কারণ: %2$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s %2$s এর আমন্ত্রণ ফেরত নিয়েছে। কারণ: %3$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">আপনি %1$s এর আমন্ত্রণ প্রত্যাহার করেছেন। কারণ: %2$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s এই ঘরের ঠিকানা হিসাবে %2$s যুক্ত করেছে।</item>
-        <item quantity="other">%1$s এই ঘরের ঠিকানাগুলি হিসাবে %2$s যুক্ত করেছে।</item>
-    </plurals>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">আপনি এই কক্ষের জন্য ঠিকানা হিসাবে %1$s যুক্ত করেছেন।</item>
-        <item quantity="other">আপনি এই কক্ষের ঠিকানা হিসাবে %1$s যুক্ত করেছেন।</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s এই ঘরের ঠিকানা হিসাবে %2$s সরানো হয়েছে।</item>
-        <item quantity="other">%1$s %3$s কে এই ঘরের ঠিকানা হিসাবে সরানো হয়েছে।</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">আপনি এই ঘরের ঠিকানা হিসাবে %1$s সরিয়েছেন।</item>
-        <item quantity="other">আপনি এই ঘরের ঠিকানা হিসাবে %1$s গুলি সরিয়েছেন।</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s %2$s যোগ করেছে এবং %3$s গুলি এই ঘরের ঠিকানা হিসাবে সরানো হয়েছে।</string>
-    <string name="notice_room_aliases_added_and_removed_by_you">আপনি %1$s যোগ করেছেন এবং %2$s কে এই ঘরের ঠিকানা হিসাবে সরিয়ে দিয়েছেন।</string>
-    <string name="notice_room_canonical_alias_set">%1$s এই ঘরের মূল ঠিকানাটি %2$s তে সেট করে।</string>
-    <string name="notice_room_canonical_alias_set_by_you">আপনি এই ঘরের মূল ঠিকানাটি %1$s তে সেট করেছেন।</string>
-    <string name="notice_room_canonical_alias_unset">%1$s এই ঘরের মূল ঠিকানা সরিয়ে নিয়েছে।</string>
-    <string name="notice_room_canonical_alias_unset_by_you">আপনি এই ঘরের মূল ঠিকানা সরিয়েছেন।</string>
-    <string name="notice_room_guest_access_can_join">%1$s অতিথিদের ঘরে যোগদানের অনুমতি দিয়েছে।</string>
-    <string name="notice_room_guest_access_can_join_by_you">আপনি অতিথিদের ঘরে যোগদানের অনুমতি দিয়েছেন।</string>
-    <string name="notice_room_guest_access_forbidden">%1$s অতিথিদের ঘরে যোগদান করতে বাধা দিয়েছে।</string>
-    <string name="notice_room_guest_access_forbidden_by_you">আপনি অতিথিদের ঘরে যোগদান করতে বাধা দিয়েছেন।</string>
-    <string name="notice_end_to_end_ok">%1$s এন্ড-টু-এন্ড এনক্রিপশন চালু করেছে।</string>
-    <string name="notice_end_to_end_ok_by_you">আপনি শেষ থেকে শেষ এনক্রিপশন চালু করেছেন।</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s এন্ড-টু-এন্ড এনক্রিপশন চালু করেছে (অজানা অ্যালগরিদম %2$s)।</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">আপনি শেষ-থেকে-শেষ এনক্রিপশন চালু করেছেন (অজানা অ্যালগরিদম %1$s )।</string>
-    <string name="key_verification_request_fallback_message">%s আপনার কীটি যাচাই করার জন্য অনুরোধ করছে, তবে আপনার ক্লায়েন্ট ইন-চ্যাট কী যাচাইকরণ সমর্থন করে না। কীগুলি যাচাই করতে আপনাকে লিগ্যাসি কী যাচাইকরণ ব্যবহার করতে হবে।</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-bs/strings.xml b/matrix-sdk-android/src/main/res/values-bs/strings.xml
deleted file mode 100644
index 6a6ee46d3243da5b9328d65c84feb0d7658a0c2d..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-bs/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="room_displayname_invite_from">Pozovite iz %s</string>
-    <string name="room_displayname_room_invite">Poziv u Sobu</string>
-    <string name="room_displayname_two_members">%1$s i %2$s</string>
-    <string name="room_displayname_empty_room">Prazna soba</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-ca/strings.xml b/matrix-sdk-android/src/main/res/values-ca/strings.xml
deleted file mode 100644
index 8ba8c9acfd33b94484fdb765981611c1bd917dc4..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-ca/strings.xml
+++ /dev/null
@@ -1,217 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s ha enviat una imatge.</string>
-    <string name="notice_room_leave">%1$s ha marxat de la sala</string>
-    <string name="notice_room_join">%1$s s\'ha unit a la sala</string>
-    <string name="medium_phone_number">Número de telèfon</string>
-    <string name="medium_email">Correu electrònic</string>
-    <string name="encrypted_message">Missatge xifrat</string>
-    <string name="notice_room_invite_no_invitee">invitació de %s</string>
-    <string name="notice_room_invite">%1$s ha convidat a %2$s</string>
-    <string name="notice_room_invite_you">%1$s t\'ha convidat</string>
-    <string name="notice_room_reject">%1$s ha rebutjat la invitació</string>
-    <string name="notice_room_kick">%1$s ha expulsat %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s ha canviat el seu nom de visualització de %2$s a %3$s</string>
-    <string name="notice_display_name_removed">%1$s ha eliminat el seu nom de visualització (era %2$s)</string>
-    <string name="notice_room_topic_changed">%1$s ha canviat el tema a: %2$s</string>
-    <string name="notice_room_name_changed">%1$s ha canviat el nom de la sala a: %2$s</string>
-    <string name="notice_answered_call">%s ha respost a la trucada.</string>
-    <string name="notice_ended_call">%s ha finalitzat la trucada.</string>
-    <string name="notice_room_visibility_invited">tots el participants de la sala, des de que són convidats.</string>
-    <string name="notice_room_visibility_shared">tots els participants de la sala.</string>
-    <string name="notice_room_visibility_unknown">desconegut (%s).</string>
-    <string name="notice_end_to_end">%1$s ha activat el xifrat d\'extrem a extrem (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s ha sol·licitat una conferència VoIP</string>
-    <string name="notice_room_unban">%1$s ha tret el veto a %2$s</string>
-    <string name="notice_room_ban">%1$s ha vetat %2$s</string>
-    <string name="notice_room_withdraw">%1$s ha retirat la invitació de %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s ha canviat el seu avatar</string>
-    <string name="notice_made_future_room_visibility">%1$s ha establert la visibilitat de l\'historial futur de la sala a %2$s</string>
-    <string name="notice_room_visibility_joined">tots els participants de la sala, des de que s\'hi uneixen.</string>
-    <string name="notice_room_visibility_world_readable">qualsevol.</string>
-    <string name="notice_voip_started">S\'ha iniciat la conferència VoIP</string>
-    <string name="notice_voip_finished">Ha finalitzat la conferència VoIP</string>
-    <string name="notice_avatar_changed_too">(també ha canviat l\'avatar)</string>
-    <string name="notice_room_name_removed">%1$s ha eliminat el nom de la sala</string>
-    <string name="notice_room_topic_removed">%1$s ha eliminat el tema de la sala</string>
-    <string name="notice_profile_change_redacted">%1$s ha actualitzat el seu perfil %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s ha enviat una invitació a %2$s perquè s\'uneixi a la sala</string>
-    <string name="notice_room_third_party_registered_invite">%1$s ha acceptat la invitació de %2$s</string>
-    <string name="notice_crypto_unable_to_decrypt">** No s\'ha pogut desxifrar: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">El dispositiu del remitent no ens ha enviat les claus per aquest missatge.</string>
-    <string name="could_not_redact">No s\'ha pogut redactar</string>
-    <string name="unable_to_send_message">No s\'ha pogut enviar el missatge</string>
-    <string name="message_failed_to_upload">No s\'ha pogut pujar la imatge</string>
-    <string name="network_error">Error de xarxa</string>
-    <string name="matrix_error">Error de Matrix</string>
-    <string name="room_error_join_failed_empty_room">Ara per ara no és possible tornar a unir-se a una sala buida.</string>
-    <string name="notice_display_name_set">%1$s a canviat el seu nom de visualització a %2$s</string>
-    <string name="notice_placed_video_call">%s ha realitzat una videotrucada.</string>
-    <string name="notice_placed_voice_call">%s ha realitzat una trucada de veu.</string>
-    <!-- Room display name -->
-    <string name="room_displayname_invite_from">Invitació de %s</string>
-    <string name="room_displayname_room_invite">Convida a la sala</string>
-    <string name="room_displayname_two_members">%1$s i %2$s</string>
-    <string name="room_displayname_empty_room">Sala buida</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s i 1 altre</item>
-        <item quantity="other">%1$s i %2$d altres</item>
-    </plurals>
-    <string name="summary_user_sent_sticker">%1$s ha enviat un adhesiu.</string>
-    <string name="notice_direct_room_update">%s s\'ha actualitzat aquí.</string>
-    <string name="notice_direct_room_update_by_you">Ho has actualitzat aquí.</string>
-    <string name="key_verification_request_fallback_message">%s està sol·licitant la verificació de la teva clau, però el teu client no admet la verificació de clau des del xat. Hauràs d\'utilitzar la verificació de claus heretada per fer la verificació.</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Has activat el xifrat d\'extrem a extrem (algorisme %1$s no reconegut).</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s ha activat el xifrat d\'extrem a extrem (algorisme %2$s no reconegut).</string>
-    <string name="notice_end_to_end_ok_by_you">Has activat el xifrat d\'extrem a extrem.</string>
-    <string name="notice_end_to_end_ok">%1$s ha activat el xifrat d\'extrem a extrem.</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">Has impedit que els convidats es puguin unir a la sala.</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s ha impedit que els convidats es puguin unir a la sala.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">Has impedit que els convidats es puguin unir a la sala.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s ha impedit que els convidats es puguin unir a la sala.</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">Has permès que els convidats s\'uneixin aquí.</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s ha permès que els convidats s\'uneixin aquí.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Has permès que els convidats s\'uneixin a la sala.</string>
-    <string name="notice_room_guest_access_can_join">%1$s ha permès que els convidats s\'uneixin a la sala.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Has eliminat l\'adreça principal d\'aquesta sala.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s ha eliminat l\'adreça principal d\'aquesta sala.</string>
-    <string name="notice_room_canonical_alias_set_by_you">Has establert l\'adreça principal d\'aquesta sala a %1$s.</string>
-    <string name="notice_room_canonical_alias_set">%1$s ha establert l\'adreça principal d\'aquesta sala a %2$s.</string>
-    <string name="notice_room_aliases_added_and_removed_by_you">Has afegit %1$s i has eliminat %2$s d\'aquesta sala (adreces).</string>
-    <string name="notice_room_aliases_added_and_removed">%1$s ha afegit %2$s i ha eliminat %3$s d\'aquesta sala (adreces).</string>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">Has eliminat l\'adreça %1$s d\'aquesta sala.</item>
-        <item quantity="other">Has eliminat les adreces %1$s d\'aquesta sala.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s ha eliminat l\'adreça %2$s d\'aquesta sala.</item>
-        <item quantity="other">%1$s ha eliminat les adreces %3$s d\'aquesta sala.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">Has afegit l\'adreça %1$s a aquesta sala.</item>
-        <item quantity="other">Has afegit les adreces %1$s a aquesta sala.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s ha afegit l\'adreça %2$s a aquesta sala.</item>
-        <item quantity="other">%1$s ha afegit les adreces %2$s a aquesta sala.</item>
-    </plurals>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Has revocat la invitació de %1$s perquè s\'uneixi a la sala. Motiu: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s ha revocat la invitació de %2$s perquè s\'uneixi a la sala. Motiu: %3$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">Has revocat la invitació de %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s ha revocat la invitació de %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Has revocat la invitació de %1$s perquè s\'uneixi a la sala</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s ha revocat la invitació de %2$s perquè s\'uneixi a la sala</string>
-    <string name="notice_room_withdraw_with_reason_by_you">Has retirat la invitació de %1$s. Motiu: %2$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s ha retirat la invitació de %2$s. Motiu: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Has acceptat la invitació de %1$s. Motiu: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s ha acceptat la invitació de %2$s. Motiu: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Has enviat una invitació a %1$s perquè s\'uneixi a la sala. Motiu: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s ha enviat una invitació a %2$s perquè s\'uneixi a la sala. Motiu: %3$s</string>
-    <string name="notice_room_ban_with_reason_by_you">Has vetat %1$s. Motiu: %2$s</string>
-    <string name="notice_room_ban_with_reason">%1$s ha vetat %2$s. Motiu: %3$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Has tret el veto a %1$s. Motiu: %2$s</string>
-    <string name="notice_room_unban_with_reason">%1$s ha tret el veto a %2$s. Motiu: %3$s</string>
-    <string name="notice_room_ban_by_you">Has vetat %1$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Has marxat de la sala. Motiu: %1$s</string>
-    <string name="notice_room_leave_with_reason">%1$s ha marxat de la sala. Motiu: %2$s</string>
-    <string name="notice_direct_room_leave_by_you">Has marxat de la sala</string>
-    <string name="notice_direct_room_leave">%1$s ha marxat de la sala</string>
-    <string name="notice_room_leave_by_you">Has marxat de la sala</string>
-    <string name="notice_room_kick_by_you">Has expulsat %1$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Has expulsat %1$s. Motiu: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s ha expulsat %2$s. Motiu: %3$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Has rebutjat la invitació. Motiu: %1$s</string>
-    <string name="notice_room_reject_with_reason">%1$s ha rebutjat la invitació. Motiu: %2$s</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">Has marxat. Motiu: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s ha marxat. Motiu: %2$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">T\'has unit. Motiu: %1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s s\'ha unit. Motiu: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">T\'has unit a la sala. Motiu: %1$s</string>
-    <string name="notice_room_join_with_reason">%1$s s\'ha unit a la sala. Motiu: %2$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s t\'ha convidat. Motiu: %2$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Has convidat %1$s. Motiu: %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s ha convidat %2$s. Motiu: %3$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">La teva invitació. Motiu: %1$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason">la invitació de %1$s. Motiu: %2$s</string>
-    <string name="clear_timeline_send_queue">Esborra la cua d\'enviament</string>
-    <string name="event_status_sending_message">Enviant missatge…</string>
-    <string name="initial_sync_start_importing_account_data">Sincronització inicial:
-\nImportant dades del compte</string>
-    <string name="initial_sync_start_importing_account_groups">Sincronització inicial:
-\nImportant comunitats</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Sincronització inicial:
-\nImportant sales que deixat</string>
-    <string name="initial_sync_start_importing_account">Sincronització inicial:
-\nImportant compte…</string>
-    <string name="initial_sync_start_importing_account_crypto">Sincronització inicial:
-\nImportant xifrat</string>
-    <string name="initial_sync_start_importing_account_rooms">Sincronització inicial:
-\nImportant sales</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Sincronització inicial:
-\nImportant sales on hi estàs convidat</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Sincronització inicial:
-\nImportant sales on hi estàs unit</string>
-    <string name="notice_power_level_diff">%1$s de %2$s a %3$s</string>
-    <string name="notice_power_level_changed">%1$s ha canviat el nivell d\'autoritat de %2$s.</string>
-    <string name="notice_power_level_changed_by_you">Has canviat el nivell d\'autoritat de %1$s.</string>
-    <string name="power_level_custom_no_value">Personalitzat</string>
-    <string name="power_level_custom">Personalitzat (%1$d)</string>
-    <string name="power_level_default">Predeterminat</string>
-    <string name="power_level_moderator">Moderador</string>
-    <string name="power_level_admin">Administrador</string>
-    <string name="notice_widget_modified_by_you">Has modificat el giny %1$s</string>
-    <string name="notice_widget_modified">%1$s ha modificat el giny %2$s</string>
-    <string name="notice_widget_removed_by_you">Has eliminat el giny %1$s</string>
-    <string name="notice_widget_removed">%1$s ha eliminat el giny %2$s</string>
-    <string name="notice_widget_added_by_you">Has afegit el giny %1$s</string>
-    <string name="notice_widget_added">%1$s ha afegit el giny %2$s</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Has acceptat la invitació de %1$s</string>
-    <string name="notice_direct_room_third_party_invite_by_you">Has convidat a %1$s</string>
-    <string name="notice_direct_room_third_party_invite">%1$s ha convidat a %2$s</string>
-    <string name="notice_room_third_party_invite_by_you">Has enviat una invitació a %1$s perquè s\'uneixi a la sala</string>
-    <string name="notice_profile_change_redacted_by_you">Has actualitzat el teu perfil %1$s</string>
-    <string name="notice_event_redacted_by_with_reason">Missatge eliminat per %1$s [motiu: %2$s]</string>
-    <string name="notice_event_redacted_with_reason">Missatge eliminat [motiu: %1$s]</string>
-    <string name="notice_event_redacted_by">Missatge eliminat per %1$s</string>
-    <string name="notice_event_redacted">Missatge eliminat</string>
-    <string name="notice_room_avatar_removed_by_you">Has eliminat l\'avatar de la sala</string>
-    <string name="notice_room_avatar_removed">%1$s ha eliminat l\'avatar de la sala</string>
-    <string name="notice_room_topic_removed_by_you">Has eliminat el tema de la sala</string>
-    <string name="notice_room_name_removed_by_you">Has eliminat el nom de la sala</string>
-    <string name="notice_requested_voip_conference_by_you">Has sol·licitat una conferència VoIP</string>
-    <string name="notice_room_update_by_you">Has actualitzat aquesta sala.</string>
-    <string name="notice_room_update">%s ha actualitzat aquesta sala.</string>
-    <string name="notice_end_to_end_by_you">Has activat el xifrat d\'extrem a extrem (%1$s)</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">Has establert la visibilitat dels missatges futurs a %1$s</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s ha establert la visibilitat dels missatges futurs a %2$s</string>
-    <string name="notice_made_future_room_visibility_by_you">Has establert la visibilitat de l\'historial futur de la sala a %1$s</string>
-    <string name="notice_ended_call_by_you">Has finalitzat la trucada.</string>
-    <string name="notice_answered_call_by_you">Has respost a la trucada.</string>
-    <string name="notice_call_candidates_by_you">Has enviat dades per configurar la trucada.</string>
-    <string name="notice_call_candidates">%s ha enviat dades per configurar la trucada.</string>
-    <string name="notice_placed_voice_call_by_you">Has realitzat una trucada de veu.</string>
-    <string name="notice_placed_video_call_by_you">Has realitzat una videotrucada.</string>
-    <string name="notice_room_name_changed_by_you">Has canviat el nom de la sala a: %1$s</string>
-    <string name="notice_room_avatar_changed_by_you">Has canviat l\'avatar de la sala</string>
-    <string name="notice_room_avatar_changed">%1$s ha canviat l\'avatar de la sala</string>
-    <string name="notice_room_topic_changed_by_you">Has canviat el tema a: %1$s</string>
-    <string name="notice_display_name_removed_by_you">Has eliminat el teu nom de visualització (era %1$s)</string>
-    <string name="notice_display_name_changed_from_by_you">Has canviat el teu nom de visualització de %1$s a %2$s</string>
-    <string name="notice_display_name_set_by_you">Has canviat el teu nom de visualització a %1$s</string>
-    <string name="notice_avatar_url_changed_by_you">Has canviat el teu avatar</string>
-    <string name="notice_room_withdraw_by_you">Has retirat la invitació de %1$s</string>
-    <string name="notice_room_unban_by_you">Has tret el veto a %1$s</string>
-    <string name="notice_room_reject_by_you">Has rebutjat la invitació</string>
-    <string name="notice_direct_room_created_by_you">Has creat la discussió</string>
-    <string name="notice_direct_room_created">%1$s ha creat la discussió</string>
-    <string name="notice_direct_room_join_by_you">T\'has unit</string>
-    <string name="notice_direct_room_join">%1$s s\'ha unit</string>
-    <string name="notice_room_join_by_you">T\'has unit a la sala</string>
-    <string name="notice_room_invite_by_you">Has convidat a %1$s</string>
-    <string name="notice_room_created_by_you">Has creat la sala</string>
-    <string name="notice_room_created">%1$s ha creat la sala</string>
-    <string name="notice_room_invite_no_invitee_by_you">La teva invitació</string>
-    <string name="summary_you_sent_sticker">Has enviat un adhesiu.</string>
-    <string name="summary_you_sent_image">Has enviat una imatge.</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-cs/strings.xml b/matrix-sdk-android/src/main/res/values-cs/strings.xml
deleted file mode 100644
index adb35179279190c52c2b3c74d90b5591b0b414d5..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-cs/strings.xml
+++ /dev/null
@@ -1,271 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">Uživatel %1$s poslal obrázek.</string>
-    <string name="summary_user_sent_sticker">Uživatel %1$s poslal nálepku.</string>
-    <string name="notice_room_invite_no_invitee">Pozvání od uživatele %s</string>
-    <string name="notice_room_invite">Uživatel %1$s pozval uživatele %2$s</string>
-    <string name="notice_room_invite_you">Uživatel %1$s vás pozval</string>
-    <string name="notice_room_join">%1$s vstoupil do místnosti</string>
-    <string name="notice_room_leave">Uživatel %1$s odešel</string>
-    <string name="notice_room_reject">%1$s odmítli pozvání</string>
-    <string name="notice_room_kick">%1$s vykopli %2$s</string>
-    <string name="notice_room_unban">%1$s zrušil vykázání %2$s</string>
-    <string name="notice_room_ban">%1$s vykázali %2$s</string>
-    <string name="notice_room_withdraw">%1$s zrušili pozvání pro %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s změnili svůj profilový obrázek</string>
-    <string name="notice_display_name_set">%1$s nastavili své veřejné jméno na %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s změnili své veřejné jméno z %2$s na %3$s</string>
-    <string name="notice_display_name_removed">%1$s odstranili své veřejné jméno (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s změnili téma na: %2$s</string>
-    <string name="notice_room_name_changed">%1$s změnili název místnosti na: %2$s</string>
-    <string name="notice_placed_video_call">%s uskutečnili videohovor.</string>
-    <string name="notice_placed_voice_call">%s uskutečnili hlasový hovor.</string>
-    <string name="notice_answered_call">%s přijali hovor.</string>
-    <string name="notice_ended_call">%s ukončili hovor.</string>
-    <string name="notice_made_future_room_visibility">%1$s nastavili viditelnost budoucí historie místnosti pro %2$s</string>
-    <string name="notice_room_visibility_invited">všechny členy místnosti od chvíle, kdy budou pozváni.</string>
-    <string name="notice_room_visibility_joined">všechny členy místnosti od chvíle, kdy se připojí.</string>
-    <string name="notice_room_visibility_shared">všechny členy místnosti.</string>
-    <string name="notice_room_visibility_world_readable">kohokoliv.</string>
-    <string name="notice_room_visibility_unknown">neznámým (%s).</string>
-    <string name="notice_end_to_end">%1$s zapnuli end-to-end šifrování (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s požádali o VoIP konferenci</string>
-    <string name="notice_voip_started">Začala VoIP konference</string>
-    <string name="notice_voip_finished">VoIP konference skončila</string>
-    <string name="notice_avatar_changed_too">(profilový obrázek byl také změněn)</string>
-    <string name="notice_room_name_removed">%1$s odstranili název místnosti</string>
-    <string name="notice_room_topic_removed">%1$s odstranili téma místnosti</string>
-    <string name="notice_profile_change_redacted">%1$s aktualizovali svůj profil %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s do této místnosti pozvali %2$s</string>
-    <string name="notice_room_third_party_registered_invite">%1$s přijali pozvání pro %2$s</string>
-    <string name="notice_crypto_unable_to_decrypt">** Nelze dešifrovat: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Odesílatelovo zařízení nám neposlalo klíče pro tuto zprávu.</string>
-    <string name="could_not_redact">Nelze vymazat</string>
-    <string name="unable_to_send_message">Zprávu nelze odeslat</string>
-    <string name="message_failed_to_upload">Obrázek nelze nahrát</string>
-    <string name="network_error">Chyba sítě</string>
-    <string name="matrix_error">Chyba v Matrixu</string>
-    <string name="room_error_join_failed_empty_room">V současnosti není možné znovu vstoupit do prázdné místnosti.</string>
-    <string name="encrypted_message">Šifrovaná zpráva</string>
-    <string name="medium_email">E-mailová adresa</string>
-    <string name="medium_phone_number">Telefonní číslo</string>
-    <string name="room_displayname_invite_from">Pozvání od %s</string>
-    <string name="room_displayname_room_invite">Pozvání do místnosti</string>
-    <string name="room_displayname_two_members">%1$s a %2$s</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s a jeden další</item>
-        <item quantity="few">%1$s a %2$d další</item>
-        <item quantity="other">%1$s a %2$d dalších</item>
-    </plurals>
-    <string name="room_displayname_empty_room">Prázdná místnost</string>
-    <string name="notice_room_update">%s povýšili tuto místnost.</string>
-    <string name="notice_event_redacted_with_reason">Zpráva byla smazána [důvod: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Zpráva smazána uživatelem %1$s [důvod: %2$s]</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s zrušili pozvánku do místnosti pro %2$s</string>
-    <string name="initial_sync_start_importing_account">Úvodní synchronizace: 
-\nImportuji účet…</string>
-    <string name="initial_sync_start_importing_account_crypto">Úvodní synchronizace: 
-\nImportuji klíče</string>
-    <string name="initial_sync_start_importing_account_rooms">Úvodní synchronizace: 
-\nImportuji místnosti</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Úvodní synchronizace: 
-\nImportuji místností, jichž jste členy</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Úvodní synchronizace: 
-\nImportuji místnost, jež jste opustili</string>
-    <string name="initial_sync_start_importing_account_groups">Úvodní synchronizace: 
-\nImportuji komunity</string>
-    <string name="initial_sync_start_importing_account_data">Úvodní synchronizace: 
-\nImportuji data účtu</string>
-    <string name="event_status_sending_message">Odesílám zprávu…</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Úvodní synchronizace: 
-\nImportuji pozvání</string>
-    <string name="clear_timeline_send_queue">Vymazat frontu neodeslaných zpráv</string>
-    <string name="notice_room_invite_with_reason">%1$s pozvali %2$s. Důvod: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s vás pozvali. Důvod: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s opustil místnost. Důvod: %2$s</string>
-    <string name="notice_event_redacted">Zpráva odstraněna</string>
-    <string name="notice_event_redacted_by">Zprávu odstranil/a %1$s</string>
-    <string name="summary_you_sent_image">Poslali jste obrázek.</string>
-    <string name="summary_you_sent_sticker">Poslali jste nálepku.</string>
-    <string name="notice_room_invite_no_invitee_by_you">Vaše pozvání</string>
-    <string name="notice_room_created">%1$s založil místnost</string>
-    <string name="notice_room_created_by_you">Vy jste založili místnost</string>
-    <string name="notice_room_invite_by_you">Pozvali jste %1$s</string>
-    <string name="notice_room_join_by_you">Vstoupili jste do místnosti</string>
-    <string name="notice_room_leave_by_you">Opustili jste místnost</string>
-    <string name="notice_room_reject_by_you">Odmítli jste pozvání</string>
-    <string name="notice_room_kick_by_you">Vykopli jste %1$s</string>
-    <string name="notice_room_unban_by_you">Zrušili jste vykázání pro %1$s</string>
-    <string name="notice_room_ban_by_you">Vykázali jste %1$s</string>
-    <string name="notice_room_withdraw_by_you">Stáhli jste pozvánku od %1$s zpět</string>
-    <string name="notice_avatar_url_changed_by_you">Změnili jste svůj profilový obrázek</string>
-    <string name="notice_display_name_set_by_you">Změnili jste své veřejné jméno na %1$s</string>
-    <string name="notice_display_name_changed_from_by_you">Změnili jste své veřejné jméno z %1$s na %2$s</string>
-    <string name="notice_display_name_removed_by_you">Odstranili jste své veřejné jméno (%1$s)</string>
-    <string name="notice_room_topic_changed_by_you">Změnili jste téma na: %1$s</string>
-    <string name="notice_room_avatar_changed">%1$s změnili obrázek místnosti</string>
-    <string name="notice_room_avatar_changed_by_you">Změnili jste obrázek místnosti</string>
-    <string name="notice_room_name_changed_by_you">Změnili jste jméno místnosti na: %1$s</string>
-    <string name="notice_placed_video_call_by_you">Zahájili jste video hovor.</string>
-    <string name="notice_placed_voice_call_by_you">Zahájili jste hlasový hovor.</string>
-    <string name="notice_call_candidates">%s poslali data, aby mohli zahájit hovor.</string>
-    <string name="notice_call_candidates_by_you">Poslali jste data, abyste mohli zahájit hovor.</string>
-    <string name="notice_answered_call_by_you">Přijali jste hovor.</string>
-    <string name="notice_ended_call_by_you">Ukončili jste hovor.</string>
-    <string name="notice_made_future_room_visibility_by_you">Učinili jste budoucí historii místnosti viditelnou pro %1$s</string>
-    <string name="notice_end_to_end_by_you">Zapnuli jste end-to-end šifrování (%1$s)</string>
-    <string name="notice_room_update_by_you">Povýšili jste tuto místnost.</string>
-    <string name="notice_requested_voip_conference_by_you">Požádali jste o VoIP konferenci</string>
-    <string name="notice_room_name_removed_by_you">Odstranili jste jméno místnosti</string>
-    <string name="notice_room_topic_removed_by_you">Odstranili jste téma místnosti</string>
-    <string name="notice_room_avatar_removed">%1$s odstranili obrázek místnosti</string>
-    <string name="notice_room_avatar_removed_by_you">Odstranili jste obrázek místnosti</string>
-    <string name="notice_profile_change_redacted_by_you">Aktualizovali jste svů profil %1$s</string>
-    <string name="notice_room_third_party_invite_by_you">Poslali jste %1$s pozvání ke vstupu do místnosti</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Zrušili jste pozvánku ke vstupu do místnosti pro %1$s</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Přijali jste pozvání pro %1$s</string>
-    <string name="notice_widget_added">%1$s přidali widget %2$s</string>
-    <string name="notice_widget_added_by_you">Přidali jste widget %1$s</string>
-    <string name="notice_widget_removed">%1$s odstranili widget %2$s</string>
-    <string name="notice_widget_removed_by_you">Odstranili jste widget %1$s</string>
-    <string name="notice_widget_modified">%1$s změnil widget %2$s</string>
-    <string name="notice_widget_modified_by_you">Změnili jste widget %1$s</string>
-    <string name="power_level_admin">Správce</string>
-    <string name="power_level_moderator">Moderátor</string>
-    <string name="power_level_default">Výchozí</string>
-    <string name="power_level_custom">Vlastní (%1$d)</string>
-    <string name="power_level_custom_no_value">Vlastní</string>
-    <string name="notice_power_level_changed_by_you">Změnili jste %1$s stupeň oprávnění.</string>
-    <string name="notice_power_level_changed">%1$s změnili %2$s stupeň oprávnění.</string>
-    <string name="notice_power_level_diff">%1$s z %2$s na %3$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason">Pozvání od %1$s. Důvod: %2$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">Vaše pozvání. Důvod: %1$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Pozvali jste %1$s. Důvod: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s vstoupili do místnosti. Důvod: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">Vstoupili jste do místnosti. Důvod: %1$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Opustili jste místnost. Důvod: %1$s</string>
-    <string name="notice_room_reject_with_reason">%1$s pozvání odmítli. Důvod: %2$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Odmítli jste pozvání. Důvod: %1$s</string>
-    <string name="notice_room_kick_with_reason">%1$s vykopnuli %2$s. Důvod: %3$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Vykopnuli jste %1$s. Důvod: %2$s</string>
-    <string name="notice_room_unban_with_reason">%1$s zrušili %2$s vykázání. Důvod: %3$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Zrušili jste %1$s vykázání. Důvod: %2$s</string>
-    <string name="notice_room_ban_with_reason">%1$s vykázali %2$s. Důvod: %3$s</string>
-    <string name="notice_room_ban_with_reason_by_you">Vykázali jste %1$s. Důvod: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s poslali %2$s pozvání, aby vstoupili do místnosti. Důvod: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Poslali jste %1$s pozvání, aby vstoupili do místnosti. Důvod: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s zrušili pozvání do místnosti pro %2$s. Důvod: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Zrušili jste pozvání do místnosti pro %1$s. Důvod: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s přijali pozvání pro %2$s. Důvod: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Přijali jste pozvání pro %1$s. Důvod: %2$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s zrušili pozvání pro %2$s. Důvod: %3$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">Zrušili jste pozvání od %1$s. Důvod: %2$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s přidali %2$s jako adresu pro tuto místnost.</item>
-        <item quantity="few">%1$s přidali %2$s jako adresy pro tuto místnost.</item>
-        <item quantity="other">%1$s přidali %2$s jako adresy pro tuto místnost.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">Přidali jste %1$s jako adresu pro tuto místnost.</item>
-        <item quantity="few">Přidali jste %1$s jako adresy pro tuto místnost.</item>
-        <item quantity="other">Přidali jste %1$s jako adresy pro tuto místnost.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s odstranili %2$s jako adresu pro tuto místnost.</item>
-        <item quantity="few">%1$s odstranili %2$s jako adresy pro tuto místnost.</item>
-        <item quantity="other">%1$s odstranili %2$s jako adresy pro tuto místnost.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">Odstranili jste %1$s jako adresu pro tuto místnost.</item>
-        <item quantity="few">Odstranili jste %1$s jako adresuy pro tuto místnost.</item>
-        <item quantity="other">Odstranili jste %1$s jako adresy pro tuto místnost.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s přidali %2$s a odstranili %3$s jako adresy pro tuto místnost.</string>
-    <string name="notice_room_aliases_added_and_removed_by_you">Přidali jste %1$s a odstranili %2$s jako adresy pro tuto místnost.</string>
-    <string name="notice_room_canonical_alias_set">%1$s nastavili hlavní adresu této místnosti na %2$s.</string>
-    <string name="notice_room_canonical_alias_set_by_you">Nastavili jste %1$s na hlavní adresu této místnosti.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s odstranili hlavní adresu této místnosti.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Odstranili jste hlavní adresu této místnosti.</string>
-    <string name="notice_room_guest_access_can_join">%1$s povolili hostům vstoupit do místnosti.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Povolili jste hostům vstoupit do místnosti.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s zamezili hostům vstoupit do místnosti.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">Zamezili jste hostům vstoupit do místnosti.</string>
-    <string name="notice_end_to_end_ok">%1$s zapnuli end-to-end šifrování.</string>
-    <string name="notice_end_to_end_ok_by_you">Zapnuli jste end-to-end šifrování.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s zapnuli end-to-end šifrování (neznámý algoritmus %2$s).</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Zapnuli jste end-to-end šifrování (neznámý algoritmus %1$s).</string>
-    <string name="key_verification_request_fallback_message">%s žádá ověření Vašeho klíče, ale Váš klient nepodporuje ověření klíče v chatu. Budete muset k ověření klíčů použít zastaralý způsob ověření.</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">Zamezili jste hostům vstoupit do této místnosti.</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s zamezil hostům vstoupit do této místnosti.</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">Povolili jste hostům vstoupit.</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s povolil hostům vstoupit.</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">Odešli jste. Důvod: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s odešli. Důvod: %2$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">Vstoupili jste. Důvod: %1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s vstoupili. Důvod: %2$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">Vy jste zrušili pozvání pro %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s zrušili pozvání pro %2$s</string>
-    <string name="notice_direct_room_third_party_invite_by_you">Vy jste pozvali %1$s</string>
-    <string name="notice_direct_room_third_party_invite">%1$s pozvali %2$s</string>
-    <string name="notice_direct_room_update_by_you">Vy jste tady provedli upgrade.</string>
-    <string name="notice_direct_room_update">%s tady provedli upgrade.</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">Učinili jste budoucí zprávy viditelné pro %1$s</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s učinili budoucí zprávy viditelné pro %2$s</string>
-    <string name="notice_direct_room_leave_by_you">Odešli jste z místnosti</string>
-    <string name="notice_direct_room_leave">%1$s odešli z místnosti</string>
-    <string name="notice_direct_room_join_by_you">Vstoupili jste</string>
-    <string name="notice_direct_room_join">%1$s vstoupili</string>
-    <string name="notice_direct_room_created_by_you">Založili jste diskusi</string>
-    <string name="notice_direct_room_created">%1$s založil diskusi</string>
-    <string name="room_displayname_empty_room_was">Prázdná místnost (byla %s)</string>
-    <plurals name="room_displayname_four_and_more_members">
-        <item quantity="one">%1$s, %2$s, %3$s a %4$d další</item>
-        <item quantity="few">%1$s, %2$s, %3$s a %4$d další</item>
-        <item quantity="other">%1$s, %2$s, %3$s a %4$d dalších</item>
-    </plurals>
-    <string name="room_displayname_4_members">%1$s, %2$s, %3$s a %4$s</string>
-    <string name="room_displayname_3_members">%1$s, %2$s a %3$s</string>
-    <string name="notice_room_server_acl_allow_is_empty">🎉 Účast všech serverů je zakázána! Tuto místnost již nelze použít.</string>
-    <string name="notice_room_server_acl_updated_no_change">Beze změny.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_not_allowed">• Servery shodující se doslovně s IP jsou nyní zakázány.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_allowed">• Servery shodující se doslovně s IP jsou nyní povoleny.</string>
-    <string name="notice_room_server_acl_updated_was_allowed">• Servery shodující se s %s byly odstraněny ze seznamu povolených.</string>
-    <string name="notice_room_server_acl_updated_allowed">• Servery shodující se s %s jsou nyní povoleny.</string>
-    <string name="notice_room_server_acl_updated_was_banned">• Servery shodující se s %s byly odstraněny ze seznamu zakázaných.</string>
-    <string name="notice_room_server_acl_updated_banned">• Servery shodující se s %s jsou nyní zakázány.</string>
-    <string name="notice_room_server_acl_updated_title_by_you">Změnili jste ACL serveru pro tuto místnost.</string>
-    <string name="notice_room_server_acl_updated_title">%s změnili ACL serveru pro tuto místnost.</string>
-    <string name="notice_room_server_acl_set_ip_literals_allowed">• Server shodující se doslovně s IP je povolen.</string>
-    <string name="notice_room_server_acl_set_ip_literals_not_allowed">• Server shodující se doslovně s IP je zakázán.</string>
-    <string name="notice_room_server_acl_set_allowed">• Server shodující se s %s je povolen.</string>
-    <string name="notice_room_server_acl_set_banned">• Server shodující se s %s je zakázán.</string>
-    <string name="notice_room_server_acl_set_title_by_you">Nastavili jste ACL serveru pro tuto místnost.</string>
-    <string name="notice_room_server_acl_set_title">%s nastavili ACL serveru pro tuto místnost.</string>
-    <string name="notice_room_canonical_alias_no_change_by_you">Změnili jste adresy pro tuto místnost.</string>
-    <string name="notice_room_canonical_alias_no_change">%1$s změnili adresy pro tuto místnost.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed_by_you">Změnili jste hlavní a alternativní adresu pro tuto místnost.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed">%1$s změnili hlavní a alternativní adresu pro tuto místnost.</string>
-    <string name="notice_room_canonical_alias_alternative_changed_by_you">Změnili jste alternativní adresu pro tuto místnost.</string>
-    <string name="notice_room_canonical_alias_alternative_changed">%1$s změnili alternativní adresu pro tuto místnost.</string>
-    <plurals name="notice_room_canonical_alias_alternative_removed_by_you">
-        <item quantity="one">Odstranili jste alternativní adresu %1$s pro tuto místnost.</item>
-        <item quantity="few">Odstranili jste alternativní adresy %1$s pro tuto místnost.</item>
-        <item quantity="other">Odstranili jste alternativní adresy %1$s pro tuto místnost.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_removed">
-        <item quantity="one">%1$s odstranili alternativní adresu %2$s pro tuto místnost.</item>
-        <item quantity="few">%1$s odstranili alternativní adresy %2$s pro tuto místnost.</item>
-        <item quantity="other">%1$s odstranili alternativní adresy %2$s pro tuto místnost.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added_by_you">
-        <item quantity="one">Přidali jste alternativní adresu %1$s pro tuto místnost.</item>
-        <item quantity="few">Přidali jste alternativní adresy %1$s pro tuto místnost.</item>
-        <item quantity="other">Přidali jste alternativní adresy %1$s pro tuto místnost.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added">
-        <item quantity="one">%1$s přidali alternativní adresu %2$s pro tuto místnost.</item>
-        <item quantity="few">%1$s přidali alternativní adresy %2$s pro tuto místnost.</item>
-        <item quantity="other">%1$s přidali alternativní adresy %2$s pro tuto místnost.</item>
-    </plurals>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-cs/strings_sas.xml b/matrix-sdk-android/src/main/res/values-cs/strings_sas.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1ef9d56f609a9c2456d6ae519f05af2b367fc61a
--- /dev/null
+++ b/matrix-sdk-android/src/main/res/values-cs/strings_sas.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- Generated file, do not edit -->
+    <string name="verification_emoji_dog">Pes</string>
+    <string name="verification_emoji_cat">Kočka</string>
+    <string name="verification_emoji_lion">Lev</string>
+    <string name="verification_emoji_horse">Kůň</string>
+    <string name="verification_emoji_unicorn">Jednorožec</string>
+    <string name="verification_emoji_pig">Prase</string>
+    <string name="verification_emoji_elephant">Slon</string>
+    <string name="verification_emoji_rabbit">Králík</string>
+    <string name="verification_emoji_panda">Panda</string>
+    <string name="verification_emoji_rooster">Kohout</string>
+    <string name="verification_emoji_penguin">Tučňák</string>
+    <string name="verification_emoji_turtle">Želva</string>
+    <string name="verification_emoji_fish">Ryba</string>
+    <string name="verification_emoji_octopus">Chobotnice</string>
+    <string name="verification_emoji_butterfly">Motýl</string>
+    <string name="verification_emoji_flower">Květina</string>
+    <string name="verification_emoji_tree">Strom</string>
+    <string name="verification_emoji_cactus">Kaktus</string>
+    <string name="verification_emoji_mushroom">Houba</string>
+    <string name="verification_emoji_globe">Zeměkoule</string>
+    <string name="verification_emoji_moon">Měsíc</string>
+    <string name="verification_emoji_cloud">Mrak</string>
+    <string name="verification_emoji_fire">Oheň</string>
+    <string name="verification_emoji_banana">Banán</string>
+    <string name="verification_emoji_apple">Jablko</string>
+    <string name="verification_emoji_strawberry">Jahoda</string>
+    <string name="verification_emoji_corn">Kukuřice</string>
+    <string name="verification_emoji_pizza">Pizza</string>
+    <string name="verification_emoji_cake">Dort</string>
+    <string name="verification_emoji_heart">Srdce</string>
+    <string name="verification_emoji_smiley">Smajlík</string>
+    <string name="verification_emoji_robot">Robot</string>
+    <string name="verification_emoji_hat">Klobouk</string>
+    <string name="verification_emoji_glasses">Brýle</string>
+    <string name="verification_emoji_spanner">Klíč</string>
+    <string name="verification_emoji_santa">Mikuláš</string>
+    <string name="verification_emoji_thumbs_up">Palec nahoru</string>
+    <string name="verification_emoji_umbrella">Deštník</string>
+    <string name="verification_emoji_hourglass">Přesýpací hodiny</string>
+    <string name="verification_emoji_clock">Hodiny</string>
+    <string name="verification_emoji_gift">Dárek</string>
+    <string name="verification_emoji_light_bulb">Žárovka</string>
+    <string name="verification_emoji_book">Kniha</string>
+    <string name="verification_emoji_pencil">Tužka</string>
+    <string name="verification_emoji_paperclip">Sponka</string>
+    <string name="verification_emoji_scissors">Nůžky</string>
+    <string name="verification_emoji_lock">Zámek</string>
+    <string name="verification_emoji_key">Klíč</string>
+    <string name="verification_emoji_hammer">Kladivo</string>
+    <string name="verification_emoji_telephone">Telefon</string>
+    <string name="verification_emoji_flag">Vlajka</string>
+    <string name="verification_emoji_train">Vlak</string>
+    <string name="verification_emoji_bicycle">Kolo</string>
+    <string name="verification_emoji_aeroplane">Letadlo</string>
+    <string name="verification_emoji_rocket">Raketa</string>
+    <string name="verification_emoji_trophy">Pohár</string>
+    <string name="verification_emoji_ball">Míč</string>
+    <string name="verification_emoji_guitar">Kytara</string>
+    <string name="verification_emoji_trumpet">Trumpeta</string>
+    <string name="verification_emoji_bell">Zvonek</string>
+    <string name="verification_emoji_anchor">Kotva</string>
+    <string name="verification_emoji_headphones">Sluchátka</string>
+    <string name="verification_emoji_folder">Složka</string>
+    <string name="verification_emoji_pin">Špendlík</string>
+</resources>
diff --git a/matrix-sdk-android/src/main/res/values-da/strings.xml b/matrix-sdk-android/src/main/res/values-da/strings.xml
deleted file mode 100644
index 510fa231afe3660cd953d0a4ed85f98a242480bb..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-da/strings.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s sendte et billede.</string>
-
-    <string name="notice_room_invite_no_invitee">%ss invitation</string>
-    <string name="notice_room_invite">%1$s inviterede %2$s</string>
-    <string name="notice_room_invite_you">%1$s inviterede dig</string>
-    <string name="notice_room_join">%1$s forbandt</string>
-    <string name="notice_room_leave">%1$s forlod rummet</string>
-    <string name="notice_room_reject">%1$s afviste invitationen</string>
-    <string name="notice_room_kick">%1$s kickede %2$s</string>
-    <string name="notice_room_unban">%1$s unbannede %2$s</string>
-    <string name="notice_room_ban">%1$s bannede %2$s</string>
-    <string name="notice_room_withdraw">%1$s trak %2$ss invitation tilbage</string>
-    <string name="notice_avatar_url_changed">%1$s skiftede sin avatar</string>
-    <string name="notice_display_name_set">%1$s satte sit viste navn til %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s ændrede sit viste navn fra %2$s til %3$s</string>
-    <string name="notice_display_name_removed">%1$s fjernede sit viste navn (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s ændrede emnet til: %2$s</string>
-    <string name="notice_room_name_changed">%1$s ændrede rumnavnet til: %2$s</string>
-    <string name="notice_placed_video_call">%s startede et videoopkald.</string>
-    <string name="notice_placed_voice_call">%s startede et stemmeopkald.</string>
-    <string name="notice_answered_call">%s svarede opkaldet.</string>
-    <string name="notice_ended_call">%s stoppede opkaldet.</string>
-    <string name="notice_made_future_room_visibility">%1$s gjorde den fremtidige rum historik synlig for %2$s</string>
-    <string name="notice_room_visibility_invited">alle medlemmer af rummet, fra det tidspunkt de er inviteret.</string>
-    <string name="notice_room_visibility_joined">alle medlemmer af rummet, fra det tidspunkt de er forbundede.</string>
-    <string name="notice_room_visibility_shared">Alle medlemmer af rummet.</string>
-    <string name="notice_room_visibility_world_readable">alle.</string>
-    <string name="notice_room_visibility_unknown">ukendt (%s).</string>
-    <string name="notice_end_to_end">%1$s slog ende-til-ende kryptering til (%2$s)</string>
-
-    <string name="notice_requested_voip_conference">%1$s forespurgte en VoIP konference</string>
-    <string name="notice_voip_started">VoIP konference startet</string>
-    <string name="notice_voip_finished">VoIP konference afsluttet</string>
-
-    <string name="notice_avatar_changed_too">(avatar blev også ændret)</string>
-    <string name="notice_room_name_removed">%1$s fjernede navnet på rummet</string>
-    <string name="notice_room_topic_removed">%1$s fjernede emnet for rummet</string>
-    <string name="notice_profile_change_redacted">%1$s opdaterede sin profil %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s inviterede %2$s til rummet</string>
-    <string name="notice_room_third_party_registered_invite">%1$s accepterede invitationen til %2$s</string>
-
-    <string name="notice_crypto_unable_to_decrypt">** Kunne ikke dekryptere: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Afsenderens enhed har ikke sendt os nøglerne til denne besked.</string>
-
-    <string name="could_not_redact">Kunne ikke hemmeligholde</string>
-    <string name="unable_to_send_message">Kunne ikke sende besked</string>
-
-    <string name="message_failed_to_upload">Kunne ikke uploade billede</string>
-
-    <string name="network_error">Netværks fejl</string>
-    <string name="matrix_error">Matrix fejl</string>
-
-    <string name="room_error_join_failed_empty_room">Det er i øjeblikket ikke muligt at genforbinde til et tomt rum.</string>
-
-    <string name="encrypted_message">Krypteret besked</string>
-
-    <string name="medium_email">mailadresse</string>
-    <string name="medium_phone_number">Telefonnummer</string>
-
-    <string name="room_displayname_invite_from">Invitation fra %s</string>
-    <string name="room_displayname_room_invite">Invitation til rum</string>
-    <string name="room_displayname_two_members">%1$s og %2$s</string>
-
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s og 1 anden</item>
-        <item quantity="other">%1$s og %2$d andre</item>
-    </plurals>
-
-    <string name="room_displayname_empty_room">Tomt rum</string>
-
-</resources>
diff --git a/matrix-sdk-android/src/main/res/values-de/strings.xml b/matrix-sdk-android/src/main/res/values-de/strings.xml
deleted file mode 100644
index bdeeafccb6825e90ff655e9c6be63d47ee3a7ea0..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-de/strings.xml
+++ /dev/null
@@ -1,224 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s hat ein Bild gesendet.</string>
-    <string name="notice_room_invite_no_invitee">Einladung von %s</string>
-    <string name="notice_room_invite">%1$s hat %2$s eingeladen</string>
-    <string name="notice_room_invite_you">%1$s hat dich eingeladen</string>
-    <string name="notice_room_join">%1$s hat den Raum betreten</string>
-    <string name="notice_room_leave">%1$s hat den Raum verlassen</string>
-    <string name="notice_room_reject">%1$s hat die Einladung abgelehnt</string>
-    <string name="notice_room_kick">%1$s hat %2$s gekickt</string>
-    <string name="notice_room_unban">%1$s hat die Sperre von %2$s aufgehoben</string>
-    <string name="notice_room_ban">%1$s hat %2$s verbannt</string>
-    <string name="notice_room_withdraw">%1$s hat die Einladung für %2$s zurückgezogen</string>
-    <string name="notice_avatar_url_changed">%1$s hat das Profilbild geändert</string>
-    <string name="notice_display_name_set">%1$s hat den Anzeigenamen geändert in %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s hat den Anzeigenamen von %2$s auf %3$s geändert</string>
-    <string name="notice_display_name_removed">%1$s hat den Anzeigenamen gelöscht (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s hat das Raumthema geändert auf: %2$s</string>
-    <string name="notice_room_name_changed">%1$s hat den Raumnamen geändert in: %2$s</string>
-    <string name="notice_placed_video_call">%s hat einen Videoanruf durchgeführt.</string>
-    <string name="notice_placed_voice_call">%s hat einen Sprachanruf getätigt.</string>
-    <string name="notice_answered_call">%s hat den Anruf angenommen.</string>
-    <string name="notice_ended_call">%s hat den Anruf beendet.</string>
-    <string name="notice_made_future_room_visibility">%1$s hat den zukünftigen Chatverlauf sichtbar gemacht für %2$s</string>
-    <string name="notice_room_visibility_invited">Alle Mitglieder (ab dem Zeitpunkt, an dem sie eingeladen wurden).</string>
-    <string name="notice_room_visibility_joined">Alle Mitglieder (ab dem Zeitpunkt, an dem sie den Raum betreten haben).</string>
-    <string name="notice_room_visibility_shared">alle Raum-Mitglieder.</string>
-    <string name="notice_room_visibility_world_readable">Jeder.</string>
-    <string name="notice_room_visibility_unknown">Unbekannt (%s).</string>
-    <string name="notice_end_to_end">%1$s hat die Ende-zu-Ende-Verschlüsselung aktiviert (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s möchte eine VoIP-Konferenz beginnen</string>
-    <string name="notice_voip_started">VoIP-Konferenz gestartet</string>
-    <string name="notice_voip_finished">VoIP-Konferenz beendet</string>
-    <string name="notice_avatar_changed_too">(Profilbild wurde ebenfalls geändert)</string>
-    <string name="notice_room_name_removed">%1$s hat den Raumnamen entfernt</string>
-    <string name="notice_room_topic_removed">%1$s hat das Raum-Thema entfernt</string>
-    <string name="notice_profile_change_redacted">%1$s hat das Benutzerprofil aktualisiert %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s hat eine Einladung an %2$s gesendet</string>
-    <string name="notice_room_third_party_registered_invite">%1$s hat die Einladung in %2$s akzeptiert</string>
-    <string name="notice_crypto_unable_to_decrypt">** Nicht entschlüsselbar: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Das absendende Gerät hat uns keine Schlüssel für diese Nachricht übermittelt.</string>
-    <!-- Room Screen -->
-    <string name="could_not_redact">Entfernen nicht möglich</string>
-    <string name="unable_to_send_message">Nachricht kann nicht gesendet werden</string>
-    <string name="message_failed_to_upload">Bild konnte nicht hochgeladen werden</string>
-    <!-- general errors -->
-    <string name="network_error">Netzwerk-Fehler</string>
-    <string name="matrix_error">Matrix-Fehler</string>
-    <!-- Home Screen -->
-    <!-- Last seen time -->
-    <!-- call events -->
-    <!-- room error messages -->
-    <string name="room_error_join_failed_empty_room">Es ist aktuell nicht möglich, einen leeren Raum erneut zu betreten.</string>
-    <string name="encrypted_message">Verschlüsselte Nachricht</string>
-    <!-- medium friendly name -->
-    <string name="medium_email">E-Mail-Adresse</string>
-    <string name="medium_phone_number">Telefonnummer</string>
-    <string name="summary_user_sent_sticker">%1$s hat einen Sticker gesendet.</string>
-    <!-- Room display name -->
-    <string name="room_displayname_invite_from">Einladung von %s</string>
-    <string name="room_displayname_room_invite">Raumeinladung</string>
-    <string name="room_displayname_two_members">%1$s und %2$s</string>
-    <string name="room_displayname_empty_room">Leerer Raum</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s und 1 andere(r)</item>
-        <item quantity="other">%1$s und %2$d andere</item>
-    </plurals>
-    <string name="notice_event_redacted">Nachricht entfernt</string>
-    <string name="notice_event_redacted_by">Nachricht entfernt von %1$s</string>
-    <string name="notice_event_redacted_with_reason">Nachricht entfernt [Grund: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Nachricht entfernt von %1$s [Grund: %2$s]</string>
-    <string name="notice_room_update">%s hat diesen Raum aufgewertet.</string>
-    <string name="event_status_sending_message">Sende eine Nachricht…</string>
-    <string name="clear_timeline_send_queue">Sendewarteschlange leeren</string>
-    <string name="initial_sync_start_importing_account">Erste Synchronisation: 
-\nImportiere Benutzerkonto…</string>
-    <string name="initial_sync_start_importing_account_crypto">Erste Synchronisation: 
-\nImportiere Cryptoschlüssel</string>
-    <string name="initial_sync_start_importing_account_rooms">Erste Synchronisation: 
-\nImportiere Räume</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Erste Synchronisation: 
-\nImportiere betretene Räume</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Erste Synchronisation: 
-\nImportiere eingeladene Räume</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Erste Synchronisation: 
-\nImportiere verlassene Räume</string>
-    <string name="initial_sync_start_importing_account_groups">Erste Synchronisation: 
-\nImportiere Communities</string>
-    <string name="initial_sync_start_importing_account_data">Erste Synchronisation: 
-\nImportiere Benutzerdaten</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s hat die Einladung an %2$s, den Raum zu betreten, zurückgezogen</string>
-    <string name="notice_room_invite_no_invitee_with_reason">%1$s\'s Einladung. Grund: %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s hat %2$s eingeladen. Grund: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s hat dich eingeladen. Grund: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s ist dem Raum beigetreten. Grund: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s hat den Raum verlassen. Grund: %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s hat die Einladung abgelehnt. Grund: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s hat %2$s gekickt. Grund: %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s hat Sperre von %2$s aufgehoben. Grund: %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s hat %2$s verbannt. Grund: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s hat eine Einladung an %2$s gesandt um diesem Raum beizutreten. Grund: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s hat Einladung an %2$s zu Betreten dieses Raumes zurückgezogen. Grund: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s hat die Einladung für %2$s angenommen. Grund: %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s hat Einladung für %2$s verworfen. Grund: %3$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s fügt %2$s als eine Adresse für diesen Raum hinzu.</item>
-        <item quantity="other">%1$s fügt %2$s als Adressen für diesen Raum hinzu.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s entfernt %2$s als eine Adresse für diesen Raum.</item>
-        <item quantity="other">%1$s entfernt %2$s als Adressen für diesen Raum.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s fügt %2$s als Adresse für diesen Raum hinzu und entfernt %3$s.</string>
-    <string name="notice_room_canonical_alias_set">%1$s legt die Hauptadresse fest für diesen Raum als %2$s fest.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s entfernt die Hauptadresse für diesen Raum.</string>
-    <string name="notice_room_guest_access_can_join">%1$s hat Gästen erlaubt den Raum zu betreten.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s hat Gästen untersagt den Raum zu betreten.</string>
-    <string name="notice_end_to_end_ok">%1$s aktivierte Ende-zu-Ende-Verschlüsselung.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s aktivierte Ende-zu-Ende-Verschlüsselung (unbekannter Algorithmus %2$s).</string>
-    <string name="key_verification_request_fallback_message">%s fordert zur Überprüfung deines Schlüssels auf, jedoch unterstützt dein Client nicht die Schlüsselüberprüfung im Chat. Du musst die herkömmliche Schlüsselüberprüfung verwenden, um die Schlüssel zu überprüfen.</string>
-    <string name="summary_you_sent_image">Du hast ein Bild gesendet.</string>
-    <string name="summary_you_sent_sticker">Du hast einen Sticker gesendet.</string>
-    <string name="notice_room_invite_no_invitee_by_you">Deine Einladung</string>
-    <string name="notice_room_created">%1$s hat den Raum erstellt</string>
-    <string name="notice_room_created_by_you">Du hast den Raum erstellt</string>
-    <string name="notice_room_invite_by_you">Du hast %1$s eingeladen</string>
-    <string name="notice_room_join_by_you">Du bist dem Raum beigetreten</string>
-    <string name="notice_room_leave_by_you">Du hast den Raum verlassen</string>
-    <string name="notice_room_reject_by_you">Du hast die Einladung abgelehnt</string>
-    <string name="notice_room_kick_by_you">Du hast %1$s aus dem Raum entfernt</string>
-    <string name="notice_room_unban_by_you">Du hast den Bann von %1$s aufgehoben</string>
-    <string name="notice_room_ban_by_you">Du hast %1$s gebannt</string>
-    <string name="notice_room_withdraw_by_you">Du hast die Einladung von %1$s zurückgenommen</string>
-    <string name="notice_avatar_url_changed_by_you">Du hast dein Profilbild geändert</string>
-    <string name="notice_display_name_set_by_you">Du hast deinen Anzeigenamen zu %1$s geändert</string>
-    <string name="notice_display_name_changed_from_by_you">Du hast deinen Anzeigenamen von %1$s zu %2$s geändert</string>
-    <string name="notice_display_name_removed_by_you">Du hast deinen Anzeigenamen entfernt (er war %1$s)</string>
-    <string name="notice_room_topic_changed_by_you">Du hast das Thema geändert auf: %1$s</string>
-    <string name="notice_room_avatar_changed">%1$s hat das Bild des Raumes geändert</string>
-    <string name="notice_room_avatar_changed_by_you">Du hast das Bild des Raumes geändert</string>
-    <string name="notice_room_name_changed_by_you">Du hast den Raumnamen zu %1$s geändert</string>
-    <string name="notice_placed_video_call_by_you">Du hast einen Videoanruf gestartet.</string>
-    <string name="notice_placed_voice_call_by_you">Du hast einen Audioanruf gestartet.</string>
-    <string name="notice_answered_call_by_you">Du hast den Anruf angenommen.</string>
-    <string name="notice_ended_call_by_you">Du hast den Anruf beendet.</string>
-    <string name="notice_made_future_room_visibility_by_you">Du hast den zukünftigen Nachrichtenverlauf für %1$s sichtbar gemacht</string>
-    <string name="notice_end_to_end_by_you">Du hast Ende-zu-Ende-Verschlüsselung aktiviert (%1$s)</string>
-    <string name="notice_room_update_by_you">Du hast den Raum aufgwertet.</string>
-    <string name="notice_requested_voip_conference_by_you">Du hast eine VoIP-Konferenz angefordert</string>
-    <string name="notice_room_name_removed_by_you">Du hast den Raumnamen entfernt</string>
-    <string name="notice_room_topic_removed_by_you">Du hast das Raumthema entfernt</string>
-    <string name="notice_room_avatar_removed">%1$s hat das Bild des Raumes entfernt</string>
-    <string name="notice_room_avatar_removed_by_you">Du hast das Bild des Raumes entfernt</string>
-    <string name="notice_profile_change_redacted_by_you">Du hast dein Profil %1$s aktualisiert</string>
-    <string name="notice_room_third_party_invite_by_you">Du hast %1$s in den Raum eingeladen</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Du hast die Einladung für %1$s zurückgenommen</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Du hast die Einladung für %1$s akzeptiert</string>
-    <string name="notice_widget_added">%1$s hat das %2$s Widget hinzugefügt</string>
-    <string name="notice_widget_added_by_you">Du hast das %1$s Widget hinzugefügt</string>
-    <string name="notice_widget_removed">%1$s hat das %2$s Widget entfernt</string>
-    <string name="notice_widget_removed_by_you">Du hast das %1$s Widget entfernt</string>
-    <string name="notice_widget_modified">%1$s hat das %2$s Widget modifiziert</string>
-    <string name="notice_widget_modified_by_you">Du hast das %1$s Widget modifiziert</string>
-    <string name="power_level_admin">Administrator</string>
-    <string name="power_level_moderator">Moderator</string>
-    <string name="power_level_default">Standard</string>
-    <string name="power_level_custom">Benutzerdefiniert (%1$d)</string>
-    <string name="power_level_custom_no_value">Benutzerdefiniert</string>
-    <string name="notice_power_level_changed_by_you">Du hast die Berechtigungsstufe von %1$s geändert.</string>
-    <string name="notice_power_level_changed">%1$s hat die Berechtigungsstufe von %2$s geändert.</string>
-    <string name="notice_power_level_diff">%1$s von %2$s zu %3$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">Deine Einladung. Grund: %1$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Du hast %1$s eingeladen. Grund: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">Du bist dem Raum beigetreten. Grund: %1$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Du hast den Raum verlassen. Grund: %1$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Du hast die Einladung abgelehnt. Grund: %1$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Du hast %1$s aus dem Raum entfernt. Grund %2$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Du hast den Bann von %1$s aufgehoben. Grund: %2$s</string>
-    <string name="notice_room_ban_with_reason_by_you">Du hast %1$s gebannt. Grund: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Du hast %1$s in den Raum eingeladen. Grund: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Du hast die Einladung für %1$s zurückgenommen. Grund: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Du hast die Einladung von %1$s angenommen. Grund: %2$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">Du hast die Einladung von %1$s abgelehnt. Grund: %2$s</string>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">Du hast die Raumaddresse %1$s hinzugefügt.</item>
-        <item quantity="other">Du hast die Raumaddressen %1$s hinzugefügt.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">Du hast die Raum-Adresse %1$s vom Raum entfernt.</item>
-        <item quantity="other">Du hast die Raum-Adressen %1$s vom Raum entfernt.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed_by_you">Du hast den Raumaddressen %1$s hinzugefügt und %2$s entfernt.</string>
-    <string name="notice_room_canonical_alias_set_by_you">Du hast die Hauptaddresse für diesen Raum auf %1$s gesetzt.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Du hast die Hauptaddresse des Raums entfernt.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Du hast Gästen erlaubt dem Raum beizutreten.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">Du hast Gästen untersagt dem Raum beizutreten.</string>
-    <string name="notice_end_to_end_ok_by_you">Du hast Ende-zu-Ende-Verschlüsselung aktiviert.</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Du hast Ende-zu-Ende-Verschlüsselung aktiviert (unbekannter Algorithmus %1$s).</string>
-    <string name="notice_call_candidates">%s hat Daten gesendet, um einen Anruf zu starten.</string>
-    <string name="notice_call_candidates_by_you">Du hast Daten geschickt, um eine Anruf zu starten.</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">Du hast Gästen erlaubt hier beizutreten.</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s hat Gästen erlaubt hier beizutreten.</string>
-    <string name="notice_direct_room_join_with_reason_by_you">Du bist beigetreten. Grund: %1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s ist beigetreten. Grund: %2$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">Du hast die Einladung für %1$s zurückgezogen</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s hat die Einladung für %2$s zurückgezogen</string>
-    <string name="notice_direct_room_third_party_invite_by_you">Du hast %1$s eingeladen</string>
-    <string name="notice_direct_room_third_party_invite">%1$s hat %2$s eingeladen</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">Du hast zukünftige Nachrichten für %1$s sichtbar gemacht</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s hat zukünftige Nachrichten für %2$s sichtbar gemacht</string>
-    <string name="notice_direct_room_leave_by_you">Du hast den Raum verlassen</string>
-    <string name="notice_direct_room_leave">%1$s hat den Raum verlassen</string>
-    <string name="notice_direct_room_join_by_you">Du bist beigetreten</string>
-    <string name="notice_direct_room_join">%1$s ist beigetreten</string>
-    <string name="notice_direct_room_created_by_you">Du hast eine Diskussion erstellt</string>
-    <string name="notice_direct_room_created">%1$s hat eine Diskussion erstellt</string>
-    <string name="notice_direct_room_update">%s hat hier ein Upgrade durchgeführt.</string>
-    <string name="notice_direct_room_update_by_you">Du hast hier ein Upgrade durchgeführt.</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">Du hast Gästen untersagt den Raum zu betreten.</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s hat Gästen untersagt den Raum zu betreten.</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">Du bist gegangen. Grund: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s ist gegangen. Grund: %2$s</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-de/strings_sas.xml b/matrix-sdk-android/src/main/res/values-de/strings_sas.xml
index 108dedd1a593dfc37cbdd61c0c1e36443544773a..be75f797f93cbbb88130a5271a16d3efc550c861 100644
--- a/matrix-sdk-android/src/main/res/values-de/strings_sas.xml
+++ b/matrix-sdk-android/src/main/res/values-de/strings_sas.xml
@@ -27,20 +27,20 @@
     <string name="verification_emoji_banana">Banane</string>
     <string name="verification_emoji_apple">Apfel</string>
     <string name="verification_emoji_strawberry">Erdbeere</string>
-    <string name="verification_emoji_corn">Korn</string>
+    <string name="verification_emoji_corn">Mais</string>
     <string name="verification_emoji_pizza">Pizza</string>
     <string name="verification_emoji_cake">Kuchen</string>
     <string name="verification_emoji_heart">Herz</string>
-    <string name="verification_emoji_smiley">Smiley</string>
+    <string name="verification_emoji_smiley">Lächeln</string>
     <string name="verification_emoji_robot">Roboter</string>
     <string name="verification_emoji_hat">Hut</string>
     <string name="verification_emoji_glasses">Brille</string>
     <string name="verification_emoji_spanner">Schraubenschlüssel</string>
-    <string name="verification_emoji_santa">Nikolaus</string>
+    <string name="verification_emoji_santa">Weihnachtsmann</string>
     <string name="verification_emoji_thumbs_up">Daumen Hoch</string>
     <string name="verification_emoji_umbrella">Regenschirm</string>
     <string name="verification_emoji_hourglass">Sanduhr</string>
-    <string name="verification_emoji_clock">Wecker</string>
+    <string name="verification_emoji_clock">Uhr</string>
     <string name="verification_emoji_gift">Geschenk</string>
     <string name="verification_emoji_light_bulb">Glühbirne</string>
     <string name="verification_emoji_book">Buch</string>
@@ -56,7 +56,7 @@
     <string name="verification_emoji_bicycle">Fahrrad</string>
     <string name="verification_emoji_aeroplane">Flugzeug</string>
     <string name="verification_emoji_rocket">Rakete</string>
-    <string name="verification_emoji_trophy">Trophäe</string>
+    <string name="verification_emoji_trophy">Pokal</string>
     <string name="verification_emoji_ball">Ball</string>
     <string name="verification_emoji_guitar">Gitarre</string>
     <string name="verification_emoji_trumpet">Trompete</string>
diff --git a/matrix-sdk-android/src/main/res/values-el/strings.xml b/matrix-sdk-android/src/main/res/values-el/strings.xml
deleted file mode 100644
index 9db4e918496520ddd054472b4d881b178101781e..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-el/strings.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-    <string name="medium_email">Ηλεκτρονική διεύθυνση</string>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">Ο/Η %1$s έστειλε μια εικόνα.</string>
-    <string name="summary_user_sent_sticker">Ο/Η %1$s έστειλε ένα αυτοκόλλητο.</string>
-
-    <string name="notice_room_invite_you">Ο/Η %1$s σας προσκάλεσε</string>
-    <string name="notice_room_leave">Ο/Η %1$s αποχώρησε</string>
-    <string name="notice_room_reject">Ο/Η %1$s απέρριψε την πρόσκληση</string>
-    <string name="notice_room_kick">Ο/Η %1$s έδιωξε τον/την %2$s</string>
-    <string name="notice_room_invite">Ο/Η %1$s προσκάλεσε τον/την %2$s</string>
-    <string name="notice_room_invite_no_invitee">Η πρόσκληση του/της %s</string>
-    <string name="medium_phone_number">Αριθμός τηλεφώνου</string>
-
-    <string name="notice_room_ban">Ο/Η %1$s απέκλεισε τον/την %2$s</string>
-    <string name="notice_room_withdraw">Ο/Η %1$s απέσυρε την πρόσκληση του/της %2$s</string>
-    <string name="notice_avatar_url_changed">Ο/Η %1$s άλλαξε εικονίδιο χρήστη</string>
-    <string name="notice_display_name_set">Ο/Η %1$s άλλαξε το εμφανιζόμενό του/της όνομα σε %2$s</string>
-    <string name="notice_display_name_changed_from">Ο/Η %1$s άλλαξε το εμφανιζόμενό του/της όνομα από %2$s σε %3$s</string>
-    <string name="notice_display_name_removed">Ο/Η %1$s αφαίρεσε το εμφανιζόμενό του/της όνομα (%2$s)</string>
-    <string name="notice_room_topic_changed">Ο/Η %1$s άλλαξε το θέμα σε: %2$s</string>
-    <string name="notice_room_name_changed">Ο/Η %1$s άλλαξε το όνομα του δωματίου σε: %2$s</string>
-    <string name="notice_answered_call">Ο/Η %s απάντησε στην κλήση.</string>
-    <string name="notice_ended_call">Ο/Η %s τερμάτισε την κλήση.</string>
-
-    <string name="notice_placed_video_call">Ο/Η %s πραγματοποίησε μια κλήση βίντεο.</string>
-    <string name="notice_placed_voice_call">Ο/Η %s πραγματοποίησε μια κλήση ήχου.</string>
-    <string name="notice_made_future_room_visibility">Ο/Η %1$s κατέστησε το μελλοντικό ιστορικό του δωματίου ορατό στον/στην %2$s</string>
-    <string name="notice_room_visibility_invited">όλα τα μέλη του δωματίου, από την στιγμή που προσκλήθηκαν.</string>
-    <string name="notice_room_visibility_shared">όλα τα μέλη του δωματίου.</string>
-    <string name="notice_room_visibility_world_readable">οποιοσδήποτε.</string>
-    <string name="notice_room_visibility_unknown">άγνωστος/η (%s).</string>
-    <string name="notice_avatar_changed_too">(έγινε αλλαγή και του εικονιδίου χρήστη)</string>
-    <string name="notice_room_name_removed">Ο/Η %1$s αφαίρεσε το όνομα του δωματίου</string>
-    <string name="notice_room_topic_removed">Ο/Η %1$s αφαίρεσε το θέμα του δωματίου</string>
-    <string name="notice_profile_change_redacted">Ο/Η %1$s ανανέωσε το προφίλ του/της %2$s</string>
-    <string name="notice_room_third_party_registered_invite">Ο/Η %1$s δέχτηκε την πρόσκληση για το %2$s</string>
-
-    <string name="notice_crypto_unable_to_decrypt">** Αδυναμία αποκρυπτογράφησης: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Η συσκευή του/της αποστολέα δεν μας έχει στείλει τα κλειδιά για αυτό το μήνυμα.</string>
-
-    <string name="unable_to_send_message">Αποτυχία αποστολής μηνύματος</string>
-
-    <string name="message_failed_to_upload">Αποτυχία αναφόρτωσης εικόνας</string>
-
-    <string name="network_error">Σφάλμα δικτύου</string>
-    <string name="matrix_error">Σφάλμα του Matrix</string>
-
-    <string name="encrypted_message">Κρυπτογραφημένο μήνυμα</string>
-
-    <string name="notice_requested_voip_conference">Ο/Η %1$s ζήτησε μια VoIP διάσκεψη</string>
-    <string name="notice_voip_started">Η VoIP διάσκεψη ξεκίνησε</string>
-    <string name="notice_voip_finished">Η VoIP διάσκεψη έληξε</string>
-
-    <string name="notice_room_join">Ο/Η %1$s εισήλθε στο δωμάτιο</string>
-
-    <string name="room_displayname_invite_from">Πρόσκληση από %s</string>
-    <string name="room_displayname_room_invite">Πρόσκληση στο δωμάτιο</string>
-
-    <string name="room_displayname_two_members">%1$s και %2$s</string>
-
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s και 1 ακόμα</item>
-        <item quantity="other">%1$s και %2$d ακόμα</item>
-    </plurals>
-
-    <string name="room_displayname_empty_room">Άδειο δωμάτιο</string>
-
-    <string name="notice_room_visibility_joined">όλα τα μέλη του δωματίου από την στιγμή που εισήλθαν.</string>
-    <string name="notice_end_to_end">Ο/Η %1$s ενεργοποίησε την κρυπτογράφηση απ\'άκρη σ\'άκρη (%2$s)</string>
-
-    <string name="notice_room_third_party_invite">Ο/Η %1$s έστειλε μία πρόσκληση στον/στην %2$s για να εισέλθει στο δωμάτιο</string>
-    <string name="room_error_join_failed_empty_room">Δεν είναι δυνατή ακόμα η επανείσοδος σε ένα άδειο δωμάτιο.</string>
-
-</resources>
diff --git a/matrix-sdk-android/src/main/res/values-eo/strings.xml b/matrix-sdk-android/src/main/res/values-eo/strings.xml
deleted file mode 100644
index 10be2103cf1551ef5d34d4ee15ad16c8adcbb0d1..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-eo/strings.xml
+++ /dev/null
@@ -1,216 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_user_sent_image">%1$s sendis bildon.</string>
-    <string name="summary_user_sent_sticker">%1$s sendis glumarkon.</string>
-    <string name="notice_room_invite_no_invitee">Invito de %s</string>
-    <string name="notice_room_invite">%1$s invitis uzanton %2$s</string>
-    <string name="notice_room_invite_you">%1$s invitis vin</string>
-    <string name="notice_room_join">%1$s envenis</string>
-    <string name="notice_room_leave">%1$s foriris de la ĉambro</string>
-    <string name="notice_room_reject">%1$s rifuzis la inviton</string>
-    <string name="notice_room_kick">%1$s forpelis uzanton %2$s</string>
-    <string name="notice_room_unban">%1$s malforbaris uzanton %2$s</string>
-    <string name="notice_room_ban">%1$s forbaris uzanton %2$s</string>
-    <string name="notice_room_withdraw">%1$s nuligis inviton por %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s ŝanĝis sian profilbildon</string>
-    <string name="notice_crypto_unable_to_decrypt">** Ne eblas malĉifri: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">La aparato de la sendinto ne sendis al ni la ŝlosilojn por tiu mesaĝo.</string>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="notice_display_name_set">%1$s ŝanĝis sian prezentan nomon al %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s ŝanĝis sian prezentan nomon de %2$s al %3$s</string>
-    <string name="notice_display_name_removed">%1$s forigis sian prezentan nomon (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s ŝanĝis la temon al: %2$s</string>
-    <string name="notice_room_name_changed">%1$s ŝanĝis nomon de la ĉambro al: %2$s</string>
-    <string name="notice_placed_video_call">%s vidvokis.</string>
-    <string name="notice_placed_voice_call">%s voĉvokis.</string>
-    <string name="notice_answered_call">%s respondis la vokon.</string>
-    <string name="notice_ended_call">%s finis la vokon.</string>
-    <string name="notice_made_future_room_visibility">%1$s videbligis estontan historion de ĉambro al %2$s</string>
-    <string name="notice_room_visibility_invited">ĉiuj ĉambranoj, ekde siaj invitoj.</string>
-    <string name="notice_room_visibility_joined">ĉiuj ĉambranoj, ekde siaj aliĝoj.</string>
-    <string name="notice_room_visibility_shared">ĉiuj ĉambranoj.</string>
-    <string name="notice_room_visibility_world_readable">ĉiu ajn.</string>
-    <string name="notice_room_visibility_unknown">nekonata (%s).</string>
-    <string name="notice_end_to_end">%1$s ŝaltis tutvojan ĉifradon (%2$s)</string>
-    <string name="notice_room_update">%s gradaltigis la ĉambron.</string>
-    <string name="notice_event_redacted">Mesaĝo foriĝis</string>
-    <string name="notice_event_redacted_by">Mesaĝon forigis %1$s</string>
-    <string name="notice_event_redacted_with_reason">Mesaĝo foriĝis [kialo: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Mesaĝon forigis %1$s [kialo: %2$s]</string>
-    <string name="notice_profile_change_redacted">%1$s ĝisdatigis sian profilon %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s sendis aliĝan inviton al %2$s</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s nuligis la aliĝan inviton por %2$s</string>
-    <string name="notice_room_third_party_registered_invite">%1$s akceptis la inviton por %2$s</string>
-    <string name="could_not_redact">Ne povis redakti</string>
-    <string name="unable_to_send_message">Ne povas sendi mesaĝon</string>
-    <string name="message_failed_to_upload">Malsukcesis alŝuti bildon</string>
-    <string name="network_error">Reta eraro</string>
-    <string name="matrix_error">Matrix-eraro</string>
-    <string name="room_error_join_failed_empty_room">Nun ne eblas re-aliĝi al malplena ĉambro.</string>
-    <string name="encrypted_message">Ĉifrita mesaĝo</string>
-    <string name="medium_email">Retpoŝtadreso</string>
-    <string name="medium_phone_number">Telefonnumero</string>
-    <string name="room_displayname_invite_from">Invito de %s</string>
-    <string name="room_displayname_room_invite">Invito al ĉambro</string>
-    <string name="room_displayname_two_members">%1$s kaj %2$s</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s kaj 1 alia</item>
-        <item quantity="other">%1$s kaj %2$d aliaj</item>
-    </plurals>
-    <string name="room_displayname_empty_room">Malplena ĉambro</string>
-    <string name="initial_sync_start_importing_account">Komenca spegulado:
-\nEnportante konton…</string>
-    <string name="initial_sync_start_importing_account_crypto">Komenca spegulado:
-\nEnportante ĉifrilojn</string>
-    <string name="initial_sync_start_importing_account_rooms">Komenca spegulado:
-\nEnportante ĉambrojn</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Komenca spegulado:
-\nEnportante aliĝitajn ĉambrojn</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Komenca spegulado:
-\nEnportante ĉambrojn de invitoj</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Komenca spegulado:
-\nEnportante forlasitajn ĉambrojn</string>
-    <string name="initial_sync_start_importing_account_groups">Komenca spegulado:
-\nEnportante komunumojn</string>
-    <string name="initial_sync_start_importing_account_data">Komenca spegulado:
-\nEnportante datumojn de konto</string>
-    <string name="event_status_sending_message">Sendante mesaĝon…</string>
-    <string name="clear_timeline_send_queue">Vakigi sendan atendovicon</string>
-    <string name="notice_requested_voip_conference">%1$s petis grupan vokon</string>
-    <string name="notice_voip_started">Grupa voko komenciĝis</string>
-    <string name="notice_voip_finished">Grupa voko finiĝis</string>
-    <string name="notice_avatar_changed_too">(ankaŭ profilbildo ŝanĝiĝis)</string>
-    <string name="notice_room_name_removed">%1$s forigis nomon de la ĉambro</string>
-    <string name="notice_room_topic_removed">%1$s forigis temon de la ĉambro</string>
-    <string name="notice_room_invite_no_invitee_with_reason">Invito de %1$s. Kialo: %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s invitis uzanton %2$s. Kialo: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s invitis vin. Kialo: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s envenis. Kialo: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s foriris de la ĉambro. Kialo: %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s rifuzis la inviton. Kialo: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s forpelis uzanton %2$s. Kialo: %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s malforbaris uzanton %2$s. Kialo: %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s forbaris uzanton %2$s. Kialo: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s sendis al %2$s inviton al la ĉambro. Kialo: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s nuligis la inviton al la ĉambro por %2$s. Kialo: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s akceptis la inviton por %2$s. Kialo: %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s nuligis la inviton por %2$s. Kialo: %3$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s aldonis %2$s kiel adreson por ĉi tiu ĉambro.</item>
-        <item quantity="other">%1$s aldonis %2$s kiel adresojn por ĉi tiu ĉambro.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s forigis %2$s kiel adreson por ĉi tiu ĉambro.</item>
-        <item quantity="other">%1$s forigis %2$s kiel adresojn por ĉi tiu ĉambro.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s aldonis %2$s kaj forigis %3$s kiel adresojn por ĉi tiu ĉambro.</string>
-    <string name="notice_room_canonical_alias_set">%1$s agordis la ĉefadreson de ĉi tiu ĉambro al %2$s.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s forigis la ĉefadreson de ĉi tiu ĉambro.</string>
-    <string name="notice_room_guest_access_can_join">%1$s permesis al gastoj enveni.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s malpermesis al gastoj enveni.</string>
-    <string name="notice_end_to_end_ok">%1$s ŝaltis tutvojan ĉifradon.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s ŝaltis tutvojan ĉifradon (kun nerekonita algoritmo %2$s).</string>
-    <string name="key_verification_request_fallback_message">%s petas kontrolon de via ŝlosilo, sed via kliento ne subtenas kontrolon de ŝlosiloj en la babilujo. Vi devos uzi malnovan kontrolmanieron de ŝlosiloj.</string>
-    <string name="notice_power_level_changed_by_you">Vi ŝanĝis la povnivelon de %1$s.</string>
-    <string name="notice_power_level_changed">%1$s sanĝis la povnivelon de %2$s.</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Vi ŝaltis tutvojan ĉifradon (kun nerekonita algoritmo %1$s).</string>
-    <string name="notice_end_to_end_ok_by_you">Vi ŝaltis tutvojan ĉifradon.</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">Vi malpermesis al gastoj aliĝi.</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s malpermesis al gastoj aliĝi.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">Vi malpermesis al gastoj enveni.</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">Vi permesis al gastoj aliĝi.</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s permesis al gastoj aliĝi.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Vi permesis al gastoj enveni.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Vi forigis la ĉefadreson de ĉi tiu ĉambro.</string>
-    <string name="notice_room_canonical_alias_set_by_you">Vi agordis al ĉefadreson de ĉi tiu ĉambro al %1$s.</string>
-    <string name="notice_room_aliases_added_and_removed_by_you">Vi aldonis %1$s kaj forigis %2$s kiel adresojn por ĉi tiu ĉambro.</string>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">Vi forigis %1$s kiel adreson por ĉi tiu ĉambro.</item>
-        <item quantity="other">Vi forigis %1$s kiel adresojn por ĉi tiu ĉambro.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">Vi aldonis %1$s kiel adreson por ĉi tiu ĉambro.</item>
-        <item quantity="other">Vi aldonis %1$s kiel adresojn por ĉi tiu ĉambro.</item>
-    </plurals>
-    <string name="notice_room_withdraw_with_reason_by_you">Vi nuligis la inviton por %1$s. Kialo: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Vi akceptis la inviton por %1$s. Kialo: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Vi nuligis inviton al la ĉambro por %1$s. Kialo: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Vi sendis al %1$s inviton al la ĉambro. Kialo: %2$s</string>
-    <string name="notice_room_ban_with_reason_by_you">Vi forbaris uzanton %1$s. Kialo: %2$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Vi malforbaris uzanton %1$s. Kialo: %2$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Vi forpelis uzanton %1$s. Kialo: %2$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Vi rifuzis la inviton. Kialo: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">Vi foriris. Kialo: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s foriris. Kialo: %2$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Vi foriris de la ĉambro. Kialo: %1$s</string>
-    <string name="notice_room_join_with_reason_by_you">Vi envenis. Kialo: %1$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">Vi aliĝis. Kialo: %1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s aliĝis. Kialo: %2$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Vi invitis uzanton %1$s. Kialo: %2$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">Via invito. Kialo: %1$s</string>
-    <string name="notice_power_level_diff">%1$s de %2$s al %3$s</string>
-    <string name="power_level_custom_no_value">Propra</string>
-    <string name="power_level_default">Ordinara</string>
-    <string name="power_level_custom">Propra (%1$d)</string>
-    <string name="power_level_moderator">Reguligisto</string>
-    <string name="power_level_admin">Administranto</string>
-    <string name="notice_widget_modified_by_you">Vi ŝanĝis la fenestraĵon %1$s</string>
-    <string name="notice_widget_modified">%1$s ŝanĝis la fenestraĵon %2$s</string>
-    <string name="notice_widget_removed_by_you">Vi forigis la fenestraĵon %1$s</string>
-    <string name="notice_widget_removed">%1$s forigis la fenestraĵon %2$s</string>
-    <string name="notice_widget_added_by_you">Vi aldonis la fenestraĵon %1$s</string>
-    <string name="notice_widget_added">%1$s aldonis la fenestraĵon %2$s</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Vi akceptis la inviton por %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">Vi nuligis la inviton por %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s nuligis la inviton por %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Vi nuligis la aliĝan inviton por %1$s</string>
-    <string name="notice_direct_room_third_party_invite_by_you">Vi invitis uzanton %1$s</string>
-    <string name="notice_direct_room_third_party_invite">%1$s invitis uzanton %2$s</string>
-    <string name="notice_room_third_party_invite_by_you">Vi sendis aliĝan inviton al %1$s</string>
-    <string name="notice_profile_change_redacted_by_you">Vi ĝisdatigis vian profilon %1$s</string>
-    <string name="notice_room_avatar_removed_by_you">Vi forigis bildon de la ĉambro</string>
-    <string name="notice_room_avatar_removed">%1$s forigis bildon de la ĉambro</string>
-    <string name="notice_room_topic_removed_by_you">Vi forigis temon de la ĉambro</string>
-    <string name="notice_room_name_removed_by_you">Vi forigis nomon de la ĉambro</string>
-    <string name="notice_requested_voip_conference_by_you">Vi petis grupan vokon</string>
-    <string name="notice_direct_room_update_by_you">Vi gradaltigis la interparolon.</string>
-    <string name="notice_direct_room_update">%s gradaltigis la interparolon.</string>
-    <string name="notice_room_update_by_you">Vi gradaltigis la ĉambron.</string>
-    <string name="notice_end_to_end_by_you">Vi ŝaltis tutvojan ĉifradon (%1$s)</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s videbligis al %2$s estontajn mesaĝojn</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">Vi videbligis al %1$s estontajn mesaĝojn</string>
-    <string name="notice_made_future_room_visibility_by_you">Vi videbligis estontan historion de ĉambro al %1$s</string>
-    <string name="notice_ended_call_by_you">Vi finis la vokon.</string>
-    <string name="notice_answered_call_by_you">Vi respondis la vokon.</string>
-    <string name="notice_call_candidates_by_you">Vi sendis datumojn por prepari la vokon.</string>
-    <string name="notice_call_candidates">%s sendis datumojn por prepari la vokon.</string>
-    <string name="notice_placed_voice_call_by_you">Vi voĉvokis.</string>
-    <string name="notice_placed_video_call_by_you">Vi vidvokis.</string>
-    <string name="notice_room_name_changed_by_you">Vi ŝanĝis la nomon de la ĉambro al: %1$s</string>
-    <string name="notice_room_avatar_changed_by_you">Vi ŝanĝis la bildon de la ĉambro</string>
-    <string name="notice_room_avatar_changed">%1$s ŝanĝis la bildon de la ĉambro</string>
-    <string name="notice_room_topic_changed_by_you">Vi ŝanĝis la temon al: %1$s</string>
-    <string name="notice_display_name_removed_by_you">Vi forigis vian prezentan nomon (%1$s)</string>
-    <string name="notice_display_name_changed_from_by_you">Vi ŝanĝis vian prezentan nomon de %1$s al %2$s</string>
-    <string name="notice_display_name_set_by_you">Vi ŝanĝis vian prezentan nomon al %1$s</string>
-    <string name="notice_avatar_url_changed_by_you">Vi ŝanĝis vian profilbildon</string>
-    <string name="notice_room_withdraw_by_you">Vi nuligis inviton por %1$s</string>
-    <string name="notice_room_ban_by_you">Vi forbaris uzanton %1$s</string>
-    <string name="notice_room_unban_by_you">Vi malforbaris uzanton %1$s</string>
-    <string name="notice_room_kick_by_you">Vi forpelis uzanton %1$s</string>
-    <string name="notice_room_reject_by_you">Vi rifuzis la inviton</string>
-    <string name="notice_direct_room_leave_by_you">Vi foriris de la ĉambro</string>
-    <string name="notice_direct_room_leave">%1$s foriris de la ĉambro</string>
-    <string name="notice_room_leave_by_you">Vi foriris de la ĉambro</string>
-    <string name="notice_direct_room_join_by_you">Vi envenis</string>
-    <string name="notice_direct_room_join">%1$s envenis</string>
-    <string name="notice_room_join_by_you">Vi envenis</string>
-    <string name="notice_room_invite_by_you">Vi invitis uzanton %1$s</string>
-    <string name="notice_direct_room_created_by_you">Vi kreis la diskuton</string>
-    <string name="notice_direct_room_created">%1$s kreis la diskuton</string>
-    <string name="notice_room_created_by_you">Vi kreis la ĉambron</string>
-    <string name="notice_room_created">%1$s kreis la ĉambron</string>
-    <string name="notice_room_invite_no_invitee_by_you">Via invito</string>
-    <string name="summary_you_sent_sticker">Vi sendis glumarkon.</string>
-    <string name="summary_you_sent_image">Vi sendis bildon.</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-es-rMX/strings.xml b/matrix-sdk-android/src/main/res/values-es-rMX/strings.xml
deleted file mode 100644
index a8e8477005195e49021d3217de53866d1a54d8c4..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-es-rMX/strings.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s envió una imagen.</string>
-
-    <string name="notice_room_invite_no_invitee">la invitación de %s</string>
-    <string name="notice_room_invite">%1$s invitó a %2$s</string>
-    <string name="notice_room_invite_you">%1$s te invitó</string>
-    <string name="notice_room_join">%1$s se unió</string>
-    <string name="notice_room_leave">%1$s salió</string>
-    <string name="notice_room_reject">%1$s rechazó la invitación</string>
-    <string name="notice_room_kick">%1$s quitó a %2$s</string>
-    <string name="notice_room_unban">%1$s desprohibió a %2$s</string>
-    <string name="notice_room_ban">%1$s prohibió %2$s</string>
-    <string name="notice_room_withdraw">%1$s retiró la invitación de %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s cambió su foto de perfil</string>
-    <string name="notice_display_name_set">%1$s estableció %2$s como su nombre visible</string>
-    <string name="notice_display_name_changed_from">%1$s cambió su nombre visible de %2$s a %3$s</string>
-    <string name="notice_display_name_removed">%1$s eliminó su nombre visible (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s cambió el tema a: %2$s</string>
-    <string name="notice_room_name_changed">%1$s cambió el nombre de la sala a: %2$s</string>
-    <string name="notice_placed_video_call">%s comenzó una llamada de video.</string>
-    <string name="notice_placed_voice_call">%s comenzó una llamada de voz.</string>
-    <string name="notice_answered_call">%s recibió la llamada.</string>
-    <string name="notice_ended_call">%s terminó la llamada.</string>
-    <string name="notice_made_future_room_visibility">%1$s dejó que %2$s vea el historial del futuro</string>
-    <string name="notice_room_visibility_invited">todos los miembros de la sala, desde su invitación.</string>
-    <string name="notice_room_visibility_joined">todos los miembros de la sala, desde cuando entraron.</string>
-    <string name="notice_room_visibility_shared">todos los miembros de la sala.</string>
-    <string name="notice_room_visibility_world_readable">todos.</string>
-    <string name="notice_room_visibility_unknown">desconocido (%s).</string>
-    <string name="notice_end_to_end">%1$s encendió el cifrado de extremo a extremo (%2$s)</string>
-
-    <string name="notice_requested_voip_conference">%1$s solicitó una conferencia VoIP</string>
-    <string name="notice_voip_started">conferencia VoIP comenzó</string>
-    <string name="notice_voip_finished">conferencia VoIP finalizó</string>
-
-    <string name="notice_avatar_changed_too">(foto de perfil también se cambió)</string>
-    <string name="notice_room_name_removed">%1$s eliminó el nombre de la sala</string>
-    <string name="notice_room_topic_removed">%1$s retiró el tema de la sala</string>
-    <string name="notice_profile_change_redacted">%1$s actualizó su perfil %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s envió una invitación a %2$s para entrar a la sala</string>
-    <string name="notice_room_third_party_registered_invite">%1$s aceptó la invitación de %2$s</string>
-
-    <string name="notice_crypto_unable_to_decrypt">** No se puede descifrar: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">El dispositivo del remitente no nos ha enviado las claves de este mensaje.</string>
-
-    <!-- Room Screen -->
-    <string name="could_not_redact">No se pudo redactar</string>
-    <string name="unable_to_send_message">No se puede enviar el mensaje</string>
-
-    <string name="message_failed_to_upload">La subida de la imagen falló</string>
-
-    <!-- general errors -->
-    <string name="network_error">Error de la red</string>
-    <string name="matrix_error">Error de Matrix</string>
-
-    <!-- Home Screen -->
-
-    <!-- Last seen time -->
-
-    <!-- call events -->
-
-    <!-- room error messages -->
-    <string name="room_error_join_failed_empty_room">No es posible volver a unirse a una sala vacía.</string>
-
-    <string name="encrypted_message">Mensaje cifrado</string>
-
-    <!-- medium friendly name -->
-    <string name="medium_email">Correo electrónico</string>
-    <string name="medium_phone_number">Número telefónico</string>
-
-    <string name="summary_user_sent_sticker">%1$s envió una calcomanía.</string>
-
-    <!-- Room display name -->
-    <string name="room_displayname_invite_from">Invitación de %s</string>
-    <string name="room_displayname_room_invite">Invitación de Sala</string>
-    <string name="room_displayname_two_members">%1$s y %2$s</string>
-    <string name="room_displayname_empty_room">Sala vacía</string>
-
-
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s y otro</item>
-        <item quantity="other">%1$s y %2$d otros</item>
-    </plurals>
-
-    <string name="notice_event_redacted">Mensaje eliminado</string>
-    <string name="notice_event_redacted_by">Mensaje eliminado por %1$s</string>
-    <string name="notice_event_redacted_with_reason">Mensaje eliminado [motivo: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Mensaje eliminado por %1$s [motivo: %2$s]</string>
-</resources>
diff --git a/matrix-sdk-android/src/main/res/values-es/strings.xml b/matrix-sdk-android/src/main/res/values-es/strings.xml
deleted file mode 100644
index 3648ca3a72d8f7b396dfdc7e93ee01b06080e59a..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-es/strings.xml
+++ /dev/null
@@ -1,224 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s envió una imagen.</string>
-    <string name="notice_room_invite_no_invitee">la invitación de %s</string>
-    <string name="notice_room_invite">%1$s invitó a %2$s</string>
-    <string name="notice_room_invite_you">%1$s te ha invitado</string>
-    <string name="notice_room_join">%1$s se ha unido</string>
-    <string name="notice_room_leave">%1$s salió</string>
-    <string name="notice_room_reject">%1$s rechazó la invitación</string>
-    <string name="notice_room_kick">%1$s expulsó a %2$s</string>
-    <string name="notice_room_unban">%1$s le quitó el veto a %2$s</string>
-    <string name="notice_room_ban">%1$s vetó a %2$s</string>
-    <string name="notice_room_withdraw">%1$s retiró la invitación de %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s cambió su avatar</string>
-    <string name="notice_display_name_set">%1$s estableció %2$s como su nombre público</string>
-    <string name="notice_display_name_changed_from">%1$s cambió su nombre público de %2$s a %3$s</string>
-    <string name="notice_display_name_removed">%1$s eliminó su nombre público (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s cambió el tema a: %2$s</string>
-    <string name="notice_room_name_changed">%1$s cambió el nombre de la sala a: %2$s</string>
-    <string name="notice_placed_video_call">%s realizó una llamada de vídeo.</string>
-    <string name="notice_placed_voice_call">%s realizó una llamada de voz.</string>
-    <string name="notice_answered_call">%s contestó la llamada.</string>
-    <string name="notice_ended_call">%s finalizó la llamada.</string>
-    <string name="notice_made_future_room_visibility">%1$s hizo visible el historial futuro de la sala para %2$s</string>
-    <string name="notice_room_visibility_invited">todos los miembros de la sala, desde su invitación.</string>
-    <string name="notice_room_visibility_joined">todos los miembros de la sala, desde el momento en que se unieron.</string>
-    <string name="notice_room_visibility_shared">todos los miembros de la sala.</string>
-    <string name="notice_room_visibility_world_readable">todos.</string>
-    <string name="notice_room_visibility_unknown">desconocido (%s).</string>
-    <string name="notice_end_to_end">%1$s ha activado la encriptación de Extremo-a-Extremo (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s solicitó una conferencia de vozIP</string>
-    <string name="notice_voip_started">conferencia de vozIP iniciada</string>
-    <string name="notice_voip_finished">conferencia de vozIP finalizada</string>
-    <string name="notice_avatar_changed_too">(el avatar también se cambió)</string>
-    <string name="notice_room_name_removed">%1$s eliminó el nombre de la sala</string>
-    <string name="notice_room_topic_removed">%1$s eliminó el tema de la sala</string>
-    <string name="notice_profile_change_redacted">%1$s actualizó su perfil %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s invitó a %2$s a unirse a la sala</string>
-    <string name="notice_room_third_party_registered_invite">%1$s aceptó la invitación para %2$s</string>
-    <string name="notice_crypto_unable_to_decrypt">** No es posible descifrar: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">El dispositivo emisor no nos ha enviado las claves para este mensaje.</string>
-    <!-- Room Screen -->
-    <string name="could_not_redact">No se pudo redactar</string>
-    <string name="unable_to_send_message">No es posible enviar el mensaje</string>
-    <string name="message_failed_to_upload">No se pudo cargar la imagen</string>
-    <!-- general errors -->
-    <string name="network_error">Error de red</string>
-    <string name="matrix_error">Error de Matrix</string>
-    <!-- Home Screen -->
-    <!-- Last seen time -->
-    <!-- call events -->
-    <!-- room error messages -->
-    <string name="room_error_join_failed_empty_room">Actualmente no es posible volver a unirse a una sala vacía.</string>
-    <string name="encrypted_message">Mensaje encriptado</string>
-    <!-- medium friendly name -->
-    <string name="medium_email">Dirección de correo electrónico</string>
-    <string name="medium_phone_number">Número telefónico</string>
-    <string name="summary_user_sent_sticker">%1$s envió una pegatina.</string>
-    <!-- Room display name -->
-    <string name="room_displayname_invite_from">Invitación de %s</string>
-    <string name="room_displayname_room_invite">Invitación a Sala</string>
-    <string name="room_displayname_two_members">%1$s y %2$s</string>
-    <string name="room_displayname_empty_room">Sala vacía</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s y 1 otro</item>
-        <item quantity="other">%1$s y %2$d otros</item>
-    </plurals>
-    <string name="notice_event_redacted">Mensaje eliminado</string>
-    <string name="notice_event_redacted_by">Mensaje eliminado por %1$s</string>
-    <string name="notice_event_redacted_with_reason">Mensaje eliminado [motivo: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Mensaje eliminado por %1$s [motivo: %2$s]</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s ha revocado la invitación a unirse a la sala para %2$s</string>
-    <string name="initial_sync_start_importing_account">Sincronización Inicial
-\nImportando cuenta…</string>
-    <string name="initial_sync_start_importing_account_rooms">Sincronización Inicial:
-\nImportando Salas</string>
-    <string name="initial_sync_start_importing_account_groups">Sincronización Inicial:
-\nImportando Comunidades</string>
-    <string name="initial_sync_start_importing_account_data">Sincronización Inicial:
-\nImportando Datos de la Cuenta</string>
-    <string name="event_status_sending_message">Enviando mensaje…</string>
-    <string name="clear_timeline_send_queue">Borrar cola de envío</string>
-    <string name="notice_room_invite_with_reason">%1$s ha invitado a %2$s. Razón: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s te ha invitado. Razón: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s se ha unido. Razón: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s se ha ido. Razón: %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s ha rechadazo la invitación. Razón: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s expulsó a %2$s. Razón: %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s ha baneado a %2$s. Razón: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s ha aceptado la invitación para %2$s. Razón: %3$s</string>
-    <string name="notice_room_canonical_alias_unset">%1$s ha eliminado la dirección principal para esta sala.</string>
-    <string name="notice_room_update">%s ha actualizado la sala.</string>
-    <string name="initial_sync_start_importing_account_crypto">Sincronización Inicial:
-\nImportando criptografía</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Sincronización Inicial:
-\nImportando Salas a las que te has unido</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Sincronización Inicial:
-\nImportando Salas a las que has sido invitada</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Sincronización Inicial:
-\nImportando Salas Abandonadas</string>
-    <string name="notice_room_invite_no_invitee_with_reason">Invitación de %1$s. Razón: %2$s</string>
-    <string name="notice_room_unban_with_reason">%1$s ha desbaneado a %2$s. Razón: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s envió una invitación a %2$s para que se una a la sala. Razón: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s revocó la invitación de %2$s para unirse a la sala. Razón: %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s ha retirado la invitación de %2$s. Razón: %3$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s ha añadido %2$s como alias de esta sala.</item>
-        <item quantity="other">%1$s ha añadido %2$s como alias de esta sala.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s ha quitado %2$s como alias de esta sala.</item>
-        <item quantity="other">%1$s ha quitado %2$s como alias de esta sala.</item>
-    </plurals>
-    <string name="notice_room_canonical_alias_set">%1$s ha establecido la dirección principal de esta sala a %2$s.</string>
-    <string name="notice_room_guest_access_can_join">%1$s ha permitido que los invitados se unan a la sala.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s ha impedido que los invitados se unan a la sala.</string>
-    <string name="notice_end_to_end_ok">%1$s ha activado la encriptación extremo a extremo.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s ha activado la encriptación de extremo a extremo (algoritmo no reconocido %2$s).</string>
-    <string name="key_verification_request_fallback_message">%s solicita verificar su clave, pero su cliente no soporta la verificación de la clave en chat. Necesitará usar la verificación de claves clásica para poder verificar las claves.</string>
-    <string name="summary_you_sent_image">Enviaste una imagen.</string>
-    <string name="summary_you_sent_sticker">Enviaste un sticker.</string>
-    <string name="notice_room_invite_no_invitee_by_you">Tu invitación</string>
-    <string name="notice_room_created">%1$s creó la sala</string>
-    <string name="notice_room_created_by_you">Creaste la sala</string>
-    <string name="notice_room_invite_by_you">Invitaste a %1$s</string>
-    <string name="notice_room_join_by_you">Te uniste a la Sala</string>
-    <string name="notice_room_leave_by_you">Dejaste la Sala</string>
-    <string name="notice_room_reject_by_you">Rechazaste la invitación</string>
-    <string name="notice_room_kick_by_you">Tu pateaste a %1$s</string>
-    <string name="notice_room_unban_by_you">Tu desbanaste a %1$s</string>
-    <string name="notice_room_ban_by_you">Usted prohibió a %1$s</string>
-    <string name="notice_room_withdraw_by_you">Retiró la invitación de %1$s\'s</string>
-    <string name="notice_avatar_url_changed_by_you">Cambiaste tu avatar</string>
-    <string name="notice_display_name_set_by_you">Establece su nombre de visualización en %1$s</string>
-    <string name="notice_display_name_changed_from_by_you">Cambiaste tu nombre para mostrar de %1$s a %2$s</string>
-    <string name="notice_display_name_removed_by_you">Quitaste tu nombre para mostrar (era %1$s)</string>
-    <string name="notice_room_topic_changed_by_you">Cambiaste el tema a: %1$s</string>
-    <string name="notice_room_avatar_changed">%1$s cambió el avatar de la sala</string>
-    <string name="notice_room_avatar_changed_by_you">Cambiaste el avatar de la sala</string>
-    <string name="notice_room_name_changed_by_you">Cambiaste el nombre de la sala a: %1$s</string>
-    <string name="notice_placed_video_call_by_you">Hiciste una videollamada.</string>
-    <string name="notice_placed_voice_call_by_you">Hiciste una llamada de voz.</string>
-    <string name="notice_call_candidates">%s envió datos para configurar la llamada.</string>
-    <string name="notice_call_candidates_by_you">Enviaste datos para configurar la llamada.</string>
-    <string name="notice_answered_call_by_you">Respondiste la llamada.</string>
-    <string name="notice_ended_call_by_you">Terminaste la llamada.</string>
-    <string name="notice_made_future_room_visibility_by_you">Hiciste visible el futuro historial de la %1$s</string>
-    <string name="notice_end_to_end_by_you">Has activado la encriptación de Extremo-a-Extremo (%1$s)</string>
-    <string name="notice_room_update_by_you">Has actualizado esta sala.</string>
-    <string name="notice_requested_voip_conference_by_you">Solicitaste una conferencia de VoIP</string>
-    <string name="notice_room_name_removed_by_you">Quitaste el nombre de la sala</string>
-    <string name="notice_room_topic_removed_by_you">Quitaste el tema de la sala</string>
-    <string name="notice_room_avatar_removed">%1$s eliminó el avatar de la sala</string>
-    <string name="notice_room_avatar_removed_by_you">Quitaste el avatar de la sala</string>
-    <string name="notice_profile_change_redacted_by_you">Actualizaste tu perfil %1$s</string>
-    <string name="notice_room_third_party_invite_by_you">Enviaste una invitación a %1$s para unirse a la sala</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Revocaste la invitación para que %1$s se una a la sala</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Aceptaste la invitación para %1$s</string>
-    <string name="notice_widget_added">%1$s agrego el widget %2$s</string>
-    <string name="notice_widget_added_by_you">Agregaste el widget %1$s</string>
-    <string name="notice_widget_removed">%1$s eliminó el widget %2$s</string>
-    <string name="notice_widget_removed_by_you">Quitaste el widget %1$s</string>
-    <string name="notice_widget_modified">%1$s modifico el widget %2$s</string>
-    <string name="notice_widget_modified_by_you">Modificaste el widget %1$s</string>
-    <string name="power_level_admin">Administrador</string>
-    <string name="power_level_moderator">Moderador</string>
-    <string name="power_level_default">Por defecto</string>
-    <string name="power_level_custom">Personalizado (%1$d)</string>
-    <string name="power_level_custom_no_value">Personalizado</string>
-    <string name="notice_power_level_changed_by_you">Cambiaste el nivel de potencia de %1$s.</string>
-    <string name="notice_power_level_changed">%1$s cambió el nivel de potencia de %2$s.</string>
-    <string name="notice_power_level_diff">%1$s de %2$s a %3$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">Tu invitación. Razón: %1$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Invitaste a %1$s. Razón: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">Te uniste a la sala. Razón: %1$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Dejaste la sala. Razón: %1$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Rechazaste la invitación. Razón: %1$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Pateaste a %1$s. Motivo: %2$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Has desactivado a %1$s. Motivo: %2$s</string>
-    <string name="notice_room_ban_with_reason_by_you">Prohibiste a %1$s. Motivo: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Enviaste una invitación a %1$s para unirse a la sala. Motivo: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Revocaste la invitación para que %1$s se una a la sala. Motivo: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Aceptaste la invitación para %1$s. Motivo: %2$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">Retiró la invitación de %1$s\'s. Motivo: %2$s</string>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">Agregaste %1$s como dirección para esta sala.</item>
-        <item quantity="other">Agregaste %1$s como direcciones para esta sala.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">Quitaste %1$s como dirección para esta sala.</item>
-        <item quantity="other">Quitaste %1$s como direcciones para esta sala.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s añadió %2$s y eliminó %3$s como alias para esta sala.</string>
-    <string name="notice_room_aliases_added_and_removed_by_you">Agregaste %1$s y quitaste %2$s como direcciones para esta sala.</string>
-    <string name="notice_room_canonical_alias_set_by_you">Estableciste la dirección principal de esta sala en %1$s.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Quitaste la dirección principal de esta sala.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Ha permitido que los invitados se unan a la sala.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">Ha impedido que los invitados se unan a la sala.</string>
-    <string name="notice_end_to_end_ok_by_you">Tu has activado la encriptación de Extremo-a-Extremo.</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Has activado la encriptación de Extremo-a-Extremo (algoritmo %1$s no reconocido).</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">Has impedido que invitados se unan a la sala.</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">Has permitido a invitados unirse aquí.</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">Te has ido. Razón: %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">Has revocado la invitación de %1$s</string>
-    <string name="notice_direct_room_third_party_invite_by_you">Has invitado a %1$s</string>
-    <string name="notice_direct_room_update_by_you">Has actualizado aquí.</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">Has hecho futuros mensajes visibles a %1$s</string>
-    <string name="notice_direct_room_leave_by_you">Te saliste de la sala</string>
-    <string name="notice_direct_room_join_by_you">Te uniste</string>
-    <string name="notice_direct_room_created_by_you">Creaste la conversación</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s ha impedido que invitados se unan a la sala.</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s ha permitido a invitados a unirse aquí.</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s se ha ido. Razón: %2$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">Tu te has unido. Razón: %1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s se ha unido. Razón: %2$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s ha revocado la invitación de %2$s</string>
-    <string name="notice_direct_room_third_party_invite">%1$s ha invitado %2$s</string>
-    <string name="notice_direct_room_update">%s ha actualizado aquí.</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s ha hecho futuros mensajes visibles a %2$s</string>
-    <string name="notice_direct_room_leave">%1$s ha salido de la sala</string>
-    <string name="notice_direct_room_join">%1$s se ha unido</string>
-    <string name="notice_direct_room_created">%1$s ha creado la conversación</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-es/strings_sas.xml b/matrix-sdk-android/src/main/res/values-es/strings_sas.xml
index fd396c1778a787d1808e7ee99ca7870a0da03196..b5f062cb6288e85f958d7723f7fe404f67b42884 100644
--- a/matrix-sdk-android/src/main/res/values-es/strings_sas.xml
+++ b/matrix-sdk-android/src/main/res/values-es/strings_sas.xml
@@ -36,18 +36,33 @@
     <string name="verification_emoji_hat">Sombrero</string>
     <string name="verification_emoji_glasses">Gafas</string>
     <string name="verification_emoji_spanner">Llave inglesa</string>
+    <string name="verification_emoji_santa">Papá Noel</string>
+    <string name="verification_emoji_thumbs_up">Pulgar arriba</string>
+    <string name="verification_emoji_umbrella">Paraguas</string>
+    <string name="verification_emoji_hourglass">Reloj de arena</string>
     <string name="verification_emoji_clock">Reloj</string>
     <string name="verification_emoji_gift">Regalo</string>
+    <string name="verification_emoji_light_bulb">Bombilla</string>
     <string name="verification_emoji_book">Libro</string>
     <string name="verification_emoji_pencil">Lápiz</string>
+    <string name="verification_emoji_paperclip">Clip</string>
+    <string name="verification_emoji_scissors">Tijeras</string>
+    <string name="verification_emoji_lock">Candado</string>
     <string name="verification_emoji_key">Llave</string>
     <string name="verification_emoji_hammer">Martillo</string>
     <string name="verification_emoji_telephone">Telefono</string>
+    <string name="verification_emoji_flag">Bandera</string>
     <string name="verification_emoji_train">Tren</string>
     <string name="verification_emoji_bicycle">Bicicleta</string>
+    <string name="verification_emoji_aeroplane">Avión</string>
+    <string name="verification_emoji_rocket">Cohete</string>
+    <string name="verification_emoji_trophy">Trofeo</string>
     <string name="verification_emoji_ball">Bola</string>
     <string name="verification_emoji_guitar">Guitarra</string>
     <string name="verification_emoji_trumpet">Trompeta</string>
     <string name="verification_emoji_bell">Campana</string>
+    <string name="verification_emoji_anchor">Ancla</string>
+    <string name="verification_emoji_headphones">Cascos</string>
+    <string name="verification_emoji_folder">Carpeta</string>
     <string name="verification_emoji_pin">Alfiler</string>
 </resources>
diff --git a/matrix-sdk-android/src/main/res/values-et/strings.xml b/matrix-sdk-android/src/main/res/values-et/strings.xml
deleted file mode 100644
index af2cc33b99c9e41952f1d92a6e5ae821413717f8..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-et/strings.xml
+++ /dev/null
@@ -1,261 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s saatis pildi.</string>
-    <string name="summary_user_sent_sticker">%1$s saatis kleepsu.</string>
-    <string name="notice_room_invite_no_invitee">Kasutaja %s kutse</string>
-    <string name="notice_room_invite">%1$s kutsus kasutajat %2$s</string>
-    <string name="notice_room_invite_you">%1$s kutsus sind</string>
-    <string name="notice_room_join">%1$s liitus jututoaga</string>
-    <string name="notice_room_leave">%1$s lahkus jututoast</string>
-    <string name="notice_room_reject">%1$s lükkas tagasi kutse</string>
-    <string name="notice_room_kick">%1$s müksas kasutajat %2$s</string>
-    <string name="notice_room_withdraw">%1$s võttis tagasi kutse kasutajale %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s muutis oma avatari</string>
-    <string name="notice_display_name_set">%1$s määras oma kuvatavaks nimeks %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s muutis senise kuvatava nime %2$s uueks nimeks %3$s</string>
-    <string name="notice_display_name_removed">%1$s eemaldas oma kuvatava nime (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s muutis uueks teemaks %2$s</string>
-    <string name="notice_room_name_changed">%1$s muutis jututoa uueks nimeks %2$s</string>
-    <string name="notice_placed_video_call">%s alustas videokõnet.</string>
-    <string name="notice_placed_voice_call">%s alustas häälkõnet.</string>
-    <string name="notice_answered_call">%s vastas kõnele.</string>
-    <string name="notice_ended_call">%s lõpetas kõne.</string>
-    <string name="notice_made_future_room_visibility">%1$s seadistas, et tulevane jututoa ajalugu on nähtav kasutajale %2$s</string>
-    <string name="notice_room_visibility_invited">kõikidele jututoa liikmetele alates kutsumise hetkest.</string>
-    <string name="notice_room_visibility_joined">kõikidele jututoa liikmetele alates liitumise hetkest.</string>
-    <string name="notice_room_visibility_shared">kõikidele jututoa liikmetele.</string>
-    <string name="notice_room_visibility_world_readable">kõikidele.</string>
-    <string name="notice_room_visibility_unknown">teadmata (%s).</string>
-    <string name="notice_end_to_end">%1$s lülitas sisse läbiva krüptimise (%2$s)</string>
-    <string name="notice_room_update">%s uuendas seda jututuba.</string>
-    <string name="notice_requested_voip_conference">%1$s saatis VoIP konverentsi kutse</string>
-    <string name="notice_voip_started">VoIP-konverents algas</string>
-    <string name="notice_voip_finished">VoIP-konverents lõppes</string>
-    <string name="notice_avatar_changed_too">(samuti sai avatar muudetud)</string>
-    <string name="notice_room_name_removed">%1$s eemaldas jututoa nime</string>
-    <string name="notice_room_topic_removed">%1$s eemaldas jututoa teema</string>
-    <string name="notice_event_redacted">Sõnum on eemaldatud</string>
-    <string name="notice_event_redacted_by">Sõnum on eemaldatud %1$s poolt</string>
-    <string name="notice_event_redacted_with_reason">Sõnum on eemaldatud [põhjus: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Sõnum on eemaldatud %1$s poolt [põhjus: %2$s]</string>
-    <string name="notice_profile_change_redacted">%1$s uuendas oma profiili %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s saatis jututoaga liitumiseks kutse kasutajale %2$s</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s võttis tagasi jututoaga liitumise kutse kasutajalt %2$s</string>
-    <string name="notice_room_third_party_registered_invite">%1$s võttis vastu kutse %2$s nimel</string>
-    <string name="notice_crypto_unable_to_decrypt">** Ei õnnestu dekrüptida: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Sõnumi saatja seade ei ole selle sõnumi jaoks saatnud dekrüptimisvõtmeid.</string>
-    <string name="could_not_redact">Ei saanud muuta sõnumit</string>
-    <string name="unable_to_send_message">Sõnumi saatmine ei õnnestunud</string>
-    <string name="message_failed_to_upload">Pildi üleslaadimine ei õnnestunud</string>
-    <string name="network_error">Võrguühenduse viga</string>
-    <string name="matrix_error">Matrix\'i viga</string>
-    <string name="room_error_join_failed_empty_room">Hetkel ei ole võimalik uuesti liituda tühja jututoaga.</string>
-    <string name="encrypted_message">Krüptitud sõnum</string>
-    <string name="medium_email">E-posti aadress</string>
-    <string name="medium_phone_number">Telefoninumber</string>
-    <string name="room_displayname_invite_from">Kutse kasutajalt %s</string>
-    <string name="room_displayname_room_invite">Kutse jututuppa</string>
-    <string name="room_displayname_two_members">%1$s ja %2$s</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s ja üks muu</item>
-        <item quantity="other">%1$s ja %2$d muud</item>
-    </plurals>
-    <string name="room_displayname_empty_room">Tühi jututuba</string>
-    <string name="initial_sync_start_importing_account">Alglaadimine:
-\nImpordin kontot…</string>
-    <string name="initial_sync_start_importing_account_crypto">Alglaadimine:
-\nImpordin krüptoseadistusi</string>
-    <string name="initial_sync_start_importing_account_rooms">Alglaadimine:
-\nImpordin jututubasid</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Alglaadimine:
-\nImpordin liitutud jututubasid</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Alglaadimine:
-\nImpordin kutsutud jututubasid</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Alglaadimine:
-\nImpordin lahkutud jututubasid</string>
-    <string name="initial_sync_start_importing_account_groups">Alglaadimine:
-\nImpordin kogukondi</string>
-    <string name="initial_sync_start_importing_account_data">Alglaadimine:
-\nImpordin kontoandmeid</string>
-    <string name="event_status_sending_message">Saadan sõnumit…</string>
-    <string name="clear_timeline_send_queue">Tühjenda saatmisjärjekord</string>
-    <string name="notice_room_invite_no_invitee_with_reason">Kasutaja %1$s kutse. Põhjus: %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s kutsus kasutajat %2$s. Põhjus: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s kutsus sind. Põhjus: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s liitus jututoaga. Põhjus: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s lahkus jututoast. Põhjus: %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s lükkas kutse tagasi. Põhjus: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s müksas välja kasutaja %2$s. Põhjus: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s saatis kasutajale %2$s kutse jututoaga liitumiseks. Põhjus: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s tühistas kasutajale %2$s saadetud kutse jututoaga liitumiseks. Põhjus: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s võttis vastu kutse %2$s jututoaga liitumiseks. Põhjus: %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s võttis tagasi kasutajale %2$s saadetud kutse. Põhjus: %3$s</string>
-    <string name="notice_end_to_end_ok">%1$s lülitas sisse läbiva krüptimise.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s lülitas sisse läbiva krüptimise (tundmatu algoritm %2$s).</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s lisas %2$s selle jututoa aadressiks.</item>
-        <item quantity="other">%1$s lisas %2$s selle jututoa aadressideks.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s eemaldas %2$s kui selle jututoa aadressi.</item>
-        <item quantity="other">%1$s eemaldas %2$s selle jututoa aadresside hulgast.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s lisas %2$s ja eemaldas %3$s selle jututoa aadresside loendist.</string>
-    <string name="notice_room_canonical_alias_set">%1$s seadistas selle jututoa põhiaadressiks %2$s.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s eemaldas selle jututoa põhiaadressi.</string>
-    <string name="notice_room_guest_access_can_join">%1$s lubas külalistel selle jututoaga liituda.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s seadistas, et külalised ei või selle jututoaga liituda.</string>
-    <string name="key_verification_request_fallback_message">%s soovib verifitseerida sinu võtmeid, kuid sinu kasutatav klient ei oska vestluse-sisest verifitseerimist teha. Sa pead kasutama traditsioonilist verifitseerimislahendust.</string>
-    <string name="notice_room_created">Kasutaja %1$s lõi jututoa</string>
-    <string name="summary_you_sent_image">Sina saatsid pildi.</string>
-    <string name="summary_you_sent_sticker">Sina saatsid kleepsu.</string>
-    <string name="notice_room_invite_no_invitee_by_you">Sinu kutse</string>
-    <string name="notice_room_created_by_you">Sa lõid jututoa</string>
-    <string name="notice_room_invite_by_you">Sina kutsusid kasutajat %1$s</string>
-    <string name="notice_room_join_by_you">Sina liitusid jututoaga</string>
-    <string name="notice_room_leave_by_you">Sina lahkusid jututoast</string>
-    <string name="notice_room_reject_by_you">Sina lükkasid kutse tagasi</string>
-    <string name="notice_room_kick_by_you">Sina müksasid %1$s välja</string>
-    <string name="notice_room_unban">%1$s taastas %2$s ligipääsu</string>
-    <string name="notice_room_unban_by_you">Sina taastasid %1$s ligipääsu</string>
-    <string name="notice_room_ban">%1$s keelas %2$s ligipääsu</string>
-    <string name="notice_room_ban_by_you">Sina keelasid %1$s ligipääsu</string>
-    <string name="notice_room_withdraw_by_you">Sina võtsid tagasi %1$s kutse</string>
-    <string name="notice_avatar_url_changed_by_you">Sina muutsid oma tunnuspilti</string>
-    <string name="notice_display_name_set_by_you">Sina määrasid oma kuvatavaks nimeks %1$s</string>
-    <string name="notice_display_name_changed_from_by_you">Sina muutsid senise kuvatava nime %1$s uueks nimeks %2$s</string>
-    <string name="notice_display_name_removed_by_you">Sina eemaldasid oma kuvatava nime (oli %1$s)</string>
-    <string name="notice_room_topic_changed_by_you">Sina muutsid uueks teemaks %1$s</string>
-    <string name="notice_room_avatar_changed">%1$s muutis jututoa tunnuspilti</string>
-    <string name="notice_room_avatar_changed_by_you">Sina muutsid jututoa tunnuspilti</string>
-    <string name="notice_room_name_changed_by_you">Sina muutsid jututoa uueks nimeks %1$s</string>
-    <string name="notice_placed_video_call_by_you">Sa alustasid videokõnet.</string>
-    <string name="notice_placed_voice_call_by_you">Sa alustasid häälkõnet.</string>
-    <string name="notice_call_candidates">%s saatis info kõne algatamiseks.</string>
-    <string name="notice_call_candidates_by_you">Sa saatsid info kõne algatamiseks.</string>
-    <string name="notice_answered_call_by_you">Sa vastasid kõnele.</string>
-    <string name="notice_ended_call_by_you">Sa lõpetasid kõne.</string>
-    <string name="notice_made_future_room_visibility_by_you">Sa seadistasid, et tulevane jututoa ajalugu on nähtav kasutajale %1$s</string>
-    <string name="notice_end_to_end_by_you">Sa lülitasid sisse läbiva krüptimise (%1$s)</string>
-    <string name="notice_room_update_by_you">Sa uuendasid seda jututuba.</string>
-    <string name="notice_requested_voip_conference_by_you">Sa algatasid VoIP rühmakõne</string>
-    <string name="notice_room_name_removed_by_you">Sa eemaldasid jututoa nime</string>
-    <string name="notice_room_topic_removed_by_you">Sa eemaldasid jututoa teema</string>
-    <string name="notice_room_avatar_removed">%1$s eemaldas jututoa tunnuspildi</string>
-    <string name="notice_room_avatar_removed_by_you">Sa eemaldasid jututoa tunnuspildi</string>
-    <string name="notice_profile_change_redacted_by_you">Sa uuendasid oma profiili %1$s</string>
-    <string name="notice_room_third_party_invite_by_you">Sina saatsid kasutajale %1$s kutse jututoaga liitumiseks</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Sina võtsid tagasi jututoaga liitumise kutse kasutajalt %1$s</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Sina võtsid vastu kutse %1$s nimel</string>
-    <string name="notice_widget_added">%1$s lisas %2$s vidina</string>
-    <string name="notice_widget_added_by_you">Sina lisasid %1$s vidina</string>
-    <string name="notice_widget_removed">%1$s eemaldas %2$s vidina</string>
-    <string name="notice_widget_removed_by_you">Sina eemdaldasid %1$s vidina</string>
-    <string name="notice_widget_modified">%1$s muutis %2$s vidinat</string>
-    <string name="notice_widget_modified_by_you">Sa muutsid %1$s vidinat</string>
-    <string name="power_level_admin">Peakasutaja</string>
-    <string name="power_level_moderator">Moderaator</string>
-    <string name="power_level_default">Tavakasutaja</string>
-    <string name="power_level_custom">Kohandatud kasutajaõigused (%1$d)</string>
-    <string name="power_level_custom_no_value">Kohandatud õigused</string>
-    <string name="notice_power_level_changed_by_you">Sina muutsid kasutaja %1$s õigusi.</string>
-    <string name="notice_power_level_changed">%1$s muutis kasutaja %2$s õigusi.</string>
-    <string name="notice_power_level_diff">%1$s õiguste muutus %2$s -&gt; %3$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">Sinu kutse. Põhjus %1$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Sina kutsusid kasutajat %1$s. Põhjus: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">Sina liitusid jututoaga. Põhjus: %1$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Sina lahkusid jututoast. Põhjus: %1$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Sina lükkasid kutse tagasi. Põhjus: %1$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Sina müksasid kasutaja %1$s välja. Põhjus: %2$s</string>
-    <string name="notice_room_unban_with_reason">%1$s taastas ligipääsu kasutajale %2$s. Põhjus: %3$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Sina taastasid kasutaja %1$s ligipääsu. Põhjus: %2$s</string>
-    <string name="notice_room_ban_with_reason">%1$s keelas kasutaja %2$s ligipääsu. Põhjus: %3$s</string>
-    <string name="notice_room_ban_with_reason_by_you">Sina keelasid kasutaja %1$s ligipääsu. Põhjus: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Sina saatsid kasutajale %1$s kutse jututoaga liitumiseks. Põhjus: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Sina võtsid tagasi jututoaga liitumise kutse kasutajalt %1$s. Põhjus: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Sina võtsid vastu kutse %1$s nimel. Põhjus: %2$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">Sina võtsid tagasi kasutaja %1$s kutse. Põhjus: %2$s</string>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">Sina lisasid %1$s selle jututoa aadressiks.</item>
-        <item quantity="other">Sina lisasid %1$s selle jututoa aadressideks.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">Sina eemaldasid %1$s, kui selle jututoa aadressi.</item>
-        <item quantity="other">Sina eemaldasid %1$s selle jututoa aadresside hulgast.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed_by_you">Sina lisasid %1$s selle jututoa aadressiks ning eemaldasid %2$s aadresside hulgast.</string>
-    <string name="notice_room_canonical_alias_set_by_you">Sina seadistasid selle jututoa põhiaadressiks %1$s.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Sina eemaldasid selle jututoa põhiaadressi.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Sina lubasid külalistel selle jututoaga liituda.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">Sina seadistasid, et külalised ei või selle jututoaga liituda.</string>
-    <string name="notice_end_to_end_ok_by_you">Sa lülitasid sisse läbiva krüptimise.</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Sa lülitasid sisse läbiva krüptimise (kasutusel on tundmatu algoritm %1$s).</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">Sina seadistasid, et külalised ei või selle jututoaga liituda.</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s seadistas, et külalised ei või selle jututoaga liituda.</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">Sina lubasid külalistel selle jututoaga liituda.</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s lubas külalistel selle jututoaga liituda.</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">Sina lahkusid jututoast. Põhjus: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s lahkus jututoast. Põhjus: %2$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">Sina liitusid jututoaga. Põhjus: %1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s liitus jututoaga. Põhjus: %2$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">Sina võtsid tagasi jututoaga liitumise kutse kasutajalt %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s võttis tagasi jututoaga liitumise kutse kasutajalt %2$s</string>
-    <string name="notice_direct_room_third_party_invite_by_you">Sina kutsusid kasutajat %1$s</string>
-    <string name="notice_direct_room_third_party_invite">%1$s kutsus kasutajat %2$s</string>
-    <string name="notice_direct_room_update_by_you">Sa uuendasid seda jututuba.</string>
-    <string name="notice_direct_room_update">%s uuendas seda jututuba.</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">Sina seadistasid, et tulevased jututoa sõnumid on nähtavad kasutajale %1$s</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s seadistas, et tulevased jututoa sõnumid on nähtavad kasutajale %2$s</string>
-    <string name="notice_direct_room_leave_by_you">Sina lahkusid jututoast</string>
-    <string name="notice_direct_room_leave">%1$s lahkus jututoast</string>
-    <string name="notice_direct_room_join_by_you">Sina liitusid</string>
-    <string name="notice_direct_room_join">%1$s liitus</string>
-    <string name="notice_direct_room_created_by_you">Sina alustasid vestlust</string>
-    <string name="notice_direct_room_created">%1$s alustas vestlust</string>
-    <string name="room_displayname_empty_room_was">Tühi jututuba (oli %s)</string>
-    <plurals name="room_displayname_four_and_more_members">
-        <item quantity="one">%1$s, %2$s, %3$s ja %4$d muu</item>
-        <item quantity="other">%1$s, %2$s, %3$s ja %4$d muud</item>
-    </plurals>
-    <string name="room_displayname_4_members">%1$s, %2$s, %3$s ja %4$s</string>
-    <string name="room_displayname_3_members">%1$s, %2$s ja %3$s</string>
-    <string name="notice_room_server_acl_allow_is_empty">🎉 Kõikide serverite osalemine on keelatud! Seda jututuba ei saa enam kasutada.</string>
-    <string name="notice_room_server_acl_updated_no_change">Muudatusi ei ole.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_not_allowed">• Nüüd on keelatud serverid, mille ip-aadress vastab mustrile.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_allowed">• Nüüd on lubatud serverid, mille ip-aadress vastab mustrile.</string>
-    <string name="notice_room_server_acl_updated_was_allowed">• Server, mille nimes leidub %s, eemaldati lubatud serverite loendist.</string>
-    <string name="notice_room_server_acl_updated_allowed">• Nüüd on lubatud serverid, mille nimes leidub %s.</string>
-    <string name="notice_room_server_acl_updated_was_banned">• Server, mille nimes leidub %s eemaldati keeluloendist.</string>
-    <string name="notice_room_server_acl_updated_banned">• Keelatud on server, mille nimes leidub %s.</string>
-    <string name="notice_room_server_acl_updated_title_by_you">Sina muutsid selle jututoa jaoks serverite pääsuloendit.</string>
-    <string name="notice_room_server_acl_updated_title">%s muutis selle jututoa jaoks serverite pääsuloendit.</string>
-    <string name="notice_room_server_acl_set_title_by_you">Sina kirjeldasid selle jututoa jaoks serverite pääsuloendi.</string>
-    <string name="notice_room_server_acl_set_title">%s kirjeldas selle jututoa jaoks serverite pääsuloendi.</string>
-    <string name="notice_room_server_acl_set_ip_literals_not_allowed">• Keelatud on serverid, mille ip-aadress vastab mustrile.</string>
-    <string name="notice_room_server_acl_set_ip_literals_allowed">• Lubatud on serverid, mille ip-aadress vastab mustrile.</string>
-    <string name="notice_room_server_acl_set_allowed">• Lubatud on serverid, mille nimes leidub %s.</string>
-    <string name="notice_room_server_acl_set_banned">• Keelatud on serverid, mille nimes leidub %s.</string>
-    <string name="notice_room_canonical_alias_no_change">%1$s muutis selle jututoa aadresse.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed_by_you">Sa muutsid selle jututoa põhiaadressi ja täiendavaid aadresse.</string>
-    <string name="notice_room_canonical_alias_alternative_changed">%1$s muutis selle jututoa täiendavaid aadresse.</string>
-    <string name="notice_room_canonical_alias_alternative_changed_by_you">Sa muutsid selle jututoa täiendavaid aadresse.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed">%1$s muutis selle jututoa põhiaadressi ja täiendavaid aadresse.</string>
-    <plurals name="notice_room_canonical_alias_alternative_removed_by_you">
-        <item quantity="one">Sa eemaldasid selle jututoa täiendava aadressi %1$s.</item>
-        <item quantity="other">Sa eemaldasid selle jututoa täiendavad aadressid %1$s.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_removed">
-        <item quantity="one">%1$s eemaldas selle jututoa täiendava aadressi %2$s.</item>
-        <item quantity="other">%1$s eemaldas selle jututoa täiendavad aadressid %2$s.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added_by_you">
-        <item quantity="one">Sa lisasid sellele jututoale täiendava aadressi %1$s.</item>
-        <item quantity="other">Sa lisasid sellele jututoale täiendavad aadressid %1$s.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added">
-        <item quantity="one">%1$s lisas sellele jututoale täiendava aadressi %2$s.</item>
-        <item quantity="other">%1$s lisas sellele jututoale täiendavad aadressid %2$s.</item>
-    </plurals>
-    <string name="notice_room_canonical_alias_no_change_by_you">Sa muutsid selle jututoa aadresse.</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-eu/strings.xml b/matrix-sdk-android/src/main/res/values-eu/strings.xml
deleted file mode 100644
index bc61035c245c02e6fa65a6d1dae15941f56a63eb..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-eu/strings.xml
+++ /dev/null
@@ -1,143 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s erabiltzaileak irudi bat bidali du.</string>
-
-    <string name="notice_room_invite_no_invitee">%s erabiltzailearen gonbidapena</string>
-    <string name="notice_room_invite">%1$s erabiltzaileak %2$s gonbidatu du</string>
-    <string name="notice_room_invite_you">%1$s erabiltzaileak gonbidatu zaitu</string>
-    <string name="notice_room_join">%1$s gelara elkartu da</string>
-    <string name="notice_room_leave">%1$s gelatik atera da</string>
-    <string name="notice_room_reject">%1$s erabiltzaileak gonbidapena baztertu du</string>
-    <string name="notice_room_kick">%1$s erabiltzaileak %2$s kanporatu du</string>
-    <string name="notice_room_unban">%1$s erabiltzaileak debekua kendu dio %2$s erabiltzaileari</string>
-    <string name="notice_room_ban">%1$s erabiltzaileak %2$s debekatu du</string>
-    <string name="notice_room_withdraw">%1$s erabiltzaileak %2$s erabiltzailearen gonbidapena atzera bota du</string>
-    <string name="notice_avatar_url_changed">%1$s erabiltzaileak abatarra aldatu du</string>
-    <string name="notice_display_name_set">%1$s erabiltzaileak bere pantaila-izena aldatu du beste honetara: %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s erabiltzaileak bere pantaila-izena aldatu du, honetatik: %2$s honetara: %3$s</string>
-    <string name="notice_display_name_removed">%1$s erabiltzaileak bere pantaila-izena kendu du (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s erabiltzaileak mintzagaia honetara aldatu du: %2$s</string>
-    <string name="notice_room_name_changed">%1$s erabiltzaileak gelaren izena honetara aldatu du: %2$s</string>
-    <string name="notice_placed_video_call">%s erabiltzaileak bideo deia hasi du.</string>
-    <string name="notice_placed_voice_call">%s erabiltzaileak ahots deia hasi du.</string>
-    <string name="notice_answered_call">%s erabiltzaileak deia erantzun du.</string>
-    <string name="notice_ended_call">%s erabiltzaileak deia amaitu du.</string>
-    <string name="notice_made_future_room_visibility">%1$s erabiltzaileak gelaren historiala ikusgai jarri du hauentzat: %2$s</string>
-    <string name="notice_room_visibility_invited">gelako kide guztiak, gonbidatu zitzaienetik.</string>
-    <string name="notice_room_visibility_joined">gelako kide guztiak, elkartu zirenetik.</string>
-    <string name="notice_room_visibility_shared">gelako kide guztiak.</string>
-    <string name="notice_room_visibility_world_readable">edonor.</string>
-    <string name="notice_room_visibility_unknown">ezezaguna (%s).</string>
-    <string name="notice_end_to_end">%1$s erabiltzaileak muturretik muturrera zifratzea aktibatu du (%2$s)</string>
-
-    <string name="notice_requested_voip_conference">%1$s erabiltzaileak VoIP konferentzia bat eskatu du</string>
-    <string name="notice_voip_started">VoIP konferentzia hasita</string>
-    <string name="notice_voip_finished">VoIP konferentzia amaituta</string>
-
-    <string name="notice_avatar_changed_too">(abatarra ere aldatu da)</string>
-    <string name="notice_room_name_removed">%1$s erabiltzaileak gelaren izena kendu du</string>
-    <string name="notice_room_topic_removed">%1$s erabiltzaileak gelaren mintzagaia kendu du</string>
-    <string name="notice_profile_change_redacted">%1$s erabiltzaileak bere profila eguneratu du %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s erabiltzaileak gelara elkartzeko gonbidapen bat bidali dio %2$s erabiltzaileari</string>
-    <string name="notice_room_third_party_registered_invite">%1$s erabiltzaileak %2$s gelarako gonbidapena onartu du</string>
-
-    <string name="notice_crypto_unable_to_decrypt">** Ezin izan da deszifratu: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Igorlearen gailuak ez dizkigu mezu honetarako gakoak bidali.</string>
-
-    <string name="could_not_redact">Ezin izan da kendu</string>
-    <string name="unable_to_send_message">Ezin izan da mezua bidali</string>
-
-    <string name="message_failed_to_upload">Huts egin du irudia igotzean</string>
-
-    <string name="network_error">Sare errorea</string>
-    <string name="matrix_error">Matrix errorea</string>
-
-    <string name="room_error_join_failed_empty_room">Ezin da oraingoz hutsik dagoen gela batetara berriro sartu.</string>
-
-    <string name="encrypted_message">Zifratutako mezua</string>
-
-    <string name="medium_email">E-mail helbidea</string>
-    <string name="medium_phone_number">Telefono zenbakia</string>
-
-    <string name="summary_user_sent_sticker">%1$s erabiltzaileak eranskailu bat bidali du.</string>
-
-    <string name="room_displayname_invite_from">%s gelarako gonbidapena</string>
-    <string name="room_displayname_room_invite">Gela gonbidapena</string>
-    <string name="room_displayname_two_members">%1$s eta %2$s</string>
-    <string name="room_displayname_empty_room">Gela hutsa</string>
-
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s eta beste bat</item>
-        <item quantity="other">%1$s eta beste %2$d</item>
-    </plurals>
-
-
-    <string name="notice_event_redacted">Mezua kendu da</string>
-    <string name="notice_event_redacted_by">%1$s erabiltzaileak mezua kendu du</string>
-    <string name="notice_event_redacted_with_reason">Mezua kendu da [arrazoia: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">%1$s erabiltzaileak mezua kendu du [arrazoia: %2$s]</string>
-
-    <string name="initial_sync_start_importing_account">Hasierako sinkronizazioa:
-\nKontua inportatzen…</string>
-    <string name="initial_sync_start_importing_account_crypto">Hasierako sinkronizazioa:
-\nZifratzea inportatzen</string>
-    <string name="initial_sync_start_importing_account_rooms">Hasierako sinkronizazioa:
-\nGelak inportatzen</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Hasierako sinkronizazioa:
-\nElkartutako gelak inportatzen</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Hasierako sinkronizazioa:
-\nGonbidatutako gelak inportatzen</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Hasierako sinkronizazioa:
-\nUtzitako gelak inportatzen</string>
-    <string name="initial_sync_start_importing_account_groups">Hasierako sinkronizazioa:
-\nKomunitateak inportatzen</string>
-    <string name="initial_sync_start_importing_account_data">Hasierako sinkronizazioa:
-\nKontuaren datuak inportatzen</string>
-
-    <string name="notice_room_update">%s erabiltzaileak gela hau eguneratu du.</string>
-
-    <string name="event_status_sending_message">Mezua bidaltzen…</string>
-    <string name="clear_timeline_send_queue">Garbitu bidalketa-ilara</string>
-
-    <string name="notice_room_third_party_revoked_invite">%1$s erabiltzaileak %2$s gelara elkartzeko gonbidapena indargabetu du</string>
-    <string name="notice_room_invite_no_invitee_with_reason">%1$s erabiltzailearen gonbidapena. Arrazoia: %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s erabiltzaileak %2$s gonbidatu du. Arrazoia: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s erabiltzaileak gonbidatu zaitu. Arrazoia: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s gelara elkartu da. Arrazoia: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s gelatik atera da. Arrazoia: %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s erabiltzaileak gonbidapena baztertu du. Arrazoia: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s erabiltzaileak %2$s kanporatu du. Arrazoia: %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s erabiltzaileak debekua kendu dio %2$s erabiltzaileari. Arrazoia: %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s erabiltzaileak %2$s debekatu du. Arrazoia: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">"%1$s erabiltzaileak gelara elkartzeko gonbidapen bat bidali dio %2$s erabiltzaileari. Arrazoia: %3$s"</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">"%1$s erabiltzaileak %2$s gelara elkartzeko gonbidapena indargabetu du. Arrazoia: %3$s"</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">"%1$s erabiltzaileak %2$s gelarako gonbidapena onartu du. Arrazoia: %3$s"</string>
-    <string name="notice_room_withdraw_with_reason">"%1$s erabiltzaileak %2$s erabiltzailearen gonbidapena indargabetu du. Arrazoia: %3$s"</string>
-
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s erabiltzaileak %2$s gehitu du gela honen helbide gisa.</item>
-        <item quantity="other">%1$s erabiltzaileak %2$s gehitu ditu gela honen helbide gisa.</item>
-    </plurals>
-
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s erabiltzaileak %2$s kendu du gela honen helbide gisa.</item>
-        <item quantity="other">%1$s erabiltzaileak %3$s kendu ditu gela honen helbide gisa.</item>
-    </plurals>
-
-    <string name="notice_room_aliases_added_and_removed">%1$s erabiltzaileak %2$s gehitu %3$s eta kendu ditu gela honen helbide gisa.</string>
-
-    <string name="notice_room_canonical_alias_set">%1$s erabiltzaileak %2$s ezarri du gela honen helbide nagusi gisa.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s erabiltzaileak gela honen helbide nagusia kendu du.</string>
-
-    <string name="notice_room_guest_access_can_join">%1$k gonbidatuak gelara sartzea onartu du.</string>
-    <string name="notice_room_guest_access_forbidden">%1%k gonbidatuak gelara sartzea galerazi du.</string>
-
-    <string name="notice_end_to_end_ok">%1$s erabiltzaileak muturretik muturrerako zifratzea gaitu du.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s erabiltzaileak muturretik muturrerako zifratzea gaitu du. (%2$s algoritmo ezezaguna).</string>
-
-    <string name="key_verification_request_fallback_message">%s(e)k zure gakoa egiaztatzea eskatu du, baina zure bezeroak ez du txatean gakoa egiaztatzea onartzen. Gako egiaztaketa zaharra erabili beharko duzu.</string>
-
-    <string name="notice_room_created">%1$s erabiltzaileak gela sortu du</string>
-</resources>
diff --git a/matrix-sdk-android/src/main/res/values-fa/strings.xml b/matrix-sdk-android/src/main/res/values-fa/strings.xml
deleted file mode 100644
index 50446b9708c5d79de412300207fa5c720ba25dc0..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-fa/strings.xml
+++ /dev/null
@@ -1,222 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s تصویری فرستاد.</string>
-    <string name="summary_user_sent_sticker">%1$s برچسبی فرستاد.</string>
-    <string name="notice_room_invite_no_invitee">دعوت %s</string>
-    <string name="notice_room_invite">‫%1$s، %2$s را دعوت کرد</string>
-    <string name="notice_room_invite_you">%1$s دعوتتان کرد</string>
-    <string name="notice_room_join">%1$s به اتاق پیوست</string>
-    <string name="notice_room_leave">%1$s اتاق را ترک کرد</string>
-    <string name="notice_room_reject">%1$s دعوت را رد کرد</string>
-    <string name="notice_room_kick">%1$s، %2$s را اخراج کرد</string>
-    <string name="notice_room_unban">%1$s، انسداد %2$s را رفع کرد</string>
-    <string name="notice_room_ban">%1$s، %2$s را مسدود کرد</string>
-    <string name="notice_room_withdraw">%1$s دعوت %2$s را نپذیرفت</string>
-    <string name="notice_avatar_url_changed">%1$s تصویرش را عوض کرد</string>
-    <string name="notice_display_name_set">%1$s نام نمایشی خود را به %2$s تنظیم کرد</string>
-    <string name="notice_display_name_changed_from">%1$s نام نمایشیش را از %2$s به %3$s تغییر داد</string>
-    <string name="notice_display_name_removed">%1$s نام نمایشیش (%2$s) را پاک کرد</string>
-    <string name="notice_room_topic_changed">%1$s موضوع را به %2$s تغییر داد</string>
-    <string name="notice_room_name_changed">%1$s نام اتاق را به %2$s تغییر داد</string>
-    <string name="notice_placed_video_call">%s یک تماس تصویری برقرار کرد.</string>
-    <string name="notice_placed_voice_call">%s یک تماس صوتی برقرار کرد.</string>
-    <string name="notice_answered_call">%s تماس را پاسخ داد.</string>
-    <string name="notice_ended_call">%s به تماس پایان داد.</string>
-    <string name="notice_made_future_room_visibility">%1$s تاریخچهٔ آیندهٔ اتاق را برای %2$s نمایان کرد</string>
-    <string name="notice_room_visibility_invited">همهٔ اعضای اتاق، از زمان دعوت شدنشان.</string>
-    <string name="notice_room_visibility_joined">همهٔ اعضای اتاق، از زمان پیوستنشان.</string>
-    <string name="notice_room_visibility_shared">همهٔ اعضای اتاق.</string>
-    <string name="notice_room_visibility_world_readable">هرکسی.</string>
-    <string name="notice_room_visibility_unknown">ناشناخته (%s).</string>
-    <string name="notice_end_to_end">%1$s رمزنگاری سرتاسری را روشن کرد (%2$s)</string>
-    <string name="notice_room_update">%s این اتاق را ارتقا داد.</string>
-    <string name="notice_requested_voip_conference">%1$s درخواست یک گردهمایی صوتی داد</string>
-    <string name="notice_voip_started">گردهمایی صوتی آغاز شد</string>
-    <string name="notice_voip_finished">گردهمایی صوتی پایان یافت</string>
-    <string name="notice_avatar_changed_too">(تصویر هم عوض شد)</string>
-    <string name="notice_room_name_removed">%1$s نام اتاق را پاک کرد</string>
-    <string name="notice_room_topic_removed">%1$s موضوع اتاق را پاک کرد</string>
-    <string name="notice_event_redacted">پیام برداشته شد</string>
-    <string name="notice_event_redacted_by">پیام به دست %1$s برداشته شد</string>
-    <string name="notice_event_redacted_with_reason">پیام برداشته شد [دلیل: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">پیام به دست %1$s برداشته شد [دلیل: %2$s]</string>
-    <string name="notice_room_third_party_invite">%1$s دعوتی برای پیوستن %2$s به اتاق فرستاد</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s دعوت پیوستن به اتاق %2$s را باطل کرد</string>
-    <string name="notice_room_third_party_registered_invite">%1$s دعوت برای %2$s را پذیرفت</string>
-    <string name="notice_crypto_unable_to_decrypt">** ناتوان در رمزگشایی: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">دستگاه فرستنده، کلیدهای این پیام را برایمان نفرستاده است.</string>
-    <string name="unable_to_send_message">ناتوان در فرستادن پیام</string>
-    <string name="message_failed_to_upload">شکست در بارگذاری تصویر</string>
-    <string name="network_error">خطای شبکه</string>
-    <string name="matrix_error">خطای ماتریکس</string>
-    <string name="room_error_join_failed_empty_room">در حال حاضر امکان بازپیوست به اتاقی خالی وجود ندارد‌‌.</string>
-    <string name="encrypted_message">پیام رمزنگاری شده</string>
-    <string name="medium_email">نشانی رایانامه</string>
-    <string name="medium_phone_number">شماره تلفن</string>
-    <string name="room_displayname_invite_from">دعوت از %s</string>
-    <string name="room_displayname_room_invite">دعوت اتاق</string>
-    <string name="room_displayname_two_members">%1$s Ùˆ %2$s</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s و ۱ نفر دیگر</item>
-        <item quantity="other">%1$s و %2$d نفر دیگر</item>
-    </plurals>
-    <string name="room_displayname_empty_room">اتاق خالی</string>
-    <string name="initial_sync_start_importing_account">همگام‌سازی نخستین:
-\nدر حال درون‌ریزی حساب…</string>
-    <string name="initial_sync_start_importing_account_crypto">همگام‌سازی نخستین:
-\nدر حال درون‌ریزی رمزنگاری</string>
-    <string name="initial_sync_start_importing_account_rooms">همگام‌سازی نخستین:
-\nدر حال درون‌ریزی اتاق‌ها</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">همگام‌سازی نخستین:
-\nدر حال درون‌ریزی اتاق‌های پیوسته</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">همگام‌سازی نخستین:
-\nدر حال درون‌ریزی اتاق‌های دعوت‌شده</string>
-    <string name="initial_sync_start_importing_account_left_rooms">همگام‌سازی نخستین:
-\nدر حال درون‌ریزی اتاق‌های ترک‌شده</string>
-    <string name="initial_sync_start_importing_account_groups">همگام‌سازی نخستین: 
-\nدر حال درون‌ریزی انجمن‌ها</string>
-    <string name="initial_sync_start_importing_account_data">همگام‌سازی نخستین:
-\nدر حال درون‌ریزی داده‌های حساب</string>
-    <string name="event_status_sending_message">در حال فرستادن پیام…</string>
-    <string name="clear_timeline_send_queue">پاک‌سازی صفِ در حال ارسال</string>
-    <string name="notice_room_invite_no_invitee_with_reason">دعوت %1$s. دلیل: %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s، %2$s را دعوت کرد. دلیل: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s دعوتتان کرد. دلیل: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s به اتاق پیوست. دلیل: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s اتاق را ترک کرد. دلیل: %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s دعوت را رد کرد. دلیل: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s، %2$s را اخراج کرد. دلیل: %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s انسداد %2$s را رفع کرد. دلیل: %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s، %2$s را مسدود کرد. دلیل: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s دعوتی برای پیوستن %2$s به اتاق فرستاد. دلیل: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s دعوت %2$s برای پیوستن به اتاق را باطل کرد. دلیل: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s دعوت برای %2$s را پذیرفت. دلیل: %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s دعوت %2$s را نپذیرفت. دلیل: %3$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s، %2$s را به عنوان نشانی‌ای برای این اتاق افزود.</item>
-        <item quantity="other">%1$s، %2$s را به عنوان نشانی‌هایی برای این اتاق افزود.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s، %2$s را به عنوان نشانی‌ای برای این اتاق پاک کرد.</item>
-        <item quantity="other">%1$s، %3$s را به عنوان نشانی‌هایی برای این اتاق پاک کرد.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s برای نشانی این اتاق، %2$s را افزود و %3$s را پاک کرد.</string>
-    <string name="notice_room_canonical_alias_set">%1$s نشانی اصلی این اتاق را به %2$s تنظیم کرد.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s نشانی اصلی را برای این اتاق پاک کرد.</string>
-    <string name="notice_room_guest_access_can_join">%1$s اجازه داد میمهانان به گروه بپیوندند.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s جلوی پیوستن میمهانان به گروه را گرفت.</string>
-    <string name="notice_end_to_end_ok">%1$s رمزنگاری سرتاسری را روشن کرد.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s رمزنگاری سرتاسری را روشن کرد (الگوریتم تشخیص‌داده‌نشده %2$s ).</string>
-    <string name="key_verification_request_fallback_message">%s درخواست تأیید کلیدتان را دارد، ولی کارخواهتان تأیید کلید درون گپ را پشتیبانی نمی‌کند. برای تأیید کلیدها لازم است از تأییدیهٔ کلید قدیمی استفاده کنید.</string>
-    <string name="notice_room_created">%1$s اتاق را ایجاد کرد</string>
-    <string name="notice_profile_change_redacted">%1$s نمایه‌اش را به‌روز کرد %2$s</string>
-    <string name="could_not_redact">نمی‌توان ویرایش کرد</string>
-    <string name="summary_you_sent_image">تصویری فرستادید.</string>
-    <string name="summary_you_sent_sticker">برچسبی فرستادید.</string>
-    <string name="notice_room_invite_no_invitee_by_you">دعوتتان</string>
-    <string name="notice_room_created_by_you">اتاق را ایجاد کردید</string>
-    <string name="notice_room_invite_by_you">از %1$s دعوت کردید</string>
-    <string name="notice_room_join_by_you">به اتاق پیوستید</string>
-    <string name="notice_room_leave_by_you">اتاق را ترک کردید</string>
-    <string name="notice_room_reject_by_you">دعوت را رد کردید</string>
-    <string name="notice_room_kick_by_you">%1$s را اخراج کردید</string>
-    <string name="notice_room_unban_by_you">تحریم %1$s را برداشتید</string>
-    <string name="notice_room_ban_by_you">%1$s را تحریم کردید</string>
-    <string name="notice_room_withdraw_by_you">دعوت %1$s را پس‌گرفتید</string>
-    <string name="notice_avatar_url_changed_by_you">آواتارتان را عوض کردید</string>
-    <string name="notice_display_name_set_by_you">نام نمایشیتان را به %1$s تغییر دادید</string>
-    <string name="notice_display_name_changed_from_by_you">نام نمایشیتان را از %1$s به %2$s تغییر دادید</string>
-    <string name="notice_display_name_removed_by_you">نام نمایشیتان را برداشتید (%1$s بود)</string>
-    <string name="notice_room_topic_changed_by_you">موضوع را به %1$s تغییر دادید</string>
-    <string name="notice_room_avatar_changed">%1$s آواتار اتاق را تغییر داد</string>
-    <string name="notice_room_avatar_changed_by_you">آواتار اتاق را تغییر دادید</string>
-    <string name="notice_room_name_changed_by_you">نام اتاق را به %1$s تغییر دادید</string>
-    <string name="notice_placed_video_call_by_you">تماس تصویری گرفتید.</string>
-    <string name="notice_placed_voice_call_by_you">تماس صوتی گرفتید.</string>
-    <string name="notice_call_candidates">%s برای برپایی تماس، داده فرستاد.</string>
-    <string name="notice_call_candidates_by_you">برای برپایی تماس، داده فرستادید.</string>
-    <string name="notice_answered_call_by_you">تماس را پاسخ دادید.</string>
-    <string name="notice_ended_call_by_you">به تماس پایان دادید.</string>
-    <string name="notice_made_future_room_visibility_by_you">تاریخچهٔ آتی اتاق را برای %1$s نمایان کردید</string>
-    <string name="notice_end_to_end_by_you">رمزنگاری سرتاسری را روشن کردید (%1$s)</string>
-    <string name="notice_room_update_by_you">این اتاق را ارتقا دادید.</string>
-    <string name="notice_requested_voip_conference_by_you">دارخواست کنفرانس ویپ دادید</string>
-    <string name="notice_room_name_removed_by_you">نام اتاق را برداشتید</string>
-    <string name="notice_room_topic_removed_by_you">موضوع اتاق را برداشتید</string>
-    <string name="notice_room_avatar_removed">%1$s آواتار اتاق را برداشت</string>
-    <string name="notice_room_avatar_removed_by_you">آواتار اتاق را برداشتید</string>
-    <string name="notice_profile_change_redacted_by_you">نمایه‌تان را به‌روز کردید %1$s</string>
-    <string name="notice_room_third_party_invite_by_you">برای %1$s دعوت پیوستن به اتاق فرستادید</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">دعوت پیوستن %1$s به اتاق را پس گرفتید</string>
-    <string name="notice_room_third_party_registered_invite_by_you">دعوت برای %1$s را پذیرفتید</string>
-    <string name="notice_widget_added">%1$s ابزارک %2$s را افزود</string>
-    <string name="notice_widget_added_by_you">ابزارک %1$s را افزودید</string>
-    <string name="notice_widget_removed">%1$s ابزارک %2$s را برداشت</string>
-    <string name="notice_widget_removed_by_you">ابزارک %1$s را برداشتید</string>
-    <string name="notice_widget_modified">%1$s ابزارک %2$s را دستکاری کرد</string>
-    <string name="notice_widget_modified_by_you">ابزارک %1$s را دستکاری کردید</string>
-    <string name="power_level_admin">مدیر</string>
-    <string name="power_level_moderator">ناظم</string>
-    <string name="power_level_default">پیش‌گزیده</string>
-    <string name="power_level_custom">سفارشی (%1$d)</string>
-    <string name="power_level_custom_no_value">سفارشی</string>
-    <string name="notice_power_level_changed_by_you">سطح قدرت %1$s را تغییر دادید.</string>
-    <string name="notice_power_level_changed">%1$s سطح قدرت %2$s را تغییر داد.</string>
-    <string name="notice_power_level_diff">%1$s از %2$s به %3$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">دعوتتان. دلیل: %1$s</string>
-    <string name="notice_room_invite_with_reason_by_you">%1$s را دعوت کردید. دلیل: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">به اتاق پیوستید. دلیل: %1$s</string>
-    <string name="notice_room_leave_with_reason_by_you">اتاق را ترک کردید. دلیل: %1$s</string>
-    <string name="notice_room_reject_with_reason_by_you">دعوت را رد کردید. دلیل: %1$s</string>
-    <string name="notice_room_kick_with_reason_by_you">%1$s را اخراج کردید. دلیل: %2$s</string>
-    <string name="notice_room_unban_with_reason_by_you">تحریم %1$s را برداشتید. دلیل: %2$s</string>
-    <string name="notice_room_ban_with_reason_by_you">%1$s را تحریم کردید. دلیل: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">دعوتی به %1$s برای پیوستن به اتاق فرستادید. دلیل: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">دعوت %1$s برای پیوستن به اتاق را پس گرفتید. دلیل: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">دعوت برای %1$s را پذیرفتید. دلیل: %2$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">دعوت %1$s را رد کردید. دلیل: %2$s</string>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">نشانی %1$s را به این اتاق افزودید.</item>
-        <item quantity="other">نشانی‌های %1$s را به این اتاق افزودید.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">نشانی %1$s را از این اتاق برداشتید.</item>
-        <item quantity="other">نشانی‌های %1$s را از این اتاق برداشتید.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed_by_you">نشانی %1$s ار افزوده و %2$s را از این اتاق برداشتید.</string>
-    <string name="notice_room_canonical_alias_set_by_you">نشانی اصلی این اتاق را به %1$s تنظیم کردید.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">نشانی اصلی این اتاق را برداشتید.</string>
-    <string name="notice_room_guest_access_can_join_by_you">به میهمانان اجازهٔ پیوستن به گروه دادید.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">میمهانان را از پیوستن به گروه بازداشتید.</string>
-    <string name="notice_end_to_end_ok_by_you">رمزنگاری سرتاسری را روشن کردید.</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">رمزنگاری سرتاسری را روشن کردید (الگوریتم ناشناخته %1$s).</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">مهمان‌ها را از پیوستن به اتاق بازداشتید.</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s مهمان‌ها را از پیوستن به اتاق بازداشت.</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">به مهمان‌ها اجازه دادید به این‌جا بپیوندند.</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s به مهمان‌ها اجازه داد به این‌جا بپیوندند.</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">رفتید. دلیل: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s رفت. دلیل: %2$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">پیوستید. دلیل: %1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$sپیوست. دلیل: %2$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">دعوت %1$s را پس گرفتید</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s دعوت %2$s را پس گرفت</string>
-    <string name="notice_direct_room_third_party_invite_by_you">%1$s را دعوت کردید</string>
-    <string name="notice_direct_room_third_party_invite">%1$s، %2$s را دعوت کرد</string>
-    <string name="notice_direct_room_update_by_you">این‌جا را ارتقا دادید.</string>
-    <string name="notice_direct_room_update">%s این‌جا را ارتقا داد.</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">پیام‌های آینده را برای %1$s نمایان کردید</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s پیام‌های آینده را برای %2$s نمایان کرد</string>
-    <string name="notice_direct_room_leave_by_you">اتاق را ترک کردید</string>
-    <string name="notice_direct_room_leave">%1$s اتاق را ترک کرد</string>
-    <string name="notice_direct_room_join_by_you">پیوستید</string>
-    <string name="notice_direct_room_join">%1$s پیوست</string>
-    <string name="notice_direct_room_created_by_you">گفت‌وگو را ایجاد کردید</string>
-    <string name="notice_direct_room_created">%1$s گفت‌وگو را ایجاد کرد</string>
-    <plurals name="room_displayname_four_and_more_members">
-        <item quantity="one">%1$s، %2$s، %3$s و %4$d نفر دیگر</item>
-        <item quantity="other">%1$s، %2$s، %3$s و %4$d نفر دیگر</item>
-    </plurals>
-    <string name="room_displayname_3_members">%1$s، %2$s و %3$s</string>
-    <string name="room_displayname_4_members">%1$s، %2$s، %3$s و %4$s</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-fi/strings.xml b/matrix-sdk-android/src/main/res/values-fi/strings.xml
deleted file mode 100644
index 1e3788476fb13db1ad29d1a5e2d073754353829a..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-fi/strings.xml
+++ /dev/null
@@ -1,213 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_user_sent_image">%1$s lähetti kuvan.</string>
-    <string name="notice_room_invite_no_invitee">Käyttäjän %s kutsu</string>
-    <string name="notice_room_invite">%1$s kutsui käyttäjän %2$s</string>
-    <string name="notice_room_invite_you">%1$s kutsui sinut</string>
-    <string name="notice_room_join">%1$s liittyi huoneeseen</string>
-    <string name="notice_room_leave">%1$s poistui huoneesta</string>
-    <string name="notice_room_reject">%1$s hylkäsi kutsun</string>
-    <string name="notice_room_kick">%1$s poisti käyttäjän %2$s</string>
-    <string name="notice_room_unban">%1$s poisti porttikiellon käyttäjältä %2$s</string>
-    <string name="notice_room_ban">%1$s antoi porttikiellon käyttäjälle %2$s</string>
-    <string name="notice_room_withdraw">%1$s veti takaisin kutsun käyttäjälle %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s vaihtoi profiilikuvaansa</string>
-    <string name="notice_display_name_set">%1$s asetti näyttönimekseen %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s muutti näyttönimensä nimestä %2$s nimeen %3$s</string>
-    <string name="notice_display_name_removed">%1$s poisti näyttönimensä (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s vaihtoi aiheeksi: %2$s</string>
-    <string name="notice_room_name_changed">%1$s vaihtoi huoneen nimeksi %2$s</string>
-    <string name="notice_placed_video_call">%s soitti videopuhelun.</string>
-    <string name="notice_placed_voice_call">%s soitti äänipuhelun.</string>
-    <string name="notice_answered_call">%s vastasi puheluun.</string>
-    <string name="notice_ended_call">%s lopetti puhelun.</string>
-    <string name="notice_made_future_room_visibility">%1$s muutti tulevan huonehistorian näkyväksi seuraaville: %2$s</string>
-    <string name="notice_room_visibility_invited">kaikki huoneen jäsenet, kutsumisestaan asti.</string>
-    <string name="notice_room_visibility_joined">kaikki huoneen jäsenet, liittymisestään asti.</string>
-    <string name="notice_room_visibility_shared">kaikki huoneen jäsenet.</string>
-    <string name="notice_room_visibility_world_readable">kaikki.</string>
-    <string name="notice_room_visibility_unknown">tuntematon (%s).</string>
-    <string name="notice_end_to_end">%1$s otti käyttöön osapuolten välisen salauksen (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s lähetti VoIP-konferenssipyynnön</string>
-    <string name="notice_voip_started">VoIP-konferenssi alkoi</string>
-    <string name="notice_voip_finished">VoIP-konferenssi päättyi</string>
-    <string name="notice_avatar_changed_too">(myös kuva vaihdettiin)</string>
-    <string name="notice_room_name_removed">%1$s poisti huoneen nimen</string>
-    <string name="notice_room_topic_removed">%1$s poisti huoneen aiheen</string>
-    <string name="notice_profile_change_redacted">%1$s päivitti profiilinsa %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s lähetti liittymiskutsun huoneeseen käyttäjälle %2$s</string>
-    <string name="notice_room_third_party_registered_invite">%1$s hyväksyi kutsun käyttäjän %2$s puolesta</string>
-    <string name="notice_crypto_unable_to_decrypt">** Salauksen purku epäonnistui: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Lähettäjän laite ei ole lähettänyt avaimia tähän viestiin.</string>
-    <string name="unable_to_send_message">Viestin lähetys epäonnistui</string>
-    <string name="message_failed_to_upload">Kuvan lataaminen epäonnistui</string>
-    <string name="network_error">Verkkovirhe</string>
-    <string name="matrix_error">Matrix-virhe</string>
-    <string name="room_error_join_failed_empty_room">Tällä hetkellä ei ole mahdollista liittyä uudelleen tyhjään huoneeseen.</string>
-    <string name="encrypted_message">Salattu viesti</string>
-    <string name="medium_email">Sähköpostiosoite</string>
-    <string name="medium_phone_number">Puhelinnumero</string>
-    <string name="could_not_redact">Takaisinveto epäonnistui</string>
-    <string name="summary_message">%1$s: %2$s</string>
-    <!-- Room display name -->
-    <string name="room_displayname_invite_from">Kutsu käyttäjältä %s</string>
-    <!-- Grammar problem -->
-    <string name="room_displayname_room_invite">Huonekutsu</string>
-    <string name="room_displayname_two_members">%1$s ja %2$s</string>
-    <string name="room_displayname_empty_room">Tyhjä huone</string>
-    <string name="summary_user_sent_sticker">%1$s lähetti tarran.</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s ja yksi muu</item>
-        <item quantity="other">%1$s ja %2$d muuta</item>
-    </plurals>
-    <string name="notice_event_redacted">Viesti poistettu</string>
-    <string name="notice_event_redacted_by">%1$s poisti viestin</string>
-    <string name="notice_event_redacted_with_reason">Viesti poistettu [syy: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">%1$s poisti viestin [syy: %2$s]</string>
-    <string name="initial_sync_start_importing_account">Alkusynkronointi:
-\nTuodaan tiliä…</string>
-    <string name="initial_sync_start_importing_account_crypto">Alkusynkronointi:
-\nTuodaan kryptoa</string>
-    <string name="initial_sync_start_importing_account_rooms">Alkusynkronointi:
-\nTuodaan huoneita</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Alkusynkronointi:
-\nTuodaan liityttyjä huoneita</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Alkusynkronointi:
-\nTuodaan kutsuttuja huoneita</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Alkusynkronointi:
-\nTuodaan poistuttuja huoneita</string>
-    <string name="initial_sync_start_importing_account_groups">Alkusynkronointi:
-\nTuodaan yhteisöjä</string>
-    <string name="initial_sync_start_importing_account_data">Alkusynkronointi:
-\nTuodaan tilin tietoja</string>
-    <string name="notice_room_update">%s päivitti tämän huoneen.</string>
-    <string name="event_status_sending_message">Lähetetään viestiä…</string>
-    <string name="clear_timeline_send_queue">Tyhjennä lähetysjono</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s veti takaisin käyttäjän %2$s liittymiskutsun huoneeseen</string>
-    <string name="notice_room_invite_no_invitee_with_reason">Henkilön %1$s kutsu. Syy: %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s kutsui henkilön %2$s. Syy: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s kutsui sinut. Syy: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s liittyi huoneeseen. Syy: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s poistui huoneesta. Syy: %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s hylkäsi kutsun. Syy: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s poisti käyttäjän %2$s huoneesta. Syy: %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s poisti porttikiellon käyttäjältä %2$s. Syy: %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s antoi porttikiellon käyttäjälle %2$s. Syy: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s lähetti kutsun liittyä huoneeseen käyttäjälle %2$s. Syy: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s kumosi kutsun liittyä huoneeseen käyttäjälle %2$s. Syy: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s hyväksyi kutsun liityäkseen huoneeseen %2$s. Syy: %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s veti takaisin käyttäjän %2$s kutsun. Syy: %3$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s lisäsi tälle huoneelle osoitteen %2$s.</item>
-        <item quantity="other">%1$s lisäsi tälle huoneelle osoitteet %2$s.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s poisti tältä huoneelta osoitteen %2$s.</item>
-        <item quantity="other">%1$s poisti tältä huoneelta osoitteet %3$s.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s lisäsi tälle huoneelle osoitteen %2$s ja poisti osoitteen %3$s.</string>
-    <string name="notice_room_canonical_alias_set">%1$s asetti tämän huoneen pääosoitteeksi %2$s.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s poisti tämän huoneen pääosoitteen.</string>
-    <string name="notice_room_guest_access_can_join">%1$s salli vieraiden liittyä huoneeseen.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s esti vieraita liittymästä huoneeseen.</string>
-    <string name="notice_end_to_end_ok">%1$s laittoi päälle osapuolten välisen salauksen.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s laittoi päälle osapuolisten välisen salauksen (tuntematon algoritmi %2$s).</string>
-    <string name="key_verification_request_fallback_message">%s haluaa varmentaa salausavaimesi, mutta asiakasohjelmasi ei tue keskustelun aikana tapahtuvaa avainten varmennusta. Joudut käyttämään perinteistä varmennustapaa.</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Hyväksyit käyttäjän %1$s kutsun. Syy: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Peruutit kutsun liittyä huoneeseen käyttäjältä %1$s. Syy: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Lähetit kutsun liittyä huoneeseen käyttäjälle %1$s. Syy: %2$s</string>
-    <string name="notice_room_ban_with_reason_by_you">Estit käyttäjän %1$s. Syy: %2$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Peruutit eston %1$s. Syy: %2$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Poistit käyttäjän %1$s. Syy: %2$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Hylkäsit kutsun. Syy: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">Lähdit. Syy: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s lähti. Syy: %2$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Poistuit huoneesta. Syy: %1$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">Liityit. Syy: %1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s liittyi. Syy: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">Liityit ryhmään. Syy: %1$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Kutsuit %1$s. Syy: %2$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">Kutsusi. Syy: %1$s</string>
-    <string name="room_displayname_empty_room_was">Tyhjä huone (oli %s)</string>
-    <string name="room_displayname_4_members">%1$s, %2$s, %3$s ja %4$s</string>
-    <string name="room_displayname_3_members">%1$s, %2$s ja %3$s</string>
-    <string name="power_level_custom_no_value">Mukautettu</string>
-    <string name="power_level_custom">Mukautettu (%1$d)</string>
-    <string name="power_level_default">Oletus</string>
-    <string name="power_level_moderator">Valvoja</string>
-    <string name="power_level_admin">Ylläpitäjä</string>
-    <string name="notice_widget_modified">%1$s muutti %2$s sovelmaa</string>
-    <string name="notice_widget_removed_by_you">Poistit %1$s sovelman</string>
-    <string name="notice_widget_removed">%1$s poisti %2$s sovelman</string>
-    <string name="notice_widget_added_by_you">Lisäsit %1$s sovelman</string>
-    <string name="notice_widget_added">%1$s lisäsi %2$s sovelman</string>
-    <string name="notice_widget_modified_by_you">Muutit %1$s sovelmaa</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Hyväksyit kutsun henkilölle %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">Peruutit kutsun henkilöltä %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s peruutti kutsun henkilöltä %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Peruutit henkilön %1$s kutsun liittyä ryhmään</string>
-    <string name="notice_direct_room_third_party_invite_by_you">Kutsuit %1$s</string>
-    <string name="notice_direct_room_third_party_invite">%1$s kutsui %2$s</string>
-    <string name="notice_room_third_party_invite_by_you">Lähetit henkilölle %1$s kutsun liittyä huoneeseen</string>
-    <string name="notice_profile_change_redacted_by_you">Päivitit profiilisi %1$s</string>
-    <string name="notice_room_avatar_removed_by_you">Poistit huoneen profiilikuvan</string>
-    <string name="notice_room_avatar_removed">%1$s poisti huoneen profiilikuvan</string>
-    <string name="notice_room_topic_removed_by_you">Poistit huoneen aiheen</string>
-    <string name="notice_room_name_removed_by_you">Poistit huoneen nimen</string>
-    <string name="notice_requested_voip_conference_by_you">Pyysit ryhmäpuhelua</string>
-    <string name="notice_room_server_acl_allow_is_empty">🎉 Kaikki palvelimet on estetty osallistumasta! Tätä huonetta ei voi enää käyttää.</string>
-    <string name="notice_room_server_acl_updated_no_change">Ei muutosta.</string>
-    <string name="notice_room_server_acl_updated_was_banned">• Palvelimet jotka %s poistettiin estolistalta.</string>
-    <string name="notice_room_server_acl_updated_banned">• Palvelimen haku %s on nyt kielletty.</string>
-    <string name="notice_room_server_acl_set_allowed">• Palvelimen haku %s on sallittu.</string>
-    <string name="notice_room_server_acl_set_banned">• Palvelimen haku %s on kielletty.</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s on estänyt vieraita liittymästä huoneeseen.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">Estit vieraita liittymästä huoneeseen.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Annoit vieraille luvan liittyä huoneeseen.</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">Annoit vieraille luvan liittyä tänne.</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s on antanut vieraille luvan liittyä tänne.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Poistit tämän huoneen pääosoitteen.</string>
-    <string name="notice_end_to_end_ok_by_you">Otit käyttöön päästä päähän -salauksen.</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">Olet estänyt vieraiden liittymisen huoneeseen.</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Otit päästä päähän -salauksen käyttöön (tuntematon algoritmi %1$s).</string>
-    <string name="notice_direct_room_update_by_you">Päivitit tässä.</string>
-    <string name="notice_direct_room_update">%s päivitti täällä.</string>
-    <string name="notice_room_update_by_you">Päivitit tämän huoneen.</string>
-    <string name="notice_end_to_end_by_you">Otit päästä päähän -salauksen käyttöön (%1$s)</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">Teit tulevista viesteistä näkyviä käyttäjälle %1$s</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s teki tulevista viesteistä näkyviä käyttäjälle %2$s</string>
-    <string name="notice_made_future_room_visibility_by_you">Teit tulevan huonehistorian näkyväksi %1$s</string>
-    <string name="notice_ended_call_by_you">Lopetit puhelun.</string>
-    <string name="notice_answered_call_by_you">Vastasit puheluun.</string>
-    <string name="notice_call_candidates_by_you">Lähetit tietoja puhelun valmistelemiseksi.</string>
-    <string name="notice_call_candidates">%s lähetti tietoja puhelun valmistelemiseksi.</string>
-    <string name="notice_placed_voice_call_by_you">Aloitit äänipuhelun.</string>
-    <string name="notice_placed_video_call_by_you">Aloitit videopuhelun.</string>
-    <string name="notice_room_name_changed_by_you">Vaihdoit huoneen nimeksi: %1$s</string>
-    <string name="notice_room_avatar_changed_by_you">Vaihdoit huoneen profiilikuvaa</string>
-    <string name="notice_room_avatar_changed">%1$s muutti huoneen profiilikuvaa</string>
-    <string name="notice_room_topic_changed_by_you">Vaihdoit aiheen: %1$s</string>
-    <string name="notice_display_name_removed_by_you">Poistit nimimerkkisi (se oli %1$s)</string>
-    <string name="notice_display_name_changed_from_by_you">Vaihdoit nimimerkkisi %1$s nimeen %2$s</string>
-    <string name="notice_display_name_set_by_you">Asetit nimimerkiksesi %1$s</string>
-    <string name="notice_room_invite_no_invitee_by_you">Kutsusi</string>
-    <string name="notice_avatar_url_changed_by_you">Vaihdoit profiilikuvaasi</string>
-    <string name="notice_room_withdraw_by_you">Peruutit %1$sn kutsun</string>
-    <string name="notice_room_ban_by_you">Estit %1$s</string>
-    <string name="notice_room_unban_by_you">Poistit eston %1$s</string>
-    <string name="notice_room_kick_by_you">Poistit %1$s</string>
-    <string name="notice_room_reject_by_you">Hylkäsit kutsun</string>
-    <string name="notice_direct_room_leave_by_you">Poistuit huoneesta</string>
-    <string name="notice_direct_room_leave">%1$s poistui huoneesta</string>
-    <string name="notice_room_leave_by_you">Poistuit huoneesta</string>
-    <string name="notice_direct_room_join_by_you">Liityit</string>
-    <string name="notice_direct_room_join">%1$s liittyi</string>
-    <string name="notice_room_join_by_you">Liityit huoneeseen</string>
-    <string name="notice_room_invite_by_you">Kutsuit %1$s</string>
-    <string name="notice_direct_room_created_by_you">Loit keskustelun</string>
-    <string name="notice_direct_room_created">%1$s loi keskustelun</string>
-    <string name="notice_room_created_by_you">Loit huoneen</string>
-    <string name="notice_room_created">%1$s loi huoneen</string>
-    <string name="summary_you_sent_sticker">Lähetit tarran.</string>
-    <string name="summary_you_sent_image">Lähetit kuvan.</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-fr/strings.xml b/matrix-sdk-android/src/main/res/values-fr/strings.xml
deleted file mode 100644
index f49c54a8ba9288a8f2abf3f649e1f79d8f4ea608..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-fr/strings.xml
+++ /dev/null
@@ -1,239 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s : %2$s</string>
-    <string name="summary_user_sent_image">%1$s a envoyé une image.</string>
-    <string name="notice_room_invite_no_invitee">invitation de %s</string>
-    <string name="notice_room_invite">%1$s a invité %2$s</string>
-    <string name="notice_room_invite_you">%1$s vous a invité</string>
-    <string name="notice_room_join">%1$s a rejoint le salon</string>
-    <string name="notice_room_leave">%1$s est parti du salon</string>
-    <string name="notice_room_reject">%1$s a rejeté l’invitation</string>
-    <string name="notice_room_kick">%1$s a expulsé %2$s</string>
-    <string name="notice_room_unban">%1$s a révoqué l\'exclusion de %2$s</string>
-    <string name="notice_room_ban">%1$s a exclus %2$s</string>
-    <string name="notice_room_withdraw">%1$s a annulé l’invitation de %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s a changé d’avatar</string>
-    <string name="notice_display_name_set">%1$s a modifié son nom affiché en %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s a modifié son nom affiché de %2$s en %3$s</string>
-    <string name="notice_display_name_removed">%1$s a supprimé son nom affiché (précédemment %2$s)</string>
-    <string name="notice_room_topic_changed">%1$s a changé le sujet en : %2$s</string>
-    <string name="notice_room_name_changed">%1$s a changé le nom du salon en : %2$s</string>
-    <string name="notice_placed_video_call">%s a passé un appel vidéo.</string>
-    <string name="notice_placed_voice_call">%s a passé un appel vocal.</string>
-    <string name="notice_answered_call">%s a répondu à l’appel.</string>
-    <string name="notice_ended_call">%s a raccroché.</string>
-    <string name="notice_made_future_room_visibility">%1$s a rendu l’historique futur du salon visible pour %2$s</string>
-    <string name="notice_room_visibility_invited">tous les membres du salon, depuis qu’ils ont été invités.</string>
-    <string name="notice_room_visibility_joined">tous les membres du salon, depuis qu’ils l’ont rejoint.</string>
-    <string name="notice_room_visibility_shared">tous les membres du salon.</string>
-    <string name="notice_room_visibility_world_readable">n’importe qui.</string>
-    <string name="notice_room_visibility_unknown">inconnu (%s).</string>
-    <string name="notice_end_to_end">%1$s a activé le chiffrement de bout en bout (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s a demandé une téléconférence VoIP</string>
-    <string name="notice_voip_started">Téléconférence VoIP démarrée</string>
-    <string name="notice_voip_finished">Téléconférence VoIP terminée</string>
-    <string name="notice_avatar_changed_too">(l’avatar a aussi changé)</string>
-    <string name="notice_room_name_removed">%1$s a supprimé le nom du salon</string>
-    <string name="notice_room_topic_removed">%1$s a supprimé le sujet du salon</string>
-    <string name="notice_profile_change_redacted">%1$s a mis à jour son profil %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s a envoyé une invitation à %2$s pour rejoindre le salon</string>
-    <string name="notice_room_third_party_registered_invite">%1$s a accepté l’invitation pour %2$s</string>
-    <string name="notice_crypto_unable_to_decrypt">** Déchiffrement impossible : %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">L’appareil de l’expéditeur ne nous a pas envoyé les clés pour ce message.</string>
-    <string name="could_not_redact">Effacement impossible</string>
-    <string name="unable_to_send_message">Envoi du message impossible</string>
-    <string name="message_failed_to_upload">L’envoi de l’image a échoué</string>
-    <string name="network_error">Erreur de réseau</string>
-    <string name="matrix_error">Erreur de Matrix</string>
-    <string name="room_error_join_failed_empty_room">Il est impossible pour le moment de revenir dans un salon vide.</string>
-    <string name="encrypted_message">Message chiffré</string>
-    <string name="medium_email">Adresse e-mail</string>
-    <string name="medium_phone_number">Numéro de téléphone</string>
-    <string name="summary_user_sent_sticker">%1$s a envoyé un sticker.</string>
-    <string name="room_displayname_invite_from">Invitation de %s</string>
-    <string name="room_displayname_room_invite">Invitation au salon</string>
-    <string name="room_displayname_empty_room">Salon vide</string>
-    <string name="room_displayname_two_members">%1$s et %2$s</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s et 1 autre</item>
-        <item quantity="other">%1$s et %2$d autres</item>
-    </plurals>
-    <string name="notice_event_redacted">Message supprimé</string>
-    <string name="notice_event_redacted_by">Message supprimé par %1$s</string>
-    <string name="notice_event_redacted_with_reason">Message supprimé [motif : %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Message supprimé par %1$s [motif : %2$s]</string>
-    <string name="initial_sync_start_importing_account">Synchronisation initiale :
-\nImportation du compte…</string>
-    <string name="initial_sync_start_importing_account_crypto">Synchronisation initiale :
-\nImportation de la cryptographie</string>
-    <string name="initial_sync_start_importing_account_rooms">Synchronisation initiale :
-\nImportation des salons</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Synchronisation initiale :
-\nImportation des salons que vous avez rejoints</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Synchronisation initiale :
-\nImportation des salons où vous avez été invités</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Synchronisation initiale :
-\nImportation des salons que vous avez quittés</string>
-    <string name="initial_sync_start_importing_account_groups">Synchronisation initiale :
-\nImportation des communautés</string>
-    <string name="initial_sync_start_importing_account_data">Synchronisation initiale :
-\nImportation des données du compte</string>
-    <string name="notice_room_update">%s a mis à niveau ce salon.</string>
-    <string name="event_status_sending_message">Envoi du message…</string>
-    <string name="clear_timeline_send_queue">Vider la file d’envoi</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s a révoqué l’invitation pour %2$s à rejoindre le salon</string>
-    <string name="notice_room_invite_no_invitee_with_reason">Invitation de %1$s. Raison : %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s a invité %2$s. Raison : %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s vous a invité. Raison : %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s a rejoint le salon. Raison : %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s est parti du salon. Raison : %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s a refusé l’invitation. Raison : %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s a expulsé %2$s. Raison : %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s a révoqué l\'exclusion de %2$s. Raison : %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s a exclus %2$s. Raison : %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s a envoyé une invitation à %2$s pour rejoindre le salon. Raison : %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s a révoqué l’invitation de %2$s à rejoindre le salon. Raison : %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s a accepté l’invitation pour %2$s. Raison : %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s a annulé l’invitation de %2$s. Raison : %3$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s a ajouté %2$s comme adresse pour ce salon.</item>
-        <item quantity="other">%1$s a ajouté %2$s comme adresses pour ce salon.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s a supprimé %2$s comme adresse pour ce salon.</item>
-        <item quantity="other">%1$s a supprimé %3$s comme adresses pour ce salon.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s a ajouté %2$s et supprimé %3$s comme adresses pour ce salon.</string>
-    <string name="notice_room_canonical_alias_set">%1$s a défini %2$s comme adresse principale pour ce salon.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s a supprimé l’adresse principale de ce salon.</string>
-    <string name="notice_room_guest_access_can_join">%1$s a autorisé les visiteurs à rejoindre le salon.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s a empêché les visiteurs de rejoindre le salon.</string>
-    <string name="notice_end_to_end_ok">%1$s a activé le chiffrement de bout en bout.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s a activé le chiffrement de bout en bout (algorithme %2$s inconnu).</string>
-    <string name="key_verification_request_fallback_message">%s demande à vérifier votre clé, mais votre client ne supporte pas la vérification de clés dans les discussions. Vous devrez utiliser l’ancienne vérification de clés pour vérifier les clés.</string>
-    <string name="notice_room_created">%1$s a créé le salon</string>
-    <string name="notice_direct_room_update_by_you">Vous avez mis cet endroit à niveau.</string>
-    <string name="notice_direct_room_update">%s a mis cet endroit à niveau.</string>
-    <string name="notice_room_update_by_you">Vous avez mis à niveau ce salon.</string>
-    <string name="notice_room_kick_by_you">Vous avez expulsé %1$s</string>
-    <string name="notice_room_reject_by_you">Vous avez rejeté l\'invitation</string>
-    <string name="notice_direct_room_leave_by_you">Vous avez quitté le salon</string>
-    <string name="notice_direct_room_leave">%1$s a quitté le salon</string>
-    <string name="notice_room_leave_by_you">Vous avez quitté le salon</string>
-    <string name="notice_direct_room_join_by_you">Vous avez rejoint le salon</string>
-    <string name="notice_direct_room_join">%1$s a rejoint le salon</string>
-    <string name="notice_room_join_by_you">Vous avez rejoint le salon</string>
-    <string name="notice_room_invite_by_you">Vous avez invité %1$s</string>
-    <string name="notice_direct_room_created_by_you">Vous avez créé la discussion</string>
-    <string name="notice_direct_room_created">%1$s a créé la discussion</string>
-    <string name="notice_room_created_by_you">Vous avez créé le salon</string>
-    <string name="notice_room_invite_no_invitee_by_you">Votre invitation</string>
-    <string name="summary_you_sent_sticker">Vous avez envoyé un autocollant.</string>
-    <string name="summary_you_sent_image">Vous avez envoyé une image.</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Vous avez activé le chiffrement de bout en bout (algorithme %1$s inconnu).</string>
-    <string name="notice_end_to_end_ok_by_you">Vous avez activé le chiffrement de bout en bout.</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">Vous avez empêché les visiteurs de rejoindre le salon.</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s a empêché les visiteurs de rejoindre le salon.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">Vous avez empêché les visiteurs de rejoindre le salon.</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">Vous avez autorisé les visiteurs à venir ici.</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s a autorisé les visiteurs à venir ici.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Vous avez autorisé les visiteurs à rejoindre le salon.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Vous avez supprimé l’adresse principale de ce salon.</string>
-    <string name="notice_room_canonical_alias_set_by_you">Vous avez défini %1$s comme adresse principale pour ce salon.</string>
-    <string name="notice_room_aliases_added_and_removed_by_you">Vous avez ajouté %1$s et supprimé %2$s comme adresses pour ce salon.</string>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">Vous avez supprimé %1$s comme adresse pour ce salon.</item>
-        <item quantity="other">Vous avez supprimé %1$s comme adresses pour ce salon.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">Vous avez ajouté %1$s comme adresse pour ce salon.</item>
-        <item quantity="other">Vous avez ajouté %1$s comme adresses pour ce salon.</item>
-    </plurals>
-    <string name="notice_room_withdraw_with_reason_by_you">Vous avez annulé l’invitation de %1$s. Raison : %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Vous avez accepté l’invitation pour %1$s. Raison : %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Vous avez révoqué l’invitation de %1$s à rejoindre le salon. Raison : %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Vous avez envoyé une invitation à %1$s pour rejoindre le salon. Raison : %2$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Vous avez refusé l’invitation. Raison : %1$s</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">Vous êtes parti. Raison : %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s est parti. Raison : %2$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Vous êtes parti du salon. Raison : %1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s rejoint. Raison : %2$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">Vous avez rejoint. Raison : %1$s</string>
-    <string name="notice_room_join_with_reason_by_you">Vous avez rejoint le salon. Raison : %1$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Vous avez invité %1$s. Raison : %2$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">Votre invitation. Raison %1$s</string>
-    <string name="notice_power_level_diff">%1$s de %2$s à %3$s</string>
-    <string name="notice_power_level_changed">%1$s a modifié le niveau de pouvoir de %2$s.</string>
-    <string name="notice_power_level_changed_by_you">Vous avez modifié le niveau de pouvoir de %1$s.</string>
-    <string name="power_level_custom_no_value">Personnalisé</string>
-    <string name="power_level_custom">Personnalisé (%1$d)</string>
-    <string name="power_level_default">Défaut</string>
-    <string name="power_level_moderator">Modérateur</string>
-    <string name="power_level_admin">Admin</string>
-    <string name="notice_widget_modified_by_you">Vous avez modifié le widget %1$s</string>
-    <string name="notice_widget_modified">%1$s a modifié le widget %2$s</string>
-    <string name="notice_widget_removed_by_you">Vous avez supprimé le widget %1$s</string>
-    <string name="notice_widget_removed">%1$s a supprimé le widget %2$s</string>
-    <string name="notice_widget_added_by_you">Vous avez ajouté le widget %1$s</string>
-    <string name="notice_widget_added">%1$s a ajouté le widget %2$s</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Vous avez accepté l’invitation pour %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">Vous avez révoqué l\'invitation pour %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s a révoqué l\'invitation pour %2$s</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">Vous avez rendu les futurs messages visible pour %1$s</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s a rendu les futurs messages visible pour %2$s</string>
-    <string name="notice_room_avatar_removed_by_you">Vous avez supprimé l\'avatar du salon</string>
-    <string name="notice_room_avatar_removed">%1$s a supprimé l\'avatar du salon</string>
-    <string name="notice_room_name_removed_by_you">Vous avez supprimé le nom du salon</string>
-    <string name="notice_requested_voip_conference_by_you">Vous avez demandé une téléconférence VoIP</string>
-    <string name="notice_end_to_end_by_you">Vous avez activé le chiffrement de bout en bout (%1$s)</string>
-    <string name="notice_made_future_room_visibility_by_you">Vous avez rendu l’historique futur du salon visible pour %1$s</string>
-    <string name="notice_ended_call_by_you">Vous avez raccroché.</string>
-    <string name="notice_answered_call_by_you">Vous avez répondu à l’appel.</string>
-    <string name="notice_call_candidates_by_you">Vous avez envoyé les données pour configurer l\'appel.</string>
-    <string name="notice_call_candidates">%s a envoyé les données pour configurer l\'appel.</string>
-    <string name="notice_placed_voice_call_by_you">Vous avez passé un appel vocal.</string>
-    <string name="notice_placed_video_call_by_you">Vous avez passé un appel vidéo.</string>
-    <string name="notice_room_name_changed_by_you">Vous avez changé le nom du salon en : %1$s</string>
-    <string name="notice_room_avatar_changed_by_you">Vous avez modifié l\'avatar du salon</string>
-    <string name="notice_room_avatar_changed">%1$s a modifié l\'avatar du salon</string>
-    <string name="notice_display_name_changed_from_by_you">Vous avez modifié votre nom affiché de %1$s en %2$s</string>
-    <string name="notice_display_name_set_by_you">Vous avez modifié votre nom affiché en %1$s</string>
-    <string name="notice_avatar_url_changed_by_you">Vous avez changé votre avatar</string>
-    <string name="notice_room_withdraw_by_you">Vous avez annulé l’invitation de %1$s</string>
-    <string name="notice_room_topic_changed_by_you">Vous avez changé le sujet en : %1$s</string>
-    <string name="notice_display_name_removed_by_you">Vous avez supprimé votre nom affiché (précédemment %1$s)</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Vous avez révoqué l’invitation pour %1$s à rejoindre le salon</string>
-    <string name="notice_direct_room_third_party_invite_by_you">Vous avez invité %1$s</string>
-    <string name="notice_direct_room_third_party_invite">%1$s a invité %2$s</string>
-    <string name="notice_room_third_party_invite_by_you">Vous avez envoyé une invitation à %1$s pour rejoindre le salon</string>
-    <string name="notice_profile_change_redacted_by_you">Vous avez mis à jour votre profile %1$s</string>
-    <string name="notice_room_topic_removed_by_you">Vous avez supprimé le sujet du salon</string>
-    <string name="notice_room_ban_with_reason_by_you">Vous avez exclus %1$s. Raison : %2$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Vous avez révoqué l\'exclusion de %1$s. Raison : %2$s</string>
-    <string name="notice_room_ban_by_you">Vous avez exclus %1$s</string>
-    <string name="notice_room_unban_by_you">Vous avez révoqué l\'exclusion de %1$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Vous avez expulsé %1$s. Raison : %2$s</string>
-    <string name="room_displayname_empty_room_was">Salon vide (était %s)</string>
-    <plurals name="room_displayname_four_and_more_members">
-        <item quantity="one">%1$s, %2$s, %3$s et %4$d autre</item>
-        <item quantity="other">%1$s, %2$s, %3$s et %4$d autres</item>
-    </plurals>
-    <string name="room_displayname_4_members">%1$s, %2$s, %3$s et %4$s</string>
-    <string name="room_displayname_3_members">%1$s, %2$s et %3$s</string>
-    <string name="notice_room_server_acl_allow_is_empty">🎉 Tous les serveurs sont interdits de participer ! Ce salon ne peut plus être utilisé.</string>
-    <string name="notice_room_server_acl_updated_no_change">Aucun changement.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_not_allowed">• Les serveurs correspondant à des IP littérales sont maintenant interdits.</string>
-    <string name="notice_room_server_acl_set_banned">• Les serveurs correspondant à %s sont interdits.</string>
-    <string name="notice_room_server_acl_set_ip_literals_not_allowed">• Les serveurs correspondants à des IP littérales sont interdites.</string>
-    <string name="notice_room_server_acl_set_ip_literals_allowed">• Les serveurs correspondants à des IP littérales sont autorisés.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_allowed">• Les serveurs correspondants à des IP littérales sont maintenant autorisées.</string>
-    <string name="notice_room_server_acl_updated_was_allowed">• Les serveurs correspondant à %s sont supprimés de la liste autorisée.</string>
-    <string name="notice_room_server_acl_updated_allowed">• les serveur correspondant à %s sont maintenant autorisés.</string>
-    <string name="notice_room_server_acl_updated_was_banned">• Les serveurs correspondant à %s étaient supprimés de la liste des interdits.</string>
-    <string name="notice_room_server_acl_updated_banned">• Les serveurs correspondant à %s sont maintenant interdits.</string>
-    <string name="notice_room_server_acl_updated_title_by_you">Vous avez changé les droits ACL du serveur pour ce salon.</string>
-    <string name="notice_room_server_acl_updated_title">%s a changé les droits ACL du serveur pour ce salon.</string>
-    <string name="notice_room_server_acl_set_allowed">• Les serveurs correspondant à %s sont autorisés.</string>
-    <string name="notice_room_server_acl_set_title_by_you">Vous avez paramétré les ACL pour ce salon.</string>
-    <string name="notice_room_server_acl_set_title">%s paramètre les autorisations étendues (ACL) du serveur pour ce salon.</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-gl/strings.xml b/matrix-sdk-android/src/main/res/values-gl/strings.xml
deleted file mode 100644
index 77868e7df3a8f96a6976659cb4b63400aeadb841..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-gl/strings.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-    <string name="medium_email">Enderezo de correo</string>
-    <string name="message_failed_to_upload">Fallo ao subir a páxina</string>
-
-
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s enviou unha imaxe.</string>
-    <string name="summary_user_sent_sticker">%1$s enviou unha icona.</string>
-
-    <string name="notice_room_invite_no_invitee">Convite de %s</string>
-    <string name="notice_room_invite">%1$s convidou a %2$s</string>
-    <string name="notice_room_invite_you">%1$s convidouno</string>
-    <string name="notice_room_join">%1$s entrou</string>
-    <string name="notice_room_leave">%1$s saíu</string>
-    <string name="notice_room_reject">%1$s rexeitou o convite</string>
-    <string name="notice_room_kick">%1$s expulsou a %2$s</string>
-    <string name="notice_room_unban">%1$s desbloqueou a %2$s</string>
-    <string name="notice_room_ban">%1$s bloqueou a %2$s</string>
-    <string name="notice_room_withdraw">%1$s cancelou o convite de %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s cambiou o seu avatar</string>
-    <string name="notice_display_name_set">%1$s cambiou o seu nome a %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s cambiou o seu nome de %2$s a %3$s</string>
-    <string name="notice_display_name_removed">%1$s borrou o seu nome público (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s cambiou o tema desta sala para: %2$s</string>
-    <string name="notice_room_name_changed">%1$s cambiou o nome desta sala para: %2$s</string>
-    <string name="notice_placed_video_call">%s iniciou unha chamada de vídeo.</string>
-    <string name="notice_placed_voice_call">%s iniciou unha chamada de voz.</string>
-    <string name="notice_answered_call">%s respondeu á chamada.</string>
-    <string name="notice_ended_call">%s terminou a chamada.</string>
-    <string name="notice_made_future_room_visibility">%1$s fixo visible os próximos históricos para %2$s</string>
-    <string name="notice_room_visibility_invited">toda a xente que integran esta sala, desde o momento en que foron convidados.</string>
-    <string name="notice_room_visibility_joined">todas a xente da sala, desde o momento en que entraron.</string>
-    <string name="notice_room_visibility_shared">todas os membros da sala.</string>
-    <string name="notice_room_visibility_world_readable">todos.</string>
-    <string name="notice_room_visibility_unknown">descoñecido (%s).</string>
-    <string name="notice_end_to_end">%1$s activou a criptografía par-a-par (%2$s)</string>
-
-    <string name="notice_requested_voip_conference">%1$s solicitou unha conferencia VoIP</string>
-    <string name="notice_voip_started">A conferencia VoIP comenzou</string>
-    <string name="notice_voip_finished">A conferencia VoIP terminou</string>
-
-    <string name="notice_avatar_changed_too">(o avatar tamén foi cambiado)</string>
-    <string name="notice_room_name_removed">%1$s borrou o nome da sala</string>
-    <string name="notice_room_topic_removed">%1$s removeu o tema da sala</string>
-    <string name="notice_profile_change_redacted">%1$s actualizou o seu perfil %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s envioulle un convite a %2$s para que entre na sala</string>
-    <string name="notice_room_third_party_registered_invite">%1$s aceptou o convite para %2$s</string>
-
-    <string name="notice_crypto_unable_to_decrypt">** Imposíbel descifrar: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">O dispositivo do que envía non enviou as chaves desta mensaxe.</string>
-
-    <string name="could_not_redact">Non se puido redactar</string>
-    <string name="unable_to_send_message">Non foi posíbel enviar a mensaxe</string>
-
-    <string name="network_error">Erro da conexión</string>
-    <string name="matrix_error">Erro de Matrix</string>
-
-    <string name="room_error_join_failed_empty_room">Aínda non é posíbel volver a entrar nunha sala baleira.</string>
-
-    <string name="encrypted_message">Mensaxe cifrada</string>
-
-    <string name="medium_phone_number">Número de teléfono</string>
-
-    <string name="room_displayname_two_members">%1$s e %2$s</string>
-
-
-</resources>
diff --git a/matrix-sdk-android/src/main/res/values-hr/strings_sas.xml b/matrix-sdk-android/src/main/res/values-hr/strings_sas.xml
new file mode 100644
index 0000000000000000000000000000000000000000..423ab20186897d412c7c5057c0e4bd7a68e6b25c
--- /dev/null
+++ b/matrix-sdk-android/src/main/res/values-hr/strings_sas.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- Generated file, do not edit -->
+    <string name="verification_emoji_dog">pas</string>
+    <string name="verification_emoji_cat">mačka</string>
+    <string name="verification_emoji_lion">lav</string>
+    <string name="verification_emoji_horse">konj</string>
+    <string name="verification_emoji_unicorn">jednorog</string>
+    <string name="verification_emoji_pig">svinja</string>
+    <string name="verification_emoji_elephant">slon</string>
+    <string name="verification_emoji_rabbit">zec</string>
+    <string name="verification_emoji_panda">panda</string>
+    <string name="verification_emoji_rooster">kokot</string>
+    <string name="verification_emoji_penguin">pingvin</string>
+    <string name="verification_emoji_turtle">kornjača</string>
+    <string name="verification_emoji_fish">riba</string>
+    <string name="verification_emoji_octopus">hobotnica</string>
+    <string name="verification_emoji_butterfly">leptir</string>
+    <string name="verification_emoji_flower">svijet</string>
+    <string name="verification_emoji_tree">drvo</string>
+    <string name="verification_emoji_cactus">kaktus</string>
+    <string name="verification_emoji_mushroom">gljiva</string>
+    <string name="verification_emoji_globe">Globus</string>
+    <string name="verification_emoji_moon">mjesec</string>
+    <string name="verification_emoji_cloud">oblak</string>
+    <string name="verification_emoji_fire">vatra</string>
+    <string name="verification_emoji_banana">banana</string>
+    <string name="verification_emoji_apple">jabuka</string>
+    <string name="verification_emoji_strawberry">jagoda</string>
+    <string name="verification_emoji_corn">kukuruza</string>
+    <string name="verification_emoji_pizza">pizza</string>
+    <string name="verification_emoji_cake">torta</string>
+    <string name="verification_emoji_heart">srca</string>
+    <string name="verification_emoji_smiley">smajlića</string>
+    <string name="verification_emoji_robot">robot</string>
+    <string name="verification_emoji_hat">kapa</string>
+    <string name="verification_emoji_glasses">naočale</string>
+    <string name="verification_emoji_spanner">ključ</string>
+    <string name="verification_emoji_santa">deda Mraz</string>
+    <string name="verification_emoji_thumbs_up">palac gore</string>
+    <string name="verification_emoji_umbrella">kišobran</string>
+    <string name="verification_emoji_hourglass">pješčani sat</string>
+    <string name="verification_emoji_clock">sat</string>
+    <string name="verification_emoji_gift">poklon</string>
+    <string name="verification_emoji_light_bulb">žarulja</string>
+    <string name="verification_emoji_book">knjiga</string>
+    <string name="verification_emoji_pencil">olovka</string>
+    <string name="verification_emoji_paperclip">spajalica</string>
+    <string name="verification_emoji_scissors">Å¡kare</string>
+    <string name="verification_emoji_lock">zaključati</string>
+    <string name="verification_emoji_key">ključ</string>
+    <string name="verification_emoji_hammer">čekić</string>
+    <string name="verification_emoji_telephone">telefon</string>
+    <string name="verification_emoji_flag">zastava</string>
+    <string name="verification_emoji_train">vlak</string>
+    <string name="verification_emoji_bicycle">bicikl</string>
+    <string name="verification_emoji_aeroplane">avion</string>
+    <string name="verification_emoji_rocket">raketa</string>
+    <string name="verification_emoji_trophy">trofej</string>
+    <string name="verification_emoji_ball">lopta</string>
+    <string name="verification_emoji_guitar">gitara</string>
+    <string name="verification_emoji_trumpet">truba</string>
+    <string name="verification_emoji_bell">zvono</string>
+    <string name="verification_emoji_anchor">sidro</string>
+    <string name="verification_emoji_headphones">slušalice</string>
+    <string name="verification_emoji_folder">mapu</string>
+    <string name="verification_emoji_pin">pribadača</string>
+</resources>
diff --git a/matrix-sdk-android/src/main/res/values-hu/strings.xml b/matrix-sdk-android/src/main/res/values-hu/strings.xml
deleted file mode 100644
index 49238ee8ff15e865f77b8026585f82fd7fa8ada6..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-hu/strings.xml
+++ /dev/null
@@ -1,178 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s küldött egy képet.</string>
-    <string name="notice_room_invite_no_invitee">%s meghívója</string>
-    <string name="notice_room_invite">%1$s meghívta: %2$s</string>
-    <string name="notice_room_invite_you">%1$s meghívott</string>
-    <string name="notice_room_join">%1$s belépett a szobába</string>
-    <string name="notice_room_leave">%1$s kilépett a szobából</string>
-    <string name="notice_room_reject">%1$s elutasította a meghívást</string>
-    <string name="notice_room_kick">%1$s kidobta: %2$s</string>
-    <string name="notice_room_unban">%1$s feloldotta %2$s tiltását</string>
-    <string name="notice_room_ban">%1$s kitiltotta: %2$s</string>
-    <string name="notice_room_withdraw">%1$s visszavonta %2$s meghívását</string>
-    <string name="notice_avatar_url_changed">%1$s megváltoztatta a profilképét</string>
-    <string name="notice_display_name_set">%1$s megváltoztatta a megjelenő nevét erre: %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s megváltoztatta a megjelenítendő nevét erről: %2$s, erre: %3$s</string>
-    <string name="notice_display_name_removed">%1$s eltávolította a megjelenítendő nevét (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s megváltoztatta a témát erre: %2$s</string>
-    <string name="notice_room_name_changed">%1$s megváltoztatta a szoba nevét erre: %2$s</string>
-    <string name="notice_placed_video_call">%s videóhívást kezdeményezett.</string>
-    <string name="notice_placed_voice_call">%s hanghívást indított.</string>
-    <string name="notice_answered_call">%s fogadta a hívást.</string>
-    <string name="notice_ended_call">%s befejezte a hívást.</string>
-    <string name="notice_made_future_room_visibility">%1$s láthatóvá tette a jövőbeli előzményeket %2$s</string>
-    <string name="notice_room_visibility_invited">a szoba összes tagja számára, a meghívásuk időpontjától kezdve.</string>
-    <string name="notice_room_visibility_joined">a szoba összes tagja számára, a csatlakozásuk időpontjától kezdve.</string>
-    <string name="notice_room_visibility_shared">az összes szobatag számára.</string>
-    <string name="notice_room_visibility_world_readable">bárki.</string>
-    <string name="notice_room_visibility_unknown">ismeretlen (%s).</string>
-    <string name="notice_end_to_end">%1$s bekapcsolta a végpontok közötti titkosítást (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s hanghívás konferenciát kérelmezett</string>
-    <string name="notice_voip_started">Hanghívás konferencia elindult</string>
-    <string name="notice_voip_finished">Hanghívás konferencia befejeződött</string>
-    <string name="notice_avatar_changed_too">(a profilkép is megváltozott)</string>
-    <string name="notice_room_name_removed">%1$s eltávolította a szoba nevét</string>
-    <string name="notice_room_topic_removed">%1$s eltávolította a szoba témáját</string>
-    <string name="notice_profile_change_redacted">%1$s megváltoztatta a(z) %2$s profilját</string>
-    <string name="notice_room_third_party_invite">%1$s meghívót küldött %2$s számára, hogy csatlakozzon a szobához</string>
-    <string name="notice_room_third_party_registered_invite">%1$s elfogadta a meghívót ebbe: %2$s</string>
-    <string name="notice_crypto_unable_to_decrypt">** Visszafejtés sikertelen: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">A küldő eszköze nem küldte el a kulcsokat ehhez az üzenethez.</string>
-    <string name="could_not_redact">Kitakarás sikertelen</string>
-    <string name="unable_to_send_message">Üzenet küldése sikertelen</string>
-    <string name="message_failed_to_upload">Kép feltöltése sikertelen</string>
-    <string name="network_error">Hálózati hiba</string>
-    <string name="matrix_error">Matrix hiba</string>
-    <string name="room_error_join_failed_empty_room">Jelenleg nem lehetséges újracsatlakozni egy üres szobához.</string>
-    <string name="encrypted_message">Titkosított üzenet</string>
-    <string name="medium_email">E-mail cím</string>
-    <string name="medium_phone_number">Telefonszám</string>
-    <string name="summary_user_sent_sticker">%1$s küldött egy matricát.</string>
-    <string name="room_displayname_invite_from">Meghívó tőle: %s</string>
-    <string name="room_displayname_room_invite">Meghívó egy szobába</string>
-    <string name="room_displayname_two_members">%1$s és %2$s</string>
-    <string name="room_displayname_empty_room">Ãœres szoba</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s és 1 másik</item>
-        <item quantity="other">%1$s és %2$d másik</item>
-    </plurals>
-    <string name="notice_event_redacted">Üzenet eltávolítva</string>
-    <string name="notice_event_redacted_by">Üzenetet eltávolította: %1$s</string>
-    <string name="notice_event_redacted_with_reason">Üzenet eltávolítva [ok: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Üzenetet eltávolította: %1$s [ok: %2$s]</string>
-    <string name="initial_sync_start_importing_account">Induló szinkronizáció:
-\nFiók betöltése…</string>
-    <string name="initial_sync_start_importing_account_crypto">Induló szinkronizáció:
-\nTitkosítás betöltése</string>
-    <string name="initial_sync_start_importing_account_rooms">Induló szinkronizáció:
-\nSzobák betöltése</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Induló szinkronizáció:
-\nCsatlakozott szobák betöltése</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Induló szinkronizáció:
-\nMeghívott szobák betöltése</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Induló szinkronizáció:
-\nElhagyott szobák betöltése</string>
-    <string name="initial_sync_start_importing_account_groups">Induló szinkronizáció:
-\nKözösségek betöltése</string>
-    <string name="initial_sync_start_importing_account_data">Induló szinkronizáció:
-\nFiók adatok betöltése</string>
-    <string name="notice_room_update">%s frissítette ezt a szobát.</string>
-    <string name="event_status_sending_message">Üzenet küldése…</string>
-    <string name="clear_timeline_send_queue">Küldő sor ürítése</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s visszavonta %2$s meghívását, hogy csatlakozzon a szobához</string>
-    <string name="notice_room_invite_no_invitee_with_reason">%1$s meghívója. Ok: %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s meghívta őt: %2$s. Ok: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s meghívott. Ok: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s belépett a szobába. Mert: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s kilépett a szobából. Ok: %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s visszautasította a meghívót. Ok: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s kirúgta őt: %2$s. Ok: %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s visszaengedte Å‘t: %2$s. Ok: %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s kitiltotta Å‘t: %2$s. Ok: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s meghívót küldött neki: %2$s, hogy lépjen be a szobába. Ok: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s visszavonta %2$s meghívóját a szobába való belépéshez. Ok: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s elfogadta a meghívót ide: %2$s. Ok: %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s visszavonta %2$s meghívóját. Ok: %3$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s ezt a címet adta a szobához: %2$s.</item>
-        <item quantity="other">%1$s ezeket a címeket adta a szobához: %2$s.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s ezt a címet törölte a szobából: %3$s.</item>
-        <item quantity="other">%1$s ezeket a címeket törölte a szobából: %3$s.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s a szobához adta ezeket:%2$s és törölte ezeket: %3$s.</string>
-    <string name="notice_room_canonical_alias_set">%1$s a szoba elsődleges címét erre állította be: %2$s.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s eltávolította a szoba elsődleges címét.</string>
-    <string name="notice_room_guest_access_can_join">%1$s megengedte a vendégeknek, hogy belépjenek ebbe a szobába.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s megtiltotta a vendégeknek, hogy belépjenek ebbe a szobába.</string>
-    <string name="notice_end_to_end_ok">%1$s bekapcsolta a végpontok közötti titkosítást.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s bekapcsolta a végpontok közötti titkosítást (ismeretlen algoritmus %2$s).</string>
-    <string name="key_verification_request_fallback_message">%s kéri a kulcsok ellenőrzését de a kliens nem támogatja a szobán belüli kulcs ellenőrzést. A hagyományos módon kell ellenőrizned a kulcsokat.</string>
-    <string name="notice_room_created">%1$s szobát készített</string>
-    <string name="notice_answered_call_by_you">Fogadtad a hívást.</string>
-    <string name="notice_ended_call_by_you">Befejezted a hívást.</string>
-    <string name="notice_call_candidates_by_you">Hívási adatokat küldtél.</string>
-    <string name="notice_call_candidates">%s hívási adatokat küldött.</string>
-    <string name="notice_placed_voice_call_by_you">Hanghívást indítottál.</string>
-    <string name="notice_placed_video_call_by_you">Videóhívást indítottál.</string>
-    <string name="notice_room_avatar_changed_by_you">Megváltoztattad a szoba képét</string>
-    <string name="notice_room_avatar_changed">%1$s megváltoztatta a szoba képét</string>
-    <string name="notice_room_topic_changed_by_you">Megváltoztattad a témát erre: %1$s</string>
-    <string name="notice_avatar_url_changed_by_you">Megváltoztattad a profilképed</string>
-    <string name="notice_room_withdraw_by_you">Visszavontad %1$s meghívóját</string>
-    <string name="notice_room_ban_by_you">Kitiltottad %1$s felhasználót</string>
-    <string name="notice_room_unban_by_you">Visszaengedted %1$s felhasználót</string>
-    <string name="notice_room_kick_by_you">Kirúgtad %1$s felhasználót</string>
-    <string name="notice_room_reject_by_you">Visszautasítottad a meghívót</string>
-    <string name="notice_direct_room_leave_by_you">Elhagytad a szobát</string>
-    <string name="notice_direct_room_leave">%1$s elhagyta a szobát</string>
-    <string name="notice_room_leave_by_you">Elhagytad a szobát</string>
-    <string name="notice_direct_room_join_by_you">Csatlakoztál</string>
-    <string name="notice_direct_room_join">%1$s csatlakozott</string>
-    <string name="notice_room_join_by_you">Beléptél a szobába</string>
-    <string name="notice_room_invite_by_you">Meghívtad: %1$s</string>
-    <string name="notice_direct_room_created_by_you">Létrehoztad a beszélgetést</string>
-    <string name="notice_direct_room_created">%1$s létrehozta a beszélgetést</string>
-    <string name="notice_room_created_by_you">Létrehoztad a szobát</string>
-    <string name="summary_you_sent_sticker">Matricát küldtél.</string>
-    <string name="summary_you_sent_image">Képet küldtél.</string>
-    <string name="power_level_custom_no_value">Saját</string>
-    <string name="power_level_custom">Saját (%1$d)</string>
-    <string name="power_level_default">Alapértelmezett</string>
-    <string name="power_level_moderator">Moderátor</string>
-    <string name="power_level_admin">Admin</string>
-    <string name="notice_widget_modified_by_you">Ön megváltoztatta a %1$s kisalkalmazást</string>
-    <string name="notice_widget_modified">%1$s megváltoztatta a %2$s kisalkalmazást</string>
-    <string name="notice_widget_removed_by_you">Ön eltávolította a %1$s kisalkalmazást</string>
-    <string name="notice_widget_removed">%1$s eltávolította a %2$s kisalkalmazást</string>
-    <string name="notice_widget_added_by_you">Ön hozzáadott egy %1$s kisalkalmazást</string>
-    <string name="notice_widget_added">%1$s hozzáadott egy %2$s kisalkalmazást</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Ön elfogadta a meghívót ehhez: %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">Ön visszavonta %1$s felhasználó meghívóját</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s visszavonta %2$s felhasználó meghívóját</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Ön visszavonta %1$s felhasználó meghívóját</string>
-    <string name="notice_direct_room_third_party_invite_by_you">Ön meghívta %1$s felhasználót</string>
-    <string name="notice_direct_room_third_party_invite">%1$s meghívta %2$s felhasználót</string>
-    <string name="notice_room_third_party_invite_by_you">Ön meghívót küldött %1$s felhasználónak, hogy csatlakozzon a szobához</string>
-    <string name="notice_profile_change_redacted_by_you">Ön frissítette a saját profilját %1$s</string>
-    <string name="notice_room_avatar_removed_by_you">Ön eltávolította a szoba képét</string>
-    <string name="notice_room_avatar_removed">%1$s eltávolította a szoba képét</string>
-    <string name="notice_room_topic_removed_by_you">Ön eltávolította a szoba témáját</string>
-    <string name="notice_room_name_removed_by_you">Ön eltávolította a szoba nevét</string>
-    <string name="notice_requested_voip_conference_by_you">Ön videókonferencia kezdeményezését kérte</string>
-    <string name="notice_direct_room_update_by_you">Ön frissítette ezt a szobát.</string>
-    <string name="notice_direct_room_update">%s frissítette a szobát.</string>
-    <string name="notice_room_update_by_you">Ön frissítette ezt a szobát.</string>
-    <string name="notice_end_to_end_by_you">Ön bekapcsolta a végpontok közötti titkosítást (%1$s)</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">Ön elérhetővé tette a jövőbeni üzeneteket %1$s</string>
-    <string name="notice_made_future_room_visibility_by_you">Ön elérhetővé tette a jövőbeni üzeneteket %1$s</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s elérhetővé tette a jövőbeni üzeneteket %2$s</string>
-    <string name="notice_room_name_changed_by_you">Ön megváltoztatta a szoba nevét erre: %1$s</string>
-    <string name="notice_display_name_removed_by_you">Ön eltávolította a saját megjelenített nevét (%1$s volt)</string>
-    <string name="notice_display_name_changed_from_by_you">Ön megváltoztatta a saját megjelenítési nevét erről: %1$s, erre: %2$s</string>
-    <string name="notice_display_name_set_by_you">Ön beállította a saját megjelenítési nevét erre: %1$s</string>
-    <string name="notice_room_invite_no_invitee_by_you">Az ön meghívása</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-id/strings.xml b/matrix-sdk-android/src/main/res/values-id/strings.xml
deleted file mode 100644
index 157b23d4017375bb9e9a253e19884046623e20fe..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-id/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="room_displayname_invite_from">Undang dari %s</string>
-    <string name="room_displayname_room_invite">Undangan Ruang</string>
-    <string name="room_displayname_two_members">%1$s dan %2$s</string>
-
-    <string name="room_displayname_empty_room">Ruang kosong</string>
-
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="other">%1$s dan %2$d yang lain</item>
-    </plurals>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-in/strings.xml b/matrix-sdk-android/src/main/res/values-in/strings.xml
deleted file mode 100644
index 157b23d4017375bb9e9a253e19884046623e20fe..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-in/strings.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="room_displayname_invite_from">Undang dari %s</string>
-    <string name="room_displayname_room_invite">Undangan Ruang</string>
-    <string name="room_displayname_two_members">%1$s dan %2$s</string>
-
-    <string name="room_displayname_empty_room">Ruang kosong</string>
-
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="other">%1$s dan %2$d yang lain</item>
-    </plurals>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-is/strings.xml b/matrix-sdk-android/src/main/res/values-is/strings.xml
deleted file mode 100644
index ecf19edb8ac48e58d210944b4618108df363de25..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-is/strings.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s sendi mynd.</string>
-    <string name="summary_user_sent_sticker">%1$s sendi límmerki.</string>
-
-    <string name="notice_room_invite_no_invitee">%s sendi boð um þátttöku</string>
-    <string name="notice_room_invite">%1$s bauð %2$s</string>
-    <string name="notice_room_invite_you">%1$s bauð þér</string>
-    <string name="notice_room_join">%1$s gekk í hópinn</string>
-    <string name="notice_room_leave">%1$s hætti</string>
-    <string name="notice_room_reject">%1$s hafnaði boðinu</string>
-    <string name="notice_room_kick">%1$s sparkaði %2$s</string>
-    <string name="notice_room_unban">%1$s afbannaði %2$s</string>
-    <string name="notice_room_ban">%1$s bannaði %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s breyttu auðkennismynd sinni</string>
-    <string name="notice_room_visibility_invited">allir meðlimir spjallrásar, síðan þeim var boðið.</string>
-    <string name="notice_room_visibility_joined">allir meðlimir spjallrásar, síðan þeir skráðu sig.</string>
-    <string name="notice_room_visibility_shared">allir meðlimir spjallrásar.</string>
-    <string name="notice_room_visibility_world_readable">hver sem er.</string>
-    <string name="notice_room_visibility_unknown">óþekktur (%s).</string>
-    <string name="notice_voip_started">VoIP-símafundur hafinn</string>
-    <string name="notice_voip_finished">VoIP-símafundi lokið</string>
-
-    <string name="notice_avatar_changed_too">(einnig var skipt um auðkennismynd)</string>
-    <string name="notice_crypto_unable_to_decrypt">** Mistókst að afkóða: %s **</string>
-
-    <string name="unable_to_send_message">Gat ekki sent skilaboð</string>
-
-    <string name="message_failed_to_upload">Gat ekki sent inn mynd</string>
-
-    <string name="network_error">Villa í netkerfi</string>
-    <string name="matrix_error">Villa í Matrix</string>
-
-    <string name="encrypted_message">Dulrituð skilaboð</string>
-
-    <string name="medium_email">Tölvupóstfang</string>
-    <string name="medium_phone_number">Símanúmer</string>
-
-    <string name="notice_room_withdraw">%1$s tók til baka boð frá %2$s</string>
-    <string name="notice_display_name_set">%1$s setti birtingarnafn sitt sem %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s breytti birtingarnafni sínu úr %2$s í %3$s</string>
-    <string name="notice_display_name_removed">%1$s fjarlægði birtingarnafn sitt (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s breytti umræðuefninu í: %2$s</string>
-    <string name="notice_room_name_changed">%1$s breytti heiti spjallrásarinnar í: %2$s</string>
-    <string name="notice_placed_video_call">%s hringdi myndsamtal.</string>
-    <string name="notice_placed_voice_call">%s hringdi raddsamtal.</string>
-    <string name="notice_answered_call">%s svaraði símtalinu.</string>
-    <string name="notice_ended_call">%s lauk símtalinu.</string>
-    <string name="notice_end_to_end">%1$s kveikti á enda-í-enda dulritun (%2$s)</string>
-
-    <string name="notice_requested_voip_conference">%1$s bað um VoIP-símafund</string>
-    <string name="notice_room_name_removed">%1$s fjarlægði heiti spjallrásar</string>
-    <string name="notice_room_topic_removed">%1$s fjarlægði umfjöllunarefni spjallrásar</string>
-    <string name="notice_made_future_room_visibility">%1$s gerði ferilskrá spjallrásar héðan í frá sýnilega fyrir %2$s</string>
-    <string name="notice_profile_change_redacted">%1$s uppfærði notandasniðið sitt %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s sendi boð til %2$s um þátttöku í spjallrásinni</string>
-    <string name="notice_room_third_party_registered_invite">%1$s samþykkti boð um að taka þátt í %2$s</string>
-
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Tæki sendandans hefur ekki sent okkur dulritunarlyklana fyrir þessi skilaboð.</string>
-
-    <string name="could_not_redact">Gat ekki ritstýrt</string>
-    <string name="room_error_join_failed_empty_room">Ekki er í augnablikinu hægt að taka aftur þátt í spjallrás sem er tóm.</string>
-
-    <string name="room_displayname_room_invite">Boð á spjallrás</string>
-    <string name="room_displayname_two_members">%1$s og %2$s</string>
-
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s og 1 annar</item>
-        <item quantity="other">%1$s og %2$d aðrir</item>
-    </plurals>
-
-    <string name="room_displayname_empty_room">Tóm spjallrás</string>
-    <string name="room_displayname_invite_from">Boð frá %s</string>
-
-</resources>
diff --git a/matrix-sdk-android/src/main/res/values-it/strings.xml b/matrix-sdk-android/src/main/res/values-it/strings.xml
deleted file mode 100644
index ec19cd5c17e072ae7c7add030363b3135bd92210..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-it/strings.xml
+++ /dev/null
@@ -1,262 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s ha inviato un\'immagine.</string>
-    <string name="notice_room_invite_no_invitee">Invito di %s</string>
-    <string name="notice_room_invite">%1$s ha invitato %2$s</string>
-    <string name="notice_room_invite_you">%1$s ti ha invitato</string>
-    <string name="notice_room_join">%1$s è entrato nella stanza</string>
-    <string name="notice_room_leave">%1$s è uscito dalla stanza</string>
-    <string name="notice_room_reject">%1$s ha rifiutato l\'invito</string>
-    <string name="notice_room_kick">%1$s ha buttato fuori %2$s</string>
-    <string name="notice_room_unban">%1$s ha tolto il bando a %2$s</string>
-    <string name="notice_room_ban">%1$s ha bandito %2$s</string>
-    <string name="notice_room_withdraw">%1$s ha revocato l\'invito per %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s ha modificato il suo avatar</string>
-    <string name="notice_display_name_set">%1$s hanno cambiato il nome visualizzato con %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s ha cambiato il nome visualizzato da %2$s a %3$s</string>
-    <string name="notice_display_name_removed">%1$s ha rimosso il nome visibile (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s ha cambiato l\'argomento con: %2$s</string>
-    <string name="notice_room_name_changed">%1$s ha cambiato il nome della stanza con: %2$s</string>
-    <string name="notice_placed_video_call">%s ha iniziato una chiamata video.</string>
-    <string name="notice_placed_voice_call">%s ha iniziato una chiamata vocale.</string>
-    <string name="notice_answered_call">%s ha risposto alla chiamata.</string>
-    <string name="notice_ended_call">%s ha terminato la chiamata.</string>
-    <string name="notice_made_future_room_visibility">%1$s ha reso la futura cronologia della stanza visibile a %2$s</string>
-    <string name="notice_room_visibility_invited">tutti i membri della stanza, dal momento del loro invito.</string>
-    <string name="notice_room_visibility_joined">tutti i membri della stanza, dal momento in cui sono entrati.</string>
-    <string name="notice_room_visibility_shared">tutti i membri della stanza.</string>
-    <string name="notice_room_visibility_world_readable">chiunque.</string>
-    <string name="notice_room_visibility_unknown">sconosciuto (%s).</string>
-    <string name="notice_end_to_end">%1$s ha attivato la crittografia end-to-end (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s ha richiesto una conferenza VoIP</string>
-    <string name="notice_voip_started">Conferenza VoIP iniziata</string>
-    <string name="notice_voip_finished">Conferenza VoIP terminata</string>
-    <string name="notice_avatar_changed_too">(anche l\'avatar è cambiato)</string>
-    <string name="notice_room_name_removed">%1$s ha rimosso il nome della stanza</string>
-    <string name="notice_room_topic_removed">%1$s ha rimosso l\'argomento della stanza</string>
-    <string name="notice_profile_change_redacted">%1$s ha aggiornato il profilo %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s ha mandato un invito a %2$s per unirsi alla stanza</string>
-    <string name="notice_room_third_party_registered_invite">%1$s ha accettato l\'invito per %2$s</string>
-    <string name="notice_crypto_unable_to_decrypt">** Impossibile decriptare: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Il dispositivo del mittente non ci ha inviato le chiavi per questo messaggio.</string>
-    <string name="could_not_redact">Impossibile revisionare</string>
-    <string name="unable_to_send_message">Impossibile inviare il messaggio</string>
-    <string name="message_failed_to_upload">Invio dell\'immagine fallito</string>
-    <string name="network_error">Errore di rete</string>
-    <string name="matrix_error">Errore di Matrix</string>
-    <string name="room_error_join_failed_empty_room">Al momento non è possibile rientrare in una stanza vuota.</string>
-    <string name="encrypted_message">Messaggio criptato</string>
-    <string name="medium_email">Indirizzo email</string>
-    <string name="medium_phone_number">Numero di telefono</string>
-    <string name="summary_user_sent_sticker">%1$s ha inviato un adesivo.</string>
-    <!-- Room display name -->
-    <string name="room_displayname_invite_from">Invito da %s</string>
-    <string name="room_displayname_room_invite">Invito nella stanza</string>
-    <string name="room_displayname_two_members">%1$s e %2$s</string>
-    <string name="room_displayname_empty_room">Stanza vuota</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s e 1 altro</item>
-        <item quantity="other">%1$s e %2$d altri</item>
-    </plurals>
-    <string name="notice_event_redacted">Messaggio rimosso</string>
-    <string name="notice_event_redacted_by">Messaggio rimosso da %1$s</string>
-    <string name="notice_event_redacted_with_reason">Messaggio rimosso [motivo: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Messaggio rimosso da %1$s [motivo: %2$s]</string>
-    <string name="initial_sync_start_importing_account">Sync iniziale:
-\nImportazione account…</string>
-    <string name="initial_sync_start_importing_account_crypto">Sync iniziale:
-\nImportazione cifratura</string>
-    <string name="initial_sync_start_importing_account_rooms">Sync iniziale:
-\nImportazione stanze</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Sync iniziale:
-\nImportazione stanze partecipate</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Sync iniziale:
-\nImportazione stanze invitate</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Sync iniziale:
-\nImportazione stanze lasciate</string>
-    <string name="initial_sync_start_importing_account_groups">Sync iniziale:
-\nImportazione comunità</string>
-    <string name="initial_sync_start_importing_account_data">Sync iniziale:
-\nImportazione dati account</string>
-    <string name="notice_room_update">%s ha aggiornato questa stanza.</string>
-    <string name="event_status_sending_message">Invio messaggio in corso …</string>
-    <string name="clear_timeline_send_queue">Cancella la coda di invio</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s ha revocato l\'invito a %2$s di unirsi alla stanza</string>
-    <string name="notice_room_invite_no_invitee_with_reason">Invito di %1$s. Motivo: %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s ha invitato %2$s. Motivo: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s ti ha invitato. Motivo: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s è entrato nella stanza. Motivo: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s è uscito dalla stanza. Motivo: %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s ha rifiutato l\'invito. Motivo: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s ha buttato fuori %2$s. Motivo: %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s ha riammesso %2$s. Motivo: %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s ha bandito %2$s. Motivo: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s ha inviato un invito a %2$s di unirsi alla stanza. Motivo: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s ha revocato l\'invito a %2$s di unirsi alla stanza. Motivo: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s ha accettato l\'invito per %2$s. Motivo: %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s ha rifiutato l\'invito di %2$s. Motivo: %3$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s ha aggiunto %2$s come indirizzo per questa stanza.</item>
-        <item quantity="other">%1$s ha aggiunto %2$s come indirizzi per questa stanza.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s ha rimosso %2$s come indirizzo per questa stanza.</item>
-        <item quantity="other">%1$s ha rimosso %2$s come indirizzi per questa stanza.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s ha aggiunto %2$s e rimosso %3$s come indirizzi per questa stanza.</string>
-    <string name="notice_room_canonical_alias_set">%1$s ha impostato l\'indirizzo principale per questa stanza a %2$s.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s ha rimosso l\'indirizzo principale per questa stanza.</string>
-    <string name="notice_room_guest_access_can_join">%1$s ha permesso l\'accesso alla stanza per gli ospiti.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s ha impedito l\'accesso alla stanza per gli ospiti.</string>
-    <string name="notice_end_to_end_ok">%1$s ha attivato la cifratura end-to-end.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s ha attivato la cifratura end-to-end (algoritmo %2$s non riconosciuto).</string>
-    <string name="key_verification_request_fallback_message">%s sta chiedendo di verificare la tua chiave, ma il tuo client non supporta la verifica in-chat. Dovrai usare il metodo di verifica obsoleto per verificare le chiavi.</string>
-    <string name="notice_room_created">%1$s ha creato la stanza</string>
-    <string name="summary_you_sent_image">Hai inviato un\'immagine.</string>
-    <string name="summary_you_sent_sticker">Hai inviato un adesivo.</string>
-    <string name="notice_room_invite_no_invitee_by_you">Il tuo invito</string>
-    <string name="notice_room_created_by_you">Hai creato la stanza</string>
-    <string name="notice_room_invite_by_you">Hai invitato %1$s</string>
-    <string name="notice_room_join_by_you">Sei entrato nella stanza</string>
-    <string name="notice_room_leave_by_you">Sei uscito dalla stanza</string>
-    <string name="notice_room_reject_by_you">Hai rifiutato l\'invito</string>
-    <string name="notice_room_kick_by_you">Hai buttato fuori %1$s</string>
-    <string name="notice_room_unban_by_you">Hai riammesso %1$s</string>
-    <string name="notice_room_ban_by_you">Hai bandito %1$s</string>
-    <string name="notice_room_withdraw_by_you">Hai ritirato l\'invito di %1$s</string>
-    <string name="notice_avatar_url_changed_by_you">Hai cambiato il tuo avatar</string>
-    <string name="notice_display_name_set_by_you">Hai impostato il tuo nome visualizzato a %1$s</string>
-    <string name="notice_display_name_changed_from_by_you">Hai cambiato il tuo nome visualizzato da %1$s a %2$s</string>
-    <string name="notice_display_name_removed_by_you">Hai rimosso il tuo nome visibile (era %1$s)</string>
-    <string name="notice_room_topic_changed_by_you">Hai cambiato l\'argomento a: %1$s</string>
-    <string name="notice_room_avatar_changed">%1$s ha modificato l\'avatar della stanza</string>
-    <string name="notice_room_avatar_changed_by_you">Hai modificato l\'avatar della stanza</string>
-    <string name="notice_room_name_changed_by_you">Hai cambiato il nome della stanza a: %1$s</string>
-    <string name="notice_placed_video_call_by_you">Hai iniziato una videochiamata.</string>
-    <string name="notice_placed_voice_call_by_you">Hai iniziato una telefonata.</string>
-    <string name="notice_call_candidates">%s ha inviato dati per impostare la chiamata.</string>
-    <string name="notice_call_candidates_by_you">Hai inviato dati per impostare la chiamata.</string>
-    <string name="notice_answered_call_by_you">Hai risposto alla chiamata.</string>
-    <string name="notice_ended_call_by_you">Hai terminato la chiamata.</string>
-    <string name="notice_made_future_room_visibility_by_you">Hai reso visibile la futura cronologia della stanza a %1$s</string>
-    <string name="notice_end_to_end_by_you">Hai attivato la crittografia end-to-end (%1$s)</string>
-    <string name="notice_room_update_by_you">Hai aggiornato questa stanza.</string>
-    <string name="notice_requested_voip_conference_by_you">Hai richiesto una conferenza VoIP</string>
-    <string name="notice_room_name_removed_by_you">Hai rimosso il nome della stanza</string>
-    <string name="notice_room_topic_removed_by_you">Hai rimosso l\'argomento della stanza</string>
-    <string name="notice_room_avatar_removed">%1$s ha rimosso l\'avatar della stanza</string>
-    <string name="notice_room_avatar_removed_by_you">Hai rimosso l\'avatar della stanza</string>
-    <string name="notice_profile_change_redacted_by_you">Hai aggiornato il tuo profilo %1$s</string>
-    <string name="notice_room_third_party_invite_by_you">Hai mandato un invito a %1$s a unirsi alla stanza</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Hai revocato l\'invito per %1$s a unirsi alla stanza</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Hai accettato l\'invito per %1$s</string>
-    <string name="notice_widget_added">%1$s ha aggiunto il widget %2$s</string>
-    <string name="notice_widget_added_by_you">Hai aggiunto il widget %1$s</string>
-    <string name="notice_widget_removed">%1$s ha rimosso il widget %2$s</string>
-    <string name="notice_widget_removed_by_you">Hai rimosso il widget %1$s</string>
-    <string name="notice_widget_modified">%1$s ha modificato il widget %2$s</string>
-    <string name="notice_widget_modified_by_you">Hai modificato il widget %1$s</string>
-    <string name="power_level_admin">Amministratore</string>
-    <string name="power_level_moderator">Moderatore</string>
-    <string name="power_level_default">Predefinito</string>
-    <string name="power_level_custom">Personalizzato (%1$d)</string>
-    <string name="power_level_custom_no_value">Personalizzato</string>
-    <string name="notice_power_level_changed_by_you">Hai cambiato il livello di potere di %1$s.</string>
-    <string name="notice_power_level_changed">%1$s ha cambiato il livello di potere di %2$s.</string>
-    <string name="notice_power_level_diff">%1$s da %2$s a %3$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">Il tuo invito. Motivo: %1$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Hai invitato %1$s. Motivo: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">Sei entrato nella stanza. Motivo: %1$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Sei uscito dalla stanza. Motivo: %1$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Hai rifiutato l\'invito. Motivo: %1$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Hai buttato fuori %1$s. Motivo: %2$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Hai riammesso %1$s. Motivo: %2$s</string>
-    <string name="notice_room_ban_with_reason_by_you">Hai bandito %1$s. Motivo: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Hai mandato un invito a %1$s a unirsi alla stanza. Motivo: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Hai revocato l\'invito a %1$s a unirsi alla stanza. Motivo: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Hai accettato l\'invito per %1$s. Motivo: %2$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">Hai ritirato l\'invito di %1$s. Motivo: %2$s</string>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">Hai aggiunto %1$s come indirizzo per questa stanza.</item>
-        <item quantity="other">Hai aggiunto %1$s come indirizzi per questa stanza.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">Hai rimosso %1$s come indirizzo per questa stanza.</item>
-        <item quantity="other">Hai rimosso %1$s come indirizzi per questa stanza.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed_by_you">Hai aggiunto %1$s e rimosso %2$s come indirizzi per questa stanza.</string>
-    <string name="notice_room_canonical_alias_set_by_you">Hai impostato l\'indirizzo principale per questa stanza a %1$s.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Hai rimosso l\'indirizzo principale per questa stanza.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Hai permesso l\'accesso alla stanza per gli ospiti.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">Hai impedito l\'accesso alla stanza per gli ospiti.</string>
-    <string name="notice_end_to_end_ok_by_you">Hai attivato la crittografia end-to-end.</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Hai attivato la crittografia end-to-end (algoritmo %1$s sconosciuto).</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">Hai impedito l\'accesso alla stanza agli ospiti.</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s ha impedito l\'accesso alla stanza agli ospiti.</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">Hai permesso l\'accesso agli ospiti.</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s ha permesso l\'accesso agli ospiti.</string>
-    <string name="notice_direct_room_join_with_reason_by_you">Sei entrato. Motivo: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">Sei uscito. Motivo: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s è uscito. Motivo: %2$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s è entrato. Motivo: %2$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">Hai revocato l\'invito per %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s ha revocato l\'invito per %2$s</string>
-    <string name="notice_direct_room_third_party_invite_by_you">Hai invitato %1$s</string>
-    <string name="notice_direct_room_third_party_invite">%1$s ha invitato %2$s</string>
-    <string name="notice_direct_room_update_by_you">Hai aggiornato la stanza.</string>
-    <string name="notice_direct_room_update">%s ha aggiornato la stanza.</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">Hai reso visibili i messaggi futuri a %1$s</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s ha reso visibili i messaggi futuri a %2$s</string>
-    <string name="notice_direct_room_leave_by_you">Sei uscito dalla stanza</string>
-    <string name="notice_direct_room_leave">%1$s è uscito dalla stanza</string>
-    <string name="notice_direct_room_join_by_you">Sei entrato</string>
-    <string name="notice_direct_room_join">%1$s è entrato</string>
-    <string name="notice_direct_room_created_by_you">Hai creato la discussione</string>
-    <string name="notice_direct_room_created">%1$s ha creato la discussione</string>
-    <string name="room_displayname_empty_room_was">Stanza vuota (era %s)</string>
-    <plurals name="room_displayname_four_and_more_members">
-        <item quantity="one">%1$s, %2$s, %3$s e %4$d altro</item>
-        <item quantity="other">%1$s, %2$s, %3$s e altri %4$d</item>
-    </plurals>
-    <string name="room_displayname_4_members">%1$s, %2$s, %3$s e %4$s</string>
-    <string name="room_displayname_3_members">%1$s, %2$s e %3$s</string>
-    <string name="notice_room_server_acl_allow_is_empty">🎉 Tutti i server sono banditi dalla partecipazione! Questa stanza non può più essere usata.</string>
-    <string name="notice_room_server_acl_updated_no_change">Nessuna modifica.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_not_allowed">• I server che corrispondono a IP letterali ora sono banditi.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_allowed">• I server che corrispondono a IP letterali ora sono permessi.</string>
-    <string name="notice_room_server_acl_updated_was_allowed">• I server che corrispondono a %s sono stati rimossi dalla lista dei consentiti.</string>
-    <string name="notice_room_server_acl_updated_allowed">• I server che corrispondono a %s ora sono permessi.</string>
-    <string name="notice_room_server_acl_updated_was_banned">• I server che corrispondono a %s sono stati rimossi dalla lista di ban.</string>
-    <string name="notice_room_server_acl_updated_banned">• I server che corrispondono a %s ora sono banditi.</string>
-    <string name="notice_room_server_acl_updated_title_by_you">Hai cambiato le ACL del server per questa stanza.</string>
-    <string name="notice_room_server_acl_updated_title">%s ha cambiato le ACL del server per questa stanza.</string>
-    <string name="notice_room_server_acl_set_ip_literals_not_allowed">• I server che corrispondono a IP letterali sono banditi.</string>
-    <string name="notice_room_server_acl_set_ip_literals_allowed">• I server che corrispondono a IP letterali sono permessi.</string>
-    <string name="notice_room_server_acl_set_allowed">• I server che corrispondono a %s sono permessi.</string>
-    <string name="notice_room_server_acl_set_banned">• I server che corrispondono a %s sono banditi.</string>
-    <string name="notice_room_server_acl_set_title_by_you">Hai impostato le ACL del server per questa stanza.</string>
-    <string name="notice_room_server_acl_set_title">%s ha impostato le ACL del server per questa stanza.</string>
-    <string name="notice_room_canonical_alias_no_change_by_you">Hai cambiato gli indirizzi per questa stanza.</string>
-    <string name="notice_room_canonical_alias_no_change">%1$s ha cambiato gli indirizzi per questa stanza.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed_by_you">Hai cambiato gli indirizzi principali ed alternativi per questa stanza.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed">%1$s ha cambiato gli indirizzi principali ed alternativi per questa stanza.</string>
-    <string name="notice_room_canonical_alias_alternative_changed_by_you">Hai cambiato gli indirizzi alternativi per questa stanza.</string>
-    <string name="notice_room_canonical_alias_alternative_changed">%1$s ha cambiato gli indirizzi alternativi per questa stanza.</string>
-    <plurals name="notice_room_canonical_alias_alternative_removed_by_you">
-        <item quantity="one">Hai rimosso l\'indirizzo alternativo %1$s per questa stanza.</item>
-        <item quantity="other">Hai rimosso gli indirizzi alternativi %1$s per questa stanza.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_removed">
-        <item quantity="one">%1$s ha rimosso l\'indirizzo alternativo %2$s per questa stanza.</item>
-        <item quantity="other">%1$s ha rimosso gli indirizzi alternativi %2$s per questa stanza.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added_by_you">
-        <item quantity="one">Hai aggiunto l\'indirizzo alternativo %1$s per questa stanza.</item>
-        <item quantity="other">Hai aggiunto gli indirizzi alternativi %1$s per questa stanza.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added">
-        <item quantity="one">%1$s ha aggiunto l\'indirizzo alternativo %2$s per questa stanza.</item>
-        <item quantity="other">%1$s ha aggiunto gli indirizzi alternativi %2$s per questa stanza.</item>
-    </plurals>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-ja/strings.xml b/matrix-sdk-android/src/main/res/values-ja/strings.xml
deleted file mode 100644
index add19edfaf0ffbd8f30ef6701fc6065e273e9f6a..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-ja/strings.xml
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$sが画像を送信しました。</string>
-    <string name="summary_user_sent_sticker">%1$sがスタンプを送信しました。</string>
-    <string name="notice_room_invite_no_invitee">%sの招待</string>
-    <string name="notice_room_invite">%1$sが%2$sを招待しました</string>
-    <string name="notice_room_invite_you">%1$sがあなたを招待しました</string>
-    <string name="notice_room_join">%1$sが参加しました</string>
-    <string name="notice_room_leave">%1$sが退出しました</string>
-    <string name="notice_room_reject">%1$sが招待を断りました</string>
-    <string name="notice_room_kick">%1$sが%2$sを追放しました</string>
-    <string name="notice_room_unban">%1$sが%2$sをブロック解除しました</string>
-    <string name="notice_room_ban">%1$sが%2$sをブロックしました</string>
-    <string name="notice_room_withdraw">%1$sが%2$sの招待を撤回しました</string>
-    <string name="notice_avatar_url_changed">%1$sがアバターを変更しました</string>
-    <string name="notice_display_name_set">%1$sが表示名を%2$sに設定しました</string>
-    <string name="notice_display_name_changed_from">%1$sが表示名を%2$sから%3$sに変更しました</string>
-    <string name="notice_display_name_removed">%1$sが表示名 (%2$s) を削除しました</string>
-    <string name="notice_room_topic_changed">%1$sがテーマを%2$sに変更しました</string>
-    <string name="notice_room_name_changed">%1$sが部屋名を%2$sに変更しました</string>
-    <string name="notice_placed_video_call">%sがビデオ通話を開始しました。</string>
-    <string name="notice_placed_voice_call">%sが音声通話を開始しました。</string>
-    <string name="notice_answered_call">%sが電話に出ました。</string>
-    <string name="notice_ended_call">%sが通話を終了しました。</string>
-    <string name="room_displayname_invite_from">%sさんからの招待</string>
-    <string name="room_displayname_room_invite">部屋への招待</string>
-    <string name="room_displayname_two_members">%1$sと%2$s</string>
-    <string name="room_displayname_empty_room">空の部屋</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="other">%1$sと他%2$d名</item>
-    </plurals>
-    <string name="notice_made_future_room_visibility">%1$sは、今後の部屋履歴を%2$sに表示させました</string>
-    <string name="notice_room_visibility_invited">部屋のメンバー全員、招待された時点から。</string>
-    <string name="notice_room_visibility_joined">部屋のメンバー全員、参加した時点から。</string>
-    <string name="notice_room_visibility_shared">部屋のメンバー全員。</string>
-    <string name="notice_room_visibility_world_readable">誰でも。</string>
-    <string name="notice_room_visibility_unknown">不明 (%s)。</string>
-    <string name="notice_end_to_end">%1$s がエンドツーエンド暗号化を有効にしました (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s がVoIP会議をリクエストしました</string>
-    <string name="notice_voip_started">VoIP会議が開始されました</string>
-    <string name="notice_voip_finished">VoIP会議が終了しました</string>
-    <string name="notice_avatar_changed_too">(アバターも変更された)</string>
-    <string name="notice_room_name_removed">%1$s が部屋名を削除しました</string>
-    <string name="notice_room_topic_removed">%1$s がルームトピックを削除しました</string>
-    <string name="notice_profile_change_redacted">%1$s がプロフィール %2$s を更新しました</string>
-    <string name="notice_room_third_party_invite">%1$s は %2$s に部屋に参加するよう招待状を送りました</string>
-    <string name="notice_room_third_party_registered_invite">%1$sは%2$sの招待を受け入れました</string>
-    <string name="notice_crypto_unable_to_decrypt">** 解読できません: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">送信者の端末からこのメッセージのキーが送信されていません。</string>
-    <string name="could_not_redact">修正できませんでした</string>
-    <string name="unable_to_send_message">メッセージを送信できません</string>
-    <string name="message_failed_to_upload">画像のアップロードに失敗しました</string>
-    <string name="network_error">ネットワークエラー</string>
-    <string name="matrix_error">Matrixエラー</string>
-    <string name="room_error_join_failed_empty_room">現在空の部屋に再参加することはできません。</string>
-    <string name="encrypted_message">暗号化されたメッセージ</string>
-    <string name="medium_email">メールアドレス</string>
-    <string name="medium_phone_number">電話番号</string>
-    <string name="notice_room_avatar_changed_by_you">ルームのアバターを変更しました</string>
-    <string name="notice_room_avatar_changed">%1$sがルームのアバターを変更しました</string>
-    <string name="notice_room_topic_changed_by_you">トピックを%1$sに変更しました</string>
-    <string name="notice_display_name_removed_by_you">表示名を削除しました(%1$sでした)</string>
-    <string name="notice_display_name_changed_from_by_you">表示名を%1$sから%2$sに変更しました</string>
-    <string name="notice_display_name_set_by_you">表示名を%1$sに設定しました</string>
-    <string name="notice_avatar_url_changed_by_you">アバターを変更しました</string>
-    <string name="notice_room_withdraw_by_you">%1$sの招待を取り下げました</string>
-    <string name="notice_room_ban_by_you">%1$sをBANしました</string>
-    <string name="notice_room_unban_by_you">%1$sのBANを解除しました</string>
-    <string name="notice_room_kick_by_you">%1$sを退出させました</string>
-    <string name="notice_room_reject_by_you">招待を拒否しました</string>
-    <string name="notice_direct_room_leave_by_you">ルームから退出しました</string>
-    <string name="notice_direct_room_leave">%1$sがルームから退出しました</string>
-    <string name="notice_room_leave_by_you">ルームから退出しました</string>
-    <string name="notice_direct_room_join_by_you">参加しました</string>
-    <string name="notice_direct_room_join">%1$sが参加しました</string>
-    <string name="notice_room_join_by_you">ルームに参加しました</string>
-    <string name="notice_room_invite_by_you">%1$sを招待しました</string>
-    <string name="notice_direct_room_created_by_you">ディスカッションを作成しました</string>
-    <string name="notice_direct_room_created">%1$sがディスカッションを作成しました</string>
-    <string name="notice_room_created_by_you">ルームを作成しました</string>
-    <string name="notice_room_created">%1$sがルームを作成しました</string>
-    <string name="notice_room_invite_no_invitee_by_you">招待</string>
-    <string name="summary_you_sent_sticker">ステッカーを送信しました。</string>
-    <string name="summary_you_sent_image">画像を送信しました。</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-kab/strings.xml b/matrix-sdk-android/src/main/res/values-kab/strings.xml
deleted file mode 100644
index 8b94fad9eb35f3091a2ea486d2bd732876de4960..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-kab/strings.xml
+++ /dev/null
@@ -1,194 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s t.yuzen tugna.</string>
-    <string name="summary_you_sent_image">Tuzneḍ tugna.</string>
-    <string name="notice_room_invite_no_invitee">Tinubga n %s</string>
-    <string name="notice_room_invite_no_invitee_by_you">Tinubga-k•m</string>
-    <string name="notice_room_created">%1$s yesnulfa-d taxxamt</string>
-    <string name="notice_room_created_by_you">Tesnulfaḍ-d taxxamt-a</string>
-    <string name="notice_room_invite">%1$s inced-d %2$s</string>
-    <string name="notice_room_invite_by_you">Tnecdeḍ-d %1$s</string>
-    <string name="notice_room_invite_you">%1$s inced-ik-id</string>
-    <string name="notice_room_join">%1$s yedda ɣer texxamt</string>
-    <string name="notice_room_join_by_you">Teddiḍ ɣer texxamt</string>
-    <string name="notice_room_leave">%1$s yeǧǧa taxxamt</string>
-    <string name="notice_room_leave_by_you">Teǧǧiḍ taxxamt</string>
-    <string name="notice_room_reject">%1$s yugi/tugi tinubga</string>
-    <string name="notice_room_reject_by_you">Tufiḍ tinubga</string>
-    <string name="notice_room_kick">%1$s yessufeɣ %2$s</string>
-    <string name="notice_room_kick_by_you">Tessufɣeḍ %1$s</string>
-    <string name="notice_avatar_url_changed_by_you">Tbeddleḍ avatar-inek·inem</string>
-    <string name="power_level_admin">Anedbal</string>
-    <string name="power_level_moderator">Aseɣyad</string>
-    <string name="power_level_default">Amezwer</string>
-    <string name="power_level_custom_no_value">Sagen</string>
-    <string name="notice_power_level_diff">%1$s seg %2$s ɣer %3$s</string>
-    <string name="message_failed_to_upload">Tegguma ad d-tali tugna</string>
-    <string name="medium_email">Tansa n yimayl</string>
-    <string name="summary_user_sent_sticker">%1$s azen astiker.</string>
-    <string name="summary_you_sent_sticker">Tuzneḍ amenṭaḍ.</string>
-    <string name="notice_room_unban">%1$s yekkes agdal i %2$s</string>
-    <string name="notice_room_unban_by_you">Tekkseḍ agdal i %1$s</string>
-    <string name="notice_room_ban">%1$s igdel %2$s</string>
-    <string name="notice_room_ban_by_you">Tgedleḍ %1$s</string>
-    <string name="notice_room_withdraw">%1$s issefsex tinubga n %2$s</string>
-    <string name="notice_room_withdraw_by_you">Tesfesxeḍ tinubga n %1$s</string>
-    <string name="notice_avatar_url_changed">%1$s ibeddel avatar-is</string>
-    <string name="notice_display_name_set">%1$s isbadu isem-is i d-ittuseknen ɣer %2$s</string>
-    <string name="notice_display_name_set_by_you">Tesbaduḍ isem-ik•im i d-ittuseknen ɣer %1$s</string>
-    <string name="notice_display_name_changed_from">%1$s ibeddel isem-is i d-ittuseknen seg %2$s ɣer %3$s</string>
-    <string name="notice_display_name_changed_from_by_you">Tbeddleḍ isem-ik•im i d-ittuseknen seg %1$s ɣer %2$s</string>
-    <string name="notice_display_name_removed">%1$s yekkes isem-is i d-ittuseknen (yella %2$s)</string>
-    <string name="notice_display_name_removed_by_you">Tekkseḍ isem-ik·im yettwaskanen (d %1$s)</string>
-    <string name="notice_room_topic_changed">%1$s isnifel asentel s: %2$s</string>
-    <string name="notice_room_topic_changed_by_you">Tesnifleḍ asentel s: %1$s</string>
-    <string name="notice_room_avatar_changed">%1$s ibeddel avaá¹­ar n texxamt</string>
-    <string name="notice_room_avatar_changed_by_you">Tbeddleḍ avaṭar n texxamt</string>
-    <string name="notice_room_name_changed">%1$s ibeddel isem n texxamt s: %2$s</string>
-    <string name="notice_room_name_changed_by_you">Tbeddleḍ isem n texxamt s: %1$s</string>
-    <string name="notice_placed_video_call">%s isɛedda siwel s tvidyut.</string>
-    <string name="notice_placed_video_call_by_you">Tesɛeddaḍ siwel s tvidyut.</string>
-    <string name="notice_placed_voice_call">%s isɛedda asiwel s taɣect.</string>
-    <string name="notice_placed_voice_call_by_you">Tesɛeddaḍ siwel s taɣect.</string>
-    <string name="notice_call_candidates">%s yuzen isefka i usbadu n usiwel.</string>
-    <string name="notice_call_candidates_by_you">Tuzneḍ isefka i usbadu n usiwel.</string>
-    <string name="notice_answered_call">%s yerra ɣef usiwel.</string>
-    <string name="notice_answered_call_by_you">Terriḍ ɣef usiwel.</string>
-    <string name="notice_ended_call">%s iḥbes asiwel.</string>
-    <string name="notice_ended_call_by_you">Tḥebseḍ asiwel.</string>
-    <string name="notice_room_visibility_invited">meṛṛa iɛeggalen n texxamt, segmi ara d-ttwanecden.</string>
-    <string name="notice_room_visibility_joined">meṛṛa iɛeggalen n texamt, segmi ara d-rnun.</string>
-    <string name="notice_room_visibility_shared">meṛṛa iɛeggalen n texxamt.</string>
-    <string name="notice_room_visibility_world_readable">yal yiwen.</string>
-    <string name="notice_room_visibility_unknown">arussin (%s).</string>
-    <string name="notice_end_to_end">%1$s isermed awgelhen seg yixef ɣer yixef (%2$s)</string>
-    <string name="notice_end_to_end_by_you">Tesremdeḍ awgelhen seg yixef ɣer yixef (%1$s)</string>
-    <string name="notice_room_update">%s ileqqem taxxamt-a.</string>
-    <string name="notice_room_update_by_you">Tleqqmeḍ taxxamt-a.</string>
-    <string name="notice_requested_voip_conference">%1$s isuter-d asarag VoIP</string>
-    <string name="notice_requested_voip_conference_by_you">Tsutreḍ-d asarag VoIP</string>
-    <string name="notice_voip_started">Asarag VoIP yebda</string>
-    <string name="notice_voip_finished">Asarag VoIP yekfa</string>
-    <string name="notice_avatar_changed_too">(avatar daɣen ibeddel)</string>
-    <string name="notice_room_name_removed">%1$s yekkes isem n texxamt</string>
-    <string name="notice_room_name_removed_by_you">Tekkseḍ isem n texxamt</string>
-    <string name="notice_room_topic_removed">%1$s yekkes asentel n texxamt</string>
-    <string name="notice_room_topic_removed_by_you">Tekkseḍ asentel n texxamt</string>
-    <string name="notice_room_avatar_removed">%1$s yekkes avatar n texxamt</string>
-    <string name="notice_room_avatar_removed_by_you">Tekkseḍ avatar n texxamt</string>
-    <string name="notice_event_redacted">Izen ittwakkes</string>
-    <string name="notice_event_redacted_by">Izen ittwakkes sɣur %1$s</string>
-    <string name="notice_event_redacted_with_reason">Izen ittwakkes [tamentilt: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Izen ittwakkes sɣur %1$s [tamentilt: %2$s]</string>
-    <string name="notice_profile_change_redacted">%1$s ileqqem amaɣnu-ines %2$s</string>
-    <string name="notice_profile_change_redacted_by_you">Tleqqmeḍ amaɣnu-inek•inem %1$s</string>
-    <string name="notice_room_third_party_invite">%1$s yuzen tinubga i %2$s akken ad yeddu ɣer texxamt</string>
-    <string name="notice_room_third_party_invite_by_you">Tuzneḍ tinubga i %1$s akken ad yeddu ɣer texxamt</string>
-    <string name="notice_room_third_party_registered_invite">%1$s iqbel tinubga i %2$s</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Tqebleḍ tinubga i %1$s</string>
-    <string name="notice_widget_added">%1$s yerna awiǧit %2$s</string>
-    <string name="notice_widget_added_by_you">Terniḍ awiǧit %1$s</string>
-    <string name="notice_widget_removed">%1$s yekkes awiǧit %2$s</string>
-    <string name="notice_widget_removed_by_you">Tekkseḍ awiǧit %1$s</string>
-    <string name="notice_widget_modified">%1$s ibeddel awiǧit %2$s</string>
-    <string name="notice_widget_modified_by_you">Tbeddleḍ awiǧit %1$s</string>
-    <string name="power_level_custom">Sagen (%1$d)</string>
-    <string name="notice_power_level_changed_by_you">Tbeddleḍ aswir n tezmert n %1$s.</string>
-    <string name="notice_power_level_changed">%1$s ibeddel aswir n tezmert n %2$s.</string>
-    <string name="notice_crypto_unable_to_decrypt">** Awgelhen d awezɣi: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Ibenk n umazan ur aɣ-d-yuzin ara tisura i yizen-a.</string>
-    <string name="unable_to_send_message">Tuzna n yizen d tawezɣit</string>
-    <string name="network_error">Tuccḍa deg uẓeṭṭa</string>
-    <string name="matrix_error">Tuccḍa deg Matrix</string>
-    <string name="notice_made_future_room_visibility">%1$s iga amazray n texxamyt i d-iteddun yettban i %2$s</string>
-    <string name="notice_made_future_room_visibility_by_you">Tgiḍ amazray n texxamyt i d-iteddun yettban i %1$s</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s issefsax tinubga i %2$s i wakken ad d-yekcem ɣer texxamt</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Tesfesxeḍ tinubga i %1$s i wakken ad d-yernu ɣer texxamt</string>
-    <string name="room_error_join_failed_empty_room">D awezɣi tura ad nales ad nuɣal ɣer texxamt tilemt.</string>
-    <string name="encrypted_message">Izen yettwawgelhen</string>
-    <string name="medium_phone_number">Uṭṭun n tiliɣri</string>
-    <string name="room_displayname_invite_from">Tinubga sɣur %s</string>
-    <string name="room_displayname_room_invite">Tinubga ɣer texxamt</string>
-    <string name="room_displayname_two_members">%1$s d %2$s</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s d 1 wayeḍ</item>
-        <item quantity="other">%1$s d %2$d wiyaḍ</item>
-    </plurals>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Tremdeḍ awgelhen seg yixef ɣer yixef (alguritm %1$s ur yettwassen ara).</string>
-    <string name="key_verification_request_fallback_message">%s isuter-d ad isenqed tasarut-ik·im, maca amsaɣ-ik·im ur issefrak ara asenqed n tsura deg yidiwenniyen. Ilaq-ak·am useqdec asenqed iqdim n tsura i usenqed n tsura.</string>
-    <string name="room_displayname_empty_room">Taxxamt tilemt</string>
-    <string name="initial_sync_start_importing_account">Amtawi n tazwara:
-\nAktar n umiḍan…</string>
-    <string name="initial_sync_start_importing_account_crypto">Amtawi n tazwara:
-\nAktar n uwgelhen</string>
-    <string name="initial_sync_start_importing_account_rooms">Amtawi n tazwara:
-\nAktar n texxamin</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Amtawi n tazwara:
-\nAktar n texxamin iɣer terniḍ</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Amtawi n tazwara:
-\nAktar n texxamin iɣer tettwanecdeḍ</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Amtawi n tazwara:
-\nAktar n texxamin i teǧǧiḍ</string>
-    <string name="initial_sync_start_importing_account_groups">Amtawi n tazwara:
-\nAktar n tmezdagnutin</string>
-    <string name="initial_sync_start_importing_account_data">Amtawi n tazwara:
-\nAktar n yisefka n umiḍan</string>
-    <string name="event_status_sending_message">Tuzzna n yizen…</string>
-    <string name="notice_room_invite_no_invitee_with_reason">Tinubga n %1$s. Tamentilt: %2$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">Tinubga-k•m. Tamentilt: %1$s</string>
-    <string name="notice_room_invite_with_reason">%1$s inced %2$s. Tamentilt: %3$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Tnecdeḍ %1$s. Tamentilt: %2$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s inced-ik•ikem. Tamentilt: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s yedda ɣer texxamt. Tamentilt: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">Teddiḍ ɣer texxamt. Tamentilt: %1$s</string>
-    <string name="notice_room_leave_with_reason">%1$s yeǧǧa taxxamt. Tamentilt: %2$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Teǧǧiḍ taxxamt. Tamentilt: %1$s</string>
-    <string name="notice_room_reject_with_reason">%1$s yugi tinubga. Tamentilt: %2$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Tugiḍ tinubga. Tamentilt: %1$s</string>
-    <string name="notice_room_kick_with_reason">%1$s yessufeɣ %2$s. Tamentilt: %3$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Tessufɣeḍ %1$s. Tamentilt: %2$s</string>
-    <string name="notice_room_unban_with_reason">%1$s yekkes agdal i %2$s. Tamentilt: %3$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Tekkseḍ agdal i %1$s. Tamentilt: %2$s</string>
-    <string name="notice_room_ban_with_reason">%1$s igdel %2$s. Tamentilt: %3$s</string>
-    <string name="notice_room_ban_with_reason_by_you">Tgedleḍ %1$s. Tamentilt: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s yuzen tinubga i %2$s akken ad yeddu ɣer texxamt. Tamentilt: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Tuzneḍ tinubga i %1$s iwakken ad yeddu ɣer texxamt. Tamentilt: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s iqbel tinubga i %2$s. Tamentilt: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Tqebleḍ tinubga i %1$s. Tamentilt: %2$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s issefsex tinubga n %2$s. Tamentilt: %3$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">Tesfesxeḍ tinubga n %1$s. Tamentilt: %2$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s yerna %2$s d tansa i texxamt-a.</item>
-        <item quantity="other">%1$s yerna %2$s d tansiwin i texxamt-a.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">Terniḍ %1$s d tansa i texxamt-a.</item>
-        <item quantity="other">Terniḍ %1$s d tansiwin i texxamt-a.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s yekkes %2$s am tansa i texxamt-a.</item>
-        <item quantity="other">%1$s yekkes %3$s am tansiwin i texxamt-a.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">Tekkseḍ %1$s am tansa i texxamt-a.</item>
-        <item quantity="other">Tekkseḍ %1$s am tansiwin i texxamt-a.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s yerna %2$s terniḍ tekkseḍ %3$s am tansiwin i texxamt-a.</string>
-    <string name="notice_room_aliases_added_and_removed_by_you">Terniḍ %1$s terniḍ tekkseḍ %2$s am tansiwin i texxamt-a.</string>
-    <string name="notice_room_canonical_alias_set">%1$s isbadu %2$s am tansa tagejdant i texxamt-a.</string>
-    <string name="notice_room_canonical_alias_set_by_you">Tesbaduḍ %1$s am tansa tagejdant i texxamt-a.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s yekkes tansa tagejdant i texxamt-a.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Tekkseḍ tansa tagejdant i texxamt-a.</string>
-    <string name="notice_room_guest_access_can_join">%1$s isireg inebgawen ad ddun ɣer texxamt.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Tsirgeḍ inebgawen ad ddun ɣer texxamt.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s issewḥel inebgawen iwakken ur tteddun ara ɣer texxamt.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">Tesweḥleḍ inebgawen iwakken ur tteddun ara ɣer texxamt.</string>
-    <string name="notice_end_to_end_ok">%1$s yermed awgelhen seg yixef ɣer yixef.</string>
-    <string name="notice_end_to_end_ok_by_you">Tremdeḍ awgelhen seg yixef ɣer yixef.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s yermed awgelhen seg yixef ɣer yixef (alguritm %2$s ur yettwassen ara).</string>
-    <string name="clear_timeline_send_queue">Sfeḍ tabdart n uraǧu n tuzzna</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s issefsex tinubga n %2$s i tmerniwt ɣer texxamt. Tamentilt: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Tesfesxeḍ tinubga n %1$s i tmerna ɣer texxamt. Tamentilt: %2$s</string>
-    <string name="could_not_redact">Yegguma ad yaru</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-ko/strings.xml b/matrix-sdk-android/src/main/res/values-ko/strings.xml
deleted file mode 100644
index eee67628ebeb16deea3a02e4f8a8da576a83d100..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-ko/strings.xml
+++ /dev/null
@@ -1,101 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="notice_room_invite_no_invitee">%s님의 초대</string>
-    <string name="summary_user_sent_image">%1$s님이 사진을 보냈습니다.</string>
-    <string name="summary_user_sent_sticker">%1$s님이 스티커를 보냈습니다.</string>
-
-    <string name="notice_room_invite">%1$s님이 %2$s님을 초대했습니다</string>
-    <string name="notice_room_invite_you">%1$s님이 당신을 초대했습니다</string>
-    <string name="notice_room_join">%1$s님이 참가했습니다</string>
-    <string name="notice_room_leave">%1$s님이 떠났습니다</string>
-    <string name="notice_room_reject">%1$s님이 초대를 거부했습니다</string>
-    <string name="notice_room_kick">%1$s님이 %2$s님을 추방했습니다</string>
-    <string name="notice_room_unban">%1$s님이 %2$s님의 출입 금지를 풀었습니다</string>
-    <string name="notice_room_ban">%1$s님이 %2$s님을 출입 금지했습니다</string>
-    <string name="notice_room_withdraw">%1$s님이 %2$s님의 초대를 취소했습니다</string>
-    <string name="notice_avatar_url_changed">%1$s님이 아바타를 변경했습니다</string>
-    <string name="notice_display_name_set">%1$s님이 표시 이름을 %2$s(으)로 설정했습니다</string>
-    <string name="notice_display_name_changed_from">%1$s님이 표시 이름을 %2$s에서 %3$s(으)로 변경했습니다</string>
-    <string name="notice_display_name_removed">%1$s님이 표시 이름을 삭제했습니다 (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s님이 주제를 다음으로 변경했습니다: %2$s</string>
-    <string name="notice_room_name_changed">%1$s님이 방 이름을 다음으로 변경했습니다: %2$s</string>
-    <string name="notice_placed_video_call">%s님이 영상 통화를 걸었습니다.</string>
-    <string name="notice_placed_voice_call">%s님이 음성 통화를 걸었습니다.</string>
-    <string name="notice_answered_call">%s님이 전화를 받았습니다.</string>
-    <string name="notice_ended_call">%s님이 전화를 끊었습니다.</string>
-    <string name="notice_made_future_room_visibility">%1$s님이 이후 %2$s에게 방 기록을 공개했습니다</string>
-    <string name="notice_room_visibility_invited">초대된 시점부터 모든 방 구성원</string>
-    <string name="notice_room_visibility_joined">들어온 시점부터 모든 방 구성원</string>
-    <string name="notice_room_visibility_shared">모든 방 구성원</string>
-    <string name="notice_room_visibility_world_readable">누구나.</string>
-    <string name="notice_room_visibility_unknown">알 수 없음 (%s).</string>
-    <string name="notice_end_to_end">%1$s님이 종단간 암호화를 켰습니다 (%2$s)</string>
-    <string name="notice_room_update">%s님이 방을 업그레이드했습니다.</string>
-
-    <string name="notice_requested_voip_conference">%1$s님이 VoIP 회의를 요청했습니다</string>
-    <string name="notice_voip_started">VoIP 회의가 시작했습니다</string>
-    <string name="notice_voip_finished">VoIP 회의가 끝났습니다</string>
-
-    <string name="notice_avatar_changed_too">(아바타도 변경됨)</string>
-    <string name="notice_room_name_removed">%1$s님이 방 이름을 삭제했습니다</string>
-    <string name="notice_room_topic_removed">%1$s님이 방 주제를 삭제했습니다</string>
-    <string name="notice_event_redacted">메시지가 삭제되었습니다</string>
-    <string name="notice_event_redacted_by">메시지가 %1$s님에 의해 삭제되었습니다</string>
-    <string name="notice_event_redacted_with_reason">메시지가 삭제되었습니다 [이유: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">메시지가 %1$s님에 의해 삭제되었습니다 [이유: %2$s]</string>
-    <string name="notice_profile_change_redacted">%1$s님이 프로필 %2$s을(를) 업데이트했습니다</string>
-    <string name="notice_room_third_party_invite">%1$s님이 %2$s님에게 방 초대를 보냈습니다</string>
-    <string name="notice_room_third_party_registered_invite">%1$s님이 %2$s의 초대를 수락했습니다</string>
-
-    <string name="notice_crypto_unable_to_decrypt">** 암호를 복호화할 수 없음: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">발신인의 기기에서 이 메시지의 키를 보내지 않았습니다.</string>
-
-    <string name="could_not_redact">검열할 수 없습니다</string>
-    <string name="unable_to_send_message">메시지를 보낼 수 없습니다</string>
-
-    <string name="message_failed_to_upload">사진 업로드에 실패했습니다</string>
-
-    <string name="network_error">네트워크 오류</string>
-    <string name="matrix_error">Matrix 오류</string>
-
-    <string name="room_error_join_failed_empty_room">현재 빈 방에 다시 들어갈 수 없습니다.</string>
-
-    <string name="encrypted_message">암호화된 메시지</string>
-
-    <string name="medium_email">이메일 주소</string>
-    <string name="medium_phone_number">전화번호</string>
-
-    <string name="room_displayname_invite_from">%s에서 초대함</string>
-    <string name="room_displayname_room_invite">방 초대</string>
-
-    <string name="room_displayname_two_members">%1$s님과 %2$s님</string>
-
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="other">%1$s님 외 %2$d명</item>
-    </plurals>
-
-    <string name="room_displayname_empty_room">빈 방</string>
-
-    <string name="initial_sync_start_importing_account">초기 동기화:
-\n계정 가져오는 중…</string>
-    <string name="initial_sync_start_importing_account_crypto">초기 동기화:
-\n암호 가져오는 중</string>
-    <string name="initial_sync_start_importing_account_rooms">초기 동기화:
-\n방 가져오는 중</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">초기 동기화:
-\n들어간 방 가져오는 중</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">초기 동기화:
-\n초대받은 방 가져오는 중</string>
-    <string name="initial_sync_start_importing_account_left_rooms">초기 동기화:
-\n떠난 방 가져오는 중</string>
-    <string name="initial_sync_start_importing_account_groups">초기 동기화:
-\n커뮤니티 가져오는 중</string>
-    <string name="initial_sync_start_importing_account_data">초기 동기화:
-\n계정 데이터 가져오는 중</string>
-
-    <string name="event_status_sending_message">메시지 보내는 중…</string>
-    <string name="clear_timeline_send_queue">전송 대기 열 지우기</string>
-
-    <string name="notice_room_third_party_revoked_invite">%1$s님이 %2$s님에게 방에 참가하라고 보낸 초대를 취소했습니다</string>
-</resources>
diff --git a/matrix-sdk-android/src/main/res/values-lt/strings.xml b/matrix-sdk-android/src/main/res/values-lt/strings.xml
deleted file mode 100644
index 4b07e1ec8818f64ceea10de8bfdff9fb0d6cf3cc..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-lt/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s išsiuntė vaizdą.</string>
-    <string name="summary_user_sent_sticker">%1$s išsiuntė lipduką.</string>
-    <string name="notice_room_invite_no_invitee">%s pakvietimas</string>
-    <string name="notice_room_join_by_you">JÅ«s prisijungÄ—te prie kambario</string>
-    <string name="notice_room_join">%1$s prisijungÄ— prie kambario</string>
-    <string name="notice_room_invite_you">%1$s pakvietÄ— jus</string>
-    <string name="notice_room_invite_by_you">JÅ«s pakvietÄ—te %1$s</string>
-    <string name="notice_room_invite">%1$s pakvietÄ— %2$s</string>
-    <string name="notice_direct_room_created_by_you">Jūs sukūrėte diskusiją</string>
-    <string name="notice_direct_room_created">%1$s sukūrė diskusiją</string>
-    <string name="notice_room_created_by_you">Jūs sukūrėte kambarį</string>
-    <string name="notice_room_created">%1$s sukūrė kambarį</string>
-    <string name="notice_room_invite_no_invitee_by_you">Jūsų pakvietimas</string>
-    <string name="summary_you_sent_sticker">Jūs išsiuntėte lipduką.</string>
-    <string name="summary_you_sent_image">Jūs išsiuntėte vaizdą.</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-lv/strings.xml b/matrix-sdk-android/src/main/res/values-lv/strings.xml
deleted file mode 100644
index ec107b47d6bd385cd63704e78d060e8e3f302f8c..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-lv/strings.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s nosūtīja attēlu.</string>
-    <string name="notice_room_invite_no_invitee">%s\'s uzaicinājums</string>
-    <string name="notice_room_invite">%1$s uzaicināja %2$s</string>
-    <string name="notice_room_invite_you">%1$s uzaicināja tevi</string>
-    <string name="notice_room_join">%1$s pievienojās</string>
-    <string name="notice_room_leave">%1$s atstāja</string>
-    <string name="notice_room_reject">%1$s noraidīja uzaicinājumu</string>
-    <string name="notice_room_kick">%1$s \"izspēra\" ārā %2$s</string>
-    <string name="notice_room_unban">%1$s atbanoja (atcēla pieejas liegumu) %2$s</string>
-    <string name="notice_room_ban">%1$s liedza pieeju (banoja) %2$s</string>
-    <string name="notice_room_withdraw">%1$s atsauca %2$s uzaicinājumu</string>
-    <string name="notice_avatar_url_changed">%1$s nomainīja profila attēlu</string>
-    <string name="notice_display_name_set">%1$s uzstādīja redzamo vārdu uz %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s nomainīja redzamo vārdu no %2$s uz %3$s</string>
-    <string name="notice_display_name_removed">%1$s dzēsa savu redzamo vārdu (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s nomainīja tēmas nosaukumu uz: %2$s</string>
-    <string name="notice_room_name_changed">%1$s nomainīja istabas nosaukumu uz: %2$s</string>
-    <string name="notice_placed_video_call">%s veica video zvanu.</string>
-    <string name="notice_placed_voice_call">%s veica audio zvanu.</string>
-    <string name="notice_answered_call">%s atbildēja zvanam.</string>
-    <string name="notice_ended_call">%s beidza zvanu.</string>
-    <string name="notice_made_future_room_visibility">%1$s padarīja istabas nākamo ziņu vēsturi redzamu  %2$s</string>
-    <string name="notice_room_visibility_invited">visi istabas biedri no brīža, kad tika uzaicināti.</string>
-    <string name="notice_room_visibility_joined">visi istabas biedri no brīža, kad tika pievienojušies.</string>
-    <string name="notice_room_visibility_shared">visi istabas biedri.</string>
-    <string name="notice_room_visibility_world_readable">ikviens.</string>
-    <string name="notice_room_visibility_unknown">nezināms (%s).</string>
-    <string name="notice_end_to_end">%1$s ieslēdza ierīce-ierīce šifrēšanu (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s vēlas VoIP konferenci</string>
-    <string name="notice_voip_started">VoIP konference sākusies</string>
-    <string name="notice_voip_finished">VoIP konference ir beigusies</string>
-    <string name="notice_avatar_changed_too">(arī profila attēls mainījās)</string>
-    <string name="notice_room_name_removed">%1$s dzēsa istabas nosaukumu</string>
-    <string name="notice_room_topic_removed">%1$s dzēsa istabas tēmas nosaukumu</string>
-    <string name="notice_profile_change_redacted">%1$s atjaunoja profila informāciju %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s nosūtīja uzaicinājumu %2$s pievienoties istabai</string>
-    <string name="notice_room_third_party_registered_invite">%1$s apstiprināja uzaicinājumu priekš %2$s</string>
-    <string name="notice_crypto_unable_to_decrypt">** Nav iespējams atkodēt: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Sūtītāja ierīce mums nenosūtīja atslēgas priekš šīs ziņas.</string>
-    <string name="could_not_redact">Nevarēja rediģēt</string>
-    <string name="unable_to_send_message">Nav iespējams nosūtīt ziņu</string>
-    <string name="message_failed_to_upload">Neizdevās augšuplādēt attēlu</string>
-    <string name="network_error">Tīkla kļūda</string>
-    <string name="matrix_error">Matrix kļūda</string>
-    <string name="room_error_join_failed_empty_room">Šobrīd nav iespējams atkārtoti pievienoties tukšai istabai.</string>
-    <string name="encrypted_message">Šifrēta ziņa</string>
-    <string name="medium_email">Epasta adrese</string>
-    <string name="medium_phone_number">Telefona numurs</string>
-    <string name="room_displayname_invite_from">Uzaicinājums no %s</string>
-    <string name="room_displayname_room_invite">Uzaicinājums uz istabu</string>
-    <string name="room_displayname_two_members">%1$s un %2$s</string>
-    <string name="room_displayname_empty_room">Tukša istaba</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="zero">%1$s un 1 cits</item>
-        <item quantity="one">%1$s un %2$d citi</item>
-        <item quantity="other">%1$s un %2$d citu</item>
-    </plurals>
-    <string name="notice_display_name_changed_from_by_you">Tu nomainīji savu attēlojamo vārdu no %1$s uz %2$s</string>
-    <string name="notice_display_name_set_by_you">Tu nomainījis savu attēlojamo vārdu uz %1$s</string>
-    <string name="notice_avatar_url_changed_by_you">Tu nomainīji savu avataru</string>
-    <string name="notice_room_withdraw_by_you">Tu atsauci %1$s uzaicinājumu</string>
-    <string name="notice_room_ban_by_you">Tu nobanoji %1$s</string>
-    <string name="notice_room_unban_by_you">Tu atbanoji %1$s</string>
-    <string name="notice_room_kick_by_you">Tu izspēri %1$s</string>
-    <string name="notice_room_reject_by_you">Tu noraidīji uzaicinājumu</string>
-    <string name="notice_direct_room_leave_by_you">Tu pameti telpu</string>
-    <string name="notice_direct_room_leave">%1$s atstāja telpu</string>
-    <string name="notice_room_leave_by_you">Tu atstāji telpu</string>
-    <string name="notice_direct_room_join_by_you">Tu pievienojies</string>
-    <string name="notice_direct_room_join">%1$s pievienojās telpai</string>
-    <string name="notice_room_join_by_you">Tu pievienojies telpai</string>
-    <string name="notice_room_invite_by_you">Tu uzaicināji %1$s</string>
-    <string name="notice_direct_room_created_by_you">Tu izveidoji apspriedi (diskusiju)</string>
-    <string name="notice_direct_room_created">%1$s izveidoja apspriedi (diskusiju)</string>
-    <string name="notice_room_created_by_you">Tu izveidoji istabu</string>
-    <string name="notice_room_created">%1$s izveidoja telpu</string>
-    <string name="notice_room_invite_no_invitee_by_you">Tavs uzaicinājums</string>
-    <string name="summary_you_sent_sticker">Tu nosūtīji uzlīmi/lipekli.</string>
-    <string name="summary_user_sent_sticker">%1$s nosūtīja uzlīmi/lipekli.</string>
-    <string name="summary_you_sent_image">Tu nosūtīji attēlu.</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-nb/strings.xml b/matrix-sdk-android/src/main/res/values-nb/strings.xml
deleted file mode 100644
index 07cf4226e02eb7338bca42a647227c62c0fc1d4d..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-nb/strings.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="notice_direct_room_created_by_you">Du opprettet diskusjonen</string>
-    <string name="notice_room_created_by_you">Du opprettet rommet</string>
-    <string name="notice_room_invite_no_invitee_by_you">Invitasjonen din</string>
-    <string name="summary_you_sent_sticker">Du sendte et klistremerke.</string>
-    <string name="summary_user_sent_sticker">%1$s sendte et klistremerke.</string>
-    <string name="summary_you_sent_image">Du sendte et bilde.</string>
-    <string name="summary_user_sent_image">%1$s sendte et bilde.</string>
-    <string name="summary_message">%1$s: %2$s</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-nl/strings.xml b/matrix-sdk-android/src/main/res/values-nl/strings.xml
deleted file mode 100644
index 1b05052ba6c24ab2eb9abe2ef7adf3aa04913b9a..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-nl/strings.xml
+++ /dev/null
@@ -1,151 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s heeft een afbeelding gestuurd.</string>
-
-    <string name="notice_room_invite_no_invitee">Uitnodiging van %s</string>
-    <string name="notice_room_invite">%1$s heeft %2$s uitgenodigd</string>
-    <string name="notice_room_invite_you">%1$s heeft u uitgenodigd</string>
-    <string name="notice_room_join">%1$s neemt nu deel aan het gesprek</string>
-    <string name="notice_room_leave">%1$s heeft het gesprek verlaten</string>
-    <string name="notice_room_reject">%1$s heeft de uitnodiging geweigerd</string>
-    <string name="notice_room_kick">%1$s heeft %2$s uit het gesprek verwijderd</string>
-    <string name="notice_room_unban">%1$s heeft %2$s ontbannen</string>
-    <string name="notice_room_ban">%1$s heeft %2$s verbannen</string>
-    <string name="notice_room_withdraw">%1$s heeft de uitnodiging van %2$s ingetrokken</string>
-    <string name="notice_avatar_url_changed">%1$s heeft zijn/haar avatar aangepast</string>
-    <string name="notice_display_name_set">%1$s heeft zijn/haar naam aangepast naar %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s heeft zijn/haar naam aangepast van %2$s naar %3$s</string>
-    <string name="notice_display_name_removed">%1$s heeft zijn/haar naam verwijderd (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s heeft het onderwerp veranderd naar: %2$s</string>
-    <string name="notice_room_name_changed">%1$s heeft de gespreksnaam veranderd naar: %2$s</string>
-    <string name="notice_placed_video_call">%s heeft een video-oproep gemaakt.</string>
-    <string name="notice_placed_voice_call">%s heeft een spraakoproep gemaakt.</string>
-    <string name="notice_answered_call">%s heeft de oproep beantwoord.</string>
-    <string name="notice_ended_call">%s heeft opgehangen.</string>
-    <string name="notice_made_future_room_visibility">%1$s heeft de toekomstige gespreksgeschiedenis zichtbaar gemaakt voor %2$s</string>
-    <string name="notice_room_visibility_invited">alle deelnemers aan het gesprek, vanaf het punt dat ze zijn uitgenodigd.</string>
-    <string name="notice_room_visibility_joined">alle deelnemers aan het gesprek, vanaf het punt dat ze zijn toegetreden.</string>
-    <string name="notice_room_visibility_shared">alle deelnemers aan het gesprek.</string>
-    <string name="notice_room_visibility_world_readable">iedereen.</string>
-    <string name="notice_room_visibility_unknown">onbekend (%s).</string>
-    <string name="notice_end_to_end">%1$s heeft eind-tot-eind-versleuteling aangezet (%2$s)</string>
-
-    <string name="notice_requested_voip_conference">%1$s heeft een VoIP-vergadering aangevraagd</string>
-    <string name="notice_voip_started">VoIP-vergadering gestart</string>
-    <string name="notice_voip_finished">VoIP-vergadering gestopt</string>
-
-    <string name="notice_avatar_changed_too">(avatar is ook veranderd)</string>
-    <string name="notice_room_name_removed">%1$s heeft de gespreksnaam verwijderd</string>
-    <string name="notice_room_topic_removed">%1$s heeft het gespreksonderwerp verwijderd</string>
-    <string name="notice_profile_change_redacted">%1$s heeft zijn/haar profiel %2$s bijgewerkt</string>
-    <string name="notice_room_third_party_invite">%1$s heeft een uitnodiging naar %2$s gestuurd om het gesprek toe te treden</string>
-    <string name="notice_room_third_party_registered_invite">%1$s heeft de uitnodiging voor %2$s aanvaard</string>
-
-    <string name="notice_crypto_unable_to_decrypt">** Kan niet ontsleutelen: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Het apparaat van de afzender heeft geen sleutels voor dit bericht gestuurd.</string>
-
-    <!-- Room Screen -->
-    <string name="could_not_redact">Kon niet verwijderd worden</string>
-    <string name="unable_to_send_message">Kan bericht niet verzenden</string>
-
-    <string name="message_failed_to_upload">Uploaden van de afbeelding mislukt</string>
-
-    <!-- general errors -->
-    <string name="network_error">Netwerkfout</string>
-    <string name="matrix_error">Matrix-fout</string>
-
-    <!-- Home Screen -->
-
-    <!-- Last seen time -->
-
-    <!-- room error messages -->
-    <string name="room_error_join_failed_empty_room">Het is momenteel niet mogelijk om een leeg gesprek opnieuw toe te treden.</string>
-
-    <string name="encrypted_message">Versleuteld bericht</string>
-
-    <!-- medium friendly name -->
-    <string name="medium_email">E-mailadres</string>
-    <string name="medium_phone_number">Telefoonnummer</string>
-
-    <string name="summary_user_sent_sticker">%1$s heeft een sticker gestuurd.</string>
-
-    <!-- Room display name -->
-    <string name="room_displayname_invite_from">Uitnodiging van %s</string>
-    <string name="room_displayname_room_invite">Gespreksuitnodiging</string>
-    <string name="room_displayname_two_members">%1$s en %2$s</string>
-    <string name="room_displayname_empty_room">Leeg gesprek</string>
-
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s en 1 andere</item>
-        <item quantity="other">%1$s en %2$d anderen</item>
-    </plurals>
-
-
-    <string name="notice_event_redacted">Bericht verwijderd</string>
-    <string name="notice_event_redacted_by">Bericht verwijderd door %1$s</string>
-    <string name="notice_event_redacted_with_reason">Bericht verwijderd [reden: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Bericht verwijderd door %1$s [reden: %2$s]</string>
-
-    <string name="initial_sync_start_importing_account">Initiële synchronisatie:
-\nAccount wordt geïmporteerd…</string>
-    <string name="initial_sync_start_importing_account_crypto">Initiële synchronisatie:
-\nCrypto wordt geïmporteerd</string>
-    <string name="initial_sync_start_importing_account_rooms">Initiële synchronisatie:
-\nGesprekken worden geïmporteerd</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Initiële synchronisatie:
-\nDeelgenomen gesprekken worden geïmporteerd</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Initiële synchronisatie:
-\nUitgenodigde gesprekken worden geïmporteerd</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Initiële synchronisatie:
-\nVerlaten gesprekken worden geïmporteerd</string>
-    <string name="initial_sync_start_importing_account_groups">Initiële synchronisatie:
-\nGemeenschappen worden geïmporteerd</string>
-    <string name="initial_sync_start_importing_account_data">Initiële synchronisatie:
-\nAccountgegevens worden geïmporteerd</string>
-
-    <string name="notice_room_update">%s heeft dit gesprek opgewaardeerd.</string>
-
-    <string name="event_status_sending_message">Bericht wordt verstuurd…</string>
-    <string name="clear_timeline_send_queue">Uitgaande wachtrij legen</string>
-
-    <string name="notice_room_third_party_revoked_invite">%1$s heeft de uitnodiging voor %2$s om het gesprek toe te treden ingetrokken</string>
-    <string name="notice_room_invite_no_invitee_with_reason">Uitnodiging van %1$s. Reden: %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s heeft %2$s uitgenodigd. Reden: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s heeft u uitgenodigd. Reden: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s neemt nu deel. Reden: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s is weggegaan. Reden: %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s heeft de uitnodiging geweigerd. Reden: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s heeft %2$s verwijderd. Reden: %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s heeft %2$s ontbannen. Reden: %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s heeft %2$s verbannen. Reden: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s heeft %2$s een uitnodiging voor het gesprek gestuurd. Reden: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s heeft de uitnodiging voor %2$s ingetrokken. Reden: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s heeft de uitnodiging voor %2$s aanvaard. Reden: %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s heeft de uitnodiging van %2$s ingetrokken. Reden: %3$s</string>
-
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s heeft %2$s als gespreksadres toegevoegd.</item>
-        <item quantity="other">%1$s heeft %2$s als gespreksadressen toegevoegd.</item>
-    </plurals>
-
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s heeft %2$s als gespreksadres verwijderd.</item>
-        <item quantity="other">%1$s heeft %3$s als gespreksadressen verwijderd.</item>
-    </plurals>
-
-    <string name="notice_room_aliases_added_and_removed">%1$s heeft %2$s als gespreksadres toegevoegd en %3$s verwijderd.</string>
-
-    <string name="notice_room_canonical_alias_set">%1$s heeft het hoofdadres voor dit gesprek ingesteld op %2$s.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s heeft het hoofdadres voor dit gesprek verwijderd.</string>
-
-    <string name="notice_room_guest_access_can_join">%1$s heeft gasten de toegang tot het gesprek verleend.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s heeft gasten de toegang tot het gesprek verhinderd.</string>
-
-    <string name="notice_end_to_end_ok">%1$s heeft eind-tot-eind-versleuteling ingeschakeld.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s heeft eind-tot-eind-versleuteling ingeschakeld (onbekend algoritme %2$s).</string>
-
-    <string name="key_verification_request_fallback_message">%s vraagt om uw sleutel te verifiëren, maar uw cliënt biedt geen ondersteuning voor verificatie in het gesprek. U zult de verouderde sleutelverificatie moeten gebruiken om de sleutels te verifiëren.</string>
-
-</resources>
diff --git a/matrix-sdk-android/src/main/res/values-nn/strings.xml b/matrix-sdk-android/src/main/res/values-nn/strings.xml
deleted file mode 100644
index 441d568fc3c92a39c9486007e79bddd81b675c0e..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-nn/strings.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="encrypted_message">Kryptert melding</string>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s sende eit bilæte.</string>
-    <string name="summary_user_sent_sticker">%1$s sende eit klistremerke.</string>
-    <string name="notice_room_invite_no_invitee">%s si innbjoding</string>
-    <string name="notice_room_invite">%1$s inviterte %2$s</string>
-    <string name="notice_room_invite_you">%1$s inviterte deg</string>
-    <string name="notice_room_join">%1$s kom inn</string>
-    <string name="notice_room_leave">%1$s forlot rommet</string>
-    <string name="notice_room_reject">%1$s sa nei til innbjodingi</string>
-    <string name="notice_room_kick">%1$s sparka %2$s</string>
-    <string name="notice_room_unban">%1$s slapp %2$s inn att</string>
-    <string name="notice_room_ban">%1$s stengde %2$s ute</string>
-    <string name="notice_room_withdraw">%1$s tok attende %2$s si innbjoding</string>
-    <string name="notice_avatar_url_changed">%1$s byta avataren sin</string>
-    <string name="notice_display_name_set">%1$s sette visingsnamnet sitt som %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s byta visingsnamnet sitt frå %2$s til %3$s</string>
-    <string name="notice_display_name_removed">%1$s tok burt visingsnamnet sitt (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s gjorde emnet til: %2$s</string>
-    <string name="notice_room_name_changed">%1$s gjorde romnamnet til: %2$s</string>
-    <string name="notice_placed_video_call">%s starta ei videosamtala.</string>
-    <string name="notice_placed_voice_call">%s starta ein talesamtale.</string>
-    <string name="notice_answered_call">%s tok røyret.</string>
-    <string name="notice_ended_call">%s la på røyret.</string>
-    <string name="notice_made_future_room_visibility">%1$s gjorde den framtidige romsoga synleg for %2$s</string>
-    <string name="notice_room_visibility_invited">alle rommedlemmar, frå då dei vart invitert inn.</string>
-    <string name="notice_room_visibility_joined">alle rommedlemmar, frå då dei kom inn.</string>
-    <string name="notice_room_visibility_shared">alle rommedlemmar.</string>
-    <string name="notice_room_visibility_world_readable">kven som heldst.</string>
-    <string name="notice_room_visibility_unknown">uvisst (%s).</string>
-    <string name="notice_end_to_end">%1$s skrudde ende-til-ende-kryptering på (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s bad um ei VoIP-gruppasamtala</string>
-    <string name="notice_voip_started">VoIP-gruppasamtala er starta</string>
-    <string name="notice_voip_finished">VoIP-gruppasamtala er ferdug</string>
-    <string name="notice_avatar_changed_too">(avataren vart au byta)</string>
-    <string name="notice_room_name_removed">%1$s tok burt romnamnet</string>
-    <string name="notice_room_topic_removed">%1$s tok burt romemnet</string>
-    <string name="notice_profile_change_redacted">%1$s gjorde um på skildringi si %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s inviterte %2$s til rommet</string>
-    <string name="notice_room_third_party_registered_invite">%1$s sa ja til innbjodingi til %2$s</string>
-    <string name="notice_crypto_unable_to_decrypt">** Fekk ikkje til å dekryptera: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Avsendareiningi hev ikkje sendt oss nyklane fyr denna meldingi.</string>
-    <string name="could_not_redact">Kunde ikkje gjera um</string>
-    <string name="unable_to_send_message">Fekk ikkje til å senda meldingi</string>
-    <string name="message_failed_to_upload">Fekk ikkje til å lasta biletet upp</string>
-    <string name="network_error">Noko gjekk gale med netverket</string>
-    <string name="matrix_error">Noko gjekk gale med Matrix</string>
-    <string name="room_error_join_failed_empty_room">Det lèt seg fyrebils ikkje gjera å fara inn att i eit tomt rom.</string>
-    <string name="medium_email">Epostadresse</string>
-    <string name="medium_phone_number">Telefonnummer</string>
-    <string name="room_displayname_invite_from">Innbjoding frå %s</string>
-    <string name="room_displayname_room_invite">Rominnbjoding</string>
-    <string name="room_displayname_two_members">%1$s og %2$s</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s og 1 til</item>
-        <item quantity="other">%1$s og %2$d til</item>
-    </plurals>
-    <string name="room_displayname_empty_room">Tomt rom</string>
-    <string name="notice_event_redacted">Ei melding vart stroki</string>
-    <string name="notice_event_redacted_by">%1$s strauk meldingi</string>
-    <string name="notice_event_redacted_with_reason">Meldingi vart stroki [av di: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">%1$s strauk meldingi [av di: %2$s]</string>
-    <string name="notice_room_update">%s oppgraderte rommet.</string>
-    <string name="clear_timeline_send_queue">Nullstill sendingskø</string>
-    <string name="notice_room_leave_with_reason">%1$s forlot rommet. Grunn: %2$s</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-pl/strings.xml b/matrix-sdk-android/src/main/res/values-pl/strings.xml
deleted file mode 100644
index 0d79edc658242cb1bd9586039185a3ef35ad0219..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-pl/strings.xml
+++ /dev/null
@@ -1,104 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s wysłał(a) zdjęcie.</string>
-
-    <string name="notice_room_invite_no_invitee">Zaproszenie od %s</string>
-    <string name="notice_room_invite">%1$s zaprosił(a) %2$s</string>
-    <string name="notice_room_invite_you">%1$s zaprosił(a) Cię</string>
-    <string name="notice_room_join">%1$s dołączył(a)</string>
-    <string name="notice_room_leave">%1$s opuścił(a)</string>
-    <string name="notice_room_reject">%1$s odrzucił(a) zaproszenie</string>
-    <string name="notice_room_kick">%1$s wyrzucił(a) %2$s</string>
-    <string name="notice_room_unban">%1$s odblokował(a) %2$s</string>
-    <string name="notice_room_ban">%1$s zablokował(a) %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s zmienił(a) awatar</string>
-    <string name="notice_display_name_set">%1$s zmienił(a) wyświetlaną nazwę na %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s zmienił(a) wyświetlaną nazwę z %2$s na %3$s</string>
-    <string name="notice_display_name_removed">%1$s usunął(-ęła) swoją wyświetlaną nazwę (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s zmienił(a) temat na: %2$s</string>
-    <string name="unable_to_send_message">Nie można wysłać wiadomości</string>
-
-    <string name="message_failed_to_upload">Przesyłanie zdjęcia nie powiodło się</string>
-
-    <string name="network_error">BÅ‚Ä…d sieci</string>
-    <string name="matrix_error">BÅ‚Ä…d Matrixa</string>
-
-    <string name="encrypted_message">Wiadomość zaszyfrowana</string>
-
-    <string name="medium_email">Adres e-mail</string>
-    <string name="medium_phone_number">Numer telefonu</string>
-
-    <string name="notice_room_visibility_shared">wszyscy członkowie pokoju.</string>
-    <string name="notice_room_visibility_world_readable">wszyscy.</string>
-    <string name="notice_room_name_changed">%1$s zmienił(a) nazwę pokoju na: %2$s</string>
-    <string name="notice_ended_call">%s zakończył(a) rozmowę.</string>
-    <string name="notice_room_name_removed">%1$s usunął(-ęła) nazwę pokoju</string>
-    <string name="notice_room_topic_removed">%1$s usunął(-ęła) temat pokoju</string>
-    <string name="summary_user_sent_sticker">%1$s wysłał(a) naklejkę.</string>
-
-    <string name="notice_end_to_end">%1$s włączył(a) szyfrowanie end-to-end (%2$s)</string>
-
-    <string name="notice_room_withdraw">%1$s wycofał(a) zaproszenie %2$s</string>
-    <string name="notice_answered_call">%s odebrał(a) połączenie.</string>
-    <string name="notice_avatar_changed_too">(awatar też został zmieniony)</string>
-
-    <string name="room_displayname_invite_from">Zaproszenie od %s</string>
-    <string name="room_displayname_room_invite">Zaproszenie do pokoju</string>
-    <string name="room_displayname_two_members">%1$s i %2$s</string>
-    <string name="room_displayname_empty_room">Pusty pokój</string>
-
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s i jeden inny</item>
-        <item quantity="few">%1$s i kilku innych</item>
-        <item quantity="many">%1$s i %2$d innych</item>
-        <item quantity="other" />
-    </plurals>
-
-    <string name="notice_crypto_unable_to_decrypt">** Nie można odszyfrować: %s **</string>
-    <string name="notice_placed_video_call">%s wykonał(a) rozmowę wideo.</string>
-    <string name="notice_placed_voice_call">%s wykonał(a) połączenie głosowe.</string>
-    <string name="notice_made_future_room_visibility">%1$s uczynił(a) przyszłą historię pokoju widoczną dla %2$s</string>
-    <string name="notice_room_visibility_invited">wszyscy członkowie pokoju, od momentu w którym zostali zaproszeni.</string>
-    <string name="notice_room_visibility_joined">wszyscy członkowie pokoju, od momentu w którym dołączyli.</string>
-    <string name="notice_room_visibility_unknown">nieznane (%s).</string>
-    <string name="notice_requested_voip_conference">%1$s zażądał(a) grupowego połączenia VoIP</string>
-    <string name="notice_voip_started">Rozpoczęto grupowe połączenie głosowe VoIP</string>
-    <string name="notice_voip_finished">Zakończono grupowe połączenie głosowe VoIP</string>
-
-    <string name="notice_profile_change_redacted">%1$s zaktualizował swój profil %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s wysłał(a) zaproszenie do %2$s aby dołączył(a) do tego pokoju</string>
-    <string name="notice_room_third_party_registered_invite">%1$s zaakceptował(a) zaproszenie dla %2$s</string>
-
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Urządzenie nadawcy nie wysłało nam kluczy do tej wiadomości.</string>
-
-    <string name="could_not_redact">Nie można zredagować</string>
-    <string name="room_error_join_failed_empty_room">Obecnie nie jest możliwe ponowne dołączenie do pustego pokoju.</string>
-
-    <string name="notice_event_redacted">Wiadomość usunięta</string>
-    <string name="notice_event_redacted_by">Wiadomość usunięta przez %1$s</string>
-    <string name="notice_event_redacted_with_reason">Wiadomość usunięta [powód: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Wiadomość usunięta przez %1$s [powód: %2$s]</string>
-    <string name="notice_room_update">%s zakutalizował(a) ten pokój.</string>
-
-    <string name="initial_sync_start_importing_account">Synchronizacja poczÄ…tkowa:
-\nImportowanie konta…</string>
-    <string name="initial_sync_start_importing_account_crypto">Synchronizacja poczÄ…tkowa:
-\nImportowanie kryptografii</string>
-    <string name="initial_sync_start_importing_account_rooms">Synchronizacja poczÄ…tkowa:
-\nImportowanie Pokoi</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Synchronizacja poczÄ…tkowa:
-\nImportowanie dołączonych Pokoi</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Synchronizacja poczÄ…tkowa:
-\nImportowanie zaproszonych Pokoi</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Synchronizacja poczÄ…tkowa:
-\nImportowanie opuszczonych Pokoi</string>
-    <string name="initial_sync_start_importing_account_groups">Synchronizacja poczÄ…tkowa:
-\nImportowanie Społeczności</string>
-    <string name="initial_sync_start_importing_account_data">Synchronizacja poczÄ…tkowa:
-\nImportowanie danych Konta</string>
-
-    <string name="event_status_sending_message">Wysyłanie wiadomości…</string>
-    <string name="clear_timeline_send_queue">Wyczyść kolejkę wysyłania</string>
-
-</resources>
diff --git a/matrix-sdk-android/src/main/res/values-pt-rBR/strings.xml b/matrix-sdk-android/src/main/res/values-pt-rBR/strings.xml
deleted file mode 100644
index 5e3282a3052560a48085f1b9cb126fc4415abb02..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-pt-rBR/strings.xml
+++ /dev/null
@@ -1,269 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s enviou uma foto.</string>
-    <string name="notice_room_invite_no_invitee">convite de %s</string>
-    <string name="notice_room_invite">%1$s convidou %2$s</string>
-    <string name="notice_room_invite_you">%1$s convidou você</string>
-    <string name="notice_room_join">%1$s entrou na sala</string>
-    <string name="notice_room_leave">%1$s saiu da sala</string>
-    <string name="notice_room_reject">%1$s recusou o convite</string>
-    <string name="notice_room_kick">%1$s removeu %2$s</string>
-    <string name="notice_room_unban">%1$s removeu o banimento de %2$s</string>
-    <string name="notice_room_ban">%1$s baniu %2$s</string>
-    <string name="notice_room_withdraw">%1$s desfez o convite a %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s alterou a foto de perfil</string>
-    <string name="notice_display_name_set">%1$s definiu o nome e sobrenome como %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s alterou o nome e sobrenome de %2$s para %3$s</string>
-    <string name="notice_display_name_removed">%1$s removeu o nome e sobrenome (era %2$s)</string>
-    <string name="notice_room_topic_changed">%1$s alterou a descrição para: %2$s</string>
-    <string name="notice_room_name_changed">%1$s alterou o nome da sala para: %2$s</string>
-    <string name="notice_placed_video_call">%s iniciou uma chamada de vídeo.</string>
-    <string name="notice_placed_voice_call">%s iniciou uma chamada de voz.</string>
-    <string name="notice_answered_call">%s aceitou a chamada.</string>
-    <string name="notice_ended_call">%s encerrou a chamada.</string>
-    <string name="notice_made_future_room_visibility">%1$s deixou o histórico futuro da sala visível para %2$s</string>
-    <string name="notice_room_visibility_invited">todos os participantes da sala, a partir do momento em que foram convidados.</string>
-    <string name="notice_room_visibility_joined">todos os participantes da sala, a partir do momento em que entraram nela.</string>
-    <string name="notice_room_visibility_shared">todos os participantes da sala.</string>
-    <string name="notice_room_visibility_world_readable">qualquer pessoa.</string>
-    <string name="notice_room_visibility_unknown">desconhecido (%s).</string>
-    <string name="notice_end_to_end">%1$s ativou a criptografia de ponta a ponta (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s deseja iniciar uma chamada em grupo</string>
-    <string name="notice_voip_started">Chamada em grupo iniciada</string>
-    <string name="notice_voip_finished">Chamada em grupo encerrada</string>
-    <string name="notice_avatar_changed_too">(a foto de perfil também foi alterada)</string>
-    <string name="notice_room_name_removed">%1$s removeu o nome da sala</string>
-    <string name="notice_room_topic_removed">%1$s removeu a descrição da sala</string>
-    <string name="notice_profile_change_redacted">%1$s atualizou o perfil %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s enviou um convite para %2$s entrar na sala</string>
-    <string name="notice_room_third_party_registered_invite">%1$s aceitou o convite para %2$s</string>
-    <string name="notice_crypto_unable_to_decrypt">** Não foi possível descriptografar: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">O aparelho do remetente não nos enviou as chaves para esta mensagem.</string>
-    <!-- Room Screen -->
-    <string name="could_not_redact">Não foi possível redigir</string>
-    <string name="unable_to_send_message">Não foi possível enviar a mensagem</string>
-    <string name="message_failed_to_upload">O envio da imagem falhou</string>
-    <!-- general errors -->
-    <string name="network_error">Erro de conexão à internet</string>
-    <string name="matrix_error">Erro no servidor Matrix</string>
-    <!-- Home Screen -->
-    <!-- Last seen time -->
-    <!-- call events -->
-    <!-- room error messages -->
-    <string name="room_error_join_failed_empty_room">Atualmente, não é possível entrar novamente em uma sala vazia.</string>
-    <string name="encrypted_message">Mensagem criptografada</string>
-    <!-- medium friendly name -->
-    <string name="medium_email">Endereço de e-mail</string>
-    <string name="medium_phone_number">Número de telefone</string>
-    <string name="summary_user_sent_sticker">%1$s enviou uma figurinha.</string>
-    <!-- Room display name -->
-    <string name="room_displayname_invite_from">Convite de %s</string>
-    <string name="room_displayname_room_invite">Convite para sala</string>
-    <string name="room_displayname_two_members">%1$s e %2$s</string>
-    <string name="room_displayname_empty_room">Sala vazia</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s e 1 outro</item>
-        <item quantity="other">%1$s e %2$d outros</item>
-    </plurals>
-    <string name="summary_you_sent_image">Você enviou uma foto.</string>
-    <string name="summary_you_sent_sticker">Você enviou uma figurinha.</string>
-    <string name="notice_room_invite_no_invitee_by_you">Seu convite</string>
-    <string name="notice_room_created">%1$s criou a sala</string>
-    <string name="notice_room_created_by_you">Você criou a sala</string>
-    <string name="notice_room_invite_by_you">Você convidou %1$s</string>
-    <string name="notice_room_join_by_you">Você entrou na sala</string>
-    <string name="notice_room_leave_by_you">Você saiu da sala</string>
-    <string name="notice_room_reject_by_you">Você recusou o convite</string>
-    <string name="notice_room_kick_by_you">Você removeu %1$s</string>
-    <string name="notice_room_unban_by_you">Você removeu o banimento de %1$s</string>
-    <string name="notice_room_ban_by_you">Você baniu %1$s</string>
-    <string name="notice_room_withdraw_by_you">Você desfez o convite a %1$s</string>
-    <string name="notice_avatar_url_changed_by_you">Você alterou a sua foto de perfil</string>
-    <string name="notice_display_name_set_by_you">Você definiu o seu nome e sobrenome como %1$s</string>
-    <string name="notice_display_name_changed_from_by_you">Você alterou o seu nome e sobrenome de %1$s para %2$s</string>
-    <string name="notice_display_name_removed_by_you">Você removeu o seu nome e sobrenome (era %1$s)</string>
-    <string name="notice_room_topic_changed_by_you">Você alterou a descrição para: %1$s</string>
-    <string name="notice_room_avatar_changed">%1$s alterou a foto da sala</string>
-    <string name="notice_room_avatar_changed_by_you">Você alterou a foto da sala</string>
-    <string name="notice_room_name_changed_by_you">Você alterou o nome da sala para: %1$s</string>
-    <string name="notice_placed_video_call_by_you">Você iniciou uma chamada de vídeo.</string>
-    <string name="notice_placed_voice_call_by_you">Você iniciou uma chamada de voz.</string>
-    <string name="notice_call_candidates">%s enviou dados para configurar a chamada.</string>
-    <string name="notice_call_candidates_by_you">Você enviou dados para configurar a chamada.</string>
-    <string name="notice_answered_call_by_you">Você aceitou a chamada.</string>
-    <string name="notice_ended_call_by_you">Você encerrou a chamada.</string>
-    <string name="notice_made_future_room_visibility_by_you">Você deixou o histórico futuro da sala visível para %1$s</string>
-    <string name="notice_end_to_end_by_you">Você ativou a criptografia de ponta a ponta (%1$s)</string>
-    <string name="notice_room_update">%s atualizou esta sala.</string>
-    <string name="notice_room_update_by_you">Você atualizou esta sala.</string>
-    <string name="notice_requested_voip_conference_by_you">Você solicitou uma chamada em grupo</string>
-    <string name="notice_room_name_removed_by_you">Você removeu o nome da sala</string>
-    <string name="notice_room_topic_removed_by_you">Você removeu a descrição da sala</string>
-    <string name="notice_room_avatar_removed">%1$s removeu a foto da sala</string>
-    <string name="notice_room_avatar_removed_by_you">Você removeu a foto da sala</string>
-    <string name="notice_event_redacted">Mensagem apagada</string>
-    <string name="notice_event_redacted_by">Mensagem apagada por %1$s</string>
-    <string name="notice_event_redacted_with_reason">Mensagem apagada [motivo: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Mensagem apagada por %1$s [motivo: %2$s]</string>
-    <string name="notice_profile_change_redacted_by_you">Você atualizou o seu perfil %1$s</string>
-    <string name="notice_room_third_party_invite_by_you">Você enviou um convite para %1$s entrar na sala</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s cancelou o convite a %2$s para entrar na sala</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Você cancelou o convite a %1$s para entrar na sala</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Você aceitou o convite para %1$s</string>
-    <string name="notice_widget_added">%1$s adicionou o widget %2$s</string>
-    <string name="notice_widget_added_by_you">Você adicionou o widget %1$s</string>
-    <string name="notice_widget_removed">%1$s removeu o widget %2$s</string>
-    <string name="notice_widget_removed_by_you">Você removeu o widget %1$s</string>
-    <string name="notice_widget_modified">%1$s editou o widget %2$s</string>
-    <string name="notice_widget_modified_by_you">Você editou o widget %1$s</string>
-    <string name="power_level_admin">Administrador</string>
-    <string name="power_level_moderator">Moderador</string>
-    <string name="power_level_default">Padrão</string>
-    <string name="power_level_custom">Personalizado (%1$d)</string>
-    <string name="power_level_custom_no_value">Personalizado</string>
-    <string name="notice_power_level_changed_by_you">Você alterou o nível de permissão de %1$s.</string>
-    <string name="notice_power_level_changed">%1$s alterou o nível de permissão de %2$s.</string>
-    <string name="notice_power_level_diff">%1$s de %2$s para %3$s</string>
-    <string name="initial_sync_start_importing_account">Primeira sincronização:
-\nImportando a conta…</string>
-    <string name="initial_sync_start_importing_account_crypto">Primeira sincronização:
-\nImportando as chaves de criptografia</string>
-    <string name="initial_sync_start_importing_account_rooms">Primeira sincronização:
-\nImportando as salas</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Primeira sincronização:
-\nImportando as salas em que você entrou</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Primeira sincronização:
-\nImportando as salas em que você foi convidado</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Primeira sincronização:
-\nImportando as salas em que você saiu</string>
-    <string name="initial_sync_start_importing_account_groups">Primeira sincronização:
-\nImportando as comunidades</string>
-    <string name="initial_sync_start_importing_account_data">Primeira sincronização:
-\nImportando os dados da conta</string>
-    <string name="event_status_sending_message">Enviando mensagem…</string>
-    <string name="clear_timeline_send_queue">Limpar a fila de envio</string>
-    <string name="notice_room_invite_no_invitee_with_reason">Convite de %1$s. Motivo: %2$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">O seu convite. Motivo: %1$s</string>
-    <string name="notice_room_invite_with_reason">%1$s convidou %2$s. Motivo: %3$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Você convidou %1$s. Motivo: %2$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s convidou você. Motivo: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s entrou na sala. Motivo: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">Você entrou na sala. Motivo: %1$s</string>
-    <string name="notice_room_leave_with_reason">%1$s saiu da sala. Motivo: %2$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Você saiu da sala. Motivo: %1$s</string>
-    <string name="notice_room_reject_with_reason">%1$s recusou o convite. Motivo: %2$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Você recusou o convite. Motivo: %1$s</string>
-    <string name="notice_room_kick_with_reason">%1$s removeu %2$s. Motivo: %3$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Você removeu %1$s. Motivo: %2$s</string>
-    <string name="notice_room_unban_with_reason">%1$s removeu o banimento de %2$s. Motivo: %3$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Você removeu o banimento de %1$s. Motivo: %2$s</string>
-    <string name="notice_room_ban_with_reason">%1$s baniu %2$s. Motivo: %3$s</string>
-    <string name="notice_room_ban_with_reason_by_you">Você baniu %1$s. Motivo: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s enviou um convite para %2$s entrar na sala. Motivo: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Você enviou um convite para %1$s entrar na sala. Motivo: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s revogou o convite para %2$s entrar na sala. Motivo: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Você revogou o convite para %1$s entrar na sala. Motivo: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s aceitou o convite para %2$s. Motivo: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Você aceitou o convite para %1$s. Motivo: %2$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s desfez o convite de %2$s. Motivo: %3$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">Você desfez o convite de %1$s. Motivo: %2$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s adicionou %2$s como um endereço desta sala.</item>
-        <item quantity="other">%1$s adicionou %2$s como endereços desta sala.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">Você adicionou %1$s como um endereço desta sala.</item>
-        <item quantity="other">Você adicionou %1$s como endereços desta sala.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s removeu %2$s como um endereço desta sala.</item>
-        <item quantity="other">%1$s removeu %2$s como endereços desta sala.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">Você removeu %1$s como um endereço desta sala.</item>
-        <item quantity="other">Você removeu %1$s como endereços desta sala.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s adicionou %2$s e removeu %3$s como endereços desta sala.</string>
-    <string name="notice_room_aliases_added_and_removed_by_you">Você adicionou %1$s e removeu %2$s como endereços desta sala.</string>
-    <string name="notice_room_canonical_alias_set">%1$s definiu o endereço principal desta sala como %2$s.</string>
-    <string name="notice_room_canonical_alias_set_by_you">Você definiu o endereço principal desta sala como %1$s.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s removeu o endereço principal desta sala.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Você removeu o endereço principal desta sala.</string>
-    <string name="notice_room_guest_access_can_join">%1$s permitiu que convidados entrem na sala.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Você permitiu que convidados entrem na sala.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s impediu que convidados entrassem na sala.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">Você impediu que convidados entrassem na sala.</string>
-    <string name="notice_end_to_end_ok">%1$s ativou a criptografia de ponta a ponta.</string>
-    <string name="notice_end_to_end_ok_by_you">Você ativou a criptografia de ponta a ponta.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s ativou a criptografia de ponta a ponta (algoritmo não reconhecido %2$s).</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Você ativou a criptografia de ponta a ponta (algoritmo não reconhecido %1$s).</string>
-    <string name="key_verification_request_fallback_message">%s deseja confirmar a sua chave, mas o seu aplicativo não suporta a confirmação da chave da conversa. Você precisará usar a confirmação tradicional de chaves para confirmar chaves.</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">Você impediu que desconhecidos entrem na sala.</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s impediu que desconhecidos entrem na sala.</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">Você permitiu que desconhecidos entrem aqui.</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s permitiu que desconhecidos entrem aqui.</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">Você saiu. Motivo: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s saiu. Motivo: %2$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">Você entrou. Motivo: %1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s entrou. Motivo: %2$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">Você cancelou o convite para %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s cancelou o convite para %2$s</string>
-    <string name="notice_direct_room_third_party_invite_by_you">Você convidou %1$s</string>
-    <string name="notice_direct_room_third_party_invite">%1$s convidou %2$s</string>
-    <string name="notice_direct_room_update_by_you">Você atualizou esta sala.</string>
-    <string name="notice_direct_room_update">%s atualizou esta sala.</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">Você definiu que as mensagens enviadas a partir do presente momento estarão disponíveis para %1$s</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s definiu que as mensagens enviadas a partir do presente momento estarão disponíveis para %2$s</string>
-    <string name="notice_direct_room_leave_by_you">Você saiu da sala</string>
-    <string name="notice_direct_room_leave">%1$s saiu da sala</string>
-    <string name="notice_direct_room_join_by_you">Você entrou</string>
-    <string name="notice_direct_room_join">%1$s entrou</string>
-    <string name="notice_direct_room_created_by_you">Você criou a sala</string>
-    <string name="notice_direct_room_created">%1$s criou a sala</string>
-    <string name="room_displayname_empty_room_was">Sala vazia (era %s)</string>
-    <plurals name="room_displayname_four_and_more_members">
-        <item quantity="one">%1$s, %2$s, %3$s e %4$d outro</item>
-        <item quantity="other">%1$s, %2$s, %3$s e %4$d outros</item>
-    </plurals>
-    <string name="room_displayname_4_members">%1$s, %2$s, %3$s e %4$s</string>
-    <string name="room_displayname_3_members">%1$s, %2$s e %3$s</string>
-    <string name="notice_room_server_acl_allow_is_empty">🎉 Todos os servidores estão proibidos de participar! Esta sala não pode mais ser usada.</string>
-    <string name="notice_room_server_acl_updated_no_change">Nenhuma alteração.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_not_allowed">• Servidores correspondentes aos IP literais agora estão banidos.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_allowed">• Servidores correspondentes aos IP literais agora estão permitidos.</string>
-    <string name="notice_room_server_acl_updated_was_allowed">• Servidores correspondentes à %s foram removidos da lista de permitidos.</string>
-    <string name="notice_room_server_acl_updated_allowed">• Servidores correspondentes à %s agora são permitidos.</string>
-    <string name="notice_room_server_acl_updated_was_banned">• Servidores correspondente à %s foram removidos da lista de banidos.</string>
-    <string name="notice_room_server_acl_updated_banned">• Servidores correspondentes à %s foram banidos.</string>
-    <string name="notice_room_server_acl_updated_title_by_you">Você alterou a lista de controle de acesso (ACL) do servidor para esta sala.</string>
-    <string name="notice_room_server_acl_updated_title">%s alterou a lista de controle de acesso (ACL) do servidor para esta sala.</string>
-    <string name="notice_room_server_acl_set_ip_literals_not_allowed">• Servidores correspondentes aos IP literais estão banidos.</string>
-    <string name="notice_room_server_acl_set_ip_literals_allowed">• Servidores correspondentes aos IP literais estão permitidos.</string>
-    <string name="notice_room_server_acl_set_allowed">• Servidores correspondentes à %s estão permitidos.</string>
-    <string name="notice_room_server_acl_set_banned">• Servidores correspondentes à %s estão banidos.</string>
-    <string name="notice_room_server_acl_set_title_by_you">Você definiu a lista de controle de acesso (ACL) do servidor para esta sala.</string>
-    <string name="notice_room_server_acl_set_title">%s definiu a lista de controle de acesso (ACL) do servidor para esta sala.</string>
-    <string name="notice_room_canonical_alias_alternative_changed_by_you">Você alterou os endereços alternativos desta sala.</string>
-    <string name="notice_room_canonical_alias_alternative_changed">%1$s alterou os endereços alternativos desta sala.</string>
-    <plurals name="notice_room_canonical_alias_alternative_removed_by_you">
-        <item quantity="one">Você removeu o endereço alternativo %1$s para esta sala.</item>
-        <item quantity="other">Você removeu os endereços alternativos %1$s para esta sala.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_removed">
-        <item quantity="one">%1$s removeu o endereço alternativo %2$s para esta sala.</item>
-        <item quantity="other">%1$s removeu os endereços alternativos %2$s para esta sala.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added_by_you">
-        <item quantity="one">Você adicionou o endereço alternativo %1$s para esta sala.</item>
-        <item quantity="other">Você adicionou os endereços alternativos %1$s para esta sala.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added">
-        <item quantity="one">%1$s adicionou o endereço alternativo %2$s para esta sala.</item>
-        <item quantity="other">%1$s adicionou os endereços alternativos %2$s para esta sala.</item>
-    </plurals>
-    <string name="notice_room_canonical_alias_no_change_by_you">Você alterou os endereços desta sala.</string>
-    <string name="notice_room_canonical_alias_no_change">%1$s alterou os endereços desta sala.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed_by_you">Você alterou os endereços principal e alternativos desta sala.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed">%1$s alterou os endereços principal e alternativos desta sala.</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-pt/strings.xml b/matrix-sdk-android/src/main/res/values-pt/strings.xml
deleted file mode 100644
index 4bc90cf0cb7a1ad4a32d17948bb68da460763b75..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-pt/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s enviou uma imagem.</string>
-
-    <string name="notice_room_invite_no_invitee">convite de %s</string>
-    <string name="notice_room_invite">%1$s convidou %2$s</string>
-    <string name="notice_room_invite_you">%1$s convidou-o</string>
-    <string name="notice_room_join">%1$s entrou</string>
-    <string name="notice_room_leave">%1$s saiu</string>
-    <string name="notice_room_reject">%1$s recusou o convite</string>
-    <string name="notice_room_kick">%1$s expulsou %2$s</string>
-    <string name="notice_room_unban">%1$s des-baniu %2$s</string>
-    <string name="notice_room_ban">%1$s baniu %2$s</string>
-    <string name="notice_room_withdraw">%1$s cancelou o convite de %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s mudou o seu avatar</string>
-    <string name="notice_display_name_set">%1$s definiu seu nome público como %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s alterou seu nome público de %2$s para %3$s</string>
-    <string name="notice_display_name_removed">%1$s apagou o seu nome público (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s alterou o tópico desta sala para: %2$s</string>
-    <string name="notice_room_name_changed">%1$s alterou o nome desta sala para: %2$s</string>
-    <string name="notice_placed_video_call">%s iniciou uma chamada de vídeo.</string>
-    <string name="notice_placed_voice_call">%s iniciou uma chamada de voz.</string>
-    <string name="notice_answered_call">%s respondeu à chamada.</string>
-    <string name="notice_ended_call">%s terminou a chamada.</string>
-    <string name="notice_made_future_room_visibility">%1$s tornou o histórico futuro desta sala visível para %2$s</string>
-    <string name="notice_room_visibility_invited">todas os membros que integram esta sala, a partir do momento em que foram convidados.</string>
-    <string name="notice_room_visibility_joined">todas os membros da sala, a partir do momento em que entraram.</string>
-    <string name="notice_room_visibility_shared">todas os membros da sala.</string>
-    <string name="notice_room_visibility_world_readable">todos.</string>
-    <string name="notice_room_visibility_unknown">desconhecida (%s).</string>
-    <string name="notice_end_to_end">%1$s ativou a criptografia ponta-a-ponta (%2$s)</string>
-
-    <string name="notice_requested_voip_conference">%1$s solicitou uma conferência VoIP</string>
-    <string name="notice_voip_started">A conferência VoIP começou</string>
-    <string name="notice_voip_finished">A conferência VoIP terminou</string>
-
-    <string name="notice_avatar_changed_too">(o avatar também foi alterado)</string>
-    <string name="notice_room_name_removed">%1$s removeu o nome da sala</string>
-    <string name="notice_room_topic_removed">%1$s removeu o tópico da sala</string>
-    <string name="notice_profile_change_redacted">%1$s atualizou o seu perfil %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s enviou um convite para que %2$s se junte à sala</string>
-    <string name="notice_room_third_party_registered_invite">%1$s aceitou o convite para %2$s</string>
-
-    <string name="notice_crypto_unable_to_decrypt">** Impossível decifrar: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">O dispositivo de quem enviou a mensagem não nos enviou as chaves para esta mensagem.</string>
-
-    <!-- Room Screen -->
-    <string name="could_not_redact">Não foi possível apagar</string>
-    <string name="unable_to_send_message">Não foi possível enviar a mensagem</string>
-
-    <string name="message_failed_to_upload">O envio da imagem falhou</string>
-
-    <!-- general errors -->
-    <string name="network_error">Erro de conexão à Internet</string>
-    <string name="matrix_error">Erro do Matrix</string>
-
-    <!-- Home Screen -->
-
-    <!-- Last seen time -->
-
-    <!-- call events -->
-
-    <!-- room error messages -->
-    <string name="room_error_join_failed_empty_room">Ainda não é possível voltar a entrar numa sala vazia.</string>
-
-    <string name="encrypted_message">Mensagem cifrada</string>
-
-    <!-- medium friendly name -->
-    <string name="medium_email">Endereço de e-mail</string>
-    <string name="medium_phone_number">Número de telefone</string>
-
-    <!-- Room display name -->
-    <string name="room_displayname_invite_from">Convite de %s</string>
-    <string name="room_displayname_room_invite">Convite para sala</string>
-    <string name="room_displayname_two_members">%1$s e %2$s</string>
-    <string name="room_displayname_empty_room">Sala vazia</string>
-
-
-    <string name="summary_user_sent_sticker">%1$s enviou um sticker.</string>
-
-    <string name="notice_room_update">%s fez o upgrade da sala.</string>
-
-    <string name="notice_event_redacted">Mensagem removida</string>
-    <string name="notice_event_redacted_by">Mensagem removida por %1$s</string>
-</resources>
diff --git a/matrix-sdk-android/src/main/res/values-ru/strings.xml b/matrix-sdk-android/src/main/res/values-ru/strings.xml
deleted file mode 100644
index f2e0bd668f6b5c85c33099ace140ff8e21896dff..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-ru/strings.xml
+++ /dev/null
@@ -1,285 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s отправил(а) изображение.</string>
-    <string name="notice_room_invite_no_invitee">%s приглашение</string>
-    <string name="notice_room_invite">%1$s пригласил(а) %2$s</string>
-    <string name="notice_room_invite_you">%1$s пригласил(а) вас</string>
-    <string name="notice_room_join">%1$s вошёл(ла) в комнату</string>
-    <string name="notice_room_leave">%1$s покинул(а) комнату</string>
-    <string name="notice_room_reject">%1$s отклонил(а) приглашение</string>
-    <string name="notice_room_kick">%1$s выгнан %2$s</string>
-    <string name="notice_room_unban">%1$s разблокировал(а) %2$s</string>
-    <string name="notice_room_ban">%1$s заблокировал(а) %2$s</string>
-    <string name="notice_room_withdraw">%1$s отозвал(а) приглашение %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s изменил(а) свой аватар</string>
-    <string name="notice_display_name_set">%1$s установил(а) имя %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s изменил(а) имя с %2$s на %3$s</string>
-    <string name="notice_display_name_removed">%1$s удалил(а) свое имя (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s изменил(а) тему на: %2$s</string>
-    <string name="notice_room_name_changed">%1$s изменил(а) название комнаты: %2$s</string>
-    <string name="notice_placed_video_call">%s начал(а) видеовызов.</string>
-    <string name="notice_placed_voice_call">%s начал(а) голосовой вызов.</string>
-    <string name="notice_answered_call">%s ответил(а) на звонок.</string>
-    <string name="notice_ended_call">%s завершил(а) вызов.</string>
-    <string name="notice_made_future_room_visibility">%1$s сделал(а) будущую историю комнаты видимой %2$s</string>
-    <string name="notice_room_visibility_invited">всем членам, с момента их приглашения.</string>
-    <string name="notice_room_visibility_joined">всем членам, с момента присоединения.</string>
-    <string name="notice_room_visibility_shared">всем членам.</string>
-    <string name="notice_room_visibility_world_readable">всем.</string>
-    <string name="notice_room_visibility_unknown">неизвестно (%s).</string>
-    <string name="notice_end_to_end">%1$s включил(а) сквозное шифрование (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s запросил(а) VoIP конференцию</string>
-    <string name="notice_voip_started">VoIP-конференция начата</string>
-    <string name="notice_voip_finished">VoIP-конференция завершена</string>
-    <string name="notice_avatar_changed_too">(аватар также был изменен)</string>
-    <string name="notice_room_name_removed">%1$s удалил(а) название комнаты</string>
-    <string name="notice_room_topic_removed">%1$s удалил(а) тему комнаты</string>
-    <string name="notice_profile_change_redacted">%1$s обновил(а) свой профиль %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s отправил(а) приглашение %2$s присоединиться к комнате</string>
-    <string name="notice_room_third_party_registered_invite">%1$s принял(а) приглашение от %2$s</string>
-    <string name="notice_crypto_unable_to_decrypt">** Невозможно расшифровать: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Устройство отправителя не предоставило нам ключ для расшифровки этого сообщения.</string>
-    <!-- Room Screen -->
-    <string name="could_not_redact">Не удалось изменить</string>
-    <string name="unable_to_send_message">Не удалось отправить сообщение</string>
-    <string name="message_failed_to_upload">Не удалось загрузить изображение</string>
-    <!-- general errors -->
-    <string name="network_error">Сетевая ошибка</string>
-    <string name="matrix_error">Ошибка Matrix</string>
-    <!-- Home Screen -->
-    <!-- Last seen time -->
-    <!-- call events -->
-    <!-- room error messages -->
-    <string name="room_error_join_failed_empty_room">В настоящее время невозможно вновь присоединиться к пустой комнате.</string>
-    <string name="encrypted_message">Зашифрованное сообщение</string>
-    <!-- medium friendly name -->
-    <string name="medium_email">Адрес электронной почты</string>
-    <string name="medium_phone_number">Номер телефона</string>
-    <string name="summary_user_sent_sticker">%1$s отправил стикер.</string>
-    <!-- Room display name -->
-    <string name="room_displayname_invite_from">Приглашение от %s</string>
-    <string name="room_displayname_room_invite">Приглашение в комнату</string>
-    <string name="room_displayname_two_members">%1$s и %2$s</string>
-    <string name="room_displayname_empty_room">Пустая комната</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s и 1 другой</item>
-        <item quantity="few">%1$s и %2$d другие</item>
-        <item quantity="many">%1$s и %2$d других</item>
-        <item quantity="other"/>
-    </plurals>
-    <string name="notice_event_redacted">Сообщение удалено</string>
-    <string name="notice_event_redacted_by">%1$s удалил(а) сообщение</string>
-    <string name="notice_event_redacted_with_reason">Сообщение удалено [причина: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">%1$s удалил(а) сообщение [причина: %2$s]</string>
-    <string name="initial_sync_start_importing_account">Начальная синхронизация:
-\nИмпорт учетной записи…</string>
-    <string name="initial_sync_start_importing_account_crypto">Начальная синхронизация:
-\nИмпорт криптографии</string>
-    <string name="initial_sync_start_importing_account_rooms">Начальная синхронизация:
-\nИмпорт комнат</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Синхронизация начата: 
-\nИмпорт присоединенных комнат</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Синхронизация начата: 
-\nИмпорт приглашенных комнат</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Начальная синхронизация:
-\nИмпорт покинутых комнат</string>
-    <string name="initial_sync_start_importing_account_groups">Начальная синхронизация:
-\nИмпорт сообществ</string>
-    <string name="initial_sync_start_importing_account_data">Начальная синхронизация:
-\nИмпорт данных учетной записи</string>
-    <string name="notice_room_update">%s обновил эту комнату.</string>
-    <string name="event_status_sending_message">Отправка сообщения…</string>
-    <string name="clear_timeline_send_queue">Очистить очередь отправки</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s отозвал приглашение %2$s присоединиться к комнате</string>
-    <string name="notice_room_invite_no_invitee_with_reason">Приглашение %1$s. Причина: %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s приглашен %2$s. Причина: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s пригласил вас. Причина: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s вошёл(ла) в комнату. Причина: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s покинул(а) комнату. Причина: %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s отклонил приглашение. Причина: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s выгнали %2$s. Причина: %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s разблокировано %2$s. Причина: %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s забанен %2$s. Причина: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s отправил приглашение %2$s в комнату. Причина: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s отозвал приглашение %2$s присоединиться к комнате. Причина: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s принял приглашение для %2$s. Причина: %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s отозвал приглашение %2$s. Причина: %3$s</string>
-    <string name="notice_room_created">%1$s создал(а) комнату</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s добавил(а) %2$s в качестве адреса для этой комнаты.</item>
-        <item quantity="few">%1$s добавил(а) %2$s в качестве адресов для этой комнаты.</item>
-        <item quantity="many">%1$s добавил(а) %2$s в качестве адресов для этой комнаты.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s удалил(а) адрес %2$s для комнаты.</item>
-        <item quantity="few">%1$s удалил(а) адреса %2$s для комнаты.</item>
-        <item quantity="many">%1$s удалил(а) адреса %2$s для комнаты.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s добавил(а) адреса %2$s и удалил(а) %3$s для комнаты.</string>
-    <string name="notice_room_canonical_alias_set">%1$s сделал(а) %2$s главным адресом комнаты.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s удалил(а) главный адрес комнаты.</string>
-    <string name="notice_room_guest_access_can_join">%1$s разрешил(а) гостям входить в комнату.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s запретил(а) гостям входить в комнату.</string>
-    <string name="notice_end_to_end_ok">%1$s включил(а) сквозное шифрование.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s включил(а) сквозное шифрование (неизвестный алгоритм %2$s).</string>
-    <string name="key_verification_request_fallback_message">%s запрашивает подтверждение вашего ключа, но ваш клиент не поддерживает подтверждение в чате. Используйте устаревшую проверку для сверки ключей.</string>
-    <string name="summary_you_sent_image">Вы отправили изображение.</string>
-    <string name="summary_you_sent_sticker">Вы отправили стикер.</string>
-    <string name="notice_room_invite_no_invitee_by_you">Ваше приглашение</string>
-    <string name="notice_room_created_by_you">Вы создали комнату</string>
-    <string name="notice_room_invite_by_you">Вы пригласили %1$s</string>
-    <string name="notice_room_join_by_you">Вы вошли в комнату</string>
-    <string name="notice_room_leave_by_you">Вы покинули комнату</string>
-    <string name="notice_room_reject_by_you">Вы отклонили приглашение</string>
-    <string name="notice_room_kick_by_you">Вы выгнали %1$s</string>
-    <string name="notice_room_unban_by_you">Вы разбанили %1$s</string>
-    <string name="notice_room_ban_by_you">Вы забанили %1$s</string>
-    <string name="notice_room_withdraw_by_you">Вы отозвали приглашение %1$s</string>
-    <string name="notice_avatar_url_changed_by_you">Вы сменили свой аватар</string>
-    <string name="notice_display_name_set_by_you">Вы сменили своё отображаемое имя на %1$s</string>
-    <string name="notice_display_name_changed_from_by_you">Вы сменили своё отображаемое имя с %1$s на %2$s</string>
-    <string name="notice_display_name_removed_by_you">Вы удалили своё отображаемое имя (%1$s)</string>
-    <string name="notice_room_topic_changed_by_you">Вы сменили тему на: %1$s</string>
-    <string name="notice_room_name_changed_by_you">Вы сменили название комнаты на: %1$s</string>
-    <string name="notice_placed_video_call_by_you">Вы начали видеозвонок.</string>
-    <string name="notice_placed_voice_call_by_you">Вы начали звонок.</string>
-    <string name="notice_answered_call_by_you">Вы ответили на звонок.</string>
-    <string name="notice_ended_call_by_you">Вы закончили звонок.</string>
-    <string name="notice_made_future_room_visibility_by_you">Вы сделали будущую историю комнаты видимой для %1$s</string>
-    <string name="notice_end_to_end_by_you">Вы включили сквозное шифрование (%1$s)</string>
-    <string name="notice_room_update_by_you">Вы обновили эту комнату.</string>
-    <string name="notice_requested_voip_conference_by_you">Вы начали групповой звонок</string>
-    <string name="notice_room_name_removed_by_you">Вы удалили название комнаты</string>
-    <string name="notice_room_topic_removed_by_you">Вы удалили тему комнаты</string>
-    <string name="notice_profile_change_redacted_by_you">Вы обновили свой профиль %1$s</string>
-    <string name="notice_room_third_party_invite_by_you">Вы отправили %1$s приглашение в эту комнату</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Вы отозвали у %1$s приглашение в эту комнату</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Вы приняли приглашение для %1$s</string>
-    <string name="notice_widget_added">%1$s добавил(а) виджет %2$s</string>
-    <string name="notice_widget_added_by_you">Вы добавили виджет %1$s</string>
-    <string name="notice_widget_removed">%1$s удалил(а) виджет %2$s</string>
-    <string name="notice_widget_removed_by_you">Вы удалили виджет %1$s</string>
-    <string name="notice_widget_modified">%1$s изменил(а) виджет %2$s</string>
-    <string name="notice_widget_modified_by_you">Вы изменили виджет %1$s</string>
-    <string name="power_level_admin">Администратор</string>
-    <string name="power_level_moderator">Модератор</string>
-    <string name="power_level_default">По умолчанию</string>
-    <string name="power_level_custom">Пользовательский (%1$d)</string>
-    <string name="power_level_custom_no_value">Пользовательский</string>
-    <string name="notice_power_level_changed_by_you">Вы изменили уровни доступа %1$s.</string>
-    <string name="notice_power_level_changed">%1$s изменил(а) уровни доступа %2$s.</string>
-    <string name="notice_power_level_diff">%1$s с %2$s на %3$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">Ваше приглашение. Причина: %1$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Вы пригласили %1$s. Причина: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">Вы вошли в комнату. Причина: %1$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Вы покинули комнату. Причина: %1$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Вы отклонили приглашение. Причина: %1$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Вы выгнали %1$s. Причина: %2$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Вы разбанили %1$s. Причина: %2$s</string>
-    <string name="notice_room_ban_with_reason_by_you">Вы забанили %1$s. Причина: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Вы отправили %1$s приглашение в эту комнату. Причина: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Вы отозвали у %1$s приглашение в эту комнату. Причина: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Вы приняли приглашение для %1$s. Причина: %2$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">Вы отозвали приглашение %1$s. Причина: %2$s</string>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">Вы добавили адрес %1$s для этой комнаты.</item>
-        <item quantity="few">Вы добавили %1$s в качестве адресов для этой комнаты.</item>
-        <item quantity="many">Вы добавили %1$s в качестве адресов для этой комнаты.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">Вы удалили адрес этой комнаты: %1$s.</item>
-        <item quantity="few">Вы удалили адреса этой комнаты: %1$s.</item>
-        <item quantity="many">Вы удалили адреса этой комнаты: %1$s.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed_by_you">Вы добавили адреса %1$s и удалили %2$s для этой комнаты.</string>
-    <string name="notice_room_canonical_alias_set_by_you">Вы задали главный адрес этой комнаты %1$s.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Вы удалили главный адрес этой комнаты.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Вы разрешили гостям входить в комнату.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">Вы запретили гостям входить в комнату.</string>
-    <string name="notice_end_to_end_ok_by_you">Вы включили сквозное шифрование.</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Вы включили сквозное шифрование (неизвестный алгоритм %1$s).</string>
-    <string name="notice_room_avatar_changed">%1$s изменил(а) аватар комнаты</string>
-    <string name="notice_room_avatar_changed_by_you">Вы изменили аватар комнаты</string>
-    <string name="notice_call_candidates">%s отправил(а) данные для начала звонка.</string>
-    <string name="notice_call_candidates_by_you">Вы отправили данные для начала звонка.</string>
-    <string name="notice_room_avatar_removed">%1$s удалил(а) аватар комнаты</string>
-    <string name="notice_room_avatar_removed_by_you">Вы удалили аватар комнаты</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">Вы запретили гостям входить в комнату.</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s запретил(а) гостям входить в комнату.</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">Вы разрешили гостям присоединяться сюда.</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s разрешил(а) гостям присоединиться сюда.</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">Вы вышли. Причина: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s вышел(-ла). Причина: %2$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">Вы вошли. Причина: %1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s вошел(-ла). Причина: %2$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">Вы отозвали приглашение %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s отозвал(а) приглашение %2$s</string>
-    <string name="notice_direct_room_third_party_invite_by_you">Вы пригласили %1$s</string>
-    <string name="notice_direct_room_third_party_invite">%1$s пригласил(а) %2$s</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">Вы сделали будущие сообщения видимыми для %1$s</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s сделал(а) будущие сообщения видимыми для %2$s</string>
-    <string name="notice_direct_room_leave_by_you">Вы покинули комнату</string>
-    <string name="notice_direct_room_leave">%1$s покинул(а) комнату</string>
-    <string name="notice_direct_room_join_by_you">Вы вошли</string>
-    <string name="notice_direct_room_join">%1$s вошел(ла)</string>
-    <string name="notice_direct_room_created_by_you">Вы создали обсуждение</string>
-    <string name="notice_direct_room_created">%1$s создал(а) обсуждение</string>
-    <string name="notice_direct_room_update_by_you">Вы обновили эту комнату.</string>
-    <string name="notice_direct_room_update">%s обновил(а) эту комнату.</string>
-    <plurals name="room_displayname_four_and_more_members">
-        <item quantity="one">%1$s, %2$s, %3$s и %4$d другой</item>
-        <item quantity="few">%1$s, %2$s, %3$s и %4$d других</item>
-        <item quantity="many">%1$s, %2$s, %3$s и %4$d другие</item>
-        <item quantity="other">%1$s, %2$s, %3$s и %4$d другие</item>
-    </plurals>
-    <string name="room_displayname_4_members">%1$s, %2$s, %3$s и %4$s</string>
-    <string name="room_displayname_3_members">%1$s, %2$s и %3$s</string>
-    <string name="notice_room_server_acl_allow_is_empty">🎉 Всем серверам запрещено участвовать! Эта комната больше не может быть использована.</string>
-    <string name="notice_room_server_acl_updated_no_change">Без изменений.</string>
-    <string name="room_displayname_empty_room_was">Пустая комната (была %s)</string>
-    <string name="notice_room_server_acl_set_banned">• Соответствующий сервер %s заблокирован.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_not_allowed">• Сервер, соответствующий буквальным IP-адресам, теперь запрещён.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_allowed">• Сервер, соответствующий буквальным IP-адресам, теперь разрешён.</string>
-    <string name="notice_room_server_acl_updated_banned">• Сервер, соответствующий %s, теперь запрещён.</string>
-    <string name="notice_room_server_acl_updated_allowed">• Сервер, соответствующий %s, теперь разрешён.</string>
-    <string name="notice_room_server_acl_updated_was_banned">• Сервер, соответствующий %s, был удалён из списка блокировки.</string>
-    <string name="notice_room_server_acl_set_ip_literals_not_allowed">• Сервер, соответствующий буквальным IP-адресам, запрещён.</string>
-    <string name="notice_room_server_acl_set_ip_literals_allowed">• Сервер, соответствующий буквальным IP-адресам, разрешён.</string>
-    <string name="notice_room_server_acl_set_allowed">• Сервер, соответствующий %s, разрешён.</string>
-    <string name="notice_room_server_acl_updated_was_allowed">• Сервер, соответствующий %s, был удалён из разрешённого списка.</string>
-    <string name="notice_room_server_acl_updated_title_by_you">Вы изменили права доступа сервера (ACL) для этой комнаты.</string>
-    <string name="notice_room_server_acl_updated_title">%s изменил права доступа сервера (ACL) для этой комнаты.</string>
-    <string name="notice_room_server_acl_set_title_by_you">Вы настроили права доступа сервера (ACL) для этой комнаты.</string>
-    <string name="notice_room_server_acl_set_title">%s устанавливает права доступа сервера (ACL) для этой комнаты.</string>
-    <string name="notice_room_canonical_alias_no_change_by_you">Вы изменили адреса этой комнаты.</string>
-    <string name="notice_room_canonical_alias_no_change">%1$s изменил(а) адреса этой комнаты.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed_by_you">Вы изменили основной и альтернативный адреса этой комнаты.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed">%1$s изменил(а) основной и альтернативный адреса этой комнаты.</string>
-    <string name="notice_room_canonical_alias_alternative_changed_by_you">Вы изменили альтернативные адреса для этой комнаты.</string>
-    <string name="notice_room_canonical_alias_alternative_changed">%1$s изменил(а) альтернативные адреса для этой комнаты.</string>
-    <plurals name="notice_room_canonical_alias_alternative_removed_by_you">
-        <item quantity="one">Вы удалили альтернативный адрес %1$s для этой комнаты.</item>
-        <item quantity="few">Вы удалили альтернативные адреса %1$s для этой комнаты.</item>
-        <item quantity="many">Вы удалили альтернативные адреса %1$s для этой комнаты.</item>
-        <item quantity="other">Вы удалили альтернативные адреса %1$s для этой комнаты.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_removed">
-        <item quantity="one">%1$s удалил(а) альтернативный адрес %2$s для этой комнаты.</item>
-        <item quantity="few">%1$s удалил(а) альтернативные адреса %2$s для этой комнаты.</item>
-        <item quantity="many">%1$s удалил(а) альтернативные адреса %2$s для этой комнаты.</item>
-        <item quantity="other">%1$s удалил(а) альтернативные адреса %2$s для этой комнаты.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added_by_you">
-        <item quantity="one">Вы добавили альтернативный адрес %1$s для этой комнаты.</item>
-        <item quantity="few">Вы добавили альтернативные адреса %1$s для этой комнаты.</item>
-        <item quantity="many">Вы добавили альтернативные адреса %1$s для этой комнаты.</item>
-        <item quantity="other">Вы добавили альтернативные адреса %1$s для этой комнаты.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added">
-        <item quantity="one">%1$s добавил(а) альтернативный адрес %2$s для этой комнаты.</item>
-        <item quantity="few">%1$s добавил(а) альтернативные адреса %2$s для этой комнаты.</item>
-        <item quantity="many">%1$s добавил(а) альтернативные адреса %2$s для этой комнаты.</item>
-        <item quantity="other">%1$s добавил(а) альтернативные адреса %2$s для этой комнаты.</item>
-    </plurals>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-si/strings_sas.xml b/matrix-sdk-android/src/main/res/values-si/strings_sas.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7ea72d2a4df9b43e633f53ad5fd7918cf666185b
--- /dev/null
+++ b/matrix-sdk-android/src/main/res/values-si/strings_sas.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- Generated file, do not edit -->
+    <string name="verification_emoji_dog">බල්ලා</string>
+    <string name="verification_emoji_cat">පූසා</string>
+    <string name="verification_emoji_lion">සිංහයා</string>
+    <string name="verification_emoji_horse">අශ්වයා</string>
+</resources>
diff --git a/matrix-sdk-android/src/main/res/values-sk/strings.xml b/matrix-sdk-android/src/main/res/values-sk/strings.xml
deleted file mode 100644
index a40654f7bf39cd922af9a677645eb42509bb3536..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-sk/strings.xml
+++ /dev/null
@@ -1,212 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s poslal/a obrázok.</string>
-    <string name="notice_room_invite_no_invitee">Pozvanie od %s</string>
-    <string name="notice_room_invite">%1$s pozval/a %2$s</string>
-    <string name="notice_room_invite_you">%1$s vás pozval/a</string>
-    <string name="notice_room_join">%1$s vstúpil/a do miestnosti</string>
-    <string name="notice_room_leave">%1$s opustil/a miestnosť</string>
-    <string name="notice_room_reject">%1$s odmietol/a pozvanie</string>
-    <string name="notice_room_kick">%1$s vykázal/a %2$s</string>
-    <string name="notice_room_unban">%1$s povolil/a vstupovať %2$s</string>
-    <string name="notice_room_ban">%1$s zakázal/a vstupovať %2$s</string>
-    <string name="notice_room_withdraw">%1$s vzal/a späť pozvanie %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s si zmenil/a obrázok v profile</string>
-    <string name="notice_display_name_set">%1$s si nastavil/a zobrazované meno %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s si zmenil/a zobrazované meno %2$s na %3$s</string>
-    <string name="notice_display_name_removed">%1$s odstránil/a svoje zobrazované meno (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s zmenil/a tému na: %2$s</string>
-    <string name="notice_room_name_changed">%1$s zmenil/a názov miestnosti na: %2$s</string>
-    <string name="notice_placed_video_call">%s uskutočnil/a video hovor.</string>
-    <string name="notice_placed_voice_call">%s zatelefonoval/a.</string>
-    <string name="notice_answered_call">%s prijal/a hovor.</string>
-    <string name="notice_ended_call">%s ukončil/a hovor.</string>
-    <string name="notice_made_future_room_visibility">%1$s sprístupnil/a budúcu históriu miestnosti %2$s</string>
-    <string name="notice_room_visibility_invited">pre všetkých členov, od kedy boli pozvaní.</string>
-    <string name="notice_room_visibility_joined">pre všetkých členov, od kedy vstúpili.</string>
-    <string name="notice_room_visibility_shared">pre všetkých členov.</string>
-    <string name="notice_room_visibility_world_readable">pre každého.</string>
-    <string name="notice_room_visibility_unknown">neznámym (%s).</string>
-    <string name="notice_end_to_end">%1$s povolil/a E2E Å¡ifrovanie (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s požiadal/a o VoIP konferenciu</string>
-    <string name="notice_voip_started">Začala sa VoIP konferencia</string>
-    <string name="notice_voip_finished">Skončila sa VoIP konferencia</string>
-    <string name="notice_avatar_changed_too">(aj obrázok v profile)</string>
-    <string name="notice_room_name_removed">%1$s odstránil/a názov miestnosti</string>
-    <string name="notice_room_topic_removed">%1$s odstránil/a tému miestnosti</string>
-    <string name="notice_profile_change_redacted">%1$s aktualizoval/a svoj profil %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s pozval/a %2$s vstúpiť do miestnosti</string>
-    <string name="notice_room_third_party_registered_invite">%1$s prijal/a pozvanie pre %2$s</string>
-    <string name="notice_crypto_unable_to_decrypt">** Nie je možné dešifrovať: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Zo zariadenia odosieľateľa nebolo možné získať kľúče potrebné na dešifrovanie tejto správy.</string>
-    <string name="could_not_redact">Nie je možné vymazať</string>
-    <string name="unable_to_send_message">Nie je možné odoslať správu</string>
-    <string name="message_failed_to_upload">Nepodarilo sa nahrať obrázok</string>
-    <string name="network_error">Chyba siete</string>
-    <string name="matrix_error">Chyba Matrix</string>
-    <string name="room_error_join_failed_empty_room">V súčasnosti nie je možné znovu vstúpiť do prázdnej miestnosti.</string>
-    <string name="encrypted_message">Šifrovaná správa</string>
-    <string name="medium_email">Emailová adresa</string>
-    <string name="medium_phone_number">Telefónne číslo</string>
-    <string name="summary_user_sent_sticker">%1$s poslal/a nálepku.</string>
-    <string name="room_displayname_invite_from">Pozvanie od %s</string>
-    <string name="room_displayname_room_invite">Pozvanie do miestnosti</string>
-    <string name="room_displayname_two_members">%1$s a %2$s</string>
-    <string name="room_displayname_empty_room">Prázdna miestnosť</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s a 1 ďalší</item>
-        <item quantity="few">%1$s a %2$d ďalší</item>
-        <item quantity="many">%1$s a %2$d ďalších</item>
-        <item quantity="other"/>
-    </plurals>
-    <string name="notice_room_update">%s aktualizoval/a túto miestnosť.</string>
-    <string name="notice_event_redacted">Odstránená správa</string>
-    <string name="notice_event_redacted_by">Odstránená správa používateľom %1$s</string>
-    <string name="notice_event_redacted_with_reason">Odstránená správa [dôvod: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Odstránená správa používateľom %1$s [dôvod: %2$s]</string>
-    <string name="initial_sync_start_importing_account">Úvodná synchronizácia:
-\nPrebieha import účtu…</string>
-    <string name="initial_sync_start_importing_account_crypto">Úvodná synchronizácia:
-\nPrebieha import šifrovacích kľúčov</string>
-    <string name="initial_sync_start_importing_account_rooms">Úvodná synchronizácia:
-\nPrebieha import miestností</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Úvodná synchronizácia:
-\nPrebieha import miestností, do ktorých ste vstúpili</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Úvodná synchronizácia: 
-\nPrebieha import pozvaní</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Úvodná synchronizácia:
-\nPrebieha import opustených miestností</string>
-    <string name="initial_sync_start_importing_account_groups">Úvodná synchronizácia:
-\nPrebieha import komunít</string>
-    <string name="initial_sync_start_importing_account_data">Úvodná synchronizácia:
-\nPrebieha import údajov účtu</string>
-    <string name="event_status_sending_message">Odosielanie správy…</string>
-    <string name="clear_timeline_send_queue">Vymazať správy na odoslanie</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s zamietol/a pozvanie používateľa %2$s vstúpiť do miestnosti</string>
-    <string name="notice_room_invite_no_invitee_with_reason">Pozvanie od %1$s. Dôvod: %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s pozval/a %2$s. Dôvod: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s vás pozval/a. Dôvod: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s vstúpil/a do miestnosti. Dôvod: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s opustil/a miestnosť. Dôvod: %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s odmietol/a pozvanie. Dôvod: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s vykázal/a %2$s. Dôvod: %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s povolil/a vstupovať %2$s. Dôvod: %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s zakázal/a vstupovať %2$s. Dôvod: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s pozval/a %2$s vstúpiť do miestnosti. Dôvod: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s zamietol/a pozvanie používateľa %2$s vstúpiť do miestnosti. Dôvod: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s prijal/a pozvanie pre %2$s. Dôvod: %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s vzal/a späť pozvanie %2$s. Dôvod: %3$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s pridal/a adresu %2$s pre túto miestnosť.</item>
-        <item quantity="few">%1$s pridal/a adresy %2$s pre túto miestnosť.</item>
-        <item quantity="other">%1$s pridal/a adresy %2$s pre túto miestnosť.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s odstránil/a adresu %2$s pre túto miestnosť.</item>
-        <item quantity="few">%1$s odstránil/a adresy %3$s pre túto miestnosť.</item>
-        <item quantity="other">%1$s odstránil/a adresy %3$s pre túto miestnosť.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s pridal/a adresy %2$s a odstránil/a adresy %3$s pre túto miestnosť.</string>
-    <string name="notice_room_canonical_alias_set">%1$s nastavil/a hlavnú adresu tejto miestnosti %2$s.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s odstránil/a hlavnú adresu tejto miestnosti.</string>
-    <string name="notice_room_guest_access_can_join">%1$s povolil/a hosťom///návštevníkom prístup do tejto miestnosti.</string>
-    <string name="summary_you_sent_image">Poslali ste obrázok.</string>
-    <string name="summary_you_sent_sticker">Poslali ste nálepku.</string>
-    <string name="notice_room_invite_no_invitee_by_you">Pozvanie od vás</string>
-    <string name="notice_room_created">%1$s vytvoril/a miestnosť</string>
-    <string name="notice_room_created_by_you">Vytvorili ste miestnosť</string>
-    <string name="notice_room_invite_by_you">Pozvali ste %1$s</string>
-    <string name="notice_room_join_by_you">Vstúpili ste do miestnosti</string>
-    <string name="notice_room_leave_by_you">Opustili ste miestnosť</string>
-    <string name="notice_room_reject_by_you">Odmietli ste pozvanie</string>
-    <string name="notice_room_kick_by_you">Vykázali ste %1$s</string>
-    <string name="notice_room_unban_by_you">Povolili ste vstupovať %1$s</string>
-    <string name="notice_room_ban_by_you">Zakázali ste vstupovať %1$s</string>
-    <string name="notice_room_withdraw_by_you">Vzali ste späť pozvanie %1$s</string>
-    <string name="notice_avatar_url_changed_by_you">Zmenili ste si obrázok v profile</string>
-    <string name="notice_display_name_set_by_you">Nastavili ste si zobrazované meno %1$s</string>
-    <string name="notice_display_name_changed_from_by_you">Zmenili ste si zobrazované meno %1$s na %2$s</string>
-    <string name="notice_display_name_removed_by_you">Odstránili ste svoje zobrazované meno %1$s</string>
-    <string name="notice_room_topic_changed_by_you">Zmenili ste tému na: %1$s</string>
-    <string name="notice_room_avatar_changed">%1$s zmenil/a obrázok miestnosti</string>
-    <string name="notice_room_avatar_changed_by_you">Zmenili ste obrázok miestnosti</string>
-    <string name="notice_room_name_changed_by_you">Zmenili ste názov miestnosti na: %1$s</string>
-    <string name="notice_placed_video_call_by_you">Uskutočnili ste video hovor.</string>
-    <string name="notice_placed_voice_call_by_you">Zatelefonovali ste.</string>
-    <string name="notice_call_candidates">%s poslal údaje pre nastavenie hovoru.</string>
-    <string name="notice_call_candidates_by_you">Poslali ste údaje na nastavenie hovoru.</string>
-    <string name="notice_answered_call_by_you">Prijali ste hovor.</string>
-    <string name="notice_ended_call_by_you">Ukončili ste hovor.</string>
-    <string name="notice_made_future_room_visibility_by_you">Sprístupnili ste budúcu históriu miestnosti %1$s</string>
-    <string name="notice_end_to_end_by_you">Povolili ste E2E Å¡ifrovanie (%1$s)</string>
-    <string name="notice_room_update_by_you">Aktualizovali ste túto miestnosť.</string>
-    <string name="notice_requested_voip_conference_by_you">Požiadali ste o VoIP konferenciu</string>
-    <string name="notice_room_name_removed_by_you">Odstránili ste názov miestnosti</string>
-    <string name="notice_room_topic_removed_by_you">Odstránili ste tému miestnosti</string>
-    <string name="notice_room_avatar_removed">%1$s odstránil obrázok miestnosti</string>
-    <string name="notice_room_avatar_removed_by_you">Odstránili ste obrázok miestnosti</string>
-    <string name="notice_profile_change_redacted_by_you">Aktualizovali ste svoj profil %1$s</string>
-    <string name="notice_room_third_party_invite_by_you">Pozvali ste %1$s vstúpiť do miestnosti</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Zamietli ste pozvanie používateľa %1$s vstúpiť do miestnosti</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Prijali ste pozvanie pre %1$s</string>
-    <string name="notice_widget_added">%1$s pridal/a widget %2$s</string>
-    <string name="notice_widget_added_by_you">Pridali ste widget %1$s</string>
-    <string name="notice_widget_removed">%1$s odstránil/a widget %2$s</string>
-    <string name="notice_widget_removed_by_you">Odstránili ste widget %1$s</string>
-    <string name="notice_widget_modified">%1$s upravil/a widget %2$s</string>
-    <string name="notice_widget_modified_by_you">Upravili ste widget %1$s</string>
-    <string name="power_level_admin">Správca</string>
-    <string name="power_level_moderator">Moderátor</string>
-    <string name="power_level_default">Predvolený</string>
-    <string name="power_level_custom">Vlastná úroveň (%1$d)</string>
-    <string name="power_level_custom_no_value">Vlastná úroveň</string>
-    <string name="notice_power_level_changed_by_you">Zmenili ste úroveň moci používateľa %1$s.</string>
-    <string name="notice_power_level_changed">%1$s zmenil úroveň moci používateľa %2$s.</string>
-    <string name="notice_power_level_diff">%1$s z %2$s na %3$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">Pozvanie od vás. Dôvod: %1$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Pozvali ste %1$s. Dôvod: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">Vstúpili ste do miestnosti. Dôvod: %1$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Opustili ste miestnosť. Dôvod: %1$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Odmietli ste pozvanie. Dôvod: %1$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Vykázali ste %1$s. Dôvod: %2$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Povolili ste vstupovať %1$s. Dôvod: %2$s</string>
-    <string name="notice_room_ban_with_reason_by_you">Zakázali ste vstupovať %1$s. Dôvod: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Pozvali ste %1$s vstúpiť do miestnosti. Dôvod: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Zamietli ste pozvanie používateľa %1$s vstúpiť do miestnosti. Dôvod: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Prijali ste pozvanie pre %1$s. Dôvod: %2$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">Vzali ste späť pozvanie %1$s. Dôvod: %2$s</string>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">Pridali ste adresu %1$s pre túto miestnosť.</item>
-        <item quantity="few">Pridali ste adresy %1$s pre túto miestnosť.</item>
-        <item quantity="other">Pridali ste adresy %1$s pre túto miestnosť.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">Odstránili ste adresu %1$s pre túto miestnosť.</item>
-        <item quantity="few">Odstránili ste adresy %1$s pre túto miestnosť.</item>
-        <item quantity="other">Odstránili ste adresy %1$s pre túto miestnosť.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed_by_you">Pridali ste %1$s a odstránili adresy %2$s pre túto miestnosť.</string>
-    <string name="notice_room_canonical_alias_set_by_you">Nastavili ste hlavnú adresu tejto miestnosti %1$s.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Odstránili ste hlavnú adresu tejto miestnosti.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Povolili ste hosťom///návštevníkom prístup do tejto miestnosti.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s zakázal/a hosťom///návštevníkom prístup do tejto miestnosti.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">Zakázali ste hosťom///návštevníkom prístup do tejto miestnosti.</string>
-    <string name="notice_end_to_end_ok">%1$s povolil/a E2E Å¡ifrovanie.</string>
-    <string name="notice_end_to_end_ok_by_you">Povolili ste E2E Å¡ifrovanie.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s povolil/a E2E šifrovanie (Nerozpoznaný algorytmus %2$s).</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Povolili ste E2E šifrovanie (Nerozpoznaný algorytmus %1$s).</string>
-    <string name="key_verification_request_fallback_message">%s požaduje overenie vašich šifrovacích kľúčov, ale váš klient nepodporuje overenie kľúčov v konverzácii. Budete musieť použiť zastaralú metódu overenia.</string>
-    <string name="notice_room_server_acl_set_title_by_you">nastavili ste na servery pravidlá ACL tejto miestnosti.</string>
-    <string name="notice_room_server_acl_set_title">%s nastavil(a) na servery pravidlá ACL tejto miestnosti.</string>
-    <string name="notice_direct_room_update_by_you">Aktualizovali ste sem.</string>
-    <string name="notice_direct_room_update">%s aktualizoval(a) sem.</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s sprístupnil(a) budúce správy %2$s</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">Sprístupnili ste budúce správy %1$s</string>
-    <string name="notice_direct_room_leave_by_you">Opustili ste miestnosť</string>
-    <string name="notice_direct_room_leave">%1$s opustil(a) miestnosť</string>
-    <string name="notice_direct_room_join_by_you">Vstúpili ste</string>
-    <string name="notice_direct_room_join">%1$s vstúpil(a)</string>
-    <string name="notice_direct_room_created_by_you">Vytvorili ste konverzáciu</string>
-    <string name="notice_direct_room_created">%1$s vytvoril(a) konverzáciu</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-sq/strings.xml b/matrix-sdk-android/src/main/res/values-sq/strings.xml
deleted file mode 100644
index 0d4b2888ba016cbdd6628621c05b346308699320..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-sq/strings.xml
+++ /dev/null
@@ -1,257 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s dërgoi një figurë.</string>
-    <string name="notice_room_invite">%1$s ftoi %2$s</string>
-    <string name="notice_room_invite_you">%1$s ju ftoi</string>
-    <string name="notice_room_join">%1$s hyri në dhomë</string>
-    <string name="notice_room_leave">%1$s doli nga dhoma</string>
-    <string name="notice_room_reject">%1$s hodhi tej ftesën</string>
-    <string name="notice_room_kick">%1$s përzuri %2$s</string>
-    <string name="notice_room_ban">%1$s dëboi %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s ndryshoi avatarin e vet</string>
-    <string name="notice_room_topic_changed">%1$s ndryshoi temën në: %2$s</string>
-    <string name="notice_room_name_changed">%1$s ndryshoi emrin e dhomës në: %2$s</string>
-    <string name="notice_placed_video_call">%s bëri një thirrje video.</string>
-    <string name="notice_placed_voice_call">%s bëri një thirrje zanore.</string>
-    <string name="notice_answered_call">%s iu përgjigj thirrjes.</string>
-    <string name="notice_ended_call">%s e përfundoi thirrjen.</string>
-    <string name="notice_made_future_room_visibility">%1$s e bëri historikun e ardhshëm të dhomës të dukshëm për %2$s</string>
-    <string name="notice_room_visibility_invited">për krejt anëtarët e dhomës, prej çastit kur janë ftuar.</string>
-    <string name="notice_room_visibility_joined">për krejt anëtarët e dhomës, prej çastit kur morën pjesë.</string>
-    <string name="notice_room_visibility_shared">krejt anëtarët e dhomës.</string>
-    <string name="notice_room_visibility_world_readable">cilido.</string>
-    <string name="notice_room_visibility_unknown">e panjohur (%s).</string>
-    <string name="notice_requested_voip_conference">%1$s kërkoi një konferencë VoIP</string>
-    <string name="notice_voip_started">Konferenca VoIP filloi</string>
-    <string name="notice_voip_finished">Konferenca VoIP përfundoi</string>
-    <string name="notice_avatar_changed_too">(u ndryshua edhe avatari)</string>
-    <string name="notice_room_name_removed">%1$s hoqi emrin e dhomës</string>
-    <string name="notice_profile_change_redacted">%1$s përditësoi profilin e tij %2$s</string>
-    <string name="notice_room_third_party_registered_invite">%1$s pranoi ftesën tuaj për %2$s</string>
-    <string name="notice_crypto_unable_to_decrypt">** S’arrihet të shfshehtëzohet: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Pajisja e dërguesit nuk na ka dërguar kyçet për këtë mesazh.</string>
-    <string name="could_not_redact">S’u redaktua dot</string>
-    <string name="unable_to_send_message">S’arrihet të dërgohet mesazh</string>
-    <string name="message_failed_to_upload">Ngarkimi i figurës dështoi</string>
-    <string name="network_error">Gabim rrjeti</string>
-    <string name="matrix_error">Gabim Matrix</string>
-    <string name="room_error_join_failed_empty_room">Hëpërhë s’është e mundur të rihyhet në një dhomë të zbrazët.</string>
-    <string name="encrypted_message">Mesazh i fshehtëzuar</string>
-    <string name="medium_email">Adresë email</string>
-    <string name="medium_phone_number">Numër telefoni</string>
-    <string name="room_displayname_invite_from">Ftesë nga %s</string>
-    <string name="room_displayname_room_invite">Ftesë Dhome</string>
-    <string name="room_displayname_two_members">%1$s dhe %2$s</string>
-    <string name="room_displayname_empty_room">Dhomë e zbrazët</string>
-    <string name="summary_user_sent_sticker">%1$s dërgoi një ngjitës.</string>
-    <string name="notice_room_invite_no_invitee">Ftesë e %s</string>
-    <string name="notice_room_unban">%1$s hoqi dëbimin për %2$s</string>
-    <string name="notice_room_withdraw">%1$s tërhoqi mbrapsht ftesën për %2$s</string>
-    <string name="notice_display_name_set">%1$s caktoi për veten emër ekrani %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s ndryshoi emrin e tyre në ekran nga %2$s në %3$s</string>
-    <string name="notice_display_name_removed">%1$s hoqi emrin e tij në ekran (%2$s)</string>
-    <string name="notice_end_to_end">%1$s aktivizoi fshehtëzim skaj-më-skaj (%2$s)</string>
-    <string name="notice_room_topic_removed">%1$s hoqi temën e dhomës</string>
-    <string name="notice_room_third_party_invite">%1$s dërgoi një ftesë për %2$s që të marrë pjesë në dhomë</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s dhe 1 tjetër</item>
-        <item quantity="other">%1$s dhe %2$d të tjerë</item>
-    </plurals>
-    <string name="notice_event_redacted">Mesazhi u hoq</string>
-    <string name="notice_event_redacted_by">Mesazhi u hoq nga %1$s</string>
-    <string name="notice_event_redacted_with_reason">Mesazh i hequr [arsye: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Mesazh i hequr nga %1$s [arsye: %2$s]</string>
-    <string name="notice_room_update">%s e përmirësoi këtë dhomë.</string>
-    <string name="initial_sync_start_importing_account">Njëkohësimi Fillestar:
-\nPo importohet llogaria…</string>
-    <string name="initial_sync_start_importing_account_crypto">Njëkohësimi Fillestar:
-\nPo importohet kriptografi</string>
-    <string name="initial_sync_start_importing_account_rooms">Njëkohësimi Fillestar:
-\nPo importohen Dhoma</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Njëkohësimi Fillestar:
-\nPo importohen Dhoma Ku Është Bërë Hyrje</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Njëkohësimi Fillestar:
-\nPo importohen Dhoma Me Ftesë</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Njëkohësimi Fillestar:
-\nPo importohen Dhoma të Braktisura</string>
-    <string name="initial_sync_start_importing_account_groups">Njëkohësimi Fillestar:
-\nPo importohen Bashkësi</string>
-    <string name="initial_sync_start_importing_account_data">Njëkohësimi Fillestar:
-\nPo importohet të Dhëna Llogarie</string>
-    <string name="event_status_sending_message">Po dërgohet mesazh…</string>
-    <string name="clear_timeline_send_queue">Spastro radhë pritjeje</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s shfuqizoi ftesën për %2$s për pjesëmarrje te dhoma</string>
-    <string name="notice_room_invite_no_invitee_with_reason">Ftesë e %1$s. Arsye: %2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s ftoi %2$s. Arsye: %3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s ju ftoi. Arsye: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s erdhi në dhomë. Arsye: %2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s doli nga dhoma. Arsye: %2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s hodhi poshtë ftesën. Arsye: %2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s përzuri %2$s. Arsye: %3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s hoqi dëbimin për %2$s. Arsye: %3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s dëboi %2$s. Arsye: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s dërgoi një ftesë për %2$s për të ardhur në dhomë. Arsye: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s shfuqizoi ftesën për %2$s për të ardhur në dhomë. Arsye: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s pranoi ftesën për %2$s. Arsye: %3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s tërhoqi mbrapsht ftesën për %2$s. Arsye: %3$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s shtoi %2$s si një adresë për këtë dhomë.</item>
-        <item quantity="other">%1$s shtoi %2$s si adresa për këtë dhomë.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s hoqi %2$s si adresë për këtë dhomë.</item>
-        <item quantity="other">%1$s hoqi %2$s si adresa për këtë dhomë.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s shtoi %2$s dhe hoqi %3$s si adresa për këtë dhomë.</string>
-    <string name="notice_room_canonical_alias_set">%1$s caktoi %2$s si adresë kryesore për këtë dhomë.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s hoqi adresën kryesore për këtë dhomë.</string>
-    <string name="notice_room_guest_access_can_join">%1$s ka lejuar vizitorë të marrin pjesë në dhomë.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s ka penguar vizitorë të marrin pjesë në dhomë.</string>
-    <string name="notice_end_to_end_ok">%1$s aktivizoi fshehtëzim skaj-më-skaj.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s aktivizoi fshehtëzim skaj-më-skaj (algoritëm i papranuar %2$s).</string>
-    <string name="key_verification_request_fallback_message">%s po kërkon të verifikojë kyçin tuaj, por klienti juaj nuk mbulon verifikim kyçesh brenda fjalosjeje. Që të verifikoni kyça, do t’ju duhet të përdorni verifikim të dikurshëm kyçesh.</string>
-    <string name="notice_room_created">%1$s krijo dhomën</string>
-    <string name="summary_you_sent_image">Dërguat një figurë.</string>
-    <string name="summary_you_sent_sticker">Dërguat një ngjitës.</string>
-    <string name="notice_room_invite_no_invitee_by_you">Ftesa juaj</string>
-    <string name="notice_room_created_by_you">Krijuat dhomën</string>
-    <string name="notice_room_invite_by_you">Ftuat %1$s</string>
-    <string name="notice_room_join_by_you">Hytë në dhomë</string>
-    <string name="notice_room_leave_by_you">Dolët nga dhoma</string>
-    <string name="notice_room_reject_by_you">Hodhët poshtë ftesën</string>
-    <string name="notice_room_kick_by_you">Përzutë %1$s</string>
-    <string name="notice_room_unban_by_you">Hoqët dëbimin për %1$s</string>
-    <string name="notice_room_ban_by_you">Dëbuat %1$s</string>
-    <string name="notice_room_withdraw_by_you">Tërhoqët mbrapsht ftesën për %1$s</string>
-    <string name="notice_avatar_url_changed_by_you">Ndryshuat avatarin tuaj</string>
-    <string name="notice_display_name_set_by_you">Caktuat si emrin tuaj në ekran %1$s</string>
-    <string name="notice_display_name_changed_from_by_you">E ndryshuat emrin tuaj në ekran nga %1$s në %2$s</string>
-    <string name="notice_display_name_removed_by_you">Hoqët emrin tuaj në ekran (qe %1$s)</string>
-    <string name="notice_room_topic_changed_by_you">E ndryshuat temën në: %1$s</string>
-    <string name="notice_room_avatar_changed">%1$s ndryshoi avatarin e dhomës</string>
-    <string name="notice_room_avatar_changed_by_you">Ndryshuat avatarin e dhomës</string>
-    <string name="notice_room_name_changed_by_you">Ndryshuat emrin e dhomës në: %1$s</string>
-    <string name="notice_placed_video_call_by_you">Filluat një thirrje video.</string>
-    <string name="notice_placed_voice_call_by_you">Filluat një thirrje zanore.</string>
-    <string name="notice_call_candidates">%s dërgoi të dhëna për ujdisjen e thirrjes.</string>
-    <string name="notice_call_candidates_by_you">Dërguat të dhëna për ujdisjen e thirrjes.</string>
-    <string name="notice_answered_call_by_you">Iu përgjigjët thirrjes.</string>
-    <string name="notice_ended_call_by_you">E përfunduat thirrjen.</string>
-    <string name="notice_made_future_room_visibility_by_you">E bëtë historikun e ardhshëm të dhomë të dukshëm për %1$s</string>
-    <string name="notice_end_to_end_by_you">Aktivizuat fshehtëzim skaj-më-skaj (%1$s)</string>
-    <string name="notice_room_update_by_you">Përmirësuat këtë dhomë.</string>
-    <string name="notice_requested_voip_conference_by_you">Kërkuat një konferencë VoIP</string>
-    <string name="notice_room_name_removed_by_you">Hoqët emrin e dhomës</string>
-    <string name="notice_room_topic_removed_by_you">Hoqët temën e dhomës</string>
-    <string name="notice_room_avatar_removed">%1$s hoqi avatarin e dhomës</string>
-    <string name="notice_room_avatar_removed_by_you">Hoqët avatarin e dhomës</string>
-    <string name="notice_profile_change_redacted_by_you">Përditësuat profilin tuaj %1$s</string>
-    <string name="notice_room_third_party_invite_by_you">Dërguat një ftesë te %1$s për të ardhur te dhoma</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Shfuqizuat ftesën për ardhjen në dhomë të %1$s</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Pranuat ftesën për %1$s</string>
-    <string name="notice_widget_added">%1$s shtoi widget-in %2$s</string>
-    <string name="notice_widget_added_by_you">Shtuat widget-in %1$s</string>
-    <string name="notice_widget_removed">%1$s hoqi widget-in %2$s</string>
-    <string name="notice_widget_removed_by_you">Hoqët widget-in %1$s</string>
-    <string name="notice_widget_modified">%1$s ndryshoi widget-in %2$s</string>
-    <string name="notice_widget_modified_by_you">Ndryshuat widget-in %1$s</string>
-    <string name="power_level_admin">Përgjegjës</string>
-    <string name="power_level_moderator">Moderator</string>
-    <string name="power_level_default">Parazgjedhje</string>
-    <string name="power_level_custom">Vetjake (%1$d)</string>
-    <string name="power_level_custom_no_value">Vetjake</string>
-    <string name="notice_power_level_changed_by_you">Ndryshuat shkallën e pushtetit për %1$s.</string>
-    <string name="notice_power_level_changed">%1$s ndryshoi shkallën e pushtetit për %2$s.</string>
-    <string name="notice_power_level_diff">%1$s nga %2$s në %3$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">Ftesa juaj. Arsye: %1$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Ftuat %1$s. Arsye: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">Erdhët në dhomë, Arsye: %1$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Ikët nga dhoma. Arsye: %1$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Hodhët poshtë ftesën. Arsye: %1$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Përzutë %1$s. Arsye: %2$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Hoqët dëbimin për %1$s. Arsye: %2$s</string>
-    <string name="notice_room_ban_with_reason_by_you">Dëbuat %1$s. Arsye: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Dërguat një ftesë për %1$s të vijë në dhomë. Arsye: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Shfuqizuat ftesën për ardhjen në dhomë të %1$s. Arsye: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Pranuat ftesën për %1$s. Arsye: %2$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">Tërhoqët mbrapsht ftesën për %1$s. Arsye: %2$s</string>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">Shtuat %1$s si një adresë për këtë dhomë.</item>
-        <item quantity="other">Shtuat %1$s si adresa për këtë dhomë.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">Hoqët %1$s si një adresë për këtë dhomë.</item>
-        <item quantity="other">Hoqët %1$s si adresa për këtë dhomë.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed_by_you">Shtuat %1$s dhe hoqët %2$s si adresa për këtë dhomë.</string>
-    <string name="notice_room_canonical_alias_set_by_you">Caktuat si adresë kryesore për këtë dhomë %1$s.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Hoqët adresën kryesore për këtë dhomë.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Keni lejuar të vijnë mysafirë në dhomë.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">U keni penguar mysafirëve të vijnë në dhomë.</string>
-    <string name="notice_end_to_end_ok_by_you">Aktivizuat fshehtëzimin skaj-më-skaj.</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Aktivizuat fshehtëzimin skaj-më-skaj (algoritëm %1$s i panjohur).</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">Keni penguar të vijnë në dhomë mysafirë.</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s ka penguar të vijnë në dhomë mysafirë.</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">Keni lejuar të vijnë mysafirë këtu.</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s ka lejuar të vijnë këtu mysafirë.</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">Dolët. Arsye: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s doli. Arsye: %2$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">Erdhët. Arsye: %1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s erdhi. Arsye: %2$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">Shfuqizuat ftesën për %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s shfuqizoi ftesën për %2$s</string>
-    <string name="notice_direct_room_third_party_invite_by_you">Ftuat %1$s</string>
-    <string name="notice_direct_room_third_party_invite">%1$s ftoi %2$s</string>
-    <string name="notice_direct_room_update_by_you">U përmirësuat këtu.</string>
-    <string name="notice_direct_room_update">%s këtu u përmirësua.</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">I bëtë mesazhet e ardhshëm të dukshëm për %1$s</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s i bëri mesazhet e ardhshëm të dukshëm për %2$s</string>
-    <string name="notice_direct_room_leave_by_you">Dolët nga dhoma</string>
-    <string name="notice_direct_room_leave">%1$s doli nga dhoma</string>
-    <string name="notice_direct_room_join_by_you">Erdhët</string>
-    <string name="notice_direct_room_join">%1$s erdhi</string>
-    <string name="notice_direct_room_created_by_you">Krijuat diskutimin</string>
-    <string name="notice_direct_room_created">%1$s krijoi diskutimin</string>
-    <string name="room_displayname_empty_room_was">Dhomë e zbrazët (was %s)</string>
-    <plurals name="room_displayname_four_and_more_members">
-        <item quantity="one">%1$s, %2$s, %3$s dhe %4$d tjetër</item>
-        <item quantity="other">%1$s, %2$s, %3$s dhe %4$d të tjerë</item>
-    </plurals>
-    <string name="room_displayname_4_members">%1$s, %2$s, %3$s dhe %4$s</string>
-    <string name="room_displayname_3_members">%1$s, %2$s dhe %3$s</string>
-    <string name="notice_room_server_acl_allow_is_empty">🎉 U është penguar pjesëmarrja krejt shërbyesve! Kjo dhomë s’mund të përdoret më.</string>
-    <string name="notice_room_server_acl_updated_no_change">Pa ndryshim.</string>
-    <string name="notice_room_server_acl_updated_title_by_you">Ndryshuat ACL-ra shërbyesi për këtë dhomë.</string>
-    <string name="notice_room_server_acl_updated_title">%s ndryshoi ACL-ra shërbyesi për këtë dhomë.</string>
-    <string name="notice_room_server_acl_set_title_by_you">Ujdisët ACL-ra shërbyesi për këtë dhomë.</string>
-    <string name="notice_room_server_acl_set_title">%s ujdisi ACL-ra shërbyesi për këtë dhomë.</string>
-    <string name="notice_room_server_acl_updated_was_allowed">• Shërbyes që kanë përputhje me %s u hoqën nga lista e të lejuarve.</string>
-    <string name="notice_room_server_acl_updated_allowed">• Shërbyesit që kanë përputhje me %s tani janë të lejuar.</string>
-    <string name="notice_room_server_acl_updated_was_banned">• Shërbyesit që kanë përputhje me %s u hoqën nga lista e ndalimeve.</string>
-    <string name="notice_room_server_acl_updated_banned">• Shërbyesit që kanë përputhje me %s tani janë të ndaluar.</string>
-    <string name="notice_room_server_acl_set_allowed">• Shërbyesit që kanë përputhje me %s janë të ndaluar.</string>
-    <string name="notice_room_server_acl_set_banned">• Shërbyesit që kanë përputhje me %s janë të ndaluar.</string>
-    <string name="notice_room_canonical_alias_no_change_by_you">Ndryshuat adresat për këtë dhomë.</string>
-    <string name="notice_room_canonical_alias_no_change">%1$s ndryshoi adresat për këtë dhomë.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed_by_you">Ndryshuat adresat kryesore dhe alternative për këtë dhomë.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed">%1$s ndryshoi adresat kryesore dhe alternative për këtë dhomë.</string>
-    <string name="notice_room_canonical_alias_alternative_changed_by_you">Ndryshuat adresat alternative për këtë dhomë.</string>
-    <string name="notice_room_canonical_alias_alternative_changed">%1$s ndryshoi adresat alternative për këtë dhomë.</string>
-    <plurals name="notice_room_canonical_alias_alternative_removed_by_you">
-        <item quantity="one">Hoqët adresën alternative %1$s për këtë dhomë.</item>
-        <item quantity="other">Hoqët adresat alternative %1$s për këtë dhomë.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_removed">
-        <item quantity="one">%1$s hoqët adresën alternative %2$s për këtë dhomë.</item>
-        <item quantity="other">%1$s hoqët adresat alternative %2$s për këtë dhomë.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added_by_you">
-        <item quantity="one">Shtuat adresën alternative %1$s për këtë dhomë.</item>
-        <item quantity="other">Shtuat adresat alternative %1$s për këtë dhomë.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added">
-        <item quantity="one">%1$s shtoi adresën alternative %2$s për këtë dhomë.</item>
-        <item quantity="other">%1$s shtoi adresat alternative %2$s për këtë dhomë.</item>
-    </plurals>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-sr/strings_sas.xml b/matrix-sdk-android/src/main/res/values-sr/strings_sas.xml
new file mode 100644
index 0000000000000000000000000000000000000000..04da7a11f0858ab8ae83ef5ec544438851e811c2
--- /dev/null
+++ b/matrix-sdk-android/src/main/res/values-sr/strings_sas.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- Generated file, do not edit -->
+    <string name="verification_emoji_dog">пас</string>
+    <string name="verification_emoji_cat">мачка</string>
+    <string name="verification_emoji_lion">лав</string>
+    <string name="verification_emoji_horse">коњ</string>
+    <string name="verification_emoji_unicorn">једнорог</string>
+    <string name="verification_emoji_pig">прасе</string>
+    <string name="verification_emoji_elephant">слон</string>
+    <string name="verification_emoji_rabbit">зец</string>
+    <string name="verification_emoji_panda">панда</string>
+    <string name="verification_emoji_rooster">петао</string>
+    <string name="verification_emoji_penguin">пингвин</string>
+    <string name="verification_emoji_turtle">корњача</string>
+    <string name="verification_emoji_fish">риба</string>
+    <string name="verification_emoji_octopus">октопод</string>
+    <string name="verification_emoji_butterfly">лептир</string>
+    <string name="verification_emoji_flower">цвет</string>
+    <string name="verification_emoji_tree">дрво</string>
+    <string name="verification_emoji_cactus">кактус</string>
+    <string name="verification_emoji_mushroom">печурка</string>
+    <string name="verification_emoji_globe">глобус</string>
+    <string name="verification_emoji_moon">месец</string>
+    <string name="verification_emoji_cloud">облак</string>
+    <string name="verification_emoji_fire">ватра</string>
+    <string name="verification_emoji_banana">банана</string>
+    <string name="verification_emoji_apple">јабука</string>
+    <string name="verification_emoji_strawberry">јагода</string>
+    <string name="verification_emoji_corn">кукуруз</string>
+    <string name="verification_emoji_pizza">пица</string>
+    <string name="verification_emoji_cake">торта</string>
+    <string name="verification_emoji_heart">срце</string>
+    <string name="verification_emoji_smiley">смајли</string>
+    <string name="verification_emoji_robot">робот</string>
+    <string name="verification_emoji_hat">шешир</string>
+    <string name="verification_emoji_glasses">наочаре</string>
+    <string name="verification_emoji_spanner">кључ</string>
+    <string name="verification_emoji_santa">деда Мраз</string>
+    <string name="verification_emoji_thumbs_up">палчић горе</string>
+    <string name="verification_emoji_umbrella">кишобран</string>
+    <string name="verification_emoji_hourglass">пешчаник</string>
+    <string name="verification_emoji_clock">сат</string>
+    <string name="verification_emoji_gift">поклон</string>
+    <string name="verification_emoji_light_bulb">сијалица</string>
+    <string name="verification_emoji_book">књига</string>
+    <string name="verification_emoji_pencil">оловка</string>
+    <string name="verification_emoji_paperclip">спајалица</string>
+    <string name="verification_emoji_scissors">маказе</string>
+    <string name="verification_emoji_lock">катанац</string>
+    <string name="verification_emoji_key">кључ</string>
+    <string name="verification_emoji_hammer">чекић</string>
+    <string name="verification_emoji_telephone">телефон</string>
+    <string name="verification_emoji_flag">застава</string>
+    <string name="verification_emoji_train">воз</string>
+    <string name="verification_emoji_bicycle">бицикл</string>
+    <string name="verification_emoji_aeroplane">авион</string>
+    <string name="verification_emoji_rocket">ракета</string>
+    <string name="verification_emoji_trophy">пехар</string>
+    <string name="verification_emoji_ball">лопта</string>
+    <string name="verification_emoji_guitar">гитара</string>
+    <string name="verification_emoji_trumpet">труба</string>
+    <string name="verification_emoji_bell">звоно</string>
+    <string name="verification_emoji_anchor">сидро</string>
+    <string name="verification_emoji_headphones">слушалице</string>
+    <string name="verification_emoji_folder">фасцикла</string>
+    <string name="verification_emoji_pin">чиода</string>
+</resources>
diff --git a/matrix-sdk-android/src/main/res/values-sv/strings.xml b/matrix-sdk-android/src/main/res/values-sv/strings.xml
deleted file mode 100644
index 91d874591f5e033d41c115c3799798ccd0f48e97..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-sv/strings.xml
+++ /dev/null
@@ -1,261 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s skickade en bild.</string>
-    <string name="summary_you_sent_image">Du skickade en bild.</string>
-    <string name="summary_user_sent_sticker">%1$s skickade en dekal.</string>
-    <string name="summary_you_sent_sticker">Du skickade en dekal.</string>
-    <string name="notice_room_invite_no_invitee">Inbjudan från %s</string>
-    <string name="notice_room_invite_no_invitee_by_you">Inbjudan från dig</string>
-    <string name="notice_room_created">%1$s skapade rummet</string>
-    <string name="notice_room_created_by_you">Du skapade rummet</string>
-    <string name="notice_room_invite">%1$s bjöd in %2$s</string>
-    <string name="notice_room_invite_by_you">Du bjöd in %1$s</string>
-    <string name="notice_room_invite_you">%1$s bjöd in dig</string>
-    <string name="notice_room_join">%1$s gick med i rummet</string>
-    <string name="notice_room_join_by_you">Du gick med i rummet</string>
-    <string name="notice_room_leave">%1$s lämnade rummet</string>
-    <string name="notice_room_leave_by_you">Du lämnade rummet</string>
-    <string name="notice_room_reject">%1$s avböjde inbjudan</string>
-    <string name="notice_room_reject_by_you">Du avböjde inbjudan</string>
-    <string name="notice_room_kick">%1$s kickade %2$s</string>
-    <string name="notice_room_kick_by_you">Du kickade %1$s</string>
-    <string name="notice_room_unban">%1$s avbannade %2$s</string>
-    <string name="notice_room_unban_by_you">Du avbannade %1$s</string>
-    <string name="notice_room_ban">%1$s avbannade %2$s</string>
-    <string name="notice_room_ban_by_you">Du bannade %1$s</string>
-    <string name="notice_room_withdraw">%1$s drog tillbaka inbjudan för %2$s</string>
-    <string name="notice_room_withdraw_by_you">Du drog tillbaka inbjudan för %1$s</string>
-    <string name="notice_avatar_url_changed">%1$s bytte sin avatar</string>
-    <string name="notice_avatar_url_changed_by_you">Du bytte din avatar</string>
-    <string name="notice_display_name_set">%1$s satte sitt visningsnamn till %2$s</string>
-    <string name="notice_display_name_set_by_you">Du satte ditt visningsnamn till %1$s</string>
-    <string name="notice_display_name_changed_from">%1$s bytte sitt visningsnamn från %2$s till %3$s</string>
-    <string name="notice_display_name_changed_from_by_you">Du bytte ditt visningsnamn från %1$s till %2$s</string>
-    <string name="notice_display_name_removed">%1$s tog bort sitt visningsnamn (det var %2$s)</string>
-    <string name="notice_display_name_removed_by_you">Du tog bort ditt visningsnamn (det var %1$s)</string>
-    <string name="notice_room_topic_changed">%1$s bytte ämnet till: %2$s</string>
-    <string name="notice_room_topic_changed_by_you">Du bytte ämnet till: %1$s</string>
-    <string name="notice_room_avatar_changed">%1$s bytte rummets avatar</string>
-    <string name="notice_room_avatar_changed_by_you">Du bytte rummets avatar</string>
-    <string name="notice_room_name_changed">%1$s bytte rummets namn till: %2$s</string>
-    <string name="notice_room_name_changed_by_you">Du bytte rummets namnet till: %1$s</string>
-    <string name="notice_placed_video_call">%s startade ett videosamtal.</string>
-    <string name="notice_placed_video_call_by_you">Du startade ett videosamtal.</string>
-    <string name="notice_placed_voice_call">%s startade ett röstsamtal.</string>
-    <string name="notice_placed_voice_call_by_you">Du startade ett röstsamtal.</string>
-    <string name="notice_call_candidates">%s skickade data för att sätta upp samtalet.</string>
-    <string name="notice_call_candidates_by_you">Du skickade data för att sätta upp samtalet.</string>
-    <string name="notice_answered_call">%s svarade på samtalet.</string>
-    <string name="notice_answered_call_by_you">Du svarade på samtalet.</string>
-    <string name="notice_ended_call">%s avslutade samtalet.</string>
-    <string name="notice_ended_call_by_you">Du avslutade samtalet.</string>
-    <string name="notice_made_future_room_visibility">%1$s gjorde framtida rumshistorik synlig för %2$s</string>
-    <string name="notice_made_future_room_visibility_by_you">Du gjorde framtida rumshistorik synlig för %1$s</string>
-    <string name="notice_room_visibility_invited">alla rumsmedlemmar, från tiden de bjöds in.</string>
-    <string name="notice_room_visibility_joined">alla rumsmedlemmar, från tiden de gick med.</string>
-    <string name="notice_room_visibility_shared">alla rumsmedlemmar.</string>
-    <string name="notice_room_visibility_world_readable">vem som helst.</string>
-    <string name="notice_room_visibility_unknown">okänt (%s).</string>
-    <string name="notice_end_to_end">%1$s aktiverade totalsträckskryptering (%2$s)</string>
-    <string name="notice_end_to_end_by_you">Du aktiverade totalsträckskryptering (%1$s)</string>
-    <string name="notice_room_update">%s uppgraderade det här rummet.</string>
-    <string name="notice_room_update_by_you">Du uppgraderade det här rummet.</string>
-    <string name="notice_requested_voip_conference">%1$s begärde ett VoIP-gruppsamtal</string>
-    <string name="notice_requested_voip_conference_by_you">Du begärde ett VoIP-gruppsamtal</string>
-    <string name="notice_voip_started">VoIP-gruppsamtal startat</string>
-    <string name="notice_voip_finished">VoIP-gruppsamtal avslutat</string>
-    <string name="notice_avatar_changed_too">(avataren blev även bytt)</string>
-    <string name="notice_room_name_removed">%1$s tog bort rummets namn</string>
-    <string name="notice_room_name_removed_by_you">Du tog bort rummets namn</string>
-    <string name="notice_room_topic_removed">%1$s tog bort rummets ämne</string>
-    <string name="notice_room_topic_removed_by_you">Du tog bort rummets ämne</string>
-    <string name="notice_room_avatar_removed">%1$s tog bort rummets avatar</string>
-    <string name="notice_room_avatar_removed_by_you">Du tog bort rummets avatar</string>
-    <string name="notice_event_redacted">Meddelande borttaget</string>
-    <string name="notice_event_redacted_by">Meddelande borttaget av %1$s</string>
-    <string name="notice_event_redacted_with_reason">Meddelande borttaget [anledning: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Meddelande borttaget av %1$s [anledning: %2$s]</string>
-    <string name="notice_profile_change_redacted">%1$s uppdaterade sim profil %2$s</string>
-    <string name="notice_profile_change_redacted_by_you">Du uppdaterade din profil %1$s</string>
-    <string name="notice_room_third_party_invite">%1$s bjöd in %2$s att gå med i rummet</string>
-    <string name="notice_room_third_party_invite_by_you">Du bjöd in %1$s att gå med i rummet</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s drog tillbaka inbjudan för %2$s att gå med i rummet</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">Du drog tillbaka inbjudan för %1$s att gå med i rummet</string>
-    <string name="notice_room_third_party_registered_invite">%1$s accepterade inbjudan för %2$s</string>
-    <string name="notice_room_third_party_registered_invite_by_you">Du accepterade inbjudan för %1$s</string>
-    <string name="notice_widget_added">%1$s lade till %2$s-widget</string>
-    <string name="notice_widget_added_by_you">Du lade till %1$s-widget</string>
-    <string name="notice_widget_removed">%1$s tog bort %2$s-widget</string>
-    <string name="notice_widget_removed_by_you">Du tog bort %1$s-widget</string>
-    <string name="notice_widget_modified">%1$s modifierade %2$s-widget</string>
-    <string name="notice_widget_modified_by_you">Du modifierade %1$s-widget</string>
-    <string name="power_level_admin">Admin</string>
-    <string name="power_level_moderator">Moderator</string>
-    <string name="power_level_default">Standard</string>
-    <string name="power_level_custom">Anpassad (%1$d)</string>
-    <string name="power_level_custom_no_value">Anpassad</string>
-    <string name="notice_power_level_changed_by_you">Du ändrade behörighetsnivå för %1$s.</string>
-    <string name="notice_power_level_changed">%1$s ändrade behörighetsnivå för %2$s.</string>
-    <string name="notice_power_level_diff">%1$s från %2$s till %3$s</string>
-    <string name="notice_crypto_unable_to_decrypt">** Kan inte avkryptera: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Avsändarens enhet har inte gett oss nycklarna för det här meddelandet.</string>
-    <string name="could_not_redact">Kunde inte dölja</string>
-    <string name="unable_to_send_message">Kunde inte skicka meddelandet</string>
-    <string name="message_failed_to_upload">Misslyckades att ladda upp bilden</string>
-    <string name="network_error">Nätverksfel</string>
-    <string name="matrix_error">Matrixfel</string>
-    <string name="room_error_join_failed_empty_room">Det går för närvarande inte att gå med i ett tomt rum igen.</string>
-    <string name="encrypted_message">Krypterat meddelande</string>
-    <string name="medium_email">E-postadress</string>
-    <string name="medium_phone_number">Telefonnummer</string>
-    <string name="room_displayname_invite_from">Inbjudan från %s</string>
-    <string name="room_displayname_room_invite">Rumsinbjudan</string>
-    <string name="room_displayname_two_members">%1$s och %2$s</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s och en till</item>
-        <item quantity="other">%1$s och %2$d till</item>
-    </plurals>
-    <string name="room_displayname_empty_room">Tomt rum</string>
-    <string name="initial_sync_start_importing_account">Inledande synk:
-\nImporterar konto…</string>
-    <string name="initial_sync_start_importing_account_crypto">Inledande synk:
-\nImporterar krypto</string>
-    <string name="initial_sync_start_importing_account_rooms">Inledande synk:
-\nImporterar rum</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Inledande synk:
-\nImporterar anslutna rum</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Inledande synk:
-\nImporterar inbjudna rum</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Inledande synk:
-\nImporterar lämnade rum</string>
-    <string name="initial_sync_start_importing_account_groups">Inledande synk:
-\nImporterar gemenskaper</string>
-    <string name="initial_sync_start_importing_account_data">Inledande synk:
-\nImporterar kontodata</string>
-    <string name="event_status_sending_message">Skickar meddelande…</string>
-    <string name="clear_timeline_send_queue">Rensa sändningskö</string>
-    <string name="notice_room_invite_no_invitee_with_reason">Inbjudan från %1$s. Anledning: %2$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">Inbjudan från dig. Anledning: %1$s</string>
-    <string name="notice_room_invite_with_reason">%1$s bjöd in %2$s. Anledning: %3$s</string>
-    <string name="notice_room_invite_with_reason_by_you">Du bjöd in %1$s. Anledning: %2$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s bjöd in dig. Anledning: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s gick med i rummet. Anledning: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">Du gick med i rummet. Anledning: %1$s</string>
-    <string name="notice_room_leave_with_reason">%1$s lämnade rummet. Anledning: %2$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Du lämnade rummet. Anledning: %1$s</string>
-    <string name="notice_room_reject_with_reason">%1$s avböjde inbjudan. Anledning: %2$s</string>
-    <string name="notice_room_reject_with_reason_by_you">Du avböjde inbjudan. Anledning: %1$s</string>
-    <string name="notice_room_kick_with_reason">%1$s kickade %2$s. Anledning: %3$s</string>
-    <string name="notice_room_kick_with_reason_by_you">Du kickade %1$s. Anledning: %2$s</string>
-    <string name="notice_room_unban_with_reason">%1$s avbannade %2$s. Anledning: %3$s</string>
-    <string name="notice_room_unban_with_reason_by_you">Du avbannade %1$s. Anledning: %2$s</string>
-    <string name="notice_room_ban_with_reason">%1$s bannade %2$s. Anledning: %3$s</string>
-    <string name="notice_room_ban_with_reason_by_you">Du bannade %1$s. Anledning: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s bjöd in %2$s att gå med i rummet. Anledning: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">Du bjöd in %1$s att gå med i rummet. Anledning: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s drog tillbaka inbjudan för %2$s att gå med i rummet. Anledning: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">Du drog tillbaka inbjudan för %1$s att gå med i rummet. Anledning: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s accepterade inbjudan för %2$s. Anledning: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">Du accepterade inbjudan för %1$s. Anledning: %2$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s drog tillbaka inbjudan för %2$s. Anledning: %3$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">Du drog tillbaka inbjudan för %1$s. Anledning: %2$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s lade till %2$s som en adress för det här rummet.</item>
-        <item quantity="other">%1$s lade till %2$s som adresser för det här rummet.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">Du lade till %1$s som en adress för det här rummet.</item>
-        <item quantity="other">Du lade till %1$s som adresser för det här rummet.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s tog bort %2$s som en adress för det här rummet.</item>
-        <item quantity="other">%1$s tog bort %2$s som adresser för det här rummet.</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">Du tog bort %1$s som en adress för det här rummet.</item>
-        <item quantity="other">Du tog bort %1$s som adresser för det här rummet.</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s lade till %2$s och tog bort %3$s som adresser för det här rummet.</string>
-    <string name="notice_room_aliases_added_and_removed_by_you">Du lade till %1$s och tog bort %2$s som adresser för det här rummet.</string>
-    <string name="notice_room_canonical_alias_set">%1$s satta huvudadressen för det här rummet till %2$s.</string>
-    <string name="notice_room_canonical_alias_set_by_you">Du satta huvudadressen för det här rummet till %1$s.</string>
-    <string name="notice_room_canonical_alias_unset">%1$s tog bort huvudadressen för det här rummet.</string>
-    <string name="notice_room_canonical_alias_unset_by_you">Du tog bort huvudadressen för det här rummet.</string>
-    <string name="notice_room_guest_access_can_join">%1$s tillät gäster att gå med i rummet.</string>
-    <string name="notice_room_guest_access_can_join_by_you">Du tillät gäster att gå med i rummet.</string>
-    <string name="notice_room_guest_access_forbidden">%1$s hindrade gäster från att gå med i rummet.</string>
-    <string name="notice_room_guest_access_forbidden_by_you">Du hindrade gäster från att gå med i rummet.</string>
-    <string name="notice_end_to_end_ok">%1$s aktiverade totalsträckskryptering.</string>
-    <string name="notice_end_to_end_ok_by_you">Du aktiverade totalsträckskryptering.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s aktiverade totalsträckskryptering (okänd algoritm %2$s).</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">Du aktiverade totalsträckskryptering (okänd algoritm %1$s).</string>
-    <string name="key_verification_request_fallback_message">%s begär att verifiera din nyckel, men din klient stöder inte nyckelverifiering i chatten. Du behöver använda legacynyckelverifiering för att verifiera nycklar.</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">Du hindrade gäster från att gå med i rummet.</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s hindrade gäster från att gå med i rummet.</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">Du tillät gäster att gå med här.</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s tillät gäster att gå med här.</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">Du lämnade. Anledning: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s Lämnade. Anledning: %2$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">Du gick med. Anledning: %1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s gick med. Anledning: %2$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">Du drog tillbaka inbjudan för %1$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s drog tillbaka inbjudan för %2$s</string>
-    <string name="notice_direct_room_third_party_invite_by_you">Du bjöd in %1$s</string>
-    <string name="notice_direct_room_third_party_invite">%1$s bjöd in %2$s</string>
-    <string name="notice_direct_room_update_by_you">Du uppgraderade här.</string>
-    <string name="notice_direct_room_update">%s uppgraderade här.</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">Du gjorde framtida meddelanden synliga för %1$s</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s gjorde framtida meddelanden synliga för %2$s</string>
-    <string name="notice_direct_room_leave_by_you">Du lämnade rummet</string>
-    <string name="notice_direct_room_leave">%1$s lämnade rummet</string>
-    <string name="notice_direct_room_join_by_you">Du gick med</string>
-    <string name="notice_direct_room_join">%1$s gick med</string>
-    <string name="notice_direct_room_created_by_you">Du skapade diskussionen</string>
-    <string name="notice_direct_room_created">%1$s skapade diskussionen</string>
-    <string name="notice_room_canonical_alias_no_change_by_you">Du ändrade adresserna för det här rummet.</string>
-    <string name="notice_room_canonical_alias_no_change">%1$s ändrade adresserna för det här rummet.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed_by_you">Du ändrade huvudadressen och de alternativa adresserna för det här rummet.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed">%1$s ändrade huvudadressen och de alternativa adresserna för det här rummet.</string>
-    <string name="notice_room_canonical_alias_alternative_changed_by_you">Du ändrade de alternativa adresserna för det här rummet.</string>
-    <string name="notice_room_canonical_alias_alternative_changed">%1$s ändrade de alternativa adresserna för det här rummet.</string>
-    <plurals name="notice_room_canonical_alias_alternative_removed_by_you">
-        <item quantity="one">Du tog bort den alternativa adressen %1$s för det här rummet.</item>
-        <item quantity="other">Du tog bort de alternativa adresserna %1$s för det här rummet.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_removed">
-        <item quantity="one">%1$s tog bort den alternativa adressen %2$s för det här rummet.</item>
-        <item quantity="other">%1$s tog bort de alternativa adresserna %2$s för det här rummet.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added_by_you">
-        <item quantity="one">Du lade till den alternativa adressen %1$s för det här rummet.</item>
-        <item quantity="other">Du lade till de alternativa adresserna %1$s för det här rummet.</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added">
-        <item quantity="one">%1$s lade till den alternativa adressen %2$s för det här rummet.</item>
-        <item quantity="other">%1$s lade till de alternativa adresserna %2$s för det här rummet.</item>
-    </plurals>
-    <string name="room_displayname_empty_room_was">Tomt rum (var %s)</string>
-    <plurals name="room_displayname_four_and_more_members">
-        <item quantity="one">%1$s, %2$s, %3$s och %4$d till</item>
-        <item quantity="other">%1$s, %2$s, %3$s och %4$d till</item>
-    </plurals>
-    <string name="room_displayname_4_members">%1$s, %2$s, %3$s och %4$s</string>
-    <string name="room_displayname_3_members">%1$s, %2$s och %3$s</string>
-    <string name="notice_room_server_acl_allow_is_empty">🎉 Alla servrar har bannats från att delta! Det här rummet kan inte användas längre.</string>
-    <string name="notice_room_server_acl_updated_no_change">Ingen ändring.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_not_allowed">• Servrar som matchar IP-adresser är nu bannade.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_allowed">• Servrar som matchar IP-adresser är nu tillåtna.</string>
-    <string name="notice_room_server_acl_updated_was_allowed">• Servrar som matchar %s togs bort från tillåtelselistan.</string>
-    <string name="notice_room_server_acl_updated_allowed">• Servrar som matchar %s är nu tillåtna.</string>
-    <string name="notice_room_server_acl_updated_was_banned">• Servrar som matchar %s togs bort från bannlistan.</string>
-    <string name="notice_room_server_acl_updated_banned">• Servrar som matchar %s är nu bannade.</string>
-    <string name="notice_room_server_acl_updated_title_by_you">Du ändrade server-ACLer för det här rummet.</string>
-    <string name="notice_room_server_acl_updated_title">%s ändrade server-ACLer för det här rummet.</string>
-    <string name="notice_room_server_acl_set_ip_literals_allowed">• Servrar som matchar IP-adresser är tillåtna.</string>
-    <string name="notice_room_server_acl_set_ip_literals_not_allowed">• Servrar som matchar IP-adresser är bannade.</string>
-    <string name="notice_room_server_acl_set_allowed">• Servrar som matchar %s är tillåtna.</string>
-    <string name="notice_room_server_acl_set_banned">• Servrar som matchar %s är bannade.</string>
-    <string name="notice_room_server_acl_set_title_by_you">Du satte server-ACLer för det här rummet.</string>
-    <string name="notice_room_server_acl_set_title">%s satte server-ACLer för det här rummet.</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-szl/strings.xml b/matrix-sdk-android/src/main/res/values-szl/strings.xml
deleted file mode 100644
index a6b3daec9354f9ae75cdf8d94a67446c6227dd96..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-szl/strings.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources></resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-szl/strings_sas.xml b/matrix-sdk-android/src/main/res/values-szl/strings_sas.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9769ad73cec0f8c98cf311662b0dae05ab375c9c
--- /dev/null
+++ b/matrix-sdk-android/src/main/res/values-szl/strings_sas.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- Generated file, do not edit -->
+</resources>
diff --git a/matrix-sdk-android/src/main/res/values-te/strings.xml b/matrix-sdk-android/src/main/res/values-te/strings.xml
deleted file mode 100644
index 62f58c9e26f4fe90b2a88e8783e065975cc6b5f0..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-te/strings.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-    <string name="notice_room_invite_no_invitee">%s\'s ఆహ్వానం</string>
-    <string name="notice_room_invite">%1$s ఆహ్వానించారు %2$s</string>
-    <string name="notice_room_leave">%1$s వదిలి వెళారు</string>
-    <string name="notice_room_reject">%1$s ఆహ్వానాన్ని తిరస్కరించారు</string>
-    <string name="notice_room_kick">%1$s తన్నాడు %2$s</string>
-    <string name="notice_room_unban">%1$s నిషేధాన్ని %2$s</string>
-    <string name="notice_room_ban">%1$s నిషేధించారు %2$s</string>
-    <string name="notice_room_withdraw">%1$s ఉపసంహరించుకుంది %2$s\'s ఆహ్వానం</string>
-    <string name="notice_avatar_url_changed">%1$s వారి అవతార్ను మార్చారు</string>
-    <string name="notice_display_name_set">%1$s వారి డిస్ప్లే పేరును ని సెట్ చేసారు %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s వారి ప్రదర్శన పేరును %2$s నుండి %3$s మార్చారు</string>
-    <string name="notice_display_name_removed">%1$s వారి ప్రదర్శన పేరుని తీసివేసారు (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s అంశం మార్చబడింది:%2$s</string>
-    <string name="notice_room_name_changed">%1$s గది పెరు మార్చబడింది %2$s</string>
-    <string name="notice_placed_video_call">%s ఒక వీడియో కాల్ని ఉంచింది.</string>
-    <string name="notice_placed_voice_call">%s వాయిస్ కాల్ని ఉంచారు.</string>
-    <string name="notice_answered_call">%s కాల్కి సమాధానం ఇచ్చారు.</string>
-    <string name="notice_ended_call">%s కాల్ ముగిసింది.</string>
-    <string name="notice_made_future_room_visibility">%1$s భవిష్యత్ గది చరిత్రను %2$s కి కనిపించేలా చేసింది</string>
-    <string name="notice_room_visibility_invited">పాయింట్నుండి, అన్ని గది సభ్యుల వారు ఆహ్వానించబడ్డారు.</string>
-    <string name="notice_room_visibility_joined">పాయింట్ నుండి, అన్ని గదుల సభ్యుల వారు చేరారు.</string>
-    <string name="notice_room_visibility_shared">అన్ని గదుల సభ్యులు.</string>
-    <string name="notice_room_visibility_world_readable">ఎవరైనా.</string>
-    <string name="notice_room_visibility_unknown">తెలియని (%s).</string>
-    <string name="notice_end_to_end">%1$s ఎండ్-టు-ఎండ్ ఎన్క్రిప్షన్ ఆన్ చెయ్యబడింది (%2$s)</string>
-
-    <string name="notice_requested_voip_conference">%1$s వి ఓ ఇ పి సమావేశాన్ని అభ్యర్థించారు</string>
-    <string name="notice_voip_started">వి ఓ ఇ పి సమావేశం ప్రారంభమైంది</string>
-    <string name="notice_voip_finished">వి ఓ ఇ పి సమావేశం ముగిసింది</string>
-
-    <string name="notice_avatar_changed_too">(అవతార్ మార్చబడింది)</string>
-    <string name="notice_room_name_removed">%1$s గది పేరు తొలగించబడింది</string>
-    <string name="notice_room_topic_removed">%1$s గది అంశాన్ని తీసివేసారు</string>
-    <string name="notice_profile_change_redacted">%1$s వారి ప్రొఫైల్ నవీకరించబడింది %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s గదిలో చేరడానికి %2$s కు ఆహ్వానాన్ని పంపారు</string>
-    <string name="notice_room_third_party_registered_invite">%2$sకోసం %1$s ఆహ్వానాన్ని అంగీకరించారు</string>
-
-    <string name="notice_crypto_unable_to_decrypt">** వ్యక్తీకరించడానికి సాధ్యం కాలేదు: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">ఈ సందేశానికి పంపేవారి పరికరం మాకు కీలను పంపలేదు.</string>
-
-    <string name="could_not_redact">గది స్క్రీన్</string>
-    <string name="unable_to_send_message">సందేశం పంపడం సాధ్యం కాలేదు</string>
-
-    <string name="message_failed_to_upload">చిత్రాన్ని అప్లోడ్ చేయడంలో విఫలమైంది</string>
-
-    <string name="network_error">సాధారణ లోపాలు</string>
-    <string name="matrix_error">మాట్రిక్స్ లోపం</string>
-
-    <string name="room_error_join_failed_empty_room">మళ్లీ ఖాళీ గది ని చేరడానికి ప్రస్తుతం ఇది సాధ్యం కాదు.</string>
-
-    <string name="encrypted_message">ఎన్క్రిప్టెడ్ సందేశం</string>
-
-    <string name="medium_email">ఇమెయిల్ చిరునామా</string>
-    <string name="medium_phone_number">ఫోను నంబరు</string>
-
-
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s ఒక చిత్రం పంపారు.</string>
-
-    <string name="notice_room_invite_you">%1$s మిమ్మల్ని ఆహ్వానించారు</string>
-    <string name="notice_room_join">%1$s చేరారు</string>
-
-    <string name="room_displayname_invite_from">%s నుండి ఆహ్వానించు</string>
-    <string name="room_displayname_two_members">%1$s మరియు %2$s</string>
-    <string name="room_displayname_room_invite">గదికి ఆహ్వానం</string>
-    <string name="room_displayname_empty_room">ఖాళీ గది</string>
-
-
-</resources>
diff --git a/matrix-sdk-android/src/main/res/values-th/strings.xml b/matrix-sdk-android/src/main/res/values-th/strings.xml
deleted file mode 100644
index 3abd948f77ebb778569ad4e7c61ddcba9c645ab4..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-th/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-</resources>
diff --git a/matrix-sdk-android/src/main/res/values-uk/strings.xml b/matrix-sdk-android/src/main/res/values-uk/strings.xml
deleted file mode 100644
index 0f45a7182ca6d16111ad3e07db35fa1197d6857e..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-uk/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s надіслав(ла) зображення.</string>
-    <string name="notice_room_invite_no_invitee">%s запрошення</string>
-    <string name="notice_room_invite">%1$s запросив(ла) %2$s</string>
-    <string name="encrypted_message">Зашифроване повідомлення</string>
-    <!-- Room display name -->
-    <string name="room_displayname_invite_from">Запрошення від %s</string>
-    <string name="room_displayname_room_invite">Запрошення до кімнати</string>
-    <string name="room_displayname_two_members">%1$s Ñ– %2$s</string>
-    <string name="room_displayname_empty_room">Порожня кімната</string>
-    <string name="summary_user_sent_sticker">%1$s надіслав(ла) наліпку.</string>
-    <string name="notice_room_invite_you">%1$s запросив(ла) Вас</string>
-    <string name="notice_room_join">%1$s приєднується</string>
-    <string name="notice_room_leave">%1$s покидає кімнату</string>
-    <string name="notice_room_reject">%1$s відхилив(ла) запрошення</string>
-    <string name="notice_room_kick">%1$s копнув(ла) %2$s</string>
-    <string name="notice_room_unban">%1$s розблокував(ла) %2$s</string>
-    <string name="notice_room_ban">%1$s заблокував(ла) %2$s</string>
-    <string name="notice_room_withdraw">%1$s відкликав(ла) запрошення для %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s змінює свій аватар</string>
-    <string name="notice_display_name_set">%1$s встановлюють собі назву %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s змінює своє ім’я з %2$s на %3$s</string>
-    <string name="notice_display_name_removed">%1$s прибрав(ла) своє ім’я (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s змінює тему на: %2$s</string>
-    <string name="notice_room_name_changed">%1$s змінив(ла) назву кімнати на: %2$s</string>
-    <string name="notice_placed_video_call">%s розпочав(ла) відеодзвінок.</string>
-    <string name="notice_placed_voice_call">%s розпочав(ла) голосовий дзвінок.</string>
-    <string name="notice_answered_call">%s відповів(ла) на дзвінок.</string>
-    <string name="notice_ended_call">%s завершує дзвінок.</string>
-    <string name="notice_made_future_room_visibility">%1$s зробив(ла) майбутню історію кімнати видимою для %2$s</string>
-    <string name="notice_room_visibility_invited">усіх співрозмовників, з моменту їх запрошення.</string>
-    <string name="notice_room_visibility_joined">усіх співрозмовників, з моменту їх приєднання.</string>
-    <string name="notice_room_visibility_shared">усіх співрозмовників.</string>
-    <string name="notice_room_visibility_world_readable">будь-кого.</string>
-    <string name="notice_room_visibility_unknown">невідомо (%s).</string>
-    <string name="notice_end_to_end">%1$s увімкнув(ла) наскрізне шифрування (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s запросив(ла) VoIP конференцію</string>
-    <string name="notice_voip_started">VoIP конференція розпочалась</string>
-    <string name="notice_voip_finished">VoIP конференція завершилась</string>
-    <string name="notice_avatar_changed_too">(аватар також змінено)</string>
-    <string name="notice_room_name_removed">%1$s прибрав(ла) назву кімнати</string>
-    <string name="notice_room_topic_removed">%1$s прибрав(ла) тему кімнати</string>
-    <string name="notice_profile_change_redacted">%1$s оновив(ла) свій профіль %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s надіслав(ла) запрошення %2$s приєднатися до кімнати</string>
-    <string name="notice_room_third_party_registered_invite">%1$s прийняв(ла) запрошення у %2$s</string>
-    <string name="notice_crypto_unable_to_decrypt">** Неможливо розшифрувати: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">Пристрій відправника не надіслав нам ключ для цього повідомлення.</string>
-    <string name="could_not_redact">Неможливо відредагувати</string>
-    <string name="unable_to_send_message">Не вдалося надіслати повідомлення</string>
-    <string name="message_failed_to_upload">Не вдалося завантажити зображення</string>
-    <string name="network_error">Помилка мережі</string>
-    <string name="matrix_error">Помилка Matrix</string>
-    <string name="room_error_join_failed_empty_room">Наразі неможливо переприєднатися до порожньої кімнати.</string>
-    <string name="medium_email">Адреса електронної пошти</string>
-    <string name="medium_phone_number">Номер телефону</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s та 1 інший</item>
-        <item quantity="few">%1$s та %2$d інші</item>
-        <item quantity="many">%1$s та %2$d інших</item>
-        <item quantity="other"/>
-    </plurals>
-    <string name="notice_room_update">%s вдосконалили цю кімнату.</string>
-    <string name="notice_event_redacted">Повідомлення видалено</string>
-    <string name="notice_event_redacted_by">%1$s видалили повідомлення</string>
-    <string name="notice_event_redacted_with_reason">Повідомлення видалено [причина: %1$s]</string>
-    <string name="initial_sync_start_importing_account_data">Початкове налаштування:
-\nІмпортування даних облікового запису</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">Ви покинули. Причина: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s покидає. Причина: %2$s</string>
-    <string name="notice_room_leave_with_reason_by_you">Ви покинули кімнату. Причина: %1$s</string>
-    <string name="notice_room_leave_with_reason">%1$s покидає кімнату. Причина: %2$s</string>
-    <string name="notice_direct_room_leave">%1$s покидає кімнату</string>
-    <string name="notice_direct_room_leave_by_you">Ви покинули кімнату</string>
-    <string name="notice_room_leave_by_you">Ви покинули кімнату</string>
-    <string name="notice_room_canonical_alias_no_change_by_you">Ви змінили адреси цієї кімнати.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed_by_you">Ви змінили основну та альтернативну адреси цієї кімнати.</string>
-    <string name="notice_room_canonical_alias_alternative_changed_by_you">Ви змінили альтернативні адреси для цієї кімнати.</string>
-    <string name="notice_power_level_changed_by_you">Ви змінили рівень доступу на %1$s.</string>
-    <string name="notice_room_server_acl_updated_title_by_you">Ви змінили серверні списки контролю доступу для цієї кімнати.</string>
-    <string name="notice_room_name_changed_by_you">Ви змінили назву кімнати на: %1$s</string>
-    <string name="notice_room_avatar_changed_by_you">Ви змінили світлину кімнати</string>
-    <string name="notice_room_topic_changed_by_you">Ви змінили тему на: %1$s</string>
-    <string name="notice_display_name_changed_from_by_you">Ви змінили показуване ім\'я з %1$s на %2$s</string>
-    <string name="notice_avatar_url_changed_by_you">Ви змінили світлину профілю</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-vls/strings.xml b/matrix-sdk-android/src/main/res/values-vls/strings.xml
deleted file mode 100644
index f0f2287a8d7f3cf44cfa6a55d435adf9d4f8f597..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-vls/strings.xml
+++ /dev/null
@@ -1,103 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s èt e fotootje gesteurd.</string>
-    <string name="summary_user_sent_sticker">%1$s èt e sticker gesteurd.</string>
-
-    <string name="notice_room_invite_no_invitee">Uutnodigienge van %s</string>
-    <string name="notice_room_invite">%1$s èt %2$s uutgenodigd</string>
-    <string name="notice_room_invite_you">%1$s èt joun uitgenodigd</string>
-    <string name="notice_room_join">%1$s neemt nu deel an ’t gesprek</string>
-    <string name="notice_room_leave">%1$s èt ’t gesprek verloatn</string>
-    <string name="notice_room_reject">%1$s èt d’uitnodigienge geweigerd</string>
-    <string name="notice_room_kick">%1$s èt %2$s uut ’t gesprek verwyderd</string>
-    <string name="notice_room_unban">%1$s èt %2$s ountbann</string>
-    <string name="notice_room_ban">%1$s èt %2$s verbann</string>
-    <string name="notice_room_withdraw">%1$s èt d’uutnodigienge van %2$s ingetrokkn</string>
-    <string name="notice_avatar_url_changed">%1$s èt zyn/heur avatar angepast</string>
-    <string name="notice_display_name_set">%1$s èt zyn/heur noame angepast noa %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s èt zyn/heur noame angepast van %2$s noa %3$s</string>
-    <string name="notice_display_name_removed">%1$s èt zyn/heur noame verwyderd (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s èt ’t ounderwerp veranderd noa: %2$s</string>
-    <string name="notice_room_name_changed">%1$s èt de gespreksnoame veranderd noa: %2$s</string>
-    <string name="notice_placed_video_call">%s èt e video-iproep gemakt.</string>
-    <string name="notice_placed_voice_call">%s èt e sproakiproep gemakt.</string>
-    <string name="notice_answered_call">%s èt den iproep beantwoord.</string>
-    <string name="notice_ended_call">%s èt ipgehangn.</string>
-    <string name="notice_made_future_room_visibility">%1$s èt de toekomstige gespreksgeschiedenisse zichtboar gemakt vo %2$s</string>
-    <string name="notice_room_visibility_invited">alle deelnemers an ’t gesprek, vanaf ’t punt dan ze zyn uutgenodigd.</string>
-    <string name="notice_room_visibility_joined">alle deelnemers an ’t gesprek, vanaf ’t punt dan ze zyn toegetreedn.</string>
-    <string name="notice_room_visibility_shared">alle deelnemers an ’t gesprek.</string>
-    <string name="notice_room_visibility_world_readable">iedereen.</string>
-    <string name="notice_room_visibility_unknown">ounbekend (%s).</string>
-    <string name="notice_end_to_end">%1$s èt eind-tout-eind-versleutelienge angezet (%2$s)</string>
-
-    <string name="notice_requested_voip_conference">%1$s èt e VoIP-vergoaderienge angevroagd</string>
-    <string name="notice_voip_started">VoIP-vergoaderienge begunn</string>
-    <string name="notice_voip_finished">VoIP-vergoaderienge gestopt</string>
-
-    <string name="notice_avatar_changed_too">(avatar es ook veranderd)</string>
-    <string name="notice_room_name_removed">%1$s èt de gespreksnoame verwyderd</string>
-    <string name="notice_room_topic_removed">%1$s èt ’t gespreksounderwerp verwyderd</string>
-    <string name="notice_event_redacted">Bericht verwyderd</string>
-    <string name="notice_event_redacted_by">Bericht verwyderd deur %1$s</string>
-    <string name="notice_event_redacted_with_reason">Bericht verwyderd [reden: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Bericht verwyderd deur %1$s [reden: %2$s]</string>
-    <string name="notice_profile_change_redacted">%1$s èt zyn/heur profiel %2$s bygewerkt</string>
-    <string name="notice_room_third_party_invite">%1$s èt een uutnodigienge noa %2$s gesteurd vo ’t gesprek toe te treedn</string>
-    <string name="notice_room_third_party_registered_invite">%1$s èt d’uutnodigienge vo %2$s anveird</string>
-
-    <string name="notice_crypto_unable_to_decrypt">** Kun nie ountsleuteln: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">’t Toestel van den afzender èt geen sleutels vo da bericht hier gesteurd.</string>
-
-    <string name="could_not_redact">Kosteg nie verwyderd wordn</string>
-    <string name="unable_to_send_message">Kosteg ’t bericht nie verzendn</string>
-
-    <string name="message_failed_to_upload">Iploadn van ’t fotootje es mislukt</string>
-
-    <string name="network_error">Netwerkfout</string>
-    <string name="matrix_error">Matrix-fout</string>
-
-    <string name="room_error_join_failed_empty_room">’t Es vo de moment nie meuglik van e leeg gesprek were toe te treedn.</string>
-
-    <string name="encrypted_message">Versleuteld bericht</string>
-
-    <string name="medium_email">E-mailadresse</string>
-    <string name="medium_phone_number">Telefongnumero</string>
-
-    <string name="room_displayname_invite_from">Uutnodigienge van %s</string>
-    <string name="room_displayname_room_invite">Gespreksuutnodigienge</string>
-
-    <string name="room_displayname_two_members">%1$s en %2$s</string>
-
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s en 1 andere</item>
-        <item quantity="other">%1$s en %2$d anderen</item>
-    </plurals>
-
-    <string name="room_displayname_empty_room">Leeg gesprek</string>
-
-    <string name="initial_sync_start_importing_account">Initiële synchronisoasje:
-\nAccount wor geïmporteerd…</string>
-    <string name="initial_sync_start_importing_account_crypto">Initiële synchronisoasje: 
-\nCrypto wor geïmporteerd</string>
-    <string name="initial_sync_start_importing_account_rooms">Initiële synchronisoasje: 
-\nGesprekkn wordn geïmporteerd</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Initiële synchronisoasje: 
-\nDeelgenoomn gesprekken wordn geïmporteerd</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Initiële synchronisoasje: 
-\nUutgenodigde gesprekkn wordn geïmporteerd</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Initiële synchronisoasje: 
-\nVerloatn gesprekkn wordn geïmporteerd</string>
-    <string name="initial_sync_start_importing_account_groups">Initiële synchronisoasje: 
-\nGemeenschappn wordn geïmporteerd</string>
-    <string name="initial_sync_start_importing_account_data">Initiële synchronisoasje: 
-\nAccountgegeevns wordn geïmporteerd</string>
-
-    <string name="notice_room_update">%s èt da gesprek hier ipgewoardeerd.</string>
-
-    <string name="event_status_sending_message">Bericht wor verstuurd…</string>
-    <string name="clear_timeline_send_queue">Uutgoande wachtreeke leegn</string>
-
-    <string name="notice_room_third_party_revoked_invite">%1$s èt d’uutnodigienge vo %2$s vo ’t gesprek toe te treedn ingetrokkn</string>
-</resources>
diff --git a/matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml b/matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 5c5da36c2696a2528fe2fc5f92ac270d1e34f5b3..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,211 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_user_sent_image">%1$s 发送了一张图片。</string>
-    <string name="notice_room_invite_no_invitee">%s 的邀请</string>
-    <string name="notice_room_invite">%1$s 邀请了 %2$s</string>
-    <string name="notice_room_invite_you">%1$s 邀请了您</string>
-    <string name="notice_room_join">%1$s 加入了聊天室</string>
-    <string name="notice_room_leave">%1$s 离开了聊天室</string>
-    <string name="notice_room_reject">%1$s 拒绝了邀请</string>
-    <string name="notice_room_kick">%1$s 移除了 %2$s</string>
-    <string name="notice_room_unban">%1$s 解封了 %2$s</string>
-    <string name="notice_room_ban">%1$s 封禁了 %2$s</string>
-    <string name="notice_avatar_url_changed">%1$s 更换了他们的头像</string>
-    <string name="notice_display_name_set">%1$s 将他们的昵称设置为 %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s 把他们的昵称从 %2$s 改为 %3$s</string>
-    <string name="notice_display_name_removed">%1$s 移除了他们的昵称 (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s 把主题改为: %2$s</string>
-    <string name="notice_room_name_changed">%1$s 把聊天室名称改为: %2$s</string>
-    <string name="notice_placed_video_call">%s 发起了一次视频通话。</string>
-    <string name="notice_placed_voice_call">%s 发起了一次语音通话。</string>
-    <string name="notice_answered_call">%s 已接听通话。</string>
-    <string name="notice_ended_call">%s 已结束通话。</string>
-    <string name="notice_room_visibility_invited">所有聊天室成员,从他们被邀请开始。</string>
-    <string name="notice_room_visibility_joined">所有聊天室成员,从他们加入开始。</string>
-    <string name="notice_room_visibility_shared">所有聊天室成员。</string>
-    <string name="notice_room_visibility_world_readable">任何人。</string>
-    <string name="notice_room_visibility_unknown">未知(%s)。</string>
-    <string name="notice_end_to_end">%1$s 开启了端到端加密(%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s 请求了一次 VoIP 会议</string>
-    <string name="notice_voip_started">VoIP 会议已开始</string>
-    <string name="notice_voip_finished">VoIP 会议已结束</string>
-    <string name="notice_avatar_changed_too">(头像也被更改)</string>
-    <string name="notice_room_name_removed">%1$s 移除了聊天室名称</string>
-    <string name="notice_room_topic_removed">%1$s 移除了聊天室主题</string>
-    <string name="notice_crypto_unable_to_decrypt">** 无法解密:%s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">发送者的设备没有向我们发送此消息的密钥。</string>
-    <string name="unable_to_send_message">无法发送消息</string>
-    <string name="message_failed_to_upload">上传图像失败</string>
-    <string name="network_error">网络错误</string>
-    <string name="matrix_error">Matrix 错误</string>
-    <string name="room_error_join_failed_empty_room">目前无法重新加入一个空的聊天室。</string>
-    <string name="encrypted_message">已加密消息</string>
-    <string name="medium_email">电子邮箱地址</string>
-    <string name="medium_phone_number">手机号码</string>
-    <string name="notice_room_withdraw">%1$s 撤回了对 %2$s 的邀请</string>
-    <string name="notice_made_future_room_visibility">%1$s 让未来的聊天室历史记录对 %2$s 可见</string>
-    <string name="notice_profile_change_redacted">%1$s 更新了他的个人档案 %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s 向 %2$s 发送了加入聊天室的邀请</string>
-    <string name="notice_room_third_party_registered_invite">%1$s 接受了 %2$s 的邀请</string>
-    <string name="could_not_redact">无法撤回</string>
-    <string name="summary_message">%1$s:%2$s</string>
-    <string name="summary_user_sent_sticker">%1$s 发送了一张贴纸。</string>
-    <string name="room_displayname_empty_room">空聊天室</string>
-    <string name="room_displayname_invite_from">来自 %s 的邀请</string>
-    <string name="room_displayname_room_invite">聊天室邀请</string>
-    <string name="room_displayname_two_members">%1$s 和 %2$s</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="other">%1$s 与其他 %2$d 位</item>
-    </plurals>
-    <string name="notice_event_redacted">消息已被移除</string>
-    <string name="notice_event_redacted_by">消息已被 %1$s 移除</string>
-    <string name="notice_event_redacted_with_reason">消息已被移除 [原因: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">消息已被 %1$s 移除 [原因: %2$s]</string>
-    <string name="initial_sync_start_importing_account">初始化同步:
-\n正在导入账号…</string>
-    <string name="initial_sync_start_importing_account_crypto">初始化同步:
-\n正在导入加密数据</string>
-    <string name="initial_sync_start_importing_account_rooms">初始化同步:
-\n正在导入聊天室</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">初始化同步:
-\n正在导入已加入的聊天室</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">初始化同步:
-\n正在导入已邀请的聊天室</string>
-    <string name="initial_sync_start_importing_account_left_rooms">初始化同步:
-\n正在导入已离开的聊天室</string>
-    <string name="initial_sync_start_importing_account_groups">初始化同步:
-\n正在导入社区</string>
-    <string name="initial_sync_start_importing_account_data">初始化同步:
-\n正在导入账号数据</string>
-    <string name="notice_room_update">%s 升级了此聊天室。</string>
-    <string name="event_status_sending_message">正在发送消息…</string>
-    <string name="clear_timeline_send_queue">清除正在发送队列</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s 撤回了对 %2$s 加入聊天室的邀请</string>
-    <string name="notice_room_invite_no_invitee_with_reason">%1$s 的邀请。理由:%2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s 邀请了 %2$s。理由:%3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s 邀请了您。理由:%2$s</string>
-    <string name="notice_room_join_with_reason">%1$s 加入了聊天室。理由:%2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s 离开了聊天室。理由:%2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s 已拒绝邀请。理由:%2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s 踢走了 %2$s。理由:%3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s 解封了 %2$s。理由:%3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s 封禁了 %2$s。理由:%3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s 已发送邀请给 %2$s 来加入聊天室。理由:%3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s 撤销了 %2$s 加入聊天室的邀請。理由:%3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s 接受 %2$s 的邀請。理由:%3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s 撤回了对 %2$s 的邀请。理由:%3$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="other">%1$s 新增了 %2$s 为此聊天室的地址。</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="other">%1$s 移除了此聊天室的 %3$s 地址。</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s 为此聊天室新增了 %2$s 并移除 %3$s 地址。</string>
-    <string name="notice_room_canonical_alias_set">%1$s 将此聊天室的主地址设为了 %2$s。</string>
-    <string name="notice_room_canonical_alias_unset">%1$s 为此聊天室移除了主地址。</string>
-    <string name="notice_room_guest_access_can_join">%1$s 已允许访客加入聊天室。</string>
-    <string name="notice_room_guest_access_forbidden">%1$s 已禁止访客加入聊天室。</string>
-    <string name="notice_end_to_end_ok">%1$s 已开启端到端加密。</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s 已开启端到端加密(无法识别的演算法 %2$s)。</string>
-    <string name="key_verification_request_fallback_message">%s 正在请求验证您的密钥,但您的客户端不支援聊天中密钥验证。 您将必须使用旧版的密钥验证来验证金钥。</string>
-    <string name="notice_room_created">%1$s 创建了这个聊天室</string>
-    <string name="summary_you_sent_image">您发送了一张图片。</string>
-    <string name="summary_you_sent_sticker">您发送了一张贴纸。</string>
-    <string name="notice_room_invite_no_invitee_by_you">您的邀请</string>
-    <string name="notice_room_created_by_you">您创建了这个聊天室</string>
-    <string name="notice_room_invite_by_you">您邀请了 %1$s</string>
-    <string name="notice_room_join_by_you">您加入了聊天室</string>
-    <string name="notice_room_leave_by_you">您离开了聊天室</string>
-    <string name="notice_room_reject_by_you">您拒绝了邀请</string>
-    <string name="notice_room_kick_by_you">您移除了 %1$s</string>
-    <string name="notice_room_unban_by_you">您解封了 %1$s</string>
-    <string name="notice_room_ban_by_you">您封禁了 %1$s</string>
-    <string name="notice_room_withdraw_by_you">您撤回了对 %1$s 的邀请</string>
-    <string name="notice_avatar_url_changed_by_you">您更换了您的头像</string>
-    <string name="notice_display_name_set_by_you">您将您的昵称设置为 %1$s</string>
-    <string name="notice_display_name_changed_from_by_you">您将您的昵称从 %1$s 改为 %2$s</string>
-    <string name="notice_display_name_removed_by_you">您移除了您的昵称 (%1$s)</string>
-    <string name="notice_room_topic_changed_by_you">您把主题改为:%1$s</string>
-    <string name="notice_room_avatar_changed">%1$s 变更了聊天室头像</string>
-    <string name="notice_room_avatar_changed_by_you">您变更了聊天室头像</string>
-    <string name="notice_room_name_changed_by_you">您把聊天室名称改为:%1$s</string>
-    <string name="notice_placed_video_call_by_you">您发起了一次视频通话。</string>
-    <string name="notice_placed_voice_call_by_you">您发起了一次语音通话。</string>
-    <string name="notice_call_candidates">%s 发送了数据以建立通话。</string>
-    <string name="notice_call_candidates_by_you">您发送了数据以建立通话。</string>
-    <string name="notice_answered_call_by_you">您接听了通话。</string>
-    <string name="notice_ended_call_by_you">您结束了通话。</string>
-    <string name="notice_made_future_room_visibility_by_you">您已让未来的聊天室记录对 %1$s 可见</string>
-    <string name="notice_end_to_end_by_you">您开启了端到端加密(%1$s)</string>
-    <string name="notice_room_update_by_you">您升级了此聊天室。</string>
-    <string name="notice_requested_voip_conference_by_you">您请求了 VoIP 会议</string>
-    <string name="notice_room_name_removed_by_you">您移除了聊天室名称</string>
-    <string name="notice_room_topic_removed_by_you">您移除了聊天室主题</string>
-    <string name="notice_room_avatar_removed">%1$s 移除了聊天室头像</string>
-    <string name="notice_room_avatar_removed_by_you">您移除了聊天室头像</string>
-    <string name="notice_profile_change_redacted_by_you">您更新了您的个人档案 %1$s</string>
-    <string name="notice_room_third_party_invite_by_you">您向 %1$s 发送了加入聊天室的邀请</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">您已撤回了对 %1$s 加入聊天室的邀请</string>
-    <string name="notice_room_third_party_registered_invite_by_you">您接受了 %1$s 的邀请</string>
-    <string name="notice_widget_added">%1$s 添加了 %2$s 小部件</string>
-    <string name="notice_widget_added_by_you">您添加了 %1$s 小部件</string>
-    <string name="notice_widget_removed">%1$s 移除了 %2$s 小部件</string>
-    <string name="notice_widget_removed_by_you">您移除了 %1$s 小部件</string>
-    <string name="notice_widget_modified">%1$s 修改了 %2$s 小部件</string>
-    <string name="notice_widget_modified_by_you">您修改了 %1$s 小部件</string>
-    <string name="power_level_admin">管理员</string>
-    <string name="power_level_moderator">审核员</string>
-    <string name="power_level_default">默认</string>
-    <string name="power_level_custom">自定义(%1$d)</string>
-    <string name="power_level_custom_no_value">自定义</string>
-    <string name="notice_power_level_changed_by_you">您更改了%1$s 的权力等级。</string>
-    <string name="notice_power_level_changed">%1$s 更改了 %2$s 的权力等级。</string>
-    <string name="notice_power_level_diff">%1$s 从 %2$s 到 %3$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">您的邀请。理由:%1$s</string>
-    <string name="notice_room_invite_with_reason_by_you">您邀请了 %1$s。理由:%2$s</string>
-    <string name="notice_room_join_with_reason_by_you">您加入了聊天室。理由:%1$s</string>
-    <string name="notice_room_leave_with_reason_by_you">您离开了聊天室。理由:%1$s</string>
-    <string name="notice_room_reject_with_reason_by_you">您拒绝了邀请。理由:%1$s</string>
-    <string name="notice_room_kick_with_reason_by_you">您踢走了 %1$s。理由:%2$s</string>
-    <string name="notice_room_unban_with_reason_by_you">您解封了 %1$s。理由:%2$s</string>
-    <string name="notice_room_ban_with_reason_by_you">您封禁了 %1$s。理由:%2$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">您已发送邀请给 %1$s 来加入聊天室。理由:%2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">您撤销了 %1$s 加入聊天室的邀请。理由:%2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">您接受了 %1$s 的邀请。理由:%2$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">您撤回了 %1$s 的邀请。理由:%2$s</string>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="other">您新增了 %1$s 为此聊天室的地址。</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="other">您移除了此聊天室的 %1$s 地址。</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed_by_you">您为此聊天室新增了 %1$s 并移除了 %2$s 地址。</string>
-    <string name="notice_room_canonical_alias_set_by_you">您将此聊天室的主地址设为了 %1$s。</string>
-    <string name="notice_room_canonical_alias_unset_by_you">您移除了此聊天室的主地址。</string>
-    <string name="notice_room_guest_access_can_join_by_you">您已允许访客加入聊天室。</string>
-    <string name="notice_room_guest_access_forbidden_by_you">您已禁止访客加入聊天室。</string>
-    <string name="notice_end_to_end_ok_by_you">您已开启端到端加密。</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">您已开启端到端加密(无法识别的算法 %1$s)。</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">您已离开。理由:%1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s 已离开。理由:%2$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">您已加入。理由:%1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s 已加入。理由:%2$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">您撤回了对 %1$s 的邀请</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s 撤回了对 %2$s 的邀请</string>
-    <string name="notice_direct_room_third_party_invite_by_you">您邀请了 %1$s</string>
-    <string name="notice_direct_room_third_party_invite">%1$s 邀请了 %2$s</string>
-    <string name="notice_direct_room_update_by_you">您在此处升级。</string>
-    <string name="notice_direct_room_update">%s 在此处升级。</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">您使未来的消息对 %1$s 可见</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s 使未来的消息对 %2$s 可见</string>
-    <string name="notice_direct_room_leave_by_you">您离开了聊天室</string>
-    <string name="notice_direct_room_leave">%1$s 离开了聊天室</string>
-    <string name="notice_direct_room_join_by_you">您已加入</string>
-    <string name="notice_direct_room_join">%1$s 已加入</string>
-    <string name="notice_direct_room_created_by_you">您创建了讨论</string>
-    <string name="notice_direct_room_created">%1$s 创建了讨论</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">你已阻止客人加入房间。</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s已阻止客人加入房间。</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">你已允许客人加入这里。</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s 已允许客人加入这里。</string>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values-zh-rTW/strings.xml b/matrix-sdk-android/src/main/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 5038e8aab2a12395019c11c03c7130c709450108..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,251 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s:%2$s</string>
-    <string name="summary_user_sent_image">%1$s 傳送了一張圖片。</string>
-    <string name="notice_room_invite_no_invitee">%s 的邀請</string>
-    <string name="notice_room_invite">%1$s 邀請了 %2$s</string>
-    <string name="notice_room_invite_you">%1$s 邀請您</string>
-    <string name="notice_room_join">%1$s 已加入聊天室</string>
-    <string name="notice_room_leave">%1$s 已離開聊天室</string>
-    <string name="notice_room_reject">%1$s 拒絕邀請</string>
-    <string name="notice_room_kick">%1$s 踢出 %2$s</string>
-    <string name="notice_room_unban">%1$s 解除禁止 %2$s</string>
-    <string name="notice_room_ban">%1$s 禁止 %2$s</string>
-    <string name="notice_room_withdraw">%1$s 收回了對 %2$s 的邀請</string>
-    <string name="notice_avatar_url_changed">%1$s 變更了他們的大頭貼</string>
-    <string name="notice_display_name_set">%1$s 設定了他們的顯示名稱為 %2$s</string>
-    <string name="notice_display_name_changed_from">%1$s 變更了他們的顯示名稱從 %2$s 到 %3$s</string>
-    <string name="notice_display_name_removed">%1$s 移除了他們的顯示名稱 (%2$s)</string>
-    <string name="notice_room_topic_changed">%1$s 變更主題為:%2$s</string>
-    <string name="notice_room_name_changed">%1$s 變更房間名稱為:%2$s</string>
-    <string name="notice_placed_video_call">%s 撥出了視訊通話。</string>
-    <string name="notice_placed_voice_call">%s 撥出了語音通話。</string>
-    <string name="notice_answered_call">%s 回覆了通話。</string>
-    <string name="notice_ended_call">%s 結束通話。</string>
-    <string name="notice_made_future_room_visibility">%1$s 讓房間未來可讓 %2$s 看到歷史紀錄</string>
-    <string name="notice_room_visibility_invited">所有的房間成員,從他們被邀請的時間開始。</string>
-    <string name="notice_room_visibility_joined">所有的房間成員,從他們加入的時間開始。</string>
-    <string name="notice_room_visibility_shared">所有的房間成員。</string>
-    <string name="notice_room_visibility_world_readable">任何人。</string>
-    <string name="notice_room_visibility_unknown">未知 (%s)。</string>
-    <string name="notice_end_to_end">%1$s 開啟了端對端加密 (%2$s)</string>
-    <string name="notice_requested_voip_conference">%1$s 請求了 VoIP 會議通話</string>
-    <string name="notice_voip_started">VoIP 會議通話已開始</string>
-    <string name="notice_voip_finished">VoIP 會議通話已結束</string>
-    <string name="notice_avatar_changed_too">(大頭貼也變更了)</string>
-    <string name="notice_room_name_removed">%1$s 移除了房間名稱</string>
-    <string name="notice_room_topic_removed">%1$s 移除了房間主題</string>
-    <string name="notice_profile_change_redacted">%1$s 更新了他們的基本資料 %2$s</string>
-    <string name="notice_room_third_party_invite">%1$s 傳送加入房間的邀請給 %2$s</string>
-    <string name="notice_room_third_party_registered_invite">%1$s 接受 %2$s 的邀請</string>
-    <string name="notice_crypto_unable_to_decrypt">** 無法解密:%s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">傳送者的裝置並未在此訊息傳送他們的金鑰。</string>
-    <string name="could_not_redact">無法編輯</string>
-    <string name="unable_to_send_message">無法傳送訊息</string>
-    <string name="message_failed_to_upload">上傳圖片失敗</string>
-    <string name="network_error">網路錯誤</string>
-    <string name="matrix_error">Matrix 錯誤</string>
-    <string name="room_error_join_failed_empty_room">目前無法重新加入空房間。</string>
-    <string name="encrypted_message">已加密的訊息</string>
-    <string name="medium_email">電子郵件</string>
-    <string name="medium_phone_number">電話號碼</string>
-    <string name="summary_user_sent_sticker">%1$s 傳送了一張貼圖。</string>
-    <string name="room_displayname_invite_from">來自%s 的邀請</string>
-    <string name="room_displayname_room_invite">聊天室邀請</string>
-    <string name="room_displayname_two_members">%1$s 和 %2$s</string>
-    <string name="room_displayname_empty_room">空聊天室</string>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="other">%1$s 和 和其他 %2$d 個人</item>
-    </plurals>
-    <string name="notice_event_redacted">訊息已移除</string>
-    <string name="notice_event_redacted_by">訊息已被 %1$s 移除</string>
-    <string name="notice_event_redacted_with_reason">訊息已移除 [理由:%1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">訊息已被 %1$s 移除 [理由:%2$s]</string>
-    <string name="initial_sync_start_importing_account">初始化同步:
-\n正在匯入帳號……</string>
-    <string name="initial_sync_start_importing_account_crypto">初始化同步:
-\n正在匯入 crypto</string>
-    <string name="initial_sync_start_importing_account_rooms">初始化同步:
-\n正在匯入聊天室</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">初始化同步:
-\n正在匯入已加入的聊天室</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">初始化同步:
-\n正在匯入已邀請的聊天室</string>
-    <string name="initial_sync_start_importing_account_left_rooms">初始化同步:
-\n正在匯入已離開的聊天室</string>
-    <string name="initial_sync_start_importing_account_groups">初始化同步:
-\n正在匯入社群</string>
-    <string name="initial_sync_start_importing_account_data">初始化同步:
-\n正在匯入帳號資料</string>
-    <string name="notice_room_update">%s 已升級此聊天室。</string>
-    <string name="event_status_sending_message">正在傳送訊息……</string>
-    <string name="clear_timeline_send_queue">清除傳送佇列</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s 撤銷了 %2$s 加入聊天室的邀請</string>
-    <string name="notice_room_invite_no_invitee_with_reason">%1$s 的邀請。理由:%2$s</string>
-    <string name="notice_room_invite_with_reason">%1$s 邀請了 %2$s。理由:%3$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s 邀請了您。理由:%2$s</string>
-    <string name="notice_room_join_with_reason">%1$s 已加入聊天室。理由:%2$s</string>
-    <string name="notice_room_leave_with_reason">%1$s 已離開聊天室。理由:%2$s</string>
-    <string name="notice_room_reject_with_reason">%1$s 已回絕邀請。理由:%2$s</string>
-    <string name="notice_room_kick_with_reason">%1$s 踢走了 %2$s。理由:%3$s</string>
-    <string name="notice_room_unban_with_reason">%1$s 取消封鎖了 %2$s。理由:%3$s</string>
-    <string name="notice_room_ban_with_reason">%1$s 封鎖了 %2$s。理由:%3$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s 已傳送邀請給 %2$s 來加入聊天室。理由:%3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s 撤銷了 %2$s 加入聊天室的邀請。理由:%3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s 接受 %2$s 的邀請。理由:%3$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s 撤回了對 %2$s 的邀請。理由:%3$s</string>
-    <plurals name="notice_room_aliases_added">
-        <item quantity="other">%1$s 新增了 %2$s 為此聊天室的地址。</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="other">%1$s 移除了此聊天室的 %2$s 地址。</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed">%1$s 為此聊天室新增 %2$s 並移除 %3$s 地址。</string>
-    <string name="notice_room_canonical_alias_set">%1$s 為此聊天室設定了 %2$s 為主地址。</string>
-    <string name="notice_room_canonical_alias_unset">%1$s 為此聊天室移除了主要地址。</string>
-    <string name="notice_room_guest_access_can_join">%1$s 已允許訪客加入聊天室。</string>
-    <string name="notice_room_guest_access_forbidden">%1$s 已禁止訪客加入聊天室。</string>
-    <string name="notice_end_to_end_ok">%1$s 已開啟端到端加密。</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s 已開啟端到端加密(無法識別的演算法 %2$s)。</string>
-    <string name="key_verification_request_fallback_message">%s 正在請求驗證您的金鑰,但您的客戶端不支援聊天中金鑰驗證。您將必須使用舊版的金鑰驗證來驗證金鑰。</string>
-    <string name="notice_room_created">%1$s 建立了聊天室</string>
-    <string name="summary_you_sent_image">您傳送了圖片。</string>
-    <string name="summary_you_sent_sticker">您傳送了貼圖。</string>
-    <string name="notice_room_invite_no_invitee_by_you">您的邀請</string>
-    <string name="notice_room_created_by_you">您建立了聊天室</string>
-    <string name="notice_room_invite_by_you">您邀請了 %1$s</string>
-    <string name="notice_room_join_by_you">您加入了聊天室</string>
-    <string name="notice_room_leave_by_you">您離開的聊天室</string>
-    <string name="notice_room_reject_by_you">您回絕了邀請</string>
-    <string name="notice_room_kick_by_you">您踢除了 %1$s</string>
-    <string name="notice_room_unban_by_you">您取消封鎖了 %1$s</string>
-    <string name="notice_room_ban_by_you">您封鎖了 %1$s</string>
-    <string name="notice_room_withdraw_by_you">您撤銷了 %1$s 的邀請</string>
-    <string name="notice_avatar_url_changed_by_you">您變更了您的大頭貼</string>
-    <string name="notice_display_name_set_by_you">您將您的顯示名稱設定為 %1$s</string>
-    <string name="notice_display_name_changed_from_by_you">您將您的顯示名稱從 %1$s 變更為 %2$s</string>
-    <string name="notice_display_name_removed_by_you">您移除了您的顯示名稱(其曾為 %1$s)</string>
-    <string name="notice_room_topic_changed_by_you">您將主題變更為:%1$s</string>
-    <string name="notice_room_avatar_changed">%1$s 變更了聊天室大頭貼</string>
-    <string name="notice_room_avatar_changed_by_you">您變更了聊天室大頭貼</string>
-    <string name="notice_room_name_changed_by_you">您將聊天室名稱變更為:%1$s</string>
-    <string name="notice_placed_video_call_by_you">您發起了視訊通話。</string>
-    <string name="notice_placed_voice_call_by_you">您發起了音訊通話。</string>
-    <string name="notice_call_candidates">%s 傳送了資料以建立通話。</string>
-    <string name="notice_call_candidates_by_you">您傳送了資料以建立通話。</string>
-    <string name="notice_answered_call_by_you">您接了通話。</string>
-    <string name="notice_ended_call_by_you">您結束了通話。</string>
-    <string name="notice_made_future_room_visibility_by_you">您已將未來的聊天室歷史設定為對 %1$s 可見</string>
-    <string name="notice_end_to_end_by_you">您開啟了端到端加密 (%1$s)</string>
-    <string name="notice_room_update_by_you">您升級了此聊天室。</string>
-    <string name="notice_requested_voip_conference_by_you">您請求了 VoIP 會議</string>
-    <string name="notice_room_name_removed_by_you">您移除了聊天室名稱</string>
-    <string name="notice_room_topic_removed_by_you">您移除了聊天室主題</string>
-    <string name="notice_room_avatar_removed">%1$s 移除了聊天室大頭貼</string>
-    <string name="notice_room_avatar_removed_by_you">您移除了聊天室大頭貼</string>
-    <string name="notice_profile_change_redacted_by_you">您更新了您的個人檔案 %1$s</string>
-    <string name="notice_room_third_party_invite_by_you">您傳送了邀請給 %1$s 以加入聊天室</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">您已撤銷對 %1$s 加入聊天室的邀請</string>
-    <string name="notice_room_third_party_registered_invite_by_you">您接受了 %1$s 的邀請</string>
-    <string name="notice_widget_added">%1$s 新增了 %2$s 小工具</string>
-    <string name="notice_widget_added_by_you">您新增了 %1$s 小工具</string>
-    <string name="notice_widget_removed">%1$s 移除了 %2$s 小工具</string>
-    <string name="notice_widget_removed_by_you">您移除了 %1$s 小工具</string>
-    <string name="notice_widget_modified">%1$s 修改了 %2$s 小工具</string>
-    <string name="notice_widget_modified_by_you">您修改了 %1$s 小工具</string>
-    <string name="power_level_admin">管理員</string>
-    <string name="power_level_moderator">板主</string>
-    <string name="power_level_default">預設</string>
-    <string name="power_level_custom">自訂 (%1$d)</string>
-    <string name="power_level_custom_no_value">自訂</string>
-    <string name="notice_power_level_changed_by_you">您變更了 %1$s 的權力等級。</string>
-    <string name="notice_power_level_changed">%1$s 變更了 %2$s 的權力等級。</string>
-    <string name="notice_power_level_diff">%1$s 從 %2$s 到 %3$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">您的邀請。理由:%1$s</string>
-    <string name="notice_room_invite_with_reason_by_you">您邀請了 %1$s。理由:%2$s</string>
-    <string name="notice_room_join_with_reason_by_you">您加入了聊天室。理由:%1$s</string>
-    <string name="notice_room_leave_with_reason_by_you">您離開了聊天室。理由:%1$s</string>
-    <string name="notice_room_reject_with_reason_by_you">您回絕了邀請。理由:%1$s</string>
-    <string name="notice_room_kick_with_reason_by_you">您踢除了 %1$s。理由:%2$s</string>
-    <string name="notice_room_unban_with_reason_by_you">您取消封鎖了 %1$s。理由:%2$s</string>
-    <string name="notice_room_ban_with_reason_by_you">您封鎖了 %1$s。理由:%2$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">您傳甕了邀請給 %1$s 以加入聊天室。理由:%2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">您撤銷了 %1$s 加入聊天室的邀請。理由:%2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">您接受了 %1$s 的邀請。理由:%2$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">您撤回了 %1$s 的邀請。理由:%2$s</string>
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="other">您為此聊天室新增了 %1$s 作為地址。</item>
-    </plurals>
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="other">您為此聊天室移除了 %1$s 作為地址。</item>
-    </plurals>
-    <string name="notice_room_aliases_added_and_removed_by_you">您為此聊天室新增了 %1$s 並移除了 %2$s 作為地址。</string>
-    <string name="notice_room_canonical_alias_set_by_you">您將此聊天室的主要地址設定為 %1$s。</string>
-    <string name="notice_room_canonical_alias_unset_by_you">您將此聊天室的主要地址移除。</string>
-    <string name="notice_room_guest_access_can_join_by_you">您已允許訪客加入聊天室。</string>
-    <string name="notice_room_guest_access_forbidden_by_you">您已阻止訪客加入聊天室。</string>
-    <string name="notice_end_to_end_ok_by_you">您開啟了端到端加密。</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">您開啟了端到端加密(無法識別的演算法 %1$s)。</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">您已避免訪客加入此聊天室。</string>
-    <string name="notice_direct_room_guest_access_forbidden">%1$s 已避免訪客加入此聊天室。</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">您已允許訪客加入這裡。</string>
-    <string name="notice_direct_room_guest_access_can_join">%1$s 已允許訪客加入這裡。</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">您已離開。理由:%1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s 已離開。理由:%2$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">您已加入。理由:%1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s 已加入。理由:%2$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">您已撤銷對 %1$s 的邀請</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s 已撤銷對 %2$s 的邀請</string>
-    <string name="notice_direct_room_third_party_invite_by_you">您已邀請了 %1$s</string>
-    <string name="notice_direct_room_third_party_invite">%1$s 邀請了 %2$s</string>
-    <string name="notice_direct_room_update_by_you">您已在此升級。</string>
-    <string name="notice_direct_room_update">%s 已在此升級。</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">您讓未來的訊息對 %1$s 可見</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s 已讓未來的訊息對 %2$s 可見</string>
-    <string name="notice_direct_room_leave_by_you">您已離開聊天室</string>
-    <string name="notice_direct_room_leave">%1$s 已離開聊天室</string>
-    <string name="notice_direct_room_join_by_you">您已加入</string>
-    <string name="notice_direct_room_join">%1$s 已加入</string>
-    <string name="notice_direct_room_created_by_you">您已建立此討論</string>
-    <string name="notice_direct_room_created">%1$s 已建立此討論</string>
-    <string name="room_displayname_empty_room_was">空的聊天室(曾為 %s)</string>
-    <plurals name="room_displayname_four_and_more_members">
-        <item quantity="other">%1$s, %2$s, %3$s 與 %4$d 個其他</item>
-    </plurals>
-    <string name="room_displayname_4_members">%1$s, %2$s, %3$s 與 %4$s</string>
-    <string name="room_displayname_3_members">%1$s, %2$s 與 %3$s</string>
-    <string name="notice_room_server_acl_allow_is_empty">🎉 禁止所有伺服器參與!無法再使用此聊天室。</string>
-    <string name="notice_room_server_acl_updated_no_change">無變更。</string>
-    <string name="notice_room_server_acl_updated_ip_literals_not_allowed">• 禁止伺服器符合 IP 文字。</string>
-    <string name="notice_room_server_acl_updated_ip_literals_allowed">• 允許伺服器符合 IP 文字。</string>
-    <string name="notice_room_server_acl_updated_was_allowed">• 伺服器符合 %s 已從允許清單中移除。</string>
-    <string name="notice_room_server_acl_updated_allowed">• 允許伺服器符合 %s。</string>
-    <string name="notice_room_server_acl_updated_was_banned">• 伺服器符合 %s 已從禁止清單中移除。</string>
-    <string name="notice_room_server_acl_updated_banned">• 現在禁止伺服器符合 %s。</string>
-    <string name="notice_room_server_acl_updated_title_by_you">您為此聊天室變更了伺服器 ACL。</string>
-    <string name="notice_room_server_acl_updated_title">%s 為此聊天是變更了伺服器 ACL。</string>
-    <string name="notice_room_server_acl_set_ip_literals_not_allowed">• 禁止伺服器符合 IP 文字。</string>
-    <string name="notice_room_server_acl_set_ip_literals_allowed">• 允許伺服器符合 IP 文字。</string>
-    <string name="notice_room_server_acl_set_allowed">• 已允許伺服器符合 %s。</string>
-    <string name="notice_room_server_acl_set_banned">• 已禁止伺服器符合 %s。</string>
-    <string name="notice_room_server_acl_set_title_by_you">您為此聊天是設定了伺服器 ACL。</string>
-    <string name="notice_room_server_acl_set_title">%s 為此聊天是設定了伺服器 ACL。</string>
-    <string name="notice_room_canonical_alias_no_change_by_you">您變更了此聊天室的地址。</string>
-    <string name="notice_room_canonical_alias_no_change">%1$s 變更了此聊天室的地址。</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed_by_you">您為此聊天室變更了主要及備用地址。</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed">%1$s 為此聊天室變更了主要及備用地址。</string>
-    <string name="notice_room_canonical_alias_alternative_changed_by_you">您為此聊天室變更了備用地址。</string>
-    <string name="notice_room_canonical_alias_alternative_changed">%1$s 變更了此聊天室的備用地址。</string>
-    <plurals name="notice_room_canonical_alias_alternative_removed_by_you">
-        <item quantity="other">您為此聊天室移除了備用地址 %1$s。</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_removed">
-        <item quantity="other">%1$s 已為此聊天室移除備用地址 %2$s。</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added_by_you">
-        <item quantity="other">您為此聊天室新增了備用地址 %1$s。</item>
-    </plurals>
-    <plurals name="notice_room_canonical_alias_alternative_added">
-        <item quantity="other">%1$s 已為此聊天室新增了備用地址 %2$s。</item>
-    </plurals>
-</resources>
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/res/values/strings.xml b/matrix-sdk-android/src/main/res/values/strings.xml
deleted file mode 100644
index 7a0fe1d7352bf35adddf3a2977fb382e5c5538da..0000000000000000000000000000000000000000
--- a/matrix-sdk-android/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,308 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="summary_message">%1$s: %2$s</string>
-    <string name="summary_user_sent_image">%1$s sent an image.</string>
-    <string name="summary_you_sent_image">You sent an image.</string>
-    <string name="summary_user_sent_sticker">%1$s sent a sticker.</string>
-    <string name="summary_you_sent_sticker">You sent a sticker.</string>
-
-    <string name="notice_room_invite_no_invitee">%s\'s invitation</string>
-    <string name="notice_room_invite_no_invitee_by_you">Your invitation</string>
-    <string name="notice_room_created">%1$s created the room</string>
-    <string name="notice_room_created_by_you">You created the room</string>
-    <string name="notice_direct_room_created">%1$s created the discussion</string>
-    <string name="notice_direct_room_created_by_you">You created the discussion</string>
-    <string name="notice_room_invite">%1$s invited %2$s</string>
-    <string name="notice_room_invite_by_you">You invited %1$s</string>
-    <string name="notice_room_invite_you">%1$s invited you</string>
-    <string name="notice_room_join">%1$s joined the room</string>
-    <string name="notice_room_join_by_you">You joined the room</string>
-    <string name="notice_direct_room_join">%1$s joined</string>
-    <string name="notice_direct_room_join_by_you">You joined</string>
-    <string name="notice_room_leave">%1$s left the room</string>
-    <string name="notice_room_leave_by_you">You left the room</string>
-    <string name="notice_direct_room_leave">%1$s left the room</string>
-    <string name="notice_direct_room_leave_by_you">You left the room</string>
-    <string name="notice_room_reject">%1$s rejected the invitation</string>
-    <string name="notice_room_reject_by_you">You rejected the invitation</string>
-    <string name="notice_room_kick">%1$s kicked %2$s</string>
-    <string name="notice_room_kick_by_you">You kicked %1$s</string>
-    <string name="notice_room_unban">%1$s unbanned %2$s</string>
-    <string name="notice_room_unban_by_you">You unbanned %1$s</string>
-    <string name="notice_room_ban">%1$s banned %2$s</string>
-    <string name="notice_room_ban_by_you">You banned %1$s</string>
-    <string name="notice_room_withdraw">%1$s withdrew %2$s\'s invitation</string>
-    <string name="notice_room_withdraw_by_you">You withdrew %1$s\'s invitation</string>
-    <string name="notice_avatar_url_changed">%1$s changed their avatar</string>
-    <string name="notice_avatar_url_changed_by_you">You changed your avatar</string>
-    <string name="notice_display_name_set">%1$s set their display name to %2$s</string>
-    <string name="notice_display_name_set_by_you">You set your display name to %1$s</string>
-    <string name="notice_display_name_changed_from">%1$s changed their display name from %2$s to %3$s</string>
-    <string name="notice_display_name_changed_from_by_you">You changed your display name from %1$s to %2$s</string>
-    <string name="notice_display_name_removed">%1$s removed their display name (it was %2$s)</string>
-    <string name="notice_display_name_removed_by_you">You removed your display name (it was %1$s)</string>
-    <string name="notice_room_topic_changed">%1$s changed the topic to: %2$s</string>
-    <string name="notice_room_topic_changed_by_you">You changed the topic to: %1$s</string>
-    <string name="notice_room_avatar_changed">%1$s changed the room avatar</string>
-    <string name="notice_room_avatar_changed_by_you">You changed the room avatar</string>
-    <string name="notice_room_name_changed">%1$s changed the room name to: %2$s</string>
-    <string name="notice_room_name_changed_by_you">You changed the room name to: %1$s</string>
-    <string name="notice_placed_video_call">%s placed a video call.</string>
-    <string name="notice_placed_video_call_by_you">You placed a video call.</string>
-    <string name="notice_placed_voice_call">%s placed a voice call.</string>
-    <string name="notice_placed_voice_call_by_you">You placed a voice call.</string>
-    <string name="notice_call_candidates">%s sent data to setup the call.</string>
-    <string name="notice_call_candidates_by_you">You sent data to setup the call.</string>
-    <string name="notice_answered_call">%s answered the call.</string>
-    <string name="notice_answered_call_by_you">You answered the call.</string>
-    <string name="notice_ended_call">%s ended the call.</string>
-    <string name="notice_ended_call_by_you">You ended the call.</string>
-    <string name="notice_made_future_room_visibility">%1$s made future room history visible to %2$s</string>
-    <string name="notice_made_future_room_visibility_by_you">You made future room history visible to %1$s</string>
-    <string name="notice_made_future_direct_room_visibility">%1$s made future messages visible to %2$s</string>
-    <string name="notice_made_future_direct_room_visibility_by_you">You made future messages visible to %1$s</string>
-    <string name="notice_room_visibility_invited">all room members, from the point they are invited.</string>
-    <string name="notice_room_visibility_joined">all room members, from the point they joined.</string>
-    <string name="notice_room_visibility_shared">all room members.</string>
-    <string name="notice_room_visibility_world_readable">anyone.</string>
-    <string name="notice_room_visibility_unknown">unknown (%s).</string>
-    <string name="notice_end_to_end">%1$s turned on end-to-end encryption (%2$s)</string>
-    <string name="notice_end_to_end_by_you">You turned on end-to-end encryption (%1$s)</string>
-    <string name="notice_room_update">%s upgraded this room.</string>
-    <string name="notice_room_update_by_you">You upgraded this room.</string>
-    <string name="notice_direct_room_update">%s upgraded here.</string>
-    <string name="notice_direct_room_update_by_you">You upgraded here.</string>
-    <string name="notice_room_server_acl_set_title">%s set the server ACLs for this room.</string>
-    <string name="notice_room_server_acl_set_title_by_you">You set the server ACLs for this room.</string>
-    <string name="notice_room_server_acl_set_banned">• Server matching %s are banned.</string>
-    <string name="notice_room_server_acl_set_allowed">• Server matching %s are allowed.</string>
-    <string name="notice_room_server_acl_set_ip_literals_allowed">• Server matching IP literals are allowed.</string>
-    <string name="notice_room_server_acl_set_ip_literals_not_allowed">• Server matching IP literals are banned.</string>
-
-    <string name="notice_room_server_acl_updated_title">%s changed the server ACLs for this room.</string>
-    <string name="notice_room_server_acl_updated_title_by_you">You changed the server ACLs for this room.</string>
-    <string name="notice_room_server_acl_updated_banned">• Server matching %s are now banned.</string>
-    <string name="notice_room_server_acl_updated_was_banned">• Server matching %s were removed from the ban list.</string>
-    <string name="notice_room_server_acl_updated_allowed">• Server matching %s are now allowed.</string>
-    <string name="notice_room_server_acl_updated_was_allowed">• Server matching %s were removed from the allowed list.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_allowed">• Server matching IP literals are now allowed.</string>
-    <string name="notice_room_server_acl_updated_ip_literals_not_allowed">• Server matching IP literals are now banned.</string>
-    <string name="notice_room_server_acl_updated_no_change">No change.</string>
-    <string name="notice_room_server_acl_allow_is_empty">🎉 All servers are banned from participating! This room can no longer be used.</string>
-
-    <string name="notice_requested_voip_conference">%1$s requested a VoIP conference</string>
-    <string name="notice_requested_voip_conference_by_you">You requested a VoIP conference</string>
-    <string name="notice_voip_started">VoIP conference started</string>
-    <string name="notice_voip_finished">VoIP conference finished</string>
-
-    <string name="notice_avatar_changed_too">(avatar was changed too)</string>
-    <string name="notice_room_name_removed">%1$s removed the room name</string>
-    <string name="notice_room_name_removed_by_you">You removed the room name</string>
-    <string name="notice_room_topic_removed">%1$s removed the room topic</string>
-    <string name="notice_room_topic_removed_by_you">You removed the room topic</string>
-    <string name="notice_room_avatar_removed">%1$s removed the room avatar</string>
-    <string name="notice_room_avatar_removed_by_you">You removed the room avatar</string>
-    <string name="notice_event_redacted">Message removed</string>
-    <string name="notice_event_redacted_by">Message removed by %1$s</string>
-    <string name="notice_event_redacted_with_reason">Message removed [reason: %1$s]</string>
-    <string name="notice_event_redacted_by_with_reason">Message removed by %1$s [reason: %2$s]</string>
-    <string name="notice_profile_change_redacted">%1$s updated their profile %2$s</string>
-    <string name="notice_profile_change_redacted_by_you">You updated your profile %1$s</string>
-    <string name="notice_room_third_party_invite">%1$s sent an invitation to %2$s to join the room</string>
-    <string name="notice_room_third_party_invite_by_you">You sent an invitation to %1$s to join the room</string>
-    <string name="notice_direct_room_third_party_invite">%1$s invited %2$s</string>
-    <string name="notice_direct_room_third_party_invite_by_you">You invited %1$s</string>
-    <string name="notice_room_third_party_revoked_invite">%1$s revoked the invitation for %2$s to join the room</string>
-    <string name="notice_room_third_party_revoked_invite_by_you">You revoked the invitation for %1$s to join the room</string>
-    <string name="notice_direct_room_third_party_revoked_invite">%1$s revoked the invitation for %2$s</string>
-    <string name="notice_direct_room_third_party_revoked_invite_by_you">You revoked the invitation for %1$s</string>
-    <string name="notice_room_third_party_registered_invite">%1$s accepted the invitation for %2$s</string>
-    <string name="notice_room_third_party_registered_invite_by_you">You accepted the invitation for %1$s</string>
-
-    <string name="notice_widget_added">%1$s added %2$s widget</string>
-    <string name="notice_widget_added_by_you">You added %1$s widget</string>
-    <string name="notice_widget_removed">%1$s removed %2$s widget</string>
-    <string name="notice_widget_removed_by_you">You removed %1$s widget</string>
-    <string name="notice_widget_modified">%1$s modified %2$s widget</string>
-    <string name="notice_widget_modified_by_you">You modified %1$s widget</string>
-
-    <string name="power_level_admin">Admin</string>
-    <string name="power_level_moderator">Moderator</string>
-    <string name="power_level_default">Default</string>
-    <string name="power_level_custom">Custom (%1$d)</string>
-    <string name="power_level_custom_no_value">Custom</string>
-
-    <!-- parameter will be a comma separated list of values of notice_power_level_diff -->
-    <string name="notice_power_level_changed_by_you">You changed the power level of %1$s.</string>
-    <!-- First parameter will be a userId or display name, second one will be a comma separated list of values of notice_power_level_diff -->
-    <string name="notice_power_level_changed">%1$s changed the power level of %2$s.</string>
-    <!-- First parameter will be a userId or display name, the two last ones will be value of power_level_* -->
-    <string name="notice_power_level_diff">%1$s from %2$s to %3$s</string>
-
-    <string name="notice_crypto_unable_to_decrypt">** Unable to decrypt: %s **</string>
-    <string name="notice_crypto_error_unkwown_inbound_session_id">The sender\'s device has not sent us the keys for this message.</string>
-
-    <!-- Messages -->
-
-    <!-- Room Screen -->
-    <string name="could_not_redact">Could not redact</string>
-    <string name="unable_to_send_message">Unable to send message</string>
-
-    <string name="message_failed_to_upload">Failed to upload image</string>
-
-    <!-- general errors -->
-    <string name="network_error">Network error</string>
-    <string name="matrix_error">Matrix error</string>
-
-    <!-- Home Screen -->
-
-    <!-- Last seen time -->
-
-    <!-- call events -->
-
-    <!-- room error messages -->
-    <string name="room_error_join_failed_empty_room">It is not currently possible to re-join an empty room.</string>
-
-    <string name="encrypted_message">Encrypted message</string>
-
-    <!-- medium friendly name -->
-    <string name="medium_email">Email address</string>
-    <string name="medium_phone_number">Phone number</string>
-
-    <!-- Room display name -->
-    <string name="room_displayname_invite_from">Invite from %s</string>
-    <string name="room_displayname_room_invite">Room Invite</string>
-
-    <!-- The 2 parameters will be members' name -->
-    <string name="room_displayname_two_members">%1$s and %2$s</string>
-    <!-- The 3 parameters will be members' name -->
-    <string name="room_displayname_3_members">%1$s, %2$s and %3$s</string>
-    <!-- The 4 parameters will be members' name -->
-    <string name="room_displayname_4_members">%1$s, %2$s, %3$s and %4$s</string>
-    <!-- The 3 first parameters will be members' name -->
-    <plurals name="room_displayname_four_and_more_members">
-        <item quantity="one">%1$s, %2$s, %3$s and %4$d other</item>
-        <item quantity="other">%1$s, %2$s, %3$s and %4$d others</item>
-    </plurals>
-    <plurals name="room_displayname_three_and_more_members">
-        <item quantity="one">%1$s and 1 other</item>
-        <item quantity="other">%1$s and %2$d others</item>
-    </plurals>
-
-    <string name="room_displayname_empty_room">Empty room</string>
-    <string name="room_displayname_empty_room_was">Empty room (was %s)</string>
-
-    <string name="initial_sync_start_importing_account">Initial Sync:\nImporting account…</string>
-    <string name="initial_sync_start_importing_account_crypto">Initial Sync:\nImporting crypto</string>
-    <string name="initial_sync_start_importing_account_rooms">Initial Sync:\nImporting Rooms</string>
-    <string name="initial_sync_start_importing_account_joined_rooms">Initial Sync:\nImporting Joined Rooms</string>
-    <string name="initial_sync_start_importing_account_invited_rooms">Initial Sync:\nImporting Invited Rooms</string>
-    <string name="initial_sync_start_importing_account_left_rooms">Initial Sync:\nImporting Left Rooms</string>
-    <string name="initial_sync_start_importing_account_groups">Initial Sync:\nImporting Communities</string>
-    <string name="initial_sync_start_importing_account_data">Initial Sync:\nImporting Account Data</string>
-
-    <string name="event_status_sending_message">Sending message…</string>
-    <string name="clear_timeline_send_queue">Clear sending queue</string>
-
-    <string name="notice_room_invite_no_invitee_with_reason">%1$s\'s invitation. Reason: %2$s</string>
-    <string name="notice_room_invite_no_invitee_with_reason_by_you">Your invitation. Reason: %1$s</string>
-    <string name="notice_room_invite_with_reason">%1$s invited %2$s. Reason: %3$s</string>
-    <string name="notice_room_invite_with_reason_by_you">You invited %1$s. Reason: %2$s</string>
-    <string name="notice_room_invite_you_with_reason">%1$s invited you. Reason: %2$s</string>
-    <string name="notice_room_join_with_reason">%1$s joined the room. Reason: %2$s</string>
-    <string name="notice_room_join_with_reason_by_you">You joined the room. Reason: %1$s</string>
-    <string name="notice_direct_room_join_with_reason">%1$s joined. Reason: %2$s</string>
-    <string name="notice_direct_room_join_with_reason_by_you">You joined. Reason: %1$s</string>
-    <string name="notice_room_leave_with_reason">%1$s left the room. Reason: %2$s</string>
-    <string name="notice_room_leave_with_reason_by_you">You left the room. Reason: %1$s</string>
-    <string name="notice_direct_room_leave_with_reason">%1$s left. Reason: %2$s</string>
-    <string name="notice_direct_room_leave_with_reason_by_you">You left. Reason: %1$s</string>
-    <string name="notice_room_reject_with_reason">%1$s rejected the invitation. Reason: %2$s</string>
-    <string name="notice_room_reject_with_reason_by_you">You rejected the invitation. Reason: %1$s</string>
-    <string name="notice_room_kick_with_reason">%1$s kicked %2$s. Reason: %3$s</string>
-    <string name="notice_room_kick_with_reason_by_you">You kicked %1$s. Reason: %2$s</string>
-    <string name="notice_room_unban_with_reason">%1$s unbanned %2$s. Reason: %3$s</string>
-    <string name="notice_room_unban_with_reason_by_you">You unbanned %1$s. Reason: %2$s</string>
-    <string name="notice_room_ban_with_reason">%1$s banned %2$s. Reason: %3$s</string>
-    <string name="notice_room_ban_with_reason_by_you">You banned %1$s. Reason: %2$s</string>
-    <string name="notice_room_third_party_invite_with_reason">%1$s sent an invitation to %2$s to join the room. Reason: %3$s</string>
-    <string name="notice_room_third_party_invite_with_reason_by_you">You sent an invitation to %1$s to join the room. Reason: %2$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason">%1$s revoked the invitation for %2$s to join the room. Reason: %3$s</string>
-    <string name="notice_room_third_party_revoked_invite_with_reason_by_you">You revoked the invitation for %1$s to join the room. Reason: %2$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason">%1$s accepted the invitation for %2$s. Reason: %3$s</string>
-    <string name="notice_room_third_party_registered_invite_with_reason_by_you">You accepted the invitation for %1$s. Reason: %2$s</string>
-    <string name="notice_room_withdraw_with_reason">%1$s withdrew %2$s\'s invitation. Reason: %3$s</string>
-    <string name="notice_room_withdraw_with_reason_by_you">You withdrew %1$s\'s invitation. Reason: %2$s</string>
-
-    <plurals name="notice_room_aliases_added">
-        <item quantity="one">%1$s added %2$s as an address for this room.</item>
-        <item quantity="other">%1$s added %2$s as addresses for this room.</item>
-    </plurals>
-
-    <plurals name="notice_room_aliases_added_by_you">
-        <item quantity="one">You added %1$s as an address for this room.</item>
-        <item quantity="other">You added %1$s as addresses for this room.</item>
-    </plurals>
-
-    <plurals name="notice_room_aliases_removed">
-        <item quantity="one">%1$s removed %2$s as an address for this room.</item>
-        <item quantity="other">%1$s removed %2$s as addresses for this room.</item>
-    </plurals>
-
-    <plurals name="notice_room_aliases_removed_by_you">
-        <item quantity="one">You removed %1$s as an address for this room.</item>
-        <item quantity="other">You removed %1$s as addresses for this room.</item>
-    </plurals>
-
-    <string name="notice_room_aliases_added_and_removed">%1$s added %2$s and removed %3$s as addresses for this room.</string>
-    <string name="notice_room_aliases_added_and_removed_by_you">You added %1$s and removed %2$s as addresses for this room.</string>
-
-    <string name="notice_room_canonical_alias_set">"%1$s set the main address for this room to %2$s."</string>
-    <string name="notice_room_canonical_alias_set_by_you">"You set the main address for this room to %1$s."</string>
-    <string name="notice_room_canonical_alias_unset">"%1$s removed the main address for this room."</string>
-    <string name="notice_room_canonical_alias_unset_by_you">"You removed the main address for this room."</string>
-
-    <plurals name="notice_room_canonical_alias_alternative_added">
-        <item quantity="one">%1$s added the alternative address %2$s for this room.</item>
-        <item quantity="other">%1$s added the alternative addresses %2$s for this room.</item>
-    </plurals>
-
-    <plurals name="notice_room_canonical_alias_alternative_added_by_you">
-        <item quantity="one">You added the alternative address %1$s for this room.</item>
-        <item quantity="other">You added the alternative addresses %1$s for this room.</item>
-    </plurals>
-
-    <plurals name="notice_room_canonical_alias_alternative_removed">
-        <item quantity="one">%1$s removed the alternative address %2$s for this room.</item>
-        <item quantity="other">%1$s removed the alternative addresses %2$s for this room.</item>
-    </plurals>
-
-    <plurals name="notice_room_canonical_alias_alternative_removed_by_you">
-        <item quantity="one">You removed the alternative address %1$s for this room.</item>
-        <item quantity="other">You removed the alternative addresses %1$s for this room.</item>
-    </plurals>
-
-    <string name="notice_room_canonical_alias_alternative_changed">%1$s changed the alternative addresses for this room.</string>
-    <string name="notice_room_canonical_alias_alternative_changed_by_you">You changed the alternative addresses for this room.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed">%1$s changed the main and alternative addresses for this room.</string>
-    <string name="notice_room_canonical_alias_main_and_alternative_changed_by_you">You changed the main and alternative addresses for this room.</string>
-    <string name="notice_room_canonical_alias_no_change">%1$s changed the addresses for this room.</string>
-    <string name="notice_room_canonical_alias_no_change_by_you">You changed the addresses for this room.</string>
-
-    <string name="notice_room_guest_access_can_join">"%1$s has allowed guests to join the room."</string>
-    <string name="notice_room_guest_access_can_join_by_you">"You have allowed guests to join the room."</string>
-    <string name="notice_direct_room_guest_access_can_join">"%1$s has allowed guests to join here."</string>
-    <string name="notice_direct_room_guest_access_can_join_by_you">"You have allowed guests to join here."</string>
-    <string name="notice_room_guest_access_forbidden">"%1$s has prevented guests from joining the room."</string>
-    <string name="notice_room_guest_access_forbidden_by_you">"You have prevented guests from joining the room."</string>
-    <string name="notice_direct_room_guest_access_forbidden">"%1$s has prevented guests from joining the room."</string>
-    <string name="notice_direct_room_guest_access_forbidden_by_you">"You have prevented guests from joining the room."</string>
-
-    <string name="notice_end_to_end_ok">%1$s turned on end-to-end encryption.</string>
-    <string name="notice_end_to_end_ok_by_you">You turned on end-to-end encryption.</string>
-    <string name="notice_end_to_end_unknown_algorithm">%1$s turned on end-to-end encryption (unrecognised algorithm %2$s).</string>
-    <string name="notice_end_to_end_unknown_algorithm_by_you">You turned on end-to-end encryption (unrecognised algorithm %1$s).</string>
-
-    <string name="key_verification_request_fallback_message">%s is requesting to verify your key, but your client does not support in-chat key verification. You will need to use legacy key verification to verify keys.</string>
-
-</resources>