diff --git a/.idea/misc.xml b/.idea/misc.xml
index 360e6d41e364d4aebf23e7f2d3e9cef58a2eb12c..5c9f89fee71360989ca8a39d7324e4a12762142d 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="ExternalStorageConfigurationManager" enabled="true" />
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/build/classes" />
   </component>
   <component name="ProjectType">
diff --git a/matrix-sdk-android/gradle-publish.gradle b/matrix-sdk-android/gradle-publish.gradle
index 5a32cf4d56590a9e086723f2c8bfa82ac0605492..168c4986d2b13e210b20b1d02e9658fb120182c9 100644
--- a/matrix-sdk-android/gradle-publish.gradle
+++ b/matrix-sdk-android/gradle-publish.gradle
@@ -3,7 +3,7 @@ apply plugin: 'maven-publish'
 
 def groupIdString = "org.matrix.android"
 def artifactIdString = "matrix-sdk-android"
-def versionName = "1.5.1.1"
+def versionName = "1.5.1.2"
 def artifactPath = "$buildDir/outputs/aar/$artifactIdString-release.aar"
 def publicationName = "release"
 def projectId = "16"
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 145cdbdc228ad1f405a66f1b60c7f154614ff2eb..07d748b90919680319133b0d261e92801409b766 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,6 +16,8 @@
 
 package org.matrix.android.sdk.api.auth.login
 
+import org.matrix.android.sdk.api.auth.registration.RegistrationResult
+import org.matrix.android.sdk.api.auth.registration.Stage
 import org.matrix.android.sdk.api.session.Session
 import org.matrix.android.sdk.api.util.JsonDict
 
@@ -77,4 +79,14 @@ interface LoginWizard {
      * if [org.matrix.android.sdk.api.auth.data.LoginFlowResult.isLogoutDevicesSupported] is true.
      */
     suspend fun resetPasswordMailConfirmed(newPassword: String, logoutAllDevices: Boolean = true)
+
+    //Added to support few login flows
+    suspend fun getAllLoginFlows(): List<List<Stage>>
+
+    /**
+     * Perform custom login stage by sending a custom JsonDict.
+     * Current login "session" param will be included into authParams by default.
+     * The authParams should contain at least one entry "type" with a String value.
+     */
+    suspend fun loginStageCustom(authParams: JsonDict): RegistrationResult
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthAPI.kt
index 6f1778ce384623b0f56efa07eb26afe35aa11097..73da2fddbb02f0e6199ab91b9f507ce2e1daf4e6 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthAPI.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthAPI.kt
@@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.auth
 import org.matrix.android.sdk.api.auth.data.Credentials
 import org.matrix.android.sdk.api.util.JsonDict
 import org.matrix.android.sdk.internal.auth.data.*
+import org.matrix.android.sdk.internal.auth.login.LoginFlowParams
 import org.matrix.android.sdk.internal.auth.login.ResetPasswordMailConfirmed
 import org.matrix.android.sdk.internal.auth.registration.AddThreePidRegistrationParams
 import org.matrix.android.sdk.internal.auth.registration.AddThreePidRegistrationResponse
@@ -140,4 +141,7 @@ internal interface AuthAPI {
      */
     @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "account/password")
     suspend fun resetPasswordMailConfirmed(@Body params: ResetPasswordMailConfirmed)
+
+    @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "login")
+    suspend fun login(@Body loginFlowParams: LoginFlowParams): Credentials
 }
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/StageExtension.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/StageExtension.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4f34a37fb6b37a86d7495225d3d84670e9039a6b
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/StageExtension.kt
@@ -0,0 +1,14 @@
+package org.matrix.android.sdk.internal.auth
+
+import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
+import org.matrix.android.sdk.api.auth.registration.Stage
+
+//Added to support few registration flows
+fun List<Stage>.findStageForType(type: String): Stage? = when (type) {
+    LoginFlowTypes.RECAPTCHA      -> firstOrNull { it is Stage.ReCaptcha }
+    LoginFlowTypes.DUMMY          -> firstOrNull { it is Stage.Dummy }
+    LoginFlowTypes.TERMS          -> firstOrNull { it is Stage.Terms }
+    LoginFlowTypes.EMAIL_IDENTITY -> firstOrNull { it is Stage.Email }
+    LoginFlowTypes.MSISDN         -> firstOrNull { it is Stage.Msisdn }
+    else                          -> firstOrNull { (it as? Stage.Other)?.type == type }
+}
\ No newline at end of file
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 468e998407cac4e38d06ebf256221053cf0e80fd..e1b212f207d04e5cf4a28f8f4ba88193656cbe43 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,10 +17,16 @@
 package org.matrix.android.sdk.internal.auth.login
 
 import android.util.Patterns
