From 6f2ceb1273ea7b9ccd20da9ea81c2ec7f0c1e2f6 Mon Sep 17 00:00:00 2001
From: Hugo Lefeuvre <hugo.lefeuvre@savoirfairelinux.com>
Date: Wed, 18 Apr 2018 15:08:01 -0400
Subject: [PATCH] Refactoring of the accountContainer logic

Before:

 - RingMainWindow has an unique_ptr to an AccountContainer
   accountContainer_.

 - each view / secondary class has its own *copy* of the account
   container pointer (given by ringmainwindow using
   accountContainer_.get()).

 - each time the reference to the struct Info is updated,
   accountContainer_ has to be reset()-ed and and the account
   container re-created by the RingMainWindow. This makes *all*
   copies of the account container pointer invalid (hence all
   view / secondary classes trying to access the account container
   before getting updated perform use-after-free / NULL pointer
   dereference).

 - These copies have to be manually updated ! (well, currently they
   are not updated at all)

After:

 - RingMainWindow has a pointer to a struct Info from LRC.

 - Each view / secondary class has a pointer pointing to
   the struct Info pointer of RingMainWindow

 - Each time the reference to the struct Info is updated, the
   RingMainWindow updates its pointer. Since secondary classes and
   views hold a pointer to this pointer, they are automatically
   updated and there is no dangling pointer anymore.

This requires no lrc side changes.

Change-Id: I1329721920a3d42ad623f9fd7202b43700713eed
Reviewed-by: Sebastien Blin <sebastien.blin@savoirfairelinux.com>
Reviewed-by: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
---
 CMakeLists.txt                |  2 +-
 src/accountcontainer.h        | 37 -------------
 src/accountinfopointer.h      | 20 +++++++
 src/chatview.cpp              | 62 +++++++++++-----------
 src/chatview.h                |  5 +-
 src/conversationpopupmenu.cpp | 40 +++++++-------
 src/conversationpopupmenu.h   |  6 ++-
 src/conversationsview.cpp     | 51 +++++++++---------
 src/conversationsview.h       |  6 ++-
 src/currentcallview.cpp       | 48 ++++++++---------
 src/currentcallview.h         |  5 +-
 src/incomingcallview.cpp      | 26 +++++-----
 src/incomingcallview.h        |  5 +-
 src/ringmainwindow.cpp        | 98 +++++++++++++++++------------------
 src/ringwelcomeview.cpp       | 25 ++++-----
 src/ringwelcomeview.h         |  8 +--
 16 files changed, 219 insertions(+), 225 deletions(-)
 delete mode 100644 src/accountcontainer.h
 create mode 100644 src/accountinfopointer.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 76974f58..6d309c0e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -339,7 +339,7 @@ SET( SRC_FILES
    src/conversationsview.cpp
    src/conversationpopupmenu.h
    src/conversationpopupmenu.cpp
-   src/accountcontainer.h
+   src/accountinfopointer.h
 )
 
 # compile glib resource files to c code
