diff --git a/core/account.cpp b/core/account.cpp
index c9e08eb..0f654fa 100644
--- a/core/account.cpp
+++ b/core/account.cpp
@@ -19,7 +19,6 @@
 #include "account.h"
 #include <QXmppMessage.h>
 #include <QDateTime>
-#include <QTimer>
 
 using namespace Core;
 
@@ -43,8 +42,8 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
     rcpm(new QXmppMessageReceiptManager()),
     contacts(),
     conferences(),
-    maxReconnectTimes(0),
-    reconnectTimes(0),
+    reconnectScheduled(false),
+    reconnectTimer(new QTimer),
     queuedContacts(),
     outOfRosterContacts(),
     pendingMessages(),
@@ -62,8 +61,7 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
     config.setAutoAcceptSubscriptions(true);
     //config.setAutoReconnectionEnabled(false);
     
-    QObject::connect(&client, &QXmppClient::connected, this, &Account::onClientConnected);
-    QObject::connect(&client, &QXmppClient::disconnected, this, &Account::onClientDisconnected);
+    QObject::connect(&client, &QXmppClient::stateChanged, this, &Account::onClientStateChange);
     QObject::connect(&client, &QXmppClient::presenceReceived, this, &Account::onPresenceReceived);
     QObject::connect(&client, &QXmppClient::messageReceived, mh, &MessageHandler::onMessageReceived);
     QObject::connect(&client, &QXmppClient::error, this, &Account::onClientError);
@@ -152,10 +150,26 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
     } else {
         presence.setVCardUpdateType(QXmppPresence::VCardUpdateNotReady);
     }
+    
+    reconnectTimer->setSingleShot(true);
+    QObject::connect(reconnectTimer, &QTimer::timeout, this, &Account::connect);
+    
+//     QXmppLogger* logger = new QXmppLogger(this);
+//     logger->setLoggingType(QXmppLogger::SignalLogging);
+//     client.setLogger(logger);
+//     
+//     QObject::connect(logger, &QXmppLogger::message, this, [](QXmppLogger::MessageType type, const QString& text){
+//         qDebug() << text;
+//     });
 }
 
 Account::~Account()
 {
+    if (reconnectScheduled) {
+        reconnectScheduled = false;
+        reconnectTimer->stop();
+    }
+    
     QObject::disconnect(network, &NetworkAccess::uploadFileComplete, mh, &MessageHandler::onFileUploaded);
     QObject::disconnect(network, &NetworkAccess::uploadFileError, mh, &MessageHandler::onFileUploadError);
     
@@ -167,6 +181,7 @@ Account::~Account()
         delete itr->second;
     }
     
+    delete reconnectTimer;
     delete rcpm;
     delete dm;
     delete um;
