diff --git a/core/account.cpp b/core/account.cpp
index 98862a4..0970a6e 100644
--- a/core/account.cpp
+++ b/core/account.cpp
@@ -735,7 +735,7 @@ void Core::Account::requestInfo(const QString& jid) {
 void Core::Account::updateInfo(const Shared::Info& info) {
     //TODO switch case of what kind of entity this info update is about
     //right now it could be only about myself
-    vh->uploadVCard(info.vcard);
+    vh->uploadVCard(info.getVCardRef());
 }
 
 QString Core::Account::getAvatarPath() const {
diff --git a/core/conference.cpp b/core/conference.cpp
index a984f41..065490c 100644
--- a/core/conference.cpp
+++ b/core/conference.cpp
@@ -339,18 +339,16 @@ bool Core::Conference::setAvatar(const QByteArray& data, Archive::AvatarInfo& in
     return result;
 }
 
-Shared::VCard Core::Conference::handleResponseVCard(const QXmppVCardIq& card, const QString &resource)
+void Core::Conference::handleResponseVCard(const QXmppVCardIq& card, const QString &resource, Shared::VCard& out)
 {
-    Shared::VCard result = RosterItem::handleResponseVCard(card, resource);
+    RosterItem::handleResponseVCard(card, resource, out);
     
     if (resource.size() > 0) {
         emit changeParticipant(resource, {
-            {"avatarState", static_cast<uint>(result.getAvatarType())},
-            {"avatarPath", result.getAvatarPath()}
+            {"avatarState", static_cast<uint>(out.getAvatarType())},
+            {"avatarPath", out.getAvatarPath()}
         });
     }
-    
-    return result;
 }
 
 QMap<QString, QVariant> Core::Conference::getAllAvatars() const
diff --git a/core/conference.h b/core/conference.h
index 4e0e463..41141ad 100644
--- a/core/conference.h
+++ b/core/conference.h
@@ -52,7 +52,7 @@ public:
     void setAutoJoin(bool p_autoJoin);
     void handlePresence(const QXmppPresence & pres) override;
     bool setAutoGeneratedAvatar(const QString& resource = "") override;
-    Shared::VCard handleResponseVCard(const QXmppVCardIq & card, const QString &resource) override;
+    void handleResponseVCard(const QXmppVCardIq & card, const QString &resource, Shared::VCard& out) override;
     QMap<QString, QVariant> getAllAvatars() const;
     
 signals:
diff --git a/core/handlers/vcardhandler.cpp b/core/handlers/vcardhandler.cpp
index ca8b29b..33c9cdb 100644
--- a/core/handlers/vcardhandler.cpp
+++ b/core/handlers/vcardhandler.cpp
@@ -101,7 +101,7 @@ void Core::VCardHandler::onVCardReceived(const QXmppVCardIq& card) {
     }
 
     Shared::Info info(jid, Shared::EntryType::contact);
-    info.vcard = item->handleResponseVCard(card, resource);
+    item->handleResponseVCard(card, resource, info.getVCardRef());
 
     emit acc->infoReady(info);
 }
@@ -187,14 +187,15 @@ void Core::VCardHandler::onOwnVCardReceived(const QXmppVCardIq& card) {
 
     ownVCardRequestInProgress = false;
 
-    Shared::Info info(acc->getBareJid(), Shared::EntryType::ownAccount, true);
-    initializeVCard(info.vcard, card);
+    Shared::Info info(acc->getBareJid(), Shared::EntryType::ownAccount);
+    Shared::VCard& vCard = info.getVCardRef();
+    initializeVCard(vCard, card);
 
     if (avatarType.size() > 0) {
-        info.vcard.setAvatarType(Shared::Avatar::valid);
-        info.vcard.setAvatarPath(path + "avatar." + avatarType);
+        vCard.setAvatarType(Shared::Avatar::valid);
+        vCard.setAvatarPath(path + "avatar." + avatarType);
     } else {
-        info.vcard.setAvatarType(Shared::Avatar::empty);
+        vCard.setAvatarType(Shared::Avatar::empty);
     }
 
     emit acc->infoReady(info);
diff --git a/core/rosteritem.cpp b/core/rosteritem.cpp
index 1b8d1e6..0bac4a4 100644
--- a/core/rosteritem.cpp
+++ b/core/rosteritem.cpp
@@ -506,14 +506,13 @@ bool Core::RosterItem::readAvatarInfo(Archive::AvatarInfo& target, const QString
     return archive->readAvatarInfo(target, resource);
 }
 
-Shared::VCard Core::RosterItem::handleResponseVCard(const QXmppVCardIq& card, const QString& resource)
+void Core::RosterItem::handleResponseVCard(const QXmppVCardIq& card, const QString& resource, Shared::VCard& vCard)
 {
     Archive::AvatarInfo info;
     Archive::AvatarInfo newInfo;
     bool hasAvatar = readAvatarInfo(info, resource);
     
     QByteArray ava = card.photo();
-    Shared::VCard vCard;
     initializeVCard(vCard, card);
     Shared::Avatar type = Shared::Avatar::empty;
     QString path = "";
@@ -546,8 +545,6 @@ Shared::VCard Core::RosterItem::handleResponseVCard(const QXmppVCardIq& card, co
     if (resource.size() == 0) {
         emit avatarChanged(vCard.getAvatarType(), vCard.getAvatarPath());
     }
-    
-    return vCard;
 }
 
 void Core::RosterItem::clearArchiveRequests()
diff --git a/core/rosteritem.h b/core/rosteritem.h
index 5f99017..7c82945 100644
--- a/core/rosteritem.h
+++ b/core/rosteritem.h
@@ -72,7 +72,7 @@ public:
     QString folderPath() const;
     bool readAvatarInfo(Archive::AvatarInfo& target, const QString& resource = "") const;
     virtual bool setAutoGeneratedAvatar(const QString& resource = "");
-    virtual Shared::VCard handleResponseVCard(const QXmppVCardIq& card, const QString& resource);
+    virtual void handleResponseVCard(const QXmppVCardIq& card, const QString& resource, Shared::VCard& out);
     virtual void handlePresence(const QXmppPresence& pres) = 0;
     
     bool changeMessage(const QString& id, const QMap<QString, QVariant>& data);
diff --git a/shared/info.cpp b/shared/info.cpp
index a0ac299..c0d6f26 100644
--- a/shared/info.cpp
+++ b/shared/info.cpp
@@ -16,32 +16,315 @@
 
 #include "info.h"
 
-Shared::Info::Info(const QString& p_jid, EntryType p_type, bool p_editable):
-    type(p_type),
-    jid(p_jid),
-    editable(p_editable),
-    vcard(),
-    activeKeys(),
-    inactiveKeys()
-{}
+Shared::Info::Info(const QString& addr, EntryType tp):
+    type(tp),
+    address(addr),
+    vcard(nullptr),
+    activeKeys(nullptr),
+    inactiveKeys(nullptr)
+{
+    switch (type) {
+        case EntryType::none:
+            break;
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            vcard = new VCard();
+            activeKeys = new std::list<KeyInfo>();
+            inactiveKeys = new std::list<KeyInfo>();
+            break;
+        default:
+            throw 352;
+    }
+}
 
 Shared::Info::Info():
-    type(EntryType::contact),
-    jid(),
-    editable(false),
-    vcard(),
-    activeKeys(),
-    inactiveKeys()
+    type(EntryType::none),
+    address(""),
+    vcard(nullptr),
+    activeKeys(nullptr),
+    inactiveKeys(nullptr)
 {}
 
 Shared::Info::Info(const Shared::Info& other):
     type(other.type),
-    jid(other.jid),
-    editable(other.editable),
-    vcard(other.vcard),
-    activeKeys(other.activeKeys),
-    inactiveKeys(other.inactiveKeys)
-{}
+    address(other.address),
+    vcard(nullptr),
+    activeKeys(nullptr),
+    inactiveKeys(nullptr)
+{
+    switch (type) {
+        case EntryType::none:
+            break;
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            vcard = new VCard(other.getVCardRef());
+            activeKeys = new std::list<KeyInfo>(other.getActiveKeysRef());
+            inactiveKeys = new std::list<KeyInfo>(other.getInactiveKeysRef());
+            break;
+        default:
+            throw 353;
+    }
+}
 
-Shared::Info::~Info()
-{}
+Shared::Info::~Info() {
+    turnIntoNone();
+}
+
+void Shared::Info::turnIntoNone() {
+    switch (type) {
+        case EntryType::none:
+            break;
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            delete vcard;
+            vcard = nullptr;
+            delete activeKeys;
+            activeKeys = nullptr;
+            delete inactiveKeys;
+            inactiveKeys = nullptr;
+            break;
+        default:
+            break;
+    }
+    type = EntryType::none;
+}
+
+void Shared::Info::turnIntoContact(
+    const Shared::VCard& crd,
+    const std::list<KeyInfo>& aks,
+    const std::list<KeyInfo>& iaks
+) {
+    switch (type) {
+        case EntryType::none:
+            vcard = new VCard(crd);
+            activeKeys = new std::list<KeyInfo>(aks);
+            inactiveKeys = new std::list<KeyInfo>(iaks);
+            break;
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            *vcard = crd;
+            *activeKeys = aks;
+            *inactiveKeys = iaks;
+            break;
+        default:
+            break;
+    }
+
+    type = EntryType::contact;
+}
+
+void Shared::Info::turnIntoContact(
+    Shared::VCard* crd,
+    std::list<KeyInfo>* aks,
+    std::list<KeyInfo>* iaks
+) {
+    switch (type) {
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            delete vcard;
+            delete activeKeys;
+            delete inactiveKeys;
+            [[fallthrough]];
+        case EntryType::none:
+            vcard = crd;
+            activeKeys = aks;
+            inactiveKeys = iaks;
+            break;
+        default:
+            break;
+    }
+
+    type = EntryType::contact;
+}
+
+void Shared::Info::turnIntoOwnAccount(
+    const Shared::VCard& crd,
+    const std::list<KeyInfo>& aks,
+    const std::list<KeyInfo>& iaks
+) {
+        switch (type) {
+        case EntryType::none:
+            vcard = new VCard(crd);
+            activeKeys = new std::list<KeyInfo>(aks);
+            inactiveKeys = new std::list<KeyInfo>(iaks);
+            break;
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            *vcard = crd;
+            *activeKeys = aks;
+            *inactiveKeys = iaks;
+            break;
+        default:
+            break;
+    }
+
+    type = EntryType::ownAccount;
+}
+
+void Shared::Info::turnIntoOwnAccount(
+    Shared::VCard* crd,
+    std::list<KeyInfo>* aks,
+    std::list<KeyInfo>* iaks
+) {
+    switch (type) {
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            delete vcard;
+            delete activeKeys;
+            delete inactiveKeys;
+            [[fallthrough]];
+        case EntryType::none:
+            vcard = crd;
+            activeKeys = aks;
+            inactiveKeys = iaks;
+            break;
+        default:
+            break;
+    }
+
+    type = EntryType::ownAccount;
+}
+
+void Shared::Info::setAddress(const QString& addr) {
+    address = addr;}
+
+QString Shared::Info::getAddress() const {
+    return address;}
+
+const QString& Shared::Info::getAddressRef() const {
+    return address;}
+
+Shared::EntryType Shared::Info::getType() const {
+    return type;}
+
+std::list<Shared::KeyInfo> & Shared::Info::getActiveKeysRef() {
+    switch (type) {
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            return *activeKeys;
+            break;
+        default:
+            throw 354;
+    }
+}
+
+const std::list<Shared::KeyInfo> & Shared::Info::getActiveKeysRef() const {
+    switch (type) {
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            return *activeKeys;
+            break;
+        default:
+            throw 355;
+    }
+}
+
+std::list<Shared::KeyInfo>* Shared::Info::getActiveKeys() {
+    switch (type) {
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            return activeKeys;
+            break;
+        default:
+            throw 356;
+    }
+}
+
+const std::list<Shared::KeyInfo>* Shared::Info::getActiveKeys() const {
+    switch (type) {
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            return activeKeys;
+            break;
+        default:
+            throw 357;
+    }
+}
+
+std::list<Shared::KeyInfo> & Shared::Info::getInactiveKeysRef() {
+    switch (type) {
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            return *inactiveKeys;
+            break;
+        default:
+            throw 358;
+    }
+}
+
+const std::list<Shared::KeyInfo> & Shared::Info::getInactiveKeysRef() const {
+    switch (type) {
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            return *inactiveKeys;
+            break;
+        default:
+            throw 359;
+    }
+}
+
+std::list<Shared::KeyInfo>* Shared::Info::getInactiveKeys() {
+    switch (type) {
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            return inactiveKeys;
+            break;
+        default:
+            throw 360;
+    }
+}
+
+const std::list<Shared::KeyInfo>* Shared::Info::getInactiveKeys() const {
+    switch (type) {
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            return inactiveKeys;
+            break;
+        default:
+            throw 361;
+    }
+}
+
+const Shared::VCard & Shared::Info::getVCardRef() const {
+    switch (type) {
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            return *vcard;
+            break;
+        default:
+            throw 362;
+    }
+}
+
+Shared::VCard & Shared::Info::getVCardRef()  {
+    switch (type) {
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            return *vcard;
+            break;
+        default:
+            throw 363;
+    }
+}
+
+const Shared::VCard * Shared::Info::getVCard() const {
+    switch (type) {
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            return vcard;
+            break;
+        default:
+            throw 364;
+    }
+}
+
+Shared::VCard * Shared::Info::getVCard() {
+    switch (type) {
+        case EntryType::contact:
+        case EntryType::ownAccount:
+            return vcard;
+            break;
+        default:
+            throw 365;
+    }
+}
diff --git a/shared/info.h b/shared/info.h
index 90248c3..b0f495e 100644
--- a/shared/info.h
+++ b/shared/info.h
@@ -34,16 +34,59 @@ namespace Shared {
 class Info {
 public:
     Info();
-    Info(const QString& jid, EntryType = EntryType::contact, bool editable = false);
+    Info(const QString& address, EntryType = EntryType::none);
     Info(const Info& other);
-    ~Info();
+    virtual ~Info();
 
+    QString getAddress() const;
+    const QString& getAddressRef() const;
+    void setAddress(const QString& address);
+
+    EntryType getType() const;
+    void turnIntoNone();
+    void turnIntoContact(
+        const VCard& card = VCard(),
+        const std::list<KeyInfo>& activeKeys = {},
+        const std::list<KeyInfo>& inactiveKeys = {}
+    );
+    void turnIntoContact(
+        VCard* card = new VCard,
+        std::list<KeyInfo>* activeKeys = new std::list<KeyInfo>,
+        std::list<KeyInfo>* inactiveKeys = new std::list<KeyInfo>
+    );
+    void turnIntoOwnAccount(
+        const VCard& card = VCard(),
+        const std::list<KeyInfo>& activeKeys = {},
+        const std::list<KeyInfo>& inactiveKeys = {}
+    );
+    void turnIntoOwnAccount(
+        VCard* card = new VCard,
+        std::list<KeyInfo>* activeKeys = new std::list<KeyInfo>,
+        std::list<KeyInfo>* inactiveKeys = new std::list<KeyInfo>
+    );
+
+    const VCard& getVCardRef() const;
+    VCard& getVCardRef();
+    const VCard* getVCard() const;
+    VCard* getVCard();
+
+    const std::list<KeyInfo>& getActiveKeysRef() const;
+    std::list<KeyInfo>& getActiveKeysRef();
+    const std::list<KeyInfo>* getActiveKeys() const;
+    std::list<KeyInfo>* getActiveKeys();
+
+    const std::list<KeyInfo>& getInactiveKeysRef() const;
+    std::list<KeyInfo>& getInactiveKeysRef();
+    const std::list<KeyInfo>* getInactiveKeys() const;
+    std::list<KeyInfo>* getInactiveKeys();
+
+private:
     EntryType type;
-    QString jid;
-    bool editable;
-    VCard vcard;
-    std::list<KeyInfo> activeKeys;
-    std::list<KeyInfo> inactiveKeys;
+    QString address;
+
+    VCard* vcard;
+    std::list<KeyInfo>* activeKeys;
+    std::list<KeyInfo>* inactiveKeys;
 };
 
 }
diff --git a/ui/squawk.cpp b/ui/squawk.cpp
index 2c969da..ce759ac 100644
--- a/ui/squawk.cpp
+++ b/ui/squawk.cpp
@@ -412,7 +412,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) {
 }
 
 void Squawk::responseInfo(const Shared::Info& info) {
-    std::map<QString, UI::Info*>::const_iterator itr = infoWidgets.find(info.jid);
+    std::map<QString, UI::Info*>::const_iterator itr = infoWidgets.find(info.getAddressRef());
     if (itr != infoWidgets.end()) {
         itr->second->setData(info);
         itr->second->hideProgress();
diff --git a/ui/widgets/info/contactgeneral.cpp b/ui/widgets/info/contactgeneral.cpp
index ccc6996..e469fcb 100644
--- a/ui/widgets/info/contactgeneral.cpp
+++ b/ui/widgets/info/contactgeneral.cpp
@@ -30,7 +30,6 @@ UI::ContactGeneral::ContactGeneral(QWidget* parent):
     currentAvatarType(Shared::Avatar::empty),
     currentAvatarPath(""),
     currentJid(""),
-    editable(false),
     avatarDiablog(nullptr)
 {
     m_ui->setupUi(this);
@@ -74,6 +73,9 @@ void UI::ContactGeneral::setEditable(bool edit) {
             m_ui->avatarButton->setMenu(nullptr);
         }
     }
+
+    m_ui->actionSetAvatar->setEnabled(edit);
+    m_ui->actionClearAvatar->setEnabled(false); //need to unlock it explicitly after the type of avatar is clear!
 }
 
 void UI::ContactGeneral::deleteAvatarDialog() {
@@ -92,7 +94,7 @@ void UI::ContactGeneral::initializeActions() {
     connect(setAvatar, &QAction::triggered, this, &UI::ContactGeneral::onSetAvatar);
     connect(clearAvatar, &QAction::triggered, this, &UI::ContactGeneral::onClearAvatar);
 
-    setAvatar->setEnabled(editable);
+    setAvatar->setEnabled(false);
     clearAvatar->setEnabled(false);
 }
 
@@ -138,7 +140,7 @@ void UI::ContactGeneral::updateAvatar() {
             qreal aspectRatio = w / h;
             m_ui->avatarButton->setIconSize(QSize(height * aspectRatio, height));
             m_ui->avatarButton->setIcon(QIcon(currentAvatarPath));
-            m_ui->actionClearAvatar->setEnabled(editable);
+            m_ui->actionClearAvatar->setEnabled(m_ui->actionSetAvatar->isEnabled());    //I assume that if set avatar is enabled then we can also clear
             break;
     }
 }
diff --git a/ui/widgets/info/contactgeneral.h b/ui/widgets/info/contactgeneral.h
index 2817e91..33b4c28 100644
--- a/ui/widgets/info/contactgeneral.h
+++ b/ui/widgets/info/contactgeneral.h
@@ -67,7 +67,6 @@ private:
     Shared::Avatar currentAvatarType;
     QString currentAvatarPath;
     QString currentJid;
-    bool editable;
     QFileDialog* avatarDiablog;
 
     static const std::set<QString> supportedTypes;
diff --git a/ui/widgets/info/info.cpp b/ui/widgets/info/info.cpp
index e951e97..a400f22 100644
--- a/ui/widgets/info/info.cpp
+++ b/ui/widgets/info/info.cpp
@@ -45,17 +45,19 @@ UI::Info::~Info() {
 
 void UI::Info::setData(const Shared::Info& info) {
     bool editable = false;
-    switch (info.type) {
+    switch (info.getType()) {
         case Shared::EntryType::ownAccount:
             editable = true;
+            [[fallthrough]];
         case Shared::EntryType::contact: {
-            QDateTime receivingTime = info.vcard.getReceivingTime();
+            const Shared::VCard card = info.getVCardRef();
+            QDateTime receivingTime = card.getReceivingTime();
             m_ui->receivingTimeLabel->show();
             m_ui->receivingTimeLabel->setText(tr("Received %1 at %2").arg(receivingTime.date().toString()).arg(receivingTime.time().toString()));
-            initializeContactGeneral(jid, info.vcard, editable);
-            initializeContactContacts(jid, info.vcard, editable);
-            initializeDescription(info.vcard.getDescription(), editable);
-            type = info.type;
+            initializeContactGeneral(jid, card, editable);
+            initializeContactContacts(jid, card, editable);
+            initializeDescription(card.getDescription(), editable);
+            type = info.getType();
         }
             break;
         default:
@@ -99,11 +101,13 @@ void UI::Info::initializeButtonBox() {
 
 void UI::Info::onButtonBoxAccepted() {
     if (type == Shared::EntryType::ownAccount) {
-        Shared::Info info;
-        contactGeneral->fillVCard(info.vcard);
-        contactContacts->fillVCard(info.vcard);
-        info.vcard.setDescription(description->description());
+        Shared::Info info(jid, Shared::EntryType::ownAccount);
+        Shared::VCard& card = info.getVCardRef();
+        contactGeneral->fillVCard(card);
+        contactContacts->fillVCard(card);
+        card.setDescription(description->description());
         emit saveInfo(info);
+        emit close();
     }
 }