diff --git a/jami-qt.pro b/jami-qt.pro
index f7691b924c7c42f8220ed9e70a83d9e02467b72a..3af3746fe9137a86ba1d4deb6f223a0e57b256cb 100644
--- a/jami-qt.pro
+++ b/jami-qt.pro
@@ -153,7 +153,9 @@ HEADERS += ./src/smartlistmodel.h \
         ./src/videoformatfpsmodel.h \
         ./src/videoformatresolutionmodel.h \
         ./src/audiomanagerlistmodel.h \
-        src/qmlregister.h
+        src/qmlregister.h \
+        src/qtutils.h \
+        src/utilsadapter.h
 
 SOURCES += ./src/bannedlistmodel.cpp \
         ./src/accountlistmodel.cpp \
@@ -192,7 +194,8 @@ SOURCES += ./src/bannedlistmodel.cpp \
         ./src/videoformatfpsmodel.cpp \
         ./src/videoformatresolutionmodel.cpp \
         ./src/audiomanagerlistmodel.cpp \
-        src/qmlregister.cpp
+        src/qmlregister.cpp \
+        src/utilsadapter.cpp
 
 RESOURCES += ./resources.qrc \
              ./qml.qrc
diff --git a/src/MainApplicationWindow.qml b/src/MainApplicationWindow.qml
index 321a7900946eb079c3d4d347095ff7a1e42a9ca9..04f83fb72f292a93b504c6379fe7b508bf555ce3 100644
--- a/src/MainApplicationWindow.qml
+++ b/src/MainApplicationWindow.qml
@@ -29,7 +29,7 @@ ApplicationWindow {
         // If we're in the onboarding wizard or 'MinimizeOnClose'
         // is set, then we can quit
         if (!SettingsAdapter.getAppValue(Settings.MinimizeOnClose) ||
-            !ClientWrapper.utilsAdaptor.getAccountListSize()) {
+            !UtilsAdapter.getAccountListSize()) {
             Qt.quit()
         } else {
             // hide to the systray
@@ -53,7 +53,7 @@ ApplicationWindow {
         setX(Screen.width / 2 - width / 2)
         setY(Screen.height / 2 - height / 2)
 
-        if (!ClientWrapper.utilsAdaptor.getAccountListSize()) {
+        if (!UtilsAdapter.getAccountListSize()) {
             wizardView.show()
         } else {
             mainViewLoader.setSource("qrc:/src/mainview/MainView.qml")
diff --git a/src/accountadapter.cpp b/src/accountadapter.cpp
index 723db1e904e4af8c08b5352c39ad21e703c3a9d0..cae123c91f4239a6a76c6cf27fc8606b9e92970a 100644
--- a/src/accountadapter.cpp
+++ b/src/accountadapter.cpp
@@ -23,6 +23,8 @@
 
 #include "accountadapter.h"
 
+#include "qtutils.h"
+
 #undef REGISTERED
 #include "../daemon/src/dring/account_const.h"
 
@@ -58,14 +60,12 @@ AccountAdapter::connectFailure()
                           &lrc::api::NewAccountModel::accountRemoved,
                           [this](const QString &accountId) {
                               Q_UNUSED(accountId);
-
                               emit reportFailure();
                           });
     Utils::oneShotConnect(&LRCInstance::accountModel(),
                           &lrc::api::NewAccountModel::invalidAccountDetected,
                           [this](const QString &accountId) {
                               Q_UNUSED(accountId);
-
                               emit reportFailure();
                           });
 }
@@ -113,7 +113,7 @@ AccountAdapter::createJamiAccount(QString registeredName,
 
     connectFailure();
 
-    QtConcurrent::run([this, settings] {
+    QtConcurrent::run([settings] {
         QMap<QString, QString> additionalAccountConfig;
         additionalAccountConfig.insert(DRing::Account::ConfProperties::Ringtone::PATH,
                                        Utils::GetRingtonePath());
@@ -162,7 +162,7 @@ AccountAdapter::createSIPAccount(const QVariantMap &settings, QString photoBooth
 
     connectFailure();
 
-    QtConcurrent::run([this, settings] {
+    QtConcurrent::run([settings] {
         QMap<QString, QString> additionalAccountConfig;
         additionalAccountConfig.insert(DRing::Account::ConfProperties::Ringtone::PATH,
                                        Utils::GetRingtonePath());
@@ -194,7 +194,7 @@ AccountAdapter::createJAMSAccount(const QVariantMap &settings)
 
     connectFailure();
 
-    QtConcurrent::run([this, settings] {
+    QtConcurrent::run([settings] {
         QMap<QString, QString> additionalAccountConfig;
         additionalAccountConfig.insert(DRing::Account::ConfProperties::Ringtone::PATH,
                                        Utils::GetRingtonePath());
@@ -302,7 +302,7 @@ AccountAdapter::exportToFile(const QString &accountId,
 void
 AccountAdapter::setArchivePasswordAsync(const QString &accountID, const QString &password)
 {
-    QtConcurrent::run([this, accountID, password] {
+    QtConcurrent::run([accountID, password] {
         auto config = LRCInstance::accountModel().getAccountConfig(accountID);
         config.archivePassword = password;
         LRCInstance::accountModel().setAccountConfig(accountID, config);
@@ -404,7 +404,7 @@ AccountAdapter::connectAccount(const QString &accountId)
         addedToConferenceConnection_
             = QObject::connect(accInfo.callModel.get(),
                                &NewCallModel::callAddedToConference,
-                               [this](const QString &callId, const QString &confId) {
+                               [](const QString &callId, const QString &confId) {
                                    Q_UNUSED(callId);
                                    LRCInstance::renderer()->addDistantRenderer(confId);
                                });
diff --git a/src/accountlistmodel.cpp b/src/accountlistmodel.cpp
index 9b3eed41c075e6158e163d677821d513ea6c7c26..4d61e43d9af73dacb64d49c97e1e94aa282285aa 100644
--- a/src/accountlistmodel.cpp
+++ b/src/accountlistmodel.cpp
@@ -75,9 +75,9 @@ AccountListModel::data(const QModelIndex &index, int role) const
         return QVariant(Utils::secondBestNameForAccount(accountInfo));
     case Role::Type:
         return QVariant(
-            Utils::toUnderlyingValue<lrc::api::profile::Type>(accountInfo.profileInfo.type));
+            static_cast<int>(accountInfo.profileInfo.type));
     case Role::Status:
-        return QVariant(Utils::toUnderlyingValue<lrc::api::account::Status>(accountInfo.status));
+        return QVariant(static_cast<int>(accountInfo.status));
     case Role::Picture:
         return QString::fromLatin1(
             Utils::QImageToByteArray(Utils::accountPhoto(accountInfo)).toBase64().data());
diff --git a/src/appsettingsmanager.h b/src/appsettingsmanager.h
index 86766f4581255bd6afe87c744153b1e297a02934..491f5636897d6d7c008bc4157dba3634bc0de261 100644
--- a/src/appsettingsmanager.h
+++ b/src/appsettingsmanager.h
@@ -62,7 +62,7 @@ public:
     static QString toString(Key key)
     {
         return QMetaEnum::fromType<Key>().valueToKey(
-                    Utils::toUnderlyingValue(key));
+                    static_cast<int>(key));
     }
     static QVariant defaultValue(const Key key)
     {
@@ -88,8 +88,7 @@ class AppSettingsManager : public QObject
 public:
     virtual ~AppSettingsManager() = default;
 
-    static AppSettingsManager&
-    instance()
+    static AppSettingsManager &instance()
     {
         static AppSettingsManager *instance_ =
                 new AppSettingsManager(nullptr);
@@ -120,9 +119,9 @@ public:
     initValues()
     {
         for (int i = 0;
-             i < Utils::toUnderlyingValue(Settings::Key::COUNT__);
+             i < static_cast<int>(Settings::Key::COUNT__);
              ++i) {
-            auto key = Utils::toEnum<Settings::Key>(i);
+            auto key = static_cast<Settings::Key>(i);
             if (!instance().settings_->contains(Settings::toString(key)))
                 setValue(key, Settings::defaultValue(key));
         }
diff --git a/src/avadapter.cpp b/src/avadapter.cpp
index 5306fda3f5c1a680089443fd33f016bc60364b45..4f82a86a982dcee923f0f0142604826090524edf 100644
--- a/src/avadapter.cpp
+++ b/src/avadapter.cpp
@@ -22,6 +22,7 @@
 
 #include "lrcinstance.h"
 
+#include <QApplication>
 #include <QScreen>
 
 AvAdapter::AvAdapter(QObject *parent)
diff --git a/src/bannedlistmodel.cpp b/src/bannedlistmodel.cpp
index 79fecd436f6dc42aba93de5f4c4016240448c069..bfc0a19d25259e46f1dc560e9e741e932e85eb53 100644
--- a/src/bannedlistmodel.cpp
+++ b/src/bannedlistmodel.cpp
@@ -62,9 +62,9 @@ BannedListModel::data(const QModelIndex &index, int role) const
     case Role::ContactID:
         return QVariant(contactInfo.profileInfo.uri);
     case Role::ContactPicture:
-        QImage avatarImage = Utils::fallbackAvatar(QSize(48, 48),
-                                                   contactInfo.profileInfo.uri,
-                                                   contactInfo.registeredName);
+        QImage avatarImage = Utils::fallbackAvatar(contactInfo.profileInfo.uri,
+                                                   contactInfo.registeredName,
+                                                   QSize(48, 48));
 
         return QString::fromLatin1(Utils::QImageToByteArray(avatarImage).toBase64().data());
     }
diff --git a/src/calladapter.cpp b/src/calladapter.cpp
index 098efacd1cae3d80fe85ecee01626af568b1a26a..e0a257530de77a6a8beca44208d8d0813a92090c 100644
--- a/src/calladapter.cpp
+++ b/src/calladapter.cpp
@@ -596,7 +596,7 @@ CallAdapter::getCurrentLayoutType() const
         auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
         try {
             auto call = callModel->getCall(convInfo.confId);
-            return Utils::toUnderlyingValue(call.layout);
+            return static_cast<int>(call.layout);
         } catch (...) {
         }
     }
diff --git a/src/clientwrapper.cpp b/src/clientwrapper.cpp
index ec61ffd8d4b36e2af8945d7ae93db597b4eeba79..f72bd1af9e32e307b77ae22384237a0a53f83281 100644
--- a/src/clientwrapper.cpp
+++ b/src/clientwrapper.cpp
@@ -36,12 +36,6 @@ ClientWrapper::getNameDirectory()
     return &(NameDirectory::instance());
 }
 
-UtilsAdapter *
-ClientWrapper::getUtilsAdapter()
-{
-    return &(UtilsAdapter::instance());
-}
-
 SettingsAdapter *
 ClientWrapper::getSettingsAdapter()
 {
diff --git a/src/clientwrapper.h b/src/clientwrapper.h
index f9a078ab6cac0288bf17888c29e7b1b4dd68ace4..514affe7dfa8a7278da2c51be52a1ee6de71e069 100644
--- a/src/clientwrapper.h
+++ b/src/clientwrapper.h
@@ -41,7 +41,6 @@
 #include "previewrenderer.h"
 #include "qrimageprovider.h"
 #include "settingsadapter.h"
-#include "utils.h"
 #include "version.h"
 #include "videocodeclistmodel.h"
 
@@ -51,7 +50,6 @@ class ClientWrapper : public QObject
 {
     Q_OBJECT
 
-    Q_PROPERTY(UtilsAdapter *utilsAdaptor READ getUtilsAdapter NOTIFY utilsAdaptorChanged)
     Q_PROPERTY(SettingsAdapter *SettingsAdapter READ getSettingsAdapter NOTIFY SettingsAdapterChanged)
     Q_PROPERTY(NameDirectory *nameDirectory READ getNameDirectory NOTIFY nameDirectoryChanged)
     Q_PROPERTY(LRCInstance *lrcInstance READ getLRCInstance NOTIFY lrcInstanceChanged)
@@ -67,7 +65,6 @@ public:
     explicit ClientWrapper(QObject *parent = nullptr);
 
     NameDirectory *getNameDirectory();
-    UtilsAdapter *getUtilsAdapter();
     SettingsAdapter *getSettingsAdapter();
     LRCInstance *getLRCInstance();
     AccountAdapter *getAccountAdapter();
@@ -82,7 +79,6 @@ public:
     lrc::api::PluginModel *getPluginModel();
 
 signals:
-    void utilsAdaptorChanged();
     void SettingsAdapterChanged();
     void nameDirectoryChanged();
     void lrcInstanceChanged();
diff --git a/src/commoncomponents/PasswordDialog.qml b/src/commoncomponents/PasswordDialog.qml
index 4d155cfb728bb2be8052d14715c89d376fbffb39..4ef46e05ca0efaab3e63fdda3501fbb9b33b54d0 100644
--- a/src/commoncomponents/PasswordDialog.qml
+++ b/src/commoncomponents/PasswordDialog.qml
@@ -112,8 +112,11 @@ Dialog {
 
     function exportAccountQML() {
         var success = false
-        if(path.length > 0){
-            success = ClientWrapper.accountAdaptor.exportToFile(ClientWrapper.utilsAdaptor.getCurrAccId(),path,currentPasswordEdit.text)
+        if (path.length > 0) {
+            success = ClientWrapper.accountAdaptor.exportToFile(
+                        UtilsAdapter.getCurrAccId(),
+                        path,
+                        currentPasswordEdit.text)
         }
 
         if (success) {
@@ -126,8 +129,10 @@ Dialog {
 
     function savePasswordQML() {
         var success = false
-        success = ClientWrapper.accountAdaptor.savePassword(ClientWrapper.utilsAdaptor.getCurrAccId(),currentPasswordEdit.text, passwordEdit.text)
-
+        success = ClientWrapper.accountAdaptor.savePassword(
+                    UtilsAdapter.getCurrAccId(),
+                    currentPasswordEdit.text,
+                    passwordEdit.text)
         if (success) {
             ClientWrapper.accountAdaptor.setArchiveHasPassword(passwordEdit.text.length !== 0)
             haveDone(successCode, root.purpose)
diff --git a/src/commoncomponents/PhotoboothView.qml b/src/commoncomponents/PhotoboothView.qml
index af78996ab7df02b430021c572128207a6d788979..9c0469633251bd7e9f88e0438e9a7fc9c93580c7 100644
--- a/src/commoncomponents/PhotoboothView.qml
+++ b/src/commoncomponents/PhotoboothView.qml
@@ -61,12 +61,13 @@ ColumnLayout {
 
         onAccepted: {
             fileName = file
-            if(fileName.length === 0) {
+            if (fileName.length === 0) {
                 imageCleared()
                 return
             }
-            imgBase64 = ClientWrapper.utilsAdaptor.getCroppedImageBase64FromFile(
-                        ClientWrapper.utilsAdaptor.getAbsPath(fileName),boothWidth)
+            imgBase64 = UtilsAdapter.getCroppedImageBase64FromFile(
+                            UtilsAdapter.getAbsPath(fileName),
+                            boothWidth)
             imageAcquired()
             stopBooth()
         }
diff --git a/src/commoncomponents/PreferenceItemDelegate.qml b/src/commoncomponents/PreferenceItemDelegate.qml
index 1e4e93662d0ba58cb3b1ff97f90d807e96a41812..5515ae2c01830125f0cbffa86761b7d2455c04a6 100644
--- a/src/commoncomponents/PreferenceItemDelegate.qml
+++ b/src/commoncomponents/PreferenceItemDelegate.qml
@@ -80,7 +80,7 @@ ItemDelegate {
         folder: "file://" + currentPath
 
         onAccepted: {
-            var url = ClientWrapper.utilsAdaptor.getAbsPath(fileUrl.toString())
+            var url = UtilsAdapter.getAbsPath(fileUrl.toString())
             preferenceNewValue = url
             btnPreferenceClicked()
         }
diff --git a/src/contactadapter.cpp b/src/contactadapter.cpp
index 9514d852c29528c0a7840ebe5924785cdc4bdd29..b8224f98beba02c789cf2d251d077a886dc134f9 100644
--- a/src/contactadapter.cpp
+++ b/src/contactadapter.cpp
@@ -34,7 +34,7 @@ ContactAdapter::getContactSelectableModel(int type)
     /*
      * Called from qml every time contact picker refreshes.
      */
-    listModeltype_ = Utils::toEnum<SmartListModel::Type>(type);
+    listModeltype_ = static_cast<SmartListModel::Type>(type);
     smartListModel_.reset(new SmartListModel(LRCInstance::getCurrAccId(),
                                              this,
                                              listModeltype_,
diff --git a/src/lrcinstance.h b/src/lrcinstance.h
index 1da63c1f1d7c7e287b9acd4ff230c5b79df360b3..b49f8bc38b9c2ac9c7cf6995eeded7c1a210b05c 100644
--- a/src/lrcinstance.h
+++ b/src/lrcinstance.h
@@ -208,10 +208,10 @@ public:
                     return *conv;
                 }
             } else {
-                for (int i = Utils::toUnderlyingValue(profile::Type::RING);
-                     i <= Utils::toUnderlyingValue(profile::Type::TEMPORARY);
+                for (int i = static_cast<int>(profile::Type::RING);
+                     i <= static_cast<int>(profile::Type::TEMPORARY);
                      ++i) {
-                    auto filter = Utils::toEnum<profile::Type>(i);
+                    auto filter = static_cast<profile::Type>(i);
                     auto &convs = convModel->getFilteredConversations(filter);
                     auto conv = std::find_if(convs.begin(), convs.end(), pred);
                     if (conv != convs.end()) {
diff --git a/src/mainview/MainView.qml b/src/mainview/MainView.qml
index 1377a7d480faa3755845360e3fe31129ab73ab96..eee9b8d3b9d68e7546d83a20c1051e7a978028d7 100644
--- a/src/mainview/MainView.qml
+++ b/src/mainview/MainView.qml
@@ -22,6 +22,7 @@ import QtQuick.Layouts 1.14
 import QtQuick.Controls.Universal 2.12
 import QtGraphicalEffects 1.14
 import net.jami.Models 1.0
+import net.jami.Adapters 1.0
 
 // Import qml component files.
 
@@ -196,9 +197,9 @@ Window {
                 toggleSettingsView()
             }
 
-            var index = ClientWrapper.utilsAdaptor.getCurrAccList().indexOf(accountId)
-            var name = ClientWrapper.utilsAdaptor.getBestName(accountId, convUid)
-            var id = ClientWrapper.utilsAdaptor.getBestId(accountId, convUid)
+            var index = UtilsAdapter.getCurrAccList().indexOf(accountId)
+            var name = UtilsAdapter.getBestName(accountId, convUid)
+            var id = UtilsAdapter.getBestId(accountId, convUid)
 
             communicationPageMessageWebView.headerUserAliasLabelText = name
             communicationPageMessageWebView.headerUserUserNameLabelText = (name !== id) ? id : ""
@@ -308,7 +309,7 @@ Window {
                         settingsView.setSelected(settingsView.selectedMenu, true)
 
                         if (needToShowCallStack
-                                && callStackView.responsibleAccountId === ClientWrapper.utilsAdaptor.getCurrAccId()){
+                                && callStackView.responsibleAccountId === UtilsAdapter.getCurrAccId()){
                             if (!ClientWrapper.accountAdaptor.hasVideoCall()) {
                                 pushCommunicationMessageWebView()
                                 needToShowCallStack = false
@@ -419,20 +420,18 @@ Window {
             communicationPageMessageWebView.headerUserUserNameLabelText = currentUserDisplayName
 
             callStackView.needToCloseInCallConversationAndPotentialWindow()
-            callStackView.responsibleAccountId = ClientWrapper.utilsAdaptor.getCurrAccId()
+            callStackView.responsibleAccountId = UtilsAdapter.getCurrAccId()
             callStackView.responsibleConvUid = currentUID
             callStackView.updateCorrspondingUI()
 
             if (callStackViewShouldShow) {
                 if (callState === Call.Status.IN_PROGRESS || callState === Call.Status.PAUSED) {
-                    ClientWrapper.utilsAdaptor.setCurrentCall(
-                                ClientWrapper.utilsAdaptor.getCurrAccId(),
-                                currentUID)
+                    UtilsAdapter.setCurrentCall(UtilsAdapter.getCurrAccId(), currentUID)
                     if (isAudioOnly)
                         callStackView.showAudioCallPage()
                     else
                         callStackView.showVideoCallPage(
-                                    ClientWrapper.utilsAdaptor.getCallId(
+                                    UtilsAdapter.getCallId(
                                         callStackView.responsibleAccountId,
                                         callStackView.responsibleConvUid))
                 } else {
@@ -751,7 +750,7 @@ Window {
         sequence: "Ctrl+Shift+A"
         context: Qt.ApplicationShortcut
         onActivated: {
-            ClientWrapper.utilsAdaptor.makePermanentCurrentConv()
+            UtilsAdapter.makePermanentCurrentConv()
             communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
         }
     }
diff --git a/src/mainview/components/AboutPopUp.qml b/src/mainview/components/AboutPopUp.qml
index fea3ff069332329eba63ce2f22d36e050225c332..740f75afec655e436f7931b9e282246959d2e7c3 100644
--- a/src/mainview/components/AboutPopUp.qml
+++ b/src/mainview/components/AboutPopUp.qml
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (C) 2020 by Savoir-faire Linux
  * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
@@ -16,10 +15,12 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
+
 import QtQuick 2.14
 import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
 import net.jami.Models 1.0
+import net.jami.Adapters 1.0
 
 import "../../commoncomponents"
 
@@ -30,7 +31,6 @@ Dialog {
     // When dialog is opened, trigger mainViewWindow overlay which is defined in overlay.model (model : true is necessary).
     modal: true
 
-
     // Content height + margin.
     contentHeight: aboutPopUpContentRectColumnLayout.height + 5 * 7
 
@@ -83,7 +83,7 @@ Dialog {
                 TextMetrics {
                     id: textMetricsjamiVersionText
                     font: jamiVersionText.font
-                    text: qsTr("version") + ": " + ClientWrapper.utilsAdaptor.getVersionStr()
+                    text: qsTr("version") + ": " + UtilsAdapter.getVersionStr()
                 }
             }
 
diff --git a/src/mainview/components/AudioCallPage.qml b/src/mainview/components/AudioCallPage.qml
index 0a85cf235897a6d8774da405ca1110b74593bf3b..1994e895b2dd37bd97e686f8d6a8ab88638957f5 100644
--- a/src/mainview/components/AudioCallPage.qml
+++ b/src/mainview/components/AudioCallPage.qml
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (C) 2020 by Savoir-faire Linux
  * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
@@ -16,11 +15,13 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
+
 import QtQuick 2.14
 import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
 import QtQuick.Controls.Universal 2.12
 import net.jami.Models 1.0
+import net.jami.Adapters 1.0
 
 import "../../commoncomponents"
 
@@ -34,11 +35,11 @@ Rectangle {
     property var linkedWebview: null
 
     function updateUI(accountId, convUid) {
-        contactImgSource = "data:image/png;base64," + ClientWrapper.utilsAdaptor.getContactImageString(
+        contactImgSource = "data:image/png;base64," + UtilsAdapter.getContactImageString(
                     accountId, convUid)
-        bestName = ClientWrapper.utilsAdaptor.getBestName(accountId, convUid)
+        bestName = UtilsAdapter.getBestName(accountId, convUid)
 
-        var id = ClientWrapper.utilsAdaptor.getBestId(accountId, convUid)
+        var id = UtilsAdapter.getBestId(accountId, convUid)
         bestId = (bestName !== id) ? id : ""
     }
 
diff --git a/src/mainview/components/CallOverlay.qml b/src/mainview/components/CallOverlay.qml
index 843df4c809e3aa551c7dac868986ba4d8468fd50..ed5653ef71345fc3305f67e903bc610d9bd75474 100644
--- a/src/mainview/components/CallOverlay.qml
+++ b/src/mainview/components/CallOverlay.qml
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (C) 2020 by Savoir-faire Linux
  * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
@@ -18,12 +17,14 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
+
 import QtQuick 2.14
 import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
 import QtQuick.Controls.Universal 2.12
 import QtQml 2.14
 import net.jami.Models 1.0
+import net.jami.Adapters 1.0
 
 import "../js/contactpickercreation.js" as ContactPickerCreation
 import "../js/mediahandlerpickercreation.js" as MediaHandlerPickerCreation
diff --git a/src/mainview/components/CallStackView.qml b/src/mainview/components/CallStackView.qml
index a626f11983e7fe2d52b7eb09d85ee671217eb612..e93bd78b966cdc80d4670dec231a82a8ef4f7cc7 100644
--- a/src/mainview/components/CallStackView.qml
+++ b/src/mainview/components/CallStackView.qml
@@ -149,7 +149,7 @@ Rectangle {
         }
 
         function onUpdateParticipantsInfos(infos, accountId, callId) {
-            var responsibleCallId = ClientWrapper.utilsAdaptor.getCallId(responsibleAccountId, responsibleConvUid)
+            var responsibleCallId = UtilsAdapter.getCallId(responsibleAccountId, responsibleConvUid)
             if (responsibleCallId === callId) {
                 videoCallPage.handleParticipantsInfo(infos)
             }
diff --git a/src/mainview/components/ChangeLogScrollView.qml b/src/mainview/components/ChangeLogScrollView.qml
index f672e65d3c710d58367baba7752a08d74b689b8a..b4962cfcf62e9c28d651bc71128a629254d6164c 100644
--- a/src/mainview/components/ChangeLogScrollView.qml
+++ b/src/mainview/components/ChangeLogScrollView.qml
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (C) 2020 by Savoir-faire Linux
  * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
@@ -16,9 +15,11 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
+
 import QtQuick 2.14
 import QtQuick.Controls 2.14
 import net.jami.Models 1.0
+import net.jami.Adapters 1.0
 
 ScrollView {
     id: changeLogScrollView
@@ -39,7 +40,7 @@ ScrollView {
         wrapMode: Text.WordWrap
 
         font.pointSize: JamiTheme.textFontSize - 3
-        text: ClientWrapper.utilsAdaptor.getChangeLog()
+        text: UtilsAdapter.getChangeLog()
         textFormat: TextEdit.RichText
 
         MouseArea {
diff --git a/src/mainview/components/ConversationSmartListContextMenu.qml b/src/mainview/components/ConversationSmartListContextMenu.qml
index c5aa47138e798ce85618ff4d205ef1398d853649..7a0a3cfcc1984d8f273610a828ba1bd699196512 100644
--- a/src/mainview/components/ConversationSmartListContextMenu.qml
+++ b/src/mainview/components/ConversationSmartListContextMenu.qml
@@ -52,7 +52,7 @@ Item {
         ContextMenuGenerator.addMenuItem(qsTr("Clear conversation"),
                                          "qrc:/images/icons/ic_clear_24px.svg",
                                          function (){
-                                             ClientWrapper.utilsAdaptor.clearConversationHistory(
+                                             UtilsAdapter.clearConversationHistory(
                                                          responsibleAccountId,
                                                          responsibleConvUid)
                                          })
@@ -61,7 +61,7 @@ Item {
             ContextMenuGenerator.addMenuItem(qsTr("Remove contact"),
                                              "qrc:/images/icons/round-remove_circle-24px.svg",
                                              function (){
-                                                 ClientWrapper.utilsAdaptor.removeConversation(
+                                                 UtilsAdapter.removeConversation(
                                                              responsibleAccountId,
                                                              responsibleConvUid)
                                              })
diff --git a/src/mainview/components/ConversationSmartListView.qml b/src/mainview/components/ConversationSmartListView.qml
index 1d61c5bb3dd377d9368fae7db32991067d76f4ca..a9da6ee93dcdbc7efaf3e532050730e1db90da7a 100644
--- a/src/mainview/components/ConversationSmartListView.qml
+++ b/src/mainview/components/ConversationSmartListView.qml
@@ -121,8 +121,8 @@ ListView {
         context: Qt.ApplicationShortcut
         enabled: root.visible
         onActivated: {
-            ClientWrapper.utilsAdaptor.clearConversationHistory(ClientWrapper.utilsAdaptor.getCurrAccId(),
-                                                  ClientWrapper.utilsAdaptor.getCurrConvId())
+            UtilsAdapter.clearConversationHistory(UtilsAdapter.getCurrAccId(),
+                                                  UtilsAdapter.getCurrConvId())
         }
     }
 
@@ -131,8 +131,9 @@ ListView {
         context: Qt.ApplicationShortcut
         enabled: root.visible
         onActivated: {
-            ClientWrapper.utilsAdaptor.removeConversation(ClientWrapper.utilsAdaptor.getCurrAccId(),
-                                            ClientWrapper.utilsAdaptor.getCurrConvId(), true)
+            UtilsAdapter.removeConversation(UtilsAdapter.getCurrAccId(),
+                                            UtilsAdapter.getCurrConvId(),
+                                            true)
             root.needToBackToWelcomePage()
         }
     }
@@ -142,8 +143,9 @@ ListView {
         context: Qt.ApplicationShortcut
         enabled: root.visible
         onActivated: {
-            ClientWrapper.utilsAdaptor.removeConversation(ClientWrapper.utilsAdaptor.getCurrAccId(),
-                                            ClientWrapper.utilsAdaptor.getCurrConvId(), false)
+            UtilsAdapter.removeConversation(UtilsAdapter.getCurrAccId(),
+                                            UtilsAdapter.getCurrConvId(),
+                                            false)
         }
     }
 
diff --git a/src/mainview/components/ConversationSmartListViewItemDelegate.qml b/src/mainview/components/ConversationSmartListViewItemDelegate.qml
index 5357dc637a51301c77bd84c021f33a1d13880cce..bc600f757d630afa94f28d581776efe9d0ebd0e7 100644
--- a/src/mainview/components/ConversationSmartListViewItemDelegate.qml
+++ b/src/mainview/components/ConversationSmartListViewItemDelegate.qml
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (C) 2020 by Savoir-faire Linux
  * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
@@ -16,10 +15,12 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
+
 import QtQuick 2.14
 import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
 import net.jami.Models 1.0
+import net.jami.Adapters 1.0
 
 import "../../commoncomponents"
 
@@ -135,7 +136,7 @@ ItemDelegate {
             elide: Text.ElideRight
             elideWidth: LastInteractionDate ? (smartListItemDelegate.width - lastInteractionPreferredWidth - conversationSmartListUserImage.width-32) :
                                               smartListItemDelegate.width - lastInteractionPreferredWidth
-            text: InCall ? ClientWrapper.utilsAdaptor.getCallStatusStr(CallState) : (Draft ? Draft : LastInteraction)
+            text: InCall ? UtilsAdapter.getCallStatusStr(CallState) : (Draft ? Draft : LastInteraction)
         }
 
         font.hintingPreference: Font.PreferNoHinting
@@ -168,8 +169,9 @@ ItemDelegate {
         }
         onDoubleClicked: {
             if (!InCall) {
-                ConversationsAdapter.selectConversation(ClientWrapper.utilsAdaptor.getCurrAccId(),
-                                                        UID, false)
+                ConversationsAdapter.selectConversation(UtilsAdapter.getCurrAccId(),
+                                                        UID,
+                                                        false)
                 CallAdapter.placeCall()
             }
         }
@@ -185,7 +187,7 @@ ItemDelegate {
                                                  mouse.x, mouse.y)
                 smartListContextMenu.x = relativeMousePos.x
                 smartListContextMenu.y = relativeMousePos.y
-                smartListContextMenu.responsibleAccountId = ClientWrapper.utilsAdaptor.getCurrAccId()
+                smartListContextMenu.responsibleAccountId = UtilsAdapter.getCurrAccId()
                 smartListContextMenu.responsibleConvUid = UID
                 smartListContextMenu.contactType = ContactType
                 userProfile.responsibleConvUid = UID
diff --git a/src/mainview/components/IncomingCallPage.qml b/src/mainview/components/IncomingCallPage.qml
index 9955efcfd1aebecd54349511f7c20bccfcae4560..87d68eea6db6a7514386001dc8851dda2fecd9eb 100644
--- a/src/mainview/components/IncomingCallPage.qml
+++ b/src/mainview/components/IncomingCallPage.qml
@@ -49,11 +49,11 @@ Window {
 
     function updateUI() {
         incomingCallPage.contactImgSource = "data:image/png;base64,"
-                + ClientWrapper.utilsAdaptor.getContactImageString(responsibleAccountId,
+                + UtilsAdapter.getContactImageString(responsibleAccountId,
                                                      responsibleConvUid)
-        incomingCallPage.bestName = ClientWrapper.utilsAdaptor.getBestName(
+        incomingCallPage.bestName = UtilsAdapter.getBestName(
                     responsibleAccountId, responsibleConvUid)
-        var id = ClientWrapper.utilsAdaptor.getBestId(responsibleAccountId,
+        var id = UtilsAdapter.getBestId(responsibleAccountId,
                                         responsibleConvUid)
         incomingCallPage.bestId = (incomingCallPage.bestName !== id) ? id : ""
     }
diff --git a/src/mainview/components/MessageWebView.qml b/src/mainview/components/MessageWebView.qml
index 8453c41cba0b3fa924781aed9853804977dbd10a..8893cadc7a7dd46062dc708276caca5687f98d74 100644
--- a/src/mainview/components/MessageWebView.qml
+++ b/src/mainview/components/MessageWebView.qml
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (C) 2020 by Savoir-faire Linux
  * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
@@ -16,16 +15,17 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
+
 import QtQuick 2.14
 import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
 import QtWebEngine 1.10
 import QtWebChannel 1.14
 import net.jami.Models 1.0
+import net.jami.Adapters 1.0
 
 import "../../commoncomponents"
 
-
 Rectangle {
     id: messageWebViewRect
 
@@ -66,7 +66,7 @@ Rectangle {
         onAccepted: {
             var filePaths = jamiFileDialog.files
             for (var index = 0; index < filePaths.length; ++index) {
-                var path = ClientWrapper.utilsAdaptor.getAbsPath(filePaths[index])
+                var path = UtilsAdapter.getAbsPath(filePaths[index])
                 MessagesAdapter.setNewMessagesContent(path)
             }
         }
@@ -77,7 +77,7 @@ Rectangle {
         DropArea{
             anchors.fill: parent
             onDropped: {
-                var path = ClientWrapper.utilsAdaptor.getAbsPath(drop.text.toString())
+                var path = UtilsAdapter.getAbsPath(drop.text.toString())
                 MessagesAdapter.setNewMessagesContent(path)
             }
         }
@@ -223,7 +223,7 @@ Rectangle {
         DropArea{
             anchors.fill: parent
             onDropped: {
-                var path = ClientWrapper.utilsAdaptor.getAbsPath(drop.text.toString())
+                var path = UtilsAdapter.getAbsPath(drop.text.toString())
                 MessagesAdapter.setNewMessagesContent(path)
             }
         }
@@ -237,33 +237,33 @@ Rectangle {
 
         onLoadingChanged: {
             if (loadRequest.status == WebEngineView.LoadSucceededStatus) {
-                messageWebView.runJavaScript(ClientWrapper.utilsAdaptor.getStyleSheet(
+                messageWebView.runJavaScript(UtilsAdapter.getStyleSheet(
                                                  "chatcss",
-                                                 ClientWrapper.utilsAdaptor.qStringFromFile(
+                                                 UtilsAdapter.qStringFromFile(
                                                      ":/chatview.css")))
-                messageWebView.runJavaScript(ClientWrapper.utilsAdaptor.getStyleSheet(
+                messageWebView.runJavaScript(UtilsAdapter.getStyleSheet(
                                                  "chatwin",
-                                                 ClientWrapper.utilsAdaptor.qStringFromFile(
+                                                 UtilsAdapter.qStringFromFile(
                                                      ":/chatview-windows.css")))
 
-                messageWebView.runJavaScript(ClientWrapper.utilsAdaptor.qStringFromFile(
+                messageWebView.runJavaScript(UtilsAdapter.qStringFromFile(
                                                  ":/jed.js"))
-                messageWebView.runJavaScript(ClientWrapper.utilsAdaptor.qStringFromFile(
+                messageWebView.runJavaScript(UtilsAdapter.qStringFromFile(
                                                  ":/linkify.js"))
-                messageWebView.runJavaScript(ClientWrapper.utilsAdaptor.qStringFromFile(
+                messageWebView.runJavaScript(UtilsAdapter.qStringFromFile(
                                                  ":/linkify-html.js"))
-                messageWebView.runJavaScript(ClientWrapper.utilsAdaptor.qStringFromFile(
+                messageWebView.runJavaScript(UtilsAdapter.qStringFromFile(
                                                  ":/linkify-string.js"))
-                messageWebView.runJavaScript(ClientWrapper.utilsAdaptor.qStringFromFile(
+                messageWebView.runJavaScript(UtilsAdapter.qStringFromFile(
                                                  ":/qwebchannel.js"))
-                messageWebView.runJavaScript(ClientWrapper.utilsAdaptor.qStringFromFile(
+                messageWebView.runJavaScript(UtilsAdapter.qStringFromFile(
                                                  ":/chatview.js"))
                 messageWebView.runJavaScript("init_i18n();")
                 messageWebView.runJavaScript("displayNavbar(false);")
             }
         }
         Component.onCompleted: {
-            messageWebView.loadHtml(ClientWrapper.utilsAdaptor.qStringFromFile(
+            messageWebView.loadHtml(UtilsAdapter.qStringFromFile(
                                         ":/chatview.html"), ":/chatview.html")
             messageWebView.url = "qrc:/chatview.html"
         }
@@ -274,8 +274,8 @@ Rectangle {
     WebEngineProfile {
         id: messageWebViewProfile
 
-        cachePath: ClientWrapper.utilsAdaptor.getCachePath()
-        persistentStoragePath: ClientWrapper.utilsAdaptor.getCachePath()
+        cachePath: UtilsAdapter.getCachePath()
+        persistentStoragePath: UtilsAdapter.getCachePath()
         persistentCookiesPolicy: WebEngineProfile.NoPersistentCookies
         httpCacheType: WebEngineProfile.NoCache
         httpUserAgent: "jami-windows"
diff --git a/src/mainview/components/OutgoingCallPage.qml b/src/mainview/components/OutgoingCallPage.qml
index 4d2171a471c8ba95b0f1f84682c061bfd912d7c1..5acd4032dd59e356a02e9deeea9fa9558f01d0d5 100644
--- a/src/mainview/components/OutgoingCallPage.qml
+++ b/src/mainview/components/OutgoingCallPage.qml
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (C) 2020 by Savoir-faire Linux
  * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
@@ -16,11 +15,13 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
+
 import QtQuick 2.14
 import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
 import QtQuick.Controls.Universal 2.12
 import net.jami.Models 1.0
+import net.jami.Adapters 1.0
 
 import "../../commoncomponents"
 
@@ -36,10 +37,10 @@ Rectangle {
     signal callCancelButtonIsClicked
 
     function updateUI(accountId, convUid) {
-        contactImgSource = "data:image/png;base64," + ClientWrapper.utilsAdaptor.getContactImageString(
+        contactImgSource = "data:image/png;base64," + UtilsAdapter.getContactImageString(
                     accountId, convUid)
-        bestName = ClientWrapper.utilsAdaptor.getBestName(accountId, convUid)
-        var id = ClientWrapper.utilsAdaptor.getBestId(accountId, convUid)
+        bestName = UtilsAdapter.getBestName(accountId, convUid)
+        var id = UtilsAdapter.getBestId(accountId, convUid)
         bestId = (bestName !== id) ? id : ""
     }
 
@@ -158,7 +159,7 @@ Rectangle {
                     horizontalAlignment: Text.AlignHCenter
                     verticalAlignment: Text.AlignVCenter
 
-                    text: ClientWrapper.utilsAdaptor.getCallStatusStr(callStatus) + "..."
+                    text: UtilsAdapter.getCallStatusStr(callStatus) + "..."
                     color: Qt.lighter("white", 1.5)
                 }
             }
diff --git a/src/mainview/components/ProjectCreditsScrollView.qml b/src/mainview/components/ProjectCreditsScrollView.qml
index 0606f04ceb32ff3fe79b6806f3ae50a3efe645d0..32170d1d4edaaa4a563aff7a660f4915d8f138de 100644
--- a/src/mainview/components/ProjectCreditsScrollView.qml
+++ b/src/mainview/components/ProjectCreditsScrollView.qml
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (C) 2020 by Savoir-faire Linux
  * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
@@ -16,9 +15,11 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
+
 import QtQuick 2.14
 import QtQuick.Controls 2.14
 import net.jami.Models 1.0
+import net.jami.Adapters 1.0
 
 ScrollView {
     id: projectCreditsScrollView
@@ -41,7 +42,7 @@ ScrollView {
         wrapMode: Text.WordWrap
 
         font.pointSize: JamiTheme.textFontSize - 3
-        text: ClientWrapper.utilsAdaptor.getProjectCredits()
+        text: UtilsAdapter.getProjectCredits()
         textFormat: TextEdit.RichText
 
         MouseArea {
diff --git a/src/mainview/components/SidePanel.qml b/src/mainview/components/SidePanel.qml
index 2a59f50fc84d7b5362129eaab7f896c3bb051812..e1fd9a310c3d32680e4023de44796de2078ea537 100644
--- a/src/mainview/components/SidePanel.qml
+++ b/src/mainview/components/SidePanel.qml
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (C) 2020 by Savoir-faire Linux
  * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
@@ -16,10 +15,12 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
+
 import QtQuick 2.14
 import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
 import net.jami.Models 1.0
+import net.jami.Adapters 1.0
 
 import "../../commoncomponents"
 
@@ -54,11 +55,11 @@ Rectangle {
     }
 
     function updatePendingRequestCount() {
-        pendingRequestCount = ClientWrapper.utilsAdaptor.getTotalPendingRequest()
+        pendingRequestCount = UtilsAdapter.getTotalPendingRequest()
     }
 
     function updateTotalUnreadMessagesCount() {
-        totalUnreadMessagesCount = ClientWrapper.utilsAdaptor.getTotalUnreadMessages()
+        totalUnreadMessagesCount = UtilsAdapter.getTotalUnreadMessages()
     }
 
     function clearContactSearchBar() {
@@ -105,7 +106,7 @@ Rectangle {
         anchors.leftMargin: 16
 
         onContactSearchBarTextChanged: {
-            ClientWrapper.utilsAdaptor.setConversationFilter(text)
+            UtilsAdapter.setConversationFilter(text)
         }
     }
 
diff --git a/src/mainview/components/VideoCallPage.qml b/src/mainview/components/VideoCallPage.qml
index 5ec8c82f48b0551e186cfed39d6726a435f446bb..7d57e82fd6f899b2b92c75a1dfbf13ca55a4d5e5 100644
--- a/src/mainview/components/VideoCallPage.qml
+++ b/src/mainview/components/VideoCallPage.qml
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (C) 2020 by Savoir-faire Linux
  * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
@@ -17,12 +16,14 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
+
 import QtQuick 2.14
 import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
 import QtQuick.Controls.Universal 2.12
 import QtGraphicalEffects 1.14
 import net.jami.Models 1.0
+import net.jami.Adapters 1.0
 
 import "../../commoncomponents"
 
@@ -44,9 +45,9 @@ Rectangle {
     function updateUI(accountId, convUid) {
         videoCallOverlay.handleParticipantsInfo(CallAdapter.getConferencesInfos())
 
-        bestName = ClientWrapper.utilsAdaptor.getBestName(accountId, convUid)
+        bestName = UtilsAdapter.getBestName(accountId, convUid)
 
-        var id = ClientWrapper.utilsAdaptor.getBestId(accountId, convUid)
+        var id = UtilsAdapter.getBestId(accountId, convUid)
         bestId = (bestName !== id) ? id : ""
     }
 
@@ -78,7 +79,7 @@ Rectangle {
 
     function handleParticipantsInfo(infos) {
         if (infos.length === 0) {
-            bestName = ClientWrapper.utilsAdaptor.getBestName(accountId, convUid)
+            bestName = UtilsAdapter.getBestName(accountId, convUid)
         } else {
             bestName = ""
         }
diff --git a/src/mainview/components/WelcomePage.qml b/src/mainview/components/WelcomePage.qml
index 49d8061d80a95414efe99e5dda95f347505e032e..7e68015e196950e9f3b318231da7e3b67d869386 100644
--- a/src/mainview/components/WelcomePage.qml
+++ b/src/mainview/components/WelcomePage.qml
@@ -136,7 +136,7 @@ Rectangle {
                         radius: 30
                         source: "qrc:/images/icons/ic_content_copy.svg"
                         onClicked: {
-                            ClientWrapper.utilsAdaptor.setText(
+                            UtilsAdapter.setText(
                                         textMetricsjamiRegisteredNameText.text)
                         }
                     }
diff --git a/src/mainview/components/WelcomePageQrDialog.qml b/src/mainview/components/WelcomePageQrDialog.qml
index ccadf0f3c0779f550b705e2c7918b2b802ece922..2cc91c0d6a2001bcdec9f68deaeaee130455cd6e 100644
--- a/src/mainview/components/WelcomePageQrDialog.qml
+++ b/src/mainview/components/WelcomePageQrDialog.qml
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (C) 2020 by Savoir-faire Linux
  * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
@@ -16,19 +15,20 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
+
 import QtQuick 2.14
 import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
 import net.jami.Models 1.0
-
+import net.jami.Adapters 1.0
 
 Dialog {
     id: userQrImageDialog
 
-    property string accountIdStr: ClientWrapper.utilsAdaptor.getCurrAccId()
+    property string accountIdStr: UtilsAdapter.getCurrAccId()
 
     function updateQrDialog() {
-        accountIdStr = ClientWrapper.utilsAdaptor.getCurrAccId()
+        accountIdStr = UtilsAdapter.getCurrAccId()
     }
 
     // When dialog is opened, trigger mainViewWindow overlay which is defined in overlay.model.
diff --git a/src/messagesadapter.cpp b/src/messagesadapter.cpp
index 8b7cd94d0008e7076f5e94f68ccd96848855c310..4e8b92765f7df914b48281d9abc3a92ff91d4499 100644
--- a/src/messagesadapter.cpp
+++ b/src/messagesadapter.cpp
@@ -23,9 +23,11 @@
 
 #include "messagesadapter.h"
 
-#include "utils.h"
+#include "qtutils.h"
 #include "webchathelpers.h"
 
+#include <QApplication>
+#include <QClipboard>
 #include <QDesktopServices>
 #include <QFileInfo>
 #include <QImageReader>
diff --git a/src/pixbufmanipulator.cpp b/src/pixbufmanipulator.cpp
index e621808e826de2b909ccbd740a5b6503128c0122..e8aea9550d76bbaa06dde9b2952b4f08fce1da95 100644
--- a/src/pixbufmanipulator.cpp
+++ b/src/pixbufmanipulator.cpp
@@ -106,26 +106,22 @@ PixbufManipulator::decorationRole(const lrc::api::conversation::Info &conversati
         auto bestId = Utils::bestIdForContact(contactInfo);
         if (accountInfo.profileInfo.type == lrc::api::profile::Type::SIP
             && contactInfo.profileInfo.type == lrc::api::profile::Type::TEMPORARY) {
-            photo = Utils::fallbackAvatar(IMAGE_SIZE, QString(), QString());
+            photo = Utils::fallbackAvatar(QString(), QString());
         } else if (contactInfo.profileInfo.type == lrc::api::profile::Type::TEMPORARY
                    && contactInfo.profileInfo.uri.isEmpty()) {
-            photo = Utils::fallbackAvatar(IMAGE_SIZE, QString(), QString());
+            photo = Utils::fallbackAvatar(QString(), QString());
         } else if (!contactPhoto.isEmpty()) {
             QByteArray byteArray = contactPhoto.toLocal8Bit();
             photo = personPhoto(byteArray, nullptr).value<QImage>();
             if (photo.isNull()) {
                 auto avatarName = contactInfo.profileInfo.uri == bestName ? QString() : bestName;
-                photo = Utils::fallbackAvatar(IMAGE_SIZE,
-                                              "ring:" + contactInfo.profileInfo.uri,
-                                              avatarName);
+                photo = Utils::fallbackAvatar("ring:" + contactInfo.profileInfo.uri, avatarName);
             }
         } else {
             auto avatarName = contactInfo.profileInfo.uri == bestName ? QString() : bestName;
-            photo = Utils::fallbackAvatar(IMAGE_SIZE,
-                                          "ring:" + contactInfo.profileInfo.uri,
-                                          avatarName);
+            photo = Utils::fallbackAvatar("ring:" + contactInfo.profileInfo.uri, avatarName);
         }
     } catch (...) {
     }
-    return QVariant::fromValue(Utils::scaleAndFrame(photo, IMAGE_SIZE));
-}
\ No newline at end of file
+    return QVariant::fromValue(Utils::scaleAndFrame(photo));
+}
diff --git a/src/preferenceitemlistmodel.cpp b/src/preferenceitemlistmodel.cpp
index 226e665327636b83cac21bf24e52351d1255fc4c..e501aaeae2452b908b54e95d9160ad9bd861a6db 100644
--- a/src/preferenceitemlistmodel.cpp
+++ b/src/preferenceitemlistmodel.cpp
@@ -1,4 +1,4 @@
-/**
+/*!
  * Copyright (C) 2020 by Savoir-faire Linux
  * Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
  *
@@ -17,7 +17,9 @@
  */
 
 #include "preferenceitemlistmodel.h"
+
 #include "utils.h"
+
 #include <map>
 
 std::map<QString, int> mapType {{QString("List"), PreferenceItemListModel::Type::LIST},
@@ -73,7 +75,7 @@ PreferenceItemListModel::data(const QModelIndex& index, int role) const
             for (auto& mimeType : mimeTypeList) {
                 QString fileExt = mimeType.mid(mimeType.lastIndexOf("/") + 1);
                 acceptedFiles.append((fileExt.toUpper() + " Files") + " (*." + fileExt + ")");
-                checkImage = UtilsAdapter().isImage(fileExt);
+                checkImage = Utils::isImage(fileExt);
             }
         }
     }
diff --git a/src/qmlregister.cpp b/src/qmlregister.cpp
index 902e5e71ac52016bc2281afb8af4bbfb4da7a872..1ab11c63b259e4b1e008fc365b5650848675cdbc 100644
--- a/src/qmlregister.cpp
+++ b/src/qmlregister.cpp
@@ -41,7 +41,7 @@
 #include "pluginlistpreferencemodel.h"
 #include "previewrenderer.h"
 #include "settingsadapter.h"
-#include "utils.h"
+#include "utilsadapter.h"
 #include "version.h"
 #include "videocodeclistmodel.h"
 #include "videoformatfpsmodel.h"
@@ -142,8 +142,9 @@ void registerTypes()
     QML_REGISTERSINGLETONTYPE("net.jami.Models", PluginAdapter, 1, 0);
     QML_REGISTERSINGLETONTYPE("net.jami.Models", ClientWrapper, 1, 0);
 
-
+    QML_REGISTERSINGLETONTYPE("net.jami.Adapters", UtilsAdapter, 1, 0);
     QML_REGISTERSINGLETONTYPE("net.jami.Adapters", SettingsAdapter, 1, 0);
+
     QML_REGISTERUNCREATABLE("net.jami.Enums", Settings, 1, 0);
 
     /*
@@ -166,7 +167,6 @@ void registerTypes()
      * qmlRegisterUncreatableType & Q_DECLARE_METATYPE to expose models in qml.
      */
     QML_REGISTERUNCREATABLE("net.jami.Models", RenderManager, 1, 0);
-    QML_REGISTERUNCREATABLE("net.jami.Models", UtilsAdapter, 1, 0);
     QML_REGISTERUNCREATABLE("net.jami.Models", NameDirectory, 1, 0);
     QML_REGISTERUNCREATABLE("net.jami.Models", LRCInstance, 1, 0);
 
diff --git a/src/qrimageprovider.h b/src/qrimageprovider.h
index e8822c668e8e2579df4aa3fb16e6e2e071aac4da..90cbf908267f9229909ddc280a106372b24f2049 100644
--- a/src/qrimageprovider.h
+++ b/src/qrimageprovider.h
@@ -47,7 +47,9 @@ public:
     getIndexFromID(const QString &id)
     {
         auto list = id.split('_', QString::SkipEmptyParts);
-        if (list.contains("account")) {
+        if (list.size() < 2)
+            return QPair(QrType::Account, "");
+        if (list.contains("account") && list.size() > 1) {
             return QPair(QrType::Account, list[1]);
         } else if (list.contains("contact") && list.size() > 1) {
             /*
diff --git a/src/qtutils.h b/src/qtutils.h
new file mode 100644
index 0000000000000000000000000000000000000000..141831e088461cf680a55dda45041eefdb2fda03
--- /dev/null
+++ b/src/qtutils.h
@@ -0,0 +1,120 @@
+/*
+ * 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 <QObject>
+
+namespace Utils {
+
+template<typename Func1, typename Func2>
+void
+oneShotConnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender,
+               Func1 signal,
+               Func2 slot)
+{
+    QMetaObject::Connection *const connection = new QMetaObject::Connection;
+    *connection = QObject::connect(sender, signal, slot);
+    QMetaObject::Connection *const disconnectConnection = new QMetaObject::Connection;
+    *disconnectConnection = QObject::connect(sender, signal, [connection, disconnectConnection] {
+        if (connection) {
+            QObject::disconnect(*connection);
+            delete connection;
+        }
+        if (disconnectConnection) {
+            QObject::disconnect(*disconnectConnection);
+            delete disconnectConnection;
+        }
+    });
+}
+
+template<typename Func1, typename Func2>
+void
+oneShotConnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender,
+               Func1 signal,
+               const typename QtPrivate::FunctionPointer<Func2>::Object *receiver,
+               Func2 slot)
+{
+    QMetaObject::Connection *const connection = new QMetaObject::Connection;
+    *connection = QObject::connect(sender, signal, receiver, slot);
+    QMetaObject::Connection *const disconnectConnection = new QMetaObject::Connection;
+    *disconnectConnection = QObject::connect(sender, signal, [connection, disconnectConnection] {
+        if (connection) {
+            QObject::disconnect(*connection);
+            delete connection;
+        }
+        if (disconnectConnection) {
+            QObject::disconnect(*disconnectConnection);
+            delete disconnectConnection;
+        }
+    });
+}
+
+class OneShotConnection final : public QObject
+{
+    Q_OBJECT
+public:
+    explicit OneShotConnection(const QObject *sender,
+                               const char *signal,
+                               QMetaObject::Connection *connection,
+                               QObject *parent = nullptr)
+        : QObject(parent)
+    {
+        connection_ = connection;
+        disconnectConnection_ = new QMetaObject::Connection;
+        *disconnectConnection_ = QObject::connect(sender,
+                                                  signal,
+                                                  this,
+                                                  SLOT(onTriggered()));
+    }
+    ~OneShotConnection() = default;
+
+public slots:
+    void
+    onTriggered()
+    {
+        if (connection_) {
+            QObject::disconnect(*connection_);
+            delete connection_;
+        }
+        if (disconnectConnection_) {
+            QObject::disconnect(*disconnectConnection_);
+            delete disconnectConnection_;
+        }
+        deleteLater();
+    }
+
+private:
+    QMetaObject::Connection *connection_;
+    QMetaObject::Connection *disconnectConnection_;
+
+};
+
+inline void
+oneShotConnect(const QObject *sender, const char *signal, const QObject *receiver, const char *slot)
+{
+    QMetaObject::Connection *const connection = new QMetaObject::Connection;
+    *connection = QObject::connect(sender, signal, receiver, slot);
+     new OneShotConnection(sender, signal, connection);
+}
+
+}
diff --git a/src/settingsview/components/AdvancedSIPSettingsView.qml b/src/settingsview/components/AdvancedSIPSettingsView.qml
index 89d1fe8b6d05c9fd7fcc9db64ae51334835215ca..f499fe3e6655f9c15996630ed9529c343d2d1985 100644
--- a/src/settingsview/components/AdvancedSIPSettingsView.qml
+++ b/src/settingsview/components/AdvancedSIPSettingsView.qml
@@ -48,9 +48,9 @@ ColumnLayout {
         enableSDESToggle.enabled = SettingsAdapter.getAccountConfig_SRTP_Enabled()
         fallbackRTPToggle.enabled = SettingsAdapter.getAccountConfig_SRTP_Enabled()
 
-        btnSIPCACert.text = ClientWrapper.utilsAdaptor.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_TLS_CertificateListFile())
-        btnSIPUserCert.text = ClientWrapper.utilsAdaptor.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_TLS_CertificateFile())
-        btnSIPPrivateKey.text = ClientWrapper.utilsAdaptor.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_TLS_PrivateKeyFile())
+        btnSIPCACert.text = UtilsAdapter.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_TLS_CertificateListFile())
+        btnSIPUserCert.text = UtilsAdapter.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_TLS_CertificateFile())
+        btnSIPPrivateKey.text = UtilsAdapter.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_TLS_PrivateKeyFile())
         lineEditSIPCertPassword.text = SettingsAdapter.getAccountConfig_TLS_Password()
 
         encryptMediaStreamsToggle.checked = SettingsAdapter.getAccountConfig_SRTP_Enabled()
@@ -96,7 +96,7 @@ ColumnLayout {
         updateAudioCodecs()
         updateVideoCodecs()
         btnRingtoneSIP.enabled = SettingsAdapter.getAccountConfig_Ringtone_RingtoneEnabled()
-        btnRingtoneSIP.text = ClientWrapper.utilsAdaptor.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_Ringtone_RingtonePath())
+        btnRingtoneSIP.text = UtilsAdapter.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_Ringtone_RingtonePath())
         lineEditSTUNAddressSIP.enabled = SettingsAdapter.getAccountConfig_STUN_Enabled()
 
         // SDP session negotiation ports
@@ -196,7 +196,7 @@ ColumnLayout {
     function changeRingtonePath(url){
         if(url.length !== 0) {
            SettingsAdapter.set_RingtonePath(url)
-            btnRingtoneSIP.text = ClientWrapper.utilsAdaptor.toFileInfoName(url)
+            btnRingtoneSIP.text = UtilsAdapter.toFileInfoName(url)
         } else if (ClientWrapper.SettingsAdapter.getAccountConfig_Ringtone_RingtonePath().length === 0){
             btnRingtoneSIP.text = qsTr("Add a custom ringtone")
         }
@@ -205,21 +205,21 @@ ColumnLayout {
     function changeFileCACert(url){
         if(url.length !== 0) {
            SettingsAdapter.set_FileCACert(url)
-            btnSIPCACert.text = ClientWrapper.utilsAdaptor.toFileInfoName(url)
+            btnSIPCACert.text = UtilsAdapter.toFileInfoName(url)
         }
     }
 
     function changeFileUserCert(url){
         if(url.length !== 0) {
            SettingsAdapter.set_FileUserCert(url)
-            btnSIPUserCert.text = ClientWrapper.utilsAdaptor.toFileInfoName(url)
+            btnSIPUserCert.text = UtilsAdapter.toFileInfoName(url)
         }
     }
 
     function changeFilePrivateKey(url){
         if(url.length !== 0) {
            SettingsAdapter.set_FilePrivateKey(url)
-            btnSIPPrivateKey.text = ClientWrapper.utilsAdaptor.toFileInfoName(url)
+            btnSIPPrivateKey.text = UtilsAdapter.toFileInfoName(url)
         }
     }
 
@@ -227,7 +227,7 @@ ColumnLayout {
         id: ringtonePath_Dialog_SIP
 
         property string oldPath : SettingsAdapter.getAccountConfig_Ringtone_RingtonePath()
-        property string openPath : oldPath === "" ? (ClientWrapper.utilsAdaptor.getCurrentPath() + "/ringtones/") : (ClientWrapper.utilsAdaptor.toFileAbsolutepath(oldPath))
+        property string openPath : oldPath === "" ? (UtilsAdapter.getCurrentPath() + "/ringtones/") : (UtilsAdapter.toFileAbsolutepath(oldPath))
 
         mode: JamiFileDialog.OpenFile
         title: qsTr("Select a new ringtone")
@@ -237,7 +237,7 @@ ColumnLayout {
                 "All files") + " (*)"]
 
         onAccepted: {
-            var url = ClientWrapper.utilsAdaptor.getAbsPath(file.toString())
+            var url = UtilsAdapter.getAbsPath(file.toString())
             changeRingtonePath(url)
         }
     }
@@ -246,7 +246,7 @@ ColumnLayout {
         id: caCert_Dialog_SIP
 
         property string oldPath : SettingsAdapter.getAccountConfig_TLS_CertificateListFile()
-        property string openPath : oldPath === "" ? (ClientWrapper.utilsAdaptor.getCurrentPath() + "/ringtones/") : (ClientWrapper.utilsAdaptor.toFileAbsolutepath(oldPath))
+        property string openPath : oldPath === "" ? (UtilsAdapter.getCurrentPath() + "/ringtones/") : (UtilsAdapter.toFileAbsolutepath(oldPath))
 
         mode: JamiFileDialog.OpenFile
         title: qsTr("Select a CA certificate")
@@ -255,7 +255,7 @@ ColumnLayout {
                 "All files") + " (*)"]
 
         onAccepted: {
-            var url = ClientWrapper.utilsAdaptor.getAbsPath(file.toString())
+            var url = UtilsAdapter.getAbsPath(file.toString())
             changeFileCACert(url)
         }
     }
@@ -264,7 +264,7 @@ ColumnLayout {
         id: userCert_Dialog_SIP
 
         property string oldPath : SettingsAdapter.getAccountConfig_TLS_CertificateFile()
-        property string openPath : oldPath === "" ? (ClientWrapper.utilsAdaptor.getCurrentPath() + "/ringtones/") : (ClientWrapper.utilsAdaptor.toFileAbsolutepath(oldPath))
+        property string openPath : oldPath === "" ? (UtilsAdapter.getCurrentPath() + "/ringtones/") : (UtilsAdapter.toFileAbsolutepath(oldPath))
 
         mode: JamiFileDialog.OpenFile
         title: qsTr("Select a user certificate")
@@ -273,7 +273,7 @@ ColumnLayout {
                 "All files") + " (*)"]
 
         onAccepted: {
-            var url = ClientWrapper.utilsAdaptor.getAbsPath(file.toString())
+            var url = UtilsAdapter.getAbsPath(file.toString())
             changeFileUserCert(url)
         }
     }
@@ -282,7 +282,7 @@ ColumnLayout {
         id: privateKey_Dialog_SIP
 
         property string oldPath : SettingsAdapter.getAccountConfig_TLS_PrivateKeyFile()
-        property string openPath : oldPath === "" ? (ClientWrapper.utilsAdaptor.getCurrentPath() + "/ringtones/") : (ClientWrapper.utilsAdaptor.toFileAbsolutepath(oldPath))
+        property string openPath : oldPath === "" ? (UtilsAdapter.getCurrentPath() + "/ringtones/") : (UtilsAdapter.toFileAbsolutepath(oldPath))
 
         mode: JamiFileDialog.OpenFile
         title: qsTr("Select a private key")
@@ -291,7 +291,7 @@ ColumnLayout {
                 "All files") + " (*)"]
 
         onAccepted: {
-            var url = ClientWrapper.utilsAdaptor.getAbsPath(file.toString())
+            var url = UtilsAdapter.getAbsPath(file.toString())
             changeFilePrivateKey(url)
         }
     }
diff --git a/src/settingsview/components/AdvancedSettingsView.qml b/src/settingsview/components/AdvancedSettingsView.qml
index 8c634ff1ccb95571c1e411ee7c0e7fd9b8bcda3a..a969b9f3797500100053b881985da1bda65f2f1b 100644
--- a/src/settingsview/components/AdvancedSettingsView.qml
+++ b/src/settingsview/components/AdvancedSettingsView.qml
@@ -52,9 +52,9 @@ ColumnLayout {
         lineEditBootstrap.text = SettingsAdapter.getAccountConfig_Hostname()
 
         // Security
-        btnCACert.text = ClientWrapper.utilsAdaptor.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_TLS_CertificateListFile())
-        btnUserCert.text = ClientWrapper.utilsAdaptor.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_TLS_CertificateFile())
-        btnPrivateKey.text = ClientWrapper.utilsAdaptor.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_TLS_PrivateKeyFile())
+        btnCACert.text = UtilsAdapter.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_TLS_CertificateListFile())
+        btnUserCert.text = UtilsAdapter.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_TLS_CertificateFile())
+        btnPrivateKey.text = UtilsAdapter.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_TLS_PrivateKeyFile())
 
         // Connectivity
         checkBoxUPnP.checked = SettingsAdapter.getAccountConfig_UpnpEnabled()
@@ -70,7 +70,7 @@ ColumnLayout {
         updateAudioCodecs();
         updateVideoCodecs();
         btnRingtone.enabled = SettingsAdapter.getAccountConfig_Ringtone_RingtoneEnabled()
-        btnRingtone.text = ClientWrapper.utilsAdaptor.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_Ringtone_RingtonePath())
+        btnRingtone.text = UtilsAdapter.toFileInfoName(ClientWrapper.SettingsAdapter.getAccountConfig_Ringtone_RingtonePath())
         lineEditProxy.enabled = SettingsAdapter.getAccountConfig_ProxyEnabled()
         lineEditSTUNAddress.enabled = SettingsAdapter.getAccountConfig_STUN_Enabled()
     }
@@ -128,7 +128,7 @@ ColumnLayout {
     function changeRingtonePath(url){
         if(url.length !== 0) {
            SettingsAdapter.set_RingtonePath(url)
-            btnRingtone.text = ClientWrapper.utilsAdaptor.toFileInfoName(url)
+            btnRingtone.text = UtilsAdapter.toFileInfoName(url)
         } else if (ClientWrapper.SettingsAdapter.getAccountConfig_Ringtone_RingtonePath().length === 0){
             btnRingtone.text = qsTr("Add a custom ringtone")
         }
@@ -137,21 +137,21 @@ ColumnLayout {
     function changeFileCACert(url){
         if(url.length !== 0) {
            SettingsAdapter.set_FileCACert(url)
-            btnCACert.text = ClientWrapper.utilsAdaptor.toFileInfoName(url)
+            btnCACert.text = UtilsAdapter.toFileInfoName(url)
         }
     }
 
     function changeFileUserCert(url){
         if(url.length !== 0) {
            SettingsAdapter.set_FileUserCert(url)
-            btnUserCert.text = ClientWrapper.utilsAdaptor.toFileInfoName(url)
+            btnUserCert.text = UtilsAdapter.toFileInfoName(url)
         }
     }
 
     function changeFilePrivateKey(url){
         if(url.length !== 0) {
            SettingsAdapter.set_FilePrivateKey(url)
-            btnPrivateKey.text = ClientWrapper.utilsAdaptor.toFileInfoName(url)
+            btnPrivateKey.text = UtilsAdapter.toFileInfoName(url)
         }
     }
 
@@ -159,7 +159,7 @@ ColumnLayout {
         id: ringtonePath_Dialog
 
         property string oldPath : SettingsAdapter.getAccountConfig_Ringtone_RingtonePath()
-        property string openPath : oldPath === "" ? (ClientWrapper.utilsAdaptor.getCurrentPath() + "/ringtones/") : (ClientWrapper.utilsAdaptor.toFileAbsolutepath(oldPath))
+        property string openPath : oldPath === "" ? (UtilsAdapter.getCurrentPath() + "/ringtones/") : (UtilsAdapter.toFileAbsolutepath(oldPath))
 
         mode: JamiFileDialog.OpenFile
         title: qsTr("Select a new ringtone")
@@ -169,7 +169,7 @@ ColumnLayout {
                 "All files") + " (*)"]
 
         onAccepted: {
-            var url = ClientWrapper.utilsAdaptor.getAbsPath(file.toString())
+            var url = UtilsAdapter.getAbsPath(file.toString())
             changeRingtonePath(url)
         }
     }
@@ -178,7 +178,7 @@ ColumnLayout {
         id: caCert_Dialog
 
         property string oldPath : SettingsAdapter.getAccountConfig_TLS_CertificateListFile()
-        property string openPath : oldPath === "" ? (ClientWrapper.utilsAdaptor.getCurrentPath() + "/ringtones/") : (ClientWrapper.utilsAdaptor.toFileAbsolutepath(oldPath))
+        property string openPath : oldPath === "" ? (UtilsAdapter.getCurrentPath() + "/ringtones/") : (UtilsAdapter.toFileAbsolutepath(oldPath))
 
         mode: JamiFileDialog.OpenFile
         title: qsTr("Select a CA certificate")
@@ -187,7 +187,7 @@ ColumnLayout {
                 "All files") + " (*)"]
 
         onAccepted: {
-            var url = ClientWrapper.utilsAdaptor.getAbsPath(file.toString())
+            var url = UtilsAdapter.getAbsPath(file.toString())
             changeFileCACert(url)
         }
     }
@@ -196,7 +196,7 @@ ColumnLayout {
         id: userCert_Dialog
 
         property string oldPath : SettingsAdapter.getAccountConfig_TLS_CertificateFile()
-        property string openPath : oldPath === "" ? (ClientWrapper.utilsAdaptor.getCurrentPath() + "/ringtones/") : (ClientWrapper.utilsAdaptor.toFileAbsolutepath(oldPath))
+        property string openPath : oldPath === "" ? (UtilsAdapter.getCurrentPath() + "/ringtones/") : (UtilsAdapter.toFileAbsolutepath(oldPath))
 
         mode: JamiFileDialog.OpenFile
         title: qsTr("Select a user certificate")
@@ -205,7 +205,7 @@ ColumnLayout {
                 "All files") + " (*)"]
 
         onAccepted: {
-            var url = ClientWrapper.utilsAdaptor.getAbsPath(file.toString())
+            var url = UtilsAdapter.getAbsPath(file.toString())
             changeFileUserCert(url)
         }
     }
@@ -216,7 +216,7 @@ ColumnLayout {
         property string oldPath : {
             return ClientWrapper.SettingsAdapter.getAccountConfig_TLS_PrivateKeyFile()
         }
-        property string openPath : oldPath === "" ? (ClientWrapper.utilsAdaptor.getCurrentPath() + "/ringtones/") : (ClientWrapper.utilsAdaptor.toFileAbsolutepath(oldPath))
+        property string openPath : oldPath === "" ? (UtilsAdapter.getCurrentPath() + "/ringtones/") : (UtilsAdapter.toFileAbsolutepath(oldPath))
 
         mode: JamiFileDialog.OpenFile
         title: qsTr("Select a private key")
@@ -225,7 +225,7 @@ ColumnLayout {
                 "All files") + " (*)"]
 
         onAccepted: {
-            var url = ClientWrapper.utilsAdaptor.getAbsPath(file.toString())
+            var url = UtilsAdapter.getAbsPath(file.toString())
             changeFilePrivateKey(url)
         }
     }
diff --git a/src/settingsview/components/CurrentAccountSettingsScrollPage.qml b/src/settingsview/components/CurrentAccountSettingsScrollPage.qml
index ba555342c6bab5f423b145dc243cbfc27aeb74fd..8a945b0654ae4f2033b24108ec6723d8a100364c 100644
--- a/src/settingsview/components/CurrentAccountSettingsScrollPage.qml
+++ b/src/settingsview/components/CurrentAccountSettingsScrollPage.qml
@@ -146,7 +146,7 @@ Rectangle {
     }
 
     function setAccEnableSlot(state) {
-        ClientWrapper.accountModel.setAccountEnabled(ClientWrapper.utilsAdaptor.getCurrAccId(), state)
+        ClientWrapper.accountModel.setAccountEnabled(UtilsAdapter.getCurrAccId(), state)
     }
 
     // JamiFileDialog for exporting account
@@ -163,13 +163,13 @@ Rectangle {
 
         onAccepted: {
             // is there password? If so, go to password dialog, else, go to following directly
-            var exportPath = ClientWrapper.utilsAdaptor.getAbsPath(file.toString())
+            var exportPath = UtilsAdapter.getAbsPath(file.toString())
             if (ClientWrapper.accountAdaptor.hasPassword()) {
                 passwordDialog.openDialog(PasswordDialog.ExportAccount,exportPath)
                 return
             } else {
                 if (exportPath.length > 0) {
-                    var isSuccessful = ClientWrapper.accountModel.exportToFile(ClientWrapper.utilsAdaptor.getCurrAccId(), exportPath,"")
+                    var isSuccessful = ClientWrapper.accountModel.exportToFile(UtilsAdapter.getCurrAccId(), exportPath,"")
                     var title = isSuccessful ? qsTr("Success") : qsTr("Error")
                     var iconMode = isSuccessful ? StandardIcon.Information : StandardIcon.Critical
                     var info = isSuccessful ? qsTr("Export Successful") : qsTr("Export Failed")
@@ -231,7 +231,7 @@ Rectangle {
         onAccepted: {
             ClientWrapper.accountAdaptor.setSelectedConvId()
 
-            if(ClientWrapper.utilsAdaptor.getAccountListSize() > 0){
+            if(UtilsAdapter.getAccountListSize() > 0){
                 navigateToMainView()
             } else {
                 navigateToNewWizardView()
diff --git a/src/settingsview/components/CurrentSIPAccountSettingScrollPage.qml b/src/settingsview/components/CurrentSIPAccountSettingScrollPage.qml
index 2f1e7b460dcbe262664a1d0334a60b439d3a1f6c..6896893e9bb032ab73983a75059d0fa6beb28761 100644
--- a/src/settingsview/components/CurrentSIPAccountSettingScrollPage.qml
+++ b/src/settingsview/components/CurrentSIPAccountSettingScrollPage.qml
@@ -67,7 +67,7 @@ Rectangle {
 
     // slots
     function setAccEnableSlot(state) {
-        ClientWrapper.accountModel.setAccountEnabled(ClientWrapper.utilsAdaptor.getCurrAccId(), state)
+        ClientWrapper.accountModel.setAccountEnabled(UtilsAdapter.getCurrAccId(), state)
     }
 
     function delAccountSlot() {
@@ -82,7 +82,7 @@ Rectangle {
         onAccepted: {
             ClientWrapper.accountAdaptor.setSelectedConvId()
 
-            if(ClientWrapper.utilsAdaptor.getAccountListSize() > 0){
+            if(UtilsAdapter.getAccountListSize() > 0){
                 navigateToMainView()
             } else {
                 navigateToNewWizardView()
diff --git a/src/settingsview/components/DeviceItemDelegate.qml b/src/settingsview/components/DeviceItemDelegate.qml
index 4bbb1c1216fb1eb2a58ef70fc1716e1a7a38099f..26311837aaffdfd49e9f6b0ef861fe9539244868 100644
--- a/src/settingsview/components/DeviceItemDelegate.qml
+++ b/src/settingsview/components/DeviceItemDelegate.qml
@@ -24,6 +24,7 @@ import QtQuick.Layouts 1.3
 import QtGraphicalEffects 1.14
 import QtQuick.Controls.Styles 1.4
 import net.jami.Models 1.0
+import net.jami.Adapters 1.0
 
 import "../../commoncomponents"
 
diff --git a/src/settingsview/components/GeneralSettingsPage.qml b/src/settingsview/components/GeneralSettingsPage.qml
index a0409c4457ac1897417b7c55ba27739f8827b89a..48e6558ab6b7c88b47782641d7764e6d0d08eece 100644
--- a/src/settingsview/components/GeneralSettingsPage.qml
+++ b/src/settingsview/components/GeneralSettingsPage.qml
@@ -34,12 +34,12 @@ Rectangle {
     function populateGeneralSettings(){
         // settings
         closeOrMinCheckBox.checked = SettingsAdapter.getAppValue(Settings.MinimizeOnClose)
-        applicationOnStartUpCheckBox.checked = ClientWrapper.utilsAdaptor.checkStartupLink()
+        applicationOnStartUpCheckBox.checked = UtilsAdapter.checkStartupLink()
         notificationCheckBox.checked = SettingsAdapter.getAppValue(Settings.EnableNotifications)
 
         alwaysRecordingCheckBox.checked = ClientWrapper.avmodel.getAlwaysRecord()
         recordPreviewCheckBox.checked = ClientWrapper.avmodel.getRecordPreview()
-        recordQualityValueLabel.text = ClientWrapper.utilsAdaptor.getRecordQualityString(ClientWrapper.avmodel.getRecordQuality() / 100)
+        recordQualityValueLabel.text = UtilsAdapter.getRecordQualityString(ClientWrapper.avmodel.getRecordQuality() / 100)
         recordQualitySlider.value = ClientWrapper.avmodel.getRecordQuality() / 100
 
         ClientWrapper.avmodel.setRecordPath(ClientWrapper.SettingsAdapter.getDir_Document())
@@ -72,7 +72,7 @@ Rectangle {
     }
 
     function slotRecordQualitySliderValueChanged(value){
-        recordQualityValueLabel.text = ClientWrapper.utilsAdaptor.getRecordQualityString(value)
+        recordQualityValueLabel.text = UtilsAdapter.getRecordQualityString(value)
         updateRecordQualityTimer.restart()
     }
 
@@ -102,7 +102,7 @@ Rectangle {
         currentFolder: StandardPaths.writableLocation(StandardPaths.DownloadLocation)
 
         onAccepted: {
-            var dir = ClientWrapper.utilsAdaptor.getAbsPath(folder.toString())
+            var dir = UtilsAdapter.getAbsPath(folder.toString())
             downloadPath = dir
         }
     }
@@ -118,7 +118,7 @@ Rectangle {
         currentFolder: StandardPaths.writableLocation(StandardPaths.HomeLocation)
 
         onAccepted: {
-            var dir = ClientWrapper.utilsAdaptor.getAbsPath(folder.toString())
+            var dir = UtilsAdapter.getAbsPath(folder.toString())
             recordPath = dir
         }
     }
diff --git a/src/settingsview/components/LinkDeviceDialog.qml b/src/settingsview/components/LinkDeviceDialog.qml
index 5741ac3260de170735758249e78aa3358b5a178e..a2e40a90c9037d68e7194c5f1dd5c3d33e5cc620 100644
--- a/src/settingsview/components/LinkDeviceDialog.qml
+++ b/src/settingsview/components/LinkDeviceDialog.qml
@@ -50,8 +50,8 @@ Dialog {
         timerForExport.restart()
     }
 
-    function slotExportOnRing() {
-        ClientWrapper.accountModel.exportOnRing(ClientWrapper.utilsAdaptor.getCurrAccId(),passwordEdit.text)
+    function slotExportOnRing(){
+        ClientWrapper.accountModel.exportOnRing(UtilsAdapter.getCurrAccId(),passwordEdit.text)
     }
 
     Timer{
diff --git a/src/settingsview/components/NameRegistrationDialog.qml b/src/settingsview/components/NameRegistrationDialog.qml
index 0e5b220f2cf01950e1f5fea873fb5cc59b4d8ec1..3fd188af224f32876ad401a850b07ccccbbc9e46 100644
--- a/src/settingsview/components/NameRegistrationDialog.qml
+++ b/src/settingsview/components/NameRegistrationDialog.qml
@@ -49,7 +49,7 @@ Dialog {
 
     function slotStartNameRegistration(){
         var password = passwordEdit.text
-        ClientWrapper.accountModel.registerName(ClientWrapper.utilsAdaptor.getCurrAccId(), password, registerdName)
+        ClientWrapper.accountModel.registerName(UtilsAdapter.getCurrAccId(), password, registerdName)
     }
 
     function startSpinner(){
diff --git a/src/settingsview/components/PluginListSettingsView.qml b/src/settingsview/components/PluginListSettingsView.qml
index 543b38bffec731e59f4403e86be636f730e254fd..a0edd1268b0583dfab7c101cf04e48316bc14e0f 100644
--- a/src/settingsview/components/PluginListSettingsView.qml
+++ b/src/settingsview/components/PluginListSettingsView.qml
@@ -77,7 +77,7 @@ Rectangle {
                 "All files") + " (*)"]
 
         onAccepted: {
-            var url = ClientWrapper.utilsAdaptor.getAbsPath(file.toString())
+            var url = UtilsAdapter.getAbsPath(file.toString())
             ClientWrapper.pluginModel.installPlugin(url, true)
         }
     }
diff --git a/src/smartlistmodel.cpp b/src/smartlistmodel.cpp
index db76a8748933c19319e349269b129e14775f4b06..b16d3a227d7ced89c3a0497ae5b2862f581a0d7b 100644
--- a/src/smartlistmodel.cpp
+++ b/src/smartlistmodel.cpp
@@ -294,14 +294,14 @@ SmartListModel::getConversationItemData(const conversation::Info &item,
     case Role::LastInteractionType: {
         if (!item.interactions.empty()) {
             return QVariant(
-                Utils::toUnderlyingValue(item.interactions.at(item.lastMessageUid).type));
+                static_cast<int>(item.interactions.at(item.lastMessageUid).type));
         }
         return QVariant(0);
     }
     case Role::ContactType: {
         if (!item.participants.isEmpty()) {
             auto &contact = contactModel->getContact(item.participants[0]);
-            return QVariant(Utils::toUnderlyingValue(contact.profileInfo.type));
+            return QVariant(static_cast<int>(contact.profileInfo.type));
         }
         return QVariant(0);
     }
@@ -397,7 +397,7 @@ Qt::ItemFlags
 SmartListModel::flags(const QModelIndex &index) const
 {
     auto flags = QAbstractItemModel::flags(index) | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable;
-    auto type = Utils::toEnum<lrc::api::profile::Type>(data(index, Role::ContactType).value<int>());
+    auto type = static_cast<lrc::api::profile::Type>(data(index, Role::ContactType).value<int>());
     auto uid = data(index, Role::UID).value<QString>();
     if (!index.isValid()) {
         return QAbstractItemModel::flags(index);
diff --git a/src/utils.cpp b/src/utils.cpp
index bf500554abe3ff3544efc3a5d4fce9dab9afbbc7..c2d63fb81570b86efbe20d74491dca9230b8d68c 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -22,20 +22,10 @@
 
 #include "utils.h"
 
-#ifdef Q_OS_WIN
-#include <lmcons.h>
-#include <shlguid.h>
-#include <shlobj.h>
-#include <shlwapi.h>
-#include <shobjidl.h>
-#include <windows.h>
-#endif
-
 #include "globalsystemtray.h"
 #include "jamiavatartheme.h"
 #include "lrcinstance.h"
 #include "pixbufmanipulator.h"
-#include "version.h"
 
 #include <globalinstances.h>
 #include <qrencode.h>
@@ -54,6 +44,15 @@
 #include <QTranslator>
 #include <QtConcurrent/QtConcurrent>
 
+#ifdef Q_OS_WIN
+#include <lmcons.h>
+#include <shlguid.h>
+#include <shlobj.h>
+#include <shlwapi.h>
+#include <shobjidl.h>
+#include <windows.h>
+#endif
+
 bool
 Utils::CreateStartupLink(const std::wstring& wstrAppName)
 {
@@ -246,24 +245,6 @@ Utils::GetISODate()
 #endif
 }
 
-void
-Utils::InvokeMailto(const QString& subject, const QString& body, const QString& attachement)
-{
-#ifdef Q_OS_WIN
-    HKEY hKey;
-    LONG lRes = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"mailto", 0, KEY_READ, &hKey);
-    if (lRes != ERROR_FILE_NOT_FOUND) {
-        auto addr = QString("mailto:?subject=%1&body=%2").arg(subject).arg(body);
-        if (not attachement.isEmpty())
-            addr += QString("&attachement=%1").arg(attachement);
-        ShellExecute(nullptr, L"open", addr.toStdWString().c_str(), NULL, NULL, SW_SHOWNORMAL);
-    } else {
-        QErrorMessage errorMessage;
-        errorMessage.showMessage(QObject::tr("No default mail client found"));
-    }
-#endif
-}
-
 QString
 Utils::getContactImageString(const QString& accountId, const QString& uid)
 {
@@ -300,16 +281,8 @@ Utils::getCirclePhoto(const QImage original, int sizePhoto)
 }
 
 void
-Utils::setStackWidget(QStackedWidget* stack, QWidget* widget)
-{
-    if (stack->indexOf(widget) != -1 && stack->currentWidget() != widget) {
-        stack->setCurrentWidget(widget);
-    }
-}
-
-void
-Utils::showSystemNotification(QWidget* widget,
-                              const QString& message,
+Utils::showSystemNotification(QWidget *widget,
+                              const QString &message,
                               long delay,
                               const QString& triggeredAccountId)
 {
@@ -373,13 +346,6 @@ Utils::forceDeleteAsync(const QString& path)
     });
 }
 
-UtilsAdapter&
-UtilsAdapter::instance()
-{
-    static auto instance = new UtilsAdapter;
-    return *instance;
-}
-
 QString
 Utils::getChangeLog()
 {
@@ -414,13 +380,13 @@ Utils::getProjectCredits()
             credits += "<h3 align=\"center\" style=\" margin-top:0px; "
                        + QString("margin-bottom:0px; margin-left:0px; margin-right:0px; ")
                        + "-qt-block-indent:0; text-indent:0px;\"><span style=\" font-weight:600;\">"
-                       + UtilsAdapter::tr("Created by:") + "</span></h3>";
+                       + QObject::tr("Created by:") + "</span></h3>";
         } else if (currentLine.contains("Marianne Forget")) {
             credits
                 += "<h3 align=\"center\" style=\" margin-top:0px; margin-bottom:0px; "
                    + QString(
                        "margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">")
-                   + "<span style=\" font-weight:600;\">" + UtilsAdapter::tr("Artwork by:")
+                   + "<span style=\" font-weight:600;\">" + QObject::tr("Artwork by:")
                    + "</span></h3>";
         }
         credits += currentLine;
@@ -428,7 +394,7 @@ Utils::getProjectCredits()
     credits += "<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; "
                + QString(
                    "margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">")
-               + UtilsAdapter::tr("Based on the SFLPhone project") + "</p>";
+               + QObject::tr("Based on the SFLPhone project") + "</p>";
 
     return credits;
 }
@@ -548,7 +514,8 @@ Utils::bestNameForConversation(const lrc::api::conversation::Info& conv,
 }
 
 /*
- * Returns empty string if only infoHash is available, second best identifier otherwise.
+ * Returns empty string if only infoHash is available,
+ * second best identifier otherwise.
  */
 QString
 Utils::secondBestNameForAccount(const lrc::api::account::Info& account)
@@ -557,23 +524,14 @@ Utils::secondBestNameForAccount(const lrc::api::account::Info& account)
     auto registeredName = removeEndlines(account.registeredName);
     auto infoHash = account.profileInfo.uri;
 
-    if (!alias.length() == 0) {
-        /*
-         * If alias exists.
-         */
-        if (!registeredName.length() == 0) {
-            /*
-             * If registeredName exists.
-             */
+    if (alias.length() != 0) {
+       if (registeredName.length() != 0) {
             return registeredName;
         } else {
             return infoHash;
         }
     } else {
-        if (!registeredName.length() == 0) {
-            /*
-             * If registeredName exists.
-             */
+        if (registeredName.length() != 0) {
             return infoHash;
         } else {
             return "";
@@ -593,6 +551,7 @@ Utils::profileType(const lrc::api::conversation::Info& conv,
     }
 }
 
+// TODO: use Qt for this
 std::string
 Utils::formatTimeString(const std::time_t& timestamp)
 {
@@ -673,7 +632,9 @@ Utils::getAvatarColor(const QString& canonicalUri)
  * color.
  */
 QImage
-Utils::fallbackAvatar(const QSize size, const QString& canonicalUriStr, const QString& letterStr)
+Utils::fallbackAvatar(const QString &canonicalUriStr,
+                      const QString &letterStr,
+                      const QSize &size)
 {
     /*
      * We start with a transparent avatar.
@@ -743,9 +704,13 @@ Utils::fallbackAvatar(const QSize size, const QString& canonicalUriStr, const QS
 }
 
 QImage
-Utils::fallbackAvatar(const QSize size, const std::string& alias, const std::string& uri)
+Utils::fallbackAvatar(const std::string &alias,
+                      const std::string &uri,
+                      const QSize &size)
 {
-    return fallbackAvatar(size, QString::fromStdString(uri), QString::fromStdString(alias));
+    return fallbackAvatar(QString::fromStdString(uri),
+                          QString::fromStdString(alias),
+                          size);
 }
 
 QByteArray
@@ -761,7 +726,6 @@ Utils::QImageToByteArray(QImage image)
 QImage
 Utils::cropImage(const QImage& img)
 {
-    QRect rect;
     auto w = img.width();
     auto h = img.height();
     if (w > h) {
@@ -784,17 +748,17 @@ Utils::pixmapFromSvg(const QString& svg_resource, const QSize& size)
 QImage
 Utils::setupQRCode(QString ringID, int margin)
 {
-    auto rcode = QRcode_encodeString(ringID.toStdString().c_str(),
+    auto qrcode = QRcode_encodeString(ringID.toStdString().c_str(),
                                      0,            // Let the version be decided by libqrencode
                                      QR_ECLEVEL_L, // Lowest level of error correction
                                      QR_MODE_8,    // 8-bit data mode
                                      1);
-    if (not rcode) {
-        qWarning() << "Failed to generate QR code: " << strerror(errno);
+    if (not qrcode) {
+        qWarning() << "Failed to generate QR code";
         return QImage();
     }
 
-    int qrwidth = rcode->width + margin * 2;
+    int qrwidth = qrcode->width + margin * 2;
     QImage result(QSize(qrwidth, qrwidth), QImage::Format_Mono);
     QPainter painter;
     painter.begin(&result);
@@ -802,33 +766,21 @@ Utils::setupQRCode(QString ringID, int margin)
     painter.setPen(QPen(Qt::black, 0.1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
     painter.setBrush(Qt::black);
     painter.fillRect(QRect(0, 0, qrwidth, qrwidth), Qt::white);
-    unsigned char* p;
-    p = rcode->data;
-    for (int y = 0; y < rcode->width; y++) {
-        unsigned char* row = (p + (y * rcode->width));
-        for (int x = 0; x < rcode->width; x++) {
+    unsigned char *p;
+    p = qrcode->data;
+    for (int y = 0; y < qrcode->width; y++) {
+        unsigned char *row = (p + (y * qrcode->width));
+        for (int x = 0; x < qrcode->width; x++) {
             if (*(row + x) & 0x1) {
                 painter.drawRect(margin + x, margin + y, 1, 1);
             }
         }
     }
     painter.end();
-    QRcode_free(rcode);
+    QRcode_free(qrcode);
     return result;
 }
 
-float
-Utils::getCurrentScalingRatio()
-{
-    return CURRENT_SCALING_RATIO;
-}
-
-void
-Utils::setCurrentScalingRatio(float ratio)
-{
-    CURRENT_SCALING_RATIO = ratio;
-}
-
 QString
 Utils::formattedTime(int duration)
 {
@@ -910,7 +862,7 @@ Utils::accountPhoto(const lrc::api::account::Info& accountInfo, const QSize& siz
         QString letterStr = bestId == bestName ? QString() : bestName;
         QString prefix = accountInfo.profileInfo.type == lrc::api::profile::Type::RING ? "ring:"
                                                                                        : "sip:";
-        photo = fallbackAvatar(size, prefix + accountInfo.profileInfo.uri, letterStr);
+        photo = fallbackAvatar(prefix + accountInfo.profileInfo.uri, letterStr, size);
     }
     return scaleAndFrame(photo, size);
 }
@@ -937,171 +889,7 @@ Utils::humanFileSize(qint64 fileSize)
     return QString::number(fileSizeF) + " " + units[unit_position];
 }
 
-const QString
-UtilsAdapter::getBestName(const QString& accountId, const QString& uid)
-{
-    auto* convModel = LRCInstance::getAccountInfo(accountId).conversationModel.get();
-    return Utils::bestNameForConversation(convModel->getConversationForUID(uid), *convModel);
-}
-
-const QString
-UtilsAdapter::getBestId(const QString& accountId, const QString& uid)
-{
-    auto* convModel = LRCInstance::getAccountInfo(accountId).conversationModel.get();
-    return Utils::bestIdForConversation(convModel->getConversationForUID(uid), *convModel);
-}
-
-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);
-        std::for_each(ringConversations.begin(),
-                      ringConversations.end(),
-                      [&totalUnreadMessages](const auto& 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);
-}
-
-void
-UtilsAdapter::clearConversationHistory(const QString& accountId, const QString& uid)
-{
-    LRCInstance::getAccountInfo(accountId).conversationModel->clearHistory(uid);
-}
-
-void
-UtilsAdapter::removeConversation(const QString& accountId, const QString& uid, bool banContact)
-{
-    LRCInstance::getAccountInfo(accountId).conversationModel->removeConversation(uid, banContact);
-}
-
-const QString
-UtilsAdapter::getCurrAccId()
-{
-    return LRCInstance::getCurrAccId();
-}
-
-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);
-    const auto convInfo = accInfo.conversationModel->getConversationForUID(convUid);
-    accInfo.callModel->setCurrentCall(convInfo.callId);
-}
-
-void
-UtilsAdapter::startPreviewing(bool force)
-{
-    LRCInstance::renderer()->startPreviewing(force);
-}
-
-void
-UtilsAdapter::stopPreviewing()
-{
-    if (!LRCInstance::hasVideoCall()) {
-        LRCInstance::renderer()->stopPreviewing();
-    }
-}
-
-bool
-UtilsAdapter::hasVideoCall()
-{
-    return LRCInstance::hasVideoCall();
-}
-
-const QString
-UtilsAdapter::getCallId(const QString& accountId, const QString& convUid)
-{
-    auto& accInfo = LRCInstance::getAccountInfo(accountId);
-    const auto convInfo = accInfo.conversationModel->getConversationForUID(convUid);
-
-    if (convInfo.uid.isEmpty()) {
-        return "";
-    }
-
-    auto call = LRCInstance::getCallInfoForConversation(convInfo, false);
-    if (!call) {
-        return "";
-    }
-
-    return call->id;
-}
-
-const QString
-UtilsAdapter::getCallStatusStr(int statusInt)
-{
-    const auto status = static_cast<lrc::api::call::Status>(statusInt);
-    return lrc::api::call::to_string(status);
-}
-
-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();
-}
-
-bool
-UtilsAdapter::checkShowPluginsButton()
-{
-    return LRCInstance::pluginModel().getPluginsEnabled()
-           && (LRCInstance::pluginModel().listLoadedPlugins().size() > 0);
-}
-
-bool
-UtilsAdapter::isImage(const QString& fileExt) const
+bool Utils::isImage(const QString &fileExt)
 {
     if (fileExt == "png" || fileExt == "jpg" || fileExt == "jpeg")
         return true;
diff --git a/src/utils.h b/src/utils.h
index f99a1ff4766bc1667a03e139033d7c99dbc1557f..e4cba7cdc774ebb543eb512e73aad7bf9fd5a543 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -22,14 +22,9 @@
 
 #pragma once
 
-#include "version.h"
-
-#include <string>
-
-#include <QClipboard>
 #include <QCryptographicHash>
 #include <QDir>
-#include <QApplication>
+
 #include <QImage>
 #include <QItemDelegate>
 #include <QLabel>
@@ -42,7 +37,8 @@
 #include <QString>
 #include <QTextDocument>
 #include <QtGlobal>
-#include <QPainterPath>
+
+#include <string>
 
 #ifdef Q_OS_WIN
 #include <ciso646>
@@ -57,35 +53,21 @@
 #include "api/contactmodel.h"
 #include "api/conversationmodel.h"
 
-static const QSize IMAGE_SIZE {128, 128};
-static float CURRENT_SCALING_RATIO {1.0};
-
-#ifdef BETA
-static constexpr bool isBeta = true;
-#else
-static constexpr bool isBeta = false;
-#endif
-
 namespace Utils {
 
 /*
- * System.
+ * App/System
  */
 bool CreateStartupLink(const std::wstring& wstrAppName);
 void DeleteStartupLink(const std::wstring& wstrAppName);
 bool CreateLink(LPCWSTR lpszPathObj, LPCWSTR lpszPathLink);
-bool CheckStartupLink(const std::wstring& wstrAppName);
-void removeOldVersions();
-const char* WinGetEnv(const char* name);
+bool CheckStartupLink(const std::wstring &wstrAppName);
+const char *WinGetEnv(const char *name);
 QString GetRingtonePath();
 QString GenGUID();
 QString GetISODate();
-void InvokeMailto(const QString& subject,
-                  const QString& body,
-                  const QString& attachement = QString());
-void setStackWidget(QStackedWidget* stack, QWidget* widget);
-void showSystemNotification(QWidget* widget,
-                            const QString& message,
+void showSystemNotification(QWidget *widget,
+                            const QString &message,
                             long delay = 5000,
                             const QString& triggeredAccountId = "");
 void showSystemNotification(QWidget* widget,
@@ -97,389 +79,72 @@ QSize getRealSize(QScreen* screen);
 void forceDeleteAsync(const QString& path);
 QString getChangeLog();
 QString getProjectCredits();
-float getCurrentScalingRatio();
-void setCurrentScalingRatio(float ratio);
+void removeOldVersions();
 
 /*
- * Updates.
+ * Updates
  */
+#ifdef BETA
+static constexpr bool isBeta = true;
+#else
+static constexpr bool isBeta = false;
+#endif
 void cleanUpdateFiles();
 void checkForUpdates(bool withUI, QWidget* parent = nullptr);
 void applyUpdates(bool updateToBeta, QWidget* parent = nullptr);
 
 /*
- * Names.
- */
-QString bestIdForConversation(const lrc::api::conversation::Info& conv,
-                              const lrc::api::ConversationModel& model);
-QString bestIdForAccount(const lrc::api::account::Info& account);
-QString bestNameForAccount(const lrc::api::account::Info& account);
-QString bestIdForContact(const lrc::api::contact::Info& contact);
-QString bestNameForContact(const lrc::api::contact::Info& contact);
-QString bestNameForConversation(const lrc::api::conversation::Info& conv,
-                                const lrc::api::ConversationModel& model);
-/*
- * Returns empty string if only infoHash is available.
- */
-QString secondBestNameForAccount(const lrc::api::account::Info& account);
-lrc::api::profile::Type profileType(const lrc::api::conversation::Info& conv,
-                                    const lrc::api::ConversationModel& model);
-
-/*
- * Interactions.
+ * LRC helpers
  */
-std::string formatTimeString(const std::time_t& timestamp);
-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);
+QString bestIdForConversation(const lrc::api::conversation::Info &conv,
+                              const lrc::api::ConversationModel &model);
+QString bestIdForAccount(const lrc::api::account::Info &account);
+QString bestNameForAccount(const lrc::api::account::Info &account);
+QString bestIdForContact(const lrc::api::contact::Info &contact);
+QString bestNameForContact(const lrc::api::contact::Info &contact);
+QString bestNameForConversation(const lrc::api::conversation::Info &conv,
+                                const lrc::api::ConversationModel &model);
+QString secondBestNameForAccount(const lrc::api::account::Info &account);
+lrc::api::profile::Type profileType(const lrc::api::conversation::Info &conv,
+                                    const lrc::api::ConversationModel &model);
+std::string formatTimeString(const std::time_t &timestamp);
+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.
+ * Image manipulation
  */
-QString getContactImageString(const QString& accountId, const QString& uid);
+static const QSize defaultAvatarSize { 128, 128 };
+QString getContactImageString(const QString &accountId, const QString &uid);
 QImage getCirclePhoto(const QImage original, int sizePhoto);
 QImage conversationPhoto(const QString& convUid,
                          const lrc::api::account::Info& accountInfo,
                          bool filtered = false);
-QColor getAvatarColor(const QString& canonicalUri);
-QImage fallbackAvatar(const QSize size,
-                      const QString& canonicalUriStr,
-                      const QString& letterStr = QString());
-QImage fallbackAvatar(const QSize size, const std::string& alias, const std::string& uri);
+QColor getAvatarColor(const QString &canonicalUri);
+QImage fallbackAvatar(const QString &canonicalUriStr,
+                      const QString &letterStr = QString(),
+                      const QSize &size = defaultAvatarSize);
+QImage fallbackAvatar(const std::string &alias,
+                      const std::string &uri,
+                      const QSize &size = defaultAvatarSize);
 QByteArray QImageToByteArray(QImage image);
-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 = IMAGE_SIZE);
-QImage accountPhoto(const lrc::api::account::Info& accountInfo, const QSize& size = IMAGE_SIZE);
-QImage cropImage(const QImage& img);
-QPixmap pixmapFromSvg(const QString& svg_resource, const QSize& size);
+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, const QSize &size = defaultAvatarSize);
+QImage cropImage(const QImage &img);
+QPixmap pixmapFromSvg(const QString &svg_resource, const QSize &size);
 QImage setupQRCode(QString ringID, int margin);
+bool isImage(const QString& fileExt);
 
 /*
- * Rounded corner.
- */
-template<typename T>
-void
-fillRoundRectPath(QPainter& painter,
-                  const T& brushType,
-                  const QRect& rectToDraw,
-                  qreal cornerRadius,
-                  int xTransFormOffset = 0,
-                  int yTransFormOffset = 0)
-{
-    QBrush brush(brushType);
-    brush.setTransform(QTransform::fromTranslate(rectToDraw.x() + xTransFormOffset,
-                                                 rectToDraw.y() + yTransFormOffset));
-    QPainterPath painterPath;
-    painterPath.addRoundRect(rectToDraw, cornerRadius);
-    painter.fillPath(painterPath, brush);
-}
-
-/*
- * Time.
+ * Misc
  */
 QString formattedTime(int seconds);
-
-/*
- * Byte to human readable size.
- */
 QString humanFileSize(qint64 fileSize);
 
-/*
- * Device plug or unplug enum.
- */
-enum class DevicePlugStatus { Plugged, Unplugged, Unchanged };
-
-class OneShotDisconnectConnection : public QObject
-{
-    Q_OBJECT
-
-public:
-    explicit OneShotDisconnectConnection(const QObject* sender,
-                                         const char* signal,
-                                         QMetaObject::Connection* connection,
-                                         QObject* parent = nullptr)
-        : QObject(parent)
-    {
-        connection_ = connection;
-        disconnectConnection_ = new QMetaObject::Connection;
-        *disconnectConnection_ = QObject::connect(sender,
-                                                  signal,
-                                                  this,
-                                                  SLOT(slotOneShotDisconnectConnection()));
-    }
-    ~OneShotDisconnectConnection()
-    {
-        if (!connection_) {
-            delete connection_;
-        }
-        if (!disconnectConnection_) {
-            delete disconnectConnection_;
-        }
-        if (!this) {
-            delete this;
-        }
-    }
-
-public slots:
-    void slotOneShotDisconnectConnection()
-    {
-        if (connection_) {
-            QObject::disconnect(*connection_);
-            delete connection_;
-        }
-        if (disconnectConnection_) {
-            QObject::disconnect(*disconnectConnection_);
-            delete disconnectConnection_;
-        }
-        delete this;
-    }
-
-private:
-    QMetaObject::Connection* connection_;
-    QMetaObject::Connection* disconnectConnection_;
-};
-
-template<typename Func1, typename Func2>
-void
-oneShotConnect(const typename QtPrivate::FunctionPointer<Func1>::Object* sender,
-               Func1 signal,
-               Func2 slot)
-{
-    QMetaObject::Connection* const connection = new QMetaObject::Connection;
-    *connection = QObject::connect(sender, signal, slot);
-    QMetaObject::Connection* const disconnectConnection = new QMetaObject::Connection;
-    *disconnectConnection = QObject::connect(sender, signal, [connection, disconnectConnection] {
-        if (connection) {
-            QObject::disconnect(*connection);
-            delete connection;
-        }
-        if (disconnectConnection) {
-            QObject::disconnect(*disconnectConnection);
-            delete disconnectConnection;
-        }
-    });
-}
-
-template<typename Func1, typename Func2>
-void
-oneShotConnect(const typename QtPrivate::FunctionPointer<Func1>::Object* sender,
-               Func1 signal,
-               const typename QtPrivate::FunctionPointer<Func2>::Object* receiver,
-               Func2 slot)
-{
-    QMetaObject::Connection* const connection = new QMetaObject::Connection;
-    *connection = QObject::connect(sender, signal, receiver, slot);
-    QMetaObject::Connection* const disconnectConnection = new QMetaObject::Connection;
-    *disconnectConnection = QObject::connect(sender, signal, [connection, disconnectConnection] {
-        if (connection) {
-            QObject::disconnect(*connection);
-            delete connection;
-        }
-        if (disconnectConnection) {
-            QObject::disconnect(*disconnectConnection);
-            delete disconnectConnection;
-        }
-    });
-}
-
-inline void
-oneShotConnect(const QObject* sender, const char* signal, const QObject* receiver, const char* slot)
-{
-    QMetaObject::Connection* const connection = new QMetaObject::Connection;
-    *connection = QObject::connect(sender, signal, receiver, slot);
-    OneShotDisconnectConnection* disconnectConnection = new OneShotDisconnectConnection(sender,
-                                                                                        signal,
-                                                                                        connection);
-    Q_UNUSED(disconnectConnection)
-}
-
-template<class T>
-class Blocker
-{
-    T* blocked;
-    bool previous;
-
-public:
-    Blocker(T* blocked)
-        : blocked(blocked)
-        , previous(blocked->blockSignals(true))
-    {}
-    ~Blocker() { blocked->blockSignals(previous); }
-    T* operator->() { return blocked; }
-};
-
-template<class T>
-inline Blocker<T>
-whileBlocking(T* blocked)
-{
-    return Blocker<T>(blocked);
-}
-
-template<typename T>
-void
-setElidedText(T* object,
-              const QString& text,
-              Qt::TextElideMode mode = Qt::ElideMiddle,
-              int padding = 32)
-{
-    QFontMetrics metrics(object->font());
-    QString clippedText = metrics.elidedText(text, mode, object->width() - padding);
-    object->setText(clippedText);
-}
-
-template<typename E>
-constexpr inline
-    typename std::enable_if<std::is_enum<E>::value, typename std::underlying_type<E>::type>::type
-    toUnderlyingValue(E e) noexcept
-{
-    return static_cast<typename std::underlying_type<E>::type>(e);
-}
-
-template<typename E, typename T>
-constexpr inline
-    typename std::enable_if<std::is_enum<E>::value && std::is_integral<T>::value, E>::type
-    toEnum(T value) noexcept
-{
-    return static_cast<E>(value);
-}
 } // namespace Utils
 
-class UtilsAdapter : public QObject
-{
-    Q_OBJECT
-public:
-    explicit UtilsAdapter(QObject* parent = nullptr)
-        : QObject(parent)
-    {
-        clipboard_ = QApplication::clipboard();
-    }
-    ~UtilsAdapter() {}
-
-    /// Singleton
-    static UtilsAdapter& instance();
-
-    Q_INVOKABLE const QString getChangeLog() { return Utils::getChangeLog(); }
-
-    Q_INVOKABLE const QString getProjectCredits() { return Utils::getProjectCredits(); }
-
-    Q_INVOKABLE const QString getVersionStr() { return QString(VERSION_STRING); }
-
-    Q_INVOKABLE void setText(QString text) { clipboard_->setText(text, QClipboard::Clipboard); }
-
-    Q_INVOKABLE const QString qStringFromFile(const QString& filename)
-    {
-        return Utils::QByteArrayFromFile(filename);
-    }
-
-    Q_INVOKABLE const QString 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;
-    }
-
-    Q_INVOKABLE const QString getCachePath()
-    {
-        QDir dataDir(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
-        dataDir.cdUp();
-        return dataDir.absolutePath() + "/jami";
-    }
-    Q_INVOKABLE bool createStartupLink() { return Utils::CreateStartupLink(L"Jami"); }
-    Q_INVOKABLE QString GetRingtonePath() { return Utils::GetRingtonePath(); }
-    Q_INVOKABLE bool checkStartupLink() { return Utils::CheckStartupLink(L"Jami"); }
-
-    Q_INVOKABLE const QString getContactImageString(const QString& accountId, const QString& uid)
-    {
-        return Utils::getContactImageString(accountId, uid);
-    }
-
-    Q_INVOKABLE void removeConversation(const QString& accountId,
-                                        const QString& uid,
-                                        bool banContact = false);
-    Q_INVOKABLE void clearConversationHistory(const QString& accountId, const QString& uid);
-    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 getBestId(const QString& accountId, const QString& uid);
-
-    Q_INVOKABLE const QString getCurrAccId();
-    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 void startPreviewing(bool force);
-    Q_INVOKABLE void stopPreviewing();
-    Q_INVOKABLE bool hasVideoCall();
-    Q_INVOKABLE const QString getCallId(const QString& accountId, const QString& convUid);
-    Q_INVOKABLE const QString getCallStatusStr(int statusInt);
-    Q_INVOKABLE QString getStringUTF8(QString string);
-    Q_INVOKABLE QString getRecordQualityString(int value);
-    Q_INVOKABLE QString getCurrentPath();
-
-    Q_INVOKABLE QString toNativeSeparators(QString inputDir)
-    {
-        return QDir::toNativeSeparators(inputDir);
-    }
-
-    Q_INVOKABLE QString toFileInfoName(QString inputFileName)
-    {
-        QFileInfo fi(inputFileName);
-        return fi.fileName();
-    }
-
-    Q_INVOKABLE QString toFileAbsolutepath(QString inputFileName)
-    {
-        QFileInfo fi(inputFileName);
-        return fi.absolutePath();
-    }
-
-    Q_INVOKABLE QString getAbsPath(QString path)
-    {
-#ifdef Q_OS_WIN
-        return path.replace("file:///", "").replace("\n", "").replace("\r", "");
-#else
-        return path.replace("file:///", "/").replace("\n", "").replace("\r", "");
-#endif
-    }
-
-    Q_INVOKABLE QString getCroppedImageBase64FromFile(QString fileName, int size)
-    {
-        auto image = Utils::cropImage(QImage(fileName));
-        auto croppedImage = image.scaled(size,
-                                         size,
-                                         Qt::KeepAspectRatioByExpanding,
-                                         Qt::SmoothTransformation);
-        return QString::fromLatin1(Utils::QImageToByteArray(croppedImage).toBase64().data());
-    }
-
-    Q_INVOKABLE bool checkShowPluginsButton();
-
-    Q_INVOKABLE QString fileName(const QString& path)
-    {
-        QFileInfo fi(path);
-        return fi.fileName();
-    }
-
-    Q_INVOKABLE QString getExt(const QString& path)
-    {
-        QFileInfo fi(path);
-        return fi.completeSuffix();
-    }
-
-    Q_INVOKABLE bool isImage(const QString& fileExt) const;
 
-private:
-    QClipboard* clipboard_;
-};
-Q_DECLARE_METATYPE(UtilsAdapter*)
diff --git a/src/utilsadapter.cpp b/src/utilsadapter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..66d423a9097419bbc396257abdb82932ab921469
--- /dev/null
+++ b/src/utilsadapter.cpp
@@ -0,0 +1,357 @@
+/*
+ * 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 "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::getChangeLog()
+{
+    return Utils::getChangeLog();
+}
+
+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::getContactImageString(const QString &accountId, const QString &uid)
+{
+    return Utils::getContactImageString(accountId, uid);
+}
+
+const QString
+UtilsAdapter::getBestName(const QString &accountId, const QString &uid)
+{
+    auto* convModel = LRCInstance::getAccountInfo(accountId).conversationModel.get();
+    return Utils::bestNameForConversation(convModel->getConversationForUID(uid), *convModel);
+}
+
+const QString
+UtilsAdapter::getBestId(const QString &accountId, const QString &uid)
+{
+    auto* convModel = LRCInstance::getAccountInfo(accountId).conversationModel.get();
+    return Utils::bestIdForConversation(convModel->getConversationForUID(uid), *convModel);
+}
+
+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);
+        std::for_each(ringConversations.begin(),
+                      ringConversations.end(),
+                      [&totalUnreadMessages](const auto &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);
+}
+
+void
+UtilsAdapter::clearConversationHistory(const QString &accountId, const QString &uid)
+{
+    LRCInstance::getAccountInfo(accountId).conversationModel->clearHistory(uid);
+}
+
+void
+UtilsAdapter::removeConversation(const QString &accountId, const QString &uid, bool banContact)
+{
+    LRCInstance::getAccountInfo(accountId).conversationModel->removeConversation(uid, banContact);
+}
+
+const QString
+UtilsAdapter::getCurrAccId()
+{
+    return LRCInstance::getCurrAccId();
+}
+
+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);
+    const auto convInfo = accInfo.conversationModel->getConversationForUID(convUid);
+    accInfo.callModel->setCurrentCall(convInfo.callId);
+}
+
+void
+UtilsAdapter::startPreviewing(bool force)
+{
+    LRCInstance::renderer()->startPreviewing(force);
+}
+
+void
+UtilsAdapter::stopPreviewing()
+{
+    if (!LRCInstance::hasVideoCall()) {
+        LRCInstance::renderer()->stopPreviewing();
+    }
+}
+
+bool
+UtilsAdapter::hasVideoCall()
+{
+    return LRCInstance::hasVideoCall();
+}
+
+const QString
+UtilsAdapter::getCallId(const QString &accountId, const QString &convUid)
+{
+    auto &accInfo = LRCInstance::getAccountInfo(accountId);
+    const auto convInfo = accInfo.conversationModel->getConversationForUID(convUid);
+
+    if (convInfo.uid.isEmpty()) {
+        return "";
+    }
+
+    auto call = LRCInstance::getCallInfoForConversation(convInfo, false);
+    if (!call) {
+        return "";
+    }
+
+    return call->id;
+}
+
+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)
+{
+#ifdef Q_OS_WIN
+    return path.replace("file:///", "").replace("\n", "").replace("\r", "");
+#else
+    return path.replace("file:///", "/").replace("\n", "").replace("\r", "");
+#endif
+}
+
+QString
+UtilsAdapter::getCroppedImageBase64FromFile(QString fileName, int size)
+{
+    auto image = Utils::cropImage(QImage(fileName));
+    auto croppedImage = image.scaled(size,
+                                     size,
+                                     Qt::KeepAspectRatioByExpanding,
+                                     Qt::SmoothTransformation);
+    return QString::fromLatin1(Utils::QImageToByteArray(croppedImage).toBase64().data());
+}
+
+bool
+UtilsAdapter::checkShowPluginsButton()
+{
+    return LRCInstance::pluginModel().getPluginsEnabled()
+           && (LRCInstance::pluginModel().listLoadedPlugins().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);
+}
diff --git a/src/utilsadapter.h b/src/utilsadapter.h
new file mode 100644
index 0000000000000000000000000000000000000000..6704e43a7610bb262a1afb11d1e5fbf6601ec3e0
--- /dev/null
+++ b/src/utilsadapter.h
@@ -0,0 +1,91 @@
+/*
+ * 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 getChangeLog();
+    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 const QString getContactImageString(const QString &accountId,
+                                                    const QString &uid);
+    Q_INVOKABLE void removeConversation(const QString &accountId,
+                                        const QString &uid,
+                                        bool banContact = false);
+    Q_INVOKABLE void clearConversationHistory(const QString &accountId,
+                                              const QString &uid);
+    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 getBestId(const QString &accountId,
+                                        const QString &uid);
+    Q_INVOKABLE const QString getCurrAccId();
+    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 void startPreviewing(bool force);
+    Q_INVOKABLE void stopPreviewing();
+    Q_INVOKABLE bool hasVideoCall();
+    Q_INVOKABLE const QString getCallId(const QString &accountId, const QString &convUid);
+    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 QString getCroppedImageBase64FromFile(QString fileName, int size);
+    Q_INVOKABLE bool checkShowPluginsButton();
+    Q_INVOKABLE QString fileName(const QString& path);
+    Q_INVOKABLE QString getExt(const QString& path);
+    Q_INVOKABLE bool isImage(const QString& fileExt);
+
+private:
+    QClipboard *clipboard_;
+};
+Q_DECLARE_METATYPE(UtilsAdapter *)
diff --git a/src/wizardview/WizardView.qml b/src/wizardview/WizardView.qml
index 402ff355b520fa7b6a870a064c2f7db892aa5dbc..fbd98cb0c6f46cb7d97eed15e686a6a2b23f2149 100644
--- a/src/wizardview/WizardView.qml
+++ b/src/wizardview/WizardView.qml
@@ -237,7 +237,7 @@ Rectangle {
 
             onImportAccount: {
                 inputParaObject = {}
-                inputParaObject["archivePath"] = ClientWrapper.utilsAdaptor.getAbsPath(importFromBackupPage.filePath)
+                inputParaObject["archivePath"] = UtilsAdapter.getAbsPath(importFromBackupPage.filePath)
                 inputParaObject["password"] = importFromBackupPage.text_passwordFromBackupEditAlias
                 showBackUp = false
                 showBottom = false
@@ -258,14 +258,14 @@ Rectangle {
                 if (accepted) {
                     // is there password? If so, go to password dialog, else, go to following directly
                     if (ClientWrapper.accountAdaptor.hasPassword()) {
-                        passwordDialog.path = ClientWrapper.utilsAdaptor.getAbsPath(folderDir)
+                        passwordDialog.path = UtilsAdapter.getAbsPath(folderDir)
                         passwordDialog.open()
                         return
                     } else {
                         if (folderDir.length > 0) {
                             ClientWrapper.accountAdaptor.exportToFile(
-                                        ClientWrapper.utilsAdaptor.getCurrAccId(),
-                                        ClientWrapper.utilsAdaptor.getAbsPath(folderDir))
+                                        UtilsAdapter.getCurrAccId(),
+                                        UtilsAdapter.getAbsPath(folderDir))
                         }
                     }
                 }
diff --git a/src/wizardview/components/ImportFromBackupPage.qml b/src/wizardview/components/ImportFromBackupPage.qml
index 9d0907384aaeb68620f022e604f6e52ddd1e17e1..8f19ab5b61583e98f4b9924670e4f0ea78b4f7a8 100644
--- a/src/wizardview/components/ImportFromBackupPage.qml
+++ b/src/wizardview/components/ImportFromBackupPage.qml
@@ -63,7 +63,7 @@ Rectangle {
         onAccepted: {
             filePath = file
             if (file.length != 0) {
-                fileImportBtnText = ClientWrapper.utilsAdaptor.toFileInfoName(file)
+                fileImportBtnText = UtilsAdapter.toFileInfoName(file)
             } else {
                 fileImportBtnText = qsTr("Archive(none)")
             }
diff --git a/src/wizardview/components/WelcomePage.qml b/src/wizardview/components/WelcomePage.qml
index c15d66f97c0217ce51f0e56ef6365082494dfef6..542a6b13c2127dc01c3101e5e46537e735d61bf2 100644
--- a/src/wizardview/components/WelcomePage.qml
+++ b/src/wizardview/components/WelcomePage.qml
@@ -22,6 +22,7 @@ import QtQuick.Layouts 1.3
 import QtQuick.Controls 2.14
 import QtGraphicalEffects 1.15
 import net.jami.Models 1.0
+import net.jami.Adapters 1.0
 
 import "../../constant"
 import "../../commoncomponents"
@@ -212,14 +213,14 @@ Rectangle {
             target: ClientWrapper.lrcInstance
 
             function onAccountListChanged() {
-                backButton.visible = ClientWrapper.utilsAdaptor.getAccountListSize()
+                backButton.visible = UtilsAdapter.getAccountListSize()
             }
         }
 
         width: 35
         height: 35
 
-        visible: ClientWrapper.utilsAdaptor.getAccountListSize()
+        visible: UtilsAdapter.getAccountListSize()
         radius: 30
 
         backgroundColor: root.color