diff --git a/app/schemas/com.nextcloud.talk.newarch.local.db.TalkDatabase/1.json b/app/schemas/com.nextcloud.talk.newarch.local.db.TalkDatabase/1.json
index acfe41a3f..8aa661eec 100644
--- a/app/schemas/com.nextcloud.talk.newarch.local.db.TalkDatabase/1.json
+++ b/app/schemas/com.nextcloud.talk.newarch.local.db.TalkDatabase/1.json
@@ -2,7 +2,7 @@
   "formatVersion": 1,
   "database": {
     "version": 1,
-    "identityHash": "26585a95894baebb7d811a80f3811b85",
+    "identityHash": "0bb77d35d80f74e97eea4a5415d9a102",
     "entities": [
       {
         "tableName": "conversations",
@@ -15,7 +15,7 @@
             "notNull": true
           },
           {
-            "fieldPath": "user",
+            "fieldPath": "userId",
             "columnName": "user_id",
             "affinity": "INTEGER",
             "notNull": false
@@ -198,7 +198,7 @@
       },
       {
         "tableName": "messages",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `conversation_id` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `actor_id` TEXT, `actor_type` TEXT, `actor_display_name` TEXT, `timestamp` INTEGER NOT NULL, `message` TEXT, `system_message_type` TEXT, PRIMARY KEY(`id`), FOREIGN KEY(`conversation_id`) REFERENCES `conversations`(`id`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `conversation_id` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `actor_id` TEXT, `actor_type` TEXT, `actor_display_name` TEXT, `timestamp` INTEGER NOT NULL, `message` TEXT, `replyable` INTEGER NOT NULL, `system_message_type` TEXT, PRIMARY KEY(`id`), FOREIGN KEY(`conversation_id`) REFERENCES `conversations`(`id`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)",
         "fields": [
           {
             "fieldPath": "id",
@@ -207,7 +207,7 @@
             "notNull": true
           },
           {
-            "fieldPath": "conversation",
+            "fieldPath": "conversationId",
             "columnName": "conversation_id",
             "affinity": "TEXT",
             "notNull": true
@@ -248,6 +248,12 @@
             "affinity": "TEXT",
             "notNull": false
           },
+          {
+            "fieldPath": "replyable",
+            "columnName": "replyable",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
           {
             "fieldPath": "systemMessageType",
             "columnName": "system_message_type",
@@ -369,7 +375,7 @@
     "views": [],
     "setupQueries": [
       "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
-      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '26585a95894baebb7d811a80f3811b85')"
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '0bb77d35d80f74e97eea4a5415d9a102')"
     ]
   }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.kt b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.kt
index 92a44d7ba..5175e0a16 100644
--- a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.kt
+++ b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.kt
@@ -34,6 +34,7 @@ import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.conversations.Conversation
 import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.ONE_TO_ONE_CONVERSATION
 import com.nextcloud.talk.newarch.local.models.UserNgEntity
+import com.nextcloud.talk.newarch.local.models.getCredentials
 import com.nextcloud.talk.utils.ApiUtils
 import eu.davidea.flexibleadapter.FlexibleAdapter
 import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
@@ -67,14 +68,14 @@ class ConversationItem(
                     && model.unreadMention == comparedConversation.unreadMention
                     && model.objectType == comparedConversation.objectType
                     && model.changing == comparedConversation.changing
-                    && user.id == inItem.user.id)
+                    && inItem.user.id == other.user.id)
         }
         return false
     }
 
     override fun hashCode(): Int {
         return Objects.hash(
-                model.conversationId, model.token,
+                model.token,
                 user.id
         )
     }
@@ -245,6 +246,7 @@ class ConversationItem(
                                     model.name, R.dimen.avatar_size
                             )
                     ) {
+                        addHeader("Authorization", user.getCredentials())
                         transformations(CircleCropTransformation())
                     }
 
diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/MentionAutocompleteItem.kt b/app/src/main/java/com/nextcloud/talk/adapters/items/MentionAutocompleteItem.kt
index 4c43d36c5..7687ff923 100644
--- a/app/src/main/java/com/nextcloud/talk/adapters/items/MentionAutocompleteItem.kt
+++ b/app/src/main/java/com/nextcloud/talk/adapters/items/MentionAutocompleteItem.kt
@@ -27,6 +27,7 @@ import coil.transform.CircleCropTransformation
 import com.nextcloud.talk.R
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.newarch.local.models.UserNgEntity
+import com.nextcloud.talk.newarch.local.models.getCredentials
 import com.nextcloud.talk.utils.ApiUtils
 import eu.davidea.flexibleadapter.FlexibleAdapter
 import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
@@ -112,6 +113,7 @@ class MentionAutocompleteItem(
             }
 
             holder.avatarImageView!!.load(avatarUrl) {
+                addHeader("Authorization", currentUser.getCredentials())
                 transformations(CircleCropTransformation())
             }
         }
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.kt b/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.kt
index f178a4140..afe4747e1 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.kt
+++ b/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.kt
@@ -59,6 +59,7 @@ import com.nextcloud.talk.models.json.conversations.Conversation
 import com.nextcloud.talk.models.json.conversations.RoomsOverall
 import com.nextcloud.talk.models.json.participants.Participant
 import com.nextcloud.talk.models.json.participants.ParticipantsOverall
+import com.nextcloud.talk.newarch.utils.getCredentials
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.DoNotDisturbUtils
 import com.nextcloud.talk.utils.bundle.BundleKeys