@@ -184,10 +199,8 @@ Shared::ConnectionState Core::Account::getState() const
 void Core::Account::connect()
 {
     if (state == Shared::ConnectionState::disconnected) {
-        reconnectTimes = maxReconnectTimes;
-        state = Shared::ConnectionState::connecting;
+        qDebug() << presence.availableStatusType();
         client.connectToServer(config, presence);
-        emit connectionStateChanged(state);
     } else {
         qDebug("An attempt to connect an account which is already connected, skipping");
     }
@@ -195,54 +208,63 @@ void Core::Account::connect()
 
 void Core::Account::disconnect()
 {
-    reconnectTimes = 0;
+    if (reconnectScheduled) {
+        reconnectScheduled = false;
+        reconnectTimer->stop();
+    }
     if (state != Shared::ConnectionState::disconnected) {
         clearConferences();
         client.disconnectFromServer();
-        state = Shared::ConnectionState::disconnected;
-        emit connectionStateChanged(state);
     }
 }
 
-void Core::Account::onClientConnected()
+void Core::Account::onClientStateChange(QXmppClient::State st)
 {
-    if (state == Shared::ConnectionState::connecting) {
-        reconnectTimes = maxReconnectTimes;
-        state = Shared::ConnectionState::connected;
-        dm->requestItems(getServer());
-        dm->requestInfo(getServer());
-        emit connectionStateChanged(state);
-    } else {
-        qDebug() << "Something weird had happened - xmpp client reported about successful connection but account wasn't in" << state << "state";
-    }
-}
-
-void Core::Account::onClientDisconnected()
-{
-    cancelHistoryRequests();
-    pendingVCardRequests.clear();
-    clearConferences();
-    if (state != Shared::ConnectionState::disconnected) {
-        if (reconnectTimes > 0) {
-            qDebug() << "Account" << name << "is reconnecting for" << reconnectTimes << "more times";
-            --reconnectTimes;
-            state = Shared::ConnectionState::connecting;
-            client.connectToServer(config, presence);
-            emit connectionStateChanged(state);
-        } else {
-            qDebug() << "Account" << name << "has been disconnected";
-            state = Shared::ConnectionState::disconnected;
-            emit connectionStateChanged(state);
+    switch (st) {
+        case QXmppClient::ConnectedState: {
+            if (state != Shared::ConnectionState::connected) {
+                if (client.isActive()) {
+                    Shared::ConnectionState os = state;
+                    state = Shared::ConnectionState::connected;
+                    if (os == Shared::ConnectionState::connecting) {
+                        dm->requestItems(getServer());
+                        dm->requestInfo(getServer());
+                    }
+                    emit connectionStateChanged(state);
+                }
+            } else {
+                qDebug()    << "Something weird happened - xmpp client of account" << name
+                            << "reported about successful connection but account was in" << state << "state";
+            }
         }
-    } else {
-        //qDebug("Something weird had happened - xmpp client reported about being disconnection but account was already in disconnected state");
+            break;
+        case QXmppClient::ConnectingState: {
+            if (state != Shared::ConnectionState::connecting) {
+                state = Shared::ConnectionState::connecting;
+                emit connectionStateChanged(state);
+            }
+        }
+            break;
+        case QXmppClient::DisconnectedState: {
+            cancelHistoryRequests();
+            pendingVCardRequests.clear();
+            if (state != Shared::ConnectionState::disconnected) {
+                state = Shared::ConnectionState::disconnected;
+                emit connectionStateChanged(state);
+            } else {
+                qDebug()    << "Something weird happened - xmpp client of account" << name
+                            << "reported about disconnection but account was in" << state << "state";
+            }
+        }
+            break;
     }
 }
 
 void Core::Account::reconnect()
 {
-    if (state == Shared::ConnectionState::connected) {
-        ++reconnectTimes;
+    if (state == Shared::ConnectionState::connected && !reconnectScheduled) {
+        reconnectScheduled = true;
+        reconnectTimer->start(500);
         client.disconnectFromServer();
     } else {
         qDebug() << "An attempt to reconnect account" << getName() << "which was not connected";
@@ -286,14 +308,6 @@ void Core::Account::onRosterReceived()
     }
 }
 
-void Core::Account::setReconnectTimes(unsigned int times)
-{
-    maxReconnectTimes = times;
-    if (state == Shared::ConnectionState::connected) {
-        reconnectTimes = times;
-    }
-}
-
 void Core::Account::onRosterItemAdded(const QString& bareJid)
 {
     addedAccount(bareJid);
@@ -589,14 +603,6 @@ void Core::Account::onMamMessageReceived(const QString& queryId, const QXmppMess
             QString jid = itr->second;
             RosterItem* item = getRosterItem(jid);
             
-            qDebug() << "archive for" << jid;
-            qDebug() << "id:" << msg.id();
-            qDebug() << "oid:" << msg.originId();
-            qDebug() << "sid:" << msg.stanzaId();
-            qDebug() << "rid:" << msg.replaceId();
-            qDebug() << "============================";
-            
-            
             Shared::Message sMsg(static_cast<Shared::Message::Type>(msg.type()));
             mh->initializeMessage(sMsg, msg, false, true, true);
             sMsg.setState(Shared::Message::State::sent);
@@ -645,49 +651,35 @@ void Core::Account::requestArchive(const QString& jid, int count, const QString&
         emit responseArchive(contact->jid, std::list<Shared::Message>());
     }
     
-    if (contact->getArchiveState() == RosterItem::empty && before.size() == 0) {
-        QXmppMessage msg(getFullJid(), jid, "", "");
-        QString last = Shared::generateUUID();
-        msg.setId(last);
-        if (contact->isMuc()) {
-            msg.setType(QXmppMessage::GroupChat);
-        } else {
-            msg.setType(QXmppMessage::Chat);
-        }
-        msg.setState(QXmppMessage::Active);
-        client.sendPacket(msg);
-        QTimer* timer = new QTimer;
-        QObject::connect(timer, &QTimer::timeout, [timer, contact, count, last](){
-            contact->requestFromEmpty(count, last);
-            timer->deleteLater();
-        });
-        
-        timer->setSingleShot(true);
-        timer->start(1000);
-    } else {
-        contact->requestHistory(count, before);
-    }
+    contact->requestHistory(count, before);
 }
 
 void Core::Account::onContactNeedHistory(const QString& before, const QString& after, const QDateTime& at)
 {
     RosterItem* contact = static_cast<RosterItem*>(sender());
-    QString to = "";
+
+    QString to = contact->jid;
     QXmppResultSetQuery query;
-    query.setMax(100);
-    if (before.size() > 0) {
-        query.setBefore(before);
-    }
     QDateTime start;
-    if (after.size() > 0) {     //there is some strange behavior of ejabberd server returning empty result set
-        if (at.isValid()) {     //there can be some useful information about it here https://github.com/processone/ejabberd/issues/2924
-            start = at;
-        } else {
-            query.setAfter(after);
+    query.setMax(100);
+    
+    if (contact->getArchiveState() == RosterItem::empty) {
+        query.setBefore(before);
+        qDebug() << "Requesting remote history from empty for" << contact->jid;
+    } else {
+        if (before.size() > 0) {
+            query.setBefore(before);
         }
+        if (after.size() > 0) {     //there is some strange behavior of ejabberd server returning empty result set
+            if (at.isValid()) {     //there can be some useful information about it here https://github.com/processone/ejabberd/issues/2924
+                start = at;
+            } else {
+                query.setAfter(after);
+            }
+        }
+        qDebug() << "Remote query for" << contact->jid << "from" << after << ", to" << before;
     }
     
-    qDebug() << "Remote query from" << after << ", to" << before;
     
     QString q = am->retrieveArchivedMessages(to, "", contact->jid, start, QDateTime(), query);
     achiveQueries.insert(std::make_pair(q, contact->jid));
@@ -704,7 +696,7 @@ void Core::Account::onMamResultsReceived(const QString& queryId, const QXmppResu
         RosterItem* ri = getRosterItem(jid);
         
         if (ri != 0) {
-            qDebug() << "Flushing messages for" << jid;
+            qDebug() << "Flushing messages for" << jid << ", complete:" << complete;
             ri->flushMessagesToArchive(complete, resultSetReply.first(), resultSetReply.last());
         }
     }
diff --git a/core/account.h b/core/account.h
index b0d5ee0..d31d066 100644
--- a/core/account.h
+++ b/core/account.h
@@ -25,6 +25,7 @@
 #include <QMimeDatabase>
 #include <QStandardPaths>
 #include <QDir>
+#include <QTimer>
 
 #include <map>
 #include <set>
@@ -66,10 +67,6 @@ public:
         QObject* parent = 0);
     ~Account();
     
-    void connect();
-    void disconnect();
-    void reconnect();
-    
     Shared::ConnectionState getState() const;
     QString getName() const;
     QString getLogin() const;
@@ -91,7 +88,6 @@ public:
     void sendMessage(const Shared::Message& data);
     void sendMessage(const Shared::Message& data, const QString& path);
     void requestArchive(const QString& jid, int count, const QString& before);
-    void setReconnectTimes(unsigned int times);
     void subscribeToContact(const QString& jid, const QString& reason);
     void unsubscribeFromContact(const QString& jid, const QString& reason);
     void removeContactRequest(const QString& jid);
@@ -107,6 +103,9 @@ public:
     void uploadVCard(const Shared::VCard& card);
     
 public slots:
+    void connect();
+    void disconnect();
+    void reconnect();
     void requestVCard(const QString& jid);
     
 signals:
@@ -154,8 +153,8 @@ private:
     QXmppMessageReceiptManager* rcpm;
     std::map<QString, Contact*> contacts;
     std::map<QString, Conference*> conferences;
-    unsigned int maxReconnectTimes;
-    unsigned int reconnectTimes;
+    bool reconnectScheduled;
+    QTimer* reconnectTimer;
     
     std::map<QString, QString> queuedContacts;
     std::set<QString> outOfRosterContacts;
@@ -172,8 +171,7 @@ private:
     MessageHandler* mh;
     
 private slots:
-    void onClientConnected();
-    void onClientDisconnected();
+    void onClientStateChange(QXmppClient::State state);
     void onClientError(QXmppClient::Error err);
     
     void onRosterReceived();
@@ -219,8 +217,6 @@ private:
     void handleNewContact(Contact* contact);
     void handleNewRosterItem(RosterItem* contact);
     void handleNewConference(Conference* contact);
-    bool handleChatMessage(const QXmppMessage& msg, bool outgoing = false, bool forwarded = false, bool guessing = false);
-    bool handleGroupMessage(const QXmppMessage& msg, bool outgoing = false, bool forwarded = false, bool guessing = false);
     void addNewRoom(const QString& jid, const QString& nick, const QString& roomName, bool autoJoin);
     void addToGroup(const QString& jid, const QString& group);
     void removeFromGroup(const QString& jid, const QString& group);
diff --git a/core/archive.cpp b/core/archive.cpp
index 179f33e..628723d 100644
--- a/core/archive.cpp
+++ b/core/archive.cpp
@@ -67,6 +67,7 @@ void Core::Archive::open(const QString& account)
         mdb_dbi_open(txn, "order", MDB_CREATE | MDB_INTEGERKEY, &order);
         mdb_dbi_open(txn, "stats", MDB_CREATE, &stats);
         mdb_dbi_open(txn, "avatars", MDB_CREATE, &avatars);
+        mdb_dbi_open(txn, "sid", MDB_CREATE, &sid);
         mdb_txn_commit(txn);
         
         mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn);
@@ -99,6 +100,7 @@ void Core::Archive::open(const QString& account)
 void Core::Archive::close()
 {
     if (opened) {
+        mdb_dbi_close(environment, sid);
         mdb_dbi_close(environment, avatars);
         mdb_dbi_close(environment, stats);
         mdb_dbi_close(environment, order);
@@ -139,12 +141,36 @@ bool Core::Archive::addElement(const Shared::Message& message)
             mdb_txn_abort(txn);
             return false;
         } else {
-            rc = mdb_txn_commit(txn);
-            if (rc) {
-                qDebug() << "A transaction error: " << mdb_strerror(rc);
-                return false;
+            if (message.getStanzaId().size() > 0) {
+                const std::string& szid = message.getStanzaId().toStdString();
+                
+                lmdbKey.mv_size = szid.size();
+                lmdbKey.mv_data = (char*)szid.c_str();
+                lmdbData.mv_size = id.size();
+                lmdbData.mv_data = (uint8_t*)id.data();
+                rc = mdb_put(txn, sid, &lmdbKey, &lmdbData, MDB_NOOVERWRITE);
+                
+                if (rc) {
+                    qDebug() << "An element stanzaId to id pair couldn't be inserted into the archive" << mdb_strerror(rc);
+                    mdb_txn_abort(txn);
+                    return false;
+                } else {
+                    rc = mdb_txn_commit(txn);
+                    if (rc) {
+                        qDebug() << "A transaction error: " << mdb_strerror(rc);
+                        return false;
+                    }
+                    return true;
+                }
+                
+            } else {
+                rc = mdb_txn_commit(txn);
+                if (rc) {
+                    qDebug() << "A transaction error: " << mdb_strerror(rc);
+                    return false;
+                }
+                return true;
             }
-            return true;
         }
     } else {
         qDebug() << "An element couldn't been added to the archive, skipping" << mdb_strerror(rc);
@@ -164,10 +190,12 @@ void Core::Archive::clear()
     mdb_drop(txn, main, 0);
     mdb_drop(txn, order, 0);
     mdb_drop(txn, stats, 0);
+    mdb_drop(txn, avatars, 0);
+    mdb_drop(txn, sid, 0);
     mdb_txn_commit(txn);
 }
 
-Shared::Message Core::Archive::getElement(const QString& id)
+Shared::Message Core::Archive::getElement(const QString& id) const
 {
     if (!opened) {
         throw Closed("getElement", jid.toStdString());
@@ -186,7 +214,7 @@ Shared::Message Core::Archive::getElement(const QString& id)
     }
 }
 
-Shared::Message Core::Archive::getMessage(const std::string& id, MDB_txn* txn)
+Shared::Message Core::Archive::getMessage(const std::string& id, MDB_txn* txn) const
 {
     MDB_val lmdbKey, lmdbData;
     lmdbKey.mv_size = id.size();
@@ -220,6 +248,7 @@ void Core::Archive::changeMessage(const QString& id, const QMap<QString, QVarian
     std::string strId(id.toStdString());
     try {
         Shared::Message msg = getMessage(strId, txn);
+        bool hadStanzaId = msg.getStanzaId().size() > 0;
         QDateTime oTime = msg.getTime();
         bool idChange = msg.change(data);
         
@@ -250,6 +279,19 @@ void Core::Archive::changeMessage(const QString& id, const QMap<QString, QVarian
                 throw Unknown(jid.toStdString(), mdb_strerror(rc));
             }
         }
+        
+        if (msg.getStanzaId().size() > 0 && (idChange || !hadStanzaId)) {
+            const std::string& szid = msg.getStanzaId().toStdString();
+            
+            lmdbData.mv_size = szid.size();
+            lmdbData.mv_data = (char*)szid.c_str();
+            rc = mdb_put(txn, sid, &lmdbData, &lmdbKey, 0);
+            
+            if (rc != 0) {
+                throw Unknown(jid.toStdString(), mdb_strerror(rc));
+            }
+        };
+        
         lmdbData.mv_size = ba.size();
         lmdbData.mv_data = (uint8_t*)ba.data();
         rc = mdb_put(txn, main, &lmdbKey, &lmdbData, 0);
@@ -395,7 +437,20 @@ unsigned int Core::Archive::addElements(const std::list<Shared::Message>& messag
             if (rc) {
                 qDebug() << "An element couldn't be inserted into the index, aborting the transaction" << mdb_strerror(rc);
             } else {
-                //qDebug() << "element added with id" << message.getId() << "stamp" << message.getTime();
+                if (message.getStanzaId().size() > 0) {
+                    const std::string& szid = message.getStanzaId().toStdString();
+                    
+                    lmdbKey.mv_size = szid.size();
+                    lmdbKey.mv_data = (char*)szid.c_str();
+                    lmdbData.mv_size = id.size();
+                    lmdbData.mv_data = (uint8_t*)id.data();
+                    rc = mdb_put(txn, sid, &lmdbKey, &lmdbData, MDB_NOOVERWRITE);
+                    
+                    if (rc) {
+                        qDebug() << "During bulk add an element stanzaId to id pair couldn't be inserted into the archive, continuing without stanzaId" << mdb_strerror(rc);
+                    }
+                    
+                }
                 success++;
             }
         } else {
@@ -536,6 +591,46 @@ void Core::Archive::setFromTheBeginning(bool is)
     }
 }
 
+QString Core::Archive::idByStanzaId(const QString& stanzaId) const
+{
+    if (!opened) {
+        throw Closed("idByStanzaId", jid.toStdString());
+    }
+    QString id;
+    std::string ssid = stanzaId.toStdString();
+    
+    MDB_txn *txn;
+    MDB_val lmdbKey, lmdbData;
+    lmdbKey.mv_size = ssid.size();
+    lmdbKey.mv_data = (char*)ssid.c_str();
+    mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn);
+    int rc = mdb_get(txn, sid, &lmdbKey, &lmdbData);
+    if (rc == 0) {
+        id = QString::fromStdString(std::string((char*)lmdbData.mv_data, lmdbData.mv_size));
+    }
+    mdb_txn_abort(txn);
+    
+    return id;
+}
+
+QString Core::Archive::stanzaIdById(const QString& id) const
+{
+    if (!opened) {
+        throw Closed("stanzaIdById", jid.toStdString());
+    }
+    
+    try {
+        Shared::Message msg = getElement(id);
+        return msg.getStanzaId();
+    } catch (const NotFound& e) {
+        return QString();
+    } catch (const Empty& e) {
+        return QString();
+    } catch (...) {
+        throw;
+    }
+}
+
 void Core::Archive::printOrder()
 {
     qDebug() << "Printing order";
diff --git a/core/archive.h b/core/archive.h
index ef6ca23..b71a8be 100644
--- a/core/archive.h
+++ b/core/archive.h
@@ -45,7 +45,7 @@ public:
     
     bool addElement(const Shared::Message& message);
     unsigned int addElements(const std::list<Shared::Message>& messages);
-    Shared::Message getElement(const QString& id);
+    Shared::Message getElement(const QString& id) const;
     void changeMessage(const QString& id, const QMap<QString, QVariant>& data);
     Shared::Message oldest();
     QString oldestId();
@@ -60,6 +60,8 @@ public:
     AvatarInfo getAvatarInfo(const QString& resource = "") const;
     bool readAvatarInfo(AvatarInfo& target, const QString& resource = "") const;
     void readAllResourcesAvatars(std::map<QString, AvatarInfo>& data) const;
+    QString idByStanzaId(const QString& stanzaId) const;
+    QString stanzaIdById(const QString& id) const;
     
 public:
     const QString jid;
@@ -169,10 +171,11 @@ private:
     bool opened;
     bool fromTheBeginning;
     MDB_env* environment;
-    MDB_dbi main;
-    MDB_dbi order;
+    MDB_dbi main;           //id to message
+    MDB_dbi order;          //time to id
     MDB_dbi stats;
-    MDB_dbi avatars;
+    MDB_dbi avatars;        
+    MDB_dbi sid;            //stanzaId to id
     
     bool getStatBoolValue(const std::string& id, MDB_txn* txn);
     std::string getStatStringValue(const std::string& id, MDB_txn* txn);
@@ -183,7 +186,7 @@ private:
     void printOrder();
     void printKeys();
     bool dropAvatar(const std::string& resource);
-    Shared::Message getMessage(const std::string& id, MDB_txn* txn);
+    Shared::Message getMessage(const std::string& id, MDB_txn* txn) const;
     Shared::Message getStoredMessage(MDB_txn *txn, MDB_cursor* cursor, MDB_cursor_op op, MDB_val* key, MDB_val* value, int& rc);
     Shared::Message edge(bool end);
 };
diff --git a/core/handlers/messagehandler.cpp b/core/handlers/messagehandler.cpp
index aa02e78..ae06694 100644
--- a/core/handlers/messagehandler.cpp
+++ b/core/handlers/messagehandler.cpp
@@ -162,7 +162,7 @@ bool Core::MessageHandler::handleGroupMessage(const QXmppMessage& msg, bool outg
         }
         
         return true;
-    }
+    } 
     return false;
 }
 
@@ -176,16 +176,13 @@ void Core::MessageHandler::initializeMessage(Shared::Message& target, const QXmp
     if (id.size() == 0) {
         id = source.id();
     }
-    if (id.size() == 0) {
-        id = source.stanzaId();
-    }
+    target.setStanzaId(source.stanzaId());
 #else
     id = source.id();
 #endif
-    if (id.size() == 0) {
-        target.generateRandomId();
-    } else {
-        target.setId(id);
+    target.setId(id);
+    if (target.getId().size() == 0) {
+        target.generateRandomId();          //TODO out of desperation, I need at least a random ID
     }
     target.setFrom(source.from());
     target.setTo(source.to());
@@ -217,13 +214,10 @@ void Core::MessageHandler::logMessage(const QXmppMessage& msg, const QString& re
     qDebug() << "- state: " << msg.state();
     qDebug() << "- stamp: " << msg.stamp();
     qDebug() << "- id: " << msg.id();
+#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 3, 0)
+    qDebug() << "- stanzaId: " << msg.stanzaId();
+#endif
     qDebug() << "- outOfBandUrl: " << msg.outOfBandUrl();
-    qDebug() << "- isAttentionRequested: " << msg.isAttentionRequested();
-    qDebug() << "- isReceiptRequested: " << msg.isReceiptRequested();
-    qDebug() << "- receiptId: " << msg.receiptId();
-    qDebug() << "- subject: " << msg.subject();
-    qDebug() << "- thread: " << msg.thread();
-    qDebug() << "- isMarkable: " << msg.isMarkable();
     qDebug() << "==============================";
 }
 
diff --git a/core/rosteritem.cpp b/core/rosteritem.cpp
index 8260eec..9163994 100644
--- a/core/rosteritem.cpp
+++ b/core/rosteritem.cpp
@@ -157,7 +157,7 @@ void Core::RosterItem::performRequest(int count, const QString& before)
                 requestedCount = -1;
             }
             Shared::Message msg = archive->newest();
-            emit needHistory("", msg.getId(), msg.getTime());
+            emit needHistory("", getId(msg), msg.getTime());
         }
             break;
         case end: 
@@ -176,27 +176,37 @@ void Core::RosterItem::performRequest(int count, const QString& before)
                 } catch (const Archive::NotFound& e) {
                     requestCache.emplace_back(requestedCount, before);
                     requestedCount = -1;
-                    emit needHistory(archive->oldestId(), "");
+                    emit needHistory(getId(archive->oldest()), "");
                 } catch (const Archive::Empty& e) {
                     requestCache.emplace_back(requestedCount, before);
                     requestedCount = -1;
-                    emit needHistory(archive->oldestId(), "");
+                    emit needHistory(getId(archive->oldest()), "");
                 }
                 
                 if (found) {
                     int rSize = responseCache.size();
                     if (rSize < count) {
                         if (rSize != 0) {
-                            emit needHistory(responseCache.front().getId(), "");
+                            emit needHistory(getId(responseCache.front()), "");
                         } else {
-                            emit needHistory(before, "");
+                            QString bf;
+                            if (muc) {
+                                bf = archive->stanzaIdById(before);
+                                if (bf.size() < 0) {
+                                    qDebug() << "Didn't find stanzaId for id requesting history for" << jid << ", falling back to requesting by id";
+                                    bf = before;
+                                }
+                            } else {
+                                bf = before;
+                            }
+                            emit needHistory(bf, "");
                         }
                     } else {
                         nextRequest();
                     }
                 }
             } else {
-                emit needHistory(archive->oldestId(), "");
+                emit needHistory(getId(archive->oldest()), "");
             }
             break;
         case complete:
@@ -213,10 +223,20 @@ void Core::RosterItem::performRequest(int count, const QString& before)
     }
 }
 