+import kotlinx.coroutines.delay
 import org.matrix.android.sdk.api.auth.LoginType
+import org.matrix.android.sdk.api.auth.data.Credentials
 import org.matrix.android.sdk.api.auth.login.LoginProfileInfo
 import org.matrix.android.sdk.api.auth.login.LoginWizard
 import org.matrix.android.sdk.api.auth.registration.RegisterThreePid
+import org.matrix.android.sdk.api.auth.registration.RegistrationResult
+import org.matrix.android.sdk.api.auth.registration.Stage
+import org.matrix.android.sdk.api.auth.registration.toFlowResult
+import org.matrix.android.sdk.api.failure.Failure
 import org.matrix.android.sdk.api.session.Session
 import org.matrix.android.sdk.api.util.JsonDict
 import org.matrix.android.sdk.internal.auth.AuthAPI
@@ -30,8 +36,13 @@ import org.matrix.android.sdk.internal.auth.data.PasswordLoginParams
 import org.matrix.android.sdk.internal.auth.data.ThreePidMedium
 import org.matrix.android.sdk.internal.auth.data.TokenLoginParams
 import org.matrix.android.sdk.internal.auth.db.PendingSessionData
+import org.matrix.android.sdk.internal.auth.findStageForType
 import org.matrix.android.sdk.internal.auth.registration.AddThreePidRegistrationParams
+import org.matrix.android.sdk.internal.auth.registration.DefaultRegisterTask
 import org.matrix.android.sdk.internal.auth.registration.RegisterAddThreePidTask
+import org.matrix.android.sdk.internal.auth.registration.RegisterTask
+import org.matrix.android.sdk.internal.auth.registration.RegistrationCustomParams
+import org.matrix.android.sdk.internal.auth.registration.RegistrationParams
 import org.matrix.android.sdk.internal.network.executeRequest
 import org.matrix.android.sdk.internal.session.content.DefaultContentUrlResolver
 import org.matrix.android.sdk.internal.session.contentscanner.DisabledContentScannerService
@@ -49,6 +60,8 @@ internal class DefaultLoginWizard(
             DefaultContentUrlResolver(pendingSessionData.homeServerConnectionConfig, DisabledContentScannerService())
     )
 
+    private val loginFlowTask: LoginFlowTask = DefaultLoginFlowTask(authAPI)
+
     override suspend fun getProfileInfo(matrixId: String): LoginProfileInfo {
         return getProfileTask.execute(GetProfileTask.Params(matrixId))
     }
@@ -138,4 +151,71 @@ internal class DefaultLoginWizard(
         // Set to null?
         // resetPasswordData = null
     }