@@ -393,6 +394,7 @@ class CallNotificationController(private val originalBundle: Bundle) : BaseContr
                                 currentConversation!!.name, R.dimen.avatar_size_very_big
                         )
                 ) {
+                    addHeader("Authorization", userBeingCalled.getCredentials())
                     transformations(CircleCropTransformation())
                     listener(onSuccess = { data, dataSource ->
                         GlobalScope.launch {
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt
index ab2ae2c2b..b72ef9f62 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt
+++ b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt
@@ -105,7 +105,6 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
 .OnMessageLongClickListener<IMessage>, MessageHolders.ContentChecker<IMessage> {
 
     val ncApi: NcApi by inject()
-    val userUtils: UserUtils by inject()
 
     @BindView(R.id.messagesListView)
     @JvmField
@@ -306,7 +305,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
                         imageLoader, context, ApiUtils.getUrlForAvatarWithNameAndPixels(
                         conversationUser?.baseUrl,
                         currentConversation?.name, avatarSize / 2
-                ), null, target, null,
+                ), conversationUser, target, null,
                         CircleCropTransformation()
                 )
 
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt
index 0f1284c88..8a79ed2dd 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt
+++ b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt
@@ -256,10 +256,10 @@ class SettingsController : BaseController() {
     }
 
     private fun removeCurrentAccount() {
-        val user = usersRepository.getActiveUser()
-        user!!.status = UserStatus.PENDING_DELETE
         GlobalScope.launch {
             val job = async {
+                val user = usersRepository.getActiveUser()
+                user!!.status = UserStatus.PENDING_DELETE
                 usersRepository.updateUser(user)
                 val accountRemovalWork = OneTimeWorkRequest.Builder(AccountRemovalWorker::class.java)
                         .build()
@@ -274,13 +274,14 @@ class SettingsController : BaseController() {
                     onAttach(view!!)
                 }
             } else {
-                router.setRoot(RouterTransaction.with(
-                        ServerSelectionController()
-                )
-                        .pushChangeHandler(VerticalChangeHandler())
-                        .popChangeHandler(VerticalChangeHandler())
-                )
-
+                withContext(Dispatchers.Main) {
+                    router.setRoot(RouterTransaction.with(
+                            ServerSelectionController()
+                    )
+                            .pushChangeHandler(VerticalChangeHandler())
+                            .popChangeHandler(VerticalChangeHandler())
+                    )
+                }
             }
         }
     }
@@ -293,7 +294,7 @@ class SettingsController : BaseController() {
         }
 
         GlobalScope.launch {
-            var hasMultipleUsers: Boolean = false
+            var hasMultipleUsers = false
             val job = async {
                 currentUser = usersRepository.getActiveUser()
                 hasMultipleUsers = usersRepository.getUsers().size > 0
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/SwitchAccountController.kt b/app/src/main/java/com/nextcloud/talk/controllers/SwitchAccountController.kt
index 7bdda773e..1b59def44 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/SwitchAccountController.kt
+++ b/app/src/main/java/com/nextcloud/talk/controllers/SwitchAccountController.kt
@@ -37,12 +37,21 @@ import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
 import com.nextcloud.talk.R
 import com.nextcloud.talk.adapters.items.AdvancedUserItem
 import com.nextcloud.talk.controllers.base.BaseController
+import com.nextcloud.talk.models.ImportAccount
+import com.nextcloud.talk.models.json.participants.Participant
+import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
+import com.nextcloud.talk.newarch.local.models.UserNgEntity
+import com.nextcloud.talk.newarch.local.models.other.UserStatus
 import com.nextcloud.talk.utils.AccountUtils
 import com.nextcloud.talk.utils.bundle.BundleKeys
 import com.nextcloud.talk.utils.database.user.UserUtils
 import eu.davidea.flexibleadapter.FlexibleAdapter
 import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
 import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 import org.koin.android.ext.android.inject
 import java.net.CookieManager
 import java.util.*
@@ -53,7 +62,7 @@ class SwitchAccountController : BaseController {
     internal var recyclerView: RecyclerView? = null
 
     val cookieManager: CookieManager by inject()
-    val userUtils: UserUtils by inject()
+    val usersRepository: UsersRepository by inject()
 
     @JvmField
     @BindView(R.id.swipe_refresh_layout)
@@ -75,30 +84,13 @@ class SwitchAccountController : BaseController {
     private val onSwitchItemClickListener = FlexibleAdapter.OnItemClickListener { view, position ->
         if (userItems.size > position) {
             val userEntity = (userItems[position] as AdvancedUserItem).entity
-            /*userUtils!!.createOrUpdateUser(null, null, null, null, null, true, null, userEntity!!.getId(), null, null, null)
-                    .`as`(AutoDispose.autoDisposable<Any>(scopeProvider))
-                    .subscribe(object : Observer<UserEntity> {
-                        override fun onSubscribe(d: Disposable) {
-
-                        }
-
-                        override fun onNext(userEntity: UserEntity) {
-                            cookieManager!!.cookieStore.removeAll()
-
-                            userUtils!!.disableAllUsersWithoutId(userEntity.getId())
-                            if (activity != null) {
-                                activity!!.runOnUiThread { router.popCurrentController() }
-                            }
-                        }
-
-                        override fun onError(e: Throwable) {
-
-                        }
-
-                        override fun onComplete() {
-
-                        }
-                    })*/
+            GlobalScope.launch {
+                usersRepository.setUserAsActiveWithId(userEntity!!.id!!)
+                cookieManager.cookieStore.removeAll()
+                withContext(Dispatchers.Main) {
+                    router.popCurrentController()
+                }
+            }
         }
 
         true
@@ -130,7 +122,69 @@ class SwitchAccountController : BaseController {
         return inflater.inflate(R.layout.controller_generic_rv, container, false)
     }
 
-    override fun onViewBound(view: View) {
+    override fun onCreateView(
+            inflater: LayoutInflater,
+            container: ViewGroup
+    ): View {
+        swipeRefreshLayout?.isEnabled = false
+        actionBar?.show()
+
+        adapter = FlexibleAdapter(userItems, activity, false)
+        GlobalScope.launch {
+            val users = usersRepository.getUsers()
+            var userEntity: UserNgEntity
+            var participant: Participant
+
+            if (isAccountImport) {
+                var account: Account
+                var importAccount: ImportAccount
+                for (accountObject in AccountUtils.findAccounts(users)) {
+                    account = accountObject
+                    importAccount = AccountUtils.getInformationFromAccount(account)
+
+                    participant = Participant()
+                    participant.name = importAccount.username
+                    participant.userId = importAccount.username
+                    userEntity = UserNgEntity(-1, "!", "!", importAccount.baseUrl)
+                    userItems.add(AdvancedUserItem(participant, userEntity, account))
+                }
+
+                adapter!!.addListener(onImportItemClickListener)
+                withContext(Dispatchers.Main) {
+                    adapter!!.updateDataSet(userItems, false)
+                }
+
+
+            } else {
+                for (userEntityObject in users) {
+                    userEntity = userEntityObject
+                    if (userEntity.status != UserStatus.ACTIVE) {
+                        participant = Participant()
+                        participant.name = userEntity.displayName
+
+                        val userId: String
+
+                        if (userEntity.userId != null) {
+                            userId = userEntity.userId
+                        } else {
+                            userId = userEntity.username
+                        }
+                        participant.userId = userId
+                        userItems.add(AdvancedUserItem(participant, userEntity, null))
+                    }
+                }
+
+                adapter!!.addListener(onSwitchItemClickListener)
+                withContext(Dispatchers.Main) {
+                    adapter!!.updateDataSet(userItems, false)
+                }
+
+            }
+
+        }
+        return super.onCreateView(inflater, container)
+    }
+        override fun onViewBound(view: View) {
         super.onViewBound(view)
         swipeRefreshLayout!!.isEnabled = false
 
diff --git a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt
index 8b194963b..3e1c927e1 100644
--- a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt
+++ b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt
@@ -486,7 +486,7 @@ class NotificationWorker(
                 }
 
                 val request = Images().getRequestForUrl(
-                        Coil.loader(), context!!, avatarUrl!!, null,
+                        Coil.loader(), context!!, avatarUrl!!, signatureVerification!!.userEntity,
                         target, null, CircleCropTransformation()
                 )
 
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.java b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.java
index 7e691d61a..1db353524 100644
--- a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.java
+++ b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.java
@@ -44,6 +44,7 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 import lombok.Data;
 
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt b/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt
index ded1fca50..c89382bb5 100644
--- a/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt
+++ b/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt
@@ -29,6 +29,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.converters.*
 import com.nextcloud.talk.models.json.participants.Participant
+import com.nextcloud.talk.newarch.local.models.ConversationEntity
 import com.nextcloud.talk.newarch.local.models.UserNgEntity
 import lombok.Data
 import org.parceler.Parcel
@@ -42,8 +43,6 @@ class Conversation {
     @JsonIgnore
     @NonNull
     var internalUserId: Long? = null
-    @JsonIgnore
-    var internalId: Long? = null
     @JsonField(name = ["id"])
     var conversationId: String? = null
     @JsonField(name = ["token"])
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/data/repository/offline/ConversationsRepositoryImpl.kt b/app/src/main/java/com/nextcloud/talk/newarch/data/repository/offline/ConversationsRepositoryImpl.kt
index 4626fd5cf..3b0719125 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/data/repository/offline/ConversationsRepositoryImpl.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/data/repository/offline/ConversationsRepositoryImpl.kt
@@ -20,9 +20,7 @@
 
 package com.nextcloud.talk.newarch.data.repository.offline
 
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.Transformations
-import androidx.lifecycle.map
+import androidx.lifecycle.*
 import com.nextcloud.talk.models.json.conversations.Conversation
 import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
 import com.nextcloud.talk.newarch.local.dao.ConversationsDao
@@ -58,14 +56,11 @@ class ConversationsRepositoryImpl(val conversationsDao: ConversationsDao) :
     }
 
     override fun getConversationsForUser(userId: Long): LiveData<List<Conversation>> {
-        return Transformations.distinctUntilChanged(conversationsDao
-                .getConversationsForUser(userId)
-                .map { data ->
-                    data.map {
-                        it.toConversation()
-                    }
-                }
-        )
+        return conversationsDao.getConversationsForUser(userId).distinctUntilChanged().map { data ->
+            data.map {
+                it.toConversation()
+            }
+        }
     }
 
     override suspend fun getConversationForUserWithToken(userId: Long, token: String): Conversation? {
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/data/repository/offline/UsersRepositoryImpl.kt b/app/src/main/java/com/nextcloud/talk/newarch/data/repository/offline/UsersRepositoryImpl.kt
index 0a85a0ae2..b2285eea6 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/data/repository/offline/UsersRepositoryImpl.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/data/repository/offline/UsersRepositoryImpl.kt
@@ -21,13 +21,15 @@
 package com.nextcloud.talk.newarch.data.repository.offline
 
 import androidx.lifecycle.LiveData
+import androidx.lifecycle.Transformations
+import androidx.lifecycle.distinctUntilChanged
 import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
 import com.nextcloud.talk.newarch.local.dao.UsersDao
 import com.nextcloud.talk.newarch.local.models.UserNgEntity
 
-class UsersRepositoryImpl(val usersDao: UsersDao) : UsersRepository {
+class UsersRepositoryImpl(private val usersDao: UsersDao) : UsersRepository {
     override fun getActiveUserLiveData(): LiveData<UserNgEntity> {
-        return usersDao.getActiveUserLiveData()
+        return usersDao.getActiveUserLiveData().distinctUntilChanged()
     }
 
     override fun getActiveUser(): UserNgEntity {
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/data/repository/online/NextcloudTalkRepositoryImpl.kt b/app/src/main/java/com/nextcloud/talk/newarch/data/repository/online/NextcloudTalkRepositoryImpl.kt
index c7e9d8944..c3f1c6350 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/data/repository/online/NextcloudTalkRepositoryImpl.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/data/repository/online/NextcloudTalkRepositoryImpl.kt
@@ -55,18 +55,26 @@ class NextcloudTalkRepositoryImpl(private val apiService: ApiService) : Nextclou
         return apiService.getConversation(userEntity.getCredentials(), conversationToken)
     }
 
+    override suspend fun joinConversationForUser(userNgEntity: UserNgEntity, conversationToken: String, conversationPassword: String?): RoomOverall {
+        return apiService.joinConversation(userNgEntity.getCredentials(), ApiUtils.getUrlForSettingMyselfAsActiveParticipant(userNgEntity.baseUrl, conversationToken), conversationPassword)
+    }
+
+    override suspend fun exitConversationForUser(userNgEntity: UserNgEntity, conversationToken: String): GenericOverall {
+        return apiService.exitConversation(userNgEntity.getCredentials(), ApiUtils.getUrlForSettingMyselfAsActiveParticipant(userNgEntity.baseUrl, conversationToken))
+    }
+
     override suspend fun setFavoriteValueForConversation(
             user: UserNgEntity,
             conversation: Conversation,
             favorite: Boolean
     ): GenericOverall {
-        if (favorite) {
-            return apiService.addConversationToFavorites(
+        return if (favorite) {
+            apiService.addConversationToFavorites(
                     user.getCredentials(),
                     ApiUtils.getUrlForConversationFavorites(user.baseUrl, conversation.token)
             )
         } else {
-            return apiService.removeConversationFromFavorites(
+            apiService.removeConversationFromFavorites(
                     user.getCredentials(),
                     ApiUtils.getUrlForConversationFavorites(user.baseUrl, conversation.token)
             )
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/data/source/remote/ApiService.kt b/app/src/main/java/com/nextcloud/talk/newarch/data/source/remote/ApiService.kt
index ade26c6af..58ddd8d1e 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/data/source/remote/ApiService.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/data/source/remote/ApiService.kt
@@ -23,6 +23,7 @@ package com.nextcloud.talk.newarch.data.source.remote
 import com.nextcloud.talk.models.json.conversations.RoomOverall
 import com.nextcloud.talk.models.json.conversations.RoomsOverall
 import com.nextcloud.talk.models.json.generic.GenericOverall
+import io.reactivex.Observable
 import retrofit2.http.*
 
 interface ApiService {
@@ -63,4 +64,14 @@ interface ApiService {
 
     @GET
     suspend fun getConversation(@Header("Authorization") authorization: String, @Url url: String): RoomOverall
+
+    @FormUrlEncoded
+    @POST
+    suspend fun joinConversation(@Header("Authorization") authorization: String,
+                          @Url url: String, @Field("password") password: String?): RoomOverall
+
+    @DELETE
+    suspend fun exitConversation(@Header("Authorization") authorization: String,
+                           @Url url: String): GenericOverall
+
 }
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/domain/repository/online/NextcloudTalkRepository.kt b/app/src/main/java/com/nextcloud/talk/newarch/domain/repository/online/NextcloudTalkRepository.kt
index 6b62830d4..d33a1342a 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/domain/repository/online/NextcloudTalkRepository.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/domain/repository/online/NextcloudTalkRepository.kt
@@ -47,4 +47,15 @@ interface NextcloudTalkRepository {
             userEntity: UserNgEntity,
             conversationToken: String
     ): RoomOverall
+
+    suspend fun joinConversationForUser(
+            userNgEntity: UserNgEntity,
+            conversationToken: String,
+            conversationPassword: String?
+    ): RoomOverall
+
+    suspend fun exitConversationForUser(
+            userNgEntity: UserNgEntity,
+            conversationToken: String
+    ): GenericOverall
 }
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/domain/usecases/ExitConversationUseCase.kt b/app/src/main/java/com/nextcloud/talk/newarch/domain/usecases/ExitConversationUseCase.kt
new file mode 100644
index 000000000..2cb0bcbd1
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/newarch/domain/usecases/ExitConversationUseCase.kt
@@ -0,0 +1,40 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.newarch.domain.usecases
+
+import com.nextcloud.talk.models.json.generic.GenericOverall
+import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
+import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
+import com.nextcloud.talk.newarch.domain.usecases.base.UseCase
+import org.koin.core.parameter.DefinitionParameters
+
+class ExitConversationUseCase constructor(
+        private val nextcloudTalkRepository: NextcloudTalkRepository,
+        apiErrorHandler: ApiErrorHandler?
+) : UseCase<GenericOverall, Any?>(apiErrorHandler) {
+
+    override suspend fun run(params: Any?): GenericOverall {
+        val definitionParameters = params as DefinitionParameters
+        return nextcloudTalkRepository.exitConversationForUser(
+                definitionParameters[0],
+                definitionParameters[1])
+    }
+}
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/domain/usecases/JoinConversationUseCase.kt b/app/src/main/java/com/nextcloud/talk/newarch/domain/usecases/JoinConversationUseCase.kt
new file mode 100644
index 000000000..727c137ea
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/newarch/domain/usecases/JoinConversationUseCase.kt
@@ -0,0 +1,42 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.newarch.domain.usecases
+
+import com.nextcloud.talk.models.json.conversations.RoomOverall
+import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
+import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
+import com.nextcloud.talk.newarch.domain.usecases.base.UseCase
+import org.koin.core.parameter.DefinitionParameters
+
+class JoinConversationUseCase constructor(
+        private val nextcloudTalkRepository: NextcloudTalkRepository,
+        apiErrorHandler: ApiErrorHandler?
+) : UseCase<RoomOverall, Any?>(apiErrorHandler) {
+
+    override suspend fun run(params: Any?): RoomOverall {
+        val definitionParameters = params as DefinitionParameters
+        return nextcloudTalkRepository.joinConversationForUser(
+                definitionParameters[0],
+                definitionParameters[1],
+                definitionParameters[2]
+        )
+    }
+}
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatView.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatView.kt
index d238b7952..c95057bd1 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatView.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatView.kt
@@ -355,7 +355,8 @@ class ChatView : BaseView(), MessageHolders.ContentChecker<IMessage>, MessagesLi
                     }
                 }
 
-                if (url.startsWith(viewModel.user.baseUrl) && url.contains("index.php/core/preview?fileId=")) {
+                val needsAuthBasedOnUrl = url.contains("index.php/core/preview?fileId=") || url.contains("index.php/avatar/")
+                if (url.startsWith(viewModel.user.baseUrl) && needsAuthBasedOnUrl) {
                     addHeader("Authorization", viewModel.user.getCredentials())
 
                 }
@@ -384,7 +385,7 @@ class ChatView : BaseView(), MessageHolders.ContentChecker<IMessage>, MessagesLi
                         imageLoader, context, ApiUtils.getUrlForAvatarWithNameAndPixels(
                         viewModel.user.baseUrl,
                         it.name, avatarSize / 2
-                ), null, target, this,
+                ), viewModel.user, target, this,
                         CircleCropTransformation()
                 )
 
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModel.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModel.kt
index fca682c01..682f209cf 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModel.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModel.kt
@@ -2,16 +2,37 @@ package com.nextcloud.talk.newarch.features.chat
 
 import android.app.Application
 import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.Transformations
 import androidx.lifecycle.viewModelScope
+import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.conversations.Conversation
+import com.nextcloud.talk.models.json.conversations.RoomOverall
+import com.nextcloud.talk.models.json.generic.GenericOverall
 import com.nextcloud.talk.newarch.conversationsList.mvp.BaseViewModel
+import com.nextcloud.talk.newarch.data.model.ErrorModel
 import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
+import com.nextcloud.talk.newarch.domain.repository.offline.MessagesRepository
+import com.nextcloud.talk.newarch.domain.usecases.ExitConversationUseCase
+import com.nextcloud.talk.newarch.domain.usecases.JoinConversationUseCase
+import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
+import com.nextcloud.talk.newarch.features.conversationsList.ConversationsListViewState
+import com.nextcloud.talk.newarch.local.models.MessageEntity
 import com.nextcloud.talk.newarch.local.models.UserNgEntity
 import kotlinx.coroutines.launch
+import org.koin.core.parameter.parametersOf
 
-class ChatViewModel constructor(application: Application, private val conversationsRepository: ConversationsRepository) : BaseViewModel<ChatView>(application) {
+class ChatViewModel constructor(application: Application,
+                                private val joinConversationUseCase: JoinConversationUseCase,
+                                private val exitConversationUseCase: ExitConversationUseCase,
+                                private val conversationsRepository: ConversationsRepository,
+                                private val messagesRepository: MessagesRepository) : BaseViewModel<ChatView>(application) {
     lateinit var user: UserNgEntity
     val conversation: MutableLiveData<Conversation?> = MutableLiveData()
+    val messagesLiveData = Transformations.switchMap(conversation) {
+        it?.let {
+            messagesRepository.getMessagesWithUserForConversation(it.conversationId!!)
+        }
+    }
     var conversationPassword: String? = null
 
 
@@ -23,6 +44,38 @@ class ChatViewModel constructor(application: Application, private val conversati
         }
     }
 
+    suspend fun joinConversation() {
+        joinConversationUseCase.invoke(viewModelScope, parametersOf(
+                user,
+                conversation.value!!.token,
+                conversationPassword
+        ),
+                object : UseCaseResponse<RoomOverall> {
+                    override suspend fun onSuccess(result: RoomOverall) {
+                        conversationsRepository.saveConversationsForUser(user.id!!, listOf(result.ocs.data))
+                    }
+
+                    override fun onError(errorModel: ErrorModel?) {
+                        // what do we do on error
+                    }
+                })
+    }
+
+    suspend fun exitConversation() {
+        exitConversationUseCase.invoke(backgroundScope, parametersOf(
+                user,
+                conversation.value!!.token
+        ),
+                object : UseCaseResponse<GenericOverall> {
+                    override suspend fun onSuccess(result: GenericOverall) {
+                    }
+
+                    override fun onError(errorModel: ErrorModel?) {
+                        // what do we do on error
+                    }
+                })
+    }
+
     fun sendMessage(message: CharSequence) {
 
     }
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModelFactory.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModelFactory.kt
index 6de298fbd..333ea41b2 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModelFactory.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/features/chat/ChatViewModelFactory.kt
@@ -4,15 +4,21 @@ import android.app.Application
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
 import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
+import com.nextcloud.talk.newarch.domain.repository.offline.MessagesRepository
+import com.nextcloud.talk.newarch.domain.usecases.ExitConversationUseCase
+import com.nextcloud.talk.newarch.domain.usecases.JoinConversationUseCase
 
 class ChatViewModelFactory constructor(
         private val application: Application,
-        private val conversationsRepository: ConversationsRepository
+        private val joinConversationUseCase: JoinConversationUseCase,
+        private val exitConversationUseCase: ExitConversationUseCase,
+        private val conversationsRepository: ConversationsRepository,
+        private val messagesRepository: MessagesRepository
 ) : ViewModelProvider.Factory {
 
     override fun <T : ViewModel?> create(modelClass: Class<T>): T {
         return ChatViewModel(
-                application, conversationsRepository
+                application, joinConversationUseCase, exitConversationUseCase, conversationsRepository, messagesRepository
         ) as T
     }
 }
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt
index 14f267795..95fe9740d 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt
@@ -26,12 +26,15 @@ import android.graphics.drawable.Drawable
 import android.os.Build
 import android.os.Bundle
 import android.text.InputType
+import android.util.Log
 import android.view.*
 import android.view.inputmethod.EditorInfo
 import androidx.appcompat.widget.SearchView
 import androidx.appcompat.widget.SearchView.OnQueryTextListener
 import androidx.core.view.MenuItemCompat
+import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.Observer
+import androidx.lifecycle.distinctUntilChanged
 import androidx.recyclerview.widget.RecyclerView.ViewHolder
 import butterknife.OnClick
 import coil.ImageLoader
@@ -74,11 +77,12 @@ import java.util.*
 class ConversationsListView : BaseView(), OnQueryTextListener,
         OnItemClickListener, OnItemLongClickListener {
 
-    lateinit var viewModel: ConversationsListViewModel
+    private lateinit var viewModel: ConversationsListViewModel
     val factory: ConversationListViewModelFactory by inject()
-    val imageLoader: ImageLoader by inject()
+    private val imageLoader: ImageLoader by inject()
+    private val viewState: MutableLiveData<ConversationsListViewState> = MutableLiveData(LOADING)
 
-    private val recyclerViewAdapter = FlexibleAdapter(mutableListOf(), null, true)
+    private val recyclerViewAdapter = FlexibleAdapter(mutableListOf(), null, false)
 
     private var searchItem: MenuItem? = null
     private var settingsItem: MenuItem? = null
@@ -178,9 +182,12 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
         searchView!!.imeOptions = imeOptions
         searchView!!.queryHint = resources?.getString(R.string.nc_search)
         searchView!!.setSearchableInfo(searchManager.getSearchableInfo(activity!!.componentName))
-
         searchView!!.setOnQueryTextListener(this)
+    }
 
+    override fun onRestoreViewState(view: View, savedViewState: Bundle) {
+        super.onRestoreViewState(view, savedViewState)
+        viewModel.loadConversations()
     }
 
     override fun onQueryTextSubmit(query: String?): Boolean {
@@ -208,71 +215,15 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
                 loadAvatar()
             })
 
-            viewState.observe(this@ConversationsListView, Observer { value ->
-                when (value) {
-                    LOADING -> {
-                        view?.swipeRefreshLayoutView?.isEnabled = false
-                        view?.loadingStateView?.visibility = View.VISIBLE
-                        view?.stateWithMessageView?.visibility = View.GONE
-                        view?.dataStateView?.visibility = View.GONE
-                        view?.floatingActionButton?.visibility = View.GONE
-                        searchItem?.isVisible = false
-                    }
-                    LOADED -> {
-                        view?.swipeRefreshLayoutView?.isEnabled = true
-                        view?.swipeRefreshLayoutView?.post {
-                            view?.swipeRefreshLayoutView?.isRefreshing = false
-                        }
-                        view?.loadingStateView?.visibility = View.GONE
-                        view?.stateWithMessageView?.visibility = View.GONE
-                        view?.dataStateView?.visibility = View.VISIBLE
-                        view?.floatingActionButton?.visibility = View.VISIBLE
-                        searchItem?.isVisible = true
-                    }
-                    LOADED_EMPTY, FAILED -> {
-                        view?.swipeRefreshLayoutView?.post {
-                            view?.swipeRefreshLayoutView?.isRefreshing = false
-                        }
-                        view?.swipeRefreshLayoutView?.isEnabled = true
-                        view?.loadingStateView?.visibility = View.GONE
-                        view?.dataStateView?.visibility = View.GONE
-                        searchItem?.isVisible = false
-
-                        if (value.equals(FAILED)) {
-                            view?.stateWithMessageView?.errorStateTextView?.text = messageData
-                            if (messageData.equals(
-                                            context.resources.getString(R.string.nc_no_connection_error)
-                                    )
-                            ) {
-                                view?.stateWithMessageView?.errorStateImageView?.setImageResource(
-                                        drawable.ic_signal_wifi_off_white_24dp
-                                )
-                            } else {
-                                view?.stateWithMessageView?.errorStateImageView?.setImageResource(
-                                        drawable.ic_announcement_white_24dp
-                                )
-                            }
-                            view?.floatingActionButton?.visibility = View.GONE
-                        } else {
-                            view?.floatingActionButton?.visibility = View.VISIBLE
-                            view?.stateWithMessageView?.errorStateTextView?.text =
-                                    resources?.getText(R.string.nc_conversations_empty)
-                            view?.stateWithMessageView?.errorStateImageView?.setImageResource(drawable.ic_logo)
-                        }
-
-                        view?.stateWithMessageView?.visibility = View.VISIBLE
-                    }
-                    else -> {
-                        // We should not be here
-                    }
-                }
-            })
-
             conversationsLiveData.observe(this@ConversationsListView, Observer {
                 if (it.isEmpty()) {
-                    viewState.value = LOADED_EMPTY
+                    if (viewState.value != LOADED_EMPTY) {
+                        viewState.value = LOADED_EMPTY
+                    }
                 } else {
-                    viewState.value = LOADED
+                    if (viewState.value != LOADED) {
+                        viewState.value = LOADED
+                    }
                 }
 
                 val newConversations = mutableListOf<ConversationItem>()
@@ -297,6 +248,67 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
             })
         }
 
+        viewState.observe(this@ConversationsListView, Observer { value ->
+            when (value) {
+                LOADING -> {
+                    view?.swipeRefreshLayoutView?.isEnabled = false
+                    view?.loadingStateView?.visibility = View.VISIBLE
+                    view?.stateWithMessageView?.visibility = View.GONE
+                    view?.dataStateView?.visibility = View.GONE
+                    view?.floatingActionButton?.visibility = View.GONE
+                    searchItem?.isVisible = false
+                }
+                LOADED -> {
+                    view?.swipeRefreshLayoutView?.isEnabled = true
+                    view?.swipeRefreshLayoutView?.post {
+                        view?.swipeRefreshLayoutView?.isRefreshing = false
+                    }
+                    view?.loadingStateView?.visibility = View.GONE
+                    view?.stateWithMessageView?.visibility = View.GONE
+                    view?.dataStateView?.visibility = View.VISIBLE
+                    view?.floatingActionButton?.visibility = View.VISIBLE
+                    searchItem?.isVisible = true
+                }
+                LOADED_EMPTY, FAILED -> {
+                    view?.swipeRefreshLayoutView?.post {
+                        view?.swipeRefreshLayoutView?.isRefreshing = false
+                    }
+                    view?.swipeRefreshLayoutView?.isEnabled = true
+                    view?.loadingStateView?.visibility = View.GONE
+                    view?.dataStateView?.visibility = View.GONE
+                    searchItem?.isVisible = false
+
+                    if (value.equals(FAILED)) {
+                        view?.stateWithMessageView?.errorStateTextView?.text = viewModel.messageData
+                        if (viewModel.messageData.equals(
+                                        context.resources.getString(R.string.nc_no_connection_error)
+                                )
+                        ) {
+                            view?.stateWithMessageView?.errorStateImageView?.setImageResource(
+                                    drawable.ic_signal_wifi_off_white_24dp
+                            )
+                        } else {
+                            view?.stateWithMessageView?.errorStateImageView?.setImageResource(
+                                    drawable.ic_announcement_white_24dp
+                            )
+                        }
+                        view?.floatingActionButton?.visibility = View.GONE
+                    } else {
+                        view?.floatingActionButton?.visibility = View.VISIBLE
+                        view?.stateWithMessageView?.errorStateTextView?.text =
+                                resources?.getText(R.string.nc_conversations_empty)
+                        view?.stateWithMessageView?.errorStateImageView?.setImageResource(drawable.ic_logo)
+                    }
+
+                    view?.stateWithMessageView?.visibility = View.VISIBLE
+                }
+                else -> {
+                    // We should not be here
+                }
+            }
+        })
+
+
         return super.onCreateView(inflater, container)
     }
 
@@ -311,7 +323,7 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
 
     @OnClick(R.id.stateWithMessageView)
     fun onStateWithMessageViewClick() {
-        if (viewModel.viewState.equals(LOADED_EMPTY)) {
+        if (viewState.value!! == LOADED_EMPTY) {
             openNewConversationScreen()
         }
     }
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt
index 3e4889b2d..f8096e2ef 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt
@@ -41,7 +41,6 @@ import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase
 import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase
 import com.nextcloud.talk.newarch.domain.usecases.SetConversationFavoriteValueUseCase
 import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
-import com.nextcloud.talk.newarch.features.conversationsList.ConversationsListViewState.LOADING
 import com.nextcloud.talk.newarch.local.models.UserNgEntity
 import com.nextcloud.talk.utils.ShareUtils
 import kotlinx.coroutines.launch
@@ -57,14 +56,11 @@ class ConversationsListViewModel constructor(
         usersRepository: UsersRepository
 ) : BaseViewModel<ConversationsListView>(application) {
 
-    val viewState = MutableLiveData(LOADING)
     var messageData: String? = null
     val searchQuery = MutableLiveData<String>()
     val currentUserLiveData: LiveData<UserNgEntity> = usersRepository.getActiveUserLiveData()
     val conversationsLiveData = Transformations.switchMap(currentUserLiveData) {
-        if (viewState.value != LOADING) {
-            viewState.value = LOADING
-        }
+        loadConversations()
         conversationsRepository.getConversationsForUser(it.id!!)
     }
 
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewState.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewState.kt
index aefa288e7..4bd9f7029 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewState.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewState.kt
@@ -21,6 +21,7 @@
 package com.nextcloud.talk.newarch.features.conversationsList
 
 enum class ConversationsListViewState {
+    INITIAL_LOAD,
     LOADING,
     LOADED_EMPTY,
     LOADED,
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt
index 740d93d91..458d0e5fb 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt
@@ -20,6 +20,7 @@
 
 package com.nextcloud.talk.newarch.local.models
 
+import android.util.Log
 import androidx.room.*
 import androidx.room.ForeignKey.CASCADE
 import com.nextcloud.talk.models.json.chat.ChatMessage
@@ -42,7 +43,7 @@ import java.util.*
 )
 data class ConversationEntity(
         @PrimaryKey @ColumnInfo(name = "id") var id: String,
-        @ColumnInfo(name = "user_id") var user: Long? = null,
+        @ColumnInfo(name = "user_id") var userId: Long? = null,
         @ColumnInfo(name = "conversation_id") var conversationId: String? = null,
         @ColumnInfo(name = "token") var token: String? = null,
         @ColumnInfo(name = "name") var name: String? = null,
@@ -74,11 +75,52 @@ data class ConversationEntity(
         @ColumnInfo(name = "last_read_message") var lastReadMessageId: Long = 0,
         @ColumnInfo(name = "modified_at") var modifiedAt: Long? = null,
         @ColumnInfo(name = "changing") var changing: Boolean = false
-)
+) {
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (javaClass != other?.javaClass) return false
+
+        other as ConversationEntity
+
+        if (id != other.id) return false
+        if (userId != other.userId) return false
+        if (conversationId != other.conversationId) return false
+        if (token != other.token) return false
+        if (name != other.name) return false
+        if (displayName != other.displayName) return false
+        if (type != other.type) return false
+        if (count != other.count) return false
+        if (numberOfGuests != other.numberOfGuests) return false
+        if (participantsCount != other.participantsCount) return false
+        if (participantType != other.participantType) return false
+        if (hasPassword != other.hasPassword) return false
+        if (sessionId != other.sessionId) return false
+        if (favorite != other.favorite) return false
+        if (lastActivity != other.lastActivity) return false
+        if (unreadMessages != other.unreadMessages) return false
+        if (unreadMention != other.unreadMention) return false
+        if (lastMessage?.internalMessageId != other.lastMessage?.internalMessageId) return false
+        if (objectType != other.objectType) return false
+        if (notificationLevel != other.notificationLevel) return false
+        if (conversationReadOnlyState != other.conversationReadOnlyState) return false
+        if (lobbyState != other.lobbyState) return false
+        if (lobbyTimer != other.lobbyTimer) return false
+        if (lastReadMessageId != other.lastReadMessageId) return false
+        if (changing != other.changing) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = userId?.hashCode() ?: 0
+        result = 31 * result + (token?.hashCode() ?: 0)
+        return result
+    }
+}
 
 fun ConversationEntity.toConversation(): Conversation {
     val conversation = Conversation()
-    conversation.internalUserId = this.user
+    conversation.internalUserId = this.userId
     conversation.conversationId = this.conversationId
     conversation.type = this.type
     conversation.token = this.token
@@ -111,7 +153,7 @@ fun ConversationEntity.toConversation(): Conversation {
 
 fun Conversation.toConversationEntity(): ConversationEntity {
     val conversationEntity = ConversationEntity(this.internalUserId.toString() + "@" + this.token)
-    conversationEntity.user = this.internalUserId
+    conversationEntity.userId = this.internalUserId
     conversationEntity.conversationId = this.conversationId
     conversationEntity.token = this.token
     conversationEntity.name = this.name
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/models/MessageEntity.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/models/MessageEntity.kt
index f24a5bdce..2b0f65656 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/local/models/MessageEntity.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/local/models/MessageEntity.kt
@@ -39,7 +39,7 @@ import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType
 )
 data class MessageEntity(
         @PrimaryKey @ColumnInfo(name = "id") var id: String,
-        @ColumnInfo(name = "conversation_id") var conversation: String,
+        @ColumnInfo(name = "conversation_id") var conversationId: String,
         @ColumnInfo(name = "message_id") var messageId: Long = 0,
         @ColumnInfo(name = "actor_id") var actorId: String? = null,
         @ColumnInfo(name = "actor_type") var actorType: String? = null,
@@ -56,7 +56,7 @@ data class MessageEntity(
 fun MessageEntity.toChatMessage(): ChatMessage {
     val chatMessage = ChatMessage()
     chatMessage.internalMessageId = this.id
-    chatMessage.internalConversationId = this.conversation
+    chatMessage.internalConversationId = this.conversationId
     chatMessage.jsonMessageId = this.messageId
     chatMessage.actorType = this.actorType
     chatMessage.actorId = this.actorId
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/utils/ConversationsManager.kt b/app/src/main/java/com/nextcloud/talk/newarch/utils/ConversationsManager.kt
new file mode 100644
index 000000000..e8fcf0a69
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/newarch/utils/ConversationsManager.kt
@@ -0,0 +1,99 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.newarch.utils
+
+import androidx.lifecycle.LiveData
+import com.nextcloud.talk.models.json.conversations.Conversation
+import com.nextcloud.talk.models.json.conversations.RoomOverall
+import com.nextcloud.talk.newarch.data.model.ErrorModel
+import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
+import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
+import com.nextcloud.talk.newarch.domain.usecases.GetConversationUseCase
+import com.nextcloud.talk.newarch.domain.usecases.JoinConversationUseCase
+import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
+import com.nextcloud.talk.newarch.local.models.UserNgEntity
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import okhttp3.OkHttpClient
+import org.koin.core.KoinComponent
+import org.koin.core.parameter.parametersOf
+import java.net.CookieManager
+
+class ConversationsManager constructor(usersRepository: UsersRepository,
+                                       cookieManager: CookieManager,
+                                       okHttpClient: OkHttpClient,
+                                       private val conversationsRepository: ConversationsRepository,
+                                       private val joinConversationUseCase: JoinConversationUseCase,
+                                       private val getConversationUseCase: GetConversationUseCase): KoinComponent {
+    private val applicationScope = CoroutineScope(Dispatchers.Default)
+    private val previousUser: UserNgEntity? = null
+    private val currentUserLiveData: LiveData<UserNgEntity> = usersRepository.getActiveUserLiveData()
+    private var currentConversation: Conversation? = null
+
+    init {
+        currentUserLiveData.observeForever { user ->
+            cookieManager.cookieStore.removeAll()
+            okHttpClient.dispatcher().cancelAll()
+            currentConversation = null
+        }
+    }
+
+    suspend fun getConversation(conversationToken: String) {
+        val currentUser = currentUserLiveData.value
+        getConversationUseCase.invoke(applicationScope, parametersOf(
+                currentUser,
+                conversationToken
+        ),
+                object : UseCaseResponse<RoomOverall> {
+                    override suspend fun onSuccess(result: RoomOverall) {
+                        currentUser?.let {
+                            conversationsRepository.saveConversationsForUser(it.id!!, listOf(result.ocs.data))
+                        }
+                    }
+
+                    override fun onError(errorModel: ErrorModel?) {
+                        // what do we do on error
+                    }
+                })
+    }
+
+    suspend fun joinConversation(conversationToken: String, conversationPassword: String?, conversationsManagerInterface: ConversationsManagerInterface) {
+        val currentUser = currentUserLiveData.value
+        joinConversationUseCase.invoke(applicationScope, parametersOf(
+                currentUser,
+                conversationToken,
+                conversationPassword
+        ),
+                object : UseCaseResponse<RoomOverall> {
+                    override suspend fun onSuccess(result: RoomOverall) {
+                        currentUser?.let {
+                            conversationsRepository.saveConversationsForUser(it.id!!, listOf(result.ocs.data))
+                            currentConversation = conversationsRepository.getConversationForUserWithToken(it.id!!, result.ocs!!.data!!.token!!)
+                            conversationsManagerInterface.joinedConversationForUser(it, currentConversation)
+                        }
+                    }
+
+                    override fun onError(errorModel: ErrorModel?) {
+                        // what do we do on error
+                    }
+                })
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/utils/ConversationsManagerInterface.kt b/app/src/main/java/com/nextcloud/talk/newarch/utils/ConversationsManagerInterface.kt
new file mode 100644
index 000000000..d4db24f4f
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/newarch/utils/ConversationsManagerInterface.kt
@@ -0,0 +1,28 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.newarch.utils
+
+import com.nextcloud.talk.models.json.conversations.Conversation
+import com.nextcloud.talk.newarch.local.models.UserNgEntity
+
+interface ConversationsManagerInterface  {
+    fun joinedConversationForUser(userNgEntity: UserNgEntity, conversation: Conversation?)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/utils/Images.kt b/app/src/main/java/com/nextcloud/talk/newarch/utils/Images.kt
index 690dd6df8..519452ec0 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/utils/Images.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/utils/Images.kt
@@ -51,9 +51,8 @@ class Images {
                 target(target)
             }
 
-            if (userEntity != null && url.startsWith(userEntity.baseUrl) && url.contains(
-                            "index.php/core/preview?fileId="
-                    )
+            if (userEntity != null && url.startsWith(userEntity.baseUrl) && (url.contains(
+                            "index.php/core/preview?fileId=") || url.contains("index.php/avatar/"))
             ) {
                 addHeader("Authorization", userEntity.getCredentials())
             }
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/utils/LiveDataTransformations.kt b/app/src/main/java/com/nextcloud/talk/newarch/utils/LiveDataTransformations.kt
new file mode 100644
index 000000000..0f1bcb0b2
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/newarch/utils/LiveDataTransformations.kt
@@ -0,0 +1,62 @@
+package com.nextcloud.talk.newarch.utils
+
+import android.util.Log
+import androidx.annotation.MainThread
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MediatorLiveData
+import androidx.lifecycle.Observer
+import java.util.*
+import kotlin.collections.ArrayList
+
+class LiveDataTransformations {
+
+    /**
+     * Creates a new [LiveData] object that does not emit a value until the source LiveData
+     * value has been changed.  The value is considered changed if `equals()` yields
+     * `false`.
+     *
+     * @param source the input [LiveData]
+     * @param <X>    the generic type parameter of `source`
+     * @return       a new [LiveData] of type `X`
+    </X> */
+    @MainThread
+    fun <X> distinctUntilChangedForArray(source: LiveData<X>): LiveData<X> {
+        val outputLiveData = MediatorLiveData<X>()
+        outputLiveData.addSource(source, object : Observer<X> {
+
+            var mFirstTime = true
+
+            override fun onChanged(currentValue: X?) {
+                val previousValue = outputLiveData.value
+                if (mFirstTime && currentValue != null
+                        || (previousValue == null && currentValue != null)) {
+                    mFirstTime = false
+                    outputLiveData.value = currentValue
+                } else if (previousValue != null) {
+                    if (currentValue == null) {
+                        outputLiveData.value = currentValue
+                    } else {
+                        val previousArray: Array<X> = (previousValue as ArrayList<X>).toArray() as Array<X>
+                        val currentArray: Array<X> = (currentValue as ArrayList<X>).toArray() as Array<X>
+
+                        if (previousArray.size != currentArray.size) {
+                            outputLiveData.value = currentValue
+                        } else {
+                            var counter = 0
+                            for(element in previousArray) {
+                                if (!element!!.equals(currentArray[counter])) {
+                                    outputLiveData.value = currentValue
+                                    return
+                                }
+
+                                counter++
+                            }
+                        }
+                    }
+                }
+            }
+        })
+
+        return outputLiveData
+    }
+}
diff --git a/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.kt
index 4f5e2cfd6..8307bb335 100644
--- a/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.kt
+++ b/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.kt
@@ -262,7 +262,7 @@ object DisplayUtils {
                 )
             }
 
-            val request = Images().getRequestForUrl(Coil.loader(), context, url, null, target, null, CircleCropTransformation())
+            val request = Images().getRequestForUrl(Coil.loader(), context, url, conversationUser, target, null, CircleCropTransformation())
             Coil.loader().load(request)
         }