+QString Core::RosterItem::getId(const Shared::Message& msg)
+{
+    QString id;
+    if (muc) {
+        id = msg.getStanzaId();
+    } else {
+        id = msg.getId();
+    }
+    return id;
+}
+
 void Core::RosterItem::appendMessageToArchive(const Shared::Message& msg)
 {
-    const QString& id = msg.getId(); 
-    if (id.size() > 0) {
+    if (msg.getId().size() > 0) {
         if (msg.storable()) {
             switch (archiveState) {
                 case empty:
@@ -224,13 +244,13 @@ void Core::RosterItem::appendMessageToArchive(const Shared::Message& msg)
                         archiveState = end;
                     }
                     if (!syncronizing) {
-                        requestHistory(-1, id);
+                        requestHistory(-1, getId(msg));
                     }
                     break;
                 case beginning:
                     appendCache.push_back(msg);
                     if (!syncronizing) {
-                        requestHistory(-1, id);
+                        requestHistory(-1, getId(msg));
                     }
                     break;
                 case end:
@@ -239,7 +259,7 @@ void Core::RosterItem::appendMessageToArchive(const Shared::Message& msg)
                 case chunk:
                     appendCache.push_back(msg);
                     if (!syncronizing) {
-                        requestHistory(-1, id);
+                        requestHistory(-1, getId(msg));
                     }
                     break;
                 case complete:
@@ -247,7 +267,7 @@ void Core::RosterItem::appendMessageToArchive(const Shared::Message& msg)
                     break;
             }
         } else if (!syncronizing && archiveState == empty) {
-            requestHistory(-1, id);
+            requestHistory(-1, getId(msg));
         }
     }
 }
