separate ChatDialog frontend & backend

Change-Id: I824e58579a9aaac0264561cc7ae3d4977d98a3bf
diff --git a/src/chat-dialog.cpp b/src/chat-dialog.cpp
index 0079f4f..a475c16 100644
--- a/src/chat-dialog.cpp
+++ b/src/chat-dialog.cpp
@@ -17,99 +17,100 @@
 #include <QMessageBox>
 #include <QCloseEvent>
 
-#ifndef Q_MOC_RUN
-#include <sync-intro-certificate.h>
-#include <boost/random/random_device.hpp>
-#include <boost/random/uniform_int_distribution.hpp>
-#include <ndn-cxx/util/random.hpp>
-#include <ndn-cxx/encoding/buffer-stream.hpp>
-#include "cryptopp.hpp"
-#include <queue>
-#include "logging.h"
-
-#define SECURITY_ENABLED false
-#endif
-
-
-// INIT_LOGGER("ChatDialog");
-
-Q_DECLARE_METATYPE(std::vector<Sync::MissingDataInfo> )
-Q_DECLARE_METATYPE(ndn::shared_ptr<const ndn::Data>)
-Q_DECLARE_METATYPE(ndn::Interest)
-Q_DECLARE_METATYPE(size_t)
-
+Q_DECLARE_METATYPE(ndn::Name)
+Q_DECLARE_METATYPE(time_t)
+Q_DECLARE_METATYPE(std::vector<chronos::NodeInfo>)
 
 namespace chronos {
 
-using std::vector;
-using std::string;
-using std::map;
-using std::queue;
+static const Name PRIVATE_PREFIX("/private/local");
+static const uint8_t ROUTING_HINT_SEPARATOR[2] = {0xF0, 0x2E}; // %F0.
 
-using ndn::IdentityCertificate;
-using ndn::SecRuleRelative;
-using ndn::Face;
-using ndn::OBufferStream;
-using ndn::OnDataValidated;
-using ndn::OnDataValidationFailed;
-
-
-static const int HELLO_INTERVAL = FRESHNESS * 3 / 4;
-static const uint8_t CHRONOS_RP_SEPARATOR[2] = {0xF0, 0x2E}; // %F0.
-
-ChatDialog::ChatDialog(ContactManager* contactManager,
-                       shared_ptr<Face> face,
-                       const IdentityCertificate& myCertificate,
-                       const Name& chatroomPrefix,
-                       const Name& localPrefix,
+ChatDialog::ChatDialog(const Name& chatroomPrefix,
+                       const Name& userChatPrefix,
+                       const Name& routingPrefix,
+                       const std::string& chatroomName,
                        const std::string& nick,
-                       bool withSecurity,
+                       bool isSecured,
                        QWidget* parent)
   : QDialog(parent)
   , ui(new Ui::ChatDialog)
-  , m_contactManager(contactManager)
-  , m_face(face)
-  , m_myCertificate(myCertificate)
-  , m_chatroomName(chatroomPrefix.get(-1).toUri())
-  , m_chatroomPrefix(chatroomPrefix)
-  , m_localPrefix(localPrefix)
-  , m_useRoutablePrefix(false)
-  , m_nick(nick)
-  , m_lastMsgTime(time::toUnixTimestamp(time::system_clock::now()).count())
-  , m_joined(false)
-  , m_sock(NULL)
-  , m_session(static_cast<uint64_t>(time::toUnixTimestamp(time::system_clock::now()).count()))
-  , m_inviteListDialog(new InviteListDialog)
-  //ymj
-  //, m_trustModel(withSecurity)
+  , m_backend(chatroomPrefix, userChatPrefix, routingPrefix, chatroomName, nick)
+  , m_chatroomName(chatroomName)
+  , m_nick(nick.c_str())
+  , m_isSecured(isSecured)
 {
-  qRegisterMetaType<std::vector<Sync::MissingDataInfo> >("std::vector<Sync::MissingDataInfo>");
-  qRegisterMetaType<ndn::shared_ptr<const ndn::Data> >("ndn.DataPtr");
-  qRegisterMetaType<ndn::Interest>("ndn.Interest");
-  qRegisterMetaType<size_t>("size_t");
+  qRegisterMetaType<ndn::Name>("ndn::Name");
+  qRegisterMetaType<time_t>("time_t");
+  qRegisterMetaType<std::vector<chronos::NodeInfo> >("std::vector<chronos::NodeInfo>");
 
   m_scene = new DigestTreeScene(this);
   m_trustScene = new TrustTreeScene(this);
   m_rosterModel = new QStringListModel(this);
-  m_timer = new QTimer(this);
 
   ui->setupUi(this);
+
   ui->syncTreeViewer->setScene(m_scene);
   m_scene->setSceneRect(m_scene->itemsBoundingRect());
   ui->syncTreeViewer->hide();
+
   ui->trustTreeViewer->setScene(m_trustScene);
   m_trustScene->setSceneRect(m_trustScene->itemsBoundingRect());
   ui->trustTreeViewer->hide();
+
   ui->listView->setModel(m_rosterModel);
 
-  m_identity =
-    IdentityCertificate::certificateNameToPublicKeyName(m_myCertificate.getName()).getPrefix(-1);
+  Name routablePrefix;
 
-  updatePrefix();
+  if (routingPrefix.isPrefixOf(userChatPrefix))
+    routablePrefix = userChatPrefix;
+  else
+    routablePrefix.append(routingPrefix)
+      .append(ROUTING_HINT_SEPARATOR, 2)
+      .append(userChatPrefix);
 
-  updateLabels();
+  updateLabels(routablePrefix);
 
-  m_scene->setCurrentPrefix(QString(m_localChatPrefix.toUri().c_str()));
+  QStringList roster;
+  roster << "- " + m_nick;
+  m_rosterModel->setStringList(roster);
+
+  // When backend receives a sync update, notify frontend to update sync tree
+  connect(&m_backend, SIGNAL(syncTreeUpdated(std::vector<chronos::NodeInfo>, QString)),
+          this,       SLOT(updateSyncTree(std::vector<chronos::NodeInfo>, QString)));
+
+  // When backend receives a new chat message, notify frontent to print it out.
+  connect(&m_backend, SIGNAL(chatMessageReceived(QString, QString, time_t)),
+          this,       SLOT(receiveChatMessage(QString, QString, time_t)));
+
+  // When backend detects a new session, notify frontend to print the message.
+  connect(&m_backend, SIGNAL(sessionAdded(QString, QString, time_t)),
+          this,       SLOT(addSession(QString, QString, time_t)));
+
+  // When backend detects a deleted session, notify frontend to print the message.
+  connect(&m_backend, SIGNAL(sessionRemoved(QString, QString, time_t)),
+          this,       SLOT(removeSession(QString, QString, time_t)));
+
+  // When backend detects nick changed, notify frontend to print the new nick
+  connect(&m_backend, SIGNAL(nickUpdated(QString, QString)),
+          this,       SLOT(updateNick(QString, QString)));
+
+  // When backend receives a new message, notify frontend to print notification
+  connect(&m_backend, SIGNAL(messageReceived(QString)),
+          this,       SLOT(receiveMessage(QString)));
+
+  // When backend updates prefix, notify frontend to update labels.
+  connect(&m_backend, SIGNAL(chatPrefixChanged(ndn::Name)),
+          this,       SLOT(updateLabels(ndn::Name)));
+
+  // When frontend gets a message to send, notify backend.
+  connect(this,       SIGNAL(msgToSent(QString, time_t)),
+          &m_backend, SLOT(sendChatMessage(QString, time_t)));
+
+  // When frontend gets a shutdown command, notify backend.
+  connect(this,       SIGNAL(shutdownBackend()),
+          &m_backend, SLOT(shutdown()));
+
   m_scene->plot("Empty");
 
   connect(ui->lineEdit, SIGNAL(returnPressed()),
@@ -118,123 +119,23 @@
           this, SLOT(onSyncTreeButtonPressed()));
   connect(ui->trustTreeButton, SIGNAL(pressed()),
           this, SLOT(onTrustTreeButtonPressed()));
-  connect(m_scene, SIGNAL(replot()),
-          this, SLOT(onReplot()));
-  connect(m_scene, SIGNAL(rosterChanged(QStringList)),
-          this, SLOT(onRosterChanged(QStringList)));
-  connect(m_timer, SIGNAL(timeout()),
-          this, SLOT(onReplot()));
 
-  connect(this, SIGNAL(processData(const ndn::shared_ptr<const ndn::Data>&, bool, bool)),
-          this, SLOT(onProcessData(const ndn::shared_ptr<const ndn::Data>&, bool, bool)));
-  connect(this, SIGNAL(processTreeUpdate(const std::vector<Sync::MissingDataInfo>)),
-          this, SLOT(onProcessTreeUpdate(const std::vector<Sync::MissingDataInfo>)));
-  connect(this, SIGNAL(reply(const ndn::Interest&,
-                             const ndn::shared_ptr<const ndn::Data>&,
-                             size_t, bool)),
-          this, SLOT(onReply(const ndn::Interest&,
-                             const ndn::shared_ptr<const ndn::Data>&,
-                             size_t, bool)));
-  connect(this, SIGNAL(replyTimeout(const ndn::Interest&, size_t)),
-          this, SLOT(onReplyTimeout(const ndn::Interest&, size_t)));
-  connect(this, SIGNAL(introCert(const ndn::Interest&, const ndn::shared_ptr<const ndn::Data>&)),
-          this, SLOT(onIntroCert(const ndn::Interest&, const ndn::shared_ptr<const ndn::Data>&)));
-  connect(this, SIGNAL(introCertTimeout(const ndn::Interest&, int, const QString&)),
-          this, SLOT(onIntroCertTimeout(const ndn::Interest&, int, const QString&)));
+  disableSyncTreeDisplay();
+  QTimer::singleShot(2200, this, SLOT(enableSyncTreeDisplay()));
 
-  if (withSecurity) {
-    m_invitationValidator = make_shared<chronos::ValidatorInvitation>();
-    m_dataRule = make_shared<SecRuleRelative>("([^<CHRONOCHAT-DATA>]*)<CHRONOCHAT-DATA><>",
-                                              "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$",
-                                              "==", "\\1", "\\1", true);
-
-    ui->inviteButton->setEnabled(true);
-    ui->trustTreeButton->setEnabled(true);
-
-    connect(ui->inviteButton, SIGNAL(clicked()),
-            this, SLOT(onInviteListDialogRequested()));
-    connect(m_inviteListDialog, SIGNAL(sendInvitation(const QString&)),
-            this, SLOT(onSendInvitation(const QString&)));
-    connect(this, SIGNAL(waitForContactList()),
-            m_contactManager, SLOT(onWaitForContactList()));
-    connect(m_contactManager, SIGNAL(contactAliasListReady(const QStringList&)),
-            m_inviteListDialog, SLOT(onContactAliasListReady(const QStringList&)));
-    connect(m_contactManager, SIGNAL(contactIdListReady(const QStringList&)),
-            m_inviteListDialog, SLOT(onContactIdListReady(const QStringList&)));
-
-    m_trustModel = ChatroomInfo::TRUST_MODEL_WEBOFTRUST;
-  }
-  else
-    m_trustModel = ChatroomInfo::TRUST_MODEL_NONE;
-
-  initializeSync();
+  m_backend.start();
 }
 
 
 ChatDialog::~ChatDialog()
 {
-  if (SECURITY_ENABLED) {
-    if (m_certListPrefixId)
-      m_face->unsetInterestFilter(m_certListPrefixId);
-
-    if (m_certSinglePrefixId)
-      m_face->unsetInterestFilter(m_certSinglePrefixId);
-  }
-
-  if (m_sock != NULL) {
-    sendLeave();
-    delete m_sock;
-    m_sock = NULL;
-  }
 }
 
-// public methods:
-void
-ChatDialog::addSyncAnchor(const Invitation& invitation)
-{
-  // _LOG_DEBUG("Add sync anchor from invitation");
-  // Add inviter certificate as trust anchor.
-  m_sock->addParticipant(invitation.getInviterCertificate());
-  plotTrustTree();
-
-  // Ask inviter for IntroCertificate
-  Name inviterNameSpace =
-    IdentityCertificate::certificateNameToPublicKeyName(
-      invitation.getInviterCertificate().getName()).getPrefix(-1);
-  fetchIntroCert(inviterNameSpace, invitation.getInviterRoutingPrefix());
-}
-
-void
-ChatDialog::processTreeUpdateWrapper(const vector<Sync::MissingDataInfo>& v,
-                                     Sync::SyncSocket *sock)
-{
-  emit processTreeUpdate(v);
-  // _LOG_DEBUG("<<< Tree update signal emitted");
-}
-
-void
-ChatDialog::processDataWrapper(const shared_ptr<const Data>& data)
-{
-  emit processData(data, true, false);
-  // _LOG_DEBUG("<<< " << data->getName() << " fetched");
-}
-
-void
-ChatDialog::processDataNoShowWrapper(const shared_ptr<const Data>& data)
-{
-  emit processData(data, false, false);
-}
-
-void
-ChatDialog::processRemoveWrapper(const string& prefix)
-{
-  // _LOG_DEBUG("Sync REMOVE signal received for prefix: " << prefix);
-}
-
-// protected methods:
 void
 ChatDialog::closeEvent(QCloseEvent *e)
 {
+  // When close button is clicked, do not close the dialog immediately.
+
   QMessageBox::information(this, tr("ChronoChat"),
                            tr("The chatroom will keep running in the "
                               "system tray. To close the chatroom, "
@@ -270,355 +171,28 @@
   fitView();
 }
 
+shared_ptr<ChatroomInfo>
+ChatDialog::getChatroomInfo()
+{
+  shared_ptr<ChatroomInfo> chatroomInfo = make_shared<ChatroomInfo>();
+
+  chatroomInfo->setName(Name::Component(m_chatroomName));
+
+  QStringList prefixList = m_scene->getRosterPrefixList();
+  for(QStringList::iterator it = prefixList.begin();
+      it != prefixList.end(); ++it ) {
+    Name participant = Name(it->toStdString()).getPrefix(-3);
+    chatroomInfo->addParticipant(participant);
+  }
+
+  if (m_isSecured)
+    chatroomInfo->setTrustModel(ChatroomInfo::TRUST_MODEL_WEBOFTRUST);
+  else
+    chatroomInfo->setTrustModel(ChatroomInfo::TRUST_MODEL_NONE);
+  return chatroomInfo;
+}
+
 // private methods:
-void
-ChatDialog::updatePrefix()
-{
-  m_certListPrefix.clear();
-  m_certSinglePrefix.clear();
-  m_localChatPrefix.clear();
-  m_chatPrefix.clear();
-  m_chatPrefix.append(m_identity)
-    .append("CHRONOCHAT-DATA")
-    .append(m_chatroomName)
-    .append(getRandomString());
-  if (!m_localPrefix.isPrefixOf(m_identity)) {
-    m_useRoutablePrefix = true;
-    m_certListPrefix.append(m_localPrefix).append(CHRONOS_RP_SEPARATOR, 2);
-    m_certSinglePrefix.append(m_localPrefix).append(CHRONOS_RP_SEPARATOR, 2);
-    m_localChatPrefix.append(m_localPrefix).append(CHRONOS_RP_SEPARATOR, 2);
-  }
-  m_certListPrefix.append(m_identity).append("CHRONOCHAT-CERT-LIST").append(m_chatroomName);
-  m_certSinglePrefix.append(m_identity).append("CHRONOCHAT-CERT-SINGLE").append(m_chatroomName);
-  m_localChatPrefix.append(m_chatPrefix);
-
-  if (SECURITY_ENABLED) {
-    if (static_cast<bool>(m_certListPrefixId))
-      m_face->unsetInterestFilter(m_certListPrefixId);
-
-    m_certListPrefixId = m_face->setInterestFilter(m_certListPrefix,
-                                                   bind(&ChatDialog::onCertListInterest,
-                                                        this, _1, _2),
-                                                   bind(&ChatDialog::onCertListRegisterFailed,
-                                                        this, _1, _2));
-
-    if (static_cast<bool>(m_certSinglePrefixId))
-      m_face->unsetInterestFilter(m_certSinglePrefixId);
-
-    m_certSinglePrefixId = m_face->setInterestFilter(m_certSinglePrefix,
-                                                     bind(&ChatDialog::onCertSingleInterest,
-                                                          this, _1, _2),
-                                                     bind(&ChatDialog::onCertSingleRegisterFailed,
-                                                          this, _1, _2));
-  }
-}
-
-void
-ChatDialog::updateLabels()
-{
-  QString settingDisp = QString("Chatroom: %1").arg(QString::fromStdString(m_chatroomName));
-  ui->infoLabel->setStyleSheet("QLabel {color: #630; font-size: 16px; font: bold \"Verdana\";}");
-  ui->infoLabel->setText(settingDisp);
-  QString prefixDisp;
-  Name privatePrefix("/private/local");
-  if (privatePrefix.isPrefixOf(m_localChatPrefix)) {
-    prefixDisp =
-      QString("<Warning: no connection to hub or hub does not support prefix autoconfig.>\n"
-              "<Prefix = %1>")
-      .arg(QString::fromStdString(m_localChatPrefix.toUri()));
-    ui->prefixLabel->setStyleSheet(
-      "QLabel {color: red; font-size: 12px; font: bold \"Verdana\";}");
-  }
-  else {
-    prefixDisp = QString("<Prefix = %1>")
-      .arg(QString::fromStdString(m_localChatPrefix.toUri()));
-    ui->prefixLabel->setStyleSheet(
-      "QLabel {color: Green; font-size: 12px; font: bold \"Verdana\";}");
-  }
-  ui->prefixLabel->setText(prefixDisp);
-}
-
-void
-ChatDialog::initializeSync()
-{
-
-  m_sock = new Sync::SyncSocket(m_chatroomPrefix,
-                                m_chatPrefix,
-                                m_session,
-                                m_useRoutablePrefix,
-                                m_localPrefix,
-                                m_face,
-                                m_myCertificate,
-                                m_dataRule,
-                                bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
-                                bind(&ChatDialog::processRemoveWrapper, this, _1));
-
-  usleep(100000);
-
-  QTimer::singleShot(600, this, SLOT(sendJoin()));
-  m_timer->start(FRESHNESS * 1000);
-  disableSyncTreeDisplay();
-  QTimer::singleShot(2200, this, SLOT(enableSyncTreeDisplay()));
-}
-
-void
-ChatDialog::sendInvitation(shared_ptr<Contact> contact, bool isIntroducer)
-{
-  // Add invitee as a trust anchor.
-  m_invitationValidator->addTrustAnchor(contact->getPublicKeyName(),
-                                        contact->getPublicKey());
-
-  // Prepared an invitation interest without routable prefix.
-  Invitation invitation(contact->getNameSpace(),
-                        m_chatroomName,
-                        m_localPrefix,
-                        m_myCertificate);
-  Interest tmpInterest(invitation.getUnsignedInterestName());
-  m_keyChain.sign(tmpInterest, m_myCertificate.getName());
-
-  // Get invitee's routable prefix
-  // (ideally it will do some DNS lookup, but we assume everyone use /ndn/broadcast
-  Name routablePrefix = getInviteeRoutablePrefix(contact->getNameSpace());
-
-  // Check if we need to prepend the routable prefix to the interest name.
-  bool requireRoutablePrefix = false;
-  Name interestName;
-  size_t routablePrefixOffset = 0;
-  if (!routablePrefix.isPrefixOf(tmpInterest.getName())) {
-    interestName.append(routablePrefix).append(CHRONOS_RP_SEPARATOR, 2);
-    requireRoutablePrefix = true;
-    routablePrefixOffset = routablePrefix.size() + 1;
-  }
-  interestName.append(tmpInterest.getName());
-
-  // Send the invitation out
-  Interest interest(interestName);
-  interest.setMustBeFresh(true);
-  // _LOG_DEBUG("sendInvitation: " << interest.getName());
-  m_face->expressInterest(interest,
-                          bind(&ChatDialog::replyWrapper,
-                               this, _1, _2, routablePrefixOffset, isIntroducer),
-                          bind(&ChatDialog::replyTimeoutWrapper,
-                               this, _1, routablePrefixOffset));
-}
-
-void
-ChatDialog::replyWrapper(const Interest& interest,
-                         Data& data,
-                         size_t routablePrefixOffset,
-                         bool isIntroducer)
-{
-  // _LOG_DEBUG("ChatDialog::replyWrapper");
-  emit reply(interest, data.shared_from_this(), routablePrefixOffset, isIntroducer);
-  // _LOG_DEBUG("OK?");
-}
-
-void
-ChatDialog::replyTimeoutWrapper(const Interest& interest,
-                                size_t routablePrefixOffset)
-{
-  // _LOG_DEBUG("ChatDialog::replyTimeoutWrapper");
-  emit replyTimeout(interest, routablePrefixOffset);
-}
-
-void
-ChatDialog::onReplyValidated(const shared_ptr<const Data>& data,
-                             size_t inviteeRoutablePrefixOffset,
-                             bool isIntroducer)
-{
-  if (data->getName().size() <= inviteeRoutablePrefixOffset) {
-    Invitation invitation(data->getName());
-    invitationRejected(invitation.getInviteeNameSpace());
-  }
-  else {
-    Name inviteePrefix;
-    inviteePrefix.wireDecode(data->getName().get(inviteeRoutablePrefixOffset).blockFromValue());
-    IdentityCertificate inviteeCert;
-    inviteeCert.wireDecode(data->getContent().blockFromValue());
-    invitationAccepted(inviteeCert, inviteePrefix, isIntroducer);
-  }
-}
-
-void
-ChatDialog::onReplyValidationFailed(const shared_ptr<const Data>& data,
-                                    const string& failureInfo)
-{
-  // _LOG_DEBUG("Invitation reply cannot be validated: " + failureInfo + " ==> " +
-  //            data->getName().toUri());
-}
-
-void
-ChatDialog::invitationRejected(const Name& identity)
-{
-  QString msg = QString::fromStdString(identity.toUri()) + " rejected your invitation!";
-  emit inivationRejection(msg);
-}
-
-void
-ChatDialog::invitationAccepted(const IdentityCertificate& inviteeCert,
-                               const Name& inviteePrefix,
-                               bool isIntroducer)
-{
-  // Add invitee certificate as trust anchor.
-  m_sock->addParticipant(inviteeCert);
-  plotTrustTree();
-
-  // Ask invitee for IntroCertificate.
-  Name inviteeNameSpace =
-    IdentityCertificate::certificateNameToPublicKeyName(inviteeCert.getName()).getPrefix(-1);
-  fetchIntroCert(inviteeNameSpace, inviteePrefix);
-}
-
-void
-ChatDialog::fetchIntroCert(const Name& identity, const Name& prefix)
-{
-  Name interestName;
-
-  if (!prefix.isPrefixOf(identity))
-    interestName.append(prefix).append(CHRONOS_RP_SEPARATOR, 2);
-
-  interestName.append(identity)
-    .append("CHRONOCHAT-CERT-LIST")
-    .append(m_chatroomName)
-    .appendVersion();
-
-  Interest interest(interestName);
-  interest.setMustBeFresh(true);
-
-  m_face->expressInterest(interest,
-                          bind(&ChatDialog::onIntroCertList, this, _1, _2),
-                          bind(&ChatDialog::onIntroCertListTimeout, this, _1, 1,
-                               "IntroCertList: " + interestName.toUri()));
-}
-
-void
-ChatDialog::onIntroCertList(const Interest& interest, const Data& data)
-{
-  Chronos::IntroCertListMsg introCertList;
-  if (!introCertList.ParseFromArray(data.getContent().value(), data.getContent().value_size()))
-    return;
-
-  for (int i = 0; i < introCertList.certname_size(); i++) {
-    Name certName(introCertList.certname(i));
-    Interest interest(certName);
-    interest.setMustBeFresh(true);
-
-    // _LOG_DEBUG("onIntroCertList: to fetch " << certName);
-
-    m_face->expressInterest(interest,
-                            bind(&ChatDialog::introCertWrapper, this, _1, _2),
-                            bind(&ChatDialog::introCertTimeoutWrapper, this, _1, 0,
-                                 QString("IntroCert: %1").arg(introCertList.certname(i).c_str())));
-  }
-}
-
-void
-ChatDialog::onIntroCertListTimeout(const Interest& interest, int retry, const string& msg)
-{
-  if (retry > 0) {
-    m_face->expressInterest(interest,
-                            bind(&ChatDialog::onIntroCertList, this, _1, _2),
-                            bind(&ChatDialog::onIntroCertListTimeout, this, _1, retry - 1, msg));
-  }
-  else {
-    // _LOG_DEBUG(msg << " TIMEOUT!");
-  }
-}
-
-void
-ChatDialog::introCertWrapper(const Interest& interest, Data& data)
-{
-  emit introCert(interest, data.shared_from_this());
-}
-
-void
-ChatDialog::introCertTimeoutWrapper(const Interest& interest, int retry, const QString& msg)
-{
-  emit introCertTimeout(interest, retry, msg);
-}
-
-void
-ChatDialog::onCertListInterest(const ndn::Name& prefix, const ndn::Interest& interest)
-{
-  vector<Name> certNameList;
-  m_sock->getIntroCertNames(certNameList);
-
-  Chronos::IntroCertListMsg msg;
-
-  for (vector<Name>::const_iterator it = certNameList.begin(); it != certNameList.end(); it++) {
-    Name certName;
-    certName.append(m_certSinglePrefix).append(*it);
-    msg.add_certname(certName.toUri());
-  }
-  OBufferStream os;
-  msg.SerializeToOstream(&os);
-
-  shared_ptr<Data> data = make_shared<Data>(interest.getName());
-  data->setContent(os.buf());
-  m_keyChain.sign(*data, m_myCertificate.getName());
-
-  m_face->put(*data);
-}
-
-void
-ChatDialog::onCertListRegisterFailed(const ndn::Name& prefix, const std::string& msg)
-{
-  _LOG_DEBUG("ChatDialog::onCertListRegisterFailed failed: " + msg);
-}
-
-void
-ChatDialog::onCertSingleInterest(const Name& prefix, const Interest& interest)
-{
-  try {
-    Name certName = interest.getName().getSubName(prefix.size());
-    const Sync::IntroCertificate& introCert = m_sock->getIntroCertificate(certName);
-
-    shared_ptr<Data> data = make_shared<Data>(interest.getName());
-    data->setContent(introCert.wireEncode());
-    m_keyChain.sign(*data,  m_myCertificate.getName());
-    m_face->put(*data);
-  }
-  catch(Sync::SyncSocket::Error& e) {
-    return;
-  }
-}
-
-void
-ChatDialog::onCertSingleRegisterFailed(const Name& prefix, const std::string& msg)
-{
-  _LOG_DEBUG("ChatDialog::onCertListRegisterFailed failed: " + msg);
-}
-
-void
-ChatDialog::sendMsg(SyncDemo::ChatMessage &msg)
-{
-  // send msg
-  OBufferStream os;
-  msg.SerializeToOstream(&os);
-
-  if (!msg.IsInitialized()) {
-    // _LOG_DEBUG("Errrrr.. msg was not probally initialized " << __FILE__ <<
-    //            ":" << __LINE__ << ". what is happening?");
-    abort();
-  }
-  uint64_t nextSequence = m_sock->getNextSeq();
-  m_sock->publishData(os.buf()->buf(), os.buf()->size(), FRESHNESS);
-
-  m_lastMsgTime = time::toUnixTimestamp(time::system_clock::now()).count();
-
-  Sync::MissingDataInfo mdi = {m_localChatPrefix.toUri(),
-                               Sync::SeqNo(0),
-                               Sync::SeqNo(nextSequence)};
-  vector<Sync::MissingDataInfo> v;
-  v.push_back(mdi);
-  {
-    boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
-    m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
-    m_scene->msgReceived(QString::fromStdString(m_localChatPrefix.toUri()),
-                         QString::fromStdString(m_nick));
-  }
-}
-
 void ChatDialog::disableSyncTreeDisplay()
 {
   ui->syncTreeButton->setEnabled(false);
@@ -627,130 +201,61 @@
 }
 
 void
-ChatDialog::appendMessage(const SyncDemo::ChatMessage msg, bool isHistory)
+ChatDialog::appendChatMessage(const QString& nick, const QString& text, time_t timestamp)
 {
-  boost::recursive_mutex::scoped_lock lock(m_msgMutex);
+  QTextCharFormat nickFormat;
+  nickFormat.setForeground(Qt::darkGreen);
+  nickFormat.setFontWeight(QFont::Bold);
+  nickFormat.setFontUnderline(true);
+  nickFormat.setUnderlineColor(Qt::gray);
 
-  if (msg.type() == SyncDemo::ChatMessage::CHAT) {
-    if (!msg.has_data()) {
-      return;
-    }
+  // Print who & when
+  QTextCursor cursor(ui->textEdit->textCursor());
+  cursor.movePosition(QTextCursor::End);
+  QTextTableFormat tableFormat;
+  tableFormat.setBorder(0);
+  QTextTable *table = cursor.insertTable(1, 2, tableFormat);
+  QString from = QString("%1 ").arg(nick);
+  QTextTableCell fromCell = table->cellAt(0, 0);
+  fromCell.setFormat(nickFormat);
+  fromCell.firstCursorPosition().insertText(from);
+  printTimeInCell(table, timestamp);
 
-    if (msg.from().empty() || msg.data().empty()) {
-      return;
-    }
+  // Print what
+  QTextCursor nextCursor(ui->textEdit->textCursor());
+  nextCursor.movePosition(QTextCursor::End);
+  table = nextCursor.insertTable(1, 1, tableFormat);
+  table->cellAt(0, 0).firstCursorPosition().insertText(text);
 
-    if (!msg.has_timestamp()) {
-      return;
-    }
-
-    // if (m_history.size() == MAX_HISTORY_ENTRY)
-    // {
-    //   m_history.dequeue();
-    // }
-
-    // m_history.enqueue(msg);
-
-    QTextCharFormat nickFormat;
-    nickFormat.setForeground(Qt::darkGreen);
-    nickFormat.setFontWeight(QFont::Bold);
-    nickFormat.setFontUnderline(true);
-    nickFormat.setUnderlineColor(Qt::gray);
-
-    QTextCursor cursor(ui->textEdit->textCursor());
-    cursor.movePosition(QTextCursor::End);
-    QTextTableFormat tableFormat;
-    tableFormat.setBorder(0);
-    QTextTable *table = cursor.insertTable(1, 2, tableFormat);
-    QString from = QString("%1 ").arg(msg.from().c_str());
-    QTextTableCell fromCell = table->cellAt(0, 0);
-    fromCell.setFormat(nickFormat);
-    fromCell.firstCursorPosition().insertText(from);
-
-    time_t timestamp = msg.timestamp();
-    printTimeInCell(table, timestamp);
-
-    QTextCursor nextCursor(ui->textEdit->textCursor());
-    nextCursor.movePosition(QTextCursor::End);
-    table = nextCursor.insertTable(1, 1, tableFormat);
-    table->cellAt(0, 0).firstCursorPosition().insertText(QString::fromUtf8(msg.data().c_str()));
-    if (!isHistory) {
-      showMessage(from, QString::fromUtf8(msg.data().c_str()));
-    }
-  }
-
-  if (msg.type() == SyncDemo::ChatMessage::JOIN || msg.type() == SyncDemo::ChatMessage::LEAVE) {
-    QTextCharFormat nickFormat;
-    nickFormat.setForeground(Qt::gray);
-    nickFormat.setFontWeight(QFont::Bold);
-    nickFormat.setFontUnderline(true);
-    nickFormat.setUnderlineColor(Qt::gray);
-
-    QTextCursor cursor(ui->textEdit->textCursor());
-    cursor.movePosition(QTextCursor::End);
-    QTextTableFormat tableFormat;
-    tableFormat.setBorder(0);
-    QTextTable *table = cursor.insertTable(1, 2, tableFormat);
-    QString action;
-    if (msg.type() == SyncDemo::ChatMessage::JOIN) {
-      action = "enters room";
-    }
-    else {
-      action = "leaves room";
-    }
-
-    QString from = QString("%1 %2  ").arg(msg.from().c_str()).arg(action);
-    QTextTableCell fromCell = table->cellAt(0, 0);
-    fromCell.setFormat(nickFormat);
-    fromCell.firstCursorPosition().insertText(from);
-
-    time_t timestamp = msg.timestamp();
-    printTimeInCell(table, timestamp);
-  }
+  // Popup notification
+  showMessage(from, text);
 
   QScrollBar *bar = ui->textEdit->verticalScrollBar();
   bar->setValue(bar->maximum());
 }
 
 void
-ChatDialog::processRemove(QString prefix)
+ChatDialog::appendControlMessage(const QString& nick,
+                                 const QString& action,
+                                 time_t timestamp)
 {
-  // _LOG_DEBUG("<<< remove node for prefix" << prefix.toStdString());
+  QTextCharFormat nickFormat;
+  nickFormat.setForeground(Qt::gray);
+  nickFormat.setFontWeight(QFont::Bold);
+  nickFormat.setFontUnderline(true);
+  nickFormat.setUnderlineColor(Qt::gray);
 
-  bool removed = m_scene->removeNode(prefix);
-  if (removed) {
-    boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
-    m_scene->plot(m_sock->getRootDigest().c_str());
-  }
-}
+  QTextCursor cursor(ui->textEdit->textCursor());
+  cursor.movePosition(QTextCursor::End);
+  QTextTableFormat tableFormat;
+  tableFormat.setBorder(0);
+  QTextTable *table = cursor.insertTable(1, 2, tableFormat);
 
-Name
-ChatDialog::getInviteeRoutablePrefix(const Name& invitee)
-{
-  return Name("/ndn/broadcast");
-}
-
-void
-ChatDialog::formChatMessage(const QString &text, SyncDemo::ChatMessage &msg) {
-  msg.set_from(m_nick);
-  msg.set_to(m_chatroomName);
-  msg.set_data(text.toStdString());
-  int32_t seconds =
-    static_cast<int32_t>(time::toUnixTimestamp(time::system_clock::now()).count()/1000);
-  msg.set_timestamp(seconds);
-  msg.set_type(SyncDemo::ChatMessage::CHAT);
-}
-
-void
-ChatDialog::formControlMessage(SyncDemo::ChatMessage &msg,
-                               SyncDemo::ChatMessage::ChatMessageType type)
-{
-  msg.set_from(m_nick);
-  msg.set_to(m_chatroomName);
-  int32_t seconds =
-    static_cast<int32_t>(time::toUnixTimestamp(time::system_clock::now()).count()/1000);
-  msg.set_timestamp(seconds);
-  msg.set_type(type);
+  QString controlMsg = QString("%1 %2  ").arg(nick).arg(action);
+  QTextTableCell fromCell = table->cellAt(0, 0);
+  fromCell.setFormat(nickFormat);
+  fromCell.firstCursorPosition().insertText(controlMsg);
+  printTimeInCell(table, timestamp);
 }
 
 QString
@@ -788,21 +293,6 @@
   timeCell.firstCursorPosition().insertText(formatTime(timestamp));
 }
 
-string
-ChatDialog::getRandomString()
-{
-  uint32_t r = ndn::random::generateWord32();
-  std::stringstream ss;
-  {
-    using namespace CryptoPP;
-    StringSource(reinterpret_cast<uint8_t*>(&r), 4, true,
-                 new HexEncoder(new FileSink(ss), false));
-
-  }
-
-  return ss.str();
-}
-
 void
 ChatDialog::showMessage(const QString& from, const QString& data)
 {
@@ -814,7 +304,6 @@
 void
 ChatDialog::fitView()
 {
-  boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
   QRectF rect = m_scene->itemsBoundingRect();
   m_scene->setSceneRect(rect);
   ui->syncTreeViewer->fitInView(m_scene->itemsBoundingRect(), Qt::KeepAspectRatio);
@@ -824,200 +313,8 @@
   ui->trustTreeViewer->fitInView(m_trustScene->itemsBoundingRect(), Qt::KeepAspectRatio);
 }
 
-void
-ChatDialog::summonReaper()
-{
-  Sync::SyncLogic &logic = m_sock->getLogic ();
-  map<string, bool> branches = logic.getBranchPrefixes();
-  QMap<QString, DisplayUserPtr> roster = m_scene->getRosterFull();
-
-  m_zombieList.clear();
-
-  QMapIterator<QString, DisplayUserPtr> it(roster);
-  map<string, bool>::iterator mapIt;
-  while (it.hasNext()) {
-    it.next();
-    DisplayUserPtr p = it.value();
-    if (p != DisplayUserNullPtr) {
-      mapIt = branches.find(p->getPrefix().toStdString());
-      if (mapIt != branches.end()) {
-        mapIt->second = true;
-      }
-    }
-  }
-
-  for (mapIt = branches.begin(); mapIt != branches.end(); ++mapIt) {
-    // this is zombie. all active users should have been marked true
-    if (! mapIt->second) {
-      m_zombieList.append(mapIt->first.c_str());
-    }
-  }
-
-  m_zombieIndex = 0;
-
-  // start reaping
-  reap();
-}
-
-void
-ChatDialog::getTree(TrustTreeNodeList& nodeList)
-{
-  typedef map<Name, shared_ptr<TrustTreeNode> > NodeMap;
-
-  vector<Name> certNameList;
-  NodeMap nodeMap;
-
-  m_sock->getIntroCertNames(certNameList);
-
-  for (vector<Name>::const_iterator it = certNameList.begin(); it != certNameList.end(); it++) {
-    Name introducerCertName;
-    Name introduceeCertName;
-
-    introducerCertName.wireDecode(it->get(-2).blockFromValue());
-    introduceeCertName.wireDecode(it->get(-3).blockFromValue());
-
-    Name introducerName =
-      IdentityCertificate::certificateNameToPublicKeyName(introducerCertName).getPrefix(-1);
-    Name introduceeName =
-      IdentityCertificate::certificateNameToPublicKeyName(introduceeCertName).getPrefix(-1);
-
-    NodeMap::iterator introducerIt = nodeMap.find(introducerName);
-    if (introducerIt == nodeMap.end()) {
-      shared_ptr<TrustTreeNode> introducerNode(new TrustTreeNode(introducerName));
-      nodeMap[introducerName] = introducerNode;
-    }
-    shared_ptr<TrustTreeNode> erNode = nodeMap[introducerName];
-
-    NodeMap::iterator introduceeIt = nodeMap.find(introduceeName);
-    if (introduceeIt == nodeMap.end()) {
-      shared_ptr<TrustTreeNode> introduceeNode(new TrustTreeNode(introduceeName));
-      nodeMap[introduceeName] = introduceeNode;
-    }
-    shared_ptr<TrustTreeNode> eeNode = nodeMap[introduceeName];
-
-    erNode->addIntroducee(eeNode);
-    eeNode->addIntroducer(erNode);
-  }
-
-  nodeList.clear();
-  queue<shared_ptr<TrustTreeNode> > nodeQueue;
-
-  NodeMap::iterator nodeIt = nodeMap.find(m_identity);
-  if (nodeIt == nodeMap.end())
-    return;
-
-  nodeQueue.push(nodeIt->second);
-  nodeIt->second->setLevel(0);
-  while (!nodeQueue.empty()) {
-    shared_ptr<TrustTreeNode>& node = nodeQueue.front();
-    node->setVisited();
-
-    TrustTreeNodeList& introducees = node->getIntroducees();
-    for (TrustTreeNodeList::iterator eeIt = introducees.begin();
-         eeIt != introducees.end(); eeIt++) {
-      // _LOG_DEBUG("introducee: " << (*eeIt)->name() <<
-      //            " visited: " << std::boolalpha << (*eeIt)->visited());
-      if (!(*eeIt)->visited()) {
-        nodeQueue.push(*eeIt);
-        (*eeIt)->setLevel(node->level()+1);
-      }
-    }
-
-    nodeList.push_back(node);
-    nodeQueue.pop();
-  }
-}
-
-void
-ChatDialog::plotTrustTree()
-{
-  TrustTreeNodeList nodeList;
-
-  getTree(nodeList);
-  {
-    boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
-    m_trustScene->plotTrustTree(nodeList);
-    fitView();
-  }
-}
-
-shared_ptr<ChatroomInfo>
-ChatDialog::getChatroomInfo() const
-{
-  shared_ptr<ChatroomInfo> chatroom = make_shared<ChatroomInfo>();
-  chatroom->setName(Name::Component(m_chatroomName));
-
-  Roster roster = m_scene->getRosterFull();
-  Roster_iterator it = roster.begin();
-
-  for(it = roster.begin(); it != roster.end(); ++it )
-  {
-    Name participant = Name(it.key().toStdString()).getPrefix(-3);
-    chatroom->addParticipant(participant);
-  }
-
-  chatroom->setTrustModel(m_trustModel);
-  return chatroom;
-}
-
-
 // public slots:
 void
-ChatDialog::onLocalPrefixUpdated(const QString& localPrefix)
-{
-  Name newLocalPrefix(localPrefix.toStdString());
-  if (!newLocalPrefix.empty() && newLocalPrefix != m_localPrefix) {
-    // Update localPrefix
-    m_localPrefix = newLocalPrefix;
-
-    updatePrefix();
-    updateLabels();
-    m_scene->setCurrentPrefix(QString(m_localChatPrefix.toUri().c_str()));
-
-    if (m_sock != NULL) {
-      {
-        boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
-        m_scene->clearAll();
-        m_scene->plot("Empty");
-      }
-
-      ui->textEdit->clear();
-
-      if (m_joined) {
-        sendLeave();
-      }
-
-      delete m_sock;
-      m_sock = NULL;
-
-      usleep(100000);
-      m_sock = new Sync::SyncSocket(m_chatroomPrefix,
-                                    m_chatPrefix,
-                                    m_session,
-                                    m_useRoutablePrefix,
-                                    m_localPrefix,
-                                    m_face,
-                                    m_myCertificate,
-                                    m_dataRule,
-                                    bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
-                                    bind(&ChatDialog::processRemoveWrapper, this, _1));
-      usleep(100000);
-      QTimer::singleShot(600, this, SLOT(sendJoin()));
-      m_timer->start(FRESHNESS * 1000);
-      disableSyncTreeDisplay();
-      QTimer::singleShot(2200, this, SLOT(enableSyncTreeDisplay()));
-    }
-    else
-      initializeSync();
-  }
-  else
-    if (m_sock == NULL)
-      initializeSync();
-
-  fitView();
-}
-
-void
 ChatDialog::onShow()
 {
   this->show();
@@ -1026,42 +323,104 @@
 }
 
 void
-ChatDialog::onClose()
+ChatDialog::shutdown()
 {
+  if (m_backend.isRunning()) {
+    emit shutdownBackend();
+    m_backend.wait();
+  }
   hide();
   emit closeChatDialog(QString::fromStdString(m_chatroomName));
 }
 
-
 // private slots:
 void
+ChatDialog::updateSyncTree(std::vector<chronos::NodeInfo> updates, QString rootDigest)
+{
+  m_scene->processSyncUpdate(updates, rootDigest);
+}
+
+void
+ChatDialog::receiveChatMessage(QString nick, QString text, time_t timestamp)
+{
+  appendChatMessage(nick, text, timestamp);
+}
+
+void
+ChatDialog::addSession(QString sessionPrefix, QString nick, time_t timestamp)
+{
+  appendControlMessage(nick, "enters room", timestamp);
+  m_scene->updateNick(sessionPrefix, nick);
+  m_rosterModel->setStringList(m_scene->getRosterList());
+}
+
+void
+ChatDialog::removeSession(QString sessionPrefix, QString nick, time_t timestamp)
+{
+  appendControlMessage(nick, "leaves room", timestamp);
+  m_scene->removeNode(sessionPrefix);
+  m_rosterModel->setStringList(m_scene->getRosterList());
+}
+
+void
+ChatDialog::updateNick(QString sessionPrefix, QString nick)
+{
+  m_scene->updateNick(sessionPrefix, nick);
+  m_rosterModel->setStringList(m_scene->getRosterList());
+}
+
+void
+ChatDialog::receiveMessage(QString sessionPrefix)
+{
+  m_scene->messageReceived(sessionPrefix);
+}
+
+void
+ChatDialog::updateLabels(Name newChatPrefix)
+{
+  // Reset DigestTree
+  m_scene->clearAll();
+  m_scene->plot("Empty");
+
+  // Display chatroom name
+  QString chatroomName = QString("Chatroom: %1").arg(QString::fromStdString(m_chatroomName));
+  ui->infoLabel->setStyleSheet("QLabel {color: #630; font-size: 16px; font: bold \"Verdana\";}");
+  ui->infoLabel->setText(chatroomName);
+
+  // Display chat message prefix
+  QString chatPrefix;
+  if (PRIVATE_PREFIX.isPrefixOf(newChatPrefix)) {
+    chatPrefix =
+      QString("<Warning: no connection to hub or hub does not support prefix autoconfig.>\n"
+              "<Prefix = %1>")
+      .arg(QString::fromStdString(newChatPrefix.toUri()));
+    ui->prefixLabel->setStyleSheet(
+      "QLabel {color: red; font-size: 12px; font: bold \"Verdana\";}");
+  }
+  else {
+    chatPrefix = QString("<Prefix = %1>")
+      .arg(QString::fromStdString(newChatPrefix.toUri()));
+    ui->prefixLabel->setStyleSheet(
+      "QLabel {color: Green; font-size: 12px; font: bold \"Verdana\";}");
+  }
+  ui->prefixLabel->setText(chatPrefix);
+}
+
+void
 ChatDialog::onReturnPressed()
 {
   QString text = ui->lineEdit->text();
+
   if (text.isEmpty())
     return;
 
   ui->lineEdit->clear();
 
-  if (text.startsWith("boruoboluomi")) {
-    summonReaper ();
-    // reapButton->show();
-    fitView();
-    return;
-  }
+  time_t timestamp =
+    static_cast<time_t>(time::toUnixTimestamp(time::system_clock::now()).count() / 1000);
+  // appendChatMessage(m_nick, text, timestamp);
 
-  if (text.startsWith("minimanihong")) {
-    // reapButton->hide();
-    fitView();
-    return;
-  }
-
-  SyncDemo::ChatMessage msg;
-  formChatMessage(text, msg);
-
-  appendMessage(msg);
-
-  sendMsg(msg);
+  emit msgToSent(text, timestamp);
 
   fitView();
 }
@@ -1096,252 +455,11 @@
   fitView();
 }
 
-void
-ChatDialog::onProcessData(const ndn::shared_ptr<const ndn::Data>& data, bool show, bool isHistory)
-{
-  SyncDemo::ChatMessage msg;
-  bool corrupted = false;
-  if (!msg.ParseFromArray(data->getContent().value(), data->getContent().value_size())) {
-    // _LOG_DEBUG("Errrrr.. Can not parse msg with name: " <<
-    //            data->getName() << ". what is happening?");
-    // nasty stuff: as a remedy, we'll form some standard msg for inparsable msgs
-    msg.set_from("inconnu");
-    msg.set_type(SyncDemo::ChatMessage::OTHER);
-    corrupted = true;
-  }
-
-  //std::cout << "onProcessData: " << show << std::endl;
-  //std::cout << "onProcessData: " << corrupted << std::endl;
-
-  // display msg received from network
-  // we have to do so; this function is called by ccnd thread
-  // so if we call appendMsg directly
-  // Qt crash as "QObject: Cannot create children for a parent that is in a different thread"
-  // the "cannonical" way to is use signal-slot
-  if (show && !corrupted) {
-    appendMessage(msg, isHistory);
-  }
-
-  if (!isHistory) {
-    // update the tree view
-    string prefix = data->getName().getPrefix(-2).toUri();
-    // _LOG_DEBUG("<<< updating scene for" << prefix << ": " << msg.from());
-    if (msg.type() == SyncDemo::ChatMessage::LEAVE) {
-      processRemove(prefix.c_str());
-    }
-    else {
-      boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
-      m_scene->msgReceived(prefix.c_str(), msg.from().c_str());
-    }
-  }
-  fitView();
-}
-
-void
-ChatDialog::onProcessTreeUpdate(const vector<Sync::MissingDataInfo>& v)
-{
-  _LOG_DEBUG("<<< processing Tree Update");
-
-  if (v.empty()) {
-    return;
-  }
-
-  // reflect the changes on digest tree
-  {
-    boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
-    m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
-  }
-
-  int n = v.size();
-  int totalMissingPackets = 0;
-  for (int i = 0; i < n; i++) {
-    totalMissingPackets += v[i].high.getSeq() - v[i].low.getSeq() + 1;
-  }
-
-  for (int i = 0; i < n; i++) {
-    if (totalMissingPackets < 4) {
-      for (Sync::SeqNo seq = v[i].low; seq <= v[i].high; ++seq) {
-        m_sock->fetchData(v[i].prefix, seq, bind(&ChatDialog::processDataWrapper, this, _1), 2);
-        _LOG_DEBUG("<<< Fetching " << v[i].prefix << "/" <<seq.getSession() <<"/" << seq.getSeq());
-      }
-    }
-    else {
-      m_sock->fetchData(v[i].prefix, v[i].high,
-                        bind(&ChatDialog::processDataNoShowWrapper, this, _1), 2);
-    }
-  }
-  // adjust the view
-  fitView();
-}
-
-void
-ChatDialog::onReplot()
-{
-  boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
-  m_scene->plot(m_sock->getRootDigest().c_str());
-  fitView();
-}
-
-void
-ChatDialog::onRosterChanged(QStringList staleUserList)
-{
-  boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
-  QStringList rosterList = m_scene->getRosterList();
-  m_rosterModel->setStringList(rosterList);
-  QString user;
-  QStringListIterator it(staleUserList);
-  while (it.hasNext()) {
-    string nick = it.next().toStdString();
-    if (nick.empty())
-      continue;
-
-    SyncDemo::ChatMessage msg;
-    formControlMessage(msg, SyncDemo::ChatMessage::LEAVE);
-    msg.set_from(nick);
-    appendMessage(msg);
-  }
-  plotTrustTree();
-
-  emit rosterChanged(*getChatroomInfo());
-}
-
-void
-ChatDialog::onInviteListDialogRequested()
-{
-  emit waitForContactList();
-  m_inviteListDialog->setInviteLabel(m_chatroomPrefix.toUri());
-  m_inviteListDialog->show();
-}
-
-void
-ChatDialog::sendJoin()
-{
-  m_joined = true;
-  SyncDemo::ChatMessage msg;
-  formControlMessage(msg, SyncDemo::ChatMessage::JOIN);
-  sendMsg(msg);
-  boost::random::random_device rng;
-  boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
-  m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
-  QTimer::singleShot(m_randomizedInterval, this, SLOT(sendHello()));
-}
-
-void
-ChatDialog::sendHello()
-{
-  int64_t now = time::toUnixTimestamp(time::system_clock::now()).count();
-  int elapsed = (now - m_lastMsgTime) / 1000;
-  if (elapsed >= m_randomizedInterval / 1000) {
-    SyncDemo::ChatMessage msg;
-    formControlMessage(msg, SyncDemo::ChatMessage::HELLO);
-    sendMsg(msg);
-    boost::random::random_device rng;
-    boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
-    m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
-    QTimer::singleShot(m_randomizedInterval, this, SLOT(sendHello()));
-  }
-  else {
-    QTimer::singleShot((m_randomizedInterval - elapsed * 1000), this, SLOT(sendHello()));
-  }
-}
-
-void
-ChatDialog::sendLeave()
-{
-  SyncDemo::ChatMessage msg;
-  formControlMessage(msg, SyncDemo::ChatMessage::LEAVE);
-  sendMsg(msg);
-  usleep(500000);
-  m_sock->leave();
-  usleep(5000);
-  m_joined = false;
-  // _LOG_DEBUG("Sync REMOVE signal sent");
-}
-
 void ChatDialog::enableSyncTreeDisplay()
 {
   ui->syncTreeButton->setEnabled(true);
-  // treeViewer->show();
-  // fitView();
-}
-
-void
-ChatDialog::reap()
-{
-  if (m_zombieIndex < m_zombieList.size()) {
-    string prefix = m_zombieList.at(m_zombieIndex).toStdString();
-    m_sock->remove(prefix);
-    // _LOG_DEBUG("Reaped: prefix = " << prefix);
-    m_zombieIndex++;
-    // reap again in 10 seconds
-    QTimer::singleShot(10000, this, SLOT(reap()));
-  }
-}
-
-void
-ChatDialog::onSendInvitation(QString invitee)
-{
-  Name inviteeNamespace(invitee.toStdString());
-  shared_ptr<Contact> inviteeItem = m_contactManager->getContact(inviteeNamespace);
-  sendInvitation(inviteeItem, true);
-}
-
-void
-ChatDialog::onReply(const Interest& interest,
-                    const shared_ptr<const Data>& data,
-                    size_t routablePrefixOffset,
-                    bool isIntroducer)
-{
-  OnDataValidated onValidated = bind(&ChatDialog::onReplyValidated,
-                                     this, _1,
-                                     //RoutablePrefix will be removed before passing to validator
-                                     interest.getName().size()-routablePrefixOffset,
-                                     isIntroducer);
-
-  OnDataValidationFailed onFailed = bind(&ChatDialog::onReplyValidationFailed,
-                                         this, _1, _2);
-
-  if (routablePrefixOffset > 0) {
-    // It is an encapsulated packet, we only validate the inner packet.
-    shared_ptr<Data> innerData = make_shared<Data>();
-    innerData->wireDecode(data->getContent().blockFromValue());
-    m_invitationValidator->validate(*innerData, onValidated, onFailed);
-  }
-  else
-    m_invitationValidator->validate(*data, onValidated, onFailed);
-}
-
-void
-ChatDialog::onReplyTimeout(const ndn::Interest& interest,
-                           size_t routablePrefixOffset)
-{
-  Name interestName;
-  if (routablePrefixOffset > 0)
-    interestName = interest.getName().getSubName(routablePrefixOffset);
-  else
-    interestName = interest.getName();
-
-  Invitation invitation(interestName);
-
-  QString msg = QString::fromUtf8("Your invitation to ") +
-    QString::fromStdString(invitation.getInviteeNameSpace().toUri()) + " times out!";
-  emit inivationRejection(msg);
-}
-
-void
-ChatDialog::onIntroCert(const ndn::Interest& interest, const ndn::shared_ptr<const ndn::Data>& data)
-{
-  Data innerData;
-  innerData.wireDecode(data->getContent().blockFromValue());
-  Sync::IntroCertificate introCert(innerData);
-  m_sock->addParticipant(introCert);
-  plotTrustTree();
-}
-
-void
-ChatDialog::onIntroCertTimeout(const ndn::Interest& interest, int retry, const QString& msg)
-{
-  // _LOG_DEBUG("onIntroCertTimeout: " << msg.toStdString());
+  ui->syncTreeViewer->show();
+  fitView();
 }
 
 } // namespace chronos