diff --git a/src/accountcontainer.h b/src/accountcontainer.h
deleted file mode 100644
index 7daecaae..00000000
--- a/src/accountcontainer.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/****************************************************************************
- *   Copyright (C) 2017-2018 Savoir-faire Linux                                  *
- *   Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>             *
- *   Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>           *
- *                                                                          *
- *   This library is free software; you can redistribute it and/or          *
- *   modify it under the terms of the GNU Lesser General Public             *
- *   License as published by the Free Software Foundation; either           *
- *   version 2.1 of the License, or (at your option) any later version.     *
- *                                                                          *
- *   This library 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      *
- *   Lesser 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
-
-// Lrc
-#include <api/account.h>
-
-/**
- * This class contains a const reference linked to an account.
- * NOTE: it avoids weird initialization with Gtk
- * @param  accInfo the account linked
- */
-class AccountContainer {
-
-public:
-    explicit AccountContainer (const lrc::api::account::Info& accInfo)
-    : info(accInfo)
-    {}
-
-    const lrc::api::account::Info& info;
-};
diff --git a/src/accountinfopointer.h b/src/accountinfopointer.h
new file mode 100644
index 00000000..1375fff6
--- /dev/null
+++ b/src/accountinfopointer.h
@@ -0,0 +1,20 @@
+/*
+ *  Copyright (C) 2018 Savoir-faire Linux Inc.
+ *  Author: Hugo Lefeuvre <hugo.lefeuvre@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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+typedef const lrc::api::account::Info* AccountInfoPointer;
diff --git a/src/chatview.cpp b/src/chatview.cpp
index f30a64cb..d36e759e 100644
--- a/src/chatview.cpp
+++ b/src/chatview.cpp
@@ -63,7 +63,7 @@ struct _ChatViewPrivate
     GSettings *settings;
 
     lrc::api::conversation::Info* conversation_;
-    AccountContainer* accountContainer_;
+    AccountInfoPointer const * accountInfo_;
     bool isTemporary_;
 
     QMetaObject::Connection new_interaction_connection;
@@ -141,7 +141,7 @@ placecall_clicked(ChatView *self)
 {
     auto priv = CHAT_VIEW_GET_PRIVATE(self);
     if (!priv->conversation_) return;
-    priv->accountContainer_->info.conversationModel->placeCall(priv->conversation_->uid);
+    (*priv->accountInfo_)->conversationModel->placeCall(priv->conversation_->uid);
 }
 
 static void
@@ -152,7 +152,7 @@ place_audio_call_clicked(ChatView *self)
     if (!priv->conversation_)
         return;
 
-    priv->accountContainer_->info.conversationModel->placeAudioOnlyCall(priv->conversation_->uid);
+    (*priv->accountInfo_)->conversationModel->placeAudioOnlyCall(priv->conversation_->uid);
 }
 
 static void
@@ -160,7 +160,7 @@ button_add_to_conversations_clicked(ChatView *self)
 {
     auto priv = CHAT_VIEW_GET_PRIVATE(self);
     if (!priv->conversation_) return;
-    priv->accountContainer_->info.conversationModel->makePermanent(priv->conversation_->uid);
+    (*priv->accountInfo_)->conversationModel->makePermanent(priv->conversation_->uid);
 }
 
 static gchar*
@@ -198,27 +198,27 @@ webkit_chat_container_script_dialog(G_GNUC_UNUSED GtkWidget* webview, gchar *int
     auto order = std::string(interaction);
     if (!priv->conversation_) return;
     if (order == "ACCEPT") {
-        priv->accountContainer_->info.conversationModel->makePermanent(priv->conversation_->uid);
+        (*priv->accountInfo_)->conversationModel->makePermanent(priv->conversation_->uid);
     } else if (order == "REFUSE") {
-        priv->accountContainer_->info.conversationModel->removeConversation(priv->conversation_->uid);
+        (*priv->accountInfo_)->conversationModel->removeConversation(priv->conversation_->uid);
     } else if (order == "BLOCK") {
-        priv->accountContainer_->info.conversationModel->removeConversation(priv->conversation_->uid, true);
+        (*priv->accountInfo_)->conversationModel->removeConversation(priv->conversation_->uid, true);
     } else if (order.find("SEND:") == 0) {
         // Get text body
         auto toSend = order.substr(std::string("SEND:").size());
-        priv->accountContainer_->info.conversationModel->sendMessage(priv->conversation_->uid, toSend);
+        (*priv->accountInfo_)->conversationModel->sendMessage(priv->conversation_->uid, toSend);
     } else if (order.find("SEND_FILE") == 0) {
-        if (auto model = priv->accountContainer_->info.conversationModel.get()) {
+        if (auto model = (*priv->accountInfo_)->conversationModel.get()) {
             if (auto filename = file_to_manipulate(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(self))), true))
                 model->sendFile(priv->conversation_->uid, filename, g_path_get_basename(filename));
         }
     } else if (order.find("ACCEPT_FILE:") == 0) {
-        if (auto model = priv->accountContainer_->info.conversationModel.get()) {
+        if (auto model = (*priv->accountInfo_)->conversationModel.get()) {
             try {
                 auto interactionId = std::stoull(order.substr(std::string("ACCEPT_FILE:").size()));
 
                 lrc::api::datatransfer::Info info = {};
-                priv->accountContainer_->info.conversationModel->getTransferInfo(interactionId, info);
+                (*priv->accountInfo_)->conversationModel->getTransferInfo(interactionId, info);
 
                 // get prefered directory destination.
                 auto* download_directory_variant = g_settings_get_value(priv->settings, "download-folder");
@@ -240,7 +240,7 @@ webkit_chat_container_script_dialog(G_GNUC_UNUSED GtkWidget* webview, gchar *int
             }
         }
     } else if (order.find("REFUSE_FILE:") == 0) {
-        if (auto model = priv->accountContainer_->info.conversationModel.get()) {
+        if (auto model = (*priv->accountInfo_)->conversationModel.get()) {
             try {
                 auto interactionId = std::stoull(order.substr(std::string("REFUSE_FILE:").size()));
                 model->cancelTransfer(priv->conversation_->uid, interactionId);
@@ -320,11 +320,11 @@ print_interaction_to_buffer(ChatView* self, uint64_t interactionId, const lrc::a
 
     if (!priv->conversation_) return;
     if (interaction.status == lrc::api::interaction::Status::UNREAD)
-        priv->accountContainer_->info.conversationModel->setInteractionRead(priv->conversation_->uid, interactionId);
+        (*priv->accountInfo_)->conversationModel->setInteractionRead(priv->conversation_->uid, interactionId);
 
     webkit_chat_container_print_new_interaction(
         WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container),
-        *priv->accountContainer_->info.conversationModel,
+        *(*priv->accountInfo_)->conversationModel,
         interactionId,
         interaction
     );
@@ -336,7 +336,7 @@ update_interaction(ChatView* self, uint64_t interactionId, const lrc::api::inter
     ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);
     webkit_chat_container_update_interaction(
         WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container),
-        *priv->accountContainer_->info.conversationModel,
+        *(*priv->accountInfo_)->conversationModel,
         interactionId,
         interaction
     );
@@ -352,11 +352,11 @@ load_participants_images(ChatView *self)
     if (!priv->conversation_) return;
     auto contactUri = priv->conversation_->participants.front();
     try{
-        auto& contact = priv->accountContainer_->info.contactModel->getContact(contactUri);
+        auto& contact = (*priv->accountInfo_)->contactModel->getContact(contactUri);
         if (!contact.profileInfo.avatar.empty()) {
             webkit_chat_container_set_sender_image(
                 WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container),
-                priv->accountContainer_->info.contactModel->getContactProfileId(contactUri),
+                (*priv->accountInfo_)->contactModel->getContactProfileId(contactUri),
                 contact.profileInfo.avatar
                 );
         }
@@ -365,11 +365,11 @@ load_participants_images(ChatView *self)
     }
 
     // For this account
-    if (!priv->accountContainer_->info.profileInfo.avatar.empty()) {
+    if (!(*priv->accountInfo_)->profileInfo.avatar.empty()) {
         webkit_chat_container_set_sender_image(
             WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container),
-            priv->accountContainer_->info.contactModel->getContactProfileId(priv->accountContainer_->info.profileInfo.uri),
-            priv->accountContainer_->info.profileInfo.avatar
+            (*priv->accountInfo_)->contactModel->getContactProfileId((*priv->accountInfo_)->profileInfo.uri),
+            (*priv->accountInfo_)->profileInfo.avatar
         );
     }
 }
@@ -384,12 +384,12 @@ print_text_recording(ChatView *self)
     if (!priv->conversation_) return;
     for (const auto& it: priv->conversation_->interactions) {
         if (it.second.status == lrc::api::interaction::Status::UNREAD)
-            priv->accountContainer_->info.conversationModel->setInteractionRead(priv->conversation_->uid, it.first);
+            (*priv->accountInfo_)->conversationModel->setInteractionRead(priv->conversation_->uid, it.first);
     }
 
     webkit_chat_container_print_history(
         WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container),
-        *priv->accountContainer_->info.conversationModel,
+        *(*priv->accountInfo_)->conversationModel,
         priv->conversation_->interactions
     );
 
@@ -404,7 +404,7 @@ update_add_to_conversations(ChatView *self)
     if (!priv->conversation_) return;
     auto participant = priv->conversation_->participants[0];
     try {
-        auto contactInfo = priv->accountContainer_->info.contactModel->getContact(participant);
+        auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(participant);
         if(contactInfo.profileInfo.type != lrc::api::profile::Type::TEMPORARY
            && contactInfo.profileInfo.type != lrc::api::profile::Type::PENDING)
             gtk_widget_hide(priv->button_add_to_conversations);
@@ -421,7 +421,7 @@ update_contact_methods(ChatView *self)
     if (!priv->conversation_) return;
     auto contactUri = priv->conversation_->participants.front();
     try {
-        auto contactInfo = priv->accountContainer_->info.contactModel->getContact(contactUri);
+        auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(contactUri);
         auto bestId = std::string(contactInfo.registeredName).empty() ? contactInfo.profileInfo.uri : contactInfo.registeredName;
         if (contactInfo.profileInfo.alias == bestId) {
             gtk_widget_hide(priv->label_cm);
@@ -442,7 +442,7 @@ update_name(ChatView *self)
     if (!priv->conversation_) return;
     auto contactUri = priv->conversation_->participants.front();
     try {
-        auto contactInfo = priv->accountContainer_->info.contactModel->getContact(contactUri);
+        auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(contactUri);
         auto alias = contactInfo.profileInfo.alias;
         alias.erase(std::remove(alias.begin(), alias.end(), '\r'), alias.end());
         gtk_label_set_text(GTK_LABEL(priv->label_peer), alias.c_str());
@@ -468,7 +468,7 @@ webkit_chat_container_ready(ChatView* self)
     load_participants_images(self);
 
     priv->new_interaction_connection = QObject::connect(
-    &*priv->accountContainer_->info.conversationModel, &lrc::api::ConversationModel::newInteraction,
+    &*(*priv->accountInfo_)->conversationModel, &lrc::api::ConversationModel::newInteraction,
     [self, priv](const std::string& uid, uint64_t interactionId, lrc::api::interaction::Info interaction) {
         if (!priv->conversation_) return;
         if(uid == priv->conversation_->uid) {
@@ -477,7 +477,7 @@ webkit_chat_container_ready(ChatView* self)
     });
 
     priv->update_interaction_connection = QObject::connect(
-    &*priv->accountContainer_->info.conversationModel, &lrc::api::ConversationModel::interactionStatusUpdated,
+    &*(*priv->accountInfo_)->conversationModel, &lrc::api::ConversationModel::interactionStatusUpdated,
     [self, priv](const std::string& uid, uint64_t msgId, lrc::api::interaction::Info msg) {
         if (!priv->conversation_) return;
         if(uid == priv->conversation_->uid) {
@@ -488,7 +488,7 @@ webkit_chat_container_ready(ChatView* self)
     if (!priv->conversation_) return;
     auto contactUri = priv->conversation_->participants.front();
     try {
-        auto contactInfo = priv->accountContainer_->info.contactModel->getContact(contactUri);
+        auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(contactUri);
         priv->isTemporary_ = contactInfo.profileInfo.type == lrc::api::profile::Type::TEMPORARY
             || contactInfo.profileInfo.type == lrc::api::profile::Type::PENDING;
         webkit_chat_container_set_temporary(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container), priv->isTemporary_);
@@ -542,7 +542,7 @@ build_chat_view(ChatView* self)
 
 GtkWidget *
 chat_view_new (WebKitChatContainer* webkit_chat_container,
-               AccountContainer* accountContainer,
+               AccountInfoPointer const & accountInfo,
                lrc::api::conversation::Info* conversation)
 {
     ChatView *self = CHAT_VIEW(g_object_new(CHAT_VIEW_TYPE, NULL));
@@ -550,7 +550,7 @@ chat_view_new (WebKitChatContainer* webkit_chat_container,
     ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);
     priv->webkit_chat_container = GTK_WIDGET(webkit_chat_container);
     priv->conversation_ = conversation;
-    priv->accountContainer_ = accountContainer;
+    priv->accountInfo_ = &accountInfo;
 
     build_chat_view(self);
     return (GtkWidget *)self;
@@ -570,7 +570,7 @@ chat_view_update_temporary(ChatView* self, bool showAddButton, bool showInvitati
     if (!priv->conversation_) return;
     auto contactUri = priv->conversation_->participants.front();
     try {
-        auto contactInfo = priv->accountContainer_->info.contactModel->getContact(contactUri);
+        auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(contactUri);
         auto bestName = contactInfo.profileInfo.alias;
         if (bestName.empty())
             bestName = contactInfo.registeredName;
diff --git a/src/chatview.h b/src/chatview.h
index 8ab8ccfe..85fb16cc 100644
--- a/src/chatview.h
+++ b/src/chatview.h
@@ -25,8 +25,9 @@
 #include <gtk/gtk.h>
 
 // Client related
-#include "accountcontainer.h"
+#include "api/account.h"
 #include "webkitchatcontainer.h"
+#include "accountinfopointer.h"
 
 namespace lrc
 {
@@ -52,7 +53,7 @@ typedef struct _ChatViewClass ChatViewClass;
 
 GType          chat_view_get_type   (void) G_GNUC_CONST;
 GtkWidget     *chat_view_new        (WebKitChatContainer* view,
-                                     AccountContainer* accountContainer,
+                                     AccountInfoPointer const & accountInfo,
                                      lrc::api::conversation::Info* conversation);
 lrc::api::conversation::Info chat_view_get_conversation(ChatView*);
 bool chat_view_get_temporary(ChatView*);
diff --git a/src/conversationpopupmenu.cpp b/src/conversationpopupmenu.cpp
index ea404ac3..5434748b 100644
--- a/src/conversationpopupmenu.cpp
+++ b/src/conversationpopupmenu.cpp
@@ -27,6 +27,8 @@
 #include <api/contactmodel.h>
 #include <api/contact.h>
 
+#include "accountinfopointer.h"
+
 struct _ConversationPopupMenu
 {
     GtkMenu parent;
@@ -43,7 +45,7 @@ struct _ConversationPopupMenuPrivate
 {
     GtkTreeView *treeview;
 
-    AccountContainer* accountContainer_;
+    AccountInfoPointer const *accountInfo_;
     int row_;
 };
 
@@ -56,9 +58,9 @@ copy_contact_info(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenuPrivate* p
 {
     try
     {
-        auto conversation = priv->accountContainer_->info.conversationModel->filteredConversation(priv->row_);
+        auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(priv->row_);
         if (conversation.participants.empty()) return;
-        auto& contact = priv->accountContainer_->info.contactModel->getContact(conversation.participants.front());
+        auto& contact = (*priv->accountInfo_)->contactModel->getContact(conversation.participants.front());
         auto bestName = contact.registeredName.empty() ? contact.profileInfo.uri : contact.registeredName;
         auto text = (gchar *)bestName.c_str();
         GtkClipboard* clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
@@ -77,8 +79,8 @@ remove_history_conversation(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenu
 {
     try
     {
-        auto conversation = priv->accountContainer_->info.conversationModel->filteredConversation(priv->row_);
-        priv->accountContainer_->info.conversationModel->clearHistory(conversation.uid);
+        auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(priv->row_);
+        (*priv->accountInfo_)->conversationModel->clearHistory(conversation.uid);
     }
     catch (...)
     {
@@ -91,8 +93,8 @@ remove_conversation(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenuPrivate*
 {
     try
     {
-        auto conversationUid = priv->accountContainer_->info.conversationModel->filteredConversation(priv->row_).uid;
-        priv->accountContainer_->info.conversationModel->removeConversation(conversationUid);
+        auto conversationUid = (*priv->accountInfo_)->conversationModel->filteredConversation(priv->row_).uid;
+        (*priv->accountInfo_)->conversationModel->removeConversation(conversationUid);
     }
     catch (...)
     {
@@ -105,8 +107,8 @@ block_conversation(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenuPrivate*
 {
     try
     {
-        auto conversationUid = priv->accountContainer_->info.conversationModel->filteredConversation(priv->row_).uid;
-        priv->accountContainer_->info.conversationModel->removeConversation(conversationUid, true);
+        auto conversationUid = (*priv->accountInfo_)->conversationModel->filteredConversation(priv->row_).uid;
+        (*priv->accountInfo_)->conversationModel->removeConversation(conversationUid, true);
     }
     catch (...)
     {
@@ -119,8 +121,8 @@ add_conversation(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenuPrivate* pr
 {
     try
     {
-        auto conversation = priv->accountContainer_->info.conversationModel->filteredConversation(priv->row_);
-        priv->accountContainer_->info.conversationModel->makePermanent(conversation.uid);
+        auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(priv->row_);
+        (*priv->accountInfo_)->conversationModel->makePermanent(conversation.uid);
     }
     catch (...)
     {
@@ -133,8 +135,8 @@ place_video_call(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenuPrivate* pr
 {
     try
     {
-        auto conversation = priv->accountContainer_->info.conversationModel->filteredConversation(priv->row_);
-        priv->accountContainer_->info.conversationModel->placeCall(conversation.uid);
+        auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(priv->row_);
+        (*priv->accountInfo_)->conversationModel->placeCall(conversation.uid);
     } catch (...) {
         g_warning("Can't get conversation at row %i", priv->row_);
     }
@@ -145,8 +147,8 @@ place_audio_call(G_GNUC_UNUSED GtkWidget *menu, ConversationPopupMenuPrivate* pr
 {
     try
     {
-        auto conversation = priv->accountContainer_->info.conversationModel->filteredConversation(priv->row_);
-        priv->accountContainer_->info.conversationModel->placeAudioOnlyCall(conversation.uid);
+        auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(priv->row_);
+        (*priv->accountInfo_)->conversationModel->placeAudioOnlyCall(conversation.uid);
     } catch (...) {
         g_warning("Can't get conversation at row %i", priv->row_);
     }
@@ -168,10 +170,10 @@ update(GtkTreeSelection *selection, ConversationPopupMenu *self)
     if (!gtk_tree_selection_get_selected(selection, &model, &iter)) return;
     auto path = gtk_tree_model_get_path(model, &iter);
     auto idx = gtk_tree_path_get_indices(path);
-    auto conversation = priv->accountContainer_->info.conversationModel->filteredConversation(idx[0]);
+    auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(idx[0]);
     priv->row_ = idx[0];
     try {
-        auto contactInfo = priv->accountContainer_->info.contactModel->getContact(conversation.participants.front());
+        auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(conversation.participants.front());
         if (contactInfo.profileInfo.uri.empty()) return;
 
         // we always build a menu, however in some cases some or all of the conversations will be deactivated
@@ -248,11 +250,11 @@ conversation_popup_menu_init(G_GNUC_UNUSED ConversationPopupMenu *self)
 }
 
 GtkWidget *
-conversation_popup_menu_new (GtkTreeView *treeview, AccountContainer* accountContainer)
+conversation_popup_menu_new (GtkTreeView *treeview, AccountInfoPointer const & accountInfo)
 {
     gpointer self = g_object_new(CONVERSATION_POPUP_MENU_TYPE, NULL);
     ConversationPopupMenuPrivate *priv = CONVERSATION_POPUP_MENU_GET_PRIVATE(self);
-    priv->accountContainer_ = accountContainer;
+    priv->accountInfo_ = &accountInfo;
 
     priv->treeview = treeview;
     GtkTreeSelection *selection = gtk_tree_view_get_selection(priv->treeview);
diff --git a/src/conversationpopupmenu.h b/src/conversationpopupmenu.h
index 7f23631a..398451db 100644
--- a/src/conversationpopupmenu.h
+++ b/src/conversationpopupmenu.h
@@ -22,7 +22,9 @@
 #include <gtk/gtk.h>
 
 // LRC
-#include "accountcontainer.h"
+#include "api/account.h"
+
+#include "accountinfopointer.h"
 
 G_BEGIN_DECLS
 
@@ -36,7 +38,7 @@ typedef struct _ConversationPopupMenu      ConversationPopupMenu;
 typedef struct _ConversationPopupMenuClass ConversationPopupMenuClass;
 
 GType      conversation_popup_menu_get_type (void) G_GNUC_CONST;
-GtkWidget *conversation_popup_menu_new      (GtkTreeView *treeview, AccountContainer* accountContainer);
+GtkWidget *conversation_popup_menu_new      (GtkTreeView *treeview, AccountInfoPointer const & accountInfo);
 gboolean   conversation_popup_menu_show     (ConversationPopupMenu *self, GdkEventButton *event);
 
 G_END_DECLS
diff --git a/src/conversationsview.cpp b/src/conversationsview.cpp
index 879a8664..2089da88 100644
--- a/src/conversationsview.cpp
+++ b/src/conversationsview.cpp
@@ -37,7 +37,6 @@
 #include "native/pixbufmanipulator.h"
 #include "conversationpopupmenu.h"
 
-
 static constexpr const char* CALL_TARGET    = "CALL_TARGET";
 static constexpr int         CALL_TARGET_ID = 0;
 
@@ -55,7 +54,7 @@ typedef struct _ConversationsViewPrivate ConversationsViewPrivate;
 
 struct _ConversationsViewPrivate
 {
-    AccountContainer* accountContainer_;
+    AccountInfoPointer const *accountInfo_;
 
     GtkWidget* popupMenu_;
 
@@ -88,12 +87,12 @@ render_contact_photo(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
     {
         // Draw first contact.
         // NOTE: We just draw the first contact, must change this for conferences when they will have their own object
-        auto conversationInfo = priv->accountContainer_->info.conversationModel->filteredConversation(row);
-        auto contactInfo = priv->accountContainer_->info.contactModel->getContact(conversationInfo.participants.front());
+        auto conversationInfo = (*priv->accountInfo_)->conversationModel->filteredConversation(row);
+        auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(conversationInfo.participants.front());
         std::shared_ptr<GdkPixbuf> image;
         auto var_photo = GlobalInstances::pixmapManipulator().conversationPhoto(
             conversationInfo,
-            priv->accountContainer_->info,
+            **(priv->accountInfo_),
             QSize(50, 50),
             contactInfo.isPresent
         );
@@ -185,10 +184,10 @@ render_time(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
 
     try
     {
-        auto conversation = priv->accountContainer_->info.conversationModel->filteredConversation(row);
+        auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(row);
         auto callId = conversation.confId.empty() ? conversation.callId : conversation.confId;
         if (!callId.empty()) {
-            auto call = priv->accountContainer_->info.callModel->getCall(callId);
+            auto call = (*priv->accountInfo_)->callModel->getCall(callId);
             text = g_markup_printf_escaped("%s",
                 lrc::api::call::to_string(call.status).c_str()
             );
@@ -242,9 +241,9 @@ update_conversation(ConversationsView *self, const std::string& uid) {
                             -1);
         if(std::string(ringId) == uid) {
             // Get informations
-            auto conversation = priv->accountContainer_->info.conversationModel->filteredConversation(idx);
+            auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(idx);
             auto contactUri = conversation.participants.front();
-            auto contactInfo = priv->accountContainer_->info.contactModel->getContact(contactUri);
+            auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(contactUri);
             auto lastMessage = conversation.interactions.empty() ? "" :
                 conversation.interactions.at(conversation.lastMessageUid).body;
             std::replace(lastMessage.begin(), lastMessage.end(), '\n', ' ');
@@ -282,11 +281,15 @@ create_and_fill_model(ConversationsView *self)
     if(!priv) GTK_TREE_MODEL (store);
     GtkTreeIter iter;
 
-    for (auto conversation : priv->accountContainer_->info.conversationModel->allFilteredConversations()) {
-        if (conversation.participants.empty()) break; // Should not
+    for (auto conversation : (*priv->accountInfo_)->conversationModel->allFilteredConversations()) {
+        if (conversation.participants.empty()) {
+            g_debug("Found conversation with empty list of participants - most likely the result of earlier bug.");
+            break;
+        }
+
         auto contactUri = conversation.participants.front();
         try {
-            auto contactInfo = priv->accountContainer_->info.contactModel->getContact(contactUri);
+            auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(contactUri);
             auto lastMessage = conversation.interactions.empty() ? "" :
                 conversation.interactions.at(conversation.lastMessageUid).body;
             std::replace(lastMessage.begin(), lastMessage.end(), '\n', ' ');
@@ -319,8 +322,8 @@ call_conversation(GtkTreeView *self,
     if (row == -1) return;
     auto priv = CONVERSATIONS_VIEW_GET_PRIVATE(self);
     if (!priv) return;
-    auto conversation = priv->accountContainer_->info.conversationModel->filteredConversation(row);
-    priv->accountContainer_->info.conversationModel->placeCall(conversation.uid);
+    auto conversation = (*priv->accountInfo_)->conversationModel->filteredConversation(row);
+    (*priv->accountInfo_)->conversationModel->placeCall(conversation.uid);
 }
 
 static void
@@ -334,7 +337,7 @@ select_conversation(GtkTreeSelection *selection, ConversationsView *self)
         // Destroy the not up to date menu.
         gtk_widget_hide(priv->popupMenu_);
         gtk_widget_destroy(priv->popupMenu_);
-        priv->popupMenu_ = conversation_popup_menu_new(GTK_TREE_VIEW(self), priv->accountContainer_);
+        priv->popupMenu_ = conversation_popup_menu_new(GTK_TREE_VIEW(self), *priv->accountInfo_);
         auto children = gtk_container_get_children (GTK_CONTAINER(priv->popupMenu_));
         auto nbItems = g_list_length(children);
         // Show the new popupMenu_ should be visible
@@ -350,7 +353,7 @@ select_conversation(GtkTreeSelection *selection, ConversationsView *self)
     gtk_tree_model_get(model, &iter,
                        0, &conversationUid,
                        -1);
-    priv->accountContainer_->info.conversationModel->selectConversation(std::string(conversationUid));
+    (*priv->accountInfo_)->conversationModel->selectConversation(std::string(conversationUid));
 }
 
 static void
@@ -500,7 +503,7 @@ on_drag_data_received(GtkWidget        *treeview,
                                0, &conversationUidDest,
                                -1);
 
-            priv->accountContainer_->info.conversationModel->joinConversations(
+            (*priv->accountInfo_)->conversationModel->joinConversations(
                 conversationUidSrc,
                 conversationUidDest
             );
@@ -566,7 +569,7 @@ build_conversations_view(ConversationsView *self)
 
     // This view should be synchronized and redraw at each update.
     priv->modelSortedConnection_ = QObject::connect(
-    &*priv->accountContainer_->info.conversationModel,
+    &*(*priv->accountInfo_)->conversationModel,
     &lrc::api::ConversationModel::modelSorted,
     [self] () {
         auto model = create_and_fill_model(self);
@@ -575,14 +578,14 @@ build_conversations_view(ConversationsView *self)
                                 GTK_TREE_MODEL(model));
     });
     priv->conversationUpdatedConnection_ = QObject::connect(
-    &*priv->accountContainer_->info.conversationModel,
+    &*(*priv->accountInfo_)->conversationModel,
     &lrc::api::ConversationModel::conversationUpdated,
     [self] (const std::string& uid) {
         update_conversation(self, uid);
     });
 
     priv->filterChangedConnection_ = QObject::connect(
-    &*priv->accountContainer_->info.conversationModel,
+    &*(*priv->accountInfo_)->conversationModel,
     &lrc::api::ConversationModel::filterChanged,
     [self] () {
         auto model = create_and_fill_model(self);
@@ -599,7 +602,7 @@ build_conversations_view(ConversationsView *self)
     // Two clicks to placeCall
     g_signal_connect(self, "row-activated", G_CALLBACK(call_conversation), NULL);
 
-    priv->popupMenu_ = conversation_popup_menu_new(GTK_TREE_VIEW(self), priv->accountContainer_);
+    priv->popupMenu_ = conversation_popup_menu_new(GTK_TREE_VIEW(self), *priv->accountInfo_);
     // Right click to show actions
     g_signal_connect_swapped(self, "button-press-event", G_CALLBACK(show_popup_menu), self);
 
@@ -651,14 +654,14 @@ conversations_view_class_init(ConversationsViewClass *klass)
 }
 
 GtkWidget *
-conversations_view_new(AccountContainer* accountContainer)
+conversations_view_new(AccountInfoPointer const & accountInfo)
 {
     auto self = CONVERSATIONS_VIEW(g_object_new(CONVERSATIONS_VIEW_TYPE, NULL));
     auto priv = CONVERSATIONS_VIEW_GET_PRIVATE(self);
 
-    priv->accountContainer_ = accountContainer;
+    priv->accountInfo_ = &accountInfo;
 
-    if (priv->accountContainer_)
+    if (*priv->accountInfo_)
         build_conversations_view(self);
 
     return (GtkWidget *)self;
diff --git a/src/conversationsview.h b/src/conversationsview.h
index 9a39addd..2dc85a0d 100644
--- a/src/conversationsview.h
+++ b/src/conversationsview.h
@@ -20,7 +20,9 @@
 
 #include <gtk/gtk.h>
 
-#include "accountcontainer.h"
+#include "api/account.h"
+
+#include "accountinfopointer.h"
 
 G_BEGIN_DECLS
 
@@ -34,7 +36,7 @@ typedef struct _ConversationsView      ConversationsView;
 typedef struct _ConversationsViewClass ConversationsViewClass;
 
 GType      conversations_view_get_type            (void) G_GNUC_CONST;
-GtkWidget *conversations_view_new                 (AccountContainer* accountContainer);
+GtkWidget *conversations_view_new                 (AccountInfoPointer const & accountInfo);
 void       conversations_view_select_conversation (ConversationsView *self, const std::string& uid);
 
 G_END_DECLS
diff --git a/src/currentcallview.cpp b/src/currentcallview.cpp
index 73163025..dbf41108 100644
--- a/src/currentcallview.cpp
+++ b/src/currentcallview.cpp
@@ -232,7 +232,7 @@ public:
 
     void init();
     void setup(WebKitChatContainer* chat_widget,
-               AccountContainer* accountContainer,
+               AccountInfoPointer const & account_info,
                lrc::api::conversation::Info* conversation);
 
     void insertControls();
@@ -242,7 +242,7 @@ public:
     CurrentCallViewPrivate* widgets = nullptr;
 
     lrc::api::conversation::Info* conversation = nullptr;
-    AccountContainer* accountContainer = nullptr;
+    AccountInfoPointer const *accountInfo = nullptr;
 
     QMetaObject::Connection state_change_connection;
     QMetaObject::Connection local_renderer_connection;
@@ -328,7 +328,7 @@ on_button_hangup_clicked(CurrentCallView* view)
     auto callToHangUp = priv->cpp->conversation->callId;
     if (!priv->cpp->conversation->confId.empty())
         callToHangUp = priv->cpp->conversation->confId;
-    priv->cpp->accountContainer->info.callModel->hangUp(callToHangUp);
+    (*priv->cpp->accountInfo)->callModel->hangUp(callToHangUp);
 }
 
 static void
@@ -340,7 +340,7 @@ on_togglebutton_hold_clicked(CurrentCallView* view)
     auto callToHold = priv->cpp->conversation->callId;
     if (!priv->cpp->conversation->confId.empty())
         callToHold = priv->cpp->conversation->confId;
-    priv->cpp->accountContainer->info.callModel->togglePause(callToHold);
+    (*priv->cpp->accountInfo)->callModel->togglePause(callToHold);
 }
 
 static void
@@ -352,7 +352,7 @@ on_togglebutton_record_clicked(CurrentCallView* view)
     auto callToRecord = priv->cpp->conversation->callId;
     if (!priv->cpp->conversation->confId.empty())
         callToRecord = priv->cpp->conversation->confId;
-    priv->cpp->accountContainer->info.callModel->toggleAudioRecord(callToRecord);
+    (*priv->cpp->accountInfo)->callModel->toggleAudioRecord(callToRecord);
 }
 
 static void
@@ -365,7 +365,7 @@ on_togglebutton_muteaudio_clicked(CurrentCallView* view)
     if (!priv->cpp->conversation->confId.empty())
         callToMute = priv->cpp->conversation->confId;
     //auto muteAudioBtn = GTK_TOGGLE_BUTTON(priv->togglebutton_muteaudio);
-    priv->cpp->accountContainer->info.callModel->toggleMedia(callToMute,
+    (*priv->cpp->accountInfo)->callModel->toggleMedia(callToMute,
         lrc::api::NewCallModel::Media::AUDIO);
 
     auto togglebutton = GTK_TOGGLE_BUTTON(priv->togglebutton_muteaudio);
@@ -385,7 +385,7 @@ on_togglebutton_mutevideo_clicked(CurrentCallView* view)
     if (!priv->cpp->conversation->confId.empty())
         callToMute = priv->cpp->conversation->confId;
     //auto muteVideoBtn = GTK_TOGGLE_BUTTON(priv->togglebutton_mutevideo);
-    priv->cpp->accountContainer->info.callModel->toggleMedia(callToMute,
+    (*priv->cpp->accountInfo)->callModel->toggleMedia(callToMute,
         lrc::api::NewCallModel::Media::VIDEO);
 
     auto togglebutton = GTK_TOGGLE_BUTTON(priv->togglebutton_mutevideo);
@@ -439,7 +439,7 @@ on_autoquality_toggled(GtkToggleButton* button, CurrentCallView* view)
     auto callToRender = priv->cpp->conversation->callId;
     if (!priv->cpp->conversation->confId.empty())
         callToRender = priv->cpp->conversation->confId;
-    auto renderer = priv->cpp->accountContainer->info.callModel->getRenderer(callToRender);
+    auto renderer = (*priv->cpp->accountInfo)->callModel->getRenderer(callToRender);
     for (auto* activeCall: CallModel::instance().getActiveCalls()) {
         if (activeCall and activeCall->videoRenderer() == renderer)
             set_call_quality(*activeCall, auto_quality_on, desired_quality);
@@ -462,7 +462,7 @@ on_quality_changed(G_GNUC_UNUSED GtkScaleButton *button, G_GNUC_UNUSED gdouble v
     auto callToRender = priv->cpp->conversation->callId;
     if (!priv->cpp->conversation->confId.empty())
         callToRender = priv->cpp->conversation->confId;
-    auto renderer = priv->cpp->accountContainer->info.callModel->getRenderer(callToRender);
+    auto renderer = (*priv->cpp->accountInfo)->callModel->getRenderer(callToRender);
     for (auto* activeCall: CallModel::instance().getActiveCalls())
         if (activeCall and activeCall->videoRenderer() == renderer)
             set_call_quality(*activeCall, false, gtk_scale_button_get_value(button));
@@ -598,12 +598,12 @@ CppImpl::init()
 
 void
 CppImpl::setup(WebKitChatContainer* chat_widget,
-               AccountContainer* account_container,
+               AccountInfoPointer const & account_info,
                lrc::api::conversation::Info* conv_info)
 {
     widgets->webkit_chat_container = GTK_WIDGET(chat_widget);
     conversation = conv_info;
-    accountContainer = account_container;
+    accountInfo = &account_info;
     setCallInfo();
 }
 
@@ -623,7 +623,7 @@ CppImpl::setCallInfo()
     if (!conversation->confId.empty())
         callToRender = conversation->confId;
     video_widget_push_new_renderer(VIDEO_WIDGET(widgets->video_widget),
-                                   accountContainer->info.callModel->getRenderer(callToRender),
+                                   (*accountInfo)->callModel->getRenderer(callToRender),
                                    VIDEO_RENDERER_REMOTE);
 
     // local renderer
@@ -650,7 +650,7 @@ CppImpl::setCallInfo()
     );
 
     remote_renderer_connection = QObject::connect(
-        &*accountContainer->info.callModel,
+        &*(*accountInfo)->callModel,
         &lrc::api::NewCallModel::remotePreviewStarted,
         [this] (const std::string& callId, Video::Renderer* renderer) {
             if (conversation->callId == callId) {
@@ -661,7 +661,7 @@ CppImpl::setCallInfo()
         });
 
     state_change_connection = QObject::connect(
-        &*accountContainer->info.callModel,
+        &*(*accountInfo)->callModel,
         &lrc::api::NewCallModel::callStatusChanged,
         [this] (const std::string& callId) {
             if (callId == conversation->callId) {
@@ -671,7 +671,7 @@ CppImpl::setCallInfo()
         });
 
     new_message_connection = QObject::connect(
-        &*accountContainer->info.conversationModel,
+        &*(*accountInfo)->conversationModel,
         &lrc::api::ConversationModel::newInteraction,
         [this] (const std::string& uid, uint64_t msgId, lrc::api::interaction::Info msg) {
             Q_UNUSED(uid)
@@ -694,7 +694,7 @@ CppImpl::setCallInfo()
 
     // init chat view
     widgets->chat_view = chat_view_new(WEBKIT_CHAT_CONTAINER(widgets->webkit_chat_container),
-                                       accountContainer, conversation);
+                                       *accountInfo, conversation);
     gtk_container_add(GTK_CONTAINER(widgets->frame_chat), widgets->chat_view);
 
     g_signal_connect_swapped(widgets->chat_view, "new-interactions-displayed",
@@ -792,7 +792,7 @@ CppImpl::insertControls()
     auto callToRender = conversation->callId;
     if (!conversation->confId.empty())
         callToRender = conversation->confId;
-    auto renderer = accountContainer->info.callModel->getRenderer(callToRender);
+    auto renderer = (*accountInfo)->callModel->getRenderer(callToRender);
     for (auto* activeCall: CallModel::instance().getActiveCalls())
         if (activeCall and activeCall->videoRenderer() == renderer) {
             g_signal_connect(widgets->video_widget, "drag-data-received",
@@ -837,9 +837,9 @@ CppImpl::updateDetails()
         callRendered = conversation->confId;
 
     gtk_label_set_text(GTK_LABEL(widgets->label_duration),
-    accountContainer->info.callModel->getFormattedCallDuration(callRendered).c_str());
+    (*accountInfo)->callModel->getFormattedCallDuration(callRendered).c_str());
 
-    auto call = accountContainer->info.callModel->getCall(callRendered);
+    auto call = (*accountInfo)->callModel->getCall(callRendered);
     gtk_widget_set_sensitive(GTK_WIDGET(widgets->togglebutton_muteaudio),
                              (call.type != lrc::api::call::Type::CONFERENCE));
     gtk_widget_set_sensitive(GTK_WIDGET(widgets->togglebutton_mutevideo),
@@ -854,7 +854,7 @@ CppImpl::updateState()
     auto callId = conversation->callId;
 
     try {
-        auto call = accountContainer->info.callModel->getCall(callId);
+        auto call = (*accountInfo)->callModel->getCall(callId);
 
         auto pauseBtn = GTK_TOGGLE_BUTTON(widgets->togglebutton_hold);
         auto image = gtk_image_new_from_resource ("/cx/ring/RingGnome/pause");
@@ -889,7 +889,7 @@ CppImpl::updateNameAndPhoto()
 {
     QVariant var_i = GlobalInstances::pixmapManipulator().conversationPhoto(
         *conversation,
-        accountContainer->info,
+        **(accountInfo),
         QSize(60, 60),
         false
     );
@@ -897,7 +897,7 @@ CppImpl::updateNameAndPhoto()
     gtk_image_set_from_pixbuf(GTK_IMAGE(widgets->image_peer), image.get());
 
     try {
-        auto contactInfo = accountContainer->info.contactModel->getContact(conversation->participants.front());
+        auto contactInfo = (*accountInfo)->contactModel->getContact(conversation->participants.front());
         auto name = contactInfo.profileInfo.alias;
         gtk_label_set_text(GTK_LABEL(widgets->label_name), name.c_str());
 
@@ -1080,13 +1080,13 @@ current_call_view_class_init(CurrentCallViewClass *klass)
 
 GtkWidget *
 current_call_view_new(WebKitChatContainer* chat_widget,
-                      AccountContainer* accountContainer,
+                      AccountInfoPointer const & accountInfo,
                       lrc::api::conversation::Info* conversation)
 {
     auto* self = g_object_new(CURRENT_CALL_VIEW_TYPE, NULL);
     auto* priv = CURRENT_CALL_VIEW_GET_PRIVATE(self);
 
-    priv->cpp->setup(chat_widget, accountContainer, conversation);
+    priv->cpp->setup(chat_widget, accountInfo, conversation);
 
     return GTK_WIDGET(self);
 }
diff --git a/src/currentcallview.h b/src/currentcallview.h
index 765ef7c0..85637de0 100644
--- a/src/currentcallview.h
+++ b/src/currentcallview.h
@@ -22,8 +22,9 @@
 #pragma once
 
 #include <gtk/gtk.h>
-#include "accountcontainer.h"
+#include "api/account.h"
 #include "webkitchatcontainer.h"
+#include "accountinfopointer.h"
 
 namespace lrc
 {
@@ -50,7 +51,7 @@ typedef struct _CurrentCallViewClass CurrentCallViewClass;
 
 GType      current_call_view_get_type      (void) G_GNUC_CONST;
 GtkWidget *current_call_view_new           (WebKitChatContainer* view,
-                                           AccountContainer* accountContainer,
+                                           AccountInfoPointer const & accountInfo,
                                            lrc::api::conversation::Info* conversation);
 lrc::api::conversation::Info current_call_view_get_conversation(CurrentCallView*);
 GtkWidget *current_call_view_get_chat_view(CurrentCallView*);
diff --git a/src/incomingcallview.cpp b/src/incomingcallview.cpp
index 0cfc5c32..cf8dcfbf 100644
--- a/src/incomingcallview.cpp
+++ b/src/incomingcallview.cpp
@@ -66,7 +66,7 @@ struct _IncomingCallViewPrivate
     GtkWidget *webkit_chat_container;
 
     lrc::api::conversation::Info* conversation_;
-    AccountContainer* accountContainer_;
+    AccountInfoPointer const * accountInfo_;
 
     QMetaObject::Connection state_change_connection;
 
@@ -113,7 +113,7 @@ static void
 reject_incoming_call(G_GNUC_UNUSED GtkWidget *widget, ChatView *self)
 {
     auto priv = INCOMING_CALL_VIEW_GET_PRIVATE(self);
-    priv->accountContainer_->info.callModel->hangUp(priv->conversation_->callId);
+    (*priv->accountInfo_)->callModel->hangUp(priv->conversation_->callId);
 }
 
 static void
@@ -122,12 +122,12 @@ accept_incoming_call(G_GNUC_UNUSED GtkWidget *widget, ChatView *self)
     auto priv = INCOMING_CALL_VIEW_GET_PRIVATE(self);
     auto contactUri = priv->conversation_->participants[0];
     try {
-        auto contact = priv->accountContainer_->info.contactModel->getContact(contactUri);
+        auto contact = (*priv->accountInfo_)->contactModel->getContact(contactUri);
         // If the contact is pending, we should accept its request
         if (contact.profileInfo.type == lrc::api::profile::Type::PENDING)
-            priv->accountContainer_->info.conversationModel->makePermanent(priv->conversation_->uid);
+            (*priv->accountInfo_)->conversationModel->makePermanent(priv->conversation_->uid);
         // Accept call
-        priv->accountContainer_->info.callModel->accept(priv->conversation_->callId);
+        (*priv->accountInfo_)->callModel->accept(priv->conversation_->callId);
     } catch (const std::out_of_range&) {
         // ContactModel::getContact() exception
     }
@@ -191,8 +191,8 @@ update_state(IncomingCallView *view)
 
     // change state label
     auto callId = priv->conversation_->callId;
-    if (!priv->accountContainer_->info.callModel->hasCall(callId)) return;
-    auto call = priv->accountContainer_->info.callModel->getCall(callId);
+    if (!(*priv->accountInfo_)->callModel->hasCall(callId)) return;
+    auto call = (*priv->accountInfo_)->callModel->getCall(callId);
 
     gchar *status = g_strdup_printf("%s", lrc::api::call::to_string(call.status).c_str());
     gtk_label_set_text(GTK_LABEL(priv->label_status), status);
@@ -214,7 +214,7 @@ update_name_and_photo(IncomingCallView *view)
 
     QVariant var_i = GlobalInstances::pixmapManipulator().conversationPhoto(
         *priv->conversation_,
-        priv->accountContainer_->info,
+        **(priv->accountInfo_),
         QSize(110, 110),
         false
     );
@@ -222,7 +222,7 @@ update_name_and_photo(IncomingCallView *view)
     gtk_image_set_from_pixbuf(GTK_IMAGE(priv->image_incoming), image.get());
 
     try {
-        auto contactInfo = priv->accountContainer_->info.contactModel->getContact(priv->conversation_->participants.front());
+        auto contactInfo = (*priv->accountInfo_)->contactModel->getContact(priv->conversation_->participants.front());
 
         auto name = contactInfo.profileInfo.alias;
         gtk_label_set_text(GTK_LABEL(priv->label_name), name.c_str());
@@ -246,7 +246,7 @@ set_call_info(IncomingCallView *view) {
 
     // Update view if call state changes
     priv->state_change_connection = QObject::connect(
-    &*priv->accountContainer_->info.callModel,
+    &*(*priv->accountInfo_)->callModel,
     &lrc::api::NewCallModel::callStatusChanged,
     [view, priv] (const std::string& callId) {
         if (callId == priv->conversation_->callId) {
@@ -256,7 +256,7 @@ set_call_info(IncomingCallView *view) {
     });
 
     auto chat_view = chat_view_new(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container),
-                                                         priv->accountContainer_,
+                                                         *priv->accountInfo_,
                                                          priv->conversation_);
     gtk_widget_show(chat_view);
     chat_view_set_header_visible(CHAT_VIEW(chat_view), FALSE);
@@ -265,7 +265,7 @@ set_call_info(IncomingCallView *view) {
 
 GtkWidget *
 incoming_call_view_new(WebKitChatContainer* view,
-                       AccountContainer* accountContainer,
+                       AccountInfoPointer const & accountInfo,
                        lrc::api::conversation::Info* conversation)
 {
     auto self = g_object_new(INCOMING_CALL_VIEW_TYPE, NULL);
@@ -273,7 +273,7 @@ incoming_call_view_new(WebKitChatContainer* view,
     IncomingCallViewPrivate *priv = INCOMING_CALL_VIEW_GET_PRIVATE(self);
     priv->webkit_chat_container = GTK_WIDGET(view);
     priv->conversation_ = conversation;
-    priv->accountContainer_ = accountContainer;
+    priv->accountInfo_ = &accountInfo;
 
     set_call_info(INCOMING_CALL_VIEW(self));
 
diff --git a/src/incomingcallview.h b/src/incomingcallview.h
index d33612f4..9214deed 100644
--- a/src/incomingcallview.h
+++ b/src/incomingcallview.h
@@ -25,8 +25,9 @@
 #include <gtk/gtk.h>
 
 // client
-#include "accountcontainer.h"
+#include "api/account.h"
 #include "webkitchatcontainer.h"
+#include "accountinfopointer.h"
 
 namespace lrc
 {
@@ -53,7 +54,7 @@ typedef struct _IncomingCallViewClass IncomingCallViewClass;
 
 GType      incoming_call_view_get_type (void) G_GNUC_CONST;
 GtkWidget *incoming_call_view_new (WebKitChatContainer* view,
-                                   AccountContainer* accountContainer,
+                                   AccountInfoPointer const & accountInfo,
                                    lrc::api::conversation::Info* conversation);
 lrc::api::conversation::Info incoming_call_view_get_conversation (IncomingCallView*);
 
diff --git a/src/ringmainwindow.cpp b/src/ringmainwindow.cpp
index b3f142ff..d78f77d3 100644
--- a/src/ringmainwindow.cpp
+++ b/src/ringmainwindow.cpp
@@ -36,7 +36,7 @@
 #include <api/newaccountmodel.h>
 #include <api/newcallmodel.h>
 #include <api/behaviorcontroller.h>
-#include "accountcontainer.h"
+#include "api/account.h"
 #include <media/textrecording.h>
 #include <media/recordingmodel.h>
 #include <media/text.h>
@@ -57,6 +57,7 @@
 #include "utils/accounts.h"
 #include "utils/files.h"
 #include "ringnotify.h"
+#include "accountinfopointer.h"
 
 //==============================================================================
 
@@ -205,7 +206,7 @@ public:
     RingMainWindowPrivate* widgets = nullptr;
 
     std::unique_ptr<lrc::api::Lrc> lrc_;
-    std::unique_ptr<AccountContainer> accountContainer_;
+    AccountInfoPointer accountInfo_ = nullptr;
     std::unique_ptr<lrc::api::conversation::Info> chatViewConversation_;
     lrc::api::profile::Type currentTypeFilter_;
     bool show_settings = false;
@@ -308,7 +309,7 @@ on_account_changed(RingMainWindow* self)
         gtk_tree_model_get(model, &iter, 0 /* col# */, &accountId /* data */, -1);
         priv->cpp->onAccountSelectionChange(accountId);
         gtk_notebook_set_show_tabs(GTK_NOTEBOOK(priv->notebook_contacts),
-                                   priv->cpp->accountContainer_->info.contactModel->hasPendingRequests());
+                                   priv->cpp->accountInfo_->contactModel->hasPendingRequests());
         g_free(accountId);
     }
 }