+
+    //Added to support few login flows
+    override suspend fun getAllLoginFlows(): List<List<Stage>> {
+        try {
+            loginFlowTask.execute(LoginFlowTask.Params(LoginFlowParams()))
+        } catch (exception: Throwable) {
+            return if (exception is Failure.RegistrationFlowError) {
+                pendingSessionData =
+                        pendingSessionData.copy(currentSession = exception.registrationFlowResponse.session)
+                                .also { pendingSessionStore.savePendingSessionData(it) }
+                val flowResponse = exception.registrationFlowResponse
+                val missingStages = flowResponse.toFlowResult().missingStages
+
+                val flowsWithStages = flowResponse.flows?.mapNotNull { it.stages }?.map { flow ->
+                    flow.mapNotNull { type -> missingStages.findStageForType(type) }
+                } ?: emptyList()
+
+                flowsWithStages
+            } else {
+                emptyList()
+            }
+        }
+        return emptyList()
+    }
+
+    //Added to support few login flows
+    override suspend fun loginStageCustom(
+            authParams: JsonDict
+    ): RegistrationResult {
+        val safeSession = pendingSessionData.currentSession
+                ?: throw IllegalStateException("developer error, call createAccount() method first")
+
+        val mutableParams = authParams.toMutableMap()
+        mutableParams["session"] = safeSession
+
+        val params = LoginFlowParams(auth = mutableParams)
+        return performRegistrationRequest(LoginType.CUSTOM, params)
+    }
+
+    private suspend fun performRegistrationRequest(
+            loginType: LoginType,
+            loginParams: LoginFlowParams
+    ): RegistrationResult {
+        return login(loginType) { loginFlowTask.execute(LoginFlowTask.Params(loginParams)) }
+    }
+
+    //Added to support few login flows
+    private suspend fun login(
+            loginType: LoginType,
+            execute: suspend () -> Credentials,
+    ): RegistrationResult {
+        val credentials = try {
+            execute.invoke()
+        } catch (exception: Throwable) {
+            if (exception is Failure.RegistrationFlowError) {
+                pendingSessionData =
+                        pendingSessionData.copy(currentSession = exception.registrationFlowResponse.session)
+                                .also { pendingSessionStore.savePendingSessionData(it) }
+                return RegistrationResult.FlowResponse(exception.registrationFlowResponse.toFlowResult())
+            } else {
+                throw exception
+            }
+        }
+
+        val session = sessionCreator.createSession(credentials, pendingSessionData.homeServerConnectionConfig, loginType)
+        return RegistrationResult.Success(session)
+    }
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/LoginFlowParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/LoginFlowParams.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3515b56eeae6ee366042e3566772b6df2ffde63c
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/LoginFlowParams.kt
@@ -0,0 +1,31 @@
+package org.matrix.android.sdk.internal.auth.login
+
+/*
+ * 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.
+ */
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+import org.matrix.android.sdk.api.util.JsonDict
+
+/**
+ * Class to pass parameters to the custom login types for /login.
+ */
+@JsonClass(generateAdapter = true)
+internal data class LoginFlowParams(
+        // authentication parameters
+        @Json(name = "auth")
+        val auth: JsonDict? = null
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/LoginFlowTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/LoginFlowTask.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c8ae22c936ae32f3f3fb7f7d572b1b63bc543571
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/LoginFlowTask.kt
@@ -0,0 +1,49 @@
+/*
+ * 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.auth.login
+
+import org.matrix.android.sdk.api.auth.data.Credentials
+import org.matrix.android.sdk.api.failure.Failure
+import org.matrix.android.sdk.api.failure.toRegistrationFlowResponse
+import org.matrix.android.sdk.internal.auth.AuthAPI
+import org.matrix.android.sdk.internal.auth.registration.RegisterTask
+import org.matrix.android.sdk.internal.auth.registration.RegistrationParams
+import org.matrix.android.sdk.internal.network.executeRequest
+import org.matrix.android.sdk.internal.task.Task
+
+internal interface LoginFlowTask : Task<LoginFlowTask.Params, Credentials> {
+    data class Params(
+            val loginParams: LoginFlowParams
+    )
+}
+
+internal class DefaultLoginFlowTask(
+        private val authAPI: AuthAPI
+) : LoginFlowTask {
+
+    override suspend fun execute(params: LoginFlowTask.Params): Credentials {
+        try {
+            return executeRequest(null) {
+                authAPI.login(params.loginParams)
+            }
+        } catch (throwable: Throwable) {
+            throw throwable.toRegistrationFlowResponse()
+                    ?.let { Failure.RegistrationFlowError(it) }
+                    ?: throwable
+        }
+    }
+}
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 63bf1b0a260819c0767ade9f5fb908e79ee5b841..8401db7fbb8d014ebf019952265ed227e38696ea 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
@@ -33,6 +33,7 @@ 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.auth.findStageForType
 
 /**
  * This class execute the registration request and is responsible to keep the session of interactive authentication.
@@ -295,16 +296,6 @@ internal class DefaultRegistrationWizard(
         return emptyList()
     }
 
-    //Added to support few registration flows
-    private fun List<Stage>.findStageForType(type: String): Stage? = when (type) {
-        LoginFlowTypes.RECAPTCHA      -> firstOrNull { it is Stage.ReCaptcha }
-        LoginFlowTypes.DUMMY          -> firstOrNull { it is Stage.Dummy }
-        LoginFlowTypes.TERMS          -> firstOrNull { it is Stage.Terms }
-        LoginFlowTypes.EMAIL_IDENTITY -> firstOrNull { it is Stage.Email }
-        LoginFlowTypes.MSISDN         -> firstOrNull { it is Stage.Msisdn }
-        else                          -> firstOrNull { (it as? Stage.Other)?.type == type }
-    }
-
     override suspend fun registrationSwiclops(
             authParams: JsonDict,
             userName: String?,