@@ -377,26 +397,6 @@ void Core::RosterItem::flushMessagesToArchive(bool finished, const QString& firs
     }
 }
 
-void Core::RosterItem::requestFromEmpty(int count, const QString& before)
-{
-    if (syncronizing) {
-        qDebug("perform from empty didn't work, another request queued");
-    } else {
-        if (archiveState != empty) {
-            qDebug("perform from empty didn't work, the state is not empty");
-            requestHistory(count, before);
-        } else {
-            syncronizing = true;
-            requestedCount = count;
-            requestedBefore = "";
-            hisoryCache.clear();
-            responseCache.clear();
-            
-            emit needHistory(before, "");
-        }
-    }
-}
-
 QString Core::RosterItem::getServer() const
 {
     QStringList lst = jid.split("@");
diff --git a/core/rosteritem.h b/core/rosteritem.h
index cecd2e4..f38e189 100644
--- a/core/rosteritem.h
+++ b/core/rosteritem.h
@@ -67,7 +67,6 @@ public:
     void appendMessageToArchive(const Shared::Message& msg);
     void flushMessagesToArchive(bool finished, const QString& firstId, const QString& lastId);
     void requestHistory(int count, const QString& before);
-    void requestFromEmpty(int count, const QString& before);
     QString avatarPath(const QString& resource = "") const;
     QString folderPath() const;
     bool readAvatarInfo(Archive::AvatarInfo& target, const QString& resource = "") const;
@@ -112,6 +111,7 @@ protected:
 private:
     void nextRequest();
     void performRequest(int count, const QString& before);
+    QString getId(const Shared::Message& msg);
 };
 
 }
