diff --git a/src/chatdialog.cpp b/src/chatdialog.cpp
index 5f1d3eb..fe7d7b5 100644
--- a/src/chatdialog.cpp
+++ b/src/chatdialog.cpp
@@ -5,67 +5,247 @@
  *
  * BSD license, See the LICENSE file for more information
  *
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ *         Yingdi Yu <yingdi@cs.ucla.edu>
  */
 
 #include "chatdialog.h"
 #include "ui_chatdialog.h"
 
+#include <QScrollBar>
+
 #ifndef Q_MOC_RUN
 #include <ndn.cxx/security/identity/identity-manager.h>
-#include <ndn.cxx/security/identity/basic-identity-storage.h>
-#include <ndn.cxx/security/identity/osx-privatekey-storage.h>
 #include <ndn.cxx/security/encryption/basic-encryption-manager.h>
+#include <sync-intro-certificate.h>
+#include <boost/random/random_device.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
 #include "logging.h"
 #endif
 
 using namespace std;
-using namespace ndn;
 
 INIT_LOGGER("ChatDialog");
 
-ChatDialog::ChatDialog(const Name& chatroomPrefix,
-		       const Name& localPrefix,
-                       const Name& defaultIdentity,
+static const int HELLO_INTERVAL = FRESHNESS * 3 / 4;
+
+Q_DECLARE_METATYPE(std::vector<Sync::MissingDataInfo> )
+Q_DECLARE_METATYPE(size_t)
+
+ChatDialog::ChatDialog(ndn::Ptr<ContactManager> contactManager,
+                       const ndn::Name& chatroomPrefix,
+		       const ndn::Name& localPrefix,
+                       const ndn::Name& defaultIdentity,
 		       QWidget *parent) 
-    : QDialog(parent)
-    , m_chatroomPrefix(chatroomPrefix)
-    , m_localPrefix(localPrefix)
-    , m_defaultIdentity(defaultIdentity)
-    , m_policyManager(Ptr<ChatroomPolicyManager>(new ChatroomPolicyManager))
-    , ui(new Ui::ChatDialog)
+: QDialog(parent)
+  , ui(new Ui::ChatDialog)
+  , m_contactManager(contactManager)
+  , m_chatroomPrefix(chatroomPrefix)
+  , m_localPrefix(localPrefix)
+  , m_defaultIdentity(defaultIdentity)
+  , m_invitationPolicyManager(ndn::Ptr<InvitationPolicyManager>(new InvitationPolicyManager(m_chatroomPrefix.get(-1).toUri())))
+  , m_sock(NULL)
+  , m_lastMsgTime(0)
+  // , m_historyInitialized(false)
+  , m_joined(false)
+  , m_inviteListDialog(new InviteListDialog(m_contactManager))
 {
+  qRegisterMetaType<std::vector<Sync::MissingDataInfo> >("std::vector<Sync::MissingDataInfo>");
+  qRegisterMetaType<size_t>("size_t");
+
   ui->setupUi(this);
 
+  m_localChatPrefix = m_localPrefix;
+  m_localChatPrefix.append("FH").append(m_defaultIdentity);
+  m_localChatPrefix.append("chronos").append(m_chatroomPrefix.get(-1));
+
+  m_session = time(NULL);
+  m_scene = new DigestTreeScene(this);
+
+  initializeSetting();
+  updateLabels();
+
+  ui->treeViewer->setScene(m_scene);
+  ui->treeViewer->hide();
+  m_scene->plot("Empty");
+  QRectF rect = m_scene->itemsBoundingRect();
+  m_scene->setSceneRect(rect);
+
+  m_rosterModel = new QStringListModel(this);
+  ui->listView->setModel(m_rosterModel);
+
+  m_timer = new QTimer(this);
+
   setWrapper();
+
+  connect(ui->inviteButton, SIGNAL(clicked()),
+          this, SLOT(openInviteListDialog()));
+  connect(m_inviteListDialog, SIGNAL(invitionDetermined(QString, bool)),
+          this, SLOT(sendInvitationWrapper(QString, bool)));
+  connect(ui->lineEdit, SIGNAL(returnPressed()), 
+          this, SLOT(returnPressed()));
+  connect(ui->treeButton, SIGNAL(pressed()), 
+          this, SLOT(treeButtonPressed()));
+  connect(this, SIGNAL(dataReceived(QString, const char *, size_t, bool, bool)), 
+          this, SLOT(processData(QString, const char *, size_t, bool, bool)));
+  connect(this, SIGNAL(treeUpdated(const std::vector<Sync::MissingDataInfo>)), 
+          this, SLOT(processTreeUpdate(const std::vector<Sync::MissingDataInfo>)));
+  connect(m_timer, SIGNAL(timeout()), 
+          this, SLOT(replot()));
+  connect(m_scene, SIGNAL(replot()), 
+          this, SLOT(replot()));
+  // TODO: TrayIcon
+  // connect(trayIcon, SIGNAL(messageClicked()), 
+  //         this, SLOT(showNormal()));
+  // connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), 
+  //         this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
+  connect(m_scene, SIGNAL(rosterChanged(QStringList)), 
+          this, SLOT(updateRosterList(QStringList)));
+
+  // m_identityManager = ndn::Ptr<ndn::security::IdentityManager>::Create();
+  // // ndn::Ptr<ndn::security::EncryptionManager> encryptionManager = ndn::Ptr<ndn::security::EncryptionManager>(new ndn::security::BasicEncryptionManager(privateStorage, "/tmp/encryption.db"));
+
+  // ndn::Name certificateName = m_identityManager->getDefaultCertificateNameByIdentity(m_defaultIdentity);
+  // m_syncPolicyManager = ndn::Ptr<SyncPolicyManager>(new SyncPolicyManager(m_defaultIdentity, certificateName, m_chatroomPrefix));
+
+  initializeSync();
 }
 
+// ChatDialog::ChatDialog(const ndn::Name& chatroomPrefix,
+// 		       const ndn::Name& localPrefix,
+//                        const ndn::Name& defaultIdentity,
+//                        const ndn::security::IdentityCertificate& identityCertificate,
+// 		       QWidget *parent) 
+//     : QDialog(parent)
+//     , ui(new Ui::ChatDialog)
+//     , m_chatroomPrefix(chatroomPrefix)
+//     , m_localPrefix(localPrefix)
+//     , m_defaultIdentity(defaultIdentity)
+//     , m_invitationPolicyManager(ndn::Ptr<InvitationPolicyManager>(new InvitationPolicyManager(m_chatroomPrefix.get(-1).toUri())))
+
+//     , m_sock(NULL)
+//     , m_lastMsgTime(0)
+//     // , m_historyInitialized(false)
+//     , m_joined(false)
+// {
+//   qRegisterMetaType<std::vector<Sync::MissingDataInfo> >("std::vector<Sync::MissingDataInfo>");
+//   qRegisterMetaType<size_t>("size_t");
+
+//   ui->setupUi(this);
+
+//   m_localChatPrefix = m_localPrefix;
+//   m_localChatPrefix.append("FH").append(m_defaultIdentity);
+//   m_localChatPrefix.append("chronos").append(m_chatroomPrefix.get(-1));
+
+//   m_session = time(NULL);
+//   m_scene = new DigestTreeScene(this);
+
+//   initializeSetting();
+//   updateLabels();
+
+//   ui->treeViewer->setScene(m_scene);
+//   ui->treeViewer->hide();
+//   m_scene->plot("Empty");
+//   QRectF rect = m_scene->itemsBoundingRect();
+//   m_scene->setSceneRect(rect);
+
+//   m_rosterModel = new QStringListModel(this);
+//   ui->listView->setModel(m_rosterModel);
+
+//   m_timer = new QTimer(this);
+
+//   setWrapper();
+
+//   connect(ui->lineEdit, SIGNAL(returnPressed()), 
+//           this, SLOT(returnPressed()));
+//   connect(ui->treeButton, SIGNAL(pressed()), 
+//           this, SLOT(treeButtonPressed()));
+//   connect(this, SIGNAL(dataReceived(QString, const char *, size_t, bool, bool)), 
+//           this, SLOT(processData(QString, const char *, size_t, bool, bool)));
+//   connect(this, SIGNAL(treeUpdated(const std::vector<Sync::MissingDataInfo>)), 
+//           this, SLOT(processTreeUpdate(const std::vector<Sync::MissingDataInfo>)));
+//   connect(m_timer, SIGNAL(timeout()), 
+//           this, SLOT(replot()));
+//   connect(m_scene, SIGNAL(replot()), 
+//           this, SLOT(replot()));
+//   // TODO: TrayIcon
+//   // connect(trayIcon, SIGNAL(messageClicked()), 
+//   //         this, SLOT(showNormal()));
+//   // connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), 
+//   //         this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
+//   connect(m_scene, SIGNAL(rosterChanged(QStringList)), 
+//           this, SLOT(updateRosterList(QStringList)));
+
+//   // m_identityManager = ndn::Ptr<ndn::security::IdentityManager>::Create();
+//   // // ndn::Ptr<ndn::security::EncryptionManager> encryptionManager = ndn::Ptr<ndn::security::EncryptionManager>(new ndn::security::BasicEncryptionManager(privateStorage, "/tmp/encryption.db"));
+
+//   // ndn::Name certificateName = m_identityManager->getDefaultCertificateNameByIdentity(m_defaultIdentity);
+//   // m_syncPolicyManager = ndn::Ptr<SyncPolicyManager>(new SyncPolicyManager(m_defaultIdentity, certificateName, m_chatroomPrefix));
+
+//   initializeSync();
+// }
+
 ChatDialog::~ChatDialog()
 {
   delete ui;
+  sendLeave();
   m_handler->shutdown();
 }
 
 void
 ChatDialog::setWrapper()
 {
-  Ptr<security::OSXPrivatekeyStorage> privateStorage = Ptr<security::OSXPrivatekeyStorage>::Create();
-  m_identityManager = Ptr<security::IdentityManager>(new security::IdentityManager(Ptr<security::BasicIdentityStorage>::Create(), privateStorage));
-  Ptr<security::EncryptionManager> encryptionManager = Ptr<security::EncryptionManager>(new security::BasicEncryptionManager(privateStorage, "/tmp/encryption.db"));
+  m_identityManager = ndn::Ptr<ndn::security::IdentityManager>::Create();
+  // ndn::Ptr<ndn::security::EncryptionManager> encryptionManager = ndn::Ptr<ndn::security::EncryptionManager>(new ndn::security::BasicEncryptionManager(privateStorage, "/tmp/encryption.db"));
 
-  m_keychain = Ptr<security::Keychain>(new security::Keychain(m_identityManager, m_policyManager, encryptionManager));
+  ndn::Name certificateName = m_identityManager->getDefaultCertificateNameByIdentity(m_defaultIdentity);
+  m_syncPolicyManager = ndn::Ptr<SyncPolicyManager>(new SyncPolicyManager(m_defaultIdentity, certificateName, m_chatroomPrefix));
 
-  m_handler = Ptr<Wrapper>(new Wrapper(m_keychain));
+  m_keychain = ndn::Ptr<ndn::security::Keychain>(new ndn::security::Keychain(m_identityManager, m_invitationPolicyManager, NULL));
+
+  m_handler = ndn::Ptr<ndn::Wrapper>(new ndn::Wrapper(m_keychain));
 }
 
 void
-ChatDialog::sendInvitation(Ptr<ContactItem> contact)
+ChatDialog::initializeSetting()
 {
-  m_policyManager->addTrustAnchor(contact->getSelfEndorseCertificate());
+  // TODO: nick name may be changed.
+  m_user.setNick(QString::fromStdString(m_defaultIdentity.get(-1).toUri()));
+  m_user.setChatroom(QString::fromStdString(m_chatroomPrefix.get(-1).toUri()));
+  m_user.setOriginPrefix(QString::fromStdString(m_localPrefix.toUri()));
+  m_user.setPrefix(QString::fromStdString(m_localChatPrefix.toUri()));
+  m_scene->setCurrentPrefix(QString::fromStdString(m_localChatPrefix.toUri()));
+}
 
-  Name certificateName = m_identityManager->getDefaultCertificateNameByIdentity(m_defaultIdentity);
+void
+ChatDialog::updateLabels()
+{
+  QString settingDisp = QString("Chatroom: %1").arg(m_user.getChatroom());
+  ui->infoLabel->setStyleSheet("QLabel {color: #630; font-size: 16px; font: bold \"Verdana\";}");
+  ui->infoLabel->setText(settingDisp);
+  QString prefixDisp;
+  if (m_user.getPrefix().startsWith("/private/local"))
+  {
+    prefixDisp = QString("<Warning: no connection to hub or hub does not support prefix autoconfig.>\n <Prefix = %1>").arg(m_user.getPrefix());
+    ui->prefixLabel->setStyleSheet("QLabel {color: red; font-size: 12px; font: bold \"Verdana\";}");
+  }
+  else
+  {
+    prefixDisp = QString("<Prefix = %1>").arg(m_user.getPrefix());
+    ui->prefixLabel->setStyleSheet("QLabel {color: Green; font-size: 12px; font: bold \"Verdana\";}");
+  }
+  ui->prefixLabel->setText(prefixDisp);
+}
 
-  Name interestName("/ndn/broadcast/chronos/invitation");
+void
+ChatDialog::sendInvitation(ndn::Ptr<ContactItem> contact, bool isIntroducer)
+{
+  m_invitationPolicyManager->addTrustAnchor(contact->getSelfEndorseCertificate());
+
+  ndn::Name certificateName = m_identityManager->getDefaultCertificateNameByIdentity(m_defaultIdentity);
+
+  ndn::Name interestName("/ndn/broadcast/chronos/invitation");
   interestName.append(contact->getNameSpace());
   interestName.append("chatroom");
   interestName.append(m_chatroomPrefix.get(-1));
@@ -75,68 +255,100 @@
   interestName.append(certificateName);
 
   string signedUri = interestName.toUri();
-  Blob signedBlob(signedUri.c_str(), signedUri.size());
+  ndn::Blob signedBlob(signedUri.c_str(), signedUri.size());
 
-  Ptr<const signature::Sha256WithRsa> sha256sig = DynamicCast<const signature::Sha256WithRsa>(m_identityManager->signByCertificate(signedBlob, certificateName));
-  const Blob& sigBits = sha256sig->getSignatureBits();
+  ndn::Ptr<const ndn::signature::Sha256WithRsa> sha256sig = ndn::DynamicCast<const ndn::signature::Sha256WithRsa>(m_identityManager->signByCertificate(signedBlob, certificateName));
+  const ndn::Blob& sigBits = sha256sig->getSignatureBits();
 
   interestName.append(sigBits.buf(), sigBits.size());
 
-  Ptr<Interest> interest = Ptr<Interest>(new Interest(interestName));
-  Ptr<Closure> closure = Ptr<Closure>(new Closure(boost::bind(&ChatDialog::onInviteReplyVerified,
-                                                              this,
-                                                              _1,
-                                                              contact->getNameSpace()),
-                                                  boost::bind(&ChatDialog::onInviteTimeout,
-                                                              this,
-                                                              _1,
-                                                              _2,
-                                                              contact->getNameSpace(),
-                                                              7),
-                                                  boost::bind(&ChatDialog::onUnverified,
-                                                              this,
-                                                              _1)));
+  ndn::Ptr<ndn::Interest> interest = ndn::Ptr<ndn::Interest>(new ndn::Interest(interestName));
+  ndn::Ptr<ndn::Closure> closure = ndn::Ptr<ndn::Closure>(new ndn::Closure(boost::bind(&ChatDialog::onInviteReplyVerified,
+                                                                                       this,
+                                                                                       _1,
+                                                                                       contact->getNameSpace(),
+                                                                                       isIntroducer),
+                                                                           boost::bind(&ChatDialog::onInviteTimeout,
+                                                                                       this,
+                                                                                       _1,
+                                                                                       _2,
+                                                                                       contact->getNameSpace(),
+                                                                                       7),
+                                                                           boost::bind(&ChatDialog::onUnverified,
+                                                                                       this,
+                                                                                       _1)));
 
   m_handler->sendInterest(interest, closure);
 }
 
 void
-ChatDialog::invitationRejected(const Name& identity)
+ChatDialog::addTrustAnchor(const EndorseCertificate& selfEndorseCertificate)
+{ m_invitationPolicyManager->addTrustAnchor(selfEndorseCertificate); }
+
+void
+ChatDialog::addChatDataRule(const ndn::Name& prefix, 
+                            const ndn::security::IdentityCertificate& identityCertificate,
+                            bool isIntroducer)
+{ m_syncPolicyManager->addChatDataRule(prefix, identityCertificate, isIntroducer); }
+
+void
+ChatDialog::publishIntroCert(ndn::Ptr<ndn::security::IdentityCertificate> dskCertificate, bool isIntroducer)
 {
-  _LOG_DEBUG(" " << identity.toUri() << " rejected your invitation!");
+  SyncIntroCertificate syncIntroCertificate(m_chatroomPrefix,
+                                            dskCertificate->getPublicKeyName(),
+                                            m_identityManager->getDefaultKeyNameForIdentity(m_defaultIdentity),
+                                            dskCertificate->getNotBefore(),
+                                            dskCertificate->getNotAfter(),
+                                            dskCertificate->getPublicKeyInfo(),
+                                            (isIntroducer ? SyncIntroCertificate::INTRODUCER : SyncIntroCertificate::PRODUCER));
+  ndn::Name certName = m_identityManager->getDefaultCertificateNameByIdentity(m_defaultIdentity);
+  m_identityManager->signByCertificate(syncIntroCertificate, certName);
+  m_handler->putToNdnd(*syncIntroCertificate.encodeToWire());
 }
 
 void
-ChatDialog::invitationAccepted(const Name& identity)
+ChatDialog::invitationRejected(const ndn::Name& identity)
+{
+  _LOG_DEBUG(" " << identity.toUri() << " rejected your invitation!");
+  //TODO:
+}
+
+void
+ChatDialog::invitationAccepted(const ndn::Name& identity, ndn::Ptr<ndn::Data> data, const string& inviteePrefix, bool isIntroducer)
 {
   _LOG_DEBUG(" " << identity.toUri() << " accepted your invitation!");
+  ndn::Ptr<const ndn::signature::Sha256WithRsa> sha256sig = boost::dynamic_pointer_cast<const ndn::signature::Sha256WithRsa> (data->getSignature());
+  const ndn::Name & keyLocatorName = sha256sig->getKeyLocator().getKeyName();
+  ndn::Ptr<ndn::security::IdentityCertificate> dskCertificate = m_invitationPolicyManager->getValidatedDskCertificate(keyLocatorName);
+  m_syncPolicyManager->addChatDataRule(inviteePrefix, *dskCertificate, isIntroducer);
+  publishIntroCert(dskCertificate, isIntroducer);
 }
 
 void 
-ChatDialog::onInviteReplyVerified(Ptr<Data> data, const Name& identity)
+ChatDialog::onInviteReplyVerified(ndn::Ptr<ndn::Data> data, const ndn::Name& identity, bool isIntroducer)
 {
   string content(data->content().buf(), data->content().size());
   if(content.empty())
     invitationRejected(identity);
   else
-    invitationAccepted(identity);
+    invitationAccepted(identity, data, content, isIntroducer);
 }
 
 void 
-ChatDialog::onInviteTimeout(Ptr<Closure> closure, Ptr<Interest> interest, const Name& identity, int retry)
+ChatDialog::onInviteTimeout(ndn::Ptr<ndn::Closure> closure, ndn::Ptr<ndn::Interest> interest, const ndn::Name& identity, int retry)
 {
   if(retry > 0)
     {
-      Ptr<Closure> newClosure = Ptr<Closure>(new Closure(closure->m_dataCallback,
-                                                         boost::bind(&ChatDialog::onInviteTimeout, 
-                                                                     this, 
-                                                                     _1, 
-                                                                     _2, 
-                                                                     identity,
-                                                                     retry - 1),
-                                                         closure->m_unverifiedCallback,
-                                                         closure->m_stepCount)
-                                             );
+      ndn::Ptr<ndn::Closure> newClosure = ndn::Ptr<ndn::Closure>(new ndn::Closure(closure->m_dataCallback,
+                                                                                  boost::bind(&ChatDialog::onInviteTimeout, 
+                                                                                              this, 
+                                                                                              _1, 
+                                                                                              _2, 
+                                                                                              identity,
+                                                                                              retry - 1),
+                                                                                  closure->m_unverifiedCallback,
+                                                                                  closure->m_stepCount)
+                                                                 );
       m_handler->sendInterest(interest, newClosure);
     }
   else
@@ -144,9 +356,620 @@
 }
  
 void
-ChatDialog::onUnverified(Ptr<Data> data)
+ChatDialog::onUnverified(ndn::Ptr<ndn::Data> data)
 {}
 
+void
+ChatDialog::initializeSync()
+{
+  
+  m_sock = new Sync::SyncSocket(m_chatroomPrefix.toUri(),
+                                m_syncPolicyManager,
+                                bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
+                                bind(&ChatDialog::processRemoveWrapper, this, _1));
+  
+  usleep(100000);
+
+  QTimer::singleShot(600, this, SLOT(sendJoin()));
+  m_timer->start(FRESHNESS * 1000);
+  disableTreeDisplay();
+  QTimer::singleShot(2200, this, SLOT(enableTreeDisplay()));
+  // Sync::CcnxWrapperPtr handle = boost::make_shared<Sync::CcnxWrapper> ();
+  // handle->setInterestFilter(m_user.getPrefix().toStdString(), bind(&ChatDialog::respondHistoryRequest, this, _1));
+  // _LOG_DEBUG("initializeSync is done!");
+}
+
+void
+ChatDialog::returnPressed()
+{
+  QString text = ui->lineEdit->text();
+  if (text.isEmpty())
+    return;
+
+  ui->lineEdit->clear();
+
+  if (text.startsWith("boruoboluomi"))
+  {
+    summonReaper ();
+    // reapButton->show();
+    fitView();
+    return;
+  }
+
+  if (text.startsWith("minimanihong"))
+  {
+    // reapButton->hide();
+    fitView();
+    return;
+  }
+
+  SyncDemo::ChatMessage msg;
+  formChatMessage(text, msg);
+
+  appendMessage(msg);
+
+  sendMsg(msg);
+
+  fitView();
+}
+
+void 
+ChatDialog::treeButtonPressed()
+{
+  if (ui->treeViewer->isVisible())
+  {
+    ui->treeViewer->hide();
+    ui->treeButton->setText("Show ChronoSync Tree");
+  }
+  else
+  {
+    ui->treeViewer->show();
+    ui->treeButton->setText("Hide ChronoSync Tree");
+  }
+
+  fitView();
+}
+
+void ChatDialog::disableTreeDisplay()
+{
+  ui->treeButton->setEnabled(false);
+  ui->treeViewer->hide();
+  fitView();
+}
+
+void ChatDialog::enableTreeDisplay()
+{
+  ui->treeButton->setEnabled(true);
+  // treeViewer->show();
+  // fitView();
+}
+
+void
+ChatDialog::processTreeUpdateWrapper(const std::vector<Sync::MissingDataInfo> v, Sync::SyncSocket *sock)
+{
+  emit treeUpdated(v);
+  _LOG_DEBUG("<<< Tree update signal emitted");
+}
+
+void
+ChatDialog::processRemoveWrapper(std::string prefix)
+{
+  _LOG_DEBUG("Sync REMOVE signal received for prefix: " << prefix);
+}
+
+void
+ChatDialog::processTreeUpdate(const std::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::processDataWrapper(ndn::Ptr<ndn::Data> data)
+{
+  string name = data->getName().toUri();
+  const char* buf = data->content().buf();
+  size_t len = data->content().size();
+
+  char *tempBuf = new char[len];
+  memcpy(tempBuf, buf, len);
+  emit dataReceived(name.c_str(), tempBuf, len, true, false);
+  _LOG_DEBUG("<<< " << name << " fetched");
+}
+
+void
+ChatDialog::processDataNoShowWrapper(ndn::Ptr<ndn::Data> data)
+{
+  string name = data->getName().toUri();
+  const char* buf = data->content().buf();
+  size_t len = data->content().size();
+
+  char *tempBuf = new char[len];
+  memcpy(tempBuf, buf, len);
+  emit dataReceived(name.c_str(), tempBuf, len, false, false);
+
+  // if (!m_historyInitialized)
+  // {
+  //   fetchHistory(name);
+  //   m_historyInitialized = true;
+  // }
+}
+
+// void
+// ChatDialog::fetchHistory(std::string name)
+// {
+
+//   /****************************/
+//   /* TODO: fix following part */
+//   /****************************/
+//   string nameWithoutSeq = name.substr(0, name.find_last_of('/'));
+//   string prefix = nameWithoutSeq.substr(0, nameWithoutSeq.find_last_of('/'));
+//   prefix += "/history";
+//   // Ptr<Wrapper>CcnxWrapperPtr handle = boost::make_shared<Sync::CcnxWrapper> ();
+//   // QString randomString = getRandomString();
+//   // for (int i = 0; i < MAX_HISTORY_ENTRY; i++)
+//   // {
+//   //   QString interest = QString("%1/%2/%3").arg(prefix.c_str()).arg(randomString).arg(i);
+//   //   handle->sendInterest(interest.toStdString(), bind(&ChatDialog::processDataHistoryWrapper, this, _1, _2, _3));
+//   // }
+// }
+
+void
+ChatDialog::processData(QString name, const char *buf, size_t len, bool show, bool isHistory)
+{
+  SyncDemo::ChatMessage msg;
+  bool corrupted = false;
+  if (!msg.ParseFromArray(buf, len))
+  {
+    _LOG_DEBUG("Errrrr.. Can not parse msg with name: " << name.toStdString() << ". 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;
+  }
+
+  delete [] buf;
+  buf = NULL;
+
+  // 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
+    std::string stdStrName = name.toStdString();
+    std::string stdStrNameWithoutSeq = stdStrName.substr(0, stdStrName.find_last_of('/'));
+    std::string prefix = stdStrNameWithoutSeq.substr(0, stdStrNameWithoutSeq.find_last_of('/'));
+    _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::processRemove(QString prefix)
+{
+  _LOG_DEBUG("<<< remove node for prefix" << prefix.toStdString());
+
+  bool removed = m_scene->removeNode(prefix);
+  if (removed)
+  {
+    boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
+    m_scene->plot(m_sock->getRootDigest().c_str());
+  }
+}
+
+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()
+{
+  time_t now = time(NULL);
+  int elapsed = now - m_lastMsgTime;
+  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->remove(m_user.getPrefix().toStdString());
+  usleep(5000);
+  m_joined = false;
+  _LOG_DEBUG("Sync REMOVE signal sent");
+}
+
+void
+ChatDialog::replot()
+{
+  boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
+  m_scene->plot(m_sock->getRootDigest().c_str());
+  fitView();
+}
+
+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::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::updateRosterList(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())
+  {
+    std::string nick = it.next().toStdString();
+    if (nick.empty())
+      continue;
+
+    SyncDemo::ChatMessage msg;
+    formControlMessage(msg, SyncDemo::ChatMessage::LEAVE);
+    msg.set_from(nick);
+    appendMessage(msg);
+  }
+}
+
+void
+ChatDialog::resizeEvent(QResizeEvent *e)
+{
+  fitView();
+}
+
+void
+ChatDialog::showEvent(QShowEvent *e)
+{
+  fitView();
+}
+
+void
+ChatDialog::fitView()
+{
+  boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
+  QRectF rect = m_scene->itemsBoundingRect();
+  m_scene->setSceneRect(rect);
+  ui->treeViewer->fitInView(m_scene->itemsBoundingRect(), Qt::KeepAspectRatio);
+}
+
+void
+ChatDialog::formChatMessage(const QString &text, SyncDemo::ChatMessage &msg) {
+  msg.set_from(m_user.getNick().toStdString());
+  msg.set_to(m_user.getChatroom().toStdString());
+  msg.set_data(text.toUtf8().constData());
+  time_t seconds = time(NULL);
+  msg.set_timestamp(seconds);
+  msg.set_type(SyncDemo::ChatMessage::CHAT);
+}
+
+void
+ChatDialog::formControlMessage(SyncDemo::ChatMessage &msg, SyncDemo::ChatMessage::ChatMessageType type)
+{
+  msg.set_from(m_user.getNick().toStdString());
+  msg.set_to(m_user.getChatroom().toStdString());
+  time_t seconds = time(NULL);
+  msg.set_timestamp(seconds);
+  msg.set_type(type);
+}
+
+void
+ChatDialog::appendMessage(const SyncDemo::ChatMessage msg, bool isHistory)
+{
+  boost::recursive_mutex::scoped_lock lock(m_msgMutex);
+
+  if (msg.type() == SyncDemo::ChatMessage::CHAT)
+  {
+
+    if (!msg.has_data())
+    {
+      return;
+    }
+
+    if (msg.from().empty() || msg.data().empty())
+    {
+      return;
+    }
+
+    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);
+  }
+
+  QScrollBar *bar = ui->textEdit->verticalScrollBar();
+  bar->setValue(bar->maximum());
+}
+
+QString
+ChatDialog::formatTime(time_t timestamp)
+{
+  struct tm *tm_time = localtime(&timestamp);
+  int hour = tm_time->tm_hour;
+  QString amOrPM;
+  if (hour > 12)
+  {
+    hour -= 12;
+    amOrPM = "PM";
+  }
+  else
+  {
+    amOrPM = "AM";
+    if (hour == 0)
+    {
+      hour = 12;
+    }
+  }
+
+  char textTime[12];
+  sprintf(textTime, "%d:%02d:%02d %s", hour, tm_time->tm_min, tm_time->tm_sec, amOrPM.toStdString().c_str());
+  return QString(textTime);
+}
+
+void
+ChatDialog::printTimeInCell(QTextTable *table, time_t timestamp)
+{
+  QTextCharFormat timeFormat;
+  timeFormat.setForeground(Qt::gray);
+  timeFormat.setFontUnderline(true);
+  timeFormat.setUnderlineColor(Qt::gray);
+  QTextTableCell timeCell = table->cellAt(0, 1);
+  timeCell.setFormat(timeFormat);
+  timeCell.firstCursorPosition().insertText(formatTime(timestamp));
+}
+
+void
+ChatDialog::showMessage(QString from, QString data)
+{
+  if (!isActiveWindow())
+  {
+    //TODO: Notification to be done
+    // trayIcon->showMessage(QString("Chatroom %1 has a new message").arg(m_user.getChatroom()), QString("<%1>: %2").arg(from).arg(data), QSystemTrayIcon::Information, 20000);
+    // trayIcon->setIcon(QIcon(":/images/note.png"));
+  }
+}
+
+void
+ChatDialog::sendMsg(SyncDemo::ChatMessage &msg)
+{
+  // send msg
+  size_t size = msg.ByteSize();
+  char *buf = new char[size];
+  msg.SerializeToArray(buf, size);
+  if (!msg.IsInitialized())
+  {
+    _LOG_DEBUG("Errrrr.. msg was not probally initialized "<<__FILE__ <<":"<<__LINE__<<". what is happening?");
+    abort();
+  }
+  m_sock->publishData(m_user.getPrefix().toStdString(), m_session, buf, size, FRESHNESS);
+
+  delete buf;
+
+  m_lastMsgTime = time(NULL);
+
+  int nextSequence = m_sock->getNextSeq(m_user.getPrefix().toStdString(), m_session);
+  Sync::MissingDataInfo mdi = {m_user.getPrefix().toStdString(), Sync::SeqNo(0), Sync::SeqNo(nextSequence - 1)};
+  std::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(m_user.getPrefix(), m_user.getNick());
+  }
+}
+
+void
+ChatDialog::openInviteListDialog()
+{
+  m_inviteListDialog->setInviteLabel(m_chatroomPrefix.toUri());
+  m_inviteListDialog->show();
+}
+
+void
+ChatDialog::sendInvitationWrapper(QString invitee, bool isIntroducer)
+{
+  ndn::Name inviteeNamespace(invitee.toUtf8().constData());
+  ndn::Ptr<ContactItem> inviteeItem = m_contactManager->getContact(inviteeNamespace);
+  sendInvitation(inviteeItem, isIntroducer);
+}
+
+
 #if WAF
 #include "chatdialog.moc"
 #include "chatdialog.cpp.moc"