@@ -375,7 +376,7 @@ on_search_entry_text_changed(GtkSearchEntry* search_entry, RingMainWindow* self)
 
     // Filter model
     const gchar *text = gtk_entry_get_text(GTK_ENTRY(search_entry));
-    priv->cpp->accountContainer_->info.conversationModel->setFilter(text);
+    priv->cpp->accountInfo_->conversationModel->setFilter(text);
 }
 
 static void
@@ -385,7 +386,7 @@ on_search_entry_activated(RingMainWindow* self)
     auto* priv = RING_MAIN_WINDOW_GET_PRIVATE(RING_MAIN_WINDOW(self));
 
     // Select the first conversation of the list
-    auto& conversationModel = priv->cpp->accountContainer_->info.conversationModel;
+    auto& conversationModel = priv->cpp->accountInfo_->conversationModel;
     auto conversations = conversationModel->allFilteredConversations();
 
     const gchar *text = gtk_entry_get_text(GTK_ENTRY(priv->search_entry));
@@ -402,7 +403,7 @@ on_search_entry_key_released(G_GNUC_UNUSED GtkEntry* search_entry, GdkEventKey*
 
     // if esc key pressed, clear the regex (keep the text, the user might not want to actually delete it)
     if (key->keyval == GDK_KEY_Escape) {
-        priv->cpp->accountContainer_->info.conversationModel->setFilter("");
+        priv->cpp->accountInfo_->conversationModel->setFilter("");
         return GDK_EVENT_STOP;
     }
 
@@ -427,8 +428,8 @@ on_dtmf_pressed(RingMainWindow* self, GdkEventKey* event, gpointer user_data)
     if (GTK_IS_ENTRY(focus))
         return GDK_EVENT_PROPAGATE;
 
-    if (priv->cpp->accountContainer_ &&
-        priv->cpp->accountContainer_->info.profileInfo.type != lrc::api::profile::Type::SIP)
+    if (priv->cpp->accountInfo_ &&
+        priv->cpp->accountInfo_->profileInfo.type != lrc::api::profile::Type::SIP)
         return GDK_EVENT_PROPAGATE;
 
     /* filter out cretain MOD masked key presses so that, for example, 'Ctrl+c'
@@ -454,7 +455,7 @@ on_dtmf_pressed(RingMainWindow* self, GdkEventKey* event, gpointer user_data)
     guint32 unicode_val = gdk_keyval_to_unicode(event->keyval);
     QString val = QString::fromUcs4(&unicode_val, 1);
     g_debug("attemptingto play DTMF tone during ongoing call: %s", val.toUtf8().constData());
-    priv->cpp->accountContainer_->info.callModel->playDTMF(current_item.callId, val.toStdString());
+    priv->cpp->accountInfo_->callModel->playDTMF(current_item.callId, val.toStdString());
     // always propogate the key, so we don't steal accelerators/shortcuts
     return GDK_EVENT_PROPAGATE;
 }
@@ -468,10 +469,10 @@ on_tab_changed(GtkNotebook* notebook, GtkWidget* page, guint page_num, RingMainW
     g_return_if_fail(IS_RING_MAIN_WINDOW(self));
     auto* priv = RING_MAIN_WINDOW_GET_PRIVATE(RING_MAIN_WINDOW(self));
 
-    auto newType = page_num == 0 ? priv->cpp->accountContainer_->info.profileInfo.type : lrc::api::profile::Type::PENDING;
+    auto newType = page_num == 0 ? priv->cpp->accountInfo_->profileInfo.type : lrc::api::profile::Type::PENDING;
     if (priv->cpp->currentTypeFilter_ != newType) {
         priv->cpp->currentTypeFilter_ = newType;
-        priv->cpp->accountContainer_->info.conversationModel->setFilter(priv->cpp->currentTypeFilter_);
+        priv->cpp->accountInfo_->conversationModel->setFilter(priv->cpp->currentTypeFilter_);
     }
 }
 
@@ -650,9 +651,9 @@ CppImpl::init()
         updateLrc(activeAccountId);
     } else {
         // No enabled account: create empty widgets
-        widgets->treeview_conversations = conversations_view_new(nullptr);
+        widgets->treeview_conversations = conversations_view_new(accountInfo_);
         gtk_container_add(GTK_CONTAINER(widgets->scrolled_window_smartview), widgets->treeview_conversations);
-        widgets->treeview_contact_requests = conversations_view_new(nullptr);
+        widgets->treeview_contact_requests = conversations_view_new(accountInfo_);
         gtk_container_add(GTK_CONTAINER(widgets->scrolled_window_contact_requests), widgets->treeview_contact_requests);
     }
 
@@ -749,7 +750,7 @@ CppImpl::init()
     g_signal_connect(widgets->notebook_contacts, "switch-page", G_CALLBACK(on_tab_changed), self);
 
     /* welcome/default view */
-    widgets->welcome_view = ring_welcome_view_new(accountContainer_.get());
+    widgets->welcome_view = ring_welcome_view_new(accountInfo_);
     g_object_ref(widgets->welcome_view); // increase ref because don't want it to be destroyed when not displayed
     gtk_container_add(GTK_CONTAINER(widgets->frame_call), widgets->welcome_view);
     gtk_widget_show(widgets->welcome_view);
@@ -811,12 +812,12 @@ CppImpl::init()
     // initialize the pending contact request icon.
     refreshPendingContactRequestTab();
 
-    if (accountContainer_) {
-        auto& conversationModel = accountContainer_->info.conversationModel;
+    if (accountInfo_) {
+        auto& conversationModel = accountInfo_->conversationModel;
         auto conversations = conversationModel->allFilteredConversations();
         for (const auto& conversation: conversations) {
             if (!conversation.callId.empty()) {
-                accountContainer_->info.conversationModel->selectConversation(conversation.uid);
+                accountInfo_->conversationModel->selectConversation(conversation.uid);
             }
         }
     }
@@ -894,7 +895,7 @@ GtkWidget*
 CppImpl::displayIncomingView(lrc::api::conversation::Info conversation)
 {
     chatViewConversation_.reset(new lrc::api::conversation::Info(conversation));
-    return incoming_call_view_new(webkitChatContainer(), accountContainer_.get(), chatViewConversation_.get());
+    return incoming_call_view_new(webkitChatContainer(), accountInfo_, chatViewConversation_.get());
 }
 
 GtkWidget*
@@ -902,11 +903,11 @@ CppImpl::displayCurrentCallView(lrc::api::conversation::Info conversation)
 {
     chatViewConversation_.reset(new lrc::api::conversation::Info(conversation));
     auto* new_view = current_call_view_new(webkitChatContainer(),
-                                           accountContainer_.get(), chatViewConversation_.get());
+                                           accountInfo_, chatViewConversation_.get());
 
     try {
         auto contactUri = chatViewConversation_->participants.front();
-        auto contactInfo = accountContainer_->info.contactModel->getContact(contactUri);
+        auto contactInfo = accountInfo_->contactModel->getContact(contactUri);
         if (auto chat_view = current_call_view_get_chat_view(CURRENT_CALL_VIEW(new_view))) {
             auto isPending = contactInfo.profileInfo.type == lrc::api::profile::Type::PENDING;
             chat_view_update_temporary(CHAT_VIEW(chat_view),
@@ -924,7 +925,7 @@ GtkWidget*
 CppImpl::displayChatView(lrc::api::conversation::Info conversation)
 {
     chatViewConversation_.reset(new lrc::api::conversation::Info(conversation));
-    auto* new_view = chat_view_new(webkitChatContainer(), accountContainer_.get(), chatViewConversation_.get());
+    auto* new_view = chat_view_new(webkitChatContainer(), accountInfo_, chatViewConversation_.get());
     g_signal_connect_swapped(new_view, "hide-view-clicked", G_CALLBACK(on_hide_view_clicked), self);
     return new_view;
 }
@@ -988,10 +989,10 @@ CppImpl::resetToWelcome()
 void
 CppImpl::refreshPendingContactRequestTab()
 {
-    if (not accountContainer_)
+    if (!accountInfo_)
         return;
 
-    auto hasPendingRequests = accountContainer_->info.contactModel->hasPendingRequests();
+    auto hasPendingRequests = accountInfo_->contactModel->hasPendingRequests();
     gtk_widget_set_visible(widgets->scrolled_window_contact_requests, hasPendingRequests);
     gtk_notebook_set_show_tabs(GTK_NOTEBOOK(widgets->notebook_contacts), hasPendingRequests);
 
@@ -1093,7 +1094,7 @@ void
 CppImpl::changeAccountSelection(const std::string& id)
 {
     // already selected?
-    if (id == accountContainer_->info.id)
+    if (id == accountInfo_->id)
         return;
 
     if (auto* model = gtk_combo_box_get_model(GTK_COMBO_BOX(widgets->combobox_account_selector))) {
@@ -1123,7 +1124,7 @@ CppImpl::onAccountSelectionChange(const std::string& id)
     // Show conversation panel
     gtk_notebook_set_current_page(GTK_NOTEBOOK(widgets->notebook_contacts), 0);
     // Update the welcome view
-    ring_welcome_update_view(RING_WELCOME_VIEW(widgets->welcome_view), accountContainer_.get());
+    ring_welcome_update_view(RING_WELCOME_VIEW(widgets->welcome_view));
 }
 
 void
@@ -1185,7 +1186,7 @@ CppImpl::leaveSettingsView()
      * obsolete messages. It will also ensure to refresh last interaction printed in the conversations list.
      */
     if (has_cleared_all_history) {
-        onAccountSelectionChange(accountContainer_->info.id);
+        onAccountSelectionChange(accountInfo_->id);
         resetToWelcome();
         has_cleared_all_history = false;
     }
@@ -1219,9 +1220,9 @@ CppImpl::updateLrc(const std::string& id, const std::string& accountIdToFlagFree
 
     // Get the account selected
     if (!id.empty())
-        accountContainer_.reset(new AccountContainer(lrc_->getAccountModel().getAccountInfo(id)));
+        accountInfo_ = &lrc_->getAccountModel().getAccountInfo(id);
     else
-        accountContainer_.reset();
+        accountInfo_ = nullptr;
 
     // Reinit tree views
     if (widgets->treeview_conversations) {
@@ -1229,7 +1230,7 @@ CppImpl::updateLrc(const std::string& id, const std::string& accountIdToFlagFree
         gtk_tree_selection_unselect_all(GTK_TREE_SELECTION(selection_conversations));
         gtk_widget_destroy(widgets->treeview_conversations);
     }
-    widgets->treeview_conversations = conversations_view_new(accountContainer_.get());
+    widgets->treeview_conversations = conversations_view_new(accountInfo_);
     gtk_container_add(GTK_CONTAINER(widgets->scrolled_window_smartview), widgets->treeview_conversations);
 
     if (widgets->treeview_contact_requests) {
@@ -1237,29 +1238,29 @@ CppImpl::updateLrc(const std::string& id, const std::string& accountIdToFlagFree
         gtk_tree_selection_unselect_all(GTK_TREE_SELECTION(selection_conversations));
         gtk_widget_destroy(widgets->treeview_contact_requests);
     }
-    widgets->treeview_contact_requests = conversations_view_new(accountContainer_.get());
+    widgets->treeview_contact_requests = conversations_view_new(accountInfo_);
     gtk_container_add(GTK_CONTAINER(widgets->scrolled_window_contact_requests), widgets->treeview_contact_requests);
 
-    if (!accountContainer_) return;
+    if (!accountInfo_) return;
 
     // Connect to signals from LRC
-    historyClearedConnection_ = QObject::connect(&*accountContainer_->info.conversationModel,
+    historyClearedConnection_ = QObject::connect(&*accountInfo_->conversationModel,
                                                  &lrc::api::ConversationModel::conversationCleared,
                                                  [this] (const std::string& id) { slotConversationCleared(id); });
 
-    modelSortedConnection_ = QObject::connect(&*accountContainer_->info.conversationModel,
+    modelSortedConnection_ = QObject::connect(&*accountInfo_->conversationModel,
                                               &lrc::api::ConversationModel::modelSorted,
                                               [this] { slotModelSorted(); });
 
-    filterChangedConnection_ = QObject::connect(&*accountContainer_->info.conversationModel,
+    filterChangedConnection_ = QObject::connect(&*accountInfo_->conversationModel,
                                                 &lrc::api::ConversationModel::filterChanged,
                                                 [this] { slotFilterChanged(); });
 
-    newConversationConnection_ = QObject::connect(&*accountContainer_->info.conversationModel,
+    newConversationConnection_ = QObject::connect(&*accountInfo_->conversationModel,
                                                   &lrc::api::ConversationModel::newConversation,
                                                   [this] (const std::string& id) { slotNewConversation(id); });
 
-    conversationRemovedConnection_ = QObject::connect(&*accountContainer_->info.conversationModel,
+    conversationRemovedConnection_ = QObject::connect(&*accountInfo_->conversationModel,
                                                       &lrc::api::ConversationModel::conversationRemoved,
                                                       [this] (const std::string& id) { slotConversationRemoved(id); });
 
@@ -1276,9 +1277,9 @@ CppImpl::updateLrc(const std::string& id, const std::string& accountIdToFlagFree
                                                    [this] (const std::string& id, lrc::api::conversation::Info origin) { slotShowIncomingCallView(id, origin); });
 
     const gchar *text = gtk_entry_get_text(GTK_ENTRY(widgets->search_entry));
-    currentTypeFilter_ = accountContainer_->info.profileInfo.type;
-    accountContainer_->info.conversationModel->setFilter(text);
-    accountContainer_->info.conversationModel->setFilter(currentTypeFilter_);
+    currentTypeFilter_ = accountInfo_->profileInfo.type;
+    accountInfo_->conversationModel->setFilter(text);
+    accountInfo_->conversationModel->setFilter(currentTypeFilter_);
 }
 
 void
@@ -1316,10 +1317,9 @@ CppImpl::slotAccountRemovedFromLrc(const std::string& id)
 void
 CppImpl::slotAccountStatusChanged(const std::string& id)
 {
-    if (not accountContainer_ ) {
+    if (!accountInfo_) {
         updateLrc(id);
-        ring_welcome_update_view(RING_WELCOME_VIEW(widgets->welcome_view),
-                                 accountContainer_.get());
+        ring_welcome_update_view(RING_WELCOME_VIEW(widgets->welcome_view));
         return;
     }
 
@@ -1337,7 +1337,7 @@ CppImpl::slotAccountStatusChanged(const std::string& id)
     if (enabledAccounts == 0) {
         updateLrc("");
         changeView(RING_WELCOME_VIEW_TYPE);
-        ring_welcome_update_view(RING_WELCOME_VIEW(widgets->welcome_view), nullptr);
+        ring_welcome_update_view(RING_WELCOME_VIEW(widgets->welcome_view));
     }
 }
 
@@ -1393,7 +1393,7 @@ CppImpl::slotFilterChanged()
         current_item = incoming_call_view_get_conversation(INCOMING_CALL_VIEW(old_view));
     conversations_view_select_conversation(CONVERSATIONS_VIEW(widgets->treeview_conversations), current_item.uid);
     // Get if conversation still exists.
-    auto& conversationModel = accountContainer_->info.conversationModel;
+    auto& conversationModel = accountInfo_->conversationModel;
     auto conversations = conversationModel->allFilteredConversations();
     auto isInConv = std::find_if(
         conversations.begin(), conversations.end(),
@@ -1409,16 +1409,16 @@ void
 CppImpl::slotNewConversation(const std::string& uid)
 {
     gtk_notebook_set_current_page(GTK_NOTEBOOK(widgets->notebook_contacts), 0);
-    accountContainer_->info.conversationModel->setFilter(lrc::api::profile::Type::RING);
+    accountInfo_->conversationModel->setFilter(lrc::api::profile::Type::RING);
     gtk_entry_set_text(GTK_ENTRY(widgets->search_entry), "");
-    accountContainer_->info.conversationModel->setFilter("");
+    accountInfo_->conversationModel->setFilter("");
     // Select new conversation if contact added
     auto* old_view = gtk_bin_get_child(GTK_BIN(widgets->frame_call));
     if (IS_RING_WELCOME_VIEW(old_view) || (IS_CHAT_VIEW(old_view) && chat_view_get_temporary(CHAT_VIEW(old_view)))) {
-        accountContainer_->info.conversationModel->selectConversation(uid);
+        accountInfo_->conversationModel->selectConversation(uid);
         try {
             auto contactUri =  chatViewConversation_->participants.front();
-            auto contactInfo = accountContainer_->info.contactModel->getContact(contactUri);
+            auto contactInfo = accountInfo_->contactModel->getContact(contactUri);
             auto isPending = contactInfo.profileInfo.type == lrc::api::profile::Type::PENDING;
             chat_view_update_temporary(CHAT_VIEW(gtk_bin_get_child(GTK_BIN(widgets->frame_call))),
                                        isPending || contactInfo.profileInfo.type == lrc::api::profile::Type::TEMPORARY,
@@ -1456,7 +1456,7 @@ CppImpl::slotShowChatView(const std::string& id, lrc::api::conversation::Info or
     // Do not show a conversation without any participants
     if (origin.participants.empty()) return;
     auto firstContactUri = origin.participants.front();
-    auto contactInfo = accountContainer_->info.contactModel->getContact(firstContactUri);
+    auto contactInfo = accountInfo_->contactModel->getContact(firstContactUri);
     // change view if necessary or just update temporary
     if (current_item.uid != origin.uid) {
         changeView(CHAT_VIEW_TYPE, origin);
diff --git a/src/ringwelcomeview.cpp b/src/ringwelcomeview.cpp
index 6de165ba..4391f119 100644
--- a/src/ringwelcomeview.cpp
+++ b/src/ringwelcomeview.cpp
@@ -52,7 +52,7 @@ struct _RingWelcomeViewPrivate
     GtkWidget *button_qrcode;
     GtkWidget *revealer_qrcode;
 
-    AccountContainer* accountContainer_;
+    AccountInfoPointer const *accountInfo_;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE(RingWelcomeView, ring_welcome_view, GTK_TYPE_SCROLLED_WINDOW);
@@ -63,14 +63,11 @@ static gboolean   draw_qrcode(GtkWidget*,cairo_t*,RingWelcomeView*);
 static void       switch_qrcode(RingWelcomeView* self);
 
 void
-ring_welcome_update_view(RingWelcomeView* self, AccountContainer* accountContainer) {
+ring_welcome_update_view(RingWelcomeView* self) {
     auto priv = RING_WELCOME_VIEW_GET_PRIVATE(self);
 
-    if (accountContainer)
-        priv->accountContainer_ = accountContainer;
-
     // Only draw a basic view for SIP accounts
-    if (not accountContainer || priv->accountContainer_->info.profileInfo.type == lrc::api::profile::Type::SIP) {
+    if (not *priv->accountInfo_ || (*priv->accountInfo_)->profileInfo.type == lrc::api::profile::Type::SIP) {
         gtk_widget_hide(priv->button_qrcode);
         gtk_widget_hide(priv->label_ringid);
         gtk_widget_hide(priv->label_explanation);
@@ -82,21 +79,21 @@ ring_welcome_update_view(RingWelcomeView* self, AccountContainer* accountContain
 
     // Get registeredName, else the Ring Id
     gchar *ring_id = nullptr;
-    if(! priv->accountContainer_->info.registeredName.empty()){
+    if(! (*priv->accountInfo_)->registeredName.empty()){
         gtk_label_set_text(
             GTK_LABEL(priv->label_explanation),
             _("This is your Ring username.\nCopy and share it with your friends!")
         );
         ring_id = g_markup_printf_escaped("<span fgcolor=\"black\">ring:%s</span>",
-                                          priv->accountContainer_->info.registeredName.c_str());
+                                          (*priv->accountInfo_)->registeredName.c_str());
     }
-    else if (!priv->accountContainer_->info.profileInfo.uri.empty()) {
+    else if (!(*priv->accountInfo_)->profileInfo.uri.empty()) {
         gtk_label_set_text(
             GTK_LABEL(priv->label_explanation),
             C_("Do not translate \"RingID\"", "This is your RingID.\nCopy and share it with your friends!")
         );
         ring_id = g_markup_printf_escaped("<span fgcolor=\"black\">%s</span>",
-                                          priv->accountContainer_->info.profileInfo.uri.c_str());
+                                          (*priv->accountInfo_)->profileInfo.uri.c_str());
     } else {
         gtk_label_set_text(GTK_LABEL(priv->label_explanation), NULL);
         ring_id = {};
@@ -232,12 +229,12 @@ ring_welcome_view_class_init(RingWelcomeViewClass *klass)
 }
 
 GtkWidget *
-ring_welcome_view_new(AccountContainer* accountContainer)
+ring_welcome_view_new(AccountInfoPointer const & accountInfo)
 {
     gpointer self = g_object_new(RING_WELCOME_VIEW_TYPE, NULL);
     auto priv = RING_WELCOME_VIEW_GET_PRIVATE(self);
-    priv->accountContainer_ = accountContainer;
-    ring_welcome_update_view(RING_WELCOME_VIEW(self), accountContainer);
+    priv->accountInfo_ = &accountInfo;
+    ring_welcome_update_view(RING_WELCOME_VIEW(self));
 
     return (GtkWidget *)self;
 }
@@ -250,7 +247,7 @@ draw_qrcode(G_GNUC_UNUSED GtkWidget* diese,
 {
     auto priv = RING_WELCOME_VIEW_GET_PRIVATE(self);
 
-    auto rcode = QRcode_encodeString(priv->accountContainer_->info.profileInfo.uri.c_str(),
+    auto rcode = QRcode_encodeString((*priv->accountInfo_)->profileInfo.uri.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
diff --git a/src/ringwelcomeview.h b/src/ringwelcomeview.h
index cf3b05bb..b5b09a05 100644
--- a/src/ringwelcomeview.h
+++ b/src/ringwelcomeview.h
@@ -23,7 +23,9 @@
 
 #include <gtk/gtk.h>
 
-#include "accountcontainer.h"
+#include "api/account.h"
+
+#include "accountinfopointer.h"
 
 G_BEGIN_DECLS
 
@@ -37,7 +39,7 @@ typedef struct _RingWelcomeView      RingWelcomeView;
 typedef struct _RingWelcomeViewClass RingWelcomeViewClass;
 
 GType             ring_welcome_view_get_type (void) G_GNUC_CONST;
-GtkWidget*        ring_welcome_view_new      (AccountContainer* accountContainer);
-void              ring_welcome_update_view   (RingWelcomeView* self, AccountContainer* accountContainer = nullptr);
+GtkWidget*        ring_welcome_view_new      (AccountInfoPointer const & accountInfo);
+void              ring_welcome_update_view   (RingWelcomeView* self);
 
 G_END_DECLS
-- 
GitLab