diff --git a/core/squawk.cpp b/core/squawk.cpp
index 8a486c0..9bb2f14 100644
--- a/core/squawk.cpp
+++ b/core/squawk.cpp
@@ -133,11 +133,9 @@ void Core::Squawk::addAccount(
 )
 {
     QSettings settings;
-    unsigned int reconnects = settings.value("reconnects", 2).toUInt();
     
     Account* acc = new Account(login, server, password, name, &network);
     acc->setResource(resource);
-    acc->setReconnectTimes(reconnects);
     acc->setPasswordType(passwordType);
     accounts.push_back(acc);
     amap.insert(std::make_pair(name, acc));
@@ -664,6 +662,7 @@ void Core::Squawk::responsePassword(const QString& account, const QString& passw
         return;
     }
     itr->second->setPassword(password);
+    emit changeAccount(account, {{"password", password}});
     accountReady();
 }
 
@@ -750,5 +749,6 @@ void Core::Squawk::onWalletResponsePassword(const QString& login, const QString&
         return;
     }
     itr->second->setPassword(password);
+    emit changeAccount(login, {{"password", password}});
     accountReady();
 }
diff --git a/shared/message.cpp b/shared/message.cpp
index 7df0f28..fad10dc 100644
--- a/shared/message.cpp
+++ b/shared/message.cpp
@@ -32,7 +32,12 @@ Shared::Message::Message(Shared::Message::Type p_type):
     outgoing(false),
     forwarded(false),
     state(State::delivered),
