From 7951764b2e03ea2c67faff8f74f76c9e139cb86f Mon Sep 17 00:00:00 2001
From: Ming Rui Zhang <mingrui.zhang@savoirfairelinux.com>
Date: Thu, 11 Mar 2021 13:30:45 -0500
Subject: [PATCH] misc: remove LRC singleton

GitLab: #337

Change-Id: Ifb671d38d364714818650a8154c43a5787460039
---
 CMakeLists.txt                                |   2 +
 jami-qt.pro                                   |   2 +
 src/abstractitemmodelbase.h                   |  41 +
 src/accountadapter.cpp                        | 164 ++--
 src/accountadapter.h                          |  54 +-
 src/accountlistmodel.cpp                      |  20 +-
 src/accountlistmodel.h                        |  10 +-
 src/accountstomigratelistmodel.cpp            |  23 +-
 src/accountstomigratelistmodel.h              |  13 +-
 src/audiodevicemodel.cpp                      |   8 +-
 src/audiodevicemodel.h                        |   6 +-
 src/audiomanagerlistmodel.cpp                 |  17 +-
 src/audiomanagerlistmodel.h                   |  13 +-
 src/avadapter.cpp                             |  79 +-
 src/avadapter.h                               |  58 +-
 src/avatarimageprovider.h                     |  20 +-
 src/bannedlistmodel.cpp                       |  11 +-
 src/bannedlistmodel.h                         |   4 +-
 src/calladapter.cpp                           | 238 +++---
 src/calladapter.h                             |  18 +-
 .../AccountMigrationDialog.qml                |   2 +
 src/commoncomponents/PhotoboothView.qml       |   2 +
 src/connectivitymonitor.h                     |   4 +-
 src/contactadapter.cpp                        |  43 +-
 src/contactadapter.h                          |  18 +-
 src/conversationsadapter.cpp                  | 100 +--
 src/conversationsadapter.h                    |   6 +-
 src/deviceitemlistmodel.cpp                   |  15 +-
 src/deviceitemlistmodel.h                     |  13 +-
 src/distantrenderer.cpp                       |  13 +-
 src/distantrenderer.h                         |  14 +-
 src/lrcinstance.h                             | 239 +++---
 src/main.cpp                                  |   2 +-
 src/mainapplication.cpp                       | 105 +--
 src/mainapplication.h                         |   9 +-
 src/mainview/MainView.qml                     |   2 +
 .../components/CallOverlayButtonGroup.qml     |   1 +
 src/mainview/components/ContactPicker.qml     |   1 +
 .../components/ContactPickerItemDelegate.qml  |   1 +
 .../components/ParticipantOverlay.qml         |   1 +
 .../components/ParticipantOverlayMenu.qml     |   1 +
 .../components/PluginHandlerPicker.qml        |   2 +
 src/mainview/components/RecordBox.qml         |   4 +
 src/mainview/components/ScreenRubberBand.qml  |   1 +
 src/mainview/components/SelectScreen.qml      |   1 +
 src/mainview/components/SipInputPanel.qml     |   1 +
 src/mainview/components/VideoCallPage.qml     |   4 +
 .../VideoCallPageContextMenuDeviceItem.qml    |   2 +-
 src/mediacodeclistmodel.cpp                   |  19 +-
 src/mediacodeclistmodel.h                     |  13 +-
 src/messagesadapter.cpp                       | 108 +--
 src/messagesadapter.h                         |  18 +-
 src/moderatorlistmodel.cpp                    |  20 +-
 src/moderatorlistmodel.h                      |   4 +-
 src/pluginadapter.cpp                         |  14 +-
 src/pluginadapter.h                           |   2 +-
 src/pluginhandleritemlistmodel.cpp            |  29 +-
 src/pluginhandleritemlistmodel.h              |  14 +-
 src/pluginitemlistmodel.cpp                   |  22 +-
 src/pluginitemlistmodel.h                     |  10 +-
 src/pluginlistpreferencemodel.cpp             |  11 +-
 src/pluginlistpreferencemodel.h               |  12 +-
 src/preferenceitemlistmodel.cpp               |  20 +-
 src/preferenceitemlistmodel.h                 |  10 +-
 src/previewrenderer.cpp                       |  30 +-
 src/previewrenderer.h                         |  17 +-
 src/qmladapterbase.h                          |  30 +-
 src/qmlregister.cpp                           | 350 ++++-----
 src/qmlregister.h                             |  44 +-
 src/qrimageprovider.h                         |  22 +-
 src/quickimageproviderbase.h                  |  40 +
 src/runguard.cpp                              |   9 +-
 src/runguard.h                                |   8 +-
 src/settingsadapter.cpp                       | 269 ++++---
 src/settingsadapter.h                         |  43 +-
 .../components/AdvancedCallSettings.qml       |   4 +-
 src/settingsview/components/AudioSettings.qml |  19 +-
 .../components/BannedContacts.qml             |   4 +-
 src/settingsview/components/LinkedDevices.qml |   4 +-
 src/settingsview/components/MediaSettings.qml |   1 +
 .../components/PluginListPreferencesView.qml  |   3 +
 .../components/PluginSettingsPage.qml         |   1 +
 src/settingsview/components/VideoSettings.qml |  15 +-
 src/smartlistmodel.cpp                        |  55 +-
 src/smartlistmodel.h                          |  16 +-
 src/tintedbuttonimageprovider.h               |  15 +-
 src/updatemanager.cpp                         | 334 ++++----
 src/updatemanager.h                           | 117 +--
 src/utils.cpp                                 |  30 +-
 src/utils.h                                   |  25 +-
 src/utilsadapter.cpp                          | 734 +++++++++---------
 src/utilsadapter.h                            | 168 ++--
 src/videoformatfpsmodel.cpp                   |  44 +-
 src/videoformatfpsmodel.h                     |  13 +-
 src/videoformatresolutionmodel.cpp            |  27 +-
 src/videoformatresolutionmodel.h              |  13 +-
 src/videoinputdevicemodel.cpp                 |  21 +-
 src/videoinputdevicemodel.h                   |  13 +-
 98 files changed, 2185 insertions(+), 2087 deletions(-)
 create mode 100644 src/abstractitemmodelbase.h
 create mode 100644 src/quickimageproviderbase.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5fb237d84..f39a52d2d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -115,6 +115,8 @@ set(COMMON_HEADERS
     ${SRC_DIR}/videoformatresolutionmodel.h
     ${SRC_DIR}/audiomanagerlistmodel.h
     ${SRC_DIR}/qmlregister.h
+    ${SRC_DIR}/abstractitemmodelbase.h
+    ${SRC_DIR}/quickimageproviderbase.h
     ${SRC_DIR}/qtutils.h
     ${SRC_DIR}/utilsadapter.h
     ${SRC_DIR}/dbuserrorhandler.h
diff --git a/jami-qt.pro b/jami-qt.pro
index 871f2ab54..532e1d10c 100644
--- a/jami-qt.pro
+++ b/jami-qt.pro
@@ -162,9 +162,11 @@ unix {
 
 # Input
 HEADERS += \
+        src/abstractitemmodelbase.h \
         src/avatarimageprovider.h \
         src/moderatorlistmodel.h \
         src/networkmanager.h \
+        src/quickimageproviderbase.h \
         src/screensaver.h \
         src/smartlistmodel.h \
         src/updatemanager.h \
diff --git a/src/abstractitemmodelbase.h b/src/abstractitemmodelbase.h
new file mode 100644
index 000000000..f073ef9b3
--- /dev/null
+++ b/src/abstractitemmodelbase.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019-2020 by Savoir-faire Linux
+ * Author: Mingrui Zhang   <mingrui.zhang@savoirfairelinux.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/>.
+ */
+
+#pragma once
+
+#include <QAbstractItemModel>
+
+#include "lrcinstance.h"
+
+class AbstractListModelBase : public QAbstractListModel
+{
+    Q_OBJECT
+    Q_PROPERTY(LRCInstance* lrcInstance MEMBER lrcInstance_ NOTIFY lrcInstanceChanged)
+
+public:
+    explicit AbstractListModelBase(QObject* parent = nullptr)
+        : QAbstractListModel(parent) {};
+    ~AbstractListModelBase() = default;
+
+signals:
+    void lrcInstanceChanged();
+
+protected:
+    // LRCInstance pointer (set in qml)
+    LRCInstance* lrcInstance_ {nullptr};
+};
diff --git a/src/accountadapter.cpp b/src/accountadapter.cpp
index e73298f11..94cdb6fce 100644
--- a/src/accountadapter.cpp
+++ b/src/accountadapter.cpp
@@ -27,21 +27,21 @@
 
 #include <QtConcurrent/QtConcurrent>
 
-AccountAdapter::AccountAdapter(QObject* parent)
-    : QmlAdapterBase(parent)
+AccountAdapter::AccountAdapter(QObject* parent, LRCInstance* instance)
+    : QmlAdapterBase(parent, instance)
 {}
 
 void
 AccountAdapter::safeInit()
 {
-    connect(&LRCInstance::instance(),
+    connect(lrcInstance_,
             &LRCInstance::currentAccountChanged,
             this,
             &AccountAdapter::onCurrentAccountChanged);
 
     deselectConversation();
 
-    auto accountId = LRCInstance::getCurrAccId();
+    auto accountId = lrcInstance_->getCurrAccId();
     setProperties(accountId);
     connectAccount(accountId);
 }
@@ -49,35 +49,35 @@ AccountAdapter::safeInit()
 lrc::api::NewAccountModel*
 AccountAdapter::getModel()
 {
-    return &(LRCInstance::accountModel());
+    return &(lrcInstance_->accountModel());
 }
 
 lrc::api::NewDeviceModel*
 AccountAdapter::getDeviceModel()
 {
-    return LRCInstance::getCurrentAccountInfo().deviceModel.get();
+    return lrcInstance_->getCurrentAccountInfo().deviceModel.get();
 }
 
 void
 AccountAdapter::accountChanged(int index)
 {
     deselectConversation(); // Hack UI
-    auto accountList = LRCInstance::accountModel().getAccountList();
+    auto accountList = lrcInstance_->accountModel().getAccountList();
     if (accountList.size() > index) {
-        LRCInstance::setSelectedAccountId(accountList.at(index));
+        lrcInstance_->setSelectedAccountId(accountList.at(index));
     }
 }
 
 void
 AccountAdapter::connectFailure()
 {
-    Utils::oneShotConnect(&LRCInstance::accountModel(),
+    Utils::oneShotConnect(&lrcInstance_->accountModel(),
                           &lrc::api::NewAccountModel::accountRemoved,
                           [this](const QString& accountId) {
                               Q_UNUSED(accountId);
                               emit reportFailure();
                           });
-    Utils::oneShotConnect(&LRCInstance::accountModel(),
+    Utils::oneShotConnect(&lrcInstance_->accountModel(),
                           &lrc::api::NewAccountModel::invalidAccountDetected,
                           [this](const QString& accountId) {
                               Q_UNUSED(accountId);
@@ -91,13 +91,13 @@ AccountAdapter::createJamiAccount(QString registeredName,
                                   bool isCreating)
 {
     Utils::oneShotConnect(
-        &LRCInstance::accountModel(),
+        &lrcInstance_->accountModel(),
         &lrc::api::NewAccountModel::accountAdded,
         [this, registeredName, settings, isCreating](const QString& accountId) {
-            auto confProps = LRCInstance::accountModel().getAccountConfig(accountId);
+            auto confProps = lrcInstance_->accountModel().getAccountConfig(accountId);
             confProps.Ringtone.ringtonePath = Utils::GetRingtonePath();
             confProps.isRendezVous = settings["isRendezVous"].toBool();
-            LRCInstance::accountModel().setAccountConfig(accountId, confProps);
+            lrcInstance_->accountModel().setAccountConfig(accountId, confProps);
 
             auto showBackup = isCreating
                               && !AppSettingsManager::getValue(Settings::Key::NeverShowMeAgain)
@@ -105,49 +105,49 @@ AccountAdapter::createJamiAccount(QString registeredName,
             if (!registeredName.isEmpty()) {
                 QObject::disconnect(registeredNameSavedConnection_);
                 registeredNameSavedConnection_ = connect(
-                    &LRCInstance::accountModel(),
+                    &lrcInstance_->accountModel(),
                     &lrc::api::NewAccountModel::profileUpdated,
                     [this, showBackup, addedAccountId = accountId](const QString& accountId) {
                         if (addedAccountId == accountId) {
-                            emit LRCInstance::instance().accountListChanged();
+                            emit lrcInstance_->accountListChanged();
                             emit accountAdded(accountId,
                                               showBackup,
-                                              LRCInstance::accountModel().getAccountList().indexOf(
+                                              lrcInstance_->accountModel().getAccountList().indexOf(
                                                   accountId));
                             QObject::disconnect(registeredNameSavedConnection_);
                         }
                     });
 
-                LRCInstance::accountModel().registerName(accountId,
-                                                         settings["password"].toString(),
-                                                         registeredName);
+                lrcInstance_->accountModel().registerName(accountId,
+                                                          settings["password"].toString(),
+                                                          registeredName);
             } else {
-                emit LRCInstance::instance().accountListChanged();
+                emit lrcInstance_->accountListChanged();
                 emit accountAdded(accountId,
                                   showBackup,
-                                  LRCInstance::accountModel().getAccountList().indexOf(accountId));
+                                  lrcInstance_->accountModel().getAccountList().indexOf(accountId));
             }
         });
 
     connectFailure();
 
-    QtConcurrent::run([settings] {
-        LRCInstance::accountModel().createNewAccount(lrc::api::profile::Type::RING,
-                                                     settings["alias"].toString(),
-                                                     settings["archivePath"].toString(),
-                                                     settings["password"].toString(),
-                                                     settings["archivePin"].toString(),
-                                                     "");
+    QtConcurrent::run([this, settings] {
+        lrcInstance_->accountModel().createNewAccount(lrc::api::profile::Type::RING,
+                                                      settings["alias"].toString(),
+                                                      settings["archivePath"].toString(),
+                                                      settings["password"].toString(),
+                                                      settings["archivePin"].toString(),
+                                                      "");
     });
 }
 
 void
 AccountAdapter::createSIPAccount(const QVariantMap& settings)
 {
-    Utils::oneShotConnect(&LRCInstance::accountModel(),
+    Utils::oneShotConnect(&lrcInstance_->accountModel(),
                           &lrc::api::NewAccountModel::accountAdded,
                           [this, settings](const QString& accountId) {
-                              auto confProps = LRCInstance::accountModel().getAccountConfig(
+                              auto confProps = lrcInstance_->accountModel().getAccountConfig(
                                   accountId);
                               // set SIP details
                               confProps.hostname = settings["hostname"].toString();
@@ -155,63 +155,63 @@ AccountAdapter::createSIPAccount(const QVariantMap& settings)
                               confProps.password = settings["password"].toString();
                               confProps.routeset = settings["proxy"].toString();
                               confProps.Ringtone.ringtonePath = Utils::GetRingtonePath();
-                              LRCInstance::accountModel().setAccountConfig(accountId, confProps);
+                              lrcInstance_->accountModel().setAccountConfig(accountId, confProps);
 
-                              emit LRCInstance::instance().accountListChanged();
+                              emit lrcInstance_->accountListChanged();
                               emit accountAdded(accountId,
                                                 false,
-                                                LRCInstance::accountModel().getAccountList().indexOf(
+                                                lrcInstance_->accountModel().getAccountList().indexOf(
                                                     accountId));
                           });
 
     connectFailure();
 
-    QtConcurrent::run([settings] {
-        LRCInstance::accountModel().createNewAccount(lrc::api::profile::Type::SIP,
-                                                     settings["alias"].toString(),
-                                                     settings["archivePath"].toString(),
-                                                     "",
-                                                     "",
-                                                     settings["username"].toString(),
-                                                     {});
+    QtConcurrent::run([this, settings] {
+        lrcInstance_->accountModel().createNewAccount(lrc::api::profile::Type::SIP,
+                                                      settings["alias"].toString(),
+                                                      settings["archivePath"].toString(),
+                                                      "",
+                                                      "",
+                                                      settings["username"].toString(),
+                                                      {});
     });
 }
 
 void
 AccountAdapter::createJAMSAccount(const QVariantMap& settings)
 {
-    Utils::oneShotConnect(&LRCInstance::accountModel(),
+    Utils::oneShotConnect(&lrcInstance_->accountModel(),
                           &lrc::api::NewAccountModel::accountAdded,
                           [this](const QString& accountId) {
-                              if (!LRCInstance::accountModel().getAccountList().size())
+                              if (!lrcInstance_->accountModel().getAccountList().size())
                                   return;
 
-                              auto confProps = LRCInstance::accountModel().getAccountConfig(
+                              auto confProps = lrcInstance_->accountModel().getAccountConfig(
                                   accountId);
                               confProps.Ringtone.ringtonePath = Utils::GetRingtonePath();
-                              LRCInstance::accountModel().setAccountConfig(accountId, confProps);
+                              lrcInstance_->accountModel().setAccountConfig(accountId, confProps);
 
                               emit accountAdded(accountId,
                                                 false,
-                                                LRCInstance::accountModel().getAccountList().indexOf(
+                                                lrcInstance_->accountModel().getAccountList().indexOf(
                                                     accountId));
-                              emit LRCInstance::instance().accountListChanged();
+                              emit lrcInstance_->accountListChanged();
                           });
 
     connectFailure();
 
-    QtConcurrent::run([settings] {
-        LRCInstance::accountModel().connectToAccountManager(settings["username"].toString(),
-                                                            settings["password"].toString(),
-                                                            settings["manager"].toString());
+    QtConcurrent::run([this, settings] {
+        lrcInstance_->accountModel().connectToAccountManager(settings["username"].toString(),
+                                                             settings["password"].toString(),
+                                                             settings["manager"].toString());
     });
 }
 
 void
 AccountAdapter::deleteCurrentAccount()
 {
-    LRCInstance::accountModel().removeAccount(LRCInstance::getCurrAccId());
-    emit LRCInstance::instance().accountListChanged();
+    lrcInstance_->accountModel().removeAccount(lrcInstance_->getCurrAccId());
+    emit lrcInstance_->accountListChanged();
 }
 
 bool
@@ -219,57 +219,57 @@ AccountAdapter::savePassword(const QString& accountId,
                              const QString& oldPassword,
                              const QString& newPassword)
 {
-    return LRCInstance::accountModel().changeAccountPassword(accountId, oldPassword, newPassword);
+    return lrcInstance_->accountModel().changeAccountPassword(accountId, oldPassword, newPassword);
 }
 
 void
 AccountAdapter::startPreviewing(bool force)
 {
-    LRCInstance::renderer()->startPreviewing(force);
+    lrcInstance_->renderer()->startPreviewing(force);
 }
 
 void
 AccountAdapter::stopPreviewing()
 {
-    if (!LRCInstance::hasVideoCall() && LRCInstance::renderer()->isPreviewing()) {
-        LRCInstance::renderer()->stopPreviewing();
+    if (!lrcInstance_->hasVideoCall() && lrcInstance_->renderer()->isPreviewing()) {
+        lrcInstance_->renderer()->stopPreviewing();
     }
 }
 
 bool
 AccountAdapter::hasVideoCall()
 {
-    return LRCInstance::hasVideoCall();
+    return lrcInstance_->hasVideoCall();
 }
 
 bool
 AccountAdapter::isPreviewing()
 {
-    return LRCInstance::renderer()->isPreviewing();
+    return lrcInstance_->renderer()->isPreviewing();
 }
 
 void
 AccountAdapter::setCurrAccDisplayName(const QString& text)
 {
-    LRCInstance::setCurrAccDisplayName(text);
+    lrcInstance_->setCurrAccDisplayName(text);
 }
 
 void
 AccountAdapter::setSelectedConvId(const QString& convId)
 {
-    LRCInstance::setSelectedConvId(convId);
+    lrcInstance_->setSelectedConvId(convId);
 }
 
 lrc::api::profile::Type
 AccountAdapter::getCurrentAccountType()
 {
-    return LRCInstance::getCurrentAccountInfo().profileInfo.type;
+    return lrcInstance_->getCurrentAccountInfo().profileInfo.type;
 }
 
 void
 AccountAdapter::setCurrAccAvatar(bool fromFile, const QString& source)
 {
-    QtConcurrent::run([fromFile, source]() {
+    QtConcurrent::run([this, fromFile, source]() {
         QPixmap image;
         bool success;
         if (fromFile)
@@ -278,14 +278,14 @@ AccountAdapter::setCurrAccAvatar(bool fromFile, const QString& source)
             success = image.loadFromData(Utils::base64StringToByteArray(source));
 
         if (success)
-            LRCInstance::setCurrAccAvatar(image);
+            lrcInstance_->setCurrAccAvatar(image);
     });
 }
 
 void
 AccountAdapter::onCurrentAccountChanged()
 {
-    auto accountId = LRCInstance::getCurrAccId();
+    auto accountId = lrcInstance_->getCurrAccId();
     setProperties(accountId);
     connectAccount(accountId);
 }
@@ -293,32 +293,32 @@ AccountAdapter::onCurrentAccountChanged()
 bool
 AccountAdapter::hasPassword()
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     return confProps.archiveHasPassword;
 }
 
 void
 AccountAdapter::setArchiveHasPassword(bool isHavePassword)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.archiveHasPassword = isHavePassword;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 bool
 AccountAdapter::exportToFile(const QString& accountId,
                              const QString& path,
                              const QString& password) const
 {
-    return LRCInstance::accountModel().exportToFile(accountId, path, password);
+    return lrcInstance_->accountModel().exportToFile(accountId, path, password);
 }
 
 void
 AccountAdapter::setArchivePasswordAsync(const QString& accountID, const QString& password)
 {
-    QtConcurrent::run([accountID, password] {
-        auto config = LRCInstance::accountModel().getAccountConfig(accountID);
+    QtConcurrent::run([this, accountID, password] {
+        auto config = lrcInstance_->accountModel().getAccountConfig(accountID);
         config.archivePassword = password;
-        LRCInstance::accountModel().setAccountConfig(accountID, config);
+        lrcInstance_->accountModel().setAccountConfig(accountID, config);
     });
 }
 
@@ -335,24 +335,24 @@ AccountAdapter::passwordSetStatusMessageBox(bool success, QString title, QString
 void
 AccountAdapter::deselectConversation()
 {
-    if (LRCInstance::getCurrentConvUid().isEmpty()) {
+    if (lrcInstance_->getCurrentConvUid().isEmpty()) {
         return;
     }
 
-    auto currentConversationModel = LRCInstance::getCurrentConversationModel();
+    auto currentConversationModel = lrcInstance_->getCurrentConversationModel();
 
     if (currentConversationModel == nullptr) {
         return;
     }
 
-    LRCInstance::setSelectedConvId();
+    lrcInstance_->setSelectedConvId();
 }
 
 void
 AccountAdapter::connectAccount(const QString& accountId)
 {
     try {
-        auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId);
+        auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
 
         QObject::disconnect(accountStatusChangedConnection_);
         QObject::disconnect(accountProfileUpdatedConnection_);
@@ -378,12 +378,12 @@ AccountAdapter::connectAccount(const QString& accountId)
             = QObject::connect(accInfo.contactModel.get(),
                                &lrc::api::ContactModel::contactAdded,
                                [this, accountId](const QString& contactUri) {
-                                   const auto& convInfo = LRCInstance::getConversationFromConvUid(
-                                       LRCInstance::getCurrentConvUid());
+                                   const auto& convInfo = lrcInstance_->getConversationFromConvUid(
+                                       lrcInstance_->getCurrentConvUid());
                                    if (convInfo.uid.isEmpty()) {
                                        return;
                                    }
-                                   auto& accInfo = LRCInstance::accountModel().getAccountInfo(
+                                   auto& accInfo = lrcInstance_->accountModel().getAccountInfo(
                                        accountId);
                                    if (contactUri
                                        == accInfo.contactModel
@@ -399,9 +399,9 @@ AccountAdapter::connectAccount(const QString& accountId)
         addedToConferenceConnection_
             = QObject::connect(accInfo.callModel.get(),
                                &NewCallModel::callAddedToConference,
-                               [](const QString& callId, const QString& confId) {
+                               [this](const QString& callId, const QString& confId) {
                                    Q_UNUSED(callId);
-                                   LRCInstance::renderer()->addDistantRenderer(confId);
+                                   lrcInstance_->renderer()->addDistantRenderer(confId);
                                });
 
         contactUnbannedConnection_ = QObject::connect(accInfo.contactModel.get(),
@@ -420,7 +420,7 @@ void
 AccountAdapter::setProperties(const QString& accountId)
 {
     setProperty("currentAccountId", accountId);
-    auto accountType = LRCInstance::getAccountInfo(accountId).profileInfo.type;
+    auto accountType = lrcInstance_->getAccountInfo(accountId).profileInfo.type;
     setProperty("currentAccountType", lrc::api::profile::to_string(accountType));
     emit deviceModelChanged();
 }
diff --git a/src/accountadapter.h b/src/accountadapter.h
index c07b785e9..6afb8d31f 100644
--- a/src/accountadapter.h
+++ b/src/accountadapter.h
@@ -1,4 +1,4 @@
-/*
+/*
  * Copyright (C) 2020 by Savoir-faire Linux
  * Author: Mingrui Zhang   <mingrui.zhang@savoirfairelinux.com>
  *
@@ -50,45 +50,38 @@ signals:
     void accountListSizeChanged();
 
 public:
-    explicit AccountAdapter(QObject* parent = 0);
+    explicit AccountAdapter(QObject* parent = nullptr, LRCInstance* instance = nullptr);
     ~AccountAdapter() = default;
 
 protected:
     void safeInit() override;
 
 public:
-    /*
-     * Change to account corresponding to combox box index.
-     */
+    // Change to account corresponding to combox box index.
     Q_INVOKABLE void accountChanged(int index);
-    /*
-     * Create normal Jami account, SIP account and JAMS accounts.
-     */
+
+    // Create normal Jami account, SIP account and JAMS accounts.
     Q_INVOKABLE void createJamiAccount(QString registeredName,
                                        const QVariantMap& settings,
                                        bool isCreating);
     Q_INVOKABLE void createSIPAccount(const QVariantMap& settings);
     Q_INVOKABLE void createJAMSAccount(const QVariantMap& settings);
-    /*
-     * Delete current account
-     */
+
+    // Delete current account
     Q_INVOKABLE void deleteCurrentAccount();
-    /*
-     * Setting related
-     */
+
+    // Setting related
     Q_INVOKABLE void passwordSetStatusMessageBox(bool success, QString title, QString infoToDisplay);
-    /*
-     * conf property
-     */
+
+    // Conf property
     Q_INVOKABLE bool hasPassword();
     Q_INVOKABLE void setArchiveHasPassword(bool isHavePassword);
     Q_INVOKABLE bool exportToFile(const QString& accountId,
                                   const QString& path,
                                   const QString& password = {}) const;
     Q_INVOKABLE void setArchivePasswordAsync(const QString& accountID, const QString& password);
-    /*
-     * lrc instances functions wrappers
-     */
+
+    // Lrc instances functions wrappers
     Q_INVOKABLE bool savePassword(const QString& accountId,
                                   const QString& oldPassword,
                                   const QString& newPassword);
@@ -104,15 +97,12 @@ public:
     Q_INVOKABLE void setCurrAccAvatar(bool fromFile, const QString& source);
 
 signals:
-    /*
-     * Trigger other components to reconnect account related signals.
-     */
+    // Trigger other components to reconnect account related signals.
     void accountStatusChanged(QString accountId = {});
 
     void updateConversationForAddedContact();
-    /*
-     * send report failure to QML to make it show the right UI state .
-     */
+
+    // Send report failure to QML to make it show the right UI state .
     void reportFailure();
     void accountAdded(QString accountId, bool showBackUp, int index);
     void contactUnbanned();
@@ -127,19 +117,13 @@ private:
 
     void deselectConversation();
 
-    /*
-     * Make account signal connections.
-     */
+    // Make account signal connections.
     void connectAccount(const QString& accountId);
 
-    /*
-     * Make account signal connections.
-     */
+    // Make account signal connections.
     void setProperties(const QString& accountId);
 
-    /*
-     * Implement what to do when account creation fails.
-     */
+    // Implement what to do when account creation fails.
     void connectFailure();
 
     QMetaObject::Connection accountStatusChangedConnection_;
diff --git a/src/accountlistmodel.cpp b/src/accountlistmodel.cpp
index 309558da4..9c3bcb9df 100644
--- a/src/accountlistmodel.cpp
+++ b/src/accountlistmodel.cpp
@@ -24,8 +24,12 @@
 #include "lrcinstance.h"
 #include "utils.h"
 
+#include "api/account.h"
+#include "api/contact.h"
+#include "api/conversation.h"
+
 AccountListModel::AccountListModel(QObject* parent)
-    : QAbstractListModel(parent)
+    : AbstractListModelBase(parent)
 {}
 
 AccountListModel::~AccountListModel() {}
@@ -33,11 +37,11 @@ AccountListModel::~AccountListModel() {}
 int
 AccountListModel::rowCount(const QModelIndex& parent) const
 {
-    if (!parent.isValid()) {
+    if (!parent.isValid() && lrcInstance_) {
         /*
          * Count.
          */
-        return LRCInstance::accountModel().getAccountList().size();
+        return lrcInstance_->accountModel().getAccountList().size();
     }
     /*
      * A valid QModelIndex returns 0 as no entry has sub-elements.
@@ -58,21 +62,21 @@ AccountListModel::columnCount(const QModelIndex& parent) const
 QVariant
 AccountListModel::data(const QModelIndex& index, int role) const
 {
-    auto accountList = LRCInstance::accountModel().getAccountList();
+    auto accountList = lrcInstance_->accountModel().getAccountList();
     if (!index.isValid() || accountList.size() <= index.row()) {
         return QVariant();
     }
 
     auto accountId = accountList.at(index.row());
-    auto& accountInfo = LRCInstance::accountModel().getAccountInfo(accountId);
+    auto& accountInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
 
     // Since we are using image provider right now, image url representation should be unique to
     // be able to use the image cache, account avatar will only be updated once PictureUid changed
     switch (role) {
     case Role::Alias:
-        return QVariant(LRCInstance::accountModel().bestNameForAccount(accountId));
+        return QVariant(lrcInstance_->accountModel().bestNameForAccount(accountId));
     case Role::Username:
-        return QVariant(LRCInstance::accountModel().bestIdForAccount(accountId));
+        return QVariant(lrcInstance_->accountModel().bestIdForAccount(accountId));
     case Role::Type:
         return QVariant(static_cast<int>(accountInfo.profileInfo.type));
     case Role::Status:
@@ -133,7 +137,7 @@ void
 AccountListModel::reset()
 {
     beginResetModel();
-    fillAvatarUidMap(LRCInstance::accountModel().getAccountList());
+    fillAvatarUidMap(lrcInstance_->accountModel().getAccountList());
     endResetModel();
 }
 
diff --git a/src/accountlistmodel.h b/src/accountlistmodel.h
index b1d247892..939fb388d 100644
--- a/src/accountlistmodel.h
+++ b/src/accountlistmodel.h
@@ -19,13 +19,9 @@
 
 #pragma once
 
-#include <QAbstractItemModel>
+#include "abstractitemmodelbase.h"
 
-#include "api/account.h"
-#include "api/contact.h"
-#include "api/conversation.h"
-
-class AccountListModel : public QAbstractListModel
+class AccountListModel : public AbstractListModelBase
 {
     Q_OBJECT
 
@@ -33,7 +29,7 @@ public:
     enum Role { Alias = Qt::UserRole + 1, Username, Type, Status, ID, PictureUid };
     Q_ENUM(Role)
 
-    explicit AccountListModel(QObject* parent = 0);
+    explicit AccountListModel(QObject* parent = nullptr);
     ~AccountListModel();
 
     /*
diff --git a/src/accountstomigratelistmodel.cpp b/src/accountstomigratelistmodel.cpp
index be9309fc2..b05bd6146 100644
--- a/src/accountstomigratelistmodel.cpp
+++ b/src/accountstomigratelistmodel.cpp
@@ -18,8 +18,15 @@
 
 #include "accountstomigratelistmodel.h"
 
+#include "lrcinstance.h"
+
+#include "api/account.h"
+#include "api/contact.h"
+#include "api/conversation.h"
+#include "api/newdevicemodel.h"
+
 AccountsToMigrateListModel::AccountsToMigrateListModel(QObject* parent)
-    : QAbstractListModel(parent)
+    : AbstractListModelBase(parent)
 {}
 
 AccountsToMigrateListModel::~AccountsToMigrateListModel() {}
@@ -27,16 +34,16 @@ AccountsToMigrateListModel::~AccountsToMigrateListModel() {}
 int
 AccountsToMigrateListModel::rowCount(const QModelIndex& parent) const
 {
-    if (!parent.isValid()) {
+    if (!parent.isValid() && lrcInstance_) {
         /*
          * Count.
          */
-        auto accountList = LRCInstance::accountModel().getAccountList();
+        auto accountList = lrcInstance_->accountModel().getAccountList();
 
         int countAccountToMigrate = 0;
 
         for (const QString& i : accountList) {
-            auto accountStatus = LRCInstance::accountModel().getAccountInfo(i).status;
+            auto accountStatus = lrcInstance_->accountModel().getAccountInfo(i).status;
             if (accountStatus == lrc::api::account::Status::ERROR_NEED_MIGRATION) {
                 countAccountToMigrate++;
             }
@@ -63,7 +70,7 @@ AccountsToMigrateListModel::columnCount(const QModelIndex& parent) const
 QVariant
 AccountsToMigrateListModel::data(const QModelIndex& index, int role) const
 {
-    auto accountList = LRCInstance::accountModel().getAccountList();
+    auto accountList = lrcInstance_->accountModel().getAccountList();
     if (!index.isValid() || accountList.size() <= index.row()) {
         return QVariant();
     }
@@ -71,7 +78,7 @@ AccountsToMigrateListModel::data(const QModelIndex& index, int role) const
     QList<QString> accountToMigrateList;
 
     for (QString i : accountList) {
-        auto accountStatus = LRCInstance::accountModel().getAccountInfo(i).status;
+        auto accountStatus = lrcInstance_->accountModel().getAccountInfo(i).status;
         if (accountStatus == lrc::api::account::Status::ERROR_NEED_MIGRATION) {
             accountToMigrateList.append(i);
         }
@@ -79,7 +86,7 @@ AccountsToMigrateListModel::data(const QModelIndex& index, int role) const
 
     QString accountId = accountToMigrateList.at(index.row());
 
-    auto& avatarInfo = LRCInstance::accountModel().getAccountInfo(accountId);
+    auto& avatarInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
 
     switch (role) {
     case Role::Account_ID:
@@ -91,7 +98,7 @@ AccountsToMigrateListModel::data(const QModelIndex& index, int role) const
     case Role::Username:
         return QVariant(avatarInfo.confProperties.username);
     case Role::Alias:
-        return QVariant(LRCInstance::accountModel().getAccountInfo(accountId).profileInfo.alias);
+        return QVariant(lrcInstance_->accountModel().getAccountInfo(accountId).profileInfo.alias);
     }
     return QVariant();
 }
diff --git a/src/accountstomigratelistmodel.h b/src/accountstomigratelistmodel.h
index 6a35f80d1..d6565199b 100644
--- a/src/accountstomigratelistmodel.h
+++ b/src/accountstomigratelistmodel.h
@@ -18,23 +18,16 @@
 
 #pragma once
 
-#include <QAbstractItemModel>
+#include "abstractitemmodelbase.h"
 
-#include "api/account.h"
-#include "api/contact.h"
-#include "api/conversation.h"
-#include "api/newdevicemodel.h"
-
-#include "lrcinstance.h"
-
-class AccountsToMigrateListModel : public QAbstractListModel
+class AccountsToMigrateListModel : public AbstractListModelBase
 {
     Q_OBJECT
 public:
     enum Role { Account_ID = Qt::UserRole + 1, ManagerUsername, ManagerUri, Username, Alias };
     Q_ENUM(Role)
 
-    explicit AccountsToMigrateListModel(QObject* parent = 0);
+    explicit AccountsToMigrateListModel(QObject* parent = nullptr);
     ~AccountsToMigrateListModel();
 
     /*
diff --git a/src/audiodevicemodel.cpp b/src/audiodevicemodel.cpp
index 83c4168e5..9dd71c82a 100644
--- a/src/audiodevicemodel.cpp
+++ b/src/audiodevicemodel.cpp
@@ -21,7 +21,7 @@
 #include "lrcinstance.h"
 
 AudioDeviceModel::AudioDeviceModel(QObject* parent)
-    : QAbstractListModel(parent)
+    : AbstractListModelBase(parent)
 {
     connect(this, &AudioDeviceModel::typeChanged, this, &AudioDeviceModel::reset);
 }
@@ -109,15 +109,15 @@ void
 AudioDeviceModel::reset()
 {
     beginResetModel();
-    devices_ = type_ == Type::Record ? LRCInstance::avModel().getAudioInputDevices()
-                                     : LRCInstance::avModel().getAudioOutputDevices();
+    devices_ = type_ == Type::Record ? lrcInstance_->avModel().getAudioInputDevices()
+                                     : lrcInstance_->avModel().getAudioOutputDevices();
     endResetModel();
 }
 
 int
 AudioDeviceModel::getCurrentIndex()
 {
-    QString currentId = LRCInstance::avModel().getInputDevice();
+    QString currentId = lrcInstance_->avModel().getInputDevice();
     auto resultList = match(index(0, 0), Qt::DisplayRole, QVariant(currentId));
     return resultList.size() > 0 ? resultList[0].row() : 0;
 }
diff --git a/src/audiodevicemodel.h b/src/audiodevicemodel.h
index c4ec427e6..497cc63d0 100644
--- a/src/audiodevicemodel.h
+++ b/src/audiodevicemodel.h
@@ -18,9 +18,9 @@
 
 #pragma once
 
-#include <QAbstractItemModel>
+#include "abstractitemmodelbase.h"
 
-class AudioDeviceModel : public QAbstractListModel
+class AudioDeviceModel : public AbstractListModelBase
 {
     Q_OBJECT
 public:
@@ -62,4 +62,4 @@ private:
     QVector<QString> devices_;
 
     Type type_ {Type::Invalid};
-};
+};
\ No newline at end of file
diff --git a/src/audiomanagerlistmodel.cpp b/src/audiomanagerlistmodel.cpp
index 866a882f5..7b5f736ea 100644
--- a/src/audiomanagerlistmodel.cpp
+++ b/src/audiomanagerlistmodel.cpp
@@ -18,8 +18,15 @@
 
 #include "audiomanagerlistmodel.h"
 
+#include "lrcinstance.h"
+
+#include "api/account.h"
+#include "api/contact.h"
+#include "api/conversation.h"
+#include "api/newdevicemodel.h"
+
 AudioManagerListModel::AudioManagerListModel(QObject* parent)
-    : QAbstractListModel(parent)
+    : AbstractListModelBase(parent)
 {}
 
 AudioManagerListModel::~AudioManagerListModel() {}
@@ -27,11 +34,11 @@ AudioManagerListModel::~AudioManagerListModel() {}
 int
 AudioManagerListModel::rowCount(const QModelIndex& parent) const
 {
-    if (!parent.isValid()) {
+    if (!parent.isValid() && lrcInstance_) {
         /*
          * Count.
          */
-        return LRCInstance::avModel().getSupportedAudioManagers().size();
+        return lrcInstance_->avModel().getSupportedAudioManagers().size();
     }
     /*
      * A valid QModelIndex returns 0 as no entry has sub-elements.
@@ -52,7 +59,7 @@ AudioManagerListModel::columnCount(const QModelIndex& parent) const
 QVariant
 AudioManagerListModel::data(const QModelIndex& index, int role) const
 {
-    auto managerList = LRCInstance::avModel().getSupportedAudioManagers();
+    auto managerList = lrcInstance_->avModel().getSupportedAudioManagers();
     if (!index.isValid() || managerList.size() <= index.row()) {
         return QVariant();
     }
@@ -116,7 +123,7 @@ AudioManagerListModel::reset()
 int
 AudioManagerListModel::getCurrentSettingIndex()
 {
-    QString currentId = LRCInstance::avModel().getAudioManager();
+    QString currentId = lrcInstance_->avModel().getAudioManager();
     auto resultList = match(index(0, 0), AudioManagerID, QVariant(currentId));
 
     int resultRowIndex = 0;
diff --git a/src/audiomanagerlistmodel.h b/src/audiomanagerlistmodel.h
index 96da803ac..30120e8f4 100644
--- a/src/audiomanagerlistmodel.h
+++ b/src/audiomanagerlistmodel.h
@@ -18,23 +18,16 @@
 
 #pragma once
 
-#include <QAbstractItemModel>
+#include "abstractitemmodelbase.h"
 
-#include "api/account.h"
-#include "api/contact.h"
-#include "api/conversation.h"
-#include "api/newdevicemodel.h"
-
-#include "lrcinstance.h"
-
-class AudioManagerListModel : public QAbstractListModel
+class AudioManagerListModel : public AbstractListModelBase
 {
     Q_OBJECT
 public:
     enum Role { AudioManagerID = Qt::UserRole + 1, ID_UTF8 };
     Q_ENUM(Role)
 
-    explicit AudioManagerListModel(QObject* parent = 0);
+    explicit AudioManagerListModel(QObject* parent = nullptr);
     ~AudioManagerListModel();
 
     /*
diff --git a/src/avadapter.cpp b/src/avadapter.cpp
index e568b087c..65f7ccded 100644
--- a/src/avadapter.cpp
+++ b/src/avadapter.cpp
@@ -1,4 +1,4 @@
-/*
+/*
  * Copyright (C) 2020 by Savoir-faire Linux
  * Author : Edric Ladent Milaret<edric.ladent - milaret @savoirfairelinux.com>
  * Author : Andreas Traczyk<andreas.traczyk @savoirfairelinux.com>
@@ -32,10 +32,10 @@
 #include <QPainter>
 #include <QScreen>
 
-AvAdapter::AvAdapter(QObject* parent)
-    : QmlAdapterBase(parent)
+AvAdapter::AvAdapter(QObject* parent, LRCInstance* instance)
+    : QmlAdapterBase(parent, instance)
 {
-    auto& avModel = LRCInstance::avModel();
+    auto& avModel = lrcInstance_->avModel();
 
     deviceListSize_ = avModel.getDevices().size();
     connect(&avModel, &lrc::api::AVModel::deviceEvent, this, &AvAdapter::slotDeviceEvent);
@@ -44,16 +44,16 @@ AvAdapter::AvAdapter(QObject* parent)
 QVariantMap
 AvAdapter::populateVideoDeviceContextMenuItem()
 {
-    auto activeDevice = LRCInstance::avModel().getCurrentVideoCaptureDevice();
+    auto activeDevice = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
 
     /*
      * Create a list of video input devices.
      */
     QVariantMap deciveContextMenuNeededInfo;
-    auto devices = LRCInstance::avModel().getDevices();
+    auto devices = lrcInstance_->avModel().getDevices();
     for (int i = 0; i < devices.size(); i++) {
         try {
-            auto settings = LRCInstance::avModel().getDeviceSettings(devices[i]);
+            auto settings = lrcInstance_->avModel().getDeviceSettings(devices[i]);
             deciveContextMenuNeededInfo[settings.name] = QVariant(settings.id == activeDevice);
         } catch (...) {
             qDebug().noquote() << "Error in getting device settings";
@@ -71,13 +71,13 @@ AvAdapter::populateVideoDeviceContextMenuItem()
 void
 AvAdapter::onVideoContextMenuDeviceItemClicked(const QString& deviceName)
 {
-    auto deviceId = LRCInstance::avModel().getDeviceIdFromName(deviceName);
+    auto deviceId = lrcInstance_->avModel().getDeviceIdFromName(deviceName);
     if (deviceId.isEmpty()) {
         qWarning() << "Couldn't find device: " << deviceName;
         return;
     }
-    LRCInstance::avModel().setCurrentVideoCaptureDevice(deviceId);
-    LRCInstance::avModel().switchInputTo(deviceId, getCurrentCallId());
+    lrcInstance_->avModel().setCurrentVideoCaptureDevice(deviceId);
+    lrcInstance_->avModel().switchInputTo(deviceId, getCurrentCallId());
 }
 
 void
@@ -88,12 +88,12 @@ AvAdapter::shareEntireScreen(int screenNumber)
         return;
     QRect rect = screen->geometry();
 
-    LRCInstance::avModel().setDisplay(getScreenNumber(),
-                                      rect.x(),
-                                      rect.y(),
-                                      rect.width(),
-                                      rect.height(),
-                                      getCurrentCallId());
+    lrcInstance_->avModel().setDisplay(getScreenNumber(),
+                                       rect.x(),
+                                       rect.y(),
+                                       rect.width(),
+                                       rect.height(),
+                                       getCurrentCallId());
 }
 
 void
@@ -108,7 +108,7 @@ AvAdapter::shareAllScreens()
             height = scr->geometry().height();
     }
 
-    LRCInstance::avModel().setDisplay(getScreenNumber(), 0, 0, width, height, getCurrentCallId());
+    lrcInstance_->avModel().setDisplay(getScreenNumber(), 0, 0, width, height, getCurrentCallId());
 }
 
 void
@@ -167,7 +167,7 @@ AvAdapter::captureAllScreens()
 void
 AvAdapter::shareFile(const QString& filePath)
 {
-    LRCInstance::avModel().setInputFile(filePath, getCurrentCallId());
+    lrcInstance_->avModel().setInputFile(filePath, getCurrentCallId());
 }
 
 void
@@ -181,47 +181,48 @@ AvAdapter::shareScreenArea(unsigned x, unsigned y, unsigned width, unsigned heig
         x = y = width = height = 0;
         xrectsel(&x, &y, &width, &height);
 
-        LRCInstance::avModel().setDisplay(getScreenNumber(),
-                                          x,
-                                          y,
-                                          width < 128 ? 128 : width,
-                                          height < 128 ? 128 : height,
-                                          getCurrentCallId());
+        lrcInstance_->avModel().setDisplay(getScreenNumber(),
+                                           x,
+                                           y,
+                                           width < 128 ? 128 : width,
+                                           height < 128 ? 128 : height,
+                                           getCurrentCallId());
     });
 #else
-    LRCInstance::avModel().setDisplay(getScreenNumber(),
-                                      x,
-                                      y,
-                                      width < 128 ? 128 : width,
-                                      height < 128 ? 128 : height,
-                                      getCurrentCallId());
+    lrcInstance_->avModel().setDisplay(getScreenNumber(),
+                                       x,
+                                       y,
+                                       width < 128 ? 128 : width,
+                                       height < 128 ? 128 : height,
+                                       getCurrentCallId());
 #endif
 }
 
 void
 AvAdapter::startAudioMeter(bool async)
 {
-    LRCInstance::startAudioMeter(async);
+    lrcInstance_->startAudioMeter(async);
 }
 
 void
 AvAdapter::stopAudioMeter(bool async)
 {
-    LRCInstance::stopAudioMeter(async);
+    lrcInstance_->stopAudioMeter(async);
 }
 
 QString
 AvAdapter::getCurrentCallId()
 {
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(LRCInstance::getCurrentConvUid());
-    auto call = LRCInstance::getCallInfoForConversation(convInfo);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(
+        lrcInstance_->getCurrentConvUid());
+    auto call = lrcInstance_->getCallInfoForConversation(convInfo);
     return call ? call->id : QString();
 }
 
 void
 AvAdapter::slotDeviceEvent()
 {
-    auto& avModel = LRCInstance::avModel();
+    auto& avModel = lrcInstance_->avModel();
     auto defaultDevice = avModel.getDefaultDevice();
     auto currentCaptureDevice = avModel.getCurrentVideoCaptureDevice();
     QString callId = getCurrentCallId();
@@ -246,7 +247,7 @@ AvAdapter::slotDeviceEvent()
     }
 
     auto cb = [this, currentDeviceListSize, deviceEvent, defaultDevice, callId] {
-        auto& avModel = LRCInstance::avModel();
+        auto& avModel = lrcInstance_->avModel();
         if (currentDeviceListSize == 0) {
             avModel.clearCurrentVideoCaptureDevice();
             avModel.switchInputTo({}, callId);
@@ -258,8 +259,8 @@ AvAdapter::slotDeviceEvent()
         }
     };
 
-    if (LRCInstance::renderer()->isPreviewing()) {
-        Utils::oneShotConnect(LRCInstance::renderer(),
+    if (lrcInstance_->renderer()->isPreviewing()) {
+        Utils::oneShotConnect(lrcInstance_->renderer(),
                               &RenderManager::previewRenderingStopped,
                               [cb] { QtConcurrent::run([cb]() { cb(); }); });
     } else {
@@ -267,7 +268,7 @@ AvAdapter::slotDeviceEvent()
             avModel.setDefaultDevice(defaultDevice);
             avModel.setCurrentVideoCaptureDevice(defaultDevice);
             if (callId.isEmpty())
-                LRCInstance::renderer()->startPreviewing();
+                lrcInstance_->renderer()->startPreviewing();
             else
                 avModel.switchInputTo(defaultDevice, callId);
         } else {
diff --git a/src/avadapter.h b/src/avadapter.h
index 0e33c5ae6..d3a66ed54 100644
--- a/src/avadapter.h
+++ b/src/avadapter.h
@@ -29,14 +29,12 @@ class AvAdapter final : public QmlAdapterBase
     Q_OBJECT
 
 public:
-    explicit AvAdapter(QObject* parent = nullptr);
+    explicit AvAdapter(QObject* parent = nullptr, LRCInstance* instance = nullptr);
     ~AvAdapter() = default;
 
 signals:
 
-    /*
-     * Emitted when the size of the video capture device list changes.
-     */
+    // Emitted when the size of the video capture device list changes.
     void videoDeviceListChanged(bool listIsEmpty);
 
     void screenCaptured(int screenNumber, QString source);
@@ -44,72 +42,46 @@ signals:
 protected:
     void safeInit() override {};
 
-    /*
-     * Return needed info for populating video device context menu item.
-     */
+    // Return needed info for populating video device context menu item.
     Q_INVOKABLE QVariantMap populateVideoDeviceContextMenuItem();
 
-    /*
-     * Preview video input switching.
-     */
+    // Preview video input switching.
     Q_INVOKABLE void onVideoContextMenuDeviceItemClicked(const QString& deviceName);
 
-    /*
-     * Share the screen specificed by screen number.
-     */
+    // Share the screen specificed by screen number.
     Q_INVOKABLE void shareEntireScreen(int screenNumber);
 
-    /*
-     * Share the all screens connected.
-     */
+    // Share the all screens connected.
     Q_INVOKABLE void shareAllScreens();
 
-    /*
-     * Take snap shot of the screen and return emitting signal.
-     */
+    // Take snap shot of the screen and return emitting signal.
     Q_INVOKABLE void captureScreen(int screenNumber);
 
-    /*
-     * Take snap shot of the all screens and return by emitting signal.
-     */
+    // Take snap shot of the all screens and return by emitting signal.
     Q_INVOKABLE void captureAllScreens();
 
-    /*
-     * Share a media file.
-     */
+    // Share a media file.
     Q_INVOKABLE void shareFile(const QString& filePath);
 
-    /*
-     * Select screen area to display (from all screens).
-     */
+    // Select screen area to display (from all screens).
     Q_INVOKABLE void shareScreenArea(unsigned x, unsigned y, unsigned width, unsigned height);
 
     Q_INVOKABLE void startAudioMeter(bool async);
     Q_INVOKABLE void stopAudioMeter(bool async);
 
 private:
-    /*
-     * Get current callId from current selected conv id.
-     */
+    // Get current callId from current selected conv id.
     QString getCurrentCallId();
 
-    /*
-     * Used to classify capture device events.
-     */
+    // Used to classify capture device events.
     enum class DeviceEvent { Added, RemovedCurrent, None };
 
-    /*
-     * Used to track the capture device count.
-     */
+    // Used to track the capture device count.
     int deviceListSize_;
 
-    /*
-     * Device changed slot.
-     */
+    // Device changed slot.
     void slotDeviceEvent();
 
-    /*
-     * Get the screen number
-     */
+    // Get the screen number
     int getScreenNumber() const;
 };
diff --git a/src/avatarimageprovider.h b/src/avatarimageprovider.h
index 49a4165be..60b9f4d74 100644
--- a/src/avatarimageprovider.h
+++ b/src/avatarimageprovider.h
@@ -18,18 +18,19 @@
 
 #pragma once
 
+#include "quickimageproviderbase.h"
 #include "utils.h"
 #include "lrcinstance.h"
 
 #include <QImage>
-#include <QQuickImageProvider>
 
-class AvatarImageProvider : public QObject, public QQuickImageProvider
+class AvatarImageProvider : public QuickImageProviderBase
 {
 public:
-    AvatarImageProvider()
-        : QQuickImageProvider(QQuickImageProvider::Image,
-                              QQmlImageProviderBase::ForceAsynchronousImageLoading)
+    AvatarImageProvider(LRCInstance* instance = nullptr)
+        : QuickImageProviderBase(QQuickImageProvider::Image,
+                                  QQmlImageProviderBase::ForceAsynchronousImageLoading,
+                                  instance)
     {}
 
     /*
@@ -55,13 +56,14 @@ public:
             return QImage();
 
         if (idType == "account") {
-            return Utils::accountPhoto(LRCInstance::accountModel().getAccountInfo(idContent),
+            return Utils::accountPhoto(lrcInstance_,
+                                       lrcInstance_->accountModel().getAccountInfo(idContent),
                                        requestedSize);
         } else if (idType == "conversation") {
-            const auto& convInfo = LRCInstance::getConversationFromConvUid(idContent);
-            return Utils::contactPhoto(convInfo.participants[0], requestedSize);
+            const auto& convInfo = lrcInstance_->getConversationFromConvUid(idContent);
+            return Utils::contactPhoto(lrcInstance_, convInfo.participants[0], requestedSize);
         } else if (idType == "contact") {
-            return Utils::contactPhoto(idContent, requestedSize);
+            return Utils::contactPhoto(lrcInstance_, idContent, requestedSize);
         } else if (idType == "fallback") {
             return Utils::fallbackAvatar(QString(), idContent, requestedSize);
         } else if (idType == "default") {
diff --git a/src/bannedlistmodel.cpp b/src/bannedlistmodel.cpp
index 684f5b443..68caa29ac 100644
--- a/src/bannedlistmodel.cpp
+++ b/src/bannedlistmodel.cpp
@@ -18,10 +18,11 @@
  */
 
 #include "bannedlistmodel.h"
+
 #include "lrcinstance.h"
 
 BannedListModel::BannedListModel(QObject* parent)
-    : QAbstractListModel(parent)
+    : AbstractListModelBase(parent)
 {}
 
 BannedListModel::~BannedListModel() {}
@@ -29,8 +30,8 @@ BannedListModel::~BannedListModel() {}
 int
 BannedListModel::rowCount(const QModelIndex& parent) const
 {
-    if (!parent.isValid()) {
-        return LRCInstance::getCurrentAccountInfo().contactModel->getBannedContacts().size();
+    if (!parent.isValid() && lrcInstance_) {
+        return lrcInstance_->getCurrentAccountInfo().contactModel->getBannedContacts().size();
     }
     return 0;
 }
@@ -48,12 +49,12 @@ BannedListModel::columnCount(const QModelIndex& parent) const
 QVariant
 BannedListModel::data(const QModelIndex& index, int role) const
 {
-    auto contactList = LRCInstance::getCurrentAccountInfo().contactModel->getBannedContacts();
+    auto contactList = lrcInstance_->getCurrentAccountInfo().contactModel->getBannedContacts();
     if (!index.isValid() || contactList.size() <= index.row()) {
         return QVariant();
     }
 
-    auto contactInfo = LRCInstance::getCurrentAccountInfo().contactModel->getContact(
+    auto contactInfo = lrcInstance_->getCurrentAccountInfo().contactModel->getContact(
         contactList.at(index.row()));
 
     switch (role) {
diff --git a/src/bannedlistmodel.h b/src/bannedlistmodel.h
index a44abc883..aa7d5ff5d 100644
--- a/src/bannedlistmodel.h
+++ b/src/bannedlistmodel.h
@@ -19,9 +19,9 @@
 
 #pragma once
 
-#include <QAbstractListModel>
+#include "abstractitemmodelbase.h"
 
-class BannedListModel : public QAbstractListModel
+class BannedListModel : public AbstractListModelBase
 {
     Q_OBJECT
 public:
diff --git a/src/calladapter.cpp b/src/calladapter.cpp
index 614ce2081..99bfd008e 100644
--- a/src/calladapter.cpp
+++ b/src/calladapter.cpp
@@ -27,79 +27,76 @@
 
 #include <QApplication>
 
-CallAdapter::CallAdapter(QObject* parent)
-    : QmlAdapterBase(parent)
+CallAdapter::CallAdapter(QObject* parent, LRCInstance* instance)
+    : QmlAdapterBase(parent, instance)
     , oneSecondTimer_(new QTimer(this))
 {
-    accountId_ = LRCInstance::getCurrAccId();
+    accountId_ = lrcInstance_->getCurrAccId();
     connectCallModel(accountId_);
 
-    connect(&LRCInstance::behaviorController(),
+    connect(&lrcInstance_->behaviorController(),
             &BehaviorController::showIncomingCallView,
             this,
             &CallAdapter::onShowIncomingCallView);
 
-    connect(&LRCInstance::behaviorController(),
+    connect(&lrcInstance_->behaviorController(),
             &BehaviorController::showCallView,
             this,
             &CallAdapter::onShowCallView);
 
-    connect(&LRCInstance::instance(),
-            &LRCInstance::currentAccountChanged,
-            this,
-            &CallAdapter::onAccountChanged);
+    connect(lrcInstance_, &LRCInstance::currentAccountChanged, this, &CallAdapter::onAccountChanged);
 }
 
 void
 CallAdapter::onAccountChanged()
 {
-    accountId_ = LRCInstance::getCurrAccId();
+    accountId_ = lrcInstance_->getCurrAccId();
     connectCallModel(accountId_);
 }
 
 void
 CallAdapter::placeAudioOnlyCall()
 {
-    const auto convUid = LRCInstance::getCurrentConvUid();
+    const auto convUid = lrcInstance_->getCurrentConvUid();
     if (!convUid.isEmpty()) {
-        LRCInstance::getCurrentConversationModel()->placeAudioOnlyCall(convUid);
+        lrcInstance_->getCurrentConversationModel()->placeAudioOnlyCall(convUid);
     }
 }
 
 void
 CallAdapter::placeCall()
 {
-    const auto convUid = LRCInstance::getCurrentConvUid();
+    const auto convUid = lrcInstance_->getCurrentConvUid();
     if (!convUid.isEmpty()) {
-        LRCInstance::getCurrentConversationModel()->placeCall(convUid);
+        lrcInstance_->getCurrentConversationModel()->placeCall(convUid);
     }
 }
 
 void
 CallAdapter::hangUpACall(const QString& accountId, const QString& convUid)
 {
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid, accountId);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
     if (!convInfo.uid.isEmpty()) {
-        LRCInstance::getAccountInfo(accountId).callModel->hangUp(convInfo.callId);
+        lrcInstance_->getAccountInfo(accountId).callModel->hangUp(convInfo.callId);
     }
 }
 
 void
 CallAdapter::refuseACall(const QString& accountId, const QString& convUid)
 {
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid, accountId);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
     if (!convInfo.uid.isEmpty()) {
-        LRCInstance::getAccountInfo(accountId).callModel->refuse(convInfo.callId);
+        lrcInstance_->getAccountInfo(accountId).callModel->refuse(convInfo.callId);
     }
 }
 
 void
 CallAdapter::acceptACall(const QString& accountId, const QString& convUid)
 {
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid, accountId);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
     if (!convInfo.uid.isEmpty()) {
-        LRCInstance::getAccountInfo(accountId).callModel->accept(convInfo.callId);
-        auto& accInfo = LRCInstance::getAccountInfo(convInfo.accountId);
+        lrcInstance_->getAccountInfo(accountId).callModel->accept(convInfo.callId);
+        auto& accInfo = lrcInstance_->getAccountInfo(convInfo.accountId);
         accInfo.callModel->setCurrentCall(convInfo.callId);
 
         auto contactUri = convInfo.participants.front();
@@ -109,7 +106,7 @@ CallAdapter::acceptACall(const QString& accountId, const QString& convUid)
         try {
             auto& contact = accInfo.contactModel->getContact(contactUri);
             if (contact.profileInfo.type == lrc::api::profile::Type::PENDING) {
-                LRCInstance::getCurrentConversationModel()->makePermanent(convInfo.uid);
+                lrcInstance_->getCurrentConversationModel()->makePermanent(convInfo.uid);
             }
         } catch (...) {
         }
@@ -119,12 +116,12 @@ CallAdapter::acceptACall(const QString& accountId, const QString& convUid)
 void
 CallAdapter::onShowIncomingCallView(const QString& accountId, const QString& convUid)
 {
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid, accountId);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
     if (convInfo.uid.isEmpty()) {
         return;
     }
-    auto selectedAccountId = LRCInstance::getCurrAccId();
-    auto* callModel = LRCInstance::getCurrentCallModel();
+    auto selectedAccountId = lrcInstance_->getCurrAccId();
+    auto* callModel = lrcInstance_->getCurrentCallModel();
 
     if (!callModel->hasCall(convInfo.callId)) {
         if (QApplication::focusObject() == nullptr || accountId != selectedAccountId) {
@@ -132,8 +129,8 @@ CallAdapter::onShowIncomingCallView(const QString& accountId, const QString& con
             return;
         }
 
-        const auto& currentConvInfo = LRCInstance::getConversationFromConvUid(
-            LRCInstance::getCurrentConvUid());
+        const auto& currentConvInfo = lrcInstance_->getConversationFromConvUid(
+            lrcInstance_->getCurrentConvUid());
 
         // Current call
         auto currentConvHasCall = callModel->hasCall(currentConvInfo.callId);
@@ -146,19 +143,19 @@ CallAdapter::onShowIncomingCallView(const QString& accountId, const QString& con
             }
         }
         emit callSetupMainViewRequired(accountId, convInfo.uid);
-        emit LRCInstance::instance().updateSmartList();
+        emit lrcInstance_->updateSmartList();
         return;
     }
 
     auto call = callModel->getCall(convInfo.callId);
-    auto isCallSelected = LRCInstance::getCurrentConvUid() == convInfo.uid;
+    auto isCallSelected = lrcInstance_->getCurrentConvUid() == convInfo.uid;
 
     if (call.isOutgoing) {
         if (isCallSelected) {
             emit callSetupMainViewRequired(accountId, convInfo.uid);
         }
     } else {
-        auto accountProperties = LRCInstance::accountModel().getAccountConfig(selectedAccountId);
+        auto accountProperties = lrcInstance_->accountModel().getAccountConfig(selectedAccountId);
         if (!accountProperties.isRendezVous) {
             // App not focused or in different account
             if (QApplication::focusObject() == nullptr || accountId != selectedAccountId) {
@@ -166,8 +163,8 @@ CallAdapter::onShowIncomingCallView(const QString& accountId, const QString& con
                 return;
             }
 
-            const auto& currentConvInfo = LRCInstance::getConversationFromConvUid(
-                LRCInstance::getCurrentConvUid());
+            const auto& currentConvInfo = lrcInstance_->getConversationFromConvUid(
+                lrcInstance_->getCurrentConvUid());
 
             // Call in current conversation
             auto currentConvHasCall = callModel->hasCall(currentConvInfo.callId);
@@ -200,13 +197,13 @@ CallAdapter::onShowIncomingCallView(const QString& accountId, const QString& con
         }
     }
     emit callStatusChanged(static_cast<int>(call.status), accountId, convInfo.uid);
-    emit LRCInstance::instance().updateSmartList();
+    emit lrcInstance_->updateSmartList();
 }
 
 void
 CallAdapter::onShowCallView(const QString& accountId, const QString& convUid)
 {
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid, accountId);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
     if (convInfo.uid.isEmpty()) {
         return;
     }
@@ -219,12 +216,12 @@ CallAdapter::updateCall(const QString& convUid, const QString& accountId, bool f
     accountId_ = accountId.isEmpty() ? accountId_ : accountId;
     convUid_ = convUid.isEmpty() ? convUid_ : convUid;
 
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid_);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid_);
     if (convInfo.uid.isEmpty()) {
         return;
     }
 
-    auto call = LRCInstance::getCallInfoForConversation(convInfo, forceCallOnly);
+    auto call = lrcInstance_->getCallInfoForConversation(convInfo, forceCallOnly);
     if (!call) {
         return;
     }
@@ -234,8 +231,8 @@ CallAdapter::updateCall(const QString& convUid, const QString& accountId, bool f
     emit previewVisibilityNeedToChange(shouldShowPreview(forceCallOnly));
 
     if (call->status == lrc::api::call::Status::IN_PROGRESS) {
-        LRCInstance::renderer()->addDistantRenderer(call->id);
-        LRCInstance::getAccountInfo(accountId_).callModel->setCurrentCall(call->id);
+        lrcInstance_->renderer()->addDistantRenderer(call->id);
+        lrcInstance_->getAccountInfo(accountId_).callModel->setCurrentCall(call->id);
     }
 }
 
@@ -243,12 +240,12 @@ bool
 CallAdapter::shouldShowPreview(bool force)
 {
     bool shouldShowPreview {false};
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid_);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid_);
 
     if (convInfo.uid.isEmpty()) {
         return shouldShowPreview;
     }
-    auto call = LRCInstance::getCallInfoForConversation(convInfo, force);
+    auto call = lrcInstance_->getCallInfoForConversation(convInfo, force);
     if (call) {
         shouldShowPreview = !call->isAudioOnly && !(call->status == lrc::api::call::Status::PAUSED)
                             && !call->videoMuted && call->participantsInfos.isEmpty();
@@ -271,7 +268,7 @@ CallAdapter::fillParticipantData(QMap<QString, QString> participant)
     data["audioModeratorMuted"] = participant["audioModeratorMuted"] == "true";
 
     auto bestName = participant["uri"];
-    auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId_);
+    auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId_);
     data["isLocal"] = false;
     if (bestName == accInfo.profileInfo.uri) {
         bestName = tr("me");
@@ -280,9 +277,9 @@ CallAdapter::fillParticipantData(QMap<QString, QString> participant)
             data["avatar"] = accInfo.profileInfo.avatar;
     } else {
         try {
-            auto& contact = LRCInstance::getCurrentAccountInfo().contactModel->getContact(
+            auto& contact = lrcInstance_->getCurrentAccountInfo().contactModel->getContact(
                 participant["uri"]);
-            bestName = LRCInstance::getCurrentAccountInfo().contactModel->bestNameForContact(
+            bestName = lrcInstance_->getCurrentAccountInfo().contactModel->bestNameForContact(
                 participant["uri"]);
             if (participant["videoMuted"] == "true")
                 data["avatar"] = contact.profileInfo.avatar;
@@ -299,13 +296,13 @@ QVariantList
 CallAdapter::getConferencesInfos()
 {
     QVariantList map;
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid_);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid_);
     if (convInfo.uid.isEmpty())
         return map;
     auto callId = convInfo.confId.isEmpty() ? convInfo.callId : convInfo.confId;
     if (!callId.isEmpty()) {
         try {
-            auto call = LRCInstance::getCurrentCallModel()->getCall(callId);
+            auto call = lrcInstance_->getCurrentCallModel()->getCall(callId);
             for (const auto& participant : call.participantsInfos) {
                 QJsonObject data = fillParticipantData(participant);
                 map.push_back(QVariant(data));
@@ -321,29 +318,29 @@ void
 CallAdapter::showNotification(const QString& accountId, const QString& convUid)
 {
     QString from {};
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid, accountId);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
     if (!accountId.isEmpty() && !convInfo.uid.isEmpty()) {
-        auto& accInfo = LRCInstance::getAccountInfo(accountId);
+        auto& accInfo = lrcInstance_->getAccountInfo(accountId);
         if (!convInfo.participants.isEmpty())
             from = accInfo.contactModel->bestNameForContact(convInfo.participants[0]);
     }
 
     auto onClicked = [this, accountId, convUid = convInfo.uid]() {
-        const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid, accountId);
+        const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
         if (convInfo.uid.isEmpty()) {
             return;
         }
-        emit LRCInstance::instance().notificationClicked();
+        emit lrcInstance_->notificationClicked();
         emit callSetupMainViewRequired(convInfo.accountId, convInfo.uid);
     };
-    emit LRCInstance::instance().updateSmartList();
+    emit lrcInstance_->updateSmartList();
     Utils::showNotification(tr("is calling you"), from, accountId, convUid, onClicked);
 }
 
 void
 CallAdapter::connectCallModel(const QString& accountId)
 {
-    auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId);
+    auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
 
     QObject::disconnect(callStatusChangedConnection_);
     QObject::disconnect(onParticipantsChangedConnection_);
@@ -352,10 +349,12 @@ CallAdapter::connectCallModel(const QString& accountId)
         = QObject::connect(accInfo.callModel.get(),
                            &lrc::api::NewCallModel::onParticipantsChanged,
                            [this, accountId](const QString& confId) {
-                               auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId);
+                               auto& accInfo = lrcInstance_->accountModel().getAccountInfo(
+                                   accountId);
                                auto& callModel = accInfo.callModel;
                                auto call = callModel->getCall(confId);
-                               const auto& convInfo = LRCInstance::getConversationFromCallId(confId);
+                               const auto& convInfo = lrcInstance_->getConversationFromCallId(
+                                   confId);
                                if (!convInfo.uid.isEmpty()) {
                                    QVariantList map;
                                    for (const auto& participant : call.participantsInfos) {
@@ -371,14 +370,14 @@ CallAdapter::connectCallModel(const QString& accountId)
         accInfo.callModel.get(),
         &lrc::api::NewCallModel::callStatusChanged,
         [this, accountId](const QString& callId) {
-            auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId);
+            auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
             auto& callModel = accInfo.callModel;
             const auto call = callModel->getCall(callId);
 
             /*
              * Change status label text.
              */
-            const auto& convInfo = LRCInstance::getConversationFromCallId(callId);
+            const auto& convInfo = lrcInstance_->getConversationFromCallId(callId);
             if (!convInfo.uid.isEmpty()) {
                 emit callStatusChanged(static_cast<int>(call.status), accountId, convInfo.uid);
                 updateCallOverlay(convInfo);
@@ -391,7 +390,7 @@ CallAdapter::connectCallModel(const QString& accountId)
             case lrc::api::call::Status::PEER_BUSY:
             case lrc::api::call::Status::TIMEOUT:
             case lrc::api::call::Status::TERMINATING: {
-                LRCInstance::renderer()->removeDistantRenderer(callId);
+                lrcInstance_->renderer()->removeDistantRenderer(callId);
                 if (convInfo.uid.isEmpty()) {
                     break;
                 }
@@ -401,17 +400,16 @@ CallAdapter::connectCallModel(const QString& accountId)
                  */
                 bool forceCallOnly {false};
                 if (!convInfo.confId.isEmpty()) {
-                    auto callList = LRCInstance::getAPI().getConferenceSubcalls(convInfo.confId);
+                    auto callList = lrcInstance_->getAPI().getConferenceSubcalls(convInfo.confId);
                     if (callList.empty()) {
-                        auto lastConference = LRCInstance::instance().poplastConference(
-                            convInfo.confId);
+                        auto lastConference = lrcInstance_->poplastConference(convInfo.confId);
                         if (!lastConference.isEmpty()) {
                             callList.append(lastConference);
                             forceCallOnly = true;
                         }
                     }
                     if (callList.isEmpty()) {
-                        callList = LRCInstance::getActiveCalls();
+                        callList = lrcInstance_->getActiveCalls();
                         forceCallOnly = true;
                     }
                     for (const auto& callId : callList) {
@@ -420,12 +418,12 @@ CallAdapter::connectCallModel(const QString& accountId)
                         }
                         auto currentCall = callModel->getCall(callId);
                         if (currentCall.status == lrc::api::call::Status::IN_PROGRESS) {
-                            const auto& otherConv = LRCInstance::getConversationFromCallId(callId);
+                            const auto& otherConv = lrcInstance_->getConversationFromCallId(callId);
                             if (!otherConv.uid.isEmpty() && otherConv.uid != convInfo.uid) {
                                 /*
                                  * Reset the call view corresponding accountId, uid.
                                  */
-                                LRCInstance::setSelectedConvId(otherConv.uid);
+                                lrcInstance_->setSelectedConvId(otherConv.uid);
                                 updateCall(otherConv.uid, otherConv.accountId, forceCallOnly);
                             }
                         }
@@ -436,8 +434,8 @@ CallAdapter::connectCallModel(const QString& accountId)
             }
             case lrc::api::call::Status::CONNECTED:
             case lrc::api::call::Status::IN_PROGRESS: {
-                const auto& convInfo = LRCInstance::getConversationFromCallId(callId, accountId);
-                if (!convInfo.uid.isEmpty() && convInfo.uid == LRCInstance::getCurrentConvUid()) {
+                const auto& convInfo = lrcInstance_->getConversationFromCallId(callId, accountId);
+                if (!convInfo.uid.isEmpty() && convInfo.uid == lrcInstance_->getCurrentConvUid()) {
                     accInfo.conversationModel->selectConversation(convInfo.uid);
                 }
                 updateCall(convInfo.uid, accountId);
@@ -450,17 +448,17 @@ CallAdapter::connectCallModel(const QString& accountId)
                 break;
             }
 
-            emit LRCInstance::instance().updateSmartList();
+            emit lrcInstance_->updateSmartList();
         });
 
     remoteRecordingChangedConnection_ = QObject::connect(
         accInfo.callModel.get(),
         &lrc::api::NewCallModel::remoteRecordingChanged,
         [this](const QString& callId, const QSet<QString>& peerRec, bool state) {
-            const auto currentCallId = LRCInstance::getCallIdForConversationUid(convUid_,
-                                                                                accountId_);
+            const auto currentCallId = lrcInstance_->getCallIdForConversationUid(convUid_,
+                                                                                 accountId_);
             if (callId == currentCallId) {
-                const auto& accInfo = LRCInstance::getCurrentAccountInfo();
+                const auto& accInfo = lrcInstance_->getCurrentAccountInfo();
                 QStringList peers {};
                 for (const auto& uri : peerRec) {
                     auto bestName = accInfo.contactModel->bestNameForContact(uri);
@@ -480,12 +478,12 @@ CallAdapter::connectCallModel(const QString& accountId)
 void
 CallAdapter::sipInputPanelPlayDTMF(const QString& key)
 {
-    auto callId = LRCInstance::getCallIdForConversationUid(convUid_, accountId_);
-    if (callId.isEmpty() || !LRCInstance::getCurrentCallModel()->hasCall(callId)) {
+    auto callId = lrcInstance_->getCallIdForConversationUid(convUid_, accountId_);
+    if (callId.isEmpty() || !lrcInstance_->getCurrentCallModel()->hasCall(callId)) {
         return;
     }
 
-    LRCInstance::getCurrentCallModel()->playDTMF(callId, key);
+    lrcInstance_->getCurrentCallModel()->playDTMF(callId, key);
 }
 
 /*
@@ -498,9 +496,9 @@ CallAdapter::updateCallOverlay(const lrc::api::conversation::Info& convInfo)
     QObject::disconnect(oneSecondTimer_);
     QObject::connect(oneSecondTimer_, &QTimer::timeout, [this] { setTime(accountId_, convUid_); });
     oneSecondTimer_->start(20);
-    auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId_);
+    auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId_);
 
-    auto* call = LRCInstance::getCallInfoForConversation(convInfo);
+    auto* call = lrcInstance_->getCallInfoForConversation(convInfo);
     if (!call) {
         return;
     }
@@ -527,20 +525,20 @@ CallAdapter::updateCallOverlay(const lrc::api::conversation::Info& convInfo)
 void
 CallAdapter::hangupCall(const QString& uri)
 {
-    const auto& convInfo = LRCInstance::getConversationFromPeerUri(uri, accountId_);
+    const auto& convInfo = lrcInstance_->getConversationFromPeerUri(uri, accountId_);
     if (!convInfo.uid.isEmpty()) {
-        auto callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
+        auto callModel = lrcInstance_->getAccountInfo(accountId_).callModel.get();
         if (callModel->hasCall(convInfo.callId)) {
             /*
              * Store the last remaining participant of the conference,
              * so we can switch the smartlist index after termination.
              */
             if (!convInfo.confId.isEmpty()) {
-                auto callList = LRCInstance::getAPI().getConferenceSubcalls(convInfo.confId);
+                auto callList = lrcInstance_->getAPI().getConferenceSubcalls(convInfo.confId);
                 if (callList.size() == 2) {
                     for (const auto& cId : callList) {
                         if (cId != convInfo.callId) {
-                            LRCInstance::instance().pushlastConference(convInfo.confId, cId);
+                            lrcInstance_->pushlastConference(convInfo.confId, cId);
                         }
                     }
                 }
@@ -553,9 +551,9 @@ CallAdapter::hangupCall(const QString& uri)
 void
 CallAdapter::maximizeParticipant(const QString& uri)
 {
-    auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(LRCInstance::getCurrentConvUid(),
-                                                                   accountId_);
+    auto* callModel = lrcInstance_->getAccountInfo(accountId_).callModel.get();
+    const auto& convInfo
+        = lrcInstance_->getConversationFromConvUid(lrcInstance_->getCurrentConvUid(), accountId_);
 
     auto confId = convInfo.confId;
     if (confId.isEmpty())
@@ -586,9 +584,9 @@ CallAdapter::maximizeParticipant(const QString& uri)
 void
 CallAdapter::minimizeParticipant(const QString& uri)
 {
-    auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(LRCInstance::getCurrentConvUid(),
-                                                                   accountId_);
+    auto* callModel = lrcInstance_->getAccountInfo(accountId_).callModel.get();
+    const auto& convInfo
+        = lrcInstance_->getConversationFromConvUid(lrcInstance_->getCurrentConvUid(), accountId_);
     auto confId = convInfo.confId;
 
     if (confId.isEmpty())
@@ -617,9 +615,9 @@ CallAdapter::minimizeParticipant(const QString& uri)
 void
 CallAdapter::hangUpThisCall()
 {
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid_, accountId_);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid_, accountId_);
     if (!convInfo.uid.isEmpty()) {
-        auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
+        auto* callModel = lrcInstance_->getAccountInfo(accountId_).callModel.get();
         if (!convInfo.confId.isEmpty() && callModel->hasCall(convInfo.confId)) {
             callModel->hangUp(convInfo.confId);
         } else if (callModel->hasCall(convInfo.callId)) {
@@ -631,8 +629,8 @@ CallAdapter::hangUpThisCall()
 bool
 CallAdapter::isRecordingThisCall()
 {
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid_, accountId_);
-    auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId_);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid_, accountId_);
+    auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId_);
     return accInfo.callModel->isRecording(convInfo.confId)
            || accInfo.callModel->isRecording(convInfo.callId);
 }
@@ -640,9 +638,9 @@ CallAdapter::isRecordingThisCall()
 bool
 CallAdapter::isCurrentHost() const
 {
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid_, accountId_);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid_, accountId_);
     if (!convInfo.uid.isEmpty()) {
-        auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
+        auto* callModel = lrcInstance_->getAccountInfo(accountId_).callModel.get();
         try {
             auto confId = convInfo.confId;
             if (confId.isEmpty())
@@ -662,9 +660,9 @@ CallAdapter::isCurrentHost() const
 bool
 CallAdapter::participantIsHost(const QString& uri) const
 {
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid_);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid_);
     if (!convInfo.uid.isEmpty()) {
-        auto& accInfo = LRCInstance::getAccountInfo(accountId_);
+        auto& accInfo = lrcInstance_->getAccountInfo(accountId_);
         auto* callModel = accInfo.callModel.get();
         try {
             if (isCurrentHost()) {
@@ -683,8 +681,8 @@ CallAdapter::participantIsHost(const QString& uri) const
 bool
 CallAdapter::isModerator(const QString& uri) const
 {
-    auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid_);
+    auto* callModel = lrcInstance_->getAccountInfo(accountId_).callModel.get();
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid_);
     auto confId = convInfo.confId;
 
     if (confId.isEmpty())
@@ -699,15 +697,15 @@ CallAdapter::isModerator(const QString& uri) const
 bool
 CallAdapter::isCurrentModerator() const
 {
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid_);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid_);
     if (!convInfo.uid.isEmpty()) {
-        auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
+        auto* callModel = lrcInstance_->getAccountInfo(accountId_).callModel.get();
         try {
             auto call = callModel->getCall(convInfo.callId);
             if (call.participantsInfos.size() == 0) {
                 return true;
             } else {
-                auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId_);
+                auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId_);
                 for (const auto& participant : call.participantsInfos) {
                     if (participant["uri"] == accInfo.profileInfo.uri)
                         return participant["isModerator"] == "true";
@@ -723,8 +721,8 @@ CallAdapter::isCurrentModerator() const
 void
 CallAdapter::setModerator(const QString& uri, const bool state)
 {
-    auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid_);
+    auto* callModel = lrcInstance_->getAccountInfo(accountId_).callModel.get();
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid_);
     auto confId = convInfo.confId;
     if (confId.isEmpty())
         confId = convInfo.callId;
@@ -737,8 +735,8 @@ CallAdapter::setModerator(const QString& uri, const bool state)
 void
 CallAdapter::muteParticipant(const QString& uri, const bool state)
 {
-    auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid_);
+    auto* callModel = lrcInstance_->getAccountInfo(accountId_).callModel.get();
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid_);
     auto confId = convInfo.confId;
 
     if (confId.isEmpty())
@@ -753,8 +751,8 @@ CallAdapter::muteParticipant(const QString& uri, const bool state)
 CallAdapter::MuteStates
 CallAdapter::getMuteState(const QString& uri) const
 {
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid_);
-    auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid_);
+    auto* callModel = lrcInstance_->getAccountInfo(accountId_).callModel.get();
     auto confId = convInfo.confId.isEmpty() ? convInfo.callId : convInfo.confId;
     try {
         auto call = callModel->getCall(confId);
@@ -785,8 +783,8 @@ CallAdapter::getMuteState(const QString& uri) const
 void
 CallAdapter::hangupParticipant(const QString& uri)
 {
-    auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid_);
+    auto* callModel = lrcInstance_->getAccountInfo(accountId_).callModel.get();
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid_);
     auto confId = convInfo.confId;
 
     if (confId.isEmpty())
@@ -801,11 +799,11 @@ CallAdapter::hangupParticipant(const QString& uri)
 void
 CallAdapter::holdThisCallToggle()
 {
-    const auto callId = LRCInstance::getCallIdForConversationUid(convUid_, accountId_);
-    if (callId.isEmpty() || !LRCInstance::getCurrentCallModel()->hasCall(callId)) {
+    const auto callId = lrcInstance_->getCallIdForConversationUid(convUid_, accountId_);
+    if (callId.isEmpty() || !lrcInstance_->getCurrentCallModel()->hasCall(callId)) {
         return;
     }
-    auto* callModel = LRCInstance::getCurrentCallModel();
+    auto* callModel = lrcInstance_->getCurrentCallModel();
     if (callModel->hasCall(callId)) {
         callModel->togglePause(callId);
     }
@@ -815,11 +813,11 @@ CallAdapter::holdThisCallToggle()
 void
 CallAdapter::muteThisCallToggle()
 {
-    const auto callId = LRCInstance::getCallIdForConversationUid(convUid_, accountId_);
-    if (callId.isEmpty() || !LRCInstance::getCurrentCallModel()->hasCall(callId)) {
+    const auto callId = lrcInstance_->getCallIdForConversationUid(convUid_, accountId_);
+    if (callId.isEmpty() || !lrcInstance_->getCurrentCallModel()->hasCall(callId)) {
         return;
     }
-    auto* callModel = LRCInstance::getCurrentCallModel();
+    auto* callModel = lrcInstance_->getCurrentCallModel();
     if (callModel->hasCall(callId)) {
         callModel->toggleMedia(callId, lrc::api::NewCallModel::Media::AUDIO);
     }
@@ -828,11 +826,11 @@ CallAdapter::muteThisCallToggle()
 void
 CallAdapter::recordThisCallToggle()
 {
-    const auto callId = LRCInstance::getCallIdForConversationUid(convUid_, accountId_);
-    if (callId.isEmpty() || !LRCInstance::getCurrentCallModel()->hasCall(callId)) {
+    const auto callId = lrcInstance_->getCallIdForConversationUid(convUid_, accountId_);
+    if (callId.isEmpty() || !lrcInstance_->getCurrentCallModel()->hasCall(callId)) {
         return;
     }
-    auto* callModel = LRCInstance::getCurrentCallModel();
+    auto* callModel = lrcInstance_->getCurrentCallModel();
     if (callModel->hasCall(callId)) {
         callModel->toggleAudioRecord(callId);
     }
@@ -841,11 +839,11 @@ CallAdapter::recordThisCallToggle()
 void
 CallAdapter::videoPauseThisCallToggle()
 {
-    const auto callId = LRCInstance::getCallIdForConversationUid(convUid_, accountId_);
-    if (callId.isEmpty() || !LRCInstance::getCurrentCallModel()->hasCall(callId)) {
+    const auto callId = lrcInstance_->getCallIdForConversationUid(convUid_, accountId_);
+    if (callId.isEmpty() || !lrcInstance_->getCurrentCallModel()->hasCall(callId)) {
         return;
     }
-    auto* callModel = LRCInstance::getCurrentCallModel();
+    auto* callModel = lrcInstance_->getCurrentCallModel();
     if (callModel->hasCall(callId)) {
         callModel->toggleMedia(callId, lrc::api::NewCallModel::Media::VIDEO);
     }
@@ -855,14 +853,14 @@ CallAdapter::videoPauseThisCallToggle()
 void
 CallAdapter::setTime(const QString& accountId, const QString& convUid)
 {
-    const auto callId = LRCInstance::getCallIdForConversationUid(convUid, accountId);
-    if (callId.isEmpty() || !LRCInstance::getCurrentCallModel()->hasCall(callId)) {
+    const auto callId = lrcInstance_->getCallIdForConversationUid(convUid, accountId);
+    if (callId.isEmpty() || !lrcInstance_->getCurrentCallModel()->hasCall(callId)) {
         return;
     }
-    const auto callInfo = LRCInstance::getCurrentCallModel()->getCall(callId);
+    const auto callInfo = lrcInstance_->getCurrentCallModel()->getCall(callId);
     if (callInfo.status == lrc::api::call::Status::IN_PROGRESS
         || callInfo.status == lrc::api::call::Status::PAUSED) {
-        auto timeString = LRCInstance::getCurrentCallModel()->getFormattedCallDuration(callId);
+        auto timeString = lrcInstance_->getCurrentCallModel()->getFormattedCallDuration(callId);
         emit updateTimeText(timeString);
     }
 }
diff --git a/src/calladapter.h b/src/calladapter.h
index e1c01adc4..5ec947b34 100644
--- a/src/calladapter.h
+++ b/src/calladapter.h
@@ -37,7 +37,7 @@ public:
     enum MuteStates { UNMUTED, LOCAL_MUTED, MODERATOR_MUTED, BOTH_MUTED };
     Q_ENUM(MuteStates)
 
-    explicit CallAdapter(QObject* parent = nullptr);
+    explicit CallAdapter(QObject* parent = nullptr, LRCInstance* instance = nullptr);
     ~CallAdapter() = default;
 
 protected:
@@ -53,9 +53,7 @@ public:
     Q_INVOKABLE void connectCallModel(const QString& accountId);
     Q_INVOKABLE void sipInputPanelPlayDTMF(const QString& key);
 
-    /*
-     * For Call Overlay
-     */
+    // For Call Overlay
     Q_INVOKABLE void hangupCall(const QString& uri);
     Q_INVOKABLE void maximizeParticipant(const QString& uri);
     Q_INVOKABLE void minimizeParticipant(const QString& uri);
@@ -87,9 +85,7 @@ signals:
     void callSetupMainViewRequired(const QString& accountId, const QString& convUid);
     void previewVisibilityNeedToChange(bool visible);
 
-    /*
-     * For Call Overlay
-     */
+    // For Call Overlay
     void updateTimeText(const QString& time);
     void showOnHoldLabel(bool isPaused);
     void updateOverlay(bool isPaused,
@@ -112,9 +108,7 @@ private:
     void showNotification(const QString& accountId, const QString& convUid);
     QJsonObject fillParticipantData(QMap<QString, QString> participant);
 
-    /*
-     * Current conf/call info.
-     */
+    // Current conf/call info.
     QString accountId_;
     QString convUid_;
 
@@ -124,9 +118,7 @@ private:
     QMetaObject::Connection appStateChangedConnection_;
     QMetaObject::Connection remoteRecordingChangedConnection_;
 
-    /*
-     * For Call Overlay
-     */
+    // For Call Overlay
     void updateCallOverlay(const lrc::api::conversation::Info& convInfo);
     void setTime(const QString& accountId, const QString& convUid);
     QTimer* oneSecondTimer_;
diff --git a/src/commoncomponents/AccountMigrationDialog.qml b/src/commoncomponents/AccountMigrationDialog.qml
index b1bba5356..8ef5fd979 100644
--- a/src/commoncomponents/AccountMigrationDialog.qml
+++ b/src/commoncomponents/AccountMigrationDialog.qml
@@ -35,6 +35,8 @@ Window {
 
     AccountsToMigrateListModel {
         id: accountsToMigrateListModel
+
+        lrcInstance: LRCInstance
     }
 
     property string accountID: ""
diff --git a/src/commoncomponents/PhotoboothView.qml b/src/commoncomponents/PhotoboothView.qml
index 1cff7b6fe..35876c31d 100644
--- a/src/commoncomponents/PhotoboothView.qml
+++ b/src/commoncomponents/PhotoboothView.qml
@@ -189,6 +189,8 @@ ColumnLayout {
         Layout.preferredWidth: boothWidth
         Layout.preferredHeight: boothWidth
 
+        lrcInstance: LRCInstance
+
         layer.enabled: true
         layer.effect: OpacityMask {
             maskSource: Rectangle {
diff --git a/src/connectivitymonitor.h b/src/connectivitymonitor.h
index 11fd9fe0b..2735d826f 100644
--- a/src/connectivitymonitor.h
+++ b/src/connectivitymonitor.h
@@ -25,7 +25,7 @@ class ConnectivityMonitor final : public QObject
 {
     Q_OBJECT
 public:
-    explicit ConnectivityMonitor(QObject* parent = 0);
+    explicit ConnectivityMonitor(QObject* parent = nullptr);
     ~ConnectivityMonitor();
 
     bool isOnline();
@@ -50,7 +50,7 @@ class ConnectivityMonitor final : public QObject
 {
     Q_OBJECT
 public:
-    explicit ConnectivityMonitor(QObject* parent = 0);
+    explicit ConnectivityMonitor(QObject* parent = nullptr);
     ~ConnectivityMonitor();
 
     bool isOnline();
diff --git a/src/contactadapter.cpp b/src/contactadapter.cpp
index 85c15ddc3..514c64c9b 100644
--- a/src/contactadapter.cpp
+++ b/src/contactadapter.cpp
@@ -22,8 +22,8 @@
 
 #include "lrcinstance.h"
 
-ContactAdapter::ContactAdapter(QObject* parent)
-    : QmlAdapterBase(parent)
+ContactAdapter::ContactAdapter(QObject* parent, LRCInstance* instance)
+    : QmlAdapterBase(parent, instance)
 {
     selectableProxyModel_.reset(new SelectableProxyModel(smartListModel_.get()));
 }
@@ -36,14 +36,13 @@ ContactAdapter::getContactSelectableModel(int type)
      */
     listModeltype_ = static_cast<SmartListModel::Type>(type);
 
-
     if (listModeltype_ == SmartListModel::Type::CONVERSATION) {
-        defaultModerators_ =
-                LRCInstance::accountModel().getDefaultModerators(LRCInstance::getCurrAccId());
-        smartListModel_.reset(new SmartListModel(this, listModeltype_));
+        defaultModerators_ = lrcInstance_->accountModel().getDefaultModerators(
+            lrcInstance_->getCurrAccId());
+        smartListModel_.reset(new SmartListModel(this, listModeltype_, lrcInstance_));
         smartListModel_->fillConversationsList();
     } else {
-        smartListModel_.reset(new SmartListModel(this, listModeltype_));
+        smartListModel_.reset(new SmartListModel(this, listModeltype_, lrcInstance_));
     }
     selectableProxyModel_->setSourceModel(smartListModel_.get());
 
@@ -52,8 +51,7 @@ ContactAdapter::getContactSelectableModel(int type)
      */
     switch (listModeltype_) {
     case SmartListModel::Type::CONVERSATION:
-        selectableProxyModel_->setPredicate([this]
-                                            (const QModelIndex& index, const QRegExp&) {
+        selectableProxyModel_->setPredicate([this](const QModelIndex& index, const QRegExp&) {
             return !defaultModerators_.contains(index.data(SmartListModel::URI).toString());
         });
         break;
@@ -94,23 +92,23 @@ ContactAdapter::setSearchFilter(const QString& filter)
     if (listModeltype_ == SmartListModel::Type::CONFERENCE) {
         smartListModel_->setConferenceableFilter(filter);
     } else if (listModeltype_ == SmartListModel::Type::CONVERSATION) {
-        selectableProxyModel_->setPredicate([this, filter](
-                                            const QModelIndex& index,
-                                            const QRegExp&) {
-            return (!defaultModerators_.contains(index.data(SmartListModel::URI).toString())
-                    && index.data(SmartListModel::DisplayName).toString().contains(filter));
-        });
+        selectableProxyModel_->setPredicate(
+            [this, filter](const QModelIndex& index, const QRegExp&) {
+                return (!defaultModerators_.contains(index.data(SmartListModel::URI).toString())
+                        && index.data(SmartListModel::DisplayName).toString().contains(filter));
+            });
     }
     selectableProxyModel_->setFilterRegExp(
-                QRegExp(filter, Qt::CaseInsensitive, QRegExp::FixedString));
+        QRegExp(filter, Qt::CaseInsensitive, QRegExp::FixedString));
 }
 
 void
 ContactAdapter::contactSelected(int index)
 {
     auto contactIndex = selectableProxyModel_->index(index, 0);
-    auto* callModel = LRCInstance::getCurrentCallModel();
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(LRCInstance::getCurrentConvUid());
+    auto* callModel = lrcInstance_->getCurrentCallModel();
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(
+        lrcInstance_->getCurrentConvUid());
     if (contactIndex.isValid()) {
         switch (listModeltype_) {
         case SmartListModel::Type::CONFERENCE: {
@@ -126,7 +124,7 @@ ContactAdapter::contactSelected(int index)
 
             const auto convUid = contactIndex.data(SmartListModel::Role::UID).value<QString>();
             const auto accId = contactIndex.data(SmartListModel::Role::AccountId).value<QString>();
-            const auto callId = LRCInstance::getCallIdForConversationUid(convUid, accId);
+            const auto callId = lrcInstance_->getCallIdForConversationUid(convUid, accId);
 
             if (!callId.isEmpty()) {
                 if (convInfo.uid.isEmpty()) {
@@ -137,7 +135,7 @@ ContactAdapter::contactSelected(int index)
                 callModel->joinCalls(thisCallId, callId);
             } else {
                 const auto contactUri = contactIndex.data(SmartListModel::Role::URI).value<QString>();
-                auto call = LRCInstance::getCallInfoForConversation(convInfo);
+                auto call = lrcInstance_->getCallInfoForConversation(convInfo);
                 if (!call) {
                     return;
                 }
@@ -186,8 +184,9 @@ ContactAdapter::contactSelected(int index)
                 return;
             }
 
-            LRCInstance::accountModel().setDefaultModerator(
-                        LRCInstance::getCurrAccId(), contactUri, true);
+            lrcInstance_->accountModel().setDefaultModerator(lrcInstance_->getCurrAccId(),
+                                                             contactUri,
+                                                             true);
             emit defaultModeratorsUpdated();
 
         } break;
diff --git a/src/contactadapter.h b/src/contactadapter.h
index 2ece5e916..46cf92afe 100644
--- a/src/contactadapter.h
+++ b/src/contactadapter.h
@@ -25,6 +25,8 @@
 #include <QSortFilterProxyModel>
 #include <QString>
 
+class LRCInstance;
+
 /*
  * The SelectableProxyModel class
  * provides support for sorting and filtering data passed between another model and a view.
@@ -53,9 +55,8 @@ public:
 
     virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
     {
-        /*
-         * Accept all contacts in conversation list filtered with account type, except those in a call.
-         */
+        // Accept all contacts in conversation list filtered with account type, except those in a call.
+
         auto index = sourceModel()->index(source_row, 0, source_parent);
         if (filterPredicate_) {
             return filterPredicate_(index, filterRegExp());
@@ -71,7 +72,7 @@ class ContactAdapter final : public QmlAdapterBase
     Q_OBJECT
 
 public:
-    explicit ContactAdapter(QObject* parent = nullptr);
+    explicit ContactAdapter(QObject* parent = nullptr, LRCInstance* instance = nullptr);
     ~ContactAdapter() = default;
 
 protected:
@@ -85,14 +86,10 @@ protected:
 private:
     SmartListModel::Type listModeltype_;
 
-    /*
-     * For sip call transfer, to exclude current sip callee.
-     */
+    // For sip call transfer, to exclude current sip callee.
     QString calleeDisplayName_;
 
-    /*
-     * SmartListModel is the source model of SelectableProxyModel.
-     */
+    // SmartListModel is the source model of SelectableProxyModel.
     std::unique_ptr<SmartListModel> smartListModel_;
     std::unique_ptr<SelectableProxyModel> selectableProxyModel_;
 
@@ -100,5 +97,4 @@ private:
 
 signals:
     void defaultModeratorsUpdated();
-
 };
diff --git a/src/conversationsadapter.cpp b/src/conversationsadapter.cpp
index caa801407..8d4510ddb 100644
--- a/src/conversationsadapter.cpp
+++ b/src/conversationsadapter.cpp
@@ -28,33 +28,35 @@
 
 #include <QApplication>
 
-ConversationsAdapter::ConversationsAdapter(QObject* parent)
-    : QmlAdapterBase(parent)
+ConversationsAdapter::ConversationsAdapter(QObject* parent, LRCInstance* instance)
+    : QmlAdapterBase(parent, instance)
 {
     connect(this, &ConversationsAdapter::currentTypeFilterChanged, [this]() {
-        LRCInstance::getCurrentConversationModel()->setFilter(currentTypeFilter_);
+        lrcInstance_->getCurrentConversationModel()->setFilter(currentTypeFilter_);
     });
 }
 
 void
 ConversationsAdapter::safeInit()
 {
-    conversationSmartListModel_ = new SmartListModel(this);
+    conversationSmartListModel_ = new SmartListModel(this,
+                                                     SmartListModel::Type::CONVERSATION,
+                                                     lrcInstance_);
 
     emit modelChanged(QVariant::fromValue(conversationSmartListModel_));
 
-    connect(&LRCInstance::behaviorController(),
+    connect(&lrcInstance_->behaviorController(),
             &BehaviorController::showChatView,
             [this](const QString& accountId, const QString& convId) {
                 emit showConversation(accountId, convId);
             });
 
-    connect(&LRCInstance::behaviorController(),
+    connect(&lrcInstance_->behaviorController(),
             &BehaviorController::newUnreadInteraction,
             this,
             &ConversationsAdapter::onNewUnreadInteraction);
 
-    connect(&LRCInstance::instance(),
+    connect(lrcInstance_,
             &LRCInstance::currentAccountChanged,
             this,
             &ConversationsAdapter::onCurrentAccountIdChanged);
@@ -62,7 +64,7 @@ ConversationsAdapter::safeInit()
     connectConversationModel();
 
     setProperty("currentTypeFilter",
-                QVariant::fromValue(LRCInstance::getCurrentAccountInfo().profileInfo.type));
+                QVariant::fromValue(lrcInstance_->getCurrentAccountInfo().profileInfo.type));
 }
 
 void
@@ -75,54 +77,54 @@ ConversationsAdapter::backToWelcomePage()
 void
 ConversationsAdapter::selectConversation(const QString& accountId, const QString& convUid)
 {
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid, accountId);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
 
-    if (LRCInstance::getCurrentConvUid() != convInfo.uid && convInfo.participants.size() > 0) {
+    if (lrcInstance_->getCurrentConvUid() != convInfo.uid && convInfo.participants.size() > 0) {
         // If the account is not currently selected, do that first, then
         // proceed to select the conversation.
         auto selectConversation = [this, accountId, convUid = convInfo.uid] {
-            const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid, accountId);
+            const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
             if (convInfo.uid.isEmpty()) {
                 return;
             }
-            auto& accInfo = LRCInstance::getAccountInfo(convInfo.accountId);
-            LRCInstance::setSelectedConvId(convInfo.uid);
+            auto& accInfo = lrcInstance_->getAccountInfo(convInfo.accountId);
+            lrcInstance_->setSelectedConvId(convInfo.uid);
             accInfo.conversationModel->clearUnreadInteractions(convInfo.uid);
 
             // Set contact filter (for conversation tab selection)
             auto& contact = accInfo.contactModel->getContact(convInfo.participants.front());
             setProperty("currentTypeFilter", QVariant::fromValue(contact.profileInfo.type));
         };
-        if (convInfo.accountId != LRCInstance::getCurrAccId()) {
-            Utils::oneShotConnect(&LRCInstance::instance(),
+        if (convInfo.accountId != lrcInstance_->getCurrAccId()) {
+            Utils::oneShotConnect(lrcInstance_,
                                   &LRCInstance::currentAccountChanged,
                                   [selectConversation] { selectConversation(); });
-            LRCInstance::setSelectedConvId();
-            LRCInstance::setSelectedAccountId(convInfo.accountId);
+            lrcInstance_->setSelectedConvId();
+            lrcInstance_->setSelectedAccountId(convInfo.accountId);
         } else {
             selectConversation();
         }
     }
 
     if (!convInfo.uid.isEmpty()) {
-        emit showConversation(LRCInstance::getCurrAccId(), convInfo.uid);
+        emit showConversation(lrcInstance_->getCurrAccId(), convInfo.uid);
     }
 }
 
 void
 ConversationsAdapter::deselectConversation()
 {
-    if (LRCInstance::getCurrentConvUid().isEmpty()) {
+    if (lrcInstance_->getCurrentConvUid().isEmpty()) {
         return;
     }
 
-    auto currentConversationModel = LRCInstance::getCurrentConversationModel();
+    auto currentConversationModel = lrcInstance_->getCurrentConversationModel();
 
     if (currentConversationModel == nullptr) {
         return;
     }
 
-    LRCInstance::setSelectedConvId();
+    lrcInstance_->setSelectedConvId();
 }
 
 void
@@ -132,7 +134,7 @@ ConversationsAdapter::onCurrentAccountIdChanged()
     connectConversationModel();
 
     setProperty("currentTypeFilter",
-                QVariant::fromValue(LRCInstance::getCurrentAccountInfo().profileInfo.type));
+                QVariant::fromValue(lrcInstance_->getCurrentAccountInfo().profileInfo.type));
 }
 
 void
@@ -143,16 +145,16 @@ ConversationsAdapter::onNewUnreadInteraction(const QString& accountId,
 {
     Q_UNUSED(interactionId)
     if (!interaction.authorUri.isEmpty()
-        && (!QApplication::focusWindow() || accountId != LRCInstance::getCurrAccId()
-            || convUid != LRCInstance::getCurrentConvUid())) {
-        auto& accInfo = LRCInstance::getAccountInfo(accountId);
+        && (!QApplication::focusWindow() || accountId != lrcInstance_->getCurrAccId()
+            || convUid != lrcInstance_->getCurrentConvUid())) {
+        auto& accInfo = lrcInstance_->getAccountInfo(accountId);
         auto from = accInfo.contactModel->bestNameForContact(interaction.authorUri);
         auto onClicked = [this, accountId, convUid, uri = interaction.authorUri] {
-            emit LRCInstance::instance().notificationClicked();
-            const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid, accountId);
+            emit lrcInstance_->notificationClicked();
+            const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
             if (!convInfo.uid.isEmpty()) {
                 selectConversation(accountId, convInfo.uid);
-                emit LRCInstance::instance().updateSmartList();
+                emit lrcInstance_->updateSmartList();
                 emit modelSorted(convInfo.uid);
             }
         };
@@ -166,7 +168,7 @@ void
 ConversationsAdapter::updateConversationsFilterWidget()
 {
     // Update status of "Conversations" and "Invitations".
-    auto invites = LRCInstance::getCurrentAccountInfo().contactModel->pendingRequestCount();
+    auto invites = lrcInstance_->getCurrentAccountInfo().contactModel->pendingRequestCount();
     if (invites == 0 && currentTypeFilter_ == lrc::api::profile::Type::PENDING) {
         setProperty("currentTypeFilter", QVariant::fromValue(lrc::api::profile::Type::RING));
     }
@@ -184,7 +186,7 @@ bool
 ConversationsAdapter::connectConversationModel(bool updateFilter)
 {
     // Signal connections
-    auto currentConversationModel = LRCInstance::getCurrentConversationModel();
+    auto currentConversationModel = lrcInstance_->getCurrentConversationModel();
 
     modelSortedConnection_ = QObject::connect(
         currentConversationModel, &lrc::api::ConversationModel::modelChanged, [this]() {
@@ -192,9 +194,9 @@ ConversationsAdapter::connectConversationModel(bool updateFilter)
             updateConversationsFilterWidget();
             emit updateListViewRequested();
 
-            auto* convModel = LRCInstance::getCurrentConversationModel();
-            const auto& convInfo = LRCInstance::getConversationFromConvUid(
-                LRCInstance::getCurrentConvUid());
+            auto* convModel = lrcInstance_->getCurrentConversationModel();
+            const auto& convInfo = lrcInstance_->getConversationFromConvUid(
+                lrcInstance_->getCurrentConvUid());
 
             if (convInfo.uid.isEmpty() || convInfo.participants.isEmpty()) {
                 return;
@@ -209,7 +211,7 @@ ConversationsAdapter::connectConversationModel(bool updateFilter)
         });
 
     contactProfileUpdatedConnection_
-        = QObject::connect(LRCInstance::getCurrentAccountInfo().contactModel.get(),
+        = QObject::connect(lrcInstance_->getCurrentAccountInfo().contactModel.get(),
                            &lrc::api::ContactModel::profileUpdated,
                            [this](const QString& contactUri) {
                                conversationSmartListModel_->updateContactAvatarUid(contactUri);
@@ -223,16 +225,16 @@ ConversationsAdapter::connectConversationModel(bool updateFilter)
                                                    emit updateListViewRequested();
                                                });
 
-    filterChangedConnection_ = QObject::connect(currentConversationModel,
-                                                &lrc::api::ConversationModel::filterChanged,
-                                                [this]() {
-                                                    conversationSmartListModel_
-                                                        ->fillConversationsList();
-                                                    updateConversationsFilterWidget();
-                                                    if (!LRCInstance::getCurrentConvUid().isEmpty())
-                                                        emit indexRepositionRequested();
-                                                    emit updateListViewRequested();
-                                                });
+    filterChangedConnection_
+        = QObject::connect(currentConversationModel,
+                           &lrc::api::ConversationModel::filterChanged,
+                           [this]() {
+                               conversationSmartListModel_->fillConversationsList();
+                               updateConversationsFilterWidget();
+                               if (!lrcInstance_->getCurrentConvUid().isEmpty())
+                                   emit indexRepositionRequested();
+                               emit updateListViewRequested();
+                           });
 
     newConversationConnection_ = QObject::connect(currentConversationModel,
                                                   &lrc::api::ConversationModel::newConversation,
@@ -256,7 +258,7 @@ ConversationsAdapter::connectConversationModel(bool updateFilter)
                            [this](const QString& convUid) {
                                // If currently selected, switch to welcome screen (deselecting
                                // current smartlist item ).
-                               if (convUid != LRCInstance::getCurrentConvUid()) {
+                               if (convUid != lrcInstance_->getCurrentConvUid()) {
                                    return;
                                }
                                backToWelcomePage();
@@ -306,18 +308,18 @@ ConversationsAdapter::disconnectConversationModel()
 void
 ConversationsAdapter::updateConversationForNewContact(const QString& convUid)
 {
-    auto* convModel = LRCInstance::getCurrentConversationModel();
+    auto* convModel = lrcInstance_->getCurrentConversationModel();
     if (convModel == nullptr) {
         return;
     }
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid);
 
     if (!convInfo.uid.isEmpty() && !convInfo.participants.isEmpty()) {
         try {
             const auto contact = convModel->owner.contactModel->getContact(convInfo.participants[0]);
             if (!contact.profileInfo.uri.isEmpty()
-                && contact.profileInfo.uri == LRCInstance::getCurrentConvUid()) {
-                LRCInstance::setSelectedConvId(convUid);
+                && contact.profileInfo.uri == lrcInstance_->getCurrentConvUid()) {
+                lrcInstance_->setSelectedConvId(convUid);
                 convModel->selectConversation(convUid);
             }
         } catch (...) {
diff --git a/src/conversationsadapter.h b/src/conversationsadapter.h
index 6fc23a0a0..fa201b807 100644
--- a/src/conversationsadapter.h
+++ b/src/conversationsadapter.h
@@ -32,7 +32,7 @@ class ConversationsAdapter final : public QmlAdapterBase
     Q_PROPERTY(lrc::api::profile::Type currentTypeFilter MEMBER currentTypeFilter_ NOTIFY
                    currentTypeFilterChanged)
 public:
-    explicit ConversationsAdapter(QObject* parent = nullptr);
+    explicit ConversationsAdapter(QObject* parent = nullptr, LRCInstance* instance = nullptr);
     ~ConversationsAdapter() = default;
 
 protected:
@@ -73,9 +73,7 @@ private:
 
     lrc::api::profile::Type currentTypeFilter_ {};
 
-    /*
-     * Connections.
-     */
+    // Connections.
     QMetaObject::Connection modelSortedConnection_;
     QMetaObject::Connection modelUpdatedConnection_;
     QMetaObject::Connection filterChangedConnection_;
diff --git a/src/deviceitemlistmodel.cpp b/src/deviceitemlistmodel.cpp
index fb61b1824..fc2d3e410 100644
--- a/src/deviceitemlistmodel.cpp
+++ b/src/deviceitemlistmodel.cpp
@@ -18,8 +18,15 @@
 
 #include "deviceitemlistmodel.h"
 
+#include "lrcinstance.h"
+
+#include "api/account.h"
+#include "api/contact.h"
+#include "api/conversation.h"
+#include "api/newdevicemodel.h"
+
 DeviceItemListModel::DeviceItemListModel(QObject* parent)
-    : QAbstractListModel(parent)
+    : AbstractListModelBase(parent)
 {}
 
 DeviceItemListModel::~DeviceItemListModel() {}
@@ -27,11 +34,11 @@ DeviceItemListModel::~DeviceItemListModel() {}
 int
 DeviceItemListModel::rowCount(const QModelIndex& parent) const
 {
-    if (!parent.isValid()) {
+    if (!parent.isValid() && lrcInstance_) {
         /*
          * Count.
          */
-        return LRCInstance::getCurrentAccountInfo().deviceModel->getAllDevices().size();
+        return lrcInstance_->getCurrentAccountInfo().deviceModel->getAllDevices().size();
     }
     /*
      * A valid QModelIndex returns 0 as no entry has sub-elements.
@@ -52,7 +59,7 @@ DeviceItemListModel::columnCount(const QModelIndex& parent) const
 QVariant
 DeviceItemListModel::data(const QModelIndex& index, int role) const
 {
-    auto deviceList = LRCInstance::getCurrentAccountInfo().deviceModel->getAllDevices();
+    auto deviceList = lrcInstance_->getCurrentAccountInfo().deviceModel->getAllDevices();
     if (!index.isValid() || deviceList.size() <= index.row()) {
         return QVariant();
     }
diff --git a/src/deviceitemlistmodel.h b/src/deviceitemlistmodel.h
index 0aed35b87..c4b34f148 100644
--- a/src/deviceitemlistmodel.h
+++ b/src/deviceitemlistmodel.h
@@ -18,16 +18,9 @@
 
 #pragma once
 
-#include <QAbstractItemModel>
+#include "abstractitemmodelbase.h"
 
-#include "api/account.h"
-#include "api/contact.h"
-#include "api/conversation.h"
-#include "api/newdevicemodel.h"
-
-#include "lrcinstance.h"
-
-class DeviceItemListModel : public QAbstractListModel
+class DeviceItemListModel : public AbstractListModelBase
 {
     Q_OBJECT
 
@@ -35,7 +28,7 @@ public:
     enum Role { DeviceName = Qt::UserRole + 1, DeviceID, IsCurrent };
     Q_ENUM(Role)
 
-    explicit DeviceItemListModel(QObject* parent = 0);
+    explicit DeviceItemListModel(QObject* parent = nullptr);
     ~DeviceItemListModel();
 
     /*
diff --git a/src/distantrenderer.cpp b/src/distantrenderer.cpp
index 55b15fa15..ca156971f 100644
--- a/src/distantrenderer.cpp
+++ b/src/distantrenderer.cpp
@@ -29,9 +29,14 @@ DistantRenderer::DistantRenderer(QQuickItem* parent)
     setRenderTarget(QQuickPaintedItem::FramebufferObject);
     setPerformanceHint(QQuickPaintedItem::FastFBOResizing);
 
-    connect(LRCInstance::renderer(), &RenderManager::distantFrameUpdated, [this](const QString& id) {
-        if (distantRenderId_ == id)
-            update(QRect(0, 0, width(), height()));
+    connect(this, &DistantRenderer::lrcInstanceChanged, [this] {
+        if (lrcInstance_)
+            connect(lrcInstance_->renderer(),
+                    &RenderManager::distantFrameUpdated,
+                    [this](const QString& id) {
+                        if (distantRenderId_ == id)
+                            update(QRect(0, 0, width(), height()));
+                    });
     });
 }
 
@@ -70,7 +75,7 @@ DistantRenderer::getScaledHeight() const
 void
 DistantRenderer::paint(QPainter* painter)
 {
-    LRCInstance::renderer()->drawFrame(distantRenderId_, [this, painter](QImage* distantImage) {
+    lrcInstance_->renderer()->drawFrame(distantRenderId_, [this, painter](QImage* distantImage) {
         if (distantImage) {
             auto scaledDistant = distantImage->scaled(size().toSize(), Qt::KeepAspectRatio);
             auto tempScaledWidth = static_cast<int>(scaledWidth_ * 1000);
diff --git a/src/distantrenderer.h b/src/distantrenderer.h
index 5de622da3..4614c788b 100644
--- a/src/distantrenderer.h
+++ b/src/distantrenderer.h
@@ -21,16 +21,19 @@
 
 #include <QtQuick>
 
+class LRCInstance;
+
 /*
  * Use QQuickPaintedItem so that QPainter apis can be used.
  * Note: Old video pipeline.
  */
-
 class DistantRenderer : public QQuickPaintedItem
 {
     Q_OBJECT
+    Q_PROPERTY(LRCInstance* lrcInstance MEMBER lrcInstance_ NOTIFY lrcInstanceChanged)
+
 public:
-    explicit DistantRenderer(QQuickItem* parent = 0);
+    explicit DistantRenderer(QQuickItem* parent = nullptr);
     ~DistantRenderer();
 
     Q_INVOKABLE void setRendererId(const QString& id);
@@ -41,6 +44,11 @@ public:
 
 signals:
     void offsetChanged();
+    void lrcInstanceChanged();
+
+protected:
+    // LRCInstance pointer (set in qml)
+    LRCInstance* lrcInstance_ {nullptr};
 
 private:
     void paint(QPainter* painter);
@@ -53,4 +61,4 @@ private:
     int yOffset_ {0};
     double scaledWidth_ {0};
     double scaledHeight_ {0};
-};
\ No newline at end of file
+};
diff --git a/src/lrcinstance.h b/src/lrcinstance.h
index bc5aadd2b..0f7efedeb 100644
--- a/src/lrcinstance.h
+++ b/src/lrcinstance.h
@@ -24,7 +24,6 @@
 #undef ERROR
 #endif
 
-#include "accountlistmodel.h"
 #include "updatemanager.h"
 #include "rendermanager.h"
 #include "appsettingsmanager.h"
@@ -68,91 +67,84 @@ class LRCInstance : public QObject
     Q_OBJECT
 
 public:
-    static LRCInstance& instance(migrateCallback willMigrate = {},
-                                 migrateCallback didMigrate = {},
-                                 const QString& updateUrl = {},
-                                 ConnectivityMonitor* connectivityMonitor = {})
-    {
-        static LRCInstance instance_(willMigrate, didMigrate, updateUrl, connectivityMonitor);
-        return instance_;
-    }
-
-    static void init(migrateCallback willMigrate = {},
-                     migrateCallback didMigrate = {},
-                     const QString& updateUrl = {},
-                     ConnectivityMonitor* connectivityMonitor = {})
+    LRCInstance(migrateCallback willMigrateCb = {},
+                migrateCallback didMigrateCb = {},
+                const QString& updateUrl = {},
+                ConnectivityMonitor* connectivityMonitor = {})
     {
-        instance(willMigrate, didMigrate, updateUrl, connectivityMonitor);
-    }
+        lrc_ = std::make_unique<Lrc>(willMigrateCb, didMigrateCb);
+        renderer_ = std::make_unique<RenderManager>(lrc_->getAVModel());
+        updateManager_ = std::make_unique<UpdateManager>(updateUrl, connectivityMonitor, this);
+    };
 
-    static Lrc& getAPI()
+    Lrc& getAPI()
     {
-        return *(instance().lrc_);
+        return *(lrc_);
     }
 
-    static RenderManager* renderer()
+    RenderManager* renderer()
     {
-        return instance().renderer_.get();
+        return renderer_.get();
     }
 
-    static UpdateManager* getUpdateManager()
+    UpdateManager* getUpdateManager()
     {
-        return instance().updateManager_.get();
+        return updateManager_.get();
     }
 
-    static void connectivityChanged()
+    void connectivityChanged()
     {
-        instance().lrc_->connectivityChanged();
+        lrc_->connectivityChanged();
     }
 
-    static NewAccountModel& accountModel()
+    NewAccountModel& accountModel()
     {
-        return instance().lrc_->getAccountModel();
+        return lrc_->getAccountModel();
     }
 
-    static BehaviorController& behaviorController()
+    BehaviorController& behaviorController()
     {
-        return instance().lrc_->getBehaviorController();
+        return lrc_->getBehaviorController();
     }
 
-    static DataTransferModel& dataTransferModel()
+    DataTransferModel& dataTransferModel()
     {
-        return instance().lrc_->getDataTransferModel();
+        return lrc_->getDataTransferModel();
     }
 
-    static AVModel& avModel()
+    AVModel& avModel()
     {
-        return instance().lrc_->getAVModel();
+        return lrc_->getAVModel();
     }
 
-    static PluginModel& pluginModel()
+    PluginModel& pluginModel()
     {
-        return instance().lrc_->getPluginModel();
+        return lrc_->getPluginModel();
     }
 
-    static bool isConnected()
+    bool isConnected()
     {
-        return instance().lrc_->isConnected();
+        return lrc_->isConnected();
     }
 
-    static VectorString getActiveCalls()
+    VectorString getActiveCalls()
     {
-        return instance().lrc_->activeCalls();
+        return lrc_->activeCalls();
     }
 
-    static const account::Info& getAccountInfo(const QString& accountId)
+    const account::Info& getAccountInfo(const QString& accountId)
     {
         return accountModel().getAccountInfo(accountId);
     }
 
-    static const account::Info& getCurrentAccountInfo()
+    const account::Info& getCurrentAccountInfo()
     {
         return getAccountInfo(getCurrAccId());
     }
 
-    static bool hasVideoCall()
+    bool hasVideoCall()
     {
-        auto activeCalls = instance().lrc_->activeCalls();
+        auto activeCalls = lrc_->activeCalls();
         auto accountList = accountModel().getAccountList();
         bool result = false;
         for (const auto& callId : activeCalls) {
@@ -167,19 +159,19 @@ public:
         return result;
     }
 
-    static QString getCallIdForConversationUid(const QString& convUid, const QString& accountId)
+    QString getCallIdForConversationUid(const QString& convUid, const QString& accountId)
     {
-        const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid, accountId);
+        const auto& convInfo = getConversationFromConvUid(convUid, accountId);
         if (convInfo.uid.isEmpty()) {
             return {};
         }
         return convInfo.confId.isEmpty() ? convInfo.callId : convInfo.confId;
     }
 
-    static const call::Info* getCallInfo(const QString& callId, const QString& accountId)
+    const call::Info* getCallInfo(const QString& callId, const QString& accountId)
     {
         try {
-            auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId);
+            auto& accInfo = accountModel().getAccountInfo(accountId);
             if (!accInfo.callModel->hasCall(callId)) {
                 return nullptr;
             }
@@ -189,12 +181,12 @@ public:
         }
     }
 
-    static const call::Info* getCallInfoForConversation(const conversation::Info& convInfo,
-                                                        bool forceCallOnly = {})
+    const call::Info* getCallInfoForConversation(const conversation::Info& convInfo,
+                                                 bool forceCallOnly = {})
     {
         try {
             auto accountId = convInfo.accountId;
-            auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId);
+            auto& accInfo = accountModel().getAccountInfo(accountId);
             auto callId = forceCallOnly
                               ? convInfo.callId
                               : (convInfo.confId.isEmpty() ? convInfo.callId : convInfo.confId);
@@ -207,88 +199,88 @@ public:
         }
     }
 
-    static const conversation::Info& getConversationFromConvUid(const QString& convUid,
-                                                                const QString& accountId = {})
+    const conversation::Info& getConversationFromConvUid(const QString& convUid,
+                                                         const QString& accountId = {})
     {
-        auto& accInfo = LRCInstance::accountModel().getAccountInfo(
-            !accountId.isEmpty() ? accountId : getCurrAccId());
+        auto& accInfo = accountModel().getAccountInfo(!accountId.isEmpty() ? accountId
+                                                                           : getCurrAccId());
         auto& convModel = accInfo.conversationModel;
-        return convModel->getConversationForUid(convUid).value_or(instance().invalid);
+        return convModel->getConversationForUid(convUid).value_or(invalid);
     }
 
-    static const conversation::Info& getConversationFromPeerUri(const QString& peerUri,
-                                                                const QString& accountId = {})
+    const conversation::Info& getConversationFromPeerUri(const QString& peerUri,
+                                                         const QString& accountId = {})
     {
-        auto& accInfo = LRCInstance::accountModel().getAccountInfo(
-            !accountId.isEmpty() ? accountId : getCurrAccId());
+        auto& accInfo = accountModel().getAccountInfo(!accountId.isEmpty() ? accountId
+                                                                           : getCurrAccId());
         auto& convModel = accInfo.conversationModel;
-        return convModel->getConversationForPeerUri(peerUri).value_or(instance().invalid);
+        return convModel->getConversationForPeerUri(peerUri).value_or(invalid);
     }
 
-    static const conversation::Info& getConversationFromCallId(const QString& callId,
-                                                               const QString& accountId = {})
+    const conversation::Info& getConversationFromCallId(const QString& callId,
+                                                        const QString& accountId = {})
     {
-        auto& accInfo = LRCInstance::accountModel().getAccountInfo(
-            !accountId.isEmpty() ? accountId : getCurrAccId());
+        auto& accInfo = accountModel().getAccountInfo(!accountId.isEmpty() ? accountId
+                                                                           : getCurrAccId());
         auto& convModel = accInfo.conversationModel;
-        return convModel->getConversationForCallId(callId).value_or(instance().invalid);
+        return convModel->getConversationForCallId(callId).value_or(invalid);
     }
 
-    static ConversationModel* getCurrentConversationModel()
+    ConversationModel* getCurrentConversationModel()
     {
         return getCurrentAccountInfo().conversationModel.get();
     }
 
-    static NewCallModel* getCurrentCallModel()
+    NewCallModel* getCurrentCallModel()
     {
         return getCurrentAccountInfo().callModel.get();
     }
 
-    static const QString& getCurrAccId()
+    const QString& getCurrAccId()
     {
-        if (instance().selectedAccountId_.isEmpty()) {
+        if (selectedAccountId_.isEmpty()) {
             auto accountList = accountModel().getAccountList();
             if (accountList.size())
-                instance().selectedAccountId_ = accountList.at(0);
+                selectedAccountId_ = accountList.at(0);
         }
-        return instance().selectedAccountId_;
+        return selectedAccountId_;
     }
 
-    static void setSelectedAccountId(const QString& accountId = {})
+    void setSelectedAccountId(const QString& accountId = {})
     {
-        if (accountId == instance().selectedAccountId_)
+        if (accountId == selectedAccountId_)
             return; // No need to select current selected account
 
-        instance().selectedAccountId_ = accountId;
+        selectedAccountId_ = accountId;
 
         // Last selected account should be set as preferred.
         accountModel().setTopAccount(accountId);
 
-        emit instance().currentAccountChanged();
+        emit currentAccountChanged();
     }
 
-    static const QString& getCurrentConvUid()
+    const QString& getCurrentConvUid()
     {
-        return instance().selectedConvUid_;
+        return selectedConvUid_;
     }
 
-    static void setSelectedConvId(const QString& convUid = {})
+    void setSelectedConvId(const QString& convUid = {})
     {
-        instance().selectedConvUid_ = convUid;
+        selectedConvUid_ = convUid;
     }
 
-    static void reset(bool newInstance = false)
+    void reset(bool newInstance = false)
     {
         if (newInstance) {
-            instance().renderer_.reset(new RenderManager(avModel()));
-            instance().lrc_.reset(new Lrc());
+            renderer_.reset(new RenderManager(avModel()));
+            lrc_.reset(new Lrc());
         } else {
-            instance().renderer_.reset();
-            instance().lrc_.reset();
+            renderer_.reset();
+            lrc_.reset();
         }
     }
 
-    static int getCurrentAccountIndex()
+    int getCurrentAccountIndex()
     {
         for (int i = 0; i < accountModel().getAccountList().size(); i++) {
             if (accountModel().getAccountList()[i] == getCurrAccId()) {
@@ -298,7 +290,7 @@ public:
         return -1;
     }
 
-    static void setAvatarForAccount(const QPixmap& avatarPixmap, const QString& accountID)
+    void setAvatarForAccount(const QPixmap& avatarPixmap, const QString& accountID)
     {
         QByteArray ba;
         QBuffer bu(&ba);
@@ -308,7 +300,7 @@ public:
         accountModel().setAvatar(accountID, str);
     }
 
-    static void setCurrAccAvatar(const QPixmap& avatarPixmap)
+    void setCurrAccAvatar(const QPixmap& avatarPixmap)
     {
         QByteArray ba;
         QBuffer bu(&ba);
@@ -318,39 +310,39 @@ public:
         accountModel().setAvatar(getCurrAccId(), str);
     }
 
-    static void setCurrAccAvatar(const QString& avatar)
+    void setCurrAccAvatar(const QString& avatar)
     {
         accountModel().setAvatar(getCurrAccId(), avatar);
     }
 
-    static void setCurrAccDisplayName(const QString& displayName)
+    void setCurrAccDisplayName(const QString& displayName)
     {
-        auto accountId = LRCInstance::getCurrAccId();
+        auto accountId = getCurrAccId();
         accountModel().setAlias(accountId, displayName);
         /*
          * Force save to .yml.
          */
-        auto confProps = LRCInstance::accountModel().getAccountConfig(accountId);
-        LRCInstance::accountModel().setAccountConfig(accountId, confProps);
+        auto confProps = accountModel().getAccountConfig(accountId);
+        accountModel().setAccountConfig(accountId, confProps);
     }
 
-    static const account::ConfProperties_t& getCurrAccConfig()
+    const account::ConfProperties_t& getCurrAccConfig()
     {
-        return instance().getCurrentAccountInfo().confProperties;
+        return getCurrentAccountInfo().confProperties;
     }
 
-    static void subscribeToDebugReceived()
+    void subscribeToDebugReceived()
     {
-        instance().lrc_->subscribeToDebugReceived();
+        lrc_->subscribeToDebugReceived();
     }
 
-    static void startAudioMeter(bool async)
+    void startAudioMeter(bool async)
     {
-        auto f = [] {
-            if (!LRCInstance::getActiveCalls().size()) {
-                LRCInstance::avModel().startAudioDevice();
+        auto f = [this] {
+            if (!getActiveCalls().size()) {
+                avModel().startAudioDevice();
             }
-            LRCInstance::avModel().setAudioMeterState(true);
+            avModel().setAudioMeterState(true);
         };
         if (async) {
             QtConcurrent::run(f);
@@ -359,13 +351,13 @@ public:
         }
     }
 
-    static void stopAudioMeter(bool async)
+    void stopAudioMeter(bool async)
     {
-        auto f = [] {
-            if (!LRCInstance::getActiveCalls().size()) {
-                LRCInstance::avModel().stopAudioDevice();
+        auto f = [this] {
+            if (!getActiveCalls().size()) {
+                avModel().stopAudioDevice();
             }
-            LRCInstance::avModel().setAudioMeterState(false);
+            avModel().setAudioMeterState(false);
         };
         if (async) {
             QtConcurrent::run(f);
@@ -374,32 +366,30 @@ public:
         }
     }
 
-    static QString getContentDraft(const QString& convUid, const QString& accountId)
+    QString getContentDraft(const QString& convUid, const QString& accountId)
     {
         auto draftKey = accountId + "_" + convUid;
-        return instance().contentDrafts_[draftKey];
+        return contentDrafts_[draftKey];
     }
 
-    static void setContentDraft(const QString& convUid,
-                                const QString& accountId,
-                                const QString& content)
+    void setContentDraft(const QString& convUid, const QString& accountId, const QString& content)
     {
         auto draftKey = accountId + "_" + convUid;
-        instance().contentDrafts_[draftKey] = content;
+        contentDrafts_[draftKey] = content;
     }
 
-    static void pushlastConference(const QString& confId, const QString& callId)
+    void pushlastConference(const QString& confId, const QString& callId)
     {
-        instance().lastConferences_[confId] = callId;
+        lastConferences_[confId] = callId;
     }
 
-    static QString poplastConference(const QString& confId)
+    QString poplastConference(const QString& confId)
     {
         QString callId = {};
-        auto iter = instance().lastConferences_.find(confId);
-        if (iter != instance().lastConferences_.end()) {
+        auto iter = lastConferences_.find(confId);
+        if (iter != lastConferences_.end()) {
             callId = iter.value();
-            instance().lastConferences_.erase(iter);
+            lastConferences_.erase(iter);
         }
         return callId;
     }
@@ -413,22 +403,11 @@ signals:
     void quitEngineRequested();
 
 private:
-    LRCInstance(migrateCallback willMigrateCb = {},
-                migrateCallback didMigrateCb = {},
-                const QString& updateUrl = {},
-                ConnectivityMonitor* connectivityMonitor = {})
-    {
-        lrc_ = std::make_unique<Lrc>(willMigrateCb, didMigrateCb);
-        renderer_ = std::make_unique<RenderManager>(lrc_->getAVModel());
-        updateManager_ = std::make_unique<UpdateManager>(updateUrl, connectivityMonitor);
-    };
-
     std::unique_ptr<Lrc> lrc_;
     std::unique_ptr<RenderManager> renderer_;
     std::unique_ptr<UpdateManager> updateManager_;
-    AccountListModel accountListModel_;
-    QString selectedAccountId_;
-    QString selectedConvUid_;
+    QString selectedAccountId_ {""};
+    QString selectedConvUid_ {""};
     MapStringString contentDrafts_;
     MapStringString lastConferences_;
 
diff --git a/src/main.cpp b/src/main.cpp
index cfa7a1718..195945c18 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -75,7 +75,7 @@ main(int argc, char* argv[])
     QCryptographicHash appData(QCryptographicHash::Sha256);
     appData.addData(QApplication::applicationName().toUtf8());
     appData.addData(QApplication::organizationDomain().toUtf8());
-    RunGuard guard(appData.result());
+    RunGuard guard(appData.result(), &app);
     if (!guard.tryToRun()) {
         return 0;
     }
diff --git a/src/mainapplication.cpp b/src/mainapplication.cpp
index ec412568d..d734dedb8 100644
--- a/src/mainapplication.cpp
+++ b/src/mainapplication.cpp
@@ -1,4 +1,4 @@
-/*!
+/*!
  * Copyright (C) 2015-2020 by Savoir-faire Linux
  * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
  * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
@@ -82,21 +82,6 @@ consoleDebug()
 #endif
 }
 
-static void
-vsConsoleDebug()
-{
-#ifdef _MSC_VER
-    /*
-     * Print debug to output window if using VS.
-     */
-    QObject::connect(&LRCInstance::behaviorController(),
-                     &lrc::api::BehaviorController::debugMessageReceived,
-                     [](const QString& message) {
-                         OutputDebugStringA((message + "\n").toStdString().c_str());
-                     });
-#endif
-}
-
 static QString
 getDebugFilePath()
 {
@@ -105,20 +90,6 @@ getDebugFilePath()
     return QString(logPath.absolutePath() + "/jami/jami.log");
 }
 
-static void
-fileDebug(QFile* debugFile)
-{
-    QObject::connect(&LRCInstance::behaviorController(),
-                     &lrc::api::BehaviorController::debugMessageReceived,
-                     [debugFile](const QString& message) {
-                         if (debugFile->open(QIODevice::WriteOnly | QIODevice::Append)) {
-                             auto msg = (message + "\n").toStdString().c_str();
-                             debugFile->write(msg, qstrlen(msg));
-                             debugFile->close();
-                         }
-                     });
-}
-
 void
 ScreenInfo::setCurrentFocusWindow(QWindow* window)
 {
@@ -142,6 +113,35 @@ ScreenInfo::setCurrentFocusWindow(QWindow* window)
     }
 }
 
+void
+MainApplication::vsConsoleDebug()
+{
+#ifdef _MSC_VER
+    /*
+     * Print debug to output window if using VS.
+     */
+    QObject::connect(&lrcInstance_->behaviorController(),
+                     &lrc::api::BehaviorController::debugMessageReceived,
+                     [](const QString& message) {
+                         OutputDebugStringA((message + "\n").toStdString().c_str());
+                     });
+#endif
+}
+
+void
+MainApplication::fileDebug(QFile* debugFile)
+{
+    QObject::connect(&lrcInstance_->behaviorController(),
+                     &lrc::api::BehaviorController::debugMessageReceived,
+                     [debugFile](const QString& message) {
+                         if (debugFile->open(QIODevice::WriteOnly | QIODevice::Append)) {
+                             auto msg = (message + "\n").toStdString().c_str();
+                             debugFile->write(msg, qstrlen(msg));
+                             debugFile->close();
+                         }
+                     });
+}
+
 MainApplication::MainApplication(int& argc, char** argv)
     : QApplication(argc, argv)
     , engine_(new QQmlApplicationEngine())
@@ -207,8 +207,8 @@ MainApplication::init()
     }
 #endif
 
-    connect(connectivityMonitor_, &ConnectivityMonitor::connectivityChanged, [] {
-        LRCInstance::connectivityChanged();
+    connect(connectivityMonitor_, &ConnectivityMonitor::connectivityChanged, [this] {
+        lrcInstance_->connectivityChanged();
     });
 
     connect(this, &QGuiApplication::focusWindowChanged, [this] {
@@ -216,7 +216,7 @@ MainApplication::init()
     });
 
     QObject::connect(
-        &LRCInstance::instance(),
+        lrcInstance_.get(),
         &LRCInstance::quitEngineRequested,
         this,
         [this] { engine_->quit(); },
@@ -240,6 +240,12 @@ MainApplication::init()
     return true;
 }
 
+void
+MainApplication::restoreApp()
+{
+    emit lrcInstance_->restoreAppRequested();
+}
+
 void
 MainApplication::loadTranslations()
 {
@@ -299,7 +305,7 @@ MainApplication::initLrc(const QString& downloadUrl, ConnectivityMonitor* cm)
      * Init mainwindow and finish splash when mainwindow shows up.
      */
     std::atomic_bool isMigrating(false);
-    LRCInstance::init(
+    lrcInstance_.reset(new LRCInstance(
         [this, &isMigrating] {
             /*
              * TODO: splash screen for account migration.
@@ -316,9 +322,9 @@ MainApplication::initLrc(const QString& downloadUrl, ConnectivityMonitor* cm)
             isMigrating = false;
         },
         downloadUrl,
-        cm);
-    LRCInstance::subscribeToDebugReceived();
-    LRCInstance::getAPI().holdConferences = false;
+        cm));
+    lrcInstance_->subscribeToDebugReceived();
+    lrcInstance_->getAPI().holdConferences = false;
 }
 
 const QVariantMap
@@ -390,18 +396,21 @@ MainApplication::setApplicationFont()
 void
 MainApplication::initQmlEngine()
 {
-    registerTypes();
+    registerTypes(lrcInstance_.get());
 
-    engine_->addImageProvider(QLatin1String("qrImage"), new QrImageProvider());
-    engine_->addImageProvider(QLatin1String("tintedPixmap"), new TintedButtonImageProvider());
-    engine_->addImageProvider(QLatin1String("avatarImage"), new AvatarImageProvider());
+    engine_->addImageProvider(QLatin1String("qrImage"), new QrImageProvider(lrcInstance_.get()));
+    engine_->addImageProvider(QLatin1String("tintedPixmap"),
+                              new TintedButtonImageProvider(lrcInstance_.get()));
+    engine_->addImageProvider(QLatin1String("avatarImage"),
+                              new AvatarImageProvider(lrcInstance_.get()));
 
     engine_->rootContext()->setContextProperty("ScreenInfo", &screenInfo_);
+    engine_->rootContext()->setContextProperty("LRCInstance", lrcInstance_.get());
 
-    engine_->setObjectOwnership(&LRCInstance::avModel(), QQmlEngine::CppOwnership);
-    engine_->setObjectOwnership(&LRCInstance::pluginModel(), QQmlEngine::CppOwnership);
-    engine_->setObjectOwnership(LRCInstance::getUpdateManager(), QQmlEngine::CppOwnership);
-    engine_->setObjectOwnership(&LRCInstance::instance(), QQmlEngine::CppOwnership);
+    engine_->setObjectOwnership(&lrcInstance_->avModel(), QQmlEngine::CppOwnership);
+    engine_->setObjectOwnership(&lrcInstance_->pluginModel(), QQmlEngine::CppOwnership);
+    engine_->setObjectOwnership(lrcInstance_->getUpdateManager(), QQmlEngine::CppOwnership);
+    engine_->setObjectOwnership(lrcInstance_.get(), QQmlEngine::CppOwnership);
     engine_->setObjectOwnership(&NameDirectory::instance(), QQmlEngine::CppOwnership);
 
     engine_->load(QUrl(QStringLiteral("qrc:/src/MainApplicationWindow.qml")));
@@ -412,7 +421,7 @@ MainApplication::initSettings()
 {
     AppSettingsManager::instance().initValues();
     auto downloadPath = AppSettingsManager::instance().getValue(Settings::Key::DownloadPath);
-    LRCInstance::dataTransferModel().downloadDirectory = downloadPath.toString() + "/";
+    lrcInstance_->dataTransferModel().downloadDirectory = downloadPath.toString() + "/";
 }
 
 void
@@ -428,9 +437,9 @@ MainApplication::initSystray()
         engine_->quit();
         cleanup();
     });
-    connect(&sysIcon, &QSystemTrayIcon::activated, [](QSystemTrayIcon::ActivationReason reason) {
+    connect(&sysIcon, &QSystemTrayIcon::activated, [this](QSystemTrayIcon::ActivationReason reason) {
         if (reason != QSystemTrayIcon::ActivationReason::Context)
-            emit LRCInstance::instance().restoreAppRequested();
+            restoreApp();
     });
 
     systrayMenu->addAction(exitAction);
diff --git a/src/mainapplication.h b/src/mainapplication.h
index 86bb7f452..f2f6273c6 100644
--- a/src/mainapplication.h
+++ b/src/mainapplication.h
@@ -1,4 +1,4 @@
-/*!
+/*!
  * Copyright (C) 2020 by Savoir-faire Linux
  * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
  * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
@@ -20,6 +20,8 @@
 
 #pragma once
 
+#include "lrcinstance.h"
+
 #include <QFile>
 #include <QApplication>
 #include <QQmlApplicationEngine>
@@ -69,8 +71,12 @@ public:
     ~MainApplication() = default;
 
     bool init();
+    void restoreApp();
 
 private:
+    void vsConsoleDebug();
+    void fileDebug(QFile* debugFile);
+
     void loadTranslations();
     void initLrc(const QString& downloadUrl, ConnectivityMonitor* cm);
     const QVariantMap parseArguments();
@@ -83,6 +89,7 @@ private:
 private:
     QScopedPointer<QFile> debugFile_;
     QScopedPointer<QQmlApplicationEngine> engine_;
+    QScopedPointer<LRCInstance> lrcInstance_;
     ConnectivityMonitor* connectivityMonitor_ {nullptr};
 
     ScreenInfo screenInfo_;
diff --git a/src/mainview/MainView.qml b/src/mainview/MainView.qml
index b766d7575..0a5ffa9db 100644
--- a/src/mainview/MainView.qml
+++ b/src/mainview/MainView.qml
@@ -379,6 +379,8 @@ Rectangle {
 
     AccountListModel {
         id: accountListModel
+
+        lrcInstance: LRCInstance
     }
 
     SettingsMenu {
diff --git a/src/mainview/components/CallOverlayButtonGroup.qml b/src/mainview/components/CallOverlayButtonGroup.qml
index b7fce991c..583d0cf21 100644
--- a/src/mainview/components/CallOverlayButtonGroup.qml
+++ b/src/mainview/components/CallOverlayButtonGroup.qml
@@ -22,6 +22,7 @@ import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
 import QtQuick.Controls.Universal 2.14
 import QtQml 2.14
+import net.jami.Adapters 1.0
 import net.jami.Models 1.0
 import net.jami.Constants 1.0
 
diff --git a/src/mainview/components/ContactPicker.qml b/src/mainview/components/ContactPicker.qml
index 3f9f2ce85..4419a43f3 100644
--- a/src/mainview/components/ContactPicker.qml
+++ b/src/mainview/components/ContactPicker.qml
@@ -20,6 +20,7 @@ import QtQuick 2.14
 import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
 import QtQuick.Controls.Universal 2.14
+import net.jami.Adapters 1.0
 import net.jami.Models 1.0
 import net.jami.Constants 1.0
 
diff --git a/src/mainview/components/ContactPickerItemDelegate.qml b/src/mainview/components/ContactPickerItemDelegate.qml
index 681ac42e5..2dae40ee4 100644
--- a/src/mainview/components/ContactPickerItemDelegate.qml
+++ b/src/mainview/components/ContactPickerItemDelegate.qml
@@ -19,6 +19,7 @@
 import QtQuick 2.14
 import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
+import net.jami.Adapters 1.0
 import net.jami.Models 1.0
 import net.jami.Constants 1.0
 
diff --git a/src/mainview/components/ParticipantOverlay.qml b/src/mainview/components/ParticipantOverlay.qml
index f801d89d7..922c6214f 100644
--- a/src/mainview/components/ParticipantOverlay.qml
+++ b/src/mainview/components/ParticipantOverlay.qml
@@ -23,6 +23,7 @@ import QtQuick.Layouts 1.14
 import QtQuick.Shapes 1.14
 import QtQuick.Controls.Universal 2.14
 import QtGraphicalEffects 1.14
+import net.jami.Adapters 1.0
 import net.jami.Models 1.0
 import net.jami.Constants 1.0
 
diff --git a/src/mainview/components/ParticipantOverlayMenu.qml b/src/mainview/components/ParticipantOverlayMenu.qml
index 270994096..7d11c32ff 100644
--- a/src/mainview/components/ParticipantOverlayMenu.qml
+++ b/src/mainview/components/ParticipantOverlayMenu.qml
@@ -20,6 +20,7 @@ import QtQuick 2.14
 import QtQuick.Controls 2.14
 import QtGraphicalEffects 1.14
 import QtQuick.Layouts 1.14
+import net.jami.Adapters 1.0
 import net.jami.Models 1.0
 import net.jami.Constants 1.0
 
diff --git a/src/mainview/components/PluginHandlerPicker.qml b/src/mainview/components/PluginHandlerPicker.qml
index 1315a9ae2..d553de6d6 100644
--- a/src/mainview/components/PluginHandlerPicker.qml
+++ b/src/mainview/components/PluginHandlerPicker.qml
@@ -270,6 +270,8 @@ Popup {
                         isImage: IsImage
                         pluginListPreferenceModel: PluginListPreferenceModel {
                             id: handlerPickerPreferenceModel
+
+                            lrcInstance: LRCInstance
                             preferenceKey : PreferenceKey
                             pluginId: PluginId
                         }
diff --git a/src/mainview/components/RecordBox.qml b/src/mainview/components/RecordBox.qml
index 46019e775..3c5cddb25 100644
--- a/src/mainview/components/RecordBox.qml
+++ b/src/mainview/components/RecordBox.qml
@@ -222,8 +222,12 @@ Rectangle {
 
         PreviewRenderer{
             id: previewWidget
+
             anchors.fill: rectBox
             anchors.centerIn: rectBox
+
+            lrcInstance: LRCInstance
+
             layer.enabled: true
             layer.effect: OpacityMask {
                 maskSource: rectBox
diff --git a/src/mainview/components/ScreenRubberBand.qml b/src/mainview/components/ScreenRubberBand.qml
index 79e853283..04704f9af 100644
--- a/src/mainview/components/ScreenRubberBand.qml
+++ b/src/mainview/components/ScreenRubberBand.qml
@@ -21,6 +21,7 @@ import QtQuick.Window 2.14
 import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
 import QtQuick.Controls.Universal 2.14
+import net.jami.Adapters 1.0
 import net.jami.Models 1.0
 import net.jami.Constants 1.0
 
diff --git a/src/mainview/components/SelectScreen.qml b/src/mainview/components/SelectScreen.qml
index 60ab8bd10..4c5c10011 100644
--- a/src/mainview/components/SelectScreen.qml
+++ b/src/mainview/components/SelectScreen.qml
@@ -21,6 +21,7 @@ import QtQuick.Window 2.14
 import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
 import QtQuick.Controls.Universal 2.14
+import net.jami.Adapters 1.0
 import net.jami.Models 1.0
 import net.jami.Constants 1.0
 
diff --git a/src/mainview/components/SipInputPanel.qml b/src/mainview/components/SipInputPanel.qml
index cd8969015..20b2c1a30 100644
--- a/src/mainview/components/SipInputPanel.qml
+++ b/src/mainview/components/SipInputPanel.qml
@@ -20,6 +20,7 @@ import QtQuick 2.14
 import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
 import QtQuick.Controls.Universal 2.14
+import net.jami.Adapters 1.0
 import net.jami.Models 1.0
 import net.jami.Constants 1.0
 
diff --git a/src/mainview/components/VideoCallPage.qml b/src/mainview/components/VideoCallPage.qml
index 52e879d5b..e246506f6 100644
--- a/src/mainview/components/VideoCallPage.qml
+++ b/src/mainview/components/VideoCallPage.qml
@@ -232,6 +232,8 @@ Rectangle {
                     width: videoCallPageMainRect.width
                     height: videoCallPageMainRect.height
 
+                    lrcInstance: LRCInstance
+
                     onOffsetChanged: {
                         videoCallOverlay.handleParticipantsInfo(CallAdapter.getConferencesInfos())
                     }
@@ -240,6 +242,8 @@ Rectangle {
                 VideoCallPreviewRenderer {
                     id: previewRenderer
 
+                    lrcInstance: LRCInstance
+
                     Connections {
                         target: CallAdapter
 
diff --git a/src/mainview/components/VideoCallPageContextMenuDeviceItem.qml b/src/mainview/components/VideoCallPageContextMenuDeviceItem.qml
index 9443c9664..4b13a4303 100644
--- a/src/mainview/components/VideoCallPageContextMenuDeviceItem.qml
+++ b/src/mainview/components/VideoCallPageContextMenuDeviceItem.qml
@@ -18,7 +18,7 @@
 
 import QtQuick 2.14
 import QtQuick.Controls 2.14
-import net.jami.Models 1.0
+import net.jami.Adapters 1.0
 import net.jami.Constants 1.0
 
 import "../../commoncomponents"
diff --git a/src/mediacodeclistmodel.cpp b/src/mediacodeclistmodel.cpp
index 1763477b9..1887fba61 100644
--- a/src/mediacodeclistmodel.cpp
+++ b/src/mediacodeclistmodel.cpp
@@ -18,8 +18,15 @@
 
 #include "mediacodeclistmodel.h"
 
+#include "lrcinstance.h"
+
+#include "api/account.h"
+#include "api/contact.h"
+#include "api/conversation.h"
+#include "api/newdevicemodel.h"
+
 MediaCodecListModel::MediaCodecListModel(QObject* parent)
-    : QAbstractListModel(parent)
+    : AbstractListModelBase(parent)
 {}
 
 MediaCodecListModel::~MediaCodecListModel() {}
@@ -27,12 +34,12 @@ MediaCodecListModel::~MediaCodecListModel() {}
 int
 MediaCodecListModel::rowCount(const QModelIndex& parent) const
 {
-    if (!parent.isValid()) {
+    if (!parent.isValid() && lrcInstance_) {
         if (mediaType_ == MediaCodecListModel::MediaType::AUDIO)
-            return LRCInstance::getCurrentAccountInfo().codecModel->getAudioCodecs().size();
+            return lrcInstance_->getCurrentAccountInfo().codecModel->getAudioCodecs().size();
         if (mediaType_ == MediaCodecListModel::MediaType::VIDEO) {
             QList<lrc::api::Codec> realCodecList;
-            auto videoCodecListOld = LRCInstance::getCurrentAccountInfo()
+            auto videoCodecListOld = lrcInstance_->getCurrentAccountInfo()
                                          .codecModel->getVideoCodecs();
 
             for (auto codec : videoCodecListOld) {
@@ -62,9 +69,9 @@ MediaCodecListModel::data(const QModelIndex& index, int role) const
 {
     QList<lrc::api::Codec> mediaCodecList;
     if (mediaType_ == MediaCodecListModel::MediaType::AUDIO)
-        mediaCodecList = LRCInstance::getCurrentAccountInfo().codecModel->getAudioCodecs();
+        mediaCodecList = lrcInstance_->getCurrentAccountInfo().codecModel->getAudioCodecs();
     else if (mediaType_ == MediaCodecListModel::MediaType::VIDEO) {
-        QList<lrc::api::Codec> videoCodecList = LRCInstance::getCurrentAccountInfo()
+        QList<lrc::api::Codec> videoCodecList = lrcInstance_->getCurrentAccountInfo()
                                                     .codecModel->getVideoCodecs();
 
         for (auto codec : videoCodecList) {
diff --git a/src/mediacodeclistmodel.h b/src/mediacodeclistmodel.h
index 6addfef0d..b0bf87898 100644
--- a/src/mediacodeclistmodel.h
+++ b/src/mediacodeclistmodel.h
@@ -18,16 +18,9 @@
 
 #pragma once
 
-#include <QAbstractItemModel>
+#include "abstractitemmodelbase.h"
 
-#include "api/account.h"
-#include "api/contact.h"
-#include "api/conversation.h"
-#include "api/newdevicemodel.h"
-
-#include "lrcinstance.h"
-
-class MediaCodecListModel : public QAbstractListModel
+class MediaCodecListModel : public AbstractListModelBase
 {
     Q_OBJECT
     Q_PROPERTY(int mediaType READ mediaType WRITE setMediaType)
@@ -36,7 +29,7 @@ public:
     enum Role { MediaCodecName = Qt::UserRole + 1, IsEnabled, MediaCodecID, Samplerate };
     Q_ENUM(Role)
 
-    explicit MediaCodecListModel(QObject* parent = 0);
+    explicit MediaCodecListModel(QObject* parent = nullptr);
     ~MediaCodecListModel();
 
     /*
diff --git a/src/messagesadapter.cpp b/src/messagesadapter.cpp
index e3dc4e9ba..971bfd5f9 100644
--- a/src/messagesadapter.cpp
+++ b/src/messagesadapter.cpp
@@ -36,14 +36,14 @@
 #include <QList>
 #include <QUrl>
 
-MessagesAdapter::MessagesAdapter(QObject* parent)
-    : QmlAdapterBase(parent)
+MessagesAdapter::MessagesAdapter(QObject* parent, LRCInstance* instance)
+    : QmlAdapterBase(parent, instance)
 {}
 
 void
 MessagesAdapter::safeInit()
 {
-    connect(&LRCInstance::instance(), &LRCInstance::currentAccountChanged, [this]() {
+    connect(lrcInstance_, &LRCInstance::currentAccountChanged, [this]() {
         currentConvUid_.clear();
         connectConversationModel();
     });
@@ -53,7 +53,7 @@ MessagesAdapter::safeInit()
 void
 MessagesAdapter::setupChatView(const QString& convUid)
 {
-    auto* convModel = LRCInstance::getCurrentConversationModel();
+    auto* convModel = lrcInstance_->getCurrentConversationModel();
     if (convModel == nullptr) {
         return;
     }
@@ -61,15 +61,15 @@ MessagesAdapter::setupChatView(const QString& convUid)
     if (currentConvUid_ == convUid)
         return;
 
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(convUid);
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid);
     if (convInfo.uid.isEmpty() || convInfo.participants.isEmpty()) {
         return;
     }
 
     QString contactURI = convInfo.participants.at(0);
 
-    auto selectedAccountId = LRCInstance::getCurrAccId();
-    auto& accountInfo = LRCInstance::accountModel().getAccountInfo(selectedAccountId);
+    auto selectedAccountId = lrcInstance_->getCurrAccId();
+    auto& accountInfo = lrcInstance_->accountModel().getAccountInfo(selectedAccountId);
 
     lrc::api::contact::Info contactInfo;
     try {
@@ -92,7 +92,7 @@ MessagesAdapter::setupChatView(const QString& convUid)
      * Type Indicator (contact).
      */
     contactIsComposing(convInfo.uid, "", false);
-    connect(LRCInstance::getCurrentConversationModel(),
+    connect(lrcInstance_->getCurrentConversationModel(),
             &ConversationModel::composingStatusChanged,
             [this](const QString& convUid, const QString& contactUri, bool isComposing) {
                 if (!AppSettingsManager::getValue(Settings::Key::EnableTypingIndicator).toBool()) {
@@ -121,7 +121,7 @@ MessagesAdapter::setupChatView(const QString& convUid)
 void
 MessagesAdapter::connectConversationModel()
 {
-    auto currentConversationModel = LRCInstance::getCurrentConversationModel();
+    auto currentConversationModel = lrcInstance_->getCurrentConversationModel();
 
     QObject::disconnect(newInteractionConnection_);
     QObject::disconnect(interactionRemovedConnection_);
@@ -133,7 +133,7 @@ MessagesAdapter::connectConversationModel()
                            [this](const QString& convUid,
                                   uint64_t interactionId,
                                   const lrc::api::interaction::Info& interaction) {
-                               auto accountId = LRCInstance::getCurrAccId();
+                               auto accountId = lrcInstance_->getCurrAccId();
                                newInteraction(accountId, convUid, interactionId, interaction);
                            });
 
@@ -143,7 +143,7 @@ MessagesAdapter::connectConversationModel()
         [this](const QString& convUid,
                uint64_t interactionId,
                const lrc::api::interaction::Info& interaction) {
-            auto currentConversationModel = LRCInstance::getCurrentConversationModel();
+            auto currentConversationModel = lrcInstance_->getCurrentConversationModel();
             currentConversationModel->clearUnreadInteractions(convUid);
             updateInteraction(*currentConversationModel, interactionId, interaction);
         });
@@ -162,17 +162,18 @@ MessagesAdapter::connectConversationModel()
 void
 MessagesAdapter::sendContactRequest()
 {
-    const auto convUid = LRCInstance::getCurrentConvUid();
+    const auto convUid = lrcInstance_->getCurrentConvUid();
     if (!convUid.isEmpty()) {
-        LRCInstance::getCurrentConversationModel()->makePermanent(convUid);
+        lrcInstance_->getCurrentConversationModel()->makePermanent(convUid);
     }
 }
 
 void
 MessagesAdapter::updateConversationForAddedContact()
 {
-    auto* convModel = LRCInstance::getCurrentConversationModel();
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(LRCInstance::getCurrentConvUid());
+    auto* convModel = lrcInstance_->getCurrentConversationModel();
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(
+        lrcInstance_->getCurrentConvUid());
 
     clear();
     setConversationProfileData(convInfo);
@@ -183,16 +184,16 @@ void
 MessagesAdapter::slotSendMessageContentSaved(const QString& content)
 {
     if (!LastConvUid_.isEmpty()) {
-        LRCInstance::setContentDraft(LastConvUid_, LRCInstance::getCurrAccId(), content);
+        lrcInstance_->setContentDraft(LastConvUid_, lrcInstance_->getCurrAccId(), content);
     }
-    LastConvUid_ = LRCInstance::getCurrentConvUid();
+    LastConvUid_ = lrcInstance_->getCurrentConvUid();
 
     Utils::oneShotConnect(qmlObj_, SIGNAL(messagesCleared()), this, SLOT(slotMessagesCleared()));
 
     setInvitation(false);
     clear();
-    auto restoredContent = LRCInstance::getContentDraft(LRCInstance::getCurrentConvUid(),
-                                                        LRCInstance::getCurrAccId());
+    auto restoredContent = lrcInstance_->getContentDraft(lrcInstance_->getCurrentConvUid(),
+                                                         lrcInstance_->getCurrAccId());
     setSendMessageContent(restoredContent);
     emit needToUpdateSmartList();
 }
@@ -201,7 +202,7 @@ void
 MessagesAdapter::slotUpdateDraft(const QString& content)
 {
     if (!LastConvUid_.isEmpty()) {
-        LRCInstance::setContentDraft(LastConvUid_, LRCInstance::getCurrAccId(), content);
+        lrcInstance_->setContentDraft(LastConvUid_, lrcInstance_->getCurrAccId(), content);
     }
     emit needToUpdateSmartList();
 }
@@ -209,8 +210,9 @@ MessagesAdapter::slotUpdateDraft(const QString& content)
 void
 MessagesAdapter::slotMessagesCleared()
 {
-    auto* convModel = LRCInstance::getCurrentConversationModel();
-    const auto& convInfo = LRCInstance::getConversationFromConvUid(LRCInstance::getCurrentConvUid());
+    auto* convModel = lrcInstance_->getCurrentConversationModel();
+    const auto& convInfo = lrcInstance_->getConversationFromConvUid(
+        lrcInstance_->getCurrentConvUid());
 
     printHistory(*convModel, convInfo.interactions);
 
@@ -229,8 +231,8 @@ void
 MessagesAdapter::sendMessage(const QString& message)
 {
     try {
-        const auto convUid = LRCInstance::getCurrentConvUid();
-        LRCInstance::getCurrentConversationModel()->sendMessage(convUid, message);
+        const auto convUid = lrcInstance_->getCurrentConvUid();
+        lrcInstance_->getCurrentConversationModel()->sendMessage(convUid, message);
     } catch (...) {
         qDebug() << "Exception during sendMessage:" << message;
     }
@@ -261,8 +263,8 @@ MessagesAdapter::sendImage(const QString& message)
         }
 
         try {
-            auto convUid = LRCInstance::getCurrentConvUid();
-            LRCInstance::getCurrentConversationModel()->sendFile(convUid, path, fileName);
+            auto convUid = lrcInstance_->getCurrentConvUid();
+            lrcInstance_->getCurrentConversationModel()->sendFile(convUid, path, fileName);
         } catch (...) {
             qDebug().noquote() << "Exception during sendFile - base64 img"
                                << "\n";
@@ -284,8 +286,8 @@ MessagesAdapter::sendImage(const QString& message)
         QString fileName = fi.fileName();
 
         try {
-            auto convUid = LRCInstance::getCurrentConvUid();
-            LRCInstance::getCurrentConversationModel()->sendFile(convUid, msg, fileName);
+            auto convUid = lrcInstance_->getCurrentConvUid();
+            lrcInstance_->getCurrentConversationModel()->sendFile(convUid, msg, fileName);
         } catch (...) {
             qDebug().noquote() << "Exception during sendFile - image from path"
                                << "\n";
@@ -299,8 +301,8 @@ MessagesAdapter::sendFile(const QString& message)
     QFileInfo fi(message);
     QString fileName = fi.fileName();
     try {
-        auto convUid = LRCInstance::getCurrentConvUid();
-        LRCInstance::getCurrentConversationModel()->sendFile(convUid, message, fileName);
+        auto convUid = lrcInstance_->getCurrentConvUid();
+        lrcInstance_->getCurrentConversationModel()->sendFile(convUid, message, fileName);
     } catch (...) {
         qDebug() << "Exception during sendFile";
     }
@@ -312,8 +314,8 @@ MessagesAdapter::retryInteraction(const QString& arg)
     bool ok;
     uint64_t interactionUid = arg.toULongLong(&ok);
     if (ok) {
-        LRCInstance::getCurrentConversationModel()
-            ->retryInteraction(LRCInstance::getCurrentConvUid(), interactionUid);
+        lrcInstance_->getCurrentConversationModel()
+            ->retryInteraction(lrcInstance_->getCurrentConvUid(), interactionUid);
     } else {
         qDebug() << "retryInteraction - invalid arg" << arg;
     }
@@ -339,8 +341,8 @@ MessagesAdapter::deleteInteraction(const QString& arg)
     bool ok;
     uint64_t interactionUid = arg.toULongLong(&ok);
     if (ok) {
-        LRCInstance::getCurrentConversationModel()
-            ->clearInteractionFromConversation(LRCInstance::getCurrentConvUid(), interactionUid);
+        lrcInstance_->getCurrentConversationModel()
+            ->clearInteractionFromConversation(lrcInstance_->getCurrentConvUid(), interactionUid);
     } else {
         qDebug() << "DeleteInteraction - invalid arg" << arg;
     }
@@ -368,8 +370,8 @@ MessagesAdapter::acceptFile(const QString& arg)
 {
     try {
         auto interactionUid = arg.toLongLong();
-        auto convUid = LRCInstance::getCurrentConvUid();
-        LRCInstance::getCurrentConversationModel()->acceptTransfer(convUid, interactionUid);
+        auto convUid = lrcInstance_->getCurrentConvUid();
+        lrcInstance_->getCurrentConversationModel()->acceptTransfer(convUid, interactionUid);
     } catch (...) {
         qDebug() << "JS bridging - exception during acceptFile: " << arg;
     }
@@ -380,8 +382,8 @@ MessagesAdapter::refuseFile(const QString& arg)
 {
     try {
         auto interactionUid = arg.toLongLong();
-        const auto convUid = LRCInstance::getCurrentConvUid();
-        LRCInstance::getCurrentConversationModel()->cancelTransfer(convUid, interactionUid);
+        const auto convUid = lrcInstance_->getCurrentConvUid();
+        lrcInstance_->getCurrentConversationModel()->cancelTransfer(convUid, interactionUid);
     } catch (...) {
         qDebug() << "JS bridging - exception during refuseFile:" << arg;
     }
@@ -440,14 +442,14 @@ MessagesAdapter::onComposing(bool isComposing)
     if (!AppSettingsManager::getValue(Settings::Key::EnableTypingIndicator).toBool()) {
         return;
     }
-    LRCInstance::getCurrentConversationModel()->setIsComposing(LRCInstance::getCurrentConvUid(),
-                                                               isComposing);
+    lrcInstance_->getCurrentConversationModel()->setIsComposing(lrcInstance_->getCurrentConvUid(),
+                                                                isComposing);
 }
 
 void
 MessagesAdapter::setConversationProfileData(const lrc::api::conversation::Info& convInfo)
 {
-    auto accInfo = &LRCInstance::getCurrentAccountInfo();
+    auto accInfo = &lrcInstance_->getCurrentAccountInfo();
 
     if (convInfo.participants.isEmpty()) {
         return;
@@ -468,7 +470,7 @@ MessagesAdapter::setConversationProfileData(const lrc::api::conversation::Info&
         if (!contact.profileInfo.avatar.isEmpty()) {
             setSenderImage(contactUri, contact.profileInfo.avatar);
         } else {
-            auto avatar = Utils::contactPhoto(convInfo.participants[0]);
+            auto avatar = Utils::contactPhoto(lrcInstance_, convInfo.participants[0]);
             QByteArray ba;
             QBuffer bu(&ba);
             avatar.save(&bu, "PNG");
@@ -486,10 +488,10 @@ MessagesAdapter::newInteraction(const QString& accountId,
 {
     Q_UNUSED(interactionId);
     try {
-        if (convUid.isEmpty() || convUid != LRCInstance::getCurrentConvUid()) {
+        if (convUid.isEmpty() || convUid != lrcInstance_->getCurrentConvUid()) {
             return;
         }
-        auto& accountInfo = LRCInstance::getAccountInfo(accountId);
+        auto& accountInfo = lrcInstance_->getAccountInfo(accountId);
         auto& convModel = accountInfo.conversationModel;
         convModel->clearUnreadInteractions(convUid);
         printNewInteraction(*convModel, interactionId, interaction);
@@ -650,7 +652,7 @@ MessagesAdapter::setSendMessageContent(const QString& content)
 void
 MessagesAdapter::contactIsComposing(const QString& uid, const QString& contactUri, bool isComposing)
 {
-    if (LRCInstance::getCurrentConvUid() == uid) {
+    if (lrcInstance_->getCurrentConvUid() == uid) {
         QString s
             = QString::fromLatin1("showTypingIndicator(`%1`, %2);").arg(contactUri).arg(isComposing);
         QMetaObject::invokeMethod(qmlObj_, "webViewRunJavaScript", Q_ARG(QVariant, s));
@@ -660,15 +662,15 @@ MessagesAdapter::contactIsComposing(const QString& uid, const QString& contactUr
 void
 MessagesAdapter::acceptInvitation(const QString& convUid)
 {
-    const auto currentConvUid = convUid.isEmpty() ? LRCInstance::getCurrentConvUid() : convUid;
-    LRCInstance::getCurrentConversationModel()->makePermanent(currentConvUid);
+    const auto currentConvUid = convUid.isEmpty() ? lrcInstance_->getCurrentConvUid() : convUid;
+    lrcInstance_->getCurrentConversationModel()->makePermanent(currentConvUid);
 }
 
 void
 MessagesAdapter::refuseInvitation(const QString& convUid)
 {
-    const auto currentConvUid = convUid.isEmpty() ? LRCInstance::getCurrentConvUid() : convUid;
-    LRCInstance::getCurrentConversationModel()->removeConversation(currentConvUid, false);
+    const auto currentConvUid = convUid.isEmpty() ? lrcInstance_->getCurrentConvUid() : convUid;
+    lrcInstance_->getCurrentConversationModel()->removeConversation(currentConvUid, false);
     setInvitation(false);
     if (convUid == currentConvUid_)
         currentConvUid_.clear();
@@ -678,8 +680,8 @@ MessagesAdapter::refuseInvitation(const QString& convUid)
 void
 MessagesAdapter::blockConversation(const QString& convUid)
 {
-    const auto currentConvUid = convUid.isEmpty() ? LRCInstance::getCurrentConvUid() : convUid;
-    LRCInstance::getCurrentConversationModel()->removeConversation(currentConvUid, true);
+    const auto currentConvUid = convUid.isEmpty() ? lrcInstance_->getCurrentConvUid() : convUid;
+    lrcInstance_->getCurrentConversationModel()->removeConversation(currentConvUid, true);
     setInvitation(false);
     if (convUid == currentConvUid_)
         currentConvUid_.clear();
@@ -690,7 +692,7 @@ MessagesAdapter::blockConversation(const QString& convUid)
 void
 MessagesAdapter::clearConversationHistory(const QString& accountId, const QString& uid)
 {
-    LRCInstance::getAccountInfo(accountId).conversationModel->clearHistory(uid);
+    lrcInstance_->getAccountInfo(accountId).conversationModel->clearHistory(uid);
     if (uid == currentConvUid_)
         currentConvUid_.clear();
 }
@@ -698,7 +700,7 @@ MessagesAdapter::clearConversationHistory(const QString& accountId, const QStrin
 void
 MessagesAdapter::removeConversation(const QString& accountId, const QString& uid, bool banContact)
 {
-    LRCInstance::getAccountInfo(accountId).conversationModel->removeConversation(uid, banContact);
+    lrcInstance_->getAccountInfo(accountId).conversationModel->removeConversation(uid, banContact);
     if (uid == currentConvUid_)
         currentConvUid_.clear();
     emit navigateToWelcomePageRequested();
diff --git a/src/messagesadapter.h b/src/messagesadapter.h
index a6925bb10..f94e58aa8 100644
--- a/src/messagesadapter.h
+++ b/src/messagesadapter.h
@@ -31,7 +31,7 @@ class MessagesAdapter final : public QmlAdapterBase
     Q_PROPERTY(QVariantMap chatviewTranslatedStrings MEMBER chatviewTranslatedStrings_ CONSTANT)
 
 public:
-    explicit MessagesAdapter(QObject* parent = 0);
+    explicit MessagesAdapter(QObject* parent = nullptr, LRCInstance* instance = nullptr);
     ~MessagesAdapter() = default;
 
 protected:
@@ -46,9 +46,7 @@ protected:
                                         bool banContact = false);
     Q_INVOKABLE void clearConversationHistory(const QString& accountId, const QString& uid);
 
-    /*
-     * JS Q_INVOKABLE.
-     */
+    // JS Q_INVOKABLE.
     Q_INVOKABLE void acceptInvitation(const QString& convUid = "");
     Q_INVOKABLE void refuseInvitation(const QString& convUid = "");
     Q_INVOKABLE void blockConversation(const QString& convUid = "");
@@ -66,14 +64,10 @@ protected:
     Q_INVOKABLE void pasteKeyDetected();
     Q_INVOKABLE void onComposing(bool isComposing);
 
-    /*
-     * Manually update draft when hiding message web view (Back to welcome page).
-     */
+    // Manually update draft when hiding message web view (Back to welcome page).
     Q_INVOKABLE void updateDraft();
 
-    /*
-     * Run corrsponding js functions, c++ to qml.
-     */
+    // Run corrsponding js functions, c++ to qml.
     void setMessagesVisibility(bool visible);
     void requestSendMessageContent();
     void setInvitation(bool show, const QString& contactUri = "", const QString& contactId = "");
@@ -116,9 +110,7 @@ private:
 
     const QVariantMap chatviewTranslatedStrings_ {lrc::api::chatview::getTranslatedStrings()};
 
-    /*
-     * Interaction connections.
-     */
+    // Interaction connections.
     QMetaObject::Connection newInteractionConnection_;
     QMetaObject::Connection interactionStatusUpdatedConnection_;
     QMetaObject::Connection interactionRemovedConnection_;
diff --git a/src/moderatorlistmodel.cpp b/src/moderatorlistmodel.cpp
index 41d135476..86c00b3c6 100644
--- a/src/moderatorlistmodel.cpp
+++ b/src/moderatorlistmodel.cpp
@@ -17,10 +17,11 @@
  */
 
 #include "moderatorlistmodel.h"
+
 #include "lrcinstance.h"
 
 ModeratorListModel::ModeratorListModel(QObject* parent)
-    : QAbstractListModel(parent)
+    : AbstractListModelBase(parent)
 {}
 
 ModeratorListModel::~ModeratorListModel() {}
@@ -28,9 +29,10 @@ ModeratorListModel::~ModeratorListModel() {}
 int
 ModeratorListModel::rowCount(const QModelIndex& parent) const
 {
-    if (!parent.isValid()) {
-        return LRCInstance::accountModel().getDefaultModerators(
-                    LRCInstance::getCurrentAccountInfo().id).size();
+    if (!parent.isValid() && lrcInstance_) {
+        return lrcInstance_->accountModel()
+            .getDefaultModerators(lrcInstance_->getCurrentAccountInfo().id)
+            .size();
     }
     return 0;
 }
@@ -48,18 +50,18 @@ ModeratorListModel::columnCount(const QModelIndex& parent) const
 QVariant
 ModeratorListModel::data(const QModelIndex& index, int role) const
 {
-    QStringList list = LRCInstance::accountModel().getDefaultModerators(
-                LRCInstance::getCurrAccId());
+    QStringList list = lrcInstance_->accountModel().getDefaultModerators(
+        lrcInstance_->getCurrAccId());
     if (!index.isValid() || list.size() <= index.row()) {
         return QVariant();
     }
-    auto contactInfo = LRCInstance::getCurrentAccountInfo().contactModel->getContact(
+    auto contactInfo = lrcInstance_->getCurrentAccountInfo().contactModel->getContact(
         list.at(index.row()));
 
     switch (role) {
     case Role::ContactName: {
-        QString str = LRCInstance::getCurrentAccountInfo().contactModel->
-                bestNameForContact(list.at(index.row()));
+        QString str = lrcInstance_->getCurrentAccountInfo().contactModel->bestNameForContact(
+            list.at(index.row()));
         return QVariant(str);
     }
     case Role::ContactID:
diff --git a/src/moderatorlistmodel.h b/src/moderatorlistmodel.h
index 060f376c7..a0aecede3 100644
--- a/src/moderatorlistmodel.h
+++ b/src/moderatorlistmodel.h
@@ -18,9 +18,9 @@
 
 #pragma once
 
-#include <QAbstractListModel>
+#include "abstractitemmodelbase.h"
 
-class ModeratorListModel : public QAbstractListModel
+class ModeratorListModel : public AbstractListModelBase
 {
     Q_OBJECT
 public:
diff --git a/src/pluginadapter.cpp b/src/pluginadapter.cpp
index c79fa24ac..b025c7b98 100644
--- a/src/pluginadapter.cpp
+++ b/src/pluginadapter.cpp
@@ -20,35 +20,37 @@
 
 #include "lrcinstance.h"
 
-PluginAdapter::PluginAdapter(QObject* parent)
-    : QmlAdapterBase(parent)
+PluginAdapter::PluginAdapter(QObject* parent, LRCInstance* instance)
+    : QmlAdapterBase(parent, instance)
 {}
 
 QVariant
 PluginAdapter::getMediaHandlerSelectableModel(const QString& callId)
 {
-    pluginHandlerListModel_.reset(new PluginHandlerItemListModel(this, callId, QString("")));
+    pluginHandlerListModel_.reset(
+        new PluginHandlerItemListModel(this, callId, QString(""), lrcInstance_));
     return QVariant::fromValue(pluginHandlerListModel_.get());
 }
 
 QVariant
 PluginAdapter::getChatHandlerSelectableModel(const QString& accountId, const QString& peerId)
 {
-    pluginHandlerListModel_.reset(new PluginHandlerItemListModel(this, accountId, peerId));
+    pluginHandlerListModel_.reset(
+        new PluginHandlerItemListModel(this, accountId, peerId, lrcInstance_));
     return QVariant::fromValue(pluginHandlerListModel_.get());
 }
 
 QVariant
 PluginAdapter::getPluginSelectableModel()
 {
-    pluginItemListModel_.reset(new PluginItemListModel(this));
+    pluginItemListModel_.reset(new PluginItemListModel(this, lrcInstance_));
     return QVariant::fromValue(pluginItemListModel_.get());
 }
 
 QVariant
 PluginAdapter::getPluginPreferencesModel(const QString& pluginId, const QString& mediaHandlerName)
 {
-    preferenceItemListModel_.reset(new PreferenceItemListModel(this));
+    preferenceItemListModel_.reset(new PreferenceItemListModel(this, lrcInstance_));
     preferenceItemListModel_->setMediaHandlerName(mediaHandlerName);
     preferenceItemListModel_->setPluginId(pluginId);
 
diff --git a/src/pluginadapter.h b/src/pluginadapter.h
index 5cc0f53ef..b33569455 100644
--- a/src/pluginadapter.h
+++ b/src/pluginadapter.h
@@ -32,7 +32,7 @@ class PluginAdapter final : public QmlAdapterBase
 {
     Q_OBJECT
 public:
-    explicit PluginAdapter(QObject* parent = nullptr);
+    explicit PluginAdapter(QObject* parent = nullptr, LRCInstance* instance = nullptr);
     ~PluginAdapter() = default;
 
 protected:
diff --git a/src/pluginhandleritemlistmodel.cpp b/src/pluginhandleritemlistmodel.cpp
index 4d7f28171..3264e0d2c 100644
--- a/src/pluginhandleritemlistmodel.cpp
+++ b/src/pluginhandleritemlistmodel.cpp
@@ -18,11 +18,18 @@
 
 #include "pluginhandleritemlistmodel.h"
 
+#include "lrcinstance.h"
+
+#include "api/pluginmodel.h"
+
 PluginHandlerItemListModel::PluginHandlerItemListModel(QObject* parent,
                                                        const QString& accountId,
-                                                       const QString& peerId)
-    : QAbstractListModel(parent)
+                                                       const QString& peerId,
+                                                       LRCInstance* instance)
+    : AbstractListModelBase(parent)
 {
+    lrcInstance_ = instance;
+
     if (!peerId.isEmpty()) {
         accountId_ = accountId;
         peerId_ = peerId;
@@ -38,14 +45,14 @@ PluginHandlerItemListModel::~PluginHandlerItemListModel() {}
 int
 PluginHandlerItemListModel::rowCount(const QModelIndex& parent) const
 {
-    if (!parent.isValid()) {
+    if (!parent.isValid() && lrcInstance_) {
         /*
          * Count.
          */
         if (isMediaHandler_)
-            return LRCInstance::pluginModel().getCallMediaHandlers().size();
+            return lrcInstance_->pluginModel().getCallMediaHandlers().size();
         else
-            return LRCInstance::pluginModel().getChatHandlers().size();
+            return lrcInstance_->pluginModel().getChatHandlers().size();
     }
     /*
      * A valid QModelIndex returns 0 as no entry has sub-elements.
@@ -73,15 +80,15 @@ PluginHandlerItemListModel::data(const QModelIndex& index, int role) const
     bool loaded = false;
 
     if (isMediaHandler_) {
-        auto mediahandlerList = LRCInstance::pluginModel().getCallMediaHandlers();
+        auto mediahandlerList = lrcInstance_->pluginModel().getCallMediaHandlers();
         if (!index.isValid() || mediahandlerList.size() <= index.row()) {
             return QVariant();
         }
 
-        auto details = LRCInstance::pluginModel().getCallMediaHandlerDetails(
+        auto details = lrcInstance_->pluginModel().getCallMediaHandlerDetails(
             mediahandlerList.at(index.row()));
         for (const auto& mediaHandler :
-             LRCInstance::pluginModel().getCallMediaHandlerStatus(callId_))
+             lrcInstance_->pluginModel().getCallMediaHandlerStatus(callId_))
             if (mediaHandler == details.id)
                 loaded = true;
         if (!details.pluginId.isEmpty()) {
@@ -94,15 +101,15 @@ PluginHandlerItemListModel::data(const QModelIndex& index, int role) const
         pluginId = details.pluginId;
 
     } else {
-        auto chathandlerList = LRCInstance::pluginModel().getChatHandlers();
+        auto chathandlerList = lrcInstance_->pluginModel().getChatHandlers();
         if (!index.isValid() || chathandlerList.size() <= index.row()) {
             return QVariant();
         }
 
-        auto details = LRCInstance::pluginModel().getChatHandlerDetails(
+        auto details = lrcInstance_->pluginModel().getChatHandlerDetails(
             chathandlerList.at(index.row()));
         for (const auto& chatHandler :
-             LRCInstance::pluginModel().getChatHandlerStatus(accountId_, peerId_))
+             lrcInstance_->pluginModel().getChatHandlerStatus(accountId_, peerId_))
             if (chatHandler == details.id)
                 loaded = true;
         if (!details.pluginId.isEmpty()) {
diff --git a/src/pluginhandleritemlistmodel.h b/src/pluginhandleritemlistmodel.h
index e72bea0d9..9a3caae87 100644
--- a/src/pluginhandleritemlistmodel.h
+++ b/src/pluginhandleritemlistmodel.h
@@ -18,13 +18,11 @@
 
 #pragma once
 
-#include <QAbstractItemModel>
+#include "abstractitemmodelbase.h"
 
-#include "api/pluginmodel.h"
+class LRCInstance;
 
-#include "lrcinstance.h"
-
-class PluginHandlerItemListModel : public QAbstractListModel
+class PluginHandlerItemListModel : public AbstractListModelBase
 {
     Q_OBJECT
 
@@ -33,10 +31,10 @@ public:
     Q_ENUM(Role)
 
     explicit PluginHandlerItemListModel(
-        QObject* parent = 0,
+        QObject* parent = nullptr,
         const QString& accountId = QString(""),
-        const QString& peerId = QString(
-            "")); // for calls, accountId is the callId and peerId is null
+        const QString& peerId = QString(""),
+        LRCInstance* instance = nullptr); // for calls, accountId is the callId and peerId is null
     ~PluginHandlerItemListModel();
 
     /*
diff --git a/src/pluginitemlistmodel.cpp b/src/pluginitemlistmodel.cpp
index d90aa45b2..a79cac761 100644
--- a/src/pluginitemlistmodel.cpp
+++ b/src/pluginitemlistmodel.cpp
@@ -18,18 +18,24 @@
 
 #include "pluginitemlistmodel.h"
 
-PluginItemListModel::PluginItemListModel(QObject* parent)
-    : QAbstractListModel(parent)
-{}
+#include "lrcinstance.h"
+
+#include "api/pluginmodel.h"
+
+PluginItemListModel::PluginItemListModel(QObject* parent, LRCInstance* instance)
+    : AbstractListModelBase(parent)
+{
+    lrcInstance_ = instance;
+}
 
 PluginItemListModel::~PluginItemListModel() {}
 
 int
 PluginItemListModel::rowCount(const QModelIndex& parent) const
 {
-    if (!parent.isValid()) {
+    if (!parent.isValid() && lrcInstance_) {
         /// Count
-        return LRCInstance::pluginModel().getInstalledPlugins().size();
+        return lrcInstance_->pluginModel().getInstalledPlugins().size();
     }
     /// A valid QModelIndex returns 0 as no entry has sub-elements.
     return 0;
@@ -46,12 +52,12 @@ PluginItemListModel::columnCount(const QModelIndex& parent) const
 QVariant
 PluginItemListModel::data(const QModelIndex& index, int role) const
 {
-    auto pluginList = LRCInstance::pluginModel().getInstalledPlugins();
+    auto pluginList = lrcInstance_->pluginModel().getInstalledPlugins();
     if (!index.isValid() || pluginList.size() <= index.row()) {
         return QVariant();
     }
 
-    auto details = LRCInstance::pluginModel().getPluginDetails(pluginList.at(index.row()));
+    auto details = lrcInstance_->pluginModel().getPluginDetails(pluginList.at(index.row()));
 
     switch (role) {
     case Role::PluginName:
@@ -119,5 +125,5 @@ PluginItemListModel::reset()
 int
 PluginItemListModel::pluginsCount()
 {
-    return LRCInstance::pluginModel().getInstalledPlugins().size();
+    return lrcInstance_->pluginModel().getInstalledPlugins().size();
 }
diff --git a/src/pluginitemlistmodel.h b/src/pluginitemlistmodel.h
index 3a6b7ef65..ea8eca3a3 100644
--- a/src/pluginitemlistmodel.h
+++ b/src/pluginitemlistmodel.h
@@ -18,13 +18,11 @@
 
 #pragma once
 
-#include <QAbstractItemModel>
+#include "abstractitemmodelbase.h"
 
-#include "api/pluginmodel.h"
+class LRCInstance;
 
-#include "lrcinstance.h"
-
-class PluginItemListModel : public QAbstractListModel
+class PluginItemListModel : public AbstractListModelBase
 {
     Q_OBJECT
     Q_PROPERTY(int pluginsCount READ pluginsCount)
@@ -33,7 +31,7 @@ public:
     enum Role { PluginName = Qt::UserRole + 1, PluginId, PluginIcon, IsLoaded };
     Q_ENUM(Role)
 
-    explicit PluginItemListModel(QObject* parent = 0);
+    explicit PluginItemListModel(QObject* parent = nullptr, LRCInstance* instance = nullptr);
     ~PluginItemListModel();
 
     /*
diff --git a/src/pluginlistpreferencemodel.cpp b/src/pluginlistpreferencemodel.cpp
index 9f54fb359..2c6751760 100644
--- a/src/pluginlistpreferencemodel.cpp
+++ b/src/pluginlistpreferencemodel.cpp
@@ -17,10 +17,13 @@
  */
 
 #include "pluginlistpreferencemodel.h"
-#include <regex>
+
+#include "lrcinstance.h"
+
+#include "api/pluginmodel.h"
 
 PluginListPreferenceModel::PluginListPreferenceModel(QObject* parent)
-    : QAbstractListModel(parent)
+    : AbstractListModelBase(parent)
 {}
 
 PluginListPreferenceModel::~PluginListPreferenceModel() {}
@@ -30,7 +33,7 @@ PluginListPreferenceModel::populateLists()
 {
     preferenceValuesList_.clear();
     preferenceList_.clear();
-    const auto preferences = LRCInstance::pluginModel().getPluginPreferences(pluginId_);
+    const auto preferences = lrcInstance_->pluginModel().getPluginPreferences(pluginId_);
     for (const auto& preference : preferences) {
         if (preference["key"] == preferenceKey_) {
             if (preference.find("entries") != preference.end()
@@ -46,7 +49,7 @@ PluginListPreferenceModel::populateLists()
 int
 PluginListPreferenceModel::rowCount(const QModelIndex& parent) const
 {
-    if (!parent.isValid()) {
+    if (!parent.isValid() && lrcInstance_) {
         /// Count
         return preferenceList_.size();
     }
diff --git a/src/pluginlistpreferencemodel.h b/src/pluginlistpreferencemodel.h
index 66e1d57b7..1ce6f6e06 100644
--- a/src/pluginlistpreferencemodel.h
+++ b/src/pluginlistpreferencemodel.h
@@ -18,13 +18,9 @@
 
 #pragma once
 
-#include <QAbstractItemModel>
+#include "abstractitemmodelbase.h"
 
-#include "api/pluginmodel.h"
-
-#include "lrcinstance.h"
-
-class PluginListPreferenceModel : public QAbstractListModel
+class PluginListPreferenceModel : public AbstractListModelBase
 {
     Q_OBJECT
     Q_PROPERTY(QString pluginId READ pluginId WRITE setPluginId)
@@ -36,7 +32,7 @@ public:
     enum Role { PreferenceValue = Qt::UserRole + 1, PreferenceEntryValue };
     Q_ENUM(Role)
 
-    explicit PluginListPreferenceModel(QObject* parent = 0);
+    explicit PluginListPreferenceModel(QObject* parent = nullptr);
     ~PluginListPreferenceModel();
 
     /*
@@ -89,7 +85,7 @@ public:
     }
     QString preferenceCurrentValue()
     {
-        return LRCInstance::pluginModel().getPluginPreferencesValues(pluginId_)[preferenceKey_];
+        return lrcInstance_->pluginModel().getPluginPreferencesValues(pluginId_)[preferenceKey_];
     }
 
     QString preferenceNewValue()
diff --git a/src/preferenceitemlistmodel.cpp b/src/preferenceitemlistmodel.cpp
index fc7152cea..e325795c8 100644
--- a/src/preferenceitemlistmodel.cpp
+++ b/src/preferenceitemlistmodel.cpp
@@ -18,25 +18,31 @@
 
 #include "preferenceitemlistmodel.h"
 
+#include "lrcinstance.h"
 #include "utils.h"
 
+#include "api/pluginmodel.h"
+
 #include <map>
 
+// TODO: Use QMap
 std::map<QString, int> mapType {{QString("List"), PreferenceItemListModel::Type::LIST},
                                 {QString("Path"), PreferenceItemListModel::Type::PATH},
                                 {QString("EditText"), PreferenceItemListModel::Type::EDITTEXT},
                                 {QString("Switch"), PreferenceItemListModel::Type::SWITCH}};
 
-PreferenceItemListModel::PreferenceItemListModel(QObject* parent)
-    : QAbstractListModel(parent)
-{}
+PreferenceItemListModel::PreferenceItemListModel(QObject* parent, LRCInstance* instance)
+    : AbstractListModelBase(parent)
+{
+    lrcInstance_ = instance;
+}
 
 PreferenceItemListModel::~PreferenceItemListModel() {}
 
 int
 PreferenceItemListModel::rowCount(const QModelIndex& parent) const
 {
-    if (!parent.isValid()) {
+    if (!parent.isValid() && lrcInstance_) {
         /// Count.
         return preferenceList_.size();
     }
@@ -66,7 +72,7 @@ PreferenceItemListModel::data(const QModelIndex& index, int role) const
     bool checkImage = false;
 
     auto details = preferenceList_.at(index.row());
-    preferenceCurrent = LRCInstance::pluginModel().getPluginPreferencesValues(
+    preferenceCurrent = lrcInstance_->pluginModel().getPluginPreferencesValues(
         pluginId_)[details["key"]];
     auto it = mapType.find(details["type"]);
     if (it != mapType.end()) {
@@ -192,10 +198,10 @@ PreferenceItemListModel::preferencesCount()
     if (!preferenceList_.isEmpty())
         return preferenceList_.size();
     if (mediaHandlerName_.isEmpty()) {
-        preferenceList_ = LRCInstance::pluginModel().getPluginPreferences(pluginId_);
+        preferenceList_ = lrcInstance_->pluginModel().getPluginPreferences(pluginId_);
         return preferenceList_.size();
     } else {
-        auto preferences = LRCInstance::pluginModel().getPluginPreferences(pluginId_);
+        auto preferences = lrcInstance_->pluginModel().getPluginPreferences(pluginId_);
         for (auto& preference : preferences) {
             QStringList scopeList = preference["scope"].split(",");
             if (scopeList.contains(mediaHandlerName_))
diff --git a/src/preferenceitemlistmodel.h b/src/preferenceitemlistmodel.h
index d9fa4ef3c..9a5f0fded 100644
--- a/src/preferenceitemlistmodel.h
+++ b/src/preferenceitemlistmodel.h
@@ -18,13 +18,11 @@
 
 #pragma once
 
-#include <QAbstractItemModel>
+#include "abstractitemmodelbase.h"
 
-#include "api/pluginmodel.h"
+class LRCInstance;
 
-#include "lrcinstance.h"
-
-class PreferenceItemListModel : public QAbstractListModel
+class PreferenceItemListModel : public AbstractListModelBase
 {
     Q_OBJECT
 
@@ -54,7 +52,7 @@ public:
 
     Q_ENUM(Role)
 
-    explicit PreferenceItemListModel(QObject* parent = 0);
+    explicit PreferenceItemListModel(QObject* parent = nullptr, LRCInstance* instance = nullptr);
     ~PreferenceItemListModel();
 
     /*
diff --git a/src/previewrenderer.cpp b/src/previewrenderer.cpp
index 2861c2bb4..e6ad1f827 100644
--- a/src/previewrenderer.cpp
+++ b/src/previewrenderer.cpp
@@ -29,12 +29,15 @@ PreviewRenderer::PreviewRenderer(QQuickItem* parent)
     setRenderTarget(QQuickPaintedItem::FramebufferObject);
     setPerformanceHint(QQuickPaintedItem::FastFBOResizing);
 
-    previewFrameUpdatedConnection_ = connect(LRCInstance::renderer(),
-                                             &RenderManager::previewFrameUpdated,
-                                             [this]() {
-                                                 if (isVisible())
-                                                     update(QRect(0, 0, width(), height()));
-                                             });
+    connect(this, &PreviewRenderer::lrcInstanceChanged, [this] {
+        if (lrcInstance_)
+            previewFrameUpdatedConnection_ = connect(lrcInstance_->renderer(),
+                                                     &RenderManager::previewFrameUpdated,
+                                                     [this]() {
+                                                         if (isVisible())
+                                                             update(QRect(0, 0, width(), height()));
+                                                     });
+    });
 }
 
 PreviewRenderer::~PreviewRenderer()
@@ -45,7 +48,7 @@ PreviewRenderer::~PreviewRenderer()
 void
 PreviewRenderer::paint(QPainter* painter)
 {
-    LRCInstance::renderer()
+    lrcInstance_->renderer()
         ->drawFrame(lrc::api::video::PREVIEW_RENDERER_ID, [this, painter](QImage* previewImage) {
             if (previewImage) {
                 auto aspectRatio = static_cast<qreal>(previewImage->width())
@@ -95,7 +98,7 @@ VideoCallPreviewRenderer::~VideoCallPreviewRenderer() {}
 void
 VideoCallPreviewRenderer::paint(QPainter* painter)
 {
-    LRCInstance::renderer()
+    lrcInstance_->renderer()
         ->drawFrame(lrc::api::video::PREVIEW_RENDERER_ID, [this, painter](QImage* previewImage) {
             if (previewImage) {
                 auto scalingFactor = static_cast<qreal>(previewImage->height())
@@ -112,8 +115,11 @@ VideoCallPreviewRenderer::paint(QPainter* painter)
 PhotoboothPreviewRender::PhotoboothPreviewRender(QQuickItem* parent)
     : PreviewRenderer(parent)
 {
-    connect(LRCInstance::renderer(), &RenderManager::previewRenderingStopped, [this]() {
-        emit hideBooth();
+    connect(this, &PreviewRenderer::lrcInstanceChanged, [this] {
+        if (lrcInstance_)
+            connect(lrcInstance_->renderer(), &RenderManager::previewRenderingStopped, [this]() {
+                emit hideBooth();
+            });
     });
 }
 
@@ -122,7 +128,7 @@ PhotoboothPreviewRender::~PhotoboothPreviewRender() {}
 QString
 PhotoboothPreviewRender::takePhoto(int size)
 {
-    if (auto previewImage = LRCInstance::renderer()->getPreviewFrame()) {
+    if (auto previewImage = lrcInstance_->renderer()->getPreviewFrame()) {
         return Utils::byteArrayToBase64String(Utils::QImageToByteArray(
             previewImage->copy()
                 .scaled(size, size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation)));
@@ -134,7 +140,7 @@ PhotoboothPreviewRender::paint(QPainter* painter)
 {
     painter->setRenderHint(QPainter::Antialiasing, true);
 
-    LRCInstance::renderer()
+    lrcInstance_->renderer()
         ->drawFrame(lrc::api::video::PREVIEW_RENDERER_ID, [this, painter](QImage* previewImage) {
             if (previewImage) {
                 QImage scaledPreview;
diff --git a/src/previewrenderer.h b/src/previewrenderer.h
index 646365e3f..239471e62 100644
--- a/src/previewrenderer.h
+++ b/src/previewrenderer.h
@@ -21,6 +21,8 @@
 
 #include <QtQuick>
 
+class LRCInstance;
+
 /*
  * Use QQuickPaintedItem so that QPainter apis can be used.
  * Note: Old video pipeline.
@@ -28,14 +30,22 @@
 class PreviewRenderer : public QQuickPaintedItem
 {
     Q_OBJECT
+    Q_PROPERTY(LRCInstance* lrcInstance MEMBER lrcInstance_ NOTIFY lrcInstanceChanged)
+
 public:
-    explicit PreviewRenderer(QQuickItem* parent = 0);
+    explicit PreviewRenderer(QQuickItem* parent = nullptr);
     ~PreviewRenderer();
 
+signals:
+    void lrcInstanceChanged();
+
 protected:
     void paint(QPainter* painter) override;
     void paintBackground(QPainter* painter);
 
+    // LRCInstance pointer (set in qml)
+    LRCInstance* lrcInstance_ {nullptr};
+
 private:
     QMetaObject::Connection previewFrameUpdatedConnection_;
 };
@@ -46,7 +56,7 @@ class VideoCallPreviewRenderer : public PreviewRenderer
     Q_PROPERTY(qreal previewImageScalingFactor MEMBER previewImageScalingFactor_ NOTIFY
                    previewImageScalingFactorChanged)
 public:
-    explicit VideoCallPreviewRenderer(QQuickItem* parent = 0);
+    explicit VideoCallPreviewRenderer(QQuickItem* parent = nullptr);
     virtual ~VideoCallPreviewRenderer();
 
 signals:
@@ -54,6 +64,7 @@ signals:
 
 private:
     void paint(QPainter* painter) override final;
+
     qreal previewImageScalingFactor_;
 };
 
@@ -61,7 +72,7 @@ class PhotoboothPreviewRender : public PreviewRenderer
 {
     Q_OBJECT
 public:
-    explicit PhotoboothPreviewRender(QQuickItem* parent = 0);
+    explicit PhotoboothPreviewRender(QQuickItem* parent = nullptr);
     virtual ~PhotoboothPreviewRender();
 
     Q_INVOKABLE QString takePhoto(int size);
diff --git a/src/qmladapterbase.h b/src/qmladapterbase.h
index 1ac0753be..b422d3266 100644
--- a/src/qmladapterbase.h
+++ b/src/qmladapterbase.h
@@ -20,24 +20,23 @@
 
 #include <QObject>
 
-/*
- * The main purpose of this class is to operate on qml objects,
- * or provide api calls to qml objects that cannot be done directly in qml.
- */
+class LRCInstance;
+
+// The main purpose of this class is to operate on qml objects,
+// or provide api calls to qml objects that cannot be done directly in qml.
 class QmlAdapterBase : public QObject
 {
     Q_OBJECT
 public:
-    explicit QmlAdapterBase(QObject* parent = nullptr)
+    explicit QmlAdapterBase(QObject* parent = nullptr, LRCInstance* instance = nullptr)
         : QObject(parent)
-        , qmlObj_(nullptr) {};
+        , qmlObj_(nullptr)
+        , lrcInstance_(instance) {};
 
     virtual ~QmlAdapterBase() = default;
 
-    /*
-     * This function should be called in the Component.onCompleted slot
-     * in the qml component that this adapter should attach to.
-     */
+    // This function should be called in the Component.onCompleted slot
+    // in the qml component that this adapter should attach to.
     Q_INVOKABLE void setQmlObject(QObject* obj)
     {
         qmlObj_ = obj;
@@ -45,13 +44,12 @@ public:
     };
 
 protected:
-    /*
-     * Once the qml object is set, Qml method invokation can be done
-     */
+    // Once the qml object is set, Qml method invokation can be done
     virtual void safeInit() = 0;
 
-    /*
-     * Object pointer.
-     */
+    // Object pointer.
     QObject* qmlObj_;
+
+    // LRCInstance pointer
+    LRCInstance* lrcInstance_ {nullptr};
 };
diff --git a/src/qmlregister.cpp b/src/qmlregister.cpp
index 292727609..71b0da785 100644
--- a/src/qmlregister.cpp
+++ b/src/qmlregister.cpp
@@ -1,186 +1,164 @@
-/*!
- * Copyright (C) 2020 by Savoir-faire Linux
- * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.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 <https://www.gnu.org/licenses/>.
- */
-
-#include "qmlregister.h"
-
-#include "accountadapter.h"
-#include "accountstomigratelistmodel.h"
-#include "mediacodeclistmodel.h"
-#include "audiodevicemodel.h"
-#include "audiomanagerlistmodel.h"
-#include "avadapter.h"
-#include "bannedlistmodel.h"
-#include "moderatorlistmodel.h"
-#include "calladapter.h"
-#include "contactadapter.h"
-#include "conversationsadapter.h"
-#include "deviceitemlistmodel.h"
-#include "distantrenderer.h"
-#include "pluginadapter.h"
-#include "pluginhandleritemlistmodel.h"
-#include "messagesadapter.h"
-#include "namedirectory.h"
-#include "updatemanager.h"
-#include "preferenceitemlistmodel.h"
-#include "pluginitemlistmodel.h"
-#include "pluginlistpreferencemodel.h"
-#include "previewrenderer.h"
-#include "settingsadapter.h"
-#include "utilsadapter.h"
-#include "version.h"
-#include "videoformatfpsmodel.h"
-#include "videoformatresolutionmodel.h"
-#include "videoinputdevicemodel.h"
-
-#include <QMetaType>
-#include <QQmlEngine>
-
-// clang-format off
-#define QML_REGISTERSINGLETONTYPE(N, T, MAJ, MIN) \
-    qmlRegisterSingletonType<T>(N, MAJ, MIN, #T, \
-                                [](QQmlEngine* e, QJSEngine* se) -> QObject* { \
-                                    Q_UNUSED(e); Q_UNUSED(se); \
-                                    T* obj = new T(); return obj; \
-                                });
-
-#define QML_REGISTERSINGLETONTYPE_WITH_INSTANCE(T, MAJ, MIN) \
-    qmlRegisterSingletonType<T>("net.jami.Models", MAJ, MIN, #T, \
-                                [](QQmlEngine* e, QJSEngine* se) -> QObject* { \
-                                    Q_UNUSED(e); Q_UNUSED(se); \
-                                    return &(T::instance()); \
-                                });
-
-#define QML_REGISTERSINGLETONTYPE_CUSTOM(N, T, MAJ, MIN, P) \
-    qmlRegisterSingletonType<T>(N, MAJ, MIN, #T, \
-                                [](QQmlEngine* e, QJSEngine* se) -> QObject* { \
-                                    Q_UNUSED(e); Q_UNUSED(se); \
-                                    return P; \
-                                });
-
-#define QML_REGISTERSINGLETONTYPE_URL(N, URL, T, MAJ, MIN) \
-    qmlRegisterSingletonType(QUrl(QStringLiteral(URL)), N, MAJ, MIN, #T);
-
-#define QML_REGISTERTYPE(N, T, MAJ, MIN) qmlRegisterType<T>(N, MAJ, MIN, #T);
-
-#define QML_REGISTERNAMESPACE(T, NAME, MAJ, MIN) \
-    qmlRegisterUncreatableMetaObject(T, "net.jami.Models", MAJ, MIN, NAME, "")
-
-#define QML_REGISTERUNCREATABLE(N, T, MAJ, MIN) \
-    qmlRegisterUncreatableType<T>(N, MAJ, MIN, #T, "Don't try to add to a qml definition of " #T);
-
-#define QML_REGISTERUNCREATABLE_IN_NAMESPACE(T, NAMESPACE, MAJ, MIN) \
-    qmlRegisterUncreatableType<NAMESPACE::T>("net.jami.Models", \
-                                             MAJ, MIN, #T, \
-                                             "Don't try to add to a qml definition of " #T);
-
-/*!
- * This function will expose custom types to the QML engine.
- */
-void
-registerTypes()
-{
-    /*
-     * QAbstractListModels
-     */
-    QML_REGISTERTYPE("net.jami.Models", AccountListModel, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", DeviceItemListModel, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", PluginItemListModel, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", PluginHandlerItemListModel, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", PreferenceItemListModel, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", BannedListModel, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", ModeratorListModel, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", MediaCodecListModel, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", AccountsToMigrateListModel, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", AudioDeviceModel, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", AudioManagerListModel, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", VideoInputDeviceModel, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", VideoFormatResolutionModel, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", VideoFormatFpsModel, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", PluginListPreferenceModel, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", SmartListModel, 1, 0);
-
-    /*
-     * QQuickItems
-     */
-    QML_REGISTERTYPE("net.jami.Models", PreviewRenderer, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", VideoCallPreviewRenderer, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", DistantRenderer, 1, 0);
-    QML_REGISTERTYPE("net.jami.Models", PhotoboothPreviewRender, 1, 0)
-
-    /*
-     * Adaptors
-     */
-    QML_REGISTERSINGLETONTYPE("net.jami.Models", CallAdapter, 1, 0);
-    QML_REGISTERSINGLETONTYPE("net.jami.Models", MessagesAdapter, 1, 0);
-    QML_REGISTERSINGLETONTYPE("net.jami.Models", ConversationsAdapter, 1, 0);
-    QML_REGISTERSINGLETONTYPE("net.jami.Models", AvAdapter, 1, 0);
-    QML_REGISTERSINGLETONTYPE("net.jami.Models", ContactAdapter, 1, 0);
-    QML_REGISTERSINGLETONTYPE("net.jami.Models", PluginAdapter, 1, 0);
-    QML_REGISTERSINGLETONTYPE("net.jami.Adapters", AccountAdapter, 1, 0);
-    QML_REGISTERSINGLETONTYPE("net.jami.Adapters", UtilsAdapter, 1, 0);
-    QML_REGISTERSINGLETONTYPE("net.jami.Adapters", SettingsAdapter, 1, 0);
-
-    QML_REGISTERSINGLETONTYPE_CUSTOM("net.jami.Models", AVModel, 1, 0, &LRCInstance::avModel())
-    QML_REGISTERSINGLETONTYPE_CUSTOM("net.jami.Models", PluginModel, 1, 0, &LRCInstance::pluginModel())
-
-    QML_REGISTERSINGLETONTYPE_CUSTOM("net.jami.Helpers", UpdateManager, 1, 0, LRCInstance::getUpdateManager())
-
-    /*
-     * Qml singleton components
-     */
-    QML_REGISTERSINGLETONTYPE_URL("net.jami.Constants", "qrc:/src/constant/JamiTheme.qml", JamiTheme, 1, 0);
-    QML_REGISTERSINGLETONTYPE_URL("net.jami.Models", "qrc:/src/constant/JamiQmlUtils.qml", JamiQmlUtils, 1, 0);
-    QML_REGISTERSINGLETONTYPE_URL("net.jami.Constants", "qrc:/src/constant/JamiStrings.qml", JamiStrings, 1, 0);
-
-    /*
-     * C++ singletons
-     */
-    QML_REGISTERSINGLETONTYPE_WITH_INSTANCE(LRCInstance, 1, 0);
-    QML_REGISTERSINGLETONTYPE_WITH_INSTANCE(NameDirectory, 1, 0);
-
-    /*
-     * lrc namespaces, models, and singletons
-     */
-    QML_REGISTERNAMESPACE(lrc::api::staticMetaObject, "Lrc", 1, 0);
-    QML_REGISTERNAMESPACE(lrc::api::account::staticMetaObject, "Account", 1, 0);
-    QML_REGISTERNAMESPACE(lrc::api::call::staticMetaObject, "Call", 1, 0);
-    QML_REGISTERNAMESPACE(lrc::api::datatransfer::staticMetaObject, "Datatransfer", 1, 0);
-    QML_REGISTERNAMESPACE(lrc::api::interaction::staticMetaObject, "Interaction", 1, 0);
-    QML_REGISTERNAMESPACE(lrc::api::video::staticMetaObject, "Video", 1, 0);
-    QML_REGISTERNAMESPACE(lrc::api::profile::staticMetaObject, "Profile", 1, 0);
-
-    /*
-     * same as QML_REGISTERUNCREATABLE but omit the namespace in Qml
-     */
-    QML_REGISTERUNCREATABLE_IN_NAMESPACE(NewAccountModel, lrc::api, 1, 0);
-    QML_REGISTERUNCREATABLE_IN_NAMESPACE(BehaviorController, lrc::api, 1, 0);
-    QML_REGISTERUNCREATABLE_IN_NAMESPACE(DataTransferModel, lrc::api, 1, 0);
-    QML_REGISTERUNCREATABLE_IN_NAMESPACE(ContactModel, lrc::api, 1, 0);
-    QML_REGISTERUNCREATABLE_IN_NAMESPACE(ConversationModel, lrc::api, 1, 0);
-    QML_REGISTERUNCREATABLE_IN_NAMESPACE(NewCallModel, lrc::api, 1, 0);
-    QML_REGISTERUNCREATABLE_IN_NAMESPACE(NewDeviceModel, lrc::api, 1, 0);
-    QML_REGISTERUNCREATABLE_IN_NAMESPACE(NewCodecModel, lrc::api, 1, 0);
-    QML_REGISTERUNCREATABLE_IN_NAMESPACE(PeerDiscoveryModel, lrc::api, 1, 0);
-
-    /*
-     * Enums
-     */
-    QML_REGISTERUNCREATABLE("net.jami.Enums", Settings, 1, 0);
-    QML_REGISTERUNCREATABLE("net.jami.Enums", NetWorkManager, 1, 0);
-}
-// clang-format on
+/*!
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.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 <https://www.gnu.org/licenses/>.
+ */
+
+#include "qmlregister.h"
+
+#include "accountadapter.h"
+#include "accountlistmodel.h"
+#include "accountstomigratelistmodel.h"
+#include "mediacodeclistmodel.h"
+#include "audiodevicemodel.h"
+#include "audiomanagerlistmodel.h"
+#include "avadapter.h"
+#include "bannedlistmodel.h"
+#include "moderatorlistmodel.h"
+#include "calladapter.h"
+#include "contactadapter.h"
+#include "conversationsadapter.h"
+#include "deviceitemlistmodel.h"
+#include "distantrenderer.h"
+#include "pluginadapter.h"
+#include "messagesadapter.h"
+#include "namedirectory.h"
+#include "updatemanager.h"
+#include "pluginlistpreferencemodel.h"
+#include "previewrenderer.h"
+#include "settingsadapter.h"
+#include "utilsadapter.h"
+#include "version.h"
+#include "videoformatfpsmodel.h"
+#include "videoformatresolutionmodel.h"
+#include "videoinputdevicemodel.h"
+
+#include <QMetaType>
+#include <QQmlEngine>
+
+// clang-format off
+#define QML_REGISTERSINGLETONTYPE_ADAPTER(N, T, MAJ, MIN) \
+    qmlRegisterSingletonType<T>(N, MAJ, MIN, #T, \
+                                [instance](QQmlEngine* e, QJSEngine* se) -> QObject* { \
+                                    Q_UNUSED(e); Q_UNUSED(se); \
+                                    T* obj = new T(nullptr, instance); return obj; \
+                                });
+
+#define QML_REGISTERSINGLETONTYPE_WITH_INSTANCE(T, MAJ, MIN) \
+    qmlRegisterSingletonType<T>("net.jami.Models", MAJ, MIN, #T, \
+                                [](QQmlEngine* e, QJSEngine* se) -> QObject* { \
+                                    Q_UNUSED(e); Q_UNUSED(se); \
+                                    return &(T::instance()); \
+                                });
+
+#define QML_REGISTERSINGLETONTYPE_CUSTOM(N, T, MAJ, MIN, P) \
+    qmlRegisterSingletonType<T>(N, MAJ, MIN, #T, \
+                                [instance](QQmlEngine* e, QJSEngine* se) -> QObject* { \
+                                    Q_UNUSED(e); Q_UNUSED(se); \
+                                    return P; \
+                                });
+
+#define QML_REGISTERSINGLETONTYPE_URL(N, URL, T, MAJ, MIN) \
+    qmlRegisterSingletonType(QUrl(QStringLiteral(URL)), N, MAJ, MIN, #T);
+
+#define QML_REGISTERTYPE(N, T, MAJ, MIN) qmlRegisterType<T>(N, MAJ, MIN, #T);
+
+#define QML_REGISTERNAMESPACE(T, NAME, MAJ, MIN) \
+    qmlRegisterUncreatableMetaObject(T, "net.jami.Models", MAJ, MIN, NAME, "")
+
+#define QML_REGISTERUNCREATABLE(N, T, MAJ, MIN) \
+    qmlRegisterUncreatableType<T>(N, MAJ, MIN, #T, "Don't try to add to a qml definition of " #T);
+
+#define QML_REGISTERUNCREATABLE_IN_NAMESPACE(T, NAMESPACE, MAJ, MIN) \
+    qmlRegisterUncreatableType<NAMESPACE::T>("net.jami.Models", \
+                                             MAJ, MIN, #T, \
+                                             "Don't try to add to a qml definition of " #T);
+
+/*!
+ * This function will expose custom types to the QML engine.
+ */
+void
+registerTypes(LRCInstance* instance)
+{
+    // QAbstractListModels
+    QML_REGISTERTYPE("net.jami.Models", AccountListModel, 1, 0);
+    QML_REGISTERTYPE("net.jami.Models", DeviceItemListModel, 1, 0);
+    QML_REGISTERTYPE("net.jami.Models", BannedListModel, 1, 0);
+    QML_REGISTERTYPE("net.jami.Models", ModeratorListModel, 1, 0);
+    QML_REGISTERTYPE("net.jami.Models", MediaCodecListModel, 1, 0);
+    QML_REGISTERTYPE("net.jami.Models", AccountsToMigrateListModel, 1, 0);
+    QML_REGISTERTYPE("net.jami.Models", AudioDeviceModel, 1, 0);
+    QML_REGISTERTYPE("net.jami.Models", AudioManagerListModel, 1, 0);
+    QML_REGISTERTYPE("net.jami.Models", VideoInputDeviceModel, 1, 0);
+    QML_REGISTERTYPE("net.jami.Models", VideoFormatResolutionModel, 1, 0);
+    QML_REGISTERTYPE("net.jami.Models", VideoFormatFpsModel, 1, 0);
+    QML_REGISTERTYPE("net.jami.Models", PluginListPreferenceModel, 1, 0);
+    QML_REGISTERTYPE("net.jami.Models", SmartListModel, 1, 0);
+
+    // QQuickItems
+    QML_REGISTERTYPE("net.jami.Models", PreviewRenderer, 1, 0);
+    QML_REGISTERTYPE("net.jami.Models", VideoCallPreviewRenderer, 1, 0);
+    QML_REGISTERTYPE("net.jami.Models", DistantRenderer, 1, 0);
+    QML_REGISTERTYPE("net.jami.Models", PhotoboothPreviewRender, 1, 0)
+
+    // Adaptors
+    QML_REGISTERSINGLETONTYPE_ADAPTER("net.jami.Adapters", CallAdapter, 1, 0);
+    QML_REGISTERSINGLETONTYPE_ADAPTER("net.jami.Adapters", MessagesAdapter, 1, 0);
+    QML_REGISTERSINGLETONTYPE_ADAPTER("net.jami.Adapters", ConversationsAdapter, 1, 0);
+    QML_REGISTERSINGLETONTYPE_ADAPTER("net.jami.Adapters", AvAdapter, 1, 0);
+    QML_REGISTERSINGLETONTYPE_ADAPTER("net.jami.Adapters", ContactAdapter, 1, 0);
+    QML_REGISTERSINGLETONTYPE_ADAPTER("net.jami.Adapters", PluginAdapter, 1, 0);
+    QML_REGISTERSINGLETONTYPE_ADAPTER("net.jami.Adapters", AccountAdapter, 1, 0);
+    QML_REGISTERSINGLETONTYPE_ADAPTER("net.jami.Adapters", UtilsAdapter, 1, 0);
+    QML_REGISTERSINGLETONTYPE_ADAPTER("net.jami.Adapters", SettingsAdapter, 1, 0);
+
+    QML_REGISTERSINGLETONTYPE_CUSTOM("net.jami.Models", AVModel, 1, 0, &instance->avModel())
+    QML_REGISTERSINGLETONTYPE_CUSTOM("net.jami.Models", PluginModel, 1, 0, &instance->pluginModel())
+
+    QML_REGISTERSINGLETONTYPE_CUSTOM("net.jami.Helpers", UpdateManager, 1, 0, instance->getUpdateManager())
+
+    // Qml singleton components
+    QML_REGISTERSINGLETONTYPE_URL("net.jami.Constants", "qrc:/src/constant/JamiTheme.qml", JamiTheme, 1, 0);
+    QML_REGISTERSINGLETONTYPE_URL("net.jami.Models", "qrc:/src/constant/JamiQmlUtils.qml", JamiQmlUtils, 1, 0);
+    QML_REGISTERSINGLETONTYPE_URL("net.jami.Constants", "qrc:/src/constant/JamiStrings.qml", JamiStrings, 1, 0);
+
+    // C++ singletons
+    QML_REGISTERSINGLETONTYPE_WITH_INSTANCE(NameDirectory, 1, 0);
+
+    // Lrc namespaces, models, and singletons
+    QML_REGISTERNAMESPACE(lrc::api::staticMetaObject, "Lrc", 1, 0);
+    QML_REGISTERNAMESPACE(lrc::api::account::staticMetaObject, "Account", 1, 0);
+    QML_REGISTERNAMESPACE(lrc::api::call::staticMetaObject, "Call", 1, 0);
+    QML_REGISTERNAMESPACE(lrc::api::datatransfer::staticMetaObject, "Datatransfer", 1, 0);
+    QML_REGISTERNAMESPACE(lrc::api::interaction::staticMetaObject, "Interaction", 1, 0);
+    QML_REGISTERNAMESPACE(lrc::api::video::staticMetaObject, "Video", 1, 0);
+    QML_REGISTERNAMESPACE(lrc::api::profile::staticMetaObject, "Profile", 1, 0);
+
+    // Same as QML_REGISTERUNCREATABLE but omit the namespace in Qml
+    QML_REGISTERUNCREATABLE_IN_NAMESPACE(NewAccountModel, lrc::api, 1, 0);
+    QML_REGISTERUNCREATABLE_IN_NAMESPACE(BehaviorController, lrc::api, 1, 0);
+    QML_REGISTERUNCREATABLE_IN_NAMESPACE(DataTransferModel, lrc::api, 1, 0);
+    QML_REGISTERUNCREATABLE_IN_NAMESPACE(ContactModel, lrc::api, 1, 0);
+    QML_REGISTERUNCREATABLE_IN_NAMESPACE(ConversationModel, lrc::api, 1, 0);
+    QML_REGISTERUNCREATABLE_IN_NAMESPACE(NewCallModel, lrc::api, 1, 0);
+    QML_REGISTERUNCREATABLE_IN_NAMESPACE(NewDeviceModel, lrc::api, 1, 0);
+    QML_REGISTERUNCREATABLE_IN_NAMESPACE(NewCodecModel, lrc::api, 1, 0);
+    QML_REGISTERUNCREATABLE_IN_NAMESPACE(PeerDiscoveryModel, lrc::api, 1, 0);
+
+    // Enums
+    QML_REGISTERUNCREATABLE("net.jami.Enums", Settings, 1, 0);
+    QML_REGISTERUNCREATABLE("net.jami.Enums", NetWorkManager, 1, 0);
+}
+// clang-format on
diff --git a/src/qmlregister.h b/src/qmlregister.h
index 0da93c8dc..2b78ac055 100644
--- a/src/qmlregister.h
+++ b/src/qmlregister.h
@@ -1,21 +1,23 @@
-/*!
- * Copyright (C) 2020 by Savoir-faire Linux
- * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.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 <https://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-void registerTypes();
+/*!
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.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 <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+class LRCInstance;
+
+void registerTypes(LRCInstance* instance);
diff --git a/src/qrimageprovider.h b/src/qrimageprovider.h
index 9293befdc..9af5c51d7 100644
--- a/src/qrimageprovider.h
+++ b/src/qrimageprovider.h
@@ -18,21 +18,19 @@
 
 #pragma once
 
+#include "quickimageproviderbase.h"
 #include "accountlistmodel.h"
-#include "lrcinstance.h"
 
-#include <QImage>
-#include <QObject>
 #include <QPair>
-#include <QQuickImageProvider>
 #include <QString>
 
-class QrImageProvider : public QObject, public QQuickImageProvider
+class QrImageProvider : public QuickImageProviderBase
 {
 public:
-    QrImageProvider()
-        : QQuickImageProvider(QQuickImageProvider::Image,
-                              QQmlImageProviderBase::ForceAsynchronousImageLoading)
+    QrImageProvider(LRCInstance* instance = nullptr)
+        : QuickImageProviderBase(QQuickImageProvider::Image,
+                                  QQmlImageProviderBase::ForceAsynchronousImageLoading,
+                                  instance)
     {}
 
     enum class QrType { Account, Contact };
@@ -54,8 +52,8 @@ public:
             /*
              * For contact_xxx, xxx is "" initially
              */
-            const auto& convInfo = LRCInstance::getConversationFromConvUid(list[1]);
-            auto contact = LRCInstance::getCurrentAccountInfo().contactModel->getContact(
+            const auto& convInfo = lrcInstance_->getConversationFromConvUid(list[1]);
+            auto contact = lrcInstance_->getCurrentAccountInfo().contactModel->getContact(
                 convInfo.participants.at(0));
             return QPair(QrType::Contact, contact.profileInfo.uri);
         }
@@ -75,12 +73,12 @@ public:
             if (indexPair.second.isEmpty())
                 return QImage();
 
-            auto accountList = LRCInstance::accountModel().getAccountList();
+            auto accountList = lrcInstance_->accountModel().getAccountList();
             auto accountIndex = indexPair.second.toInt();
             if (accountList.size() <= accountIndex)
                 return QImage();
 
-            auto& accountInfo = LRCInstance::accountModel().getAccountInfo(
+            auto& accountInfo = lrcInstance_->accountModel().getAccountInfo(
                 accountList.at(accountIndex));
             uri = accountInfo.profileInfo.uri;
         }
diff --git a/src/quickimageproviderbase.h b/src/quickimageproviderbase.h
new file mode 100644
index 000000000..8a612a140
--- /dev/null
+++ b/src/quickimageproviderbase.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019-2020 by Savoir-faire Linux
+ * Author: Mingrui Zhang   <mingrui.zhang@savoirfairelinux.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/>.
+ */
+
+#pragma once
+
+#include <QImage>
+#include <QObject>
+#include <QQuickImageProvider>
+
+class LRCInstance;
+
+class QuickImageProviderBase : public QObject, public QQuickImageProvider
+{
+public:
+    QuickImageProviderBase(QQuickImageProvider::ImageType type,
+                            QQmlImageProviderBase::Flag flag,
+                            LRCInstance* instance = nullptr)
+        : QQuickImageProvider(type, flag)
+        , lrcInstance_(instance)
+    {}
+
+protected:
+    // LRCInstance pointer
+    LRCInstance* lrcInstance_ {nullptr};
+};
diff --git a/src/runguard.cpp b/src/runguard.cpp
index 2ec2d3d9b..b20cd16a9 100644
--- a/src/runguard.cpp
+++ b/src/runguard.cpp
@@ -19,7 +19,7 @@
 
 #include "runguard.h"
 
-#include "lrcinstance.h"
+#include "mainapplication.h"
 
 #include <QCryptographicHash>
 
@@ -39,12 +39,13 @@ generateKeyHash(const QString& key, const QString& salt)
 
 } // namespace
 
-RunGuard::RunGuard(const QString& key)
+RunGuard::RunGuard(const QString& key, MainApplication* mainApp)
     : key_(key)
     , memLockKey_(generateKeyHash(key, "_memLockKey"))
     , sharedmemKey_(generateKeyHash(key, "_sharedmemKey"))
     , sharedMem_(sharedmemKey_)
     , memLock_(memLockKey_, 1)
+    , mainAppInstance_(mainApp)
 {}
 
 RunGuard::~RunGuard()
@@ -55,7 +56,7 @@ RunGuard::~RunGuard()
 void
 RunGuard::tryRestorePrimaryInstance()
 {
-    emit LRCInstance::instance().restoreAppRequested();
+    mainAppInstance_->restoreApp();
 }
 
 bool
@@ -128,4 +129,4 @@ RunGuard::release()
     if (sharedMem_.isAttached())
         sharedMem_.detach();
     memLock_.release();
-}
\ No newline at end of file
+}
diff --git a/src/runguard.h b/src/runguard.h
index 29b7ad419..093c6e082 100644
--- a/src/runguard.h
+++ b/src/runguard.h
@@ -25,12 +25,14 @@
 #include <QtNetwork/QLocalServer>
 #include <QtNetwork/QLocalSocket>
 
+class MainApplication;
+
 class RunGuard : public QObject
 {
     Q_OBJECT;
 
 public:
-    RunGuard(const QString& key);
+    RunGuard(const QString& key, MainApplication* mainApp = nullptr);
     ~RunGuard();
 
     bool isAnotherRunning();
@@ -41,6 +43,8 @@ private slots:
     void tryRestorePrimaryInstance();
 
 private:
+    MainApplication* mainAppInstance_;
+
     const QString key_;
     const QString memLockKey_;
     const QString sharedmemKey_;
@@ -52,4 +56,4 @@ private:
     QLocalServer* server_;
 
     Q_DISABLE_COPY(RunGuard)
-};
\ No newline at end of file
+};
diff --git a/src/settingsadapter.cpp b/src/settingsadapter.cpp
index b444653a9..ab7b57503 100644
--- a/src/settingsadapter.cpp
+++ b/src/settingsadapter.cpp
@@ -20,18 +20,10 @@
 
 #include "api/newdevicemodel.h"
 
-SettingsAdapter::SettingsAdapter(QObject* parent)
-    : QObject(parent)
+SettingsAdapter::SettingsAdapter(QObject* parent, LRCInstance* instance)
+    : QmlAdapterBase(parent, instance)
 {}
 
-/// Singleton
-SettingsAdapter&
-SettingsAdapter::instance()
-{
-    static auto instance = new SettingsAdapter;
-    return *instance;
-}
-
 QString
 SettingsAdapter::getDir_Document()
 {
@@ -43,11 +35,11 @@ QString
 SettingsAdapter::getDir_Download()
 {
     QString downloadPath = QDir::toNativeSeparators(
-        LRCInstance::dataTransferModel().downloadDirectory);
+        lrcInstance_->dataTransferModel().downloadDirectory);
     if (downloadPath.isEmpty()) {
         downloadPath = lrc::api::DataTransferModel::createDefaultDirectory();
         setDownloadPath(downloadPath);
-        LRCInstance::dataTransferModel().downloadDirectory = downloadPath;
+        lrcInstance_->dataTransferModel().downloadDirectory = downloadPath;
     }
 #ifdef Q_OS_WIN
     int pos = downloadPath.lastIndexOf(QChar('\\'));
@@ -87,7 +79,7 @@ void
 SettingsAdapter::setDownloadPath(QString dir)
 {
     setAppValue(Settings::Key::DownloadPath, dir);
-    LRCInstance::dataTransferModel().downloadDirectory = dir + "/";
+    lrcInstance_->dataTransferModel().downloadDirectory = dir + "/";
 }
 
 lrc::api::video::ResRateList
@@ -109,7 +101,7 @@ SettingsAdapter::getResolutions(const QString& device)
 {
     QVector<QString> resolutions;
 
-    auto currentSettings = LRCInstance::avModel().getDeviceSettings(device);
+    auto currentSettings = lrcInstance_->avModel().getDeviceSettings(device);
 
     auto currentChannel = currentSettings.channel.isEmpty() ? "default" : currentSettings.channel;
     auto channelCaps = get_ResRateList(currentChannel, device);
@@ -128,7 +120,7 @@ SettingsAdapter::getFrameRates(const QString& device)
 {
     QVector<int> rates;
 
-    auto currentSettings = LRCInstance::avModel().getDeviceSettings(device);
+    auto currentSettings = lrcInstance_->avModel().getDeviceSettings(device);
 
     auto currentChannel = currentSettings.channel.isEmpty() ? "default" : currentSettings.channel;
     auto channelCaps = get_ResRateList(currentChannel, device);
@@ -144,13 +136,13 @@ SettingsAdapter::getFrameRates(const QString& device)
 lrc::api::video::Capabilities
 SettingsAdapter::get_DeviceCapabilities(const QString& device)
 {
-    return LRCInstance::avModel().getDeviceCapabilities(device);
+    return lrcInstance_->avModel().getDeviceCapabilities(device);
 }
 
 QString
 SettingsAdapter::get_Video_Settings_Channel(const QString& deviceId)
 {
-    auto settings = LRCInstance::avModel().getDeviceSettings(deviceId);
+    auto settings = lrcInstance_->avModel().getDeviceSettings(deviceId);
 
     return (QString) settings.channel;
 }
@@ -158,7 +150,7 @@ SettingsAdapter::get_Video_Settings_Channel(const QString& deviceId)
 QString
 SettingsAdapter::get_Video_Settings_Name(const QString& deviceId)
 {
-    auto settings = LRCInstance::avModel().getDeviceSettings(deviceId);
+    auto settings = lrcInstance_->avModel().getDeviceSettings(deviceId);
 
     return (QString) settings.name;
 }
@@ -166,7 +158,7 @@ SettingsAdapter::get_Video_Settings_Name(const QString& deviceId)
 QString
 SettingsAdapter::get_Video_Settings_Id(const QString& deviceId)
 {
-    auto settings = LRCInstance::avModel().getDeviceSettings(deviceId);
+    auto settings = lrcInstance_->avModel().getDeviceSettings(deviceId);
 
     return (QString) settings.id;
 }
@@ -174,7 +166,7 @@ SettingsAdapter::get_Video_Settings_Id(const QString& deviceId)
 qreal
 SettingsAdapter::get_Video_Settings_Rate(const QString& deviceId)
 {
-    auto settings = LRCInstance::avModel().getDeviceSettings(deviceId);
+    auto settings = lrcInstance_->avModel().getDeviceSettings(deviceId);
 
     return (qreal) settings.rate;
 }
@@ -182,7 +174,7 @@ SettingsAdapter::get_Video_Settings_Rate(const QString& deviceId)
 QString
 SettingsAdapter::get_Video_Settings_Size(const QString& deviceId)
 {
-    auto settings = LRCInstance::avModel().getDeviceSettings(deviceId);
+    auto settings = lrcInstance_->avModel().getDeviceSettings(deviceId);
 
     return (QString) settings.size;
 }
@@ -192,22 +184,22 @@ SettingsAdapter::set_Video_Settings_Rate_And_Resolution(const QString& deviceId,
                                                         qreal rate,
                                                         const QString& resolution)
 {
-    auto settings = LRCInstance::avModel().getDeviceSettings(deviceId);
+    auto settings = lrcInstance_->avModel().getDeviceSettings(deviceId);
     settings.rate = rate;
     settings.size = resolution;
-    LRCInstance::avModel().setDeviceSettings(settings);
+    lrcInstance_->avModel().setDeviceSettings(settings);
 }
 
 const lrc::api::account::Info&
 SettingsAdapter::getCurrentAccountInfo()
 {
-    return LRCInstance::getCurrentAccountInfo();
+    return lrcInstance_->getCurrentAccountInfo();
 }
 
 const Q_INVOKABLE lrc::api::profile::Info&
 SettingsAdapter::getCurrentAccount_Profile_Info()
 {
-    return LRCInstance::getCurrentAccountInfo().profileInfo;
+    return lrcInstance_->getCurrentAccountInfo().profileInfo;
 }
 
 lrc::api::ContactModel*
@@ -225,19 +217,19 @@ SettingsAdapter::getDeviceModel()
 QString
 SettingsAdapter::get_CurrentAccountInfo_RegisteredName()
 {
-    return LRCInstance::getCurrentAccountInfo().registeredName;
+    return lrcInstance_->getCurrentAccountInfo().registeredName;
 }
 
 QString
 SettingsAdapter::get_CurrentAccountInfo_Id()
 {
-    return LRCInstance::getCurrentAccountInfo().id;
+    return lrcInstance_->getCurrentAccountInfo().id;
 }
 
 bool
 SettingsAdapter::get_CurrentAccountInfo_Enabled()
 {
-    return LRCInstance::getCurrentAccountInfo().enabled;
+    return lrcInstance_->getCurrentAccountInfo().enabled;
 }
 
 QString
@@ -261,7 +253,7 @@ SettingsAdapter::getCurrentAccount_Profile_Info_Type()
 QString
 SettingsAdapter::getAccountBestName()
 {
-    return LRCInstance::accountModel().bestNameForAccount(LRCInstance::getCurrAccId());
+    return lrcInstance_->accountModel().bestNameForAccount(lrcInstance_->getCurrAccId());
 }
 
 lrc::api::account::ConfProperties_t
@@ -269,7 +261,7 @@ SettingsAdapter::getAccountConfig()
 {
     lrc::api::account::ConfProperties_t res;
     try {
-        res = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+        res = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     } catch (...) {
     }
     return res;
@@ -568,7 +560,7 @@ SettingsAdapter::setAccountConfig_Username(QString input)
 {
     auto confProps = getAccountConfig();
     confProps.username = input;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
@@ -576,7 +568,7 @@ SettingsAdapter::setAccountConfig_Hostname(QString input)
 {
     auto confProps = getAccountConfig();
     confProps.hostname = input;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
@@ -584,7 +576,7 @@ SettingsAdapter::setAccountConfig_Password(QString input)
 {
     auto confProps = getAccountConfig();
     confProps.password = input;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
@@ -592,326 +584,326 @@ SettingsAdapter::setAccountConfig_RouteSet(QString input)
 {
     auto confProps = getAccountConfig();
     confProps.routeset = input;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setAutoConnectOnLocalNetwork(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.peerDiscovery = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setCallsUntrusted(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.DHT.PublicInCalls = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setIsRendezVous(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.isRendezVous = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setAutoAnswerCalls(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.autoAnswer = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setEnableRingtone(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.Ringtone.ringtoneEnabled = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setEnableProxy(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.proxyEnabled = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setKeepAliveEnabled(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.keepAliveEnabled = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setUseUPnP(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.upnpEnabled = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setUseTURN(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.TURN.enable = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setUseSTUN(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.STUN.enable = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setVideoState(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.Video.videoEnabled = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setUseSRTP(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.SRTP.enable = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setUseSDES(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.SRTP.keyExchange = state ? lrc::api::account::KeyExchangeProtocol::SDES
                                        : lrc::api::account::KeyExchangeProtocol::NONE;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setUseRTPFallback(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.SRTP.rtpFallback = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setUseTLS(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.TLS.enable = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setVerifyCertificatesServer(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.TLS.verifyServer = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setVerifyCertificatesClient(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.TLS.verifyClient = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setRequireCertificatesIncomingTLS(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.TLS.requireClientCertificate = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setUseCustomAddressAndPort(bool state)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.publishedSameAsLocal = state;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setNameServer(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.RingNS.uri = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setProxyAddress(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.proxyServer = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setBootstrapAddress(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.hostname = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setTURNAddress(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.TURN.server = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setTURNUsername(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.TURN.username = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setTURNPassword(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.TURN.password = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setTURNRealm(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.TURN.realm = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::setSTUNAddress(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.STUN.server = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::lineEditVoiceMailDialCodeEditFinished(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.mailbox = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::outgoingTLSServerNameLineEditTextChanged(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.TLS.serverName = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::lineEditSIPCertPasswordLineEditTextChanged(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.TLS.password = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::lineEditSIPCustomAddressLineEditTextChanged(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.publishedAddress = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::customPortSIPSpinBoxValueChanged(int value)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.publishedPort = value;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::negotiationTimeoutSpinBoxValueChanged(int value)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.TLS.negotiationTimeoutSec = value;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::registrationTimeoutSpinBoxValueChanged(int value)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.Registration.expire = value;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::networkInterfaceSpinBoxValueChanged(int value)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.localPort = value;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::audioRTPMinPortSpinBoxEditFinished(int value)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.Audio.audioPortMin = value;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::audioRTPMaxPortSpinBoxEditFinished(int value)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.Audio.audioPortMax = value;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::videoRTPMinPortSpinBoxEditFinished(int value)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.Video.videoPortMin = value;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::videoRTPMaxPortSpinBoxEditFinished(int value)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.Video.videoPortMax = value;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::tlsProtocolComboBoxIndexChanged(const int& index)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
 
     if (static_cast<int>(confProps.TLS.method) != index) {
         if (index == 0) {
@@ -923,22 +915,22 @@ SettingsAdapter::tlsProtocolComboBoxIndexChanged(const int& index)
         } else {
             confProps.TLS.method = lrc::api::account::TlsMethod::TLSv1_2;
         }
-        LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+        lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
     }
 }
 
 void
 SettingsAdapter::setDeviceName(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.deviceName = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::unbanContact(int index)
 {
-    auto& accountInfo = LRCInstance::getCurrentAccountInfo();
+    auto& accountInfo = lrcInstance_->getCurrentAccountInfo();
     auto bannedContactList = accountInfo.contactModel->getBannedContacts();
     auto it = bannedContactList.begin();
     std::advance(it, index);
@@ -950,71 +942,71 @@ SettingsAdapter::unbanContact(int index)
 void
 SettingsAdapter::audioCodecsStateChange(unsigned int id, bool isToEnable)
 {
-    auto audioCodecList = LRCInstance::getCurrentAccountInfo().codecModel->getAudioCodecs();
-    LRCInstance::getCurrentAccountInfo().codecModel->enable(id, isToEnable);
+    auto audioCodecList = lrcInstance_->getCurrentAccountInfo().codecModel->getAudioCodecs();
+    lrcInstance_->getCurrentAccountInfo().codecModel->enable(id, isToEnable);
 }
 
 void
 SettingsAdapter::videoCodecsStateChange(unsigned int id, bool isToEnable)
 {
-    auto videoCodecList = LRCInstance::getCurrentAccountInfo().codecModel->getVideoCodecs();
-    LRCInstance::getCurrentAccountInfo().codecModel->enable(id, isToEnable);
+    auto videoCodecList = lrcInstance_->getCurrentAccountInfo().codecModel->getVideoCodecs();
+    lrcInstance_->getCurrentAccountInfo().codecModel->enable(id, isToEnable);
 }
 
 void
 SettingsAdapter::decreaseAudioCodecPriority(unsigned int id)
 {
-    LRCInstance::getCurrentAccountInfo().codecModel->decreasePriority(id, false);
+    lrcInstance_->getCurrentAccountInfo().codecModel->decreasePriority(id, false);
 }
 
 void
 SettingsAdapter::increaseAudioCodecPriority(unsigned int id)
 {
-    LRCInstance::getCurrentAccountInfo().codecModel->increasePriority(id, false);
+    lrcInstance_->getCurrentAccountInfo().codecModel->increasePriority(id, false);
 }
 
 void
 SettingsAdapter::decreaseVideoCodecPriority(unsigned int id)
 {
-    LRCInstance::getCurrentAccountInfo().codecModel->decreasePriority(id, true);
+    lrcInstance_->getCurrentAccountInfo().codecModel->decreasePriority(id, true);
 }
 
 void
 SettingsAdapter::increaseVideoCodecPriority(unsigned int id)
 {
-    LRCInstance::getCurrentAccountInfo().codecModel->increasePriority(id, true);
+    lrcInstance_->getCurrentAccountInfo().codecModel->increasePriority(id, true);
 }
 
 void
 SettingsAdapter::set_RingtonePath(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.Ringtone.ringtonePath = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::set_FileCACert(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.TLS.certificateListFile = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::set_FileUserCert(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.TLS.certificateFile = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
 SettingsAdapter::set_FilePrivateKey(QString text)
 {
-    auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
+    auto confProps = lrcInstance_->accountModel().getAccountConfig(lrcInstance_->getCurrAccId());
     confProps.TLS.privateKeyFile = text;
-    LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
+    lrcInstance_->accountModel().setAccountConfig(lrcInstance_->getCurrAccId(), confProps);
 }
 
 void
@@ -1022,24 +1014,23 @@ SettingsAdapter::setDefaultModerator(const QString& accountId,
                                      const QString& peerURI,
                                      const bool& state)
 {
-    return LRCInstance::accountModel().setDefaultModerator(accountId, peerURI, state);
+    return lrcInstance_->accountModel().setDefaultModerator(accountId, peerURI, state);
 }
 
 QStringList
 SettingsAdapter::getDefaultModerators(const QString& accountId)
 {
-    return LRCInstance::accountModel().getDefaultModerators(accountId);
+    return lrcInstance_->accountModel().getDefaultModerators(accountId);
 }
 
 void
-SettingsAdapter::enableLocalModerators(const QString& accountId,
-                                       const bool& isModEnabled)
+SettingsAdapter::enableLocalModerators(const QString& accountId, const bool& isModEnabled)
 {
-    return LRCInstance::accountModel().enableLocalModerators(accountId, isModEnabled);
+    return lrcInstance_->accountModel().enableLocalModerators(accountId, isModEnabled);
 }
 
 bool
 SettingsAdapter::isLocalModeratorsEnabled(const QString& accountId)
 {
-    return LRCInstance::accountModel().isLocalModeratorsEnabled(accountId);
+    return lrcInstance_->accountModel().isLocalModeratorsEnabled(accountId);
 }
diff --git a/src/settingsadapter.h b/src/settingsadapter.h
index cabf798c5..25063b445 100644
--- a/src/settingsadapter.h
+++ b/src/settingsadapter.h
@@ -26,18 +26,17 @@
 #include "lrcinstance.h"
 #include "typedefs.h"
 #include "utils.h"
+#include "qmladapterbase.h"
 
-class SettingsAdapter : public QObject
+class SettingsAdapter : public QmlAdapterBase
 {
     Q_OBJECT
 public:
-    explicit SettingsAdapter(QObject* parent = nullptr);
+    explicit SettingsAdapter(QObject* parent = nullptr, LRCInstance* instance = nullptr);
 
-    // Singleton
-    static SettingsAdapter& instance();
-    /*
-     * getters of directories
-     */
+    void safeInit() override {}
+
+    // Getters of directories
     Q_INVOKABLE QString getDir_Document();
     Q_INVOKABLE QString getDir_Download();
 
@@ -47,23 +46,17 @@ public:
     Q_INVOKABLE void setRunOnStartUp(bool state);
     Q_INVOKABLE void setDownloadPath(QString dir);
 
-    /*
-     * getters of devices' Info and options
-     */
+    // Getters of devices' Info and options
     Q_INVOKABLE lrc::api::video::Capabilities get_DeviceCapabilities(const QString& device);
     Q_INVOKABLE lrc::api::video::ResRateList get_ResRateList(lrc::api::video::Channel channel,
                                                              QString device);
     Q_INVOKABLE int get_DeviceCapabilitiesSize(const QString& device);
 
-    /*
-     * getters of resolution and frame rates of current device
-     */
+    // Getters of resolution and frame rates of current device
     Q_INVOKABLE QVector<QString> getResolutions(const QString& device);
     Q_INVOKABLE QVector<int> getFrameRates(const QString& device);
 
-    /*
-     * getters and setters: lrc video::setting
-     */
+    // Getters and setters: lrc video::setting
     Q_INVOKABLE QString get_Video_Settings_Channel(const QString& deviceId);
     Q_INVOKABLE QString get_Video_Settings_Name(const QString& deviceId);
     Q_INVOKABLE QString get_Video_Settings_Id(const QString& deviceId);
@@ -74,9 +67,7 @@ public:
                                                             qreal rate,
                                                             const QString& resolution);
 
-    /*
-     * getters and setters of current account Info
-     */
+    // Getters and setters of current account Info
     const Q_INVOKABLE lrc::api::account::Info& getCurrentAccountInfo();
     const Q_INVOKABLE lrc::api::profile::Info& getCurrentAccount_Profile_Info();
 
@@ -87,16 +78,14 @@ public:
     Q_INVOKABLE QString get_CurrentAccountInfo_Id();
     Q_INVOKABLE bool get_CurrentAccountInfo_Enabled();
 
-    // profile info
+    // Profile info
     Q_INVOKABLE QString getCurrentAccount_Profile_Info_Uri();
     Q_INVOKABLE QString getCurrentAccount_Profile_Info_Alias();
     Q_INVOKABLE int getCurrentAccount_Profile_Info_Type();
     Q_INVOKABLE QString getAccountBestName();
 
-    /*
-     * getters and setters of ConfProperties_t
-     */
-    // getters
+    // Getters and setters of ConfProperties_t
+    // Getters
     Q_INVOKABLE lrc::api::account::ConfProperties_t getAccountConfig();
     Q_INVOKABLE QString getAccountConfig_Manageruri();
     Q_INVOKABLE QString getAccountConfig_Username();
@@ -159,7 +148,7 @@ public:
 
     Q_INVOKABLE QString getAccountConfig_Mailbox();
 
-    // setters
+    // Setters
     Q_INVOKABLE void setAccountConfig_Username(QString input);
     Q_INVOKABLE void setAccountConfig_Hostname(QString input);
     Q_INVOKABLE void setAccountConfig_Password(QString input);
@@ -232,9 +221,7 @@ public:
                                          const QString& peerURI,
                                          const bool& state);
     Q_INVOKABLE QStringList getDefaultModerators(const QString& accId);
-    Q_INVOKABLE void enableLocalModerators(const QString& accountID,
-                                           const bool& isModEnabled);
+    Q_INVOKABLE void enableLocalModerators(const QString& accountID, const bool& isModEnabled);
     Q_INVOKABLE bool isLocalModeratorsEnabled(const QString& accountId);
-
 };
 Q_DECLARE_METATYPE(SettingsAdapter*)
diff --git a/src/settingsview/components/AdvancedCallSettings.qml b/src/settingsview/components/AdvancedCallSettings.qml
index e389581b6..d7436af4d 100644
--- a/src/settingsview/components/AdvancedCallSettings.qml
+++ b/src/settingsview/components/AdvancedCallSettings.qml
@@ -187,7 +187,9 @@ ColumnLayout {
             Layout.fillWidth: true
             Layout.preferredHeight: 160
 
-            model: ModeratorListModel {}
+            model: ModeratorListModel {
+                lrcInstance: LRCInstance
+            }
 
             delegate: ContactItemDelegate {
                 id: moderatorListDelegate
diff --git a/src/settingsview/components/AudioSettings.qml b/src/settingsview/components/AudioSettings.qml
index 8d29010c7..9c9a5b731 100644
--- a/src/settingsview/components/AudioSettings.qml
+++ b/src/settingsview/components/AudioSettings.qml
@@ -66,7 +66,10 @@ ColumnLayout {
 
         labelText: JamiStrings.microphone
         fontPointSize: JamiTheme.settingsFontSize
-        comboModel: AudioDeviceModel { type: AudioDeviceModel.Type.Record }
+        comboModel: AudioDeviceModel {
+            lrcInstance: LRCInstance
+            type: AudioDeviceModel.Type.Record
+        }
         widthOfComboBox: itemWidth
         tipText: JamiStrings.selectAudioInputDevice
         role: "DeviceName"
@@ -102,7 +105,10 @@ ColumnLayout {
 
         labelText: JamiStrings.outputDevice
         fontPointSize: JamiTheme.settingsFontSize
-        comboModel: AudioDeviceModel { type: AudioDeviceModel.Type.Playback }
+        comboModel: AudioDeviceModel {
+            lrcInstance: LRCInstance
+            type: AudioDeviceModel.Type.Playback
+        }
         widthOfComboBox: itemWidth
         tipText: JamiStrings.selectAudioOutputDevice
         role: "DeviceName"
@@ -125,7 +131,10 @@ ColumnLayout {
 
         labelText: JamiStrings.ringtoneDevice
         fontPointSize: JamiTheme.settingsFontSize
-        comboModel: AudioDeviceModel { type: AudioDeviceModel.Type.Ringtone }
+        comboModel: AudioDeviceModel {
+            lrcInstance: LRCInstance
+            type: AudioDeviceModel.Type.Ringtone
+        }
         widthOfComboBox: itemWidth
         tipText: JamiStrings.selectRingtoneOutputDevice
         role: "DeviceName"
@@ -148,7 +157,9 @@ ColumnLayout {
 
         labelText: JamiStrings.audioManager
         fontPointSize: JamiTheme.settingsFontSize
-        comboModel: AudioManagerListModel {}
+        comboModel: AudioManagerListModel {
+            lrcInstance: LRCInstance
+        }
         widthOfComboBox: itemWidth
         role: "ID_UTF8"
 
diff --git a/src/settingsview/components/BannedContacts.qml b/src/settingsview/components/BannedContacts.qml
index 2364f3dd8..9c995d9fd 100644
--- a/src/settingsview/components/BannedContacts.qml
+++ b/src/settingsview/components/BannedContacts.qml
@@ -118,7 +118,9 @@ ColumnLayout {
 
         visible: false
 
-        model: BannedListModel {}
+        model: BannedListModel {
+            lrcInstance: LRCInstance
+        }
 
         delegate: ContactItemDelegate {
             id: bannedListDelegate
diff --git a/src/settingsview/components/LinkedDevices.qml b/src/settingsview/components/LinkedDevices.qml
index 846821978..35fe2722a 100644
--- a/src/settingsview/components/LinkedDevices.qml
+++ b/src/settingsview/components/LinkedDevices.qml
@@ -133,7 +133,9 @@ ColumnLayout {
         Layout.fillWidth: true
         Layout.preferredHeight: 160
 
-        model: DeviceItemListModel {}
+        model: DeviceItemListModel {
+            lrcInstance: LRCInstance
+        }
 
         delegate: DeviceItemDelegate {
             id: settingsListDelegate
diff --git a/src/settingsview/components/MediaSettings.qml b/src/settingsview/components/MediaSettings.qml
index cc01d66f5..cf451fed7 100644
--- a/src/settingsview/components/MediaSettings.qml
+++ b/src/settingsview/components/MediaSettings.qml
@@ -117,6 +117,7 @@ ColumnLayout {
 
         model: MediaCodecListModel {
             mediaType: root.mediaType
+            lrcInstance: LRCInstance
         }
 
         delegate: MediaCodecDelegate {
diff --git a/src/settingsview/components/PluginListPreferencesView.qml b/src/settingsview/components/PluginListPreferencesView.qml
index 4ad61a06b..bf986ca08 100644
--- a/src/settingsview/components/PluginListPreferencesView.qml
+++ b/src/settingsview/components/PluginListPreferencesView.qml
@@ -23,6 +23,7 @@ import QtQuick.Layouts 1.14
 import Qt.labs.platform 1.1
 import QtQuick.Dialogs 1.3
 import QtGraphicalEffects 1.14
+import net.jami.Adapters 1.0
 import net.jami.Models 1.0
 import net.jami.Constants 1.0
 
@@ -211,6 +212,8 @@ Rectangle {
                 isImage: IsImage
                 pluginListPreferenceModel: PluginListPreferenceModel {
                     id: pluginListPreferenceModel
+
+                    lrcInstance: LRCInstance
                     preferenceKey : PreferenceKey
                     pluginId: PluginId
                 }
diff --git a/src/settingsview/components/PluginSettingsPage.qml b/src/settingsview/components/PluginSettingsPage.qml
index 91242913a..0a4260e2d 100644
--- a/src/settingsview/components/PluginSettingsPage.qml
+++ b/src/settingsview/components/PluginSettingsPage.qml
@@ -22,6 +22,7 @@ import QtQuick.Controls.Universal 2.14
 import QtQuick.Layouts 1.14
 import Qt.labs.platform 1.1
 import QtGraphicalEffects 1.14
+import net.jami.Adapters 1.0
 import net.jami.Models 1.0
 import net.jami.Constants 1.0
 
diff --git a/src/settingsview/components/VideoSettings.qml b/src/settingsview/components/VideoSettings.qml
index 721c75a3d..6e3c301f6 100644
--- a/src/settingsview/components/VideoSettings.qml
+++ b/src/settingsview/components/VideoSettings.qml
@@ -166,7 +166,9 @@ ColumnLayout {
 
         labelText: JamiStrings.device
         fontPointSize: JamiTheme.settingsFontSize
-        comboModel: VideoInputDeviceModel {}
+        comboModel: VideoInputDeviceModel {
+            lrcInstance: LRCInstance
+        }
         widthOfComboBox: itemWidth
         tipText: JamiStrings.selectVideoDevice
         role: "DeviceName_UTF8"
@@ -185,7 +187,9 @@ ColumnLayout {
 
         labelText: JamiStrings.resolution
         fontPointSize: JamiTheme.settingsFontSize
-        comboModel: VideoFormatResolutionModel {}
+        comboModel: VideoFormatResolutionModel {
+            lrcInstance: LRCInstance
+        }
         widthOfComboBox: itemWidth
         tipText: JamiStrings.selectVideoResolution
         role: "Resolution_UTF8"
@@ -204,7 +208,9 @@ ColumnLayout {
 
         labelText: JamiStrings.fps
         fontPointSize: JamiTheme.settingsFontSize
-        comboModel: VideoFormatFpsModel {}
+        comboModel: VideoFormatFpsModel {
+            lrcInstance: LRCInstance
+        }
         widthOfComboBox: itemWidth
         tipText: JamiStrings.selectFPS
         role: "FPS_ToDisplay_UTF8"
@@ -247,8 +253,11 @@ ColumnLayout {
 
         PreviewRenderer {
             id: previewWidget
+
             anchors.fill: rectBox
 
+            lrcInstance: LRCInstance
+
             layer.enabled: true
             layer.effect: OpacityMask {
                 maskSource: rectBox
diff --git a/src/smartlistmodel.cpp b/src/smartlistmodel.cpp
index d3c425b1f..096ebb31e 100644
--- a/src/smartlistmodel.cpp
+++ b/src/smartlistmodel.cpp
@@ -23,12 +23,21 @@
 #include "lrcinstance.h"
 #include "utils.h"
 
+#include "api/account.h"
+#include "api/contact.h"
+#include "api/conversation.h"
+#include "api/conversationmodel.h"
+#include "api/contactmodel.h"
+
 #include <QDateTime>
 
-SmartListModel::SmartListModel(QObject* parent, SmartListModel::Type listModelType)
-    : QAbstractListModel(parent)
+SmartListModel::SmartListModel(QObject* parent,
+                               SmartListModel::Type listModelType,
+                               LRCInstance* instance)
+    : AbstractListModelBase(parent)
     , listModelType_(listModelType)
 {
+    lrcInstance_ = instance;
     if (listModelType_ == Type::CONFERENCE) {
         setConferenceableFilter();
     }
@@ -39,8 +48,8 @@ SmartListModel::~SmartListModel() {}
 int
 SmartListModel::rowCount(const QModelIndex& parent) const
 {
-    if (!parent.isValid()) {
-        auto& accInfo = LRCInstance::accountModel().getAccountInfo(LRCInstance::getCurrAccId());
+    if (!parent.isValid() && lrcInstance_) {
+        auto& accInfo = lrcInstance_->accountModel().getAccountInfo(lrcInstance_->getCurrAccId());
         auto& convModel = accInfo.conversationModel;
         if (listModelType_ == Type::TRANSFER) {
             auto filterType = accInfo.profileInfo.type;
@@ -76,8 +85,8 @@ SmartListModel::data(const QModelIndex& index, int role) const
     }
 
     try {
-        auto& currentAccountInfo = LRCInstance::accountModel().getAccountInfo(
-            LRCInstance::getCurrAccId());
+        auto& currentAccountInfo = lrcInstance_->accountModel().getAccountInfo(
+            lrcInstance_->getCurrAccId());
         auto& convModel = currentAccountInfo.conversationModel;
         if (listModelType_ == Type::TRANSFER) {
             auto filterType = currentAccountInfo.profileInfo.type;
@@ -122,8 +131,8 @@ SmartListModel::data(const QModelIndex& index, int role) const
                 return QVariant(itemAccountId);
             }
 
-            auto& itemAccountInfo = LRCInstance::accountModel().getAccountInfo(itemAccountId);
-            auto& item = LRCInstance::getConversationFromConvUid(itemConvUid, itemAccountId);
+            auto& itemAccountInfo = lrcInstance_->accountModel().getAccountInfo(itemAccountId);
+            auto& item = lrcInstance_->getConversationFromConvUid(itemConvUid, itemAccountId);
             return getConversationItemData(item, itemAccountInfo, role);
         } else if (listModelType_ == Type::CONVERSATION) {
             auto& item = conversations_.at(index.row());
@@ -163,9 +172,9 @@ void
 SmartListModel::setConferenceableFilter(const QString& filter)
 {
     beginResetModel();
-    auto& accountInfo = LRCInstance::accountModel().getAccountInfo(LRCInstance::getCurrAccId());
+    auto& accountInfo = lrcInstance_->accountModel().getAccountInfo(lrcInstance_->getCurrAccId());
     auto& convModel = accountInfo.conversationModel;
-    conferenceables_ = convModel->getConferenceableConversations(LRCInstance::getCurrentConvUid(),
+    conferenceables_ = convModel->getConferenceableConversations(lrcInstance_->getCurrentConvUid(),
                                                                  filter);
     sectionState_[tr("Calls")] = true;
     sectionState_[tr("Contacts")] = true;
@@ -176,9 +185,9 @@ void
 SmartListModel::fillConversationsList()
 {
     beginResetModel();
-    fillContactAvatarUidMap(LRCInstance::getCurrentAccountInfo().contactModel->getAllContacts());
+    fillContactAvatarUidMap(lrcInstance_->getCurrentAccountInfo().contactModel->getAllContacts());
 
-    auto* convModel = LRCInstance::getCurrentConversationModel();
+    auto* convModel = lrcInstance_->getCurrentConversationModel();
     using ConversationList = ConversationModel::ConversationQueueProxy;
     conversations_ = ConversationList(convModel->getAllSearchResults())
                      + convModel->allFilteredConversations();
@@ -233,7 +242,7 @@ SmartListModel::toggleSection(const QString& section)
 int
 SmartListModel::currentUidSmartListModelIndex()
 {
-    const auto convUid = LRCInstance::getCurrentConvUid();
+    const auto convUid = lrcInstance_->getCurrentConvUid();
     for (int i = 0; i < rowCount(); i++) {
         if (convUid == data(index(i, 0), Role::UID))
             return i;
@@ -315,17 +324,17 @@ SmartListModel::getConversationItemData(const conversation::Info& item,
     case Role::UID:
         return QVariant(item.uid);
     case Role::InCall: {
-        const auto& convInfo = LRCInstance::getConversationFromConvUid(item.uid);
+        const auto& convInfo = lrcInstance_->getConversationFromConvUid(item.uid);
         if (!convInfo.uid.isEmpty()) {
-            auto* callModel = LRCInstance::getCurrentCallModel();
+            auto* callModel = lrcInstance_->getCurrentCallModel();
             return QVariant(callModel->hasCall(convInfo.callId));
         }
         return QVariant(false);
     }
     case Role::IsAudioOnly: {
-        const auto& convInfo = LRCInstance::getConversationFromConvUid(item.uid);
+        const auto& convInfo = lrcInstance_->getConversationFromConvUid(item.uid);
         if (!convInfo.uid.isEmpty()) {
-            auto* call = LRCInstance::getCallInfoForConversation(convInfo);
+            auto* call = lrcInstance_->getCallInfoForConversation(convInfo);
             if (call) {
                 return QVariant(call->isAudioOnly);
             }
@@ -333,9 +342,9 @@ SmartListModel::getConversationItemData(const conversation::Info& item,
         return QVariant();
     }
     case Role::CallStackViewShouldShow: {
-        const auto& convInfo = LRCInstance::getConversationFromConvUid(item.uid);
+        const auto& convInfo = lrcInstance_->getConversationFromConvUid(item.uid);
         if (!convInfo.uid.isEmpty()) {
-            auto* callModel = LRCInstance::getCurrentCallModel();
+            auto* callModel = lrcInstance_->getCurrentCallModel();
             const auto& call = callModel->getCall(convInfo.callId);
             return QVariant(
                 callModel->hasCall(convInfo.callId)
@@ -348,9 +357,9 @@ SmartListModel::getConversationItemData(const conversation::Info& item,
         return QVariant(false);
     }
     case Role::CallState: {
-        const auto& convInfo = LRCInstance::getConversationFromConvUid(item.uid);
+        const auto& convInfo = lrcInstance_->getConversationFromConvUid(item.uid);
         if (!convInfo.uid.isEmpty()) {
-            if (auto* call = LRCInstance::getCallInfoForConversation(convInfo)) {
+            if (auto* call = lrcInstance_->getCallInfoForConversation(convInfo)) {
                 return QVariant(static_cast<int>(call->status));
             }
         }
@@ -360,14 +369,14 @@ SmartListModel::getConversationItemData(const conversation::Info& item,
         return QVariant(QString());
     case Role::Draft: {
         if (!item.uid.isEmpty()) {
-            const auto draft = LRCInstance::getContentDraft(item.uid, accountInfo.id);
+            const auto draft = lrcInstance_->getContentDraft(item.uid, accountInfo.id);
             if (!draft.isEmpty()) {
                 /*
                  * Pencil Emoji
                  */
                 uint cp = 0x270F;
                 auto emojiString = QString::fromUcs4(&cp, 1);
-                return emojiString + LRCInstance::getContentDraft(item.uid, accountInfo.id);
+                return emojiString + lrcInstance_->getContentDraft(item.uid, accountInfo.id);
             }
         }
         return QVariant("");
diff --git a/src/smartlistmodel.h b/src/smartlistmodel.h
index 357dd0c94..a90db11b4 100644
--- a/src/smartlistmodel.h
+++ b/src/smartlistmodel.h
@@ -20,17 +20,12 @@
 
 #pragma once
 
-#include "api/account.h"
-#include "api/contact.h"
-#include "api/conversation.h"
-#include "api/conversationmodel.h"
-#include "api/contactmodel.h"
-
-#include <QAbstractItemModel>
+#include "abstractitemmodelbase.h"
 
 using namespace lrc::api;
+class LRCInstance;
 
-class SmartListModel : public QAbstractListModel
+class SmartListModel : public AbstractListModelBase
 {
     Q_OBJECT
 public:
@@ -63,8 +58,9 @@ public:
     };
     Q_ENUM(Role)
 
-    explicit SmartListModel(QObject* parent = 0,
-                            SmartListModel::Type listModelType = Type::CONVERSATION);
+    explicit SmartListModel(QObject* parent = nullptr,
+                            SmartListModel::Type listModelType = Type::CONVERSATION,
+                            LRCInstance* instance = nullptr);
     ~SmartListModel();
 
     /*
diff --git a/src/tintedbuttonimageprovider.h b/src/tintedbuttonimageprovider.h
index ce6149c70..d708c295c 100644
--- a/src/tintedbuttonimageprovider.h
+++ b/src/tintedbuttonimageprovider.h
@@ -18,21 +18,20 @@
 
 #pragma once
 
+#include "quickimageproviderbase.h"
 #include "lrcinstance.h"
 #include "utils.h"
 
-#include <QImage>
-#include <QObject>
 #include <QPair>
-#include <QQuickImageProvider>
 #include <QString>
 
-class TintedButtonImageProvider : public QObject, public QQuickImageProvider
+class TintedButtonImageProvider : public QuickImageProviderBase
 {
 public:
-    TintedButtonImageProvider()
-        : QQuickImageProvider(QQuickImageProvider::Pixmap,
-                              QQmlImageProviderBase::ForceAsynchronousImageLoading)
+    TintedButtonImageProvider(LRCInstance* instance = nullptr)
+        : QuickImageProviderBase(QQuickImageProvider::Pixmap,
+                                  QQmlImageProviderBase::ForceAsynchronousImageLoading,
+                                  instance)
     {}
 
     QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) override
@@ -57,4 +56,4 @@ public:
 
         return QPixmap();
     }
-};
\ No newline at end of file
+};
diff --git a/src/updatemanager.cpp b/src/updatemanager.cpp
index 9adb8480d..06dfd1549 100644
--- a/src/updatemanager.cpp
+++ b/src/updatemanager.cpp
@@ -1,165 +1,169 @@
-/*!
- * Copyright (C) 2020 by Savoir-faire Linux
- * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.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/>.
- */
-
-#include "updatemanager.h"
-
-#include "appsettingsmanager.h"
-#include "lrcinstance.h"
-#include "utils.h"
-#include "version.h"
-
-#include <QProcess>
-#include <QTimer>
-
-#ifdef BETA
-static constexpr bool isBeta = true;
-#else
-static constexpr bool isBeta = false;
-#endif
-
-static constexpr int updatePeriod = 1000 * 60 * 60 * 24; // one day in millis
-
-UpdateManager::UpdateManager(const QString& url, ConnectivityMonitor* cm, QObject* parent)
-    : NetWorkManager(cm, parent)
-    , baseUrl_(url.isEmpty() ? "https://dl.jami.net/windows" : url.toLatin1())
-    , tempPath_(Utils::WinGetEnv("TEMP"))
-    , updateTimer_(new QTimer(this))
-{
-    connect(updateTimer_, &QTimer::timeout, [this] {
-        // Quiet period update check.
-        checkForUpdates(true);
-    });
-}
-
-void
-UpdateManager::setAutoUpdateCheck(bool state)
-{
-    // Quiet check for updates periodically, if set to.
-    if (!state) {
-        updateTimer_->stop();
-        return;
-    }
-    updateTimer_->start(updatePeriod);
-}
-
-bool
-UpdateManager::isCurrentVersionBeta()
-{
-    return isBeta;
-}
-
-void
-UpdateManager::checkForUpdates(bool quiet)
-{
-    disconnect();
-
-    // Fail without UI if this is a programmatic check.
-    if (!quiet)
-        connect(this, &NetWorkManager::errorOccured, this, &UpdateManager::updateCheckErrorOccurred);
-
-    cleanUpdateFiles();
-    QUrl versionUrl {isBeta ? QUrl::fromEncoded(baseUrl_ + "/beta/version")
-                            : QUrl::fromEncoded(baseUrl_ + "/version")};
-
-    get(versionUrl, [this, quiet](const QString& latestVersionString) {
-        if (latestVersionString.isEmpty()) {
-            qWarning() << "Error checking version";
-            if (!quiet)
-                emit updateCheckReplyReceived(false);
-            return;
-        }
-        auto currentVersion = QString(VERSION_STRING).toULongLong();
-        auto latestVersion = latestVersionString.toULongLong();
-        qDebug() << "latest: " << latestVersion << " current: " << currentVersion;
-        if (latestVersion > currentVersion) {
-            qDebug() << "New version found";
-            emit updateCheckReplyReceived(true, true);
-        } else {
-            qDebug() << "No new version found";
-            if (!quiet)
-                emit updateCheckReplyReceived(true, false);
-        }
-    });
-}
-
-void
-UpdateManager::applyUpdates(bool beta)
-{
-    disconnect();
-    connect(this, &NetWorkManager::errorOccured, this, &UpdateManager::updateDownloadErrorOccurred);
-    connect(this, &NetWorkManager::statusChanged, [this](GetStatus status) {
-        switch (status) {
-        case GetStatus::STARTED:
-            connect(this,
-                    &NetWorkManager::downloadProgressChanged,
-                    this,
-                    &UpdateManager::updateDownloadProgressChanged);
-            emit updateDownloadStarted();
-            break;
-        case GetStatus::FINISHED:
-            emit updateDownloadFinished();
-            break;
-        default:
-            break;
-        }
-    });
-
-    QUrl downloadUrl {(beta || isBeta) ? QUrl::fromEncoded(baseUrl_ + "/beta/jami.beta.x64.msi")
-                                       : QUrl::fromEncoded(baseUrl_ + "/jami.release.x64.msi")};
-
-    get(
-        downloadUrl,
-        [this, downloadUrl](const QString&) {
-            LRCInstance::reset();
-            emit LRCInstance::instance().quitEngineRequested();
-            auto args = QString(" /passive /norestart WIXNONUILAUNCH=1");
-            QProcess process;
-            process.start("powershell ",
-                          QStringList() << tempPath_ + "\\" + downloadUrl.fileName() << "/L*V"
-                                        << tempPath_ + "\\jami_x64_install.log" + args);
-            process.waitForFinished();
-        },
-        tempPath_);
-}
-
-void
-UpdateManager::cancelUpdate()
-{
-    cancelRequest();
-}
-
-void
-UpdateManager::cleanUpdateFiles()
-{
-    /*
-     * Delete all logs and msi in the %TEMP% directory before launching.
-     */
-    QString dir = QString(Utils::WinGetEnv("TEMP"));
-    QDir log_dir(dir, {"jami*.log"});
-    for (const QString& filename : log_dir.entryList()) {
-        log_dir.remove(filename);
-    }
-    QDir msi_dir(dir, {"jami*.msi"});
-    for (const QString& filename : msi_dir.entryList()) {
-        msi_dir.remove(filename);
-    }
-    QDir version_dir(dir, {"version"});
-    for (const QString& filename : version_dir.entryList()) {
-        version_dir.remove(filename);
-    }
-}
+/*!
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.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/>.
+ */
+
+#include "updatemanager.h"
+
+#include "appsettingsmanager.h"
+#include "lrcinstance.h"
+#include "utils.h"
+#include "version.h"
+
+#include <QProcess>
+#include <QTimer>
+
+#ifdef BETA
+static constexpr bool isBeta = true;
+#else
+static constexpr bool isBeta = false;
+#endif
+
+static constexpr int updatePeriod = 1000 * 60 * 60 * 24; // one day in millis
+
+UpdateManager::UpdateManager(const QString& url,
+                             ConnectivityMonitor* cm,
+                             QObject* parent,
+                             LRCInstance* instance)
+    : NetWorkManager(cm, parent)
+    , baseUrl_(url.isEmpty() ? "https://dl.jami.net/windows" : url.toLatin1())
+    , tempPath_(Utils::WinGetEnv("TEMP"))
+    , updateTimer_(new QTimer(this))
+    , lrcInstance_(instance)
+{
+    connect(updateTimer_, &QTimer::timeout, [this] {
+        // Quiet period update check.
+        checkForUpdates(true);
+    });
+}
+
+void
+UpdateManager::setAutoUpdateCheck(bool state)
+{
+    // Quiet check for updates periodically, if set to.
+    if (!state) {
+        updateTimer_->stop();
+        return;
+    }
+    updateTimer_->start(updatePeriod);
+}
+
+bool
+UpdateManager::isCurrentVersionBeta()
+{
+    return isBeta;
+}
+
+void
+UpdateManager::checkForUpdates(bool quiet)
+{
+    disconnect();
+
+    // Fail without UI if this is a programmatic check.
+    if (!quiet)
+        connect(this, &NetWorkManager::errorOccured, this, &UpdateManager::updateCheckErrorOccurred);
+
+    cleanUpdateFiles();
+    QUrl versionUrl {isBeta ? QUrl::fromEncoded(baseUrl_ + "/beta/version")
+                            : QUrl::fromEncoded(baseUrl_ + "/version")};
+
+    get(versionUrl, [this, quiet](const QString& latestVersionString) {
+        if (latestVersionString.isEmpty()) {
+            qWarning() << "Error checking version";
+            if (!quiet)
+                emit updateCheckReplyReceived(false);
+            return;
+        }
+        auto currentVersion = QString(VERSION_STRING).toULongLong();
+        auto latestVersion = latestVersionString.toULongLong();
+        qDebug() << "latest: " << latestVersion << " current: " << currentVersion;
+        if (latestVersion > currentVersion) {
+            qDebug() << "New version found";
+            emit updateCheckReplyReceived(true, true);
+        } else {
+            qDebug() << "No new version found";
+            if (!quiet)
+                emit updateCheckReplyReceived(true, false);
+        }
+    });
+}
+
+void
+UpdateManager::applyUpdates(bool beta)
+{
+    disconnect();
+    connect(this, &NetWorkManager::errorOccured, this, &UpdateManager::updateDownloadErrorOccurred);
+    connect(this, &NetWorkManager::statusChanged, [this](GetStatus status) {
+        switch (status) {
+        case GetStatus::STARTED:
+            connect(this,
+                    &NetWorkManager::downloadProgressChanged,
+                    this,
+                    &UpdateManager::updateDownloadProgressChanged);
+            emit updateDownloadStarted();
+            break;
+        case GetStatus::FINISHED:
+            emit updateDownloadFinished();
+            break;
+        default:
+            break;
+        }
+    });
+
+    QUrl downloadUrl {(beta || isBeta) ? QUrl::fromEncoded(baseUrl_ + "/beta/jami.beta.x64.msi")
+                                       : QUrl::fromEncoded(baseUrl_ + "/jami.release.x64.msi")};
+
+    get(
+        downloadUrl,
+        [this, downloadUrl](const QString&) {
+            lrcInstance_->reset();
+            emit lrcInstance_->quitEngineRequested();
+            auto args = QString(" /passive /norestart WIXNONUILAUNCH=1");
+            QProcess process;
+            process.start("powershell ",
+                          QStringList() << tempPath_ + "\\" + downloadUrl.fileName() << "/L*V"
+                                        << tempPath_ + "\\jami_x64_install.log" + args);
+            process.waitForFinished();
+        },
+        tempPath_);
+}
+
+void
+UpdateManager::cancelUpdate()
+{
+    cancelRequest();
+}
+
+void
+UpdateManager::cleanUpdateFiles()
+{
+    /*
+     * Delete all logs and msi in the %TEMP% directory before launching.
+     */
+    QString dir = QString(Utils::WinGetEnv("TEMP"));
+    QDir log_dir(dir, {"jami*.log"});
+    for (const QString& filename : log_dir.entryList()) {
+        log_dir.remove(filename);
+    }
+    QDir msi_dir(dir, {"jami*.msi"});
+    for (const QString& filename : msi_dir.entryList()) {
+        msi_dir.remove(filename);
+    }
+    QDir version_dir(dir, {"version"});
+    for (const QString& filename : version_dir.entryList()) {
+        version_dir.remove(filename);
+    }
+}
diff --git a/src/updatemanager.h b/src/updatemanager.h
index 792830739..f60e942a1 100644
--- a/src/updatemanager.h
+++ b/src/updatemanager.h
@@ -1,55 +1,62 @@
-/*!
- * Copyright (C) 2020 by Savoir-faire Linux
- * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.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/>.
- */
-
-#pragma once
-
-#include "networkmanager.h"
-
-class ConnectivityMonitor;
-class QTimer;
-
-class UpdateManager final : public NetWorkManager
-{
-    Q_OBJECT
-public:
-    explicit UpdateManager(const QString& url, ConnectivityMonitor* cm, QObject* parent = nullptr);
-    ~UpdateManager() = default;
-
-    Q_INVOKABLE void checkForUpdates(bool quiet = false);
-    Q_INVOKABLE void applyUpdates(bool beta = false);
-    Q_INVOKABLE void cancelUpdate();
-    Q_INVOKABLE void setAutoUpdateCheck(bool state);
-    Q_INVOKABLE bool isCurrentVersionBeta();
-
-signals:
-    void updateCheckReplyReceived(bool ok, bool found = false);
-    void updateCheckErrorOccurred(GetError error);
-    void updateDownloadStarted();
-    void updateDownloadProgressChanged(qint64 bytesRead, qint64 totalBytes);
-    void updateDownloadErrorOccurred(GetError error);
-    void updateDownloadFinished();
-    void appCloseRequested();
-
-private:
-    QByteArray baseUrl_;
-    QString tempPath_;
-    QTimer* updateTimer_;
-
-    void cleanUpdateFiles();
-};
-Q_DECLARE_METATYPE(UpdateManager*)
+/*!
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.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/>.
+ */
+
+#pragma once
+
+#include "networkmanager.h"
+
+class LRCInstance;
+class ConnectivityMonitor;
+class QTimer;
+
+class UpdateManager final : public NetWorkManager
+{
+    Q_OBJECT
+public:
+    explicit UpdateManager(const QString& url,
+                           ConnectivityMonitor* cm,
+                           QObject* parent = nullptr,
+                           LRCInstance* instance = nullptr);
+    ~UpdateManager() = default;
+
+    Q_INVOKABLE void checkForUpdates(bool quiet = false);
+    Q_INVOKABLE void applyUpdates(bool beta = false);
+    Q_INVOKABLE void cancelUpdate();
+    Q_INVOKABLE void setAutoUpdateCheck(bool state);
+    Q_INVOKABLE bool isCurrentVersionBeta();
+
+signals:
+    void updateCheckReplyReceived(bool ok, bool found = false);
+    void updateCheckErrorOccurred(GetError error);
+    void updateDownloadStarted();
+    void updateDownloadProgressChanged(qint64 bytesRead, qint64 totalBytes);
+    void updateDownloadErrorOccurred(GetError error);
+    void updateDownloadFinished();
+    void appCloseRequested();
+
+private:
+    // LRCInstance pointer
+    LRCInstance* lrcInstance_ {nullptr};
+
+    QByteArray baseUrl_;
+    QString tempPath_;
+    QTimer* updateTimer_;
+
+    void cleanUpdateFiles();
+};
+Q_DECLARE_METATYPE(UpdateManager*)
diff --git a/src/utils.cpp b/src/utils.cpp
index 6073b1d89..0edb4c2fc 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -81,10 +81,9 @@ Utils::CreateStartupLink(const std::wstring& wstrAppName)
     desktopPath += "/jami-qt/jami-qt.desktop";
 #else
     desktopPath = "share/jami-qt/jami-qt.desktop";
-    QStringList paths = {
-        "/usr/" + desktopPath,
-        "/usr/local/" + desktopPath,
-        QDir::currentPath() + "/../../install/client-qt/" + desktopPath };
+    QStringList paths = {"/usr/" + desktopPath,
+                         "/usr/local/" + desktopPath,
+                         QDir::currentPath() + "/../../install/client-qt/" + desktopPath};
     for (QString filename : paths) {
         if (QFile::exists(filename)) {
             desktopPath = filename;
@@ -115,7 +114,7 @@ Utils::CreateStartupLink(const std::wstring& wstrAppName)
         }
     } else {
         QString autoStartDir = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)
-                + "/autostart";
+                               + "/autostart";
 
         if (!QDir(autoStartDir).exists()) {
             if (QDir().mkdir(autoStartDir)) {
@@ -130,9 +129,8 @@ Utils::CreateStartupLink(const std::wstring& wstrAppName)
 
     QFile srcFile(desktopPath);
     bool result = srcFile.link(desktopFile);
-    qDebug() << desktopFile << (result
-                                ? "-> " + desktopPath + " successfully created"
-                                : "could not be created");
+    qDebug() << desktopFile
+             << (result ? "-> " + desktopPath + " successfully created" : "could not be created");
     return result;
 #endif
 }
@@ -208,8 +206,8 @@ Utils::CheckStartupLink(const std::wstring& wstrAppName)
     linkPath += std::wstring(TEXT("\\") + wstrAppName + TEXT(".lnk"));
     return PathFileExists(linkPath.c_str());
 #else
-    return (!QStandardPaths::locate(QStandardPaths::ConfigLocation,
-                                    "autostart/jami-qt.desktop").isEmpty());
+    return (!QStandardPaths::locate(QStandardPaths::ConfigLocation, "autostart/jami-qt.desktop")
+                 .isEmpty());
 #endif
 }
 
@@ -324,7 +322,7 @@ Utils::GetISODate()
 }
 
 QImage
-Utils::contactPhoto(const QString& contactUri, const QSize& size)
+Utils::contactPhoto(LRCInstance* instance, const QString& contactUri, const QSize& size)
 {
     QImage photo;
 
@@ -332,7 +330,7 @@ Utils::contactPhoto(const QString& contactUri, const QSize& size)
         /*
          * Get first contact photo.
          */
-        auto& accountInfo = LRCInstance::accountModel().getAccountInfo(LRCInstance::getCurrAccId());
+        auto& accountInfo = instance->accountModel().getAccountInfo(instance->getCurrAccId());
         auto contactInfo = accountInfo.contactModel->getContact(contactUri);
         auto contactPhoto = contactInfo.profileInfo.avatar;
         auto bestName = accountInfo.contactModel->bestNameForContact(contactUri);
@@ -805,15 +803,17 @@ Utils::scaleAndFrame(const QImage photo, const QSize& size)
 }
 
 QImage
-Utils::accountPhoto(const lrc::api::account::Info& accountInfo, const QSize& size)
+Utils::accountPhoto(LRCInstance* instance,
+                    const lrc::api::account::Info& accountInfo,
+                    const QSize& size)
 {
     QImage photo;
     if (!accountInfo.profileInfo.avatar.isEmpty()) {
         QByteArray ba = Utils::base64StringToByteArray(accountInfo.profileInfo.avatar);
         photo = contactPhotoFromBase64(ba, nullptr);
     } else {
-        auto bestId = LRCInstance::accountModel().bestIdForAccount(accountInfo.id);
-        auto bestName = LRCInstance::accountModel().bestNameForAccount(accountInfo.id);
+        auto bestId = instance->accountModel().bestIdForAccount(accountInfo.id);
+        auto bestName = instance->accountModel().bestNameForAccount(accountInfo.id);
         QString letterStr = (bestId == bestName || bestName == accountInfo.profileInfo.uri)
                                 ? QString()
                                 : bestName;
diff --git a/src/utils.h b/src/utils.h
index f21958ea3..e39439d9d 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -53,11 +53,11 @@
 #include "api/contactmodel.h"
 #include "api/conversationmodel.h"
 
+class LRCInstance;
+
 namespace Utils {
 
-/*
- * App/System
- */
+// App System
 bool CreateStartupLink(const std::wstring& wstrAppName);
 void DeleteStartupLink(const std::wstring& wstrAppName);
 bool CreateLink(LPCWSTR lpszPathObj, LPCWSTR lpszPathLink);
@@ -76,9 +76,7 @@ void forceDeleteAsync(const QString& path);
 QString getProjectCredits();
 void removeOldVersions();
 
-/*
- * LRC helpers
- */
+// LRC helpers
 lrc::api::profile::Type profileType(const lrc::api::conversation::Info& conv,
                                     const lrc::api::ConversationModel& model);
 std::string formatTimeString(const std::time_t& timestamp);
@@ -86,12 +84,12 @@ bool isInteractionGenerated(const lrc::api::interaction::Type& interaction);
 bool isContactValid(const QString& contactUid, const lrc::api::ConversationModel& model);
 bool getReplyMessageBox(QWidget* widget, const QString& title, const QString& text);
 
-/*
- * Image manipulation
- */
+// Image manipulation
 static const QSize defaultAvatarSize {128, 128};
 QImage contactPhotoFromBase64(const QByteArray& data, const QString& type);
-QImage contactPhoto(const QString& contactUri, const QSize& size = defaultAvatarSize);
+QImage contactPhoto(LRCInstance* instance,
+                    const QString& contactUri,
+                    const QSize& size = defaultAvatarSize);
 QImage getCirclePhoto(const QImage original, int sizePhoto);
 QColor getAvatarColor(const QString& canonicalUri);
 QImage fallbackAvatar(const QString& canonicalUriStr,
@@ -107,7 +105,8 @@ QByteArray QByteArrayFromFile(const QString& filename);
 QPixmap generateTintedPixmap(const QString& filename, QColor color);
 QPixmap generateTintedPixmap(const QPixmap& pix, QColor color);
 QImage scaleAndFrame(const QImage photo, const QSize& size = defaultAvatarSize);
-QImage accountPhoto(const lrc::api::account::Info& accountInfo,
+QImage accountPhoto(LRCInstance* instance,
+                    const lrc::api::account::Info& accountInfo,
                     const QSize& size = defaultAvatarSize);
 QImage cropImage(const QImage& img);
 QPixmap pixmapFromSvg(const QString& svg_resource, const QSize& size);
@@ -115,9 +114,7 @@ QImage setupQRCode(QString ringID, int margin);
 bool isImage(const QString& fileExt);
 QString generateUid();
 
-/*
- * Misc
- */
+// Misc
 QString formattedTime(int seconds);
 QString humanFileSize(qint64 fileSize);
 
diff --git a/src/utilsadapter.cpp b/src/utilsadapter.cpp
index 49eeeff6b..d886a0f4e 100644
--- a/src/utilsadapter.cpp
+++ b/src/utilsadapter.cpp
@@ -1,367 +1,367 @@
-/*!
- * Copyright (C) 2015-2020 by Savoir-faire Linux
- * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
- * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
- * Author: Isa Nanic <isa.nanic@savoirfairelinux.com>
- * Author: Mingrui Zhang   <mingrui.zhang@savoirfairelinux.com>
- * Author: Aline Gondim Santos   <aline.gondimsantos@savoirfairelinux.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/>.
- */
-
-#include "utilsadapter.h"
-
-#include "globalsystemtray.h"
-#include "lrcinstance.h"
-#include "utils.h"
-#include "version.h"
-
-#include <QApplication>
-#include <QClipboard>
-#include <QFileInfo>
-
-UtilsAdapter::UtilsAdapter(QObject* parent)
-    : QObject(parent)
-    , clipboard_(QApplication::clipboard())
-{}
-
-const QString
-UtilsAdapter::getProjectCredits()
-{
-    return Utils::getProjectCredits();
-}
-
-const QString
-UtilsAdapter::getVersionStr()
-{
-    return QString(VERSION_STRING);
-}
-
-void
-UtilsAdapter::setText(QString text)
-{
-    clipboard_->setText(text, QClipboard::Clipboard);
-}
-
-const QString
-UtilsAdapter::qStringFromFile(const QString& filename)
-{
-    return Utils::QByteArrayFromFile(filename);
-}
-
-const QString
-UtilsAdapter::getStyleSheet(const QString& name, const QString& source)
-{
-    auto simplifiedCSS = source.simplified().replace("'", "\"");
-    QString s = QString::fromLatin1("(function() {"
-                                    "    var node = document.createElement('style');"
-                                    "    node.id = '%1';"
-                                    "    node.innerHTML = '%2';"
-                                    "    document.head.appendChild(node);"
-                                    "})()")
-                    .arg(name)
-                    .arg(simplifiedCSS);
-    return s;
-}
-
-const QString
-UtilsAdapter::getCachePath()
-{
-    QDir dataDir(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
-    dataDir.cdUp();
-    return dataDir.absolutePath() + "/jami";
-}
-bool
-UtilsAdapter::createStartupLink()
-{
-    return Utils::CreateStartupLink(L"Jami");
-}
-
-QString
-UtilsAdapter::GetRingtonePath()
-{
-    return Utils::GetRingtonePath();
-}
-
-bool
-UtilsAdapter::checkStartupLink()
-{
-    return Utils::CheckStartupLink(L"Jami");
-}
-
-const QString
-UtilsAdapter::getBestName(const QString& accountId, const QString& uid)
-{
-    const auto& conv = LRCInstance::getConversationFromConvUid(uid);
-    if (!conv.participants.isEmpty())
-        return LRCInstance::getAccountInfo(accountId).contactModel->bestNameForContact(
-            conv.participants[0]);
-    return QString();
-}
-
-const QString
-UtilsAdapter::getPeerUri(const QString& accountId, const QString& uid)
-{
-    auto* convModel = LRCInstance::getAccountInfo(accountId).conversationModel.get();
-    const auto& convInfo = convModel->getConversationForUid(uid).value();
-    return convInfo.get().participants.front();
-}
-
-QString
-UtilsAdapter::getBestId(const QString& accountId)
-{
-    if (accountId.isEmpty())
-        return {};
-    return LRCInstance::accountModel().bestIdForAccount(accountId);
-}
-
-const QString
-UtilsAdapter::getBestId(const QString& accountId, const QString& uid)
-{
-    const auto& conv = LRCInstance::getConversationFromConvUid(uid);
-    if (!conv.participants.isEmpty())
-        return LRCInstance::getAccountInfo(accountId).contactModel->bestIdForContact(
-            conv.participants[0]);
-    return QString();
-}
-
-int
-UtilsAdapter::getTotalUnreadMessages()
-{
-    int totalUnreadMessages {0};
-    if (LRCInstance::getCurrentAccountInfo().profileInfo.type != lrc::api::profile::Type::SIP) {
-        auto* convModel = LRCInstance::getCurrentConversationModel();
-        auto ringConversations = convModel->getFilteredConversations(lrc::api::profile::Type::RING,
-                                                                     false);
-        ringConversations.for_each(
-            [&totalUnreadMessages](const lrc::api::conversation::Info& conversation) {
-                totalUnreadMessages += conversation.unreadMessages;
-            });
-    }
-    return totalUnreadMessages;
-}
-
-int
-UtilsAdapter::getTotalPendingRequest()
-{
-    auto& accountInfo = LRCInstance::getCurrentAccountInfo();
-    return accountInfo.contactModel->pendingRequestCount();
-}
-
-void
-UtilsAdapter::setConversationFilter(const QString& filter)
-{
-    LRCInstance::getCurrentConversationModel()->setFilter(filter);
-}
-
-const QString
-UtilsAdapter::getCurrConvId()
-{
-    return LRCInstance::getCurrentConvUid();
-}
-
-void
-UtilsAdapter::makePermanentCurrentConv()
-{
-    LRCInstance::getCurrentConversationModel()->makePermanent(LRCInstance::getCurrentConvUid());
-}
-
-const QStringList
-UtilsAdapter::getCurrAccList()
-{
-    return LRCInstance::accountModel().getAccountList();
-}
-
-int
-UtilsAdapter::getAccountListSize()
-{
-    return getCurrAccList().size();
-}
-
-void
-UtilsAdapter::setCurrentCall(const QString& accountId, const QString& convUid)
-{
-    auto& accInfo = LRCInstance::getAccountInfo(accountId);
-    auto const& convInfo = LRCInstance::getConversationFromConvUid(convUid, accountId);
-    accInfo.callModel->setCurrentCall(convInfo.callId);
-}
-
-bool
-UtilsAdapter::hasCall(const QString& accountId)
-{
-    auto activeCalls = LRCInstance::getActiveCalls();
-    for (const auto& callId : activeCalls) {
-        auto& accountInfo = LRCInstance::accountModel().getAccountInfo(accountId);
-        if (accountInfo.callModel->hasCall(callId)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-const QString
-UtilsAdapter::getCallConvForAccount(const QString& accountId)
-{
-    // TODO: Currently returning first call, establish priority according to state?
-    for (const auto& callId : LRCInstance::getActiveCalls()) {
-        auto& accountInfo = LRCInstance::accountModel().getAccountInfo(accountId);
-        if (accountInfo.callModel->hasCall(callId)) {
-            return LRCInstance::getConversationFromCallId(callId, accountId).uid;
-        }
-    }
-    return "";
-}
-
-const QString
-UtilsAdapter::getCallId(const QString& accountId, const QString& convUid)
-{
-    auto const& convInfo = LRCInstance::getConversationFromConvUid(convUid, accountId);
-    if (convInfo.uid.isEmpty()) {
-        return {};
-    }
-
-    if (auto* call = LRCInstance::getCallInfoForConversation(convInfo, false)) {
-        return call->id;
-    }
-
-    return {};
-}
-
-int
-UtilsAdapter::getCallStatus(const QString& callId)
-{
-    const auto callStatus = LRCInstance::getCallInfo(callId, LRCInstance::getCurrAccId());
-    return static_cast<int>(callStatus->status);
-}
-
-const QString
-UtilsAdapter::getCallStatusStr(int statusInt)
-{
-    const auto status = static_cast<lrc::api::call::Status>(statusInt);
-    return lrc::api::call::to_string(status);
-}
-
-// returns true if name is valid registered name
-bool
-UtilsAdapter::validateRegNameForm(const QString& regName)
-{
-    QRegularExpression regExp(" ");
-
-    if (regName.size() > 2 && !regName.contains(regExp)) {
-        return true;
-
-    } else {
-        return false;
-    }
-}
-
-QString
-UtilsAdapter::getStringUTF8(QString string)
-{
-    return string.toUtf8();
-}
-
-QString
-UtilsAdapter::getRecordQualityString(int value)
-{
-    return value ? QString::number(static_cast<float>(value) / 100, 'f', 1) + " Mbps" : "Default";
-}
-
-QString
-UtilsAdapter::getCurrentPath()
-{
-    return QDir::currentPath();
-}
-
-QString
-UtilsAdapter::stringSimplifier(QString input)
-{
-    return input.simplified();
-}
-
-QString
-UtilsAdapter::toNativeSeparators(QString inputDir)
-{
-    return QDir::toNativeSeparators(inputDir);
-}
-
-QString
-UtilsAdapter::toFileInfoName(QString inputFileName)
-{
-    QFileInfo fi(inputFileName);
-    return fi.fileName();
-}
-
-QString
-UtilsAdapter::toFileAbsolutepath(QString inputFileName)
-{
-    QFileInfo fi(inputFileName);
-    return fi.absolutePath();
-}
-
-QString
-UtilsAdapter::getAbsPath(QString path)
-{
-    // Note: this function is used on urls returned from qml-FileDialogs which
-    // contain 'file:///' for reasons we don't understand.
-    // TODO: this logic can be refactored into the JamiFileDialog component.
-#ifdef Q_OS_WIN
-    return path.replace(QRegExp("^file:\\/{2,3}"), "").replace("\n", "").replace("\r", "");
-#else
-    return path.replace(QRegExp("^file:\\/{2,3}"), "/").replace("\n", "").replace("\r", "");
-#endif
-}
-
-bool
-UtilsAdapter::checkShowPluginsButton(bool isCall)
-{
-    if (isCall)
-        return LRCInstance::pluginModel().getPluginsEnabled()
-               && (LRCInstance::pluginModel().getCallMediaHandlers().size() > 0);
-    else
-        return LRCInstance::pluginModel().getPluginsEnabled()
-               && (LRCInstance::pluginModel().getChatHandlers().size() > 0);
-}
-
-QString
-UtilsAdapter::fileName(const QString& path)
-{
-    QFileInfo fi(path);
-    return fi.fileName();
-}
-
-QString
-UtilsAdapter::getExt(const QString& path)
-{
-    QFileInfo fi(path);
-    return fi.completeSuffix();
-}
-
-bool
-UtilsAdapter::isImage(const QString& fileExt)
-{
-    return Utils::isImage(fileExt);
-}
-
-QString
-UtilsAdapter::humanFileSize(qint64 fileSize)
-{
-    return Utils::humanFileSize(fileSize);
-}
-
-void
-UtilsAdapter::setSystemTrayIconVisible(bool visible)
-{
-    GlobalSystemTray::instance().setVisible(visible);
-}
+/*!
+ * Copyright (C) 2015-2020 by Savoir-faire Linux
+ * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
+ * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
+ * Author: Isa Nanic <isa.nanic@savoirfairelinux.com>
+ * Author: Mingrui Zhang   <mingrui.zhang@savoirfairelinux.com>
+ * Author: Aline Gondim Santos   <aline.gondimsantos@savoirfairelinux.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/>.
+ */
+
+#include "utilsadapter.h"
+
+#include "globalsystemtray.h"
+#include "lrcinstance.h"
+#include "utils.h"
+#include "version.h"
+
+#include <QApplication>
+#include <QClipboard>
+#include <QFileInfo>
+
+UtilsAdapter::UtilsAdapter(QObject* parent, LRCInstance* instance)
+    : QmlAdapterBase(parent, instance)
+    , clipboard_(QApplication::clipboard())
+{}
+
+const QString
+UtilsAdapter::getProjectCredits()
+{
+    return Utils::getProjectCredits();
+}
+
+const QString
+UtilsAdapter::getVersionStr()
+{
+    return QString(VERSION_STRING);
+}
+
+void
+UtilsAdapter::setText(QString text)
+{
+    clipboard_->setText(text, QClipboard::Clipboard);
+}
+
+const QString
+UtilsAdapter::qStringFromFile(const QString& filename)
+{
+    return Utils::QByteArrayFromFile(filename);
+}
+
+const QString
+UtilsAdapter::getStyleSheet(const QString& name, const QString& source)
+{
+    auto simplifiedCSS = source.simplified().replace("'", "\"");
+    QString s = QString::fromLatin1("(function() {"
+                                    "    var node = document.createElement('style');"
+                                    "    node.id = '%1';"
+                                    "    node.innerHTML = '%2';"
+                                    "    document.head.appendChild(node);"
+                                    "})()")
+                    .arg(name)
+                    .arg(simplifiedCSS);
+    return s;
+}
+
+const QString
+UtilsAdapter::getCachePath()
+{
+    QDir dataDir(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
+    dataDir.cdUp();
+    return dataDir.absolutePath() + "/jami";
+}
+bool
+UtilsAdapter::createStartupLink()
+{
+    return Utils::CreateStartupLink(L"Jami");
+}
+
+QString
+UtilsAdapter::GetRingtonePath()
+{
+    return Utils::GetRingtonePath();
+}
+
+bool
+UtilsAdapter::checkStartupLink()
+{
+    return Utils::CheckStartupLink(L"Jami");
+}
+
+const QString
+UtilsAdapter::getBestName(const QString& accountId, const QString& uid)
+{
+    const auto& conv = lrcInstance_->getConversationFromConvUid(uid);
+    if (!conv.participants.isEmpty())
+        return lrcInstance_->getAccountInfo(accountId).contactModel->bestNameForContact(
+            conv.participants[0]);
+    return QString();
+}
+
+const QString
+UtilsAdapter::getPeerUri(const QString& accountId, const QString& uid)
+{
+    auto* convModel = lrcInstance_->getAccountInfo(accountId).conversationModel.get();
+    const auto& convInfo = convModel->getConversationForUid(uid).value();
+    return convInfo.get().participants.front();
+}
+
+QString
+UtilsAdapter::getBestId(const QString& accountId)
+{
+    if (accountId.isEmpty())
+        return {};
+    return lrcInstance_->accountModel().bestIdForAccount(accountId);
+}
+
+const QString
+UtilsAdapter::getBestId(const QString& accountId, const QString& uid)
+{
+    const auto& conv = lrcInstance_->getConversationFromConvUid(uid);
+    if (!conv.participants.isEmpty())
+        return lrcInstance_->getAccountInfo(accountId).contactModel->bestIdForContact(
+            conv.participants[0]);
+    return QString();
+}
+
+int
+UtilsAdapter::getTotalUnreadMessages()
+{
+    int totalUnreadMessages {0};
+    if (lrcInstance_->getCurrentAccountInfo().profileInfo.type != lrc::api::profile::Type::SIP) {
+        auto* convModel = lrcInstance_->getCurrentConversationModel();
+        auto ringConversations = convModel->getFilteredConversations(lrc::api::profile::Type::RING,
+                                                                     false);
+        ringConversations.for_each(
+            [&totalUnreadMessages](const lrc::api::conversation::Info& conversation) {
+                totalUnreadMessages += conversation.unreadMessages;
+            });
+    }
+    return totalUnreadMessages;
+}
+
+int
+UtilsAdapter::getTotalPendingRequest()
+{
+    auto& accountInfo = lrcInstance_->getCurrentAccountInfo();
+    return accountInfo.contactModel->pendingRequestCount();
+}
+
+void
+UtilsAdapter::setConversationFilter(const QString& filter)
+{
+    lrcInstance_->getCurrentConversationModel()->setFilter(filter);
+}
+
+const QString
+UtilsAdapter::getCurrConvId()
+{
+    return lrcInstance_->getCurrentConvUid();
+}
+
+void
+UtilsAdapter::makePermanentCurrentConv()
+{
+    lrcInstance_->getCurrentConversationModel()->makePermanent(lrcInstance_->getCurrentConvUid());
+}
+
+const QStringList
+UtilsAdapter::getCurrAccList()
+{
+    return lrcInstance_->accountModel().getAccountList();
+}
+
+int
+UtilsAdapter::getAccountListSize()
+{
+    return getCurrAccList().size();
+}
+
+void
+UtilsAdapter::setCurrentCall(const QString& accountId, const QString& convUid)
+{
+    auto& accInfo = lrcInstance_->getAccountInfo(accountId);
+    auto const& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
+    accInfo.callModel->setCurrentCall(convInfo.callId);
+}
+
+bool
+UtilsAdapter::hasCall(const QString& accountId)
+{
+    auto activeCalls = lrcInstance_->getActiveCalls();
+    for (const auto& callId : activeCalls) {
+        auto& accountInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
+        if (accountInfo.callModel->hasCall(callId)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+const QString
+UtilsAdapter::getCallConvForAccount(const QString& accountId)
+{
+    // TODO: Currently returning first call, establish priority according to state?
+    for (const auto& callId : lrcInstance_->getActiveCalls()) {
+        auto& accountInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
+        if (accountInfo.callModel->hasCall(callId)) {
+            return lrcInstance_->getConversationFromCallId(callId, accountId).uid;
+        }
+    }
+    return "";
+}
+
+const QString
+UtilsAdapter::getCallId(const QString& accountId, const QString& convUid)
+{
+    auto const& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
+    if (convInfo.uid.isEmpty()) {
+        return {};
+    }
+
+    if (auto* call = lrcInstance_->getCallInfoForConversation(convInfo, false)) {
+        return call->id;
+    }
+
+    return {};
+}
+
+int
+UtilsAdapter::getCallStatus(const QString& callId)
+{
+    const auto callStatus = lrcInstance_->getCallInfo(callId, lrcInstance_->getCurrAccId());
+    return static_cast<int>(callStatus->status);
+}
+
+const QString
+UtilsAdapter::getCallStatusStr(int statusInt)
+{
+    const auto status = static_cast<lrc::api::call::Status>(statusInt);
+    return lrc::api::call::to_string(status);
+}
+
+// returns true if name is valid registered name
+bool
+UtilsAdapter::validateRegNameForm(const QString& regName)
+{
+    QRegularExpression regExp(" ");
+
+    if (regName.size() > 2 && !regName.contains(regExp)) {
+        return true;
+
+    } else {
+        return false;
+    }
+}
+
+QString
+UtilsAdapter::getStringUTF8(QString string)
+{
+    return string.toUtf8();
+}
+
+QString
+UtilsAdapter::getRecordQualityString(int value)
+{
+    return value ? QString::number(static_cast<float>(value) / 100, 'f', 1) + " Mbps" : "Default";
+}
+
+QString
+UtilsAdapter::getCurrentPath()
+{
+    return QDir::currentPath();
+}
+
+QString
+UtilsAdapter::stringSimplifier(QString input)
+{
+    return input.simplified();
+}
+
+QString
+UtilsAdapter::toNativeSeparators(QString inputDir)
+{
+    return QDir::toNativeSeparators(inputDir);
+}
+
+QString
+UtilsAdapter::toFileInfoName(QString inputFileName)
+{
+    QFileInfo fi(inputFileName);
+    return fi.fileName();
+}
+
+QString
+UtilsAdapter::toFileAbsolutepath(QString inputFileName)
+{
+    QFileInfo fi(inputFileName);
+    return fi.absolutePath();
+}
+
+QString
+UtilsAdapter::getAbsPath(QString path)
+{
+    // Note: this function is used on urls returned from qml-FileDialogs which
+    // contain 'file:///' for reasons we don't understand.
+    // TODO: this logic can be refactored into the JamiFileDialog component.
+#ifdef Q_OS_WIN
+    return path.replace(QRegExp("^file:\\/{2,3}"), "").replace("\n", "").replace("\r", "");
+#else
+    return path.replace(QRegExp("^file:\\/{2,3}"), "/").replace("\n", "").replace("\r", "");
+#endif
+}
+
+bool
+UtilsAdapter::checkShowPluginsButton(bool isCall)
+{
+    if (isCall)
+        return lrcInstance_->pluginModel().getPluginsEnabled()
+               && (lrcInstance_->pluginModel().getCallMediaHandlers().size() > 0);
+    else
+        return lrcInstance_->pluginModel().getPluginsEnabled()
+               && (lrcInstance_->pluginModel().getChatHandlers().size() > 0);
+}
+
+QString
+UtilsAdapter::fileName(const QString& path)
+{
+    QFileInfo fi(path);
+    return fi.fileName();
+}
+
+QString
+UtilsAdapter::getExt(const QString& path)
+{
+    QFileInfo fi(path);
+    return fi.completeSuffix();
+}
+
+bool
+UtilsAdapter::isImage(const QString& fileExt)
+{
+    return Utils::isImage(fileExt);
+}
+
+QString
+UtilsAdapter::humanFileSize(qint64 fileSize)
+{
+    return Utils::humanFileSize(fileSize);
+}
+
+void
+UtilsAdapter::setSystemTrayIconVisible(bool visible)
+{
+    GlobalSystemTray::instance().setVisible(visible);
+}
diff --git a/src/utilsadapter.h b/src/utilsadapter.h
index 88b773393..8d4fe6add 100644
--- a/src/utilsadapter.h
+++ b/src/utilsadapter.h
@@ -1,82 +1,86 @@
-/*
- * Copyright (C) 2015-2020 by Savoir-faire Linux
- * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
- * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
- * Author: Isa Nanic <isa.nanic@savoirfairelinux.com>
- * Author: Mingrui Zhang   <mingrui.zhang@savoirfairelinux.com>
- * Author: Aline Gondim Santos   <aline.gondimsantos@savoirfairelinux.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/>.
- */
-
-#pragma once
-
-#include <QApplication>
-#include <QObject>
-
-class QClipboard;
-
-class UtilsAdapter final : public QObject
-{
-    Q_OBJECT
-public:
-    explicit UtilsAdapter(QObject* parent = nullptr);
-    ~UtilsAdapter() = default;
-
-    Q_INVOKABLE const QString getProjectCredits();
-    Q_INVOKABLE const QString getVersionStr();
-    Q_INVOKABLE void setText(QString text);
-    Q_INVOKABLE const QString qStringFromFile(const QString& filename);
-    Q_INVOKABLE const QString getStyleSheet(const QString& name, const QString& source);
-    Q_INVOKABLE const QString getCachePath();
-    Q_INVOKABLE bool createStartupLink();
-    Q_INVOKABLE QString GetRingtonePath();
-    Q_INVOKABLE bool checkStartupLink();
-    Q_INVOKABLE void setConversationFilter(const QString& filter);
-    Q_INVOKABLE int getTotalUnreadMessages();
-    Q_INVOKABLE int getTotalPendingRequest();
-    Q_INVOKABLE const QString getBestName(const QString& accountId, const QString& uid);
-    Q_INVOKABLE const QString getPeerUri(const QString& accountId, const QString& uid);
-    Q_INVOKABLE QString getBestId(const QString& accountId);
-    Q_INVOKABLE const QString getBestId(const QString& accountId, const QString& uid);
-    Q_INVOKABLE const QString getCurrConvId();
-    Q_INVOKABLE void makePermanentCurrentConv();
-    Q_INVOKABLE const QStringList getCurrAccList();
-    Q_INVOKABLE int getAccountListSize();
-    Q_INVOKABLE void setCurrentCall(const QString& accountId, const QString& convUid);
-    Q_INVOKABLE bool hasCall(const QString& accountId);
-    Q_INVOKABLE const QString getCallConvForAccount(const QString& accountId);
-    Q_INVOKABLE const QString getCallId(const QString& accountId, const QString& convUid);
-    Q_INVOKABLE int getCallStatus(const QString& callId);
-    Q_INVOKABLE const QString getCallStatusStr(int statusInt);
-    Q_INVOKABLE QString getStringUTF8(QString string);
-    Q_INVOKABLE bool validateRegNameForm(const QString& regName);
-    Q_INVOKABLE QString getRecordQualityString(int value);
-    Q_INVOKABLE QString getCurrentPath();
-    Q_INVOKABLE QString stringSimplifier(QString input);
-    Q_INVOKABLE QString toNativeSeparators(QString inputDir);
-    Q_INVOKABLE QString toFileInfoName(QString inputFileName);
-    Q_INVOKABLE QString toFileAbsolutepath(QString inputFileName);
-    Q_INVOKABLE QString getAbsPath(QString path);
-    Q_INVOKABLE bool checkShowPluginsButton(bool isCall);
-    Q_INVOKABLE QString fileName(const QString& path);
-    Q_INVOKABLE QString getExt(const QString& path);
-    Q_INVOKABLE bool isImage(const QString& fileExt);
-    Q_INVOKABLE QString humanFileSize(qint64 fileSize);
-    Q_INVOKABLE void setSystemTrayIconVisible(bool visible);
-
-private:
-    QClipboard* clipboard_;
-};
-Q_DECLARE_METATYPE(UtilsAdapter*)
+/*
+ * Copyright (C) 2015-2020 by Savoir-faire Linux
+ * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
+ * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
+ * Author: Isa Nanic <isa.nanic@savoirfairelinux.com>
+ * Author: Mingrui Zhang   <mingrui.zhang@savoirfairelinux.com>
+ * Author: Aline Gondim Santos   <aline.gondimsantos@savoirfairelinux.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/>.
+ */
+
+#pragma once
+
+#include <QApplication>
+#include <QObject>
+
+#include "qmladapterbase.h"
+
+class QClipboard;
+
+class UtilsAdapter final : public QmlAdapterBase
+{
+    Q_OBJECT
+public:
+    explicit UtilsAdapter(QObject* parent = nullptr, LRCInstance* instance = nullptr);
+    ~UtilsAdapter() = default;
+
+    void safeInit() override {}
+
+    Q_INVOKABLE const QString getProjectCredits();
+    Q_INVOKABLE const QString getVersionStr();
+    Q_INVOKABLE void setText(QString text);
+    Q_INVOKABLE const QString qStringFromFile(const QString& filename);
+    Q_INVOKABLE const QString getStyleSheet(const QString& name, const QString& source);
+    Q_INVOKABLE const QString getCachePath();
+    Q_INVOKABLE bool createStartupLink();
+    Q_INVOKABLE QString GetRingtonePath();
+    Q_INVOKABLE bool checkStartupLink();
+    Q_INVOKABLE void setConversationFilter(const QString& filter);
+    Q_INVOKABLE int getTotalUnreadMessages();
+    Q_INVOKABLE int getTotalPendingRequest();
+    Q_INVOKABLE const QString getBestName(const QString& accountId, const QString& uid);
+    Q_INVOKABLE const QString getPeerUri(const QString& accountId, const QString& uid);
+    Q_INVOKABLE QString getBestId(const QString& accountId);
+    Q_INVOKABLE const QString getBestId(const QString& accountId, const QString& uid);
+    Q_INVOKABLE const QString getCurrConvId();
+    Q_INVOKABLE void makePermanentCurrentConv();
+    Q_INVOKABLE const QStringList getCurrAccList();
+    Q_INVOKABLE int getAccountListSize();
+    Q_INVOKABLE void setCurrentCall(const QString& accountId, const QString& convUid);
+    Q_INVOKABLE bool hasCall(const QString& accountId);
+    Q_INVOKABLE const QString getCallConvForAccount(const QString& accountId);
+    Q_INVOKABLE const QString getCallId(const QString& accountId, const QString& convUid);
+    Q_INVOKABLE int getCallStatus(const QString& callId);
+    Q_INVOKABLE const QString getCallStatusStr(int statusInt);
+    Q_INVOKABLE QString getStringUTF8(QString string);
+    Q_INVOKABLE bool validateRegNameForm(const QString& regName);
+    Q_INVOKABLE QString getRecordQualityString(int value);
+    Q_INVOKABLE QString getCurrentPath();
+    Q_INVOKABLE QString stringSimplifier(QString input);
+    Q_INVOKABLE QString toNativeSeparators(QString inputDir);
+    Q_INVOKABLE QString toFileInfoName(QString inputFileName);
+    Q_INVOKABLE QString toFileAbsolutepath(QString inputFileName);
+    Q_INVOKABLE QString getAbsPath(QString path);
+    Q_INVOKABLE bool checkShowPluginsButton(bool isCall);
+    Q_INVOKABLE QString fileName(const QString& path);
+    Q_INVOKABLE QString getExt(const QString& path);
+    Q_INVOKABLE bool isImage(const QString& fileExt);
+    Q_INVOKABLE QString humanFileSize(qint64 fileSize);
+    Q_INVOKABLE void setSystemTrayIconVisible(bool visible);
+
+private:
+    QClipboard* clipboard_;
+};
+Q_DECLARE_METATYPE(UtilsAdapter*)
diff --git a/src/videoformatfpsmodel.cpp b/src/videoformatfpsmodel.cpp
index 6d1dbac03..6e1307c66 100644
--- a/src/videoformatfpsmodel.cpp
+++ b/src/videoformatfpsmodel.cpp
@@ -18,16 +18,26 @@
 
 #include "videoformatfpsmodel.h"
 
+#include "lrcinstance.h"
+
+#include "api/account.h"
+#include "api/contact.h"
+#include "api/conversation.h"
+#include "api/newdevicemodel.h"
+
 VideoFormatFpsModel::VideoFormatFpsModel(QObject* parent)
-    : QAbstractListModel(parent)
+    : AbstractListModelBase(parent)
 {
-    try {
-        QString currentDeviceId = LRCInstance::avModel().getCurrentVideoCaptureDevice();
-        auto currentSettings = LRCInstance::avModel().getDeviceSettings(currentDeviceId);
-        currentResolution_ = currentSettings.size;
-    } catch (const std::exception& e) {
-        qWarning() << "Constructor of VideoFormatFpsModel, exception: " << e.what();
-    }
+    connect(this, &AbstractListModelBase::lrcInstanceChanged, [this] {
+        if (lrcInstance_)
+            try {
+                QString currentDeviceId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
+                auto currentSettings = lrcInstance_->avModel().getDeviceSettings(currentDeviceId);
+                currentResolution_ = currentSettings.size;
+            } catch (const std::exception& e) {
+                qWarning() << "Constructor of VideoFormatFpsModel, exception: " << e.what();
+            }
+    });
 }
 
 VideoFormatFpsModel::~VideoFormatFpsModel() {}
@@ -35,17 +45,17 @@ VideoFormatFpsModel::~VideoFormatFpsModel() {}
 int
 VideoFormatFpsModel::rowCount(const QModelIndex& parent) const
 {
-    if (!parent.isValid()) {
+    if (!parent.isValid() && lrcInstance_) {
         /*
          * Count.
          */
-        QString currentDeviceId = LRCInstance::avModel().getCurrentVideoCaptureDevice();
-        auto deviceCapabilities = LRCInstance::avModel().getDeviceCapabilities(currentDeviceId);
+        QString currentDeviceId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
+        auto deviceCapabilities = lrcInstance_->avModel().getDeviceCapabilities(currentDeviceId);
         if (deviceCapabilities.size() == 0) {
             return 0;
         }
         try {
-            auto currentSettings = LRCInstance::avModel().getDeviceSettings(currentDeviceId);
+            auto currentSettings = lrcInstance_->avModel().getDeviceSettings(currentDeviceId);
             auto currentChannel = currentSettings.channel;
             currentChannel = currentChannel.isEmpty() ? "default" : currentChannel;
             auto channelCaps = deviceCapabilities[currentChannel];
@@ -90,10 +100,10 @@ QVariant
 VideoFormatFpsModel::data(const QModelIndex& index, int role) const
 {
     try {
-        QString currentDeviceId = LRCInstance::avModel().getCurrentVideoCaptureDevice();
-        auto deviceCapabilities = LRCInstance::avModel().getDeviceCapabilities(currentDeviceId);
+        QString currentDeviceId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
+        auto deviceCapabilities = lrcInstance_->avModel().getDeviceCapabilities(currentDeviceId);
 
-        auto currentSettings = LRCInstance::avModel().getDeviceSettings(currentDeviceId);
+        auto currentSettings = lrcInstance_->avModel().getDeviceSettings(currentDeviceId);
         auto currentChannel = currentSettings.channel;
         currentChannel = currentChannel.isEmpty() ? "default" : currentChannel;
         auto channelCaps = deviceCapabilities[currentChannel];
@@ -183,8 +193,8 @@ VideoFormatFpsModel::getCurrentSettingIndex()
 {
     int resultRowIndex = 0;
     try {
-        QString currentDeviceId = LRCInstance::avModel().getCurrentVideoCaptureDevice();
-        auto currentSettings = LRCInstance::avModel().getDeviceSettings(currentDeviceId);
+        QString currentDeviceId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
+        auto currentSettings = lrcInstance_->avModel().getDeviceSettings(currentDeviceId);
         float currentFps = currentSettings.rate;
         auto resultList = match(index(0, 0), FPS, QVariant(currentFps));
 
diff --git a/src/videoformatfpsmodel.h b/src/videoformatfpsmodel.h
index 9b5c18f11..28206448e 100644
--- a/src/videoformatfpsmodel.h
+++ b/src/videoformatfpsmodel.h
@@ -18,16 +18,9 @@
 
 #pragma once
 
-#include <QAbstractItemModel>
+#include "abstractitemmodelbase.h"
 
-#include "api/account.h"
-#include "api/contact.h"
-#include "api/conversation.h"
-#include "api/newdevicemodel.h"
-
-#include "lrcinstance.h"
-
-class VideoFormatFpsModel : public QAbstractListModel
+class VideoFormatFpsModel : public AbstractListModelBase
 {
     Q_OBJECT
     Q_PROPERTY(QString currentResolution READ getCurrentResolution WRITE setCurrentResolution NOTIFY
@@ -37,7 +30,7 @@ public:
     enum Role { FPS = Qt::UserRole + 1, FPS_ToDisplay_UTF8 };
     Q_ENUM(Role)
 
-    explicit VideoFormatFpsModel(QObject* parent = 0);
+    explicit VideoFormatFpsModel(QObject* parent = nullptr);
     ~VideoFormatFpsModel();
 
     /*
diff --git a/src/videoformatresolutionmodel.cpp b/src/videoformatresolutionmodel.cpp
index ebf07656c..59a864d49 100644
--- a/src/videoformatresolutionmodel.cpp
+++ b/src/videoformatresolutionmodel.cpp
@@ -18,8 +18,15 @@
 
 #include "videoformatresolutionmodel.h"
 
+#include "lrcinstance.h"
+
+#include "api/account.h"
+#include "api/contact.h"
+#include "api/conversation.h"
+#include "api/newdevicemodel.h"
+
 VideoFormatResolutionModel::VideoFormatResolutionModel(QObject* parent)
-    : QAbstractListModel(parent)
+    : AbstractListModelBase(parent)
 {}
 
 VideoFormatResolutionModel::~VideoFormatResolutionModel() {}
@@ -27,17 +34,17 @@ VideoFormatResolutionModel::~VideoFormatResolutionModel() {}
 int
 VideoFormatResolutionModel::rowCount(const QModelIndex& parent) const
 {
-    if (!parent.isValid()) {
+    if (!parent.isValid() && lrcInstance_) {
         /*
          * Count.
          */
-        QString currentDeviceId = LRCInstance::avModel().getCurrentVideoCaptureDevice();
-        auto deviceCapabilities = LRCInstance::avModel().getDeviceCapabilities(currentDeviceId);
+        QString currentDeviceId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
+        auto deviceCapabilities = lrcInstance_->avModel().getDeviceCapabilities(currentDeviceId);
         if (deviceCapabilities.size() == 0) {
             return 0;
         }
         try {
-            auto currentSettings = LRCInstance::avModel().getDeviceSettings(currentDeviceId);
+            auto currentSettings = lrcInstance_->avModel().getDeviceSettings(currentDeviceId);
             auto currentChannel = currentSettings.channel;
             currentChannel = currentChannel.isEmpty() ? "default" : currentChannel;
             auto channelCaps = deviceCapabilities[currentChannel];
@@ -68,10 +75,10 @@ QVariant
 VideoFormatResolutionModel::data(const QModelIndex& index, int role) const
 {
     try {
-        QString currentDeviceId = LRCInstance::avModel().getCurrentVideoCaptureDevice();
-        auto deviceCapabilities = LRCInstance::avModel().getDeviceCapabilities(currentDeviceId);
+        QString currentDeviceId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
+        auto deviceCapabilities = lrcInstance_->avModel().getDeviceCapabilities(currentDeviceId);
 
-        auto currentSettings = LRCInstance::avModel().getDeviceSettings(currentDeviceId);
+        auto currentSettings = lrcInstance_->avModel().getDeviceSettings(currentDeviceId);
         auto currentChannel = currentSettings.channel;
         currentChannel = currentChannel.isEmpty() ? "default" : currentChannel;
         auto channelCaps = deviceCapabilities[currentChannel];
@@ -147,8 +154,8 @@ VideoFormatResolutionModel::getCurrentSettingIndex()
 {
     int resultRowIndex = 0;
     try {
-        QString currentDeviceId = LRCInstance::avModel().getCurrentVideoCaptureDevice();
-        auto currentSettings = LRCInstance::avModel().getDeviceSettings(currentDeviceId);
+        QString currentDeviceId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
+        auto currentSettings = lrcInstance_->avModel().getDeviceSettings(currentDeviceId);
         QString currentResolution = currentSettings.size;
         auto resultList = match(index(0, 0), Resolution, QVariant(currentResolution));
 
diff --git a/src/videoformatresolutionmodel.h b/src/videoformatresolutionmodel.h
index c79a83113..5e4af0b0a 100644
--- a/src/videoformatresolutionmodel.h
+++ b/src/videoformatresolutionmodel.h
@@ -18,23 +18,16 @@
 
 #pragma once
 
-#include <QAbstractItemModel>
+#include "abstractitemmodelbase.h"
 
-#include "api/account.h"
-#include "api/contact.h"
-#include "api/conversation.h"
-#include "api/newdevicemodel.h"
-
-#include "lrcinstance.h"
-
-class VideoFormatResolutionModel : public QAbstractListModel
+class VideoFormatResolutionModel : public AbstractListModelBase
 {
     Q_OBJECT
 public:
     enum Role { Resolution = Qt::UserRole + 1, Resolution_UTF8 };
     Q_ENUM(Role)
 
-    explicit VideoFormatResolutionModel(QObject* parent = 0);
+    explicit VideoFormatResolutionModel(QObject* parent = nullptr);
     ~VideoFormatResolutionModel();
 
     /*
diff --git a/src/videoinputdevicemodel.cpp b/src/videoinputdevicemodel.cpp
index f817f8d56..b92c19b52 100644
--- a/src/videoinputdevicemodel.cpp
+++ b/src/videoinputdevicemodel.cpp
@@ -18,8 +18,15 @@
 
 #include "videoinputdevicemodel.h"
 
+#include "lrcinstance.h"
+
+#include "api/account.h"
+#include "api/contact.h"
+#include "api/conversation.h"
+#include "api/newdevicemodel.h"
+
 VideoInputDeviceModel::VideoInputDeviceModel(QObject* parent)
-    : QAbstractListModel(parent)
+    : AbstractListModelBase(parent)
 {}
 
 VideoInputDeviceModel::~VideoInputDeviceModel() {}
@@ -27,11 +34,11 @@ VideoInputDeviceModel::~VideoInputDeviceModel() {}
 int
 VideoInputDeviceModel::rowCount(const QModelIndex& parent) const
 {
-    if (!parent.isValid()) {
+    if (!parent.isValid() && lrcInstance_) {
         /*
          * Count.
          */
-        int deviceListSize = LRCInstance::avModel().getDevices().size();
+        int deviceListSize = lrcInstance_->avModel().getDevices().size();
         if (deviceListSize > 0) {
             return deviceListSize;
         } else {
@@ -57,7 +64,7 @@ VideoInputDeviceModel::columnCount(const QModelIndex& parent) const
 QVariant
 VideoInputDeviceModel::data(const QModelIndex& index, int role) const
 {
-    auto deviceList = LRCInstance::avModel().getDevices();
+    auto deviceList = lrcInstance_->avModel().getDevices();
     if (!index.isValid()) {
         return QVariant();
     }
@@ -75,7 +82,7 @@ VideoInputDeviceModel::data(const QModelIndex& index, int role) const
         return QVariant();
     }
 
-    auto currentDeviceSetting = LRCInstance::avModel().getDeviceSettings(deviceList[index.row()]);
+    auto currentDeviceSetting = lrcInstance_->avModel().getDeviceSettings(deviceList[index.row()]);
 
     switch (role) {
     case Role::DeviceChannel:
@@ -148,13 +155,13 @@ VideoInputDeviceModel::reset()
 int
 VideoInputDeviceModel::deviceCount()
 {
-    return LRCInstance::avModel().getDevices().size();
+    return lrcInstance_->avModel().getDevices().size();
 }
 
 int
 VideoInputDeviceModel::getCurrentSettingIndex()
 {
-    QString currentId = LRCInstance::avModel().getCurrentVideoCaptureDevice();
+    QString currentId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
     auto resultList = match(index(0, 0), DeviceId, QVariant(currentId));
 
     int resultRowIndex = 0;
diff --git a/src/videoinputdevicemodel.h b/src/videoinputdevicemodel.h
index 99343b5ac..4920d0d91 100644
--- a/src/videoinputdevicemodel.h
+++ b/src/videoinputdevicemodel.h
@@ -18,16 +18,9 @@
 
 #pragma once
 
-#include <QAbstractItemModel>
+#include "abstractitemmodelbase.h"
 
-#include "api/account.h"
-#include "api/contact.h"
-#include "api/conversation.h"
-#include "api/newdevicemodel.h"
-
-#include "lrcinstance.h"
-
-class VideoInputDeviceModel : public QAbstractListModel
+class VideoInputDeviceModel : public AbstractListModelBase
 {
     Q_OBJECT
 public:
@@ -41,7 +34,7 @@ public:
     };
     Q_ENUM(Role)
 
-    explicit VideoInputDeviceModel(QObject* parent = 0);
+    explicit VideoInputDeviceModel(QObject* parent = nullptr);
     ~VideoInputDeviceModel();
 
     /*
-- 
GitLab