switching accounts fails / wrong username shown in account switcher
## Steps to reproduce
there exist 2 users: userA and userB

1. login with userA
2. go to account switcher
3. BUG: avatars are shown correctly, but userA has the name of userB
4. keep userA selected. go to some conversation and send a message
5. BUG: message is sent as userB
6. go back to account switcher and select userB
7. go to the conversation and send a message
8. BUG: message is sent as userA

this doesn't always happen but sometimes.

### Expected behaviour
- names in account switcher match the avatars
- actions are not executed as another user


i guess this is caused by the room migration..

## Device information
**Talk version:** master (>= 14.2.0 Alpha 02)

## Server information
sermo

diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/AdvancedUserItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/AdvancedUserItem.java
index 7613168e0..a7b49be04 100644
--- a/app/src/main/java/com/nextcloud/talk/adapters/items/AdvancedUserItem.java
+++ b/app/src/main/java/com/nextcloud/talk/adapters/items/AdvancedUserItem.java
@@ -31,8 +31,8 @@ import com.facebook.drawee.backends.pipeline.Fresco;
 import com.facebook.drawee.interfaces.DraweeController;
 import com.nextcloud.talk.R;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
+import com.nextcloud.talk.data.user.model.User;
 import com.nextcloud.talk.databinding.AccountItemBinding;
-import com.nextcloud.talk.models.database.UserEntity;
 import com.nextcloud.talk.models.json.participants.Participant;
 import com.nextcloud.talk.utils.ApiUtils;
 import com.nextcloud.talk.utils.DisplayUtils;
@@ -51,13 +51,13 @@ public class AdvancedUserItem extends AbstractFlexibleItem<AdvancedUserItem.User
         IFilterable<String> {
 
     private final Participant participant;
-    private final UserEntity userEntity;
+    private final User user;
     @Nullable
     private final Account account;
 
-    public AdvancedUserItem(Participant participant, UserEntity userEntity, @Nullable Account account) {
+    public AdvancedUserItem(Participant participant, User user, @Nullable Account account) {
         this.participant = participant;
-        this.userEntity = userEntity;
+        this.user = user;
         this.account = account;
     }
 
@@ -82,8 +82,8 @@ public class AdvancedUserItem extends AbstractFlexibleItem<AdvancedUserItem.User
         return participant;
     }
 
-    public UserEntity getEntity() {
-        return userEntity;
+    public User getUser() {
+        return user;
     }
 
     @Nullable
@@ -117,21 +117,21 @@ public class AdvancedUserItem extends AbstractFlexibleItem<AdvancedUserItem.User
             holder.binding.userName.setText(participant.getDisplayName());
         }
 
-        if (userEntity != null && !TextUtils.isEmpty(userEntity.getBaseUrl())) {
-            String host = Uri.parse(userEntity.getBaseUrl()).getHost();
+        if (user != null && !TextUtils.isEmpty(user.getBaseUrl())) {
+            String host = Uri.parse(user.getBaseUrl()).getHost();
             if (!TextUtils.isEmpty(host)) {
-                holder.binding.account.setText(Uri.parse(userEntity.getBaseUrl()).getHost());
+                holder.binding.account.setText(Uri.parse(user.getBaseUrl()).getHost());
             } else {
-                holder.binding.account.setText(userEntity.getBaseUrl());
+                holder.binding.account.setText(user.getBaseUrl());
             }
         }
 
         holder.binding.userIcon.getHierarchy().setPlaceholderImage(R.drawable.account_circle_48dp);
         holder.binding.userIcon.getHierarchy().setFailureImage(R.drawable.account_circle_48dp);
 
-        if (userEntity != null && userEntity.getBaseUrl() != null &&
-                userEntity.getBaseUrl().startsWith("http://") ||
-                userEntity.getBaseUrl().startsWith("https://")) {
+        if (user != null && user.getBaseUrl() != null &&
+                user.getBaseUrl().startsWith("http://") ||
+                user.getBaseUrl().startsWith("https://")) {
 
             DraweeController draweeController = Fresco.newDraweeControllerBuilder()
                 .setOldController(holder.binding.userIcon.getController())
@@ -139,7 +139,7 @@ public class AdvancedUserItem extends AbstractFlexibleItem<AdvancedUserItem.User
                 .setImageRequest(
                     DisplayUtils.getImageRequestForUrl(
                         ApiUtils.getUrlForAvatar(
-                            userEntity.getBaseUrl(),
+                            user.getBaseUrl(),
                             participant.getCalculatedActorId(),
                             true)))
                 .build();
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ProfileController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ProfileController.kt
index ea4a44557..52631f15f 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/ProfileController.kt
+++ b/app/src/main/java/com/nextcloud/talk/controllers/ProfileController.kt
@@ -59,10 +59,9 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
 import com.nextcloud.talk.controllers.base.NewBaseController
 import com.nextcloud.talk.controllers.util.viewBinding
+import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.databinding.ControllerProfileBinding
 import com.nextcloud.talk.databinding.UserInfoDetailsTableItemBinding
-import com.nextcloud.talk.models.database.CapabilitiesUtil
-import com.nextcloud.talk.models.database.UserEntity
 import com.nextcloud.talk.models.json.generic.GenericOverall
 import com.nextcloud.talk.models.json.userprofile.Scope
 import com.nextcloud.talk.models.json.userprofile.UserProfileData
@@ -70,6 +69,7 @@ import com.nextcloud.talk.models.json.userprofile.UserProfileFieldsOverall
 import com.nextcloud.talk.models.json.userprofile.UserProfileOverall
 import com.nextcloud.talk.remotefilebrowser.activities.RemoteFileBrowserActivity
 import com.nextcloud.talk.ui.dialog.ScopeDialog
+import com.nextcloud.talk.users.UserManager
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.FileUtils
@@ -77,7 +77,7 @@ import com.nextcloud.talk.utils.Mimetype.IMAGE_JPG
 import com.nextcloud.talk.utils.Mimetype.IMAGE_PREFIX
 import com.nextcloud.talk.utils.Mimetype.IMAGE_PREFIX_GENERIC
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_MIME_TYPE_FILTER
-import com.nextcloud.talk.utils.database.user.UserUtils
+import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
 import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil
 import io.reactivex.Observer
 import io.reactivex.android.schedulers.AndroidSchedulers
@@ -105,12 +105,12 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
     lateinit var ncApi: NcApi
 
     @Inject
-    lateinit var userUtils: UserUtils
+    lateinit var userManager: UserManager
 
     @Inject
     lateinit var permissionUtil: PlatformPermissionUtil
 
-    private var currentUser: UserEntity? = null
+    private var currentUser: User? = null
     private var edit = false
     private var adapter: UserInfoAdapter? = null
     private var userInfo: UserProfileData? = null
@@ -151,7 +151,7 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
                 item.setTitle(R.string.save)
                 binding.emptyList.root.visibility = View.GONE
                 binding.userinfoList.visibility = View.VISIBLE
-                if (CapabilitiesUtil.isAvatarEndpointAvailable(currentUser)) {
+                if (CapabilitiesUtilNew.isAvatarEndpointAvailable(currentUser!!)) {
                     // TODO later avatar can also be checked via user fields, for now it is in Talk capability
                     binding.avatarButtons.visibility = View.VISIBLE
                 }
@@ -199,7 +199,7 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
         adapter = UserInfoAdapter(null, activity!!.resources.getColor(R.color.colorPrimary), this)
         binding.userinfoList.adapter = adapter
         binding.userinfoList.setItemViewCacheSize(DEFAULT_CACHE_SIZE)
-        currentUser = userUtils.currentUser
+        currentUser = userManager.currentUser.blockingGet()
         val credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
         binding.avatarUpload.setOnClickListener { sendSelectLocalFileIntent() }
         binding.avatarChoose.setOnClickListener { showBrowserScreen() }
@@ -310,7 +310,7 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
         }
 
         // show edit button
-        if (CapabilitiesUtil.canEditScopes(currentUser)) {
+        if (CapabilitiesUtilNew.canEditScopes(currentUser!!)) {
             ncApi.getEditableUserProfileFields(
                 ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token),
                 ApiUtils.getUrlForUserFields(currentUser!!.baseUrl)
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 185ad0b4b..98f7c5364 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt
+++ b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt
@@ -75,10 +75,9 @@ import com.nextcloud.talk.jobs.AccountRemovalWorker
 import com.nextcloud.talk.jobs.ContactAddressBookWorker
 import com.nextcloud.talk.jobs.ContactAddressBookWorker.Companion.checkPermission
 import com.nextcloud.talk.jobs.ContactAddressBookWorker.Companion.deleteAll
-import com.nextcloud.talk.models.database.CapabilitiesUtil
-import com.nextcloud.talk.models.database.UserEntity
 import com.nextcloud.talk.models.json.generic.GenericOverall
 import com.nextcloud.talk.models.json.userprofile.UserProfileOverall
+import com.nextcloud.talk.users.UserManager
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.LoggingUtils.sendMailWithAttachment
@@ -89,7 +88,6 @@ import com.nextcloud.talk.utils.SecurityUtils
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ARE_CALL_SOUNDS
 import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
 import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
-import com.nextcloud.talk.utils.database.user.UserUtils
 import com.nextcloud.talk.utils.preferences.MagicUserInputModule
 import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder
 import com.yarolegovich.lovelydialog.LovelySaveStateHandler
@@ -115,7 +113,7 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
     lateinit var ncApi: NcApi
 
     @Inject
-    lateinit var userUtils: UserUtils
+    lateinit var userManager: UserManager
 
     @Inject
     lateinit var currentUserProvider: CurrentUserProviderNew
@@ -328,19 +326,8 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
                         finalAlias = ""
                     }
 
-                    userUtils.createOrUpdateUser(
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        currentUser!!.id,
-                        null,
-                        finalAlias,
-                        null
-                    )
+                    currentUser!!.clientCertificate = finalAlias
+                    userManager.updateOrCreateUser(currentUser!!)
                 },
                 arrayOf("RSA", "EC"),
                 null,
@@ -430,7 +417,7 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
     }
 
     private fun removeCurrentAccount() {
-        val otherUserExists = userUtils.scheduleUserForDeletionWithId(currentUser!!.id!!)
+        val otherUserExists = userManager.scheduleUserForDeletionWithId(currentUser!!.id!!).blockingGet()
         val accountRemovalWork = OneTimeWorkRequest.Builder(AccountRemovalWorker::class.java).build()
         WorkManager.getInstance().enqueue(accountRemovalWork)
         if (otherUserExists && view != null) {
@@ -613,28 +600,9 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
                         displayName = userProfileOverall.ocs!!.data!!.displayNameAlt
                     }
                     if ((!TextUtils.isEmpty(displayName) && !(displayName == currentUser!!.displayName))) {
-                        dbQueryDisposable = userUtils.createOrUpdateUser(
-                            null,
-                            null,
-                            null,
-                            displayName,
-                            null,
-                            null,
-                            null,
-                            currentUser!!.id,
-                            null,
-                            null,
-                            null
-                        )
-                            .subscribeOn(Schedulers.io())
-                            .observeOn(AndroidSchedulers.mainThread())
-                            .subscribe(
-                                { userEntityResult: UserEntity ->
-                                    binding.displayNameText.text = userEntityResult.displayName
-                                },
-                                { dispose(dbQueryDisposable) },
-                                { dispose(dbQueryDisposable) }
-                            )
+                        currentUser!!.displayName = displayName
+                        userManager.updateOrCreateUser(currentUser!!)
+                        binding.displayNameText.text = currentUser!!.displayName
                     }
                 },
                 { dispose(profileQueryDisposable) },
@@ -682,7 +650,7 @@ class SettingsController : NewBaseController(R.layout.controller_settings) {
                 appPreferences!!.isKeyboardIncognito
         }
 
-        if (CapabilitiesUtil.isReadStatusAvailable(userUtils.currentUser)) {
+        if (CapabilitiesUtilNew.isReadStatusAvailable(userManager.currentUser.blockingGet())) {
             (binding.settingsReadPrivacy.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked =
                 !CapabilitiesUtilNew.isReadStatusPrivate(currentUser!!)
         } else {
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 a66cffd54..b4ac8e152 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/SwitchAccountController.kt
+++ b/app/src/main/java/com/nextcloud/talk/controllers/SwitchAccountController.kt
@@ -39,25 +39,22 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
 import com.nextcloud.talk.controllers.base.NewBaseController
 import com.nextcloud.talk.controllers.util.viewBinding
+import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.databinding.ControllerGenericRvBinding
 import com.nextcloud.talk.models.ImportAccount
-import com.nextcloud.talk.models.database.UserEntity
 import com.nextcloud.talk.models.json.participants.Participant
-import com.nextcloud.talk.utils.AccountUtils.findAccounts
+import com.nextcloud.talk.users.UserManager
+import com.nextcloud.talk.utils.AccountUtils.findAccountsForUsers
 import com.nextcloud.talk.utils.AccountUtils.getInformationFromAccount
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_BASE_URL
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_IS_ACCOUNT_IMPORT
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_TOKEN
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USERNAME
-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 io.reactivex.Observer
-import io.reactivex.disposables.Disposable
 import org.osmdroid.config.Configuration
 import java.net.CookieManager
-import java.util.ArrayList
 import javax.inject.Inject
 
 @AutoInjector(NextcloudTalkApplication::class)
@@ -69,7 +66,7 @@ class SwitchAccountController(args: Bundle? = null) :
     private val binding: ControllerGenericRvBinding by viewBinding(ControllerGenericRvBinding::bind)
 
     @Inject
-    lateinit var userUtils: UserUtils
+    lateinit var userManager: UserManager
 
     @Inject
     lateinit var cookieManager: CookieManager
@@ -85,33 +82,17 @@ class SwitchAccountController(args: Bundle? = null) :
         }
         true
     }
+
     private val onSwitchItemClickListener = FlexibleAdapter.OnItemClickListener { _, position ->
         if (userItems.size > position) {
-            val userEntity = (userItems[position] as AdvancedUserItem).entity
-            userUtils.createOrUpdateUser(
-                null,
-                null, null, null,
-                null, java.lang.Boolean.TRUE, null, userEntity.id, null, null, null
-            )
-                .subscribe(object : Observer<UserEntity> {
-                    override fun onSubscribe(d: Disposable) {
-                        // unused atm
-                    }
-                    override fun onNext(userEntity: UserEntity) {
-                        cookieManager.cookieStore.removeAll()
-                        userUtils.disableAllUsersWithoutId(userEntity.id)
-                        if (activity != null) {
-                            activity!!.runOnUiThread { router.popCurrentController() }
-                        }
-                    }
+            val user = (userItems[position] as AdvancedUserItem).user
 
-                    override fun onError(e: Throwable) {
-                        // unused atm
-                    }
-                    override fun onComplete() {
-                        // unused atm
-                    }
-                })
+            if (userManager.setUserAsActive(user).blockingGet()) {
+                cookieManager.cookieStore.removeAll()
+                if (activity != null) {
+                    activity!!.runOnUiThread { router.popCurrentController() }
+                }
+            }
         }
         true
     }
@@ -143,23 +124,21 @@ class SwitchAccountController(args: Bundle? = null) :
 
         if (adapter == null) {
             adapter = FlexibleAdapter(userItems, activity, false)
-            var userEntity: UserEntity?
             var participant: Participant
+
             if (!isAccountImport) {
-                for (userEntityObject in userUtils.users) {
-                    userEntity = userEntityObject as UserEntity?
-                    if (!userEntity!!.current) {
-                        var userId: String?
-                        userId = if (userEntity.userId != null) {
-                            userEntity.userId
+                for (user in userManager.users.blockingGet()) {
+                    if (!user.current) {
+                        val userId: String? = if (user.userId != null) {
+                            user.userId
                         } else {
-                            userEntity.username
+                            user.username
                         }
                         participant = Participant()
                         participant.actorType = Participant.ActorType.USERS
                         participant.actorId = userId
-                        participant.displayName = userEntity.displayName
-                        userItems.add(AdvancedUserItem(participant, userEntity, null))
+                        participant.displayName = user.displayName
+                        userItems.add(AdvancedUserItem(participant, user, null))
                     }
                 }
                 adapter!!.addListener(onSwitchItemClickListener)
@@ -167,16 +146,17 @@ class SwitchAccountController(args: Bundle? = null) :
             } else {
                 var account: Account
                 var importAccount: ImportAccount
-                for (accountObject in findAccounts(userUtils.users as List<UserEntity>)) {
+                var user: User
+                for (accountObject in findAccountsForUsers(userManager.users.blockingGet())) {
                     account = accountObject
                     importAccount = getInformationFromAccount(account)
                     participant = Participant()
                     participant.actorType = Participant.ActorType.USERS
                     participant.actorId = importAccount.getUsername()
                     participant.displayName = importAccount.getUsername()
-                    userEntity = UserEntity()
-                    userEntity.baseUrl = importAccount.getBaseUrl()
-                    userItems.add(AdvancedUserItem(participant, userEntity, account))
+                    user = User()
+                    user.baseUrl = importAccount.getBaseUrl()
+                    userItems.add(AdvancedUserItem(participant, user, account))
                 }
                 adapter!!.addListener(onImportItemClickListener)
                 adapter!!.updateDataSet(userItems, false)
diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java b/app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java
index 3ae40b40c..c78db0e4c 100644
--- a/app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java
+++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java
@@ -44,17 +44,16 @@ import com.nextcloud.talk.activities.MainActivity;
 import com.nextcloud.talk.adapters.items.AdvancedUserItem;
 import com.nextcloud.talk.api.NcApi;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
+import com.nextcloud.talk.data.user.model.User;
 import com.nextcloud.talk.databinding.DialogChooseAccountBinding;
-import com.nextcloud.talk.models.database.CapabilitiesUtil;
-import com.nextcloud.talk.models.database.User;
-import com.nextcloud.talk.models.database.UserEntity;
 import com.nextcloud.talk.models.json.participants.Participant;
 import com.nextcloud.talk.models.json.status.Status;
 import com.nextcloud.talk.models.json.status.StatusOverall;
 import com.nextcloud.talk.ui.StatusDrawable;
+import com.nextcloud.talk.users.UserManager;
 import com.nextcloud.talk.utils.ApiUtils;
 import com.nextcloud.talk.utils.DisplayUtils;
-import com.nextcloud.talk.utils.database.user.UserUtils;
+import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew;
 
 import java.net.CookieManager;
 import java.util.ArrayList;
@@ -80,7 +79,7 @@ public class ChooseAccountDialogFragment extends DialogFragment {
     private static final float STATUS_SIZE_IN_DP = 9f;
 
     @Inject
-    UserUtils userUtils;
+    UserManager userManager;
 
     @Inject
     CookieManager cookieManager;
@@ -115,7 +114,7 @@ public class ChooseAccountDialogFragment extends DialogFragment {
         binding.currentAccount.userIcon.setTag("");
 
         // Defining user texts, accounts, etc.
-        User user = userUtils.getCurrentUser();
+        User user = userManager.getCurrentUser().blockingGet();
         if (user != null) {
             binding.currentAccount.userName.setText(user.getDisplayName());
             binding.currentAccount.ticker.setVisibility(View.GONE);
@@ -171,11 +170,11 @@ public class ChooseAccountDialogFragment extends DialogFragment {
         if (adapter == null) {
             adapter = new FlexibleAdapter<>(userItems, getActivity(), false);
 
-            UserEntity userEntity;
+            User userEntity;
             Participant participant;
 
-            for (Object userEntityObject : userUtils.getUsers()) {
-                userEntity = (UserEntity) userEntityObject;
+            for (Object userItem : userManager.getUsers().blockingGet()) {
+                userEntity = (User) userItem;
                 if (!userEntity.getCurrent()) {
                     String userId;
                     if (userEntity.getUserId() != null) {
@@ -202,7 +201,7 @@ public class ChooseAccountDialogFragment extends DialogFragment {
     private void loadCurrentStatus(User user) {
         String credentials = ApiUtils.getCredentials(user.getUsername(), user.getToken());
 
-        if (CapabilitiesUtil.isUserStatusAvailable(userUtils.getCurrentUser())) {
+        if (CapabilitiesUtilNew.isUserStatusAvailable(userManager.getCurrentUser().blockingGet())) {
             binding.statusView.setVisibility(View.VISIBLE);
 
             ncApi.status(credentials, ApiUtils.getUrlForStatus(user.getBaseUrl())).
@@ -276,45 +275,16 @@ public class ChooseAccountDialogFragment extends DialogFragment {
             @Override
             public boolean onItemClick(View view, int position) {
                 if (userItems.size() > position) {
-                    UserEntity userEntity = (userItems.get(position)).getEntity();
-                    userUtils.createOrUpdateUser(null,
-                                                 null,
-                                                 null,
-                                                 null,
-                                                 null,
-                                                 Boolean.TRUE,
-                                                 null,
-                                                 userEntity.getId(),
-                                                 null,
-                                                 null,
-                                                 null)
-                        .subscribe(new Observer<UserEntity>() {
-                            @Override
-                            public void onSubscribe(@NonNull Disposable d) {
-                                // unused atm
-                            }
-
-                            @Override
-                            public void onNext(@NonNull UserEntity userEntity) {
-                                cookieManager.getCookieStore().removeAll();
-                                userUtils.disableAllUsersWithoutId(userEntity.getId());
-                                if (getActivity() != null) {
-                                    getActivity().runOnUiThread(
-                                        () -> ((MainActivity) getActivity()).resetConversationsList());
-                                }
-                                dismiss();
-                            }
-
-                            @Override
-                            public void onError(@NonNull Throwable e) {
-                                Log.w(TAG, "Error updating user", e);
-                            }
-
-                            @Override
-                            public void onComplete() {
-                                // unused atm
-                            }
-                        });
+                    User user = (userItems.get(position)).getUser();
+
+                    if (userManager.setUserAsActive(user).blockingGet()) {
+                        cookieManager.getCookieStore().removeAll();
+                        if (getActivity() != null) {
+                            getActivity().runOnUiThread(
+                                () -> ((MainActivity) getActivity()).resetConversationsList());
+                        }
+                        dismiss();
+                    }
                 }
 
                 return true;
diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt
index 3e37d6c6f..e0d8630f9 100644
--- a/app/src/main/java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt
+++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt
@@ -45,8 +45,8 @@ import com.nextcloud.talk.adapters.PredefinedStatusClickListener
 import com.nextcloud.talk.adapters.PredefinedStatusListAdapter
 import com.nextcloud.talk.api.NcApi
 import com.nextcloud.talk.application.NextcloudTalkApplication
+import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.databinding.DialogSetStatusBinding
-import com.nextcloud.talk.models.database.User
 import com.nextcloud.talk.models.json.generic.GenericOverall
 import com.nextcloud.talk.models.json.status.ClearAt
 import com.nextcloud.talk.models.json.status.Status
diff --git a/app/src/main/java/com/nextcloud/talk/users/UserManager.kt b/app/src/main/java/com/nextcloud/talk/users/UserManager.kt
index cfd83b88b..2262da0ac 100644
--- a/app/src/main/java/com/nextcloud/talk/users/UserManager.kt
+++ b/app/src/main/java/com/nextcloud/talk/users/UserManager.kt
@@ -123,6 +123,19 @@ class UserManager internal constructor(private val userRepository: UsersReposito
         }.toSingle()
     }
 
+    fun updateOrCreateUser(user: User): Single<Int> {
+        return Single.fromCallable {
+            when (user.id) {
+                null -> userRepository.insertUser(user).toInt()
+                else -> userRepository.updateUser(user)
+            }
+        }
+    }
+
+    fun setUserAsActive(user: User): Single<Boolean> {
+        return userRepository.setUserAsActiveWithId(user.id!!)
+    }
+
     @Deprecated("Only available for migration, use updateExternalSignalingServer or create new methods")
     fun createOrUpdateUser(
         username: String?,
diff --git a/app/src/main/java/com/nextcloud/talk/utils/AccountUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/AccountUtils.kt
index fbc05cbdc..3cc5fde3f 100644
--- a/app/src/main/java/com/nextcloud/talk/utils/AccountUtils.kt
+++ b/app/src/main/java/com/nextcloud/talk/utils/AccountUtils.kt
@@ -30,9 +30,9 @@ import android.content.pm.PackageManager
 import android.util.Log
 import com.nextcloud.talk.R
 import com.nextcloud.talk.application.NextcloudTalkApplication
+import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.models.ImportAccount
 import com.nextcloud.talk.models.database.UserEntity
-import java.util.ArrayList
 import java.util.Arrays
 
 object AccountUtils {
@@ -40,42 +40,23 @@ object AccountUtils {
     private const val TAG = "AccountUtils"
     private const val MIN_SUPPORTED_FILES_APP_VERSION = 30060151
 
+    @Deprecated("Migrate to findAccountsForUsers")
     fun findAccounts(userEntitiesList: List<UserEntity>): List<Account> {
+        return findAccountsForUsers(LegacyUserEntityMapper.toModel(userEntitiesList))
+    }
+
+    fun findAccountsForUsers(users: List<User>): List<Account> {
         val context = NextcloudTalkApplication.sharedApplication!!.applicationContext
         val accMgr = AccountManager.get(context)
         val accounts = accMgr.getAccountsByType(context.getString(R.string.nc_import_account_type))
 
         val accountsAvailable = ArrayList<Account>()
-        var importAccount: ImportAccount
-        var internalUserEntity: UserEntity
         var accountFound: Boolean
         for (account in accounts) {
             accountFound = false
 
-            for (i in userEntitiesList.indices) {
-                internalUserEntity = userEntitiesList[i]
-                importAccount = getInformationFromAccount(account)
-                if (importAccount.token != null) {
-                    if (UriUtils.hasHttpProtocollPrefixed(importAccount.baseUrl)) {
-                        if (
-                            internalUserEntity.username == importAccount.username &&
-                            internalUserEntity.baseUrl == importAccount.baseUrl
-                        ) {
-                            accountFound = true
-                            break
-                        }
-                    } else {
-                        if (internalUserEntity.username == importAccount.username &&
-                            (
-                                internalUserEntity.baseUrl == "http://" + importAccount.baseUrl ||
-                                    internalUserEntity.baseUrl == "https://" + importAccount.baseUrl
-                                )
-                        ) {
-                            accountFound = true
-                            break
-                        }
-                    }
-                } else {
+            for (user in users) {
+                if (matchAccounts(getInformationFromAccount(account), user)) {
                     accountFound = true
                     break
                 }
@@ -89,6 +70,33 @@ object AccountUtils {
         return accountsAvailable
     }
 
+    private fun matchAccounts(importAccount: ImportAccount, user: User): Boolean {
+        var accountFound = false
+        if (importAccount.token != null) {
+            if (UriUtils.hasHttpProtocollPrefixed(importAccount.baseUrl)) {
+                if (
+                    user.username == importAccount.username &&
+                    user.baseUrl == importAccount.baseUrl
+                ) {
+                    accountFound = true
+                }
+            } else {
+                if (user.username == importAccount.username &&
+                    (
+                        user.baseUrl == "http://" + importAccount.baseUrl ||
+                            user.baseUrl == "https://" + importAccount.baseUrl
+                        )
+                ) {
+                    accountFound = true
+                }
+            }
+        } else {
+            accountFound = true
+        }
+
+        return accountFound
+    }
+
     fun getAppNameBasedOnPackage(packageName: String): String {
         val context = NextcloudTalkApplication.sharedApplication!!.applicationContext
         val packageManager = context.packageManager
diff --git a/scripts/analysis/findbugs-results.txt b/scripts/analysis/findbugs-results.txt
index c663e4d09..d7019ae2e 100644
--- a/scripts/analysis/findbugs-results.txt
+++ b/scripts/analysis/findbugs-results.txt
@@ -1 +1 @@
-151
\ No newline at end of file
+149
\ No newline at end of file
['app/src/main/java/com/nextcloud/talk/controllers/SettingsController.kt', 'app/src/main/java/com/nextcloud/talk/users/UserManager.kt', 'app/src/main/java/com/nextcloud/talk/utils/AccountUtils.kt', 'app/src/main/java/com/nextcloud/talk/ui/dialog/SetStatusDialogFragment.kt', 'app/src/main/java/com/nextcloud/talk/controllers/SwitchAccountController.kt', 'app/src/main/java/com/nextcloud/talk/adapters/items/AdvancedUserItem.java', 'app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java', 'scripts/analysis/findbugs-results.txt', 'app/src/main/java/com/nextcloud/talk/controllers/ProfileController.kt']