-    edited(false) {}
+    edited(false),
+    errorText(),
+    originalMessage(),
+    lastModified(),
+    stanzaId()
+    {}
 
 Shared::Message::Message():
     jFrom(),
@@ -50,7 +55,9 @@ Shared::Message::Message():
     edited(false),
     errorText(),
     originalMessage(),
-    lastModified() {}
+    lastModified(),
+    stanzaId()
+    {}
 
 QString Shared::Message::getBody() const
 {
@@ -77,7 +84,11 @@ QString Shared::Message::getTo() const
 
 QString Shared::Message::getId() const
 {
-    return id;
+    if (id.size() > 0) {
+        return id;
+    } else {
+        return stanzaId;
+    }
 }
 
 QDateTime Shared::Message::getTime() const
@@ -299,6 +310,7 @@ void Shared::Message::serialize(QDataStream& data) const
         data << originalMessage;
         data << lastModified;
     }
+    data << stanzaId;
 }
 
 void Shared::Message::deserialize(QDataStream& data)
@@ -328,6 +340,7 @@ void Shared::Message::deserialize(QDataStream& data)
         data >> originalMessage;
         data >> lastModified;
     }
+    data >> stanzaId;
 }
 
 bool Shared::Message::change(const QMap<QString, QVariant>& data)
@@ -353,6 +366,18 @@ bool Shared::Message::change(const QMap<QString, QVariant>& data)
             idChanged = true;
         }
     }
+    
+    itr = data.find("stanzaId");
+    if (itr != data.end()) {
+        QString newId = itr.value().toString();
+        if (stanzaId != newId) {
+            setStanzaId(newId);
+            if (id.size() == 0) {
+                idChanged = true;
+            }
+        }
+    }
+    
     itr = data.find("body");
     if (itr != data.end()) {
         QMap<QString, QVariant>::const_iterator dItr = data.find("stamp");
@@ -397,3 +422,13 @@ bool Shared::Message::storable() const
 {
     return id.size() > 0 && (body.size() > 0 || oob.size()) > 0;
 }
+
+void Shared::Message::setStanzaId(const QString& sid)
+{
+    stanzaId = sid;
+}
+
+QString Shared::Message::getStanzaId() const
+{
+    return stanzaId;
+}
diff --git a/shared/message.h b/shared/message.h
index 4a0d661..d84053f 100644
--- a/shared/message.h
+++ b/shared/message.h
@@ -71,6 +71,7 @@ public:
     void setEdited(bool p_edited);
     void setErrorText(const QString& err);
     bool change(const QMap<QString, QVariant>& data);
+    void setStanzaId(const QString& sid);
     
     QString getFrom() const;
     QString getFromJid() const;
@@ -98,6 +99,7 @@ public:
     bool serverStored() const;
     QDateTime getLastModified() const;
     QString getOriginalBody() const;
+    QString getStanzaId() const;
     
     void serialize(QDataStream& data) const;
     void deserialize(QDataStream& data);
@@ -120,6 +122,7 @@ private:
     QString errorText;
     QString originalMessage;
     QDateTime lastModified;
+    QString stanzaId;
 };
 
 }