diff --git a/src/chat-dialog-backend.cpp b/src/chat-dialog-backend.cpp
new file mode 100644
index 0000000..87eed37
--- /dev/null
+++ b/src/chat-dialog-backend.cpp
@@ -0,0 +1,386 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "chat-dialog-backend.hpp"
+
+#ifndef Q_MOC_RUN
+#include <ndn-cxx/util/io.hpp>
+#include "logging.h"
+#endif
+
+
+INIT_LOGGER("ChatDialogBackend");
+
+namespace chronos {
+
+static const time::milliseconds FRESHNESS_PERIOD(60000);
+static const time::seconds HELLO_INTERVAL(60);
+static const uint8_t ROUTING_HINT_SEPARATOR[2] = {0xF0, 0x2E}; // %F0.
+
+ChatDialogBackend::ChatDialogBackend(const Name& chatroomPrefix,
+                                     const Name& userChatPrefix,
+                                     const Name& routingPrefix,
+                                     const std::string& chatroomName,
+                                     const std::string& nick,
+                                     QObject* parent)
+  : QThread(parent)
+  , m_localRoutingPrefix(routingPrefix)
+  , m_chatroomPrefix(chatroomPrefix)
+  , m_userChatPrefix(userChatPrefix)
+  , m_chatroomName(chatroomName)
+  , m_nick(nick)
+  , m_scheduler(m_face.getIoService())
+{
+  updatePrefixes();
+}
+
+
+ChatDialogBackend::~ChatDialogBackend()
+{
+}
+
+// protected methods:
+void
+ChatDialogBackend::run()
+{
+  initializeSync();
+
+  m_face.processEvents();
+
+  std::cerr << "Bye!" << std::endl;
+}
+
+// private methods:
+void
+ChatDialogBackend::initializeSync()
+{
+  QMutexLocker locker(&mutex);
+
+  // if a SyncSocket is running, turn it off
+  if (static_cast<bool>(m_sock)) {
+    if (m_joined)
+      sendLeave();
+    m_sock.reset();
+
+    usleep(100000);
+  }
+
+  // create a new SyncSocket
+  m_sock = make_shared<chronosync::Socket>(m_chatroomPrefix,
+                                           m_routableUserChatPrefix,
+                                           ref(m_face),
+                                           bind(&ChatDialogBackend::processSyncUpdate, this, _1));
+
+  // schedule a new join event
+  m_scheduler.scheduleEvent(time::milliseconds(600),
+                            bind(&ChatDialogBackend::sendJoin, this));
+
+  // cancel existing hello event if it exists
+  if (static_cast<bool>(m_helloEventId)) {
+    m_scheduler.cancelEvent(m_helloEventId);
+    m_helloEventId.reset();
+  }
+}
+
+void
+ChatDialogBackend::processSyncUpdate(const std::vector<chronosync::MissingDataInfo>& updates)
+{
+  _LOG_DEBUG("<<< processing Tree Update");
+
+  if (updates.empty()) {
+    return;
+  }
+
+  std::vector<NodeInfo> nodeInfos;
+
+
+  for (int i = 0; i < updates.size(); i++) {
+    // update roster
+    if (m_roster.find(updates[i].session) == m_roster.end()) {
+      m_roster[updates[i].session].sessionPrefix = updates[i].session;
+      m_roster[updates[i].session].hasNick = false;
+    }
+
+    // fetch missing chat data
+    if (updates[i].high - updates[i].low < 3) {
+      for (chronosync::SeqNo seq = updates[i].low; seq <= updates[i].high; ++seq) {
+        m_sock->fetchData(updates[i].session, seq,
+                          bind(&ChatDialogBackend::processChatData, this, _1, true),
+                          2);
+        _LOG_DEBUG("<<< Fetching " << updates[i].session << "/" << seq);
+      }
+    }
+    else {
+      // There are too many msgs to fetch, let's just fetch the latest one
+      m_sock->fetchData(updates[i].session, updates[i].high,
+                        bind(&ChatDialogBackend::processChatData, this, _1, false),
+                        2);
+    }
+
+    // prepare notification to frontend
+    NodeInfo nodeInfo;
+    nodeInfo.sessionPrefix = QString::fromStdString(updates[i].session.toUri());
+    nodeInfo.seqNo = updates[i].high;
+    nodeInfos.push_back(nodeInfo);
+  }
+
+  // reflect the changes on GUI
+  emit syncTreeUpdated(nodeInfos,
+                       QString::fromStdString(getHexEncodedDigest(m_sock->getRootDigest())));
+}
+
+void
+ChatDialogBackend::processChatData(const ndn::shared_ptr<const ndn::Data>& data, bool needDisplay)
+{
+  SyncDemo::ChatMessage msg;
+
+  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);
+    return;
+  }
+
+  Name remoteSessionPrefix = data->getName().getPrefix(-1);
+
+  if (msg.type() == SyncDemo::ChatMessage::LEAVE) {
+    BackendRoster::iterator it = m_roster.find(remoteSessionPrefix);
+
+    if (it != m_roster.end()) {
+      // cancel timeout event
+      if (static_cast<bool>(it->second.timeoutEventId))
+        m_scheduler.cancelEvent(it->second.timeoutEventId);
+
+      // notify frontend to remove the remote session (node)
+      emit sessionRemoved(QString::fromStdString(remoteSessionPrefix.toUri()),
+                          QString::fromStdString(msg.from()),
+                          msg.timestamp());
+
+      // remove roster entry
+      m_roster.erase(remoteSessionPrefix);
+    }
+  }
+  else {
+    BackendRoster::iterator it = m_roster.find(remoteSessionPrefix);
+
+    if (it == m_roster.end()) {
+      // Should not happen
+      BOOST_ASSERT(false);
+    }
+
+    // If we haven't got any message from this session yet.
+    if (m_roster[remoteSessionPrefix].hasNick == false) {
+      m_roster[remoteSessionPrefix].userNick = msg.from();
+      m_roster[remoteSessionPrefix].hasNick = true;
+      emit sessionAdded(QString::fromStdString(remoteSessionPrefix.toUri()),
+                        QString::fromStdString(msg.from()),
+                        msg.timestamp());
+    }
+
+    // If we get a new nick for an existing session, update it.
+    if (m_roster[remoteSessionPrefix].userNick != msg.from()) {
+      m_roster[remoteSessionPrefix].userNick = msg.from();
+      emit nickUpdated(QString::fromStdString(remoteSessionPrefix.toUri()),
+                       QString::fromStdString(msg.from()));
+    }
+
+    // If a timeout event has been scheduled, cancel it.
+    if (static_cast<bool>(it->second.timeoutEventId))
+      m_scheduler.cancelEvent(it->second.timeoutEventId);
+
+    // (Re)schedule another timeout event after 3 HELLO_INTERVAL;
+    it->second.timeoutEventId =
+      m_scheduler.scheduleEvent(HELLO_INTERVAL * 3,
+                                bind(&ChatDialogBackend::remoteSessionTimeout,
+                                     this, remoteSessionPrefix));
+
+    // If chat message, notify the frontend
+    if (msg.type() == SyncDemo::ChatMessage::CHAT)
+      emit chatMessageReceived(QString::fromStdString(msg.from()),
+                               QString::fromStdString(msg.data()),
+                               msg.timestamp());
+
+    // Notify frontend to plot notification on DigestTree.
+    emit messageReceived(QString::fromStdString(remoteSessionPrefix.toUri()));
+  }
+}
+
+void
+ChatDialogBackend::remoteSessionTimeout(const Name& sessionPrefix)
+{
+  time_t timestamp =
+    static_cast<time_t>(time::toUnixTimestamp(time::system_clock::now()).count() / 1000);
+
+  // notify frontend
+  emit sessionRemoved(QString::fromStdString(sessionPrefix.toUri()),
+                      QString::fromStdString(m_roster[sessionPrefix].userNick),
+                      timestamp);
+
+  // remove roster entry
+  m_roster.erase(sessionPrefix);
+}
+
+void
+ChatDialogBackend::sendMsg(SyncDemo::ChatMessage& msg)
+{
+  // send msg
+  ndn::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->getLogic().getSeqNo() + 1;
+
+  m_sock->publishData(os.buf()->buf(), os.buf()->size(), FRESHNESS_PERIOD);
+
+  std::vector<NodeInfo> nodeInfos;
+  NodeInfo nodeInfo = {QString::fromStdString(m_routableUserChatPrefix.toUri()),
+                       nextSequence};
+  nodeInfos.push_back(nodeInfo);
+
+  emit syncTreeUpdated(nodeInfos,
+                       QString::fromStdString(getHexEncodedDigest(m_sock->getRootDigest())));
+}
+
+void
+ChatDialogBackend::sendJoin()
+{
+  m_joined = true;
+
+  SyncDemo::ChatMessage msg;
+  prepareControlMessage(msg, SyncDemo::ChatMessage::JOIN);
+  sendMsg(msg);
+
+  m_helloEventId = m_scheduler.scheduleEvent(HELLO_INTERVAL,
+                                             bind(&ChatDialogBackend::sendHello, this));
+
+  emit sessionAdded(QString::fromStdString(m_routableUserChatPrefix.toUri()),
+                    QString::fromStdString(msg.from()),
+                    msg.timestamp());
+}
+
+void
+ChatDialogBackend::sendHello()
+{
+  SyncDemo::ChatMessage msg;
+  prepareControlMessage(msg, SyncDemo::ChatMessage::HELLO);
+  sendMsg(msg);
+
+  m_helloEventId = m_scheduler.scheduleEvent(HELLO_INTERVAL,
+                                             bind(&ChatDialogBackend::sendHello, this));
+}
+
+void
+ChatDialogBackend::sendLeave()
+{
+  SyncDemo::ChatMessage msg;
+  prepareControlMessage(msg, SyncDemo::ChatMessage::LEAVE);
+  sendMsg(msg);
+
+  usleep(5000);
+  m_joined = false;
+}
+
+void
+ChatDialogBackend::prepareControlMessage(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);
+}
+
+void
+ChatDialogBackend::prepareChatMessage(const QString& text,
+                                      time_t timestamp,
+                                      SyncDemo::ChatMessage &msg)
+{
+  msg.set_from(m_nick);
+  msg.set_to(m_chatroomName);
+  msg.set_data(text.toStdString());
+  msg.set_timestamp(timestamp);
+  msg.set_type(SyncDemo::ChatMessage::CHAT);
+}
+
+void
+ChatDialogBackend::updatePrefixes()
+{
+  m_routableUserChatPrefix.clear();
+
+  if (m_localRoutingPrefix.isPrefixOf(m_userChatPrefix))
+    m_routableUserChatPrefix = m_userChatPrefix;
+  else
+    m_routableUserChatPrefix.append(m_localRoutingPrefix)
+      .append(ROUTING_HINT_SEPARATOR, 2)
+      .append(m_userChatPrefix);
+
+  emit chatPrefixChanged(m_routableUserChatPrefix);
+}
+
+std::string
+ChatDialogBackend::getHexEncodedDigest(ndn::ConstBufferPtr digest)
+{
+  std::stringstream os;
+
+  CryptoPP::StringSource(digest->buf(), digest->size(), true,
+                         new CryptoPP::HexEncoder(new CryptoPP::FileSink(os), false));
+  return os.str();
+}
+
+
+// public slots:
+void
+ChatDialogBackend::sendChatMessage(QString text, time_t timestamp)
+{
+  SyncDemo::ChatMessage msg;
+  prepareChatMessage(text, timestamp, msg);
+  sendMsg(msg);
+
+  emit chatMessageReceived(QString::fromStdString(msg.from()),
+                           QString::fromStdString(msg.data()),
+                           msg.timestamp());
+}
+
+void
+ChatDialogBackend::updateRoutingPrefix(const QString& localRoutingPrefix)
+{
+  Name newLocalRoutingPrefix(localRoutingPrefix.toStdString());
+
+  if (!newLocalRoutingPrefix.empty() && newLocalRoutingPrefix != m_localRoutingPrefix) {
+    // Update localPrefix
+    m_localRoutingPrefix = newLocalRoutingPrefix;
+
+    updatePrefixes();
+
+    initializeSync();
+  }
+}
+
+void
+ChatDialogBackend::shutdown()
+{
+  m_face.getIoService().stop();
+}
+
+} // namespace chronos
+
+#if WAF
+#include "chat-dialog-backend.moc"
+// #include "chat-dialog-backend.cpp.moc"
+#endif
diff --git a/src/chat-dialog-backend.hpp b/src/chat-dialog-backend.hpp
new file mode 100644
index 0000000..eda4094
--- /dev/null
+++ b/src/chat-dialog-backend.hpp
@@ -0,0 +1,156 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef CHRONOCHAT_CHAT_DIALOG_BACKEND_HPP
+#define CHRONOCHAT_CHAT_DIALOG_BACKEND_HPP
+
+#include <QThread>
+#include <QMutex>
+
+#ifndef Q_MOC_RUN
+#include "common.hpp"
+#include "chatroom-info.hpp"
+#include "chatbuf.pb.h"
+#include <socket.hpp>
+#endif
+
+namespace chronos {
+
+class NodeInfo {
+public:
+  QString sessionPrefix;
+  chronosync::SeqNo seqNo;
+};
+
+class UserInfo {
+public:
+  ndn::Name sessionPrefix;
+  bool hasNick;
+  std::string userNick;
+  ndn::EventId timeoutEventId;
+};
+
+class ChatDialogBackend : public QThread
+{
+  Q_OBJECT
+
+public:
+  ChatDialogBackend(const Name& chatroomPrefix,
+                    const Name& userChatPrefix,
+                    const Name& routingPrefix,
+                    const std::string& chatroomName,
+                    const std::string& nick,
+                    QObject* parent = 0);
+
+  ~ChatDialogBackend();
+
+protected:
+  void
+  run();
+
+private:
+  void
+  initializeSync();
+
+  void
+  processSyncUpdate(const std::vector<chronosync::MissingDataInfo>& updates);
+
+  void
+  processChatData(const ndn::shared_ptr<const ndn::Data>& data, bool needDisplay);
+
+  void
+  remoteSessionTimeout(const Name& sessionPrefix);
+
+  void
+  sendMsg(SyncDemo::ChatMessage& msg);
+
+  void
+  sendJoin();
+
+  void
+  sendHello();
+
+  void
+  sendLeave();
+
+  void
+  prepareControlMessage(SyncDemo::ChatMessage& msg,
+                        SyncDemo::ChatMessage::ChatMessageType type);
+
+  void
+  prepareChatMessage(const QString& text,
+                     time_t timestamp,
+                     SyncDemo::ChatMessage &msg);
+
+  void
+  updatePrefixes();
+
+  std::string
+  getHexEncodedDigest(ndn::ConstBufferPtr digest);
+
+signals:
+  void
+  syncTreeUpdated(std::vector<chronos::NodeInfo> updates, QString digest);
+
+  void
+  chatMessageReceived(QString nick, QString text, time_t timestamp);
+
+  void
+  sessionAdded(QString sessionPrefix, QString nick, time_t timestamp);
+
+  void
+  sessionRemoved(QString sessionPrefix, QString nick, time_t timestamp);
+
+  void
+  nickUpdated(QString sessionPrefix, QString nick);
+
+  void
+  messageReceived(QString sessionPrefix);
+
+  void
+  chatPrefixChanged(ndn::Name newChatPrefix);
+
+public slots:
+  void
+  sendChatMessage(QString text, time_t timestamp);
+
+  void
+  updateRoutingPrefix(const QString& localRoutingPrefix);
+
+  void
+  shutdown();
+
+private:
+  typedef std::map<ndn::Name, UserInfo> BackendRoster;
+
+  ndn::Face m_face;
+
+  Name m_localRoutingPrefix;             // routable local prefix
+  Name m_chatroomPrefix;                 // chatroom sync prefix
+  Name m_userChatPrefix;                 // user chat prefix
+  Name m_routableUserChatPrefix;         // routable user chat prefix
+
+  std::string m_chatroomName;            // chatroom name
+  std::string m_nick;                    // user nick
+
+  shared_ptr<chronosync::Socket> m_sock; // SyncSocket
+
+  ndn::Scheduler m_scheduler;            // scheduler
+  ndn::EventId m_helloEventId;           // event id of timeout
+
+  QMutex mutex;                          // mutex used for prefix updates
+
+  bool m_joined;                         // true if in a chatroom
+
+  BackendRoster m_roster;                // User roster
+};
+
+} // namespace chronos
+
+#endif // CHRONOCHAT_CHAT_DIALOG_BACKEND_HPP
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
diff --git a/src/chat-dialog.hpp b/src/chat-dialog.hpp
index 7c63b30..7f1a726 100644
--- a/src/chat-dialog.hpp
+++ b/src/chat-dialog.hpp
@@ -20,30 +20,16 @@
 #include <QTimer>
 
 #ifndef Q_MOC_RUN
-#include "common.hpp"
-#include "contact-manager.hpp"
 #include "invitation.hpp"
-#include "contact.hpp"
-#include "chatbuf.pb.h"
-#include "intro-cert-list.pb.h"
+
 #include "digest-tree-scene.hpp"
 #include "trust-tree-scene.hpp"
 #include "trust-tree-node.hpp"
-#include "validator-invitation.hpp"
-#include <sync-socket.h>
-#include <sync-seq-no.h>
-#include <ndn-cxx/security/key-chain.hpp>
-#include <boost/thread/locks.hpp>
-#include <boost/thread/recursive_mutex.hpp>
-#include <boost/thread/thread.hpp>
+#include "chat-dialog-backend.hpp"
+
 #include "chatroom-info.hpp"
 #endif
 
-#include "invite-list-dialog.hpp"
-
-
-#define MAX_HISTORY_ENTRY   20
-
 namespace Ui {
 class ChatDialog;
 }
@@ -56,37 +42,17 @@
 
 public:
   explicit
-  ChatDialog(ContactManager* contactManager,
-             shared_ptr<ndn::Face> face,
-             const ndn::IdentityCertificate& myCertificate,
-             const Name& chatroomPrefix,
-             const Name& localPrefix,
+  ChatDialog(const Name& chatroomPrefix,
+             const Name& userChatPrefix,
+             const Name& routingPrefix,
+             const std::string& chatroomName,
              const std::string& nick,
-             bool witSecurity,
+             bool isSecured = false,
              QWidget* parent = 0);
 
   ~ChatDialog();
 
   void
-  addSyncAnchor(const Invitation& invitation);
-
-  void
-  processTreeUpdateWrapper(const std::vector<Sync::MissingDataInfo>&, Sync::SyncSocket *);
-
-  void
-  processDataWrapper(const shared_ptr<const Data>& data);
-
-  void
-  processDataNoShowWrapper(const shared_ptr<const Data>& data);
-
-  void
-  processRemoveWrapper(const std::string& prefix);
-
-  //ymj
-  shared_ptr<ChatroomInfo>
-  getChatroomInfo() const;
-
-  void
   closeEvent(QCloseEvent* e);
 
   void
@@ -98,91 +64,29 @@
   void
   showEvent(QShowEvent* e);
 
+  ChatDialogBackend*
+  getBackend()
+  {
+    return &m_backend;
+  }
+
+  void
+  addSyncAnchor(const Invitation& invitation)
+  {
+  }
+
+  shared_ptr<ChatroomInfo>
+  getChatroomInfo();
+
 private:
   void
-  updatePrefix();
-
-  void
-  updateLabels();
-
-  void
-  initializeSync();
-
-  void
-  sendInvitation(shared_ptr<Contact> contact, bool isIntroducer);
-
-  void
-  replyWrapper(const Interest& interest, Data& data,
-               size_t routablePrefixOffset, bool isIntroducer);
-
-  void
-  replyTimeoutWrapper(const Interest& interest,
-                      size_t routablePrefixOffset);
-
-  void
-  onReplyValidated(const ndn::shared_ptr<const ndn::Data>& data,
-                   size_t inviteeRoutablePrefixOffset,
-                   bool isIntroduce);
-
-  void
-  onReplyValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
-                          const std::string& failureInfo);
-
-  void
-  invitationRejected(const Name& identity);
-
-  void
-  invitationAccepted(const ndn::IdentityCertificate& inviteeCert,
-                     const Name& inviteePrefix, bool isIntroducer);
-
-  void
-  fetchIntroCert(const Name& identity, const Name& prefix);
-
-  void
-  onIntroCertList(const Interest& interest, const Data& data);
-
-  void
-  onIntroCertListTimeout(const Interest& interest, int retry, const std::string& msg);
-
-  void
-  introCertWrapper(const Interest& interest, Data& data);
-
-  void
-  introCertTimeoutWrapper(const Interest& interest, int retry, const QString& msg);
-
-  void
-  onCertListInterest(const ndn::Name& prefix, const ndn::Interest& interest);
-
-  void
-  onCertListRegisterFailed(const ndn::Name& prefix, const std::string& msg);
-
-  void
-  onCertSingleInterest(const Name& prefix, const Interest& interest);
-
-  void
-  onCertSingleRegisterFailed(const Name& prefix, const std::string& msg);
-
-
-  void
-  sendMsg(SyncDemo::ChatMessage& msg);
-
-  void
   disableSyncTreeDisplay();
 
   void
-  appendMessage(const SyncDemo::ChatMessage msg, bool isHistory = false);
+  appendChatMessage(const QString& nick, const QString& text, time_t timestamp);
 
   void
-  processRemove(QString prefix);
-
-  ndn::Name
-  getInviteeRoutablePrefix(const Name& invitee);
-
-  void
-  formChatMessage(const QString& text, SyncDemo::ChatMessage& msg);
-
-  void
-  formControlMessage(SyncDemo::ChatMessage &msg, SyncDemo::ChatMessage::ChatMessageType type);
+  appendControlMessage(const QString& nick, const QString& action, time_t timestamp);
 
   QString
   formatTime(time_t timestamp);
@@ -190,61 +94,29 @@
   void
   printTimeInCell(QTextTable* table, time_t timestamp);
 
-  std::string
-  getRandomString();
-
   void
   showMessage(const QString&, const QString&);
 
   void
   fitView();
 
-  void
-  summonReaper();
-
-  void
-  getTree(TrustTreeNodeList& nodeList);
-
-  void
-  plotTrustTree();
-
 signals:
   void
-  processData(const ndn::shared_ptr<const ndn::Data>& data,
-              bool show, bool isHistory);
+  shutdownBackend();
 
   void
-  processTreeUpdate(const std::vector<Sync::MissingDataInfo>);
+  msgToSent(QString text, time_t timestamp);
 
   void
   closeChatDialog(const QString& chatroomName);
 
   void
-  inivationRejection(const QString& msg);
-
-  void
   showChatMessage(const QString& chatroomName, const QString& from, const QString& data);
 
   void
   resetIcon();
 
   void
-  reply(const ndn::Interest& interest, const ndn::shared_ptr<const ndn::Data>& data,
-        size_t routablePrefixOffset, bool isIntroducer);
-
-  void
-  replyTimeout(const ndn::Interest& interest, size_t routablePrefixOffset);
-
-  void
-  introCert(const ndn::Interest& interest, const ndn::shared_ptr<const ndn::Data>& data);
-
-  void
-  introCertTimeout(const ndn::Interest& interest, int retry, const QString& msg);
-
-  void
-  waitForContactList();
-
-  void
   rosterChanged(const chronos::ChatroomInfo& info);
 
 public slots:
@@ -252,13 +124,31 @@
   onShow();
 
   void
-  onLocalPrefixUpdated(const QString& localPrefix);
-
-  void
-  onClose();
+  shutdown();
 
 private slots:
   void
+  updateSyncTree(std::vector<chronos::NodeInfo> updates, QString rootDigest);
+
+  void
+  receiveChatMessage(QString nick, QString text, time_t timestamp);
+
+  void
+  addSession(QString sessionPrefix, QString nick, time_t timestamp);
+
+  void
+  removeSession(QString sessionPrefix, QString nick, time_t timestamp);
+
+  void
+  updateNick(QString sessionPrefix, QString nick);
+
+  void
+  receiveMessage(QString sessionPrefix);
+
+  void
+  updateLabels(ndn::Name newChatPrefix);
+
+  void
   onReturnPressed();
 
   void
@@ -268,97 +158,21 @@
   onTrustTreeButtonPressed();
 
   void
-  onProcessData(const ndn::shared_ptr<const ndn::Data>& data, bool show, bool isHistory);
-
-  void
-  onProcessTreeUpdate(const std::vector<Sync::MissingDataInfo>&);
-
-  void
-  onReplot();
-
-  void
-  onRosterChanged(QStringList staleUserList);
-
-  void
-  onInviteListDialogRequested();
-
-  void
-  sendJoin();
-
-  void
-  sendHello();
-
-  void
-  sendLeave();
-
-  void
   enableSyncTreeDisplay();
 
-  void
-  reap();
-
-  void
-  onSendInvitation(QString invitee);
-
-  void
-  onReply(const ndn::Interest& interest, const ndn::shared_ptr<const ndn::Data>& data,
-          size_t routablePrefixOffset, bool isIntroducer);
-
-  void
-  onReplyTimeout(const ndn::Interest& interest, size_t routablePrefixOffset);
-
-  void
-  onIntroCert(const ndn::Interest& interest, const ndn::shared_ptr<const ndn::Data>& data);
-
-  void
-  onIntroCertTimeout(const ndn::Interest& interest, int retry, const QString& msg);
-
 private:
-  Ui::ChatDialog *ui;
-  ndn::KeyChain m_keyChain;
+  Ui::ChatDialog* ui;
 
-  ContactManager* m_contactManager;
-  shared_ptr<ndn::Face> m_face;
-
-  ndn::IdentityCertificate m_myCertificate;
-  Name m_identity;
-
-  Name m_certListPrefix;
-  const ndn::RegisteredPrefixId* m_certListPrefixId;
-  Name m_certSinglePrefix;
-  const ndn::RegisteredPrefixId* m_certSinglePrefixId;
+  ChatDialogBackend m_backend;
 
   std::string m_chatroomName;
-  Name m_chatroomPrefix;
-  Name m_localPrefix;
-  bool m_useRoutablePrefix;
-  Name m_chatPrefix;
-  Name m_localChatPrefix;
-  std::string m_nick;
-  DigestTreeScene *m_scene;
-  TrustTreeScene *m_trustScene;
-  QStringListModel *m_rosterModel;
-  QTimer* m_timer;
+  QString m_nick;
+  bool m_isSecured;
 
 
-  int64_t m_lastMsgTime;
-  int m_randomizedInterval;
-  bool m_joined;
-
-  Sync::SyncSocket *m_sock;
-  uint64_t m_session;
-  shared_ptr<ndn::SecRuleRelative> m_dataRule;
-
-  InviteListDialog* m_inviteListDialog;
-  shared_ptr<ValidatorInvitation> m_invitationValidator;
-
-  boost::recursive_mutex m_msgMutex;
-  boost::recursive_mutex m_sceneMutex;
-  QList<QString> m_zombieList;
-  int m_zombieIndex;
-
-  //ymj
-  ChatroomInfo::TrustModel m_trustModel;
+  DigestTreeScene* m_scene;
+  TrustTreeScene* m_trustScene;
+  QStringListModel* m_rosterModel;
 };
 
 } // namespace chronos
diff --git a/src/controller.cpp b/src/controller.cpp
index d99b7a6..b52c188 100644
--- a/src/controller.cpp
+++ b/src/controller.cpp
@@ -19,6 +19,7 @@
 #include <boost/filesystem.hpp>
 #include <boost/lexical_cast.hpp>
 #include <ndn-cxx/util/random.hpp>
+#include "invitation.hpp"
 #include "cryptopp.hpp"
 #include "config.pb.h"
 #include "endorse-info.pb.h"
@@ -547,9 +548,9 @@
   connect(chatDialog, SIGNAL(rosterChanged(const chronos::ChatroomInfo&)),
           this, SLOT(onRosterChanged(const chronos::ChatroomInfo&)));
   connect(this, SIGNAL(localPrefixUpdated(const QString&)),
-          chatDialog, SLOT(onLocalPrefixUpdated(const QString&)));
+          chatDialog->getBackend(), SLOT(updateRoutingPrefix(const QString&)));
   connect(this, SIGNAL(localPrefixConfigured(const QString&)),
-          chatDialog, SLOT(onLocalPrefixUpdated(const QString&)));
+          chatDialog->getBackend(), SLOT(updateRoutingPrefix(const QString&)));
 
   QAction* chatAction = new QAction(chatroomName, this);
   m_chatActionList[chatroomName.toStdString()] = chatAction;
@@ -558,7 +559,8 @@
 
   QAction* closeAction = new QAction(chatroomName, this);
   m_closeActionList[chatroomName.toStdString()] = closeAction;
-  connect(closeAction, SIGNAL(triggered()), chatDialog, SLOT(onClose()));
+  connect(closeAction, SIGNAL(triggered()),
+          chatDialog, SLOT(shutdown()));
 
   updateMenu();
 }
@@ -734,7 +736,7 @@
 {
   while (!m_chatDialogList.empty()) {
     ChatDialogList::const_iterator it = m_chatDialogList.begin();
-    onRemoveChatDialog(QString::fromStdString(it->first));
+    it->second->shutdown();
   }
 
   if (m_invitationListenerId != 0)
@@ -775,9 +777,16 @@
   // std::cout << "start chat room localprefix: " << m_localPrefix.toUri() << std::endl;
   shared_ptr<IdentityCertificate> idCert
     = m_keyChain.getCertificate(m_keyChain.getDefaultCertificateNameForIdentity(m_identity));
+
+  Name chatPrefix;
+  chatPrefix.append(m_identity).append("CHRONOCHAT-DATA").append(chatroomName.toStdString());
+
   ChatDialog* chatDialog
-    = new ChatDialog(&m_contactManager, m_face, *idCert, chatroomPrefix
-                     , m_localPrefix, m_nick, secured);
+    = new ChatDialog(chatroomPrefix,
+                     chatPrefix,
+                     m_localPrefix,
+                     chatroomName.toStdString(),
+                     m_nick);
 
   addChatDialog(chatroomName, chatDialog);
   chatDialog->show();
@@ -845,9 +854,18 @@
     //but let's use the default one for now.
     shared_ptr<IdentityCertificate> idCert
       = m_keyChain.getCertificate(m_keyChain.getDefaultCertificateNameForIdentity(m_identity));
+
+    Name chatPrefix;
+    chatPrefix.append(m_identity).append("CHRONOCHAT-DATA").append(invitation.getChatroom());
+
     ChatDialog* chatDialog
-      = new ChatDialog(&m_contactManager, m_face, *idCert,
-                       chatroomPrefix, m_localPrefix, m_nick, true);
+      = new ChatDialog(chatroomPrefix,
+                       chatPrefix,
+                       m_localPrefix,
+                       invitation.getChatroom(),
+                       m_nick,
+                       true);
+
     chatDialog->addSyncAnchor(invitation);
 
     addChatDialog(QString::fromStdString(invitation.getChatroom()), chatDialog);
diff --git a/src/digest-tree-scene.cpp b/src/digest-tree-scene.cpp
index 07e5dea..e7adba9 100644
--- a/src/digest-tree-scene.cpp
+++ b/src/digest-tree-scene.cpp
@@ -24,55 +24,52 @@
 namespace chronos {
 
 static const double Pi = 3.14159265358979323846264338327950288419717;
+static const int NODE_SIZE = 40;
 
 //DisplayUserPtr DisplayUserNullPtr;
 
 DigestTreeScene::DigestTreeScene(QWidget *parent)
   : QGraphicsScene(parent)
 {
-  previouslyUpdatedUser = DisplayUserNullPtr;
+  m_previouslyUpdatedUser = DisplayUserNullPtr;
 }
 
 void
-DigestTreeScene::processUpdate(const std::vector<Sync::MissingDataInfo> &v, QString digest)
+DigestTreeScene::processSyncUpdate(const std::vector<chronos::NodeInfo>& nodeInfos,
+                                   const QString& digest)
 {
-  int n = v.size();
-  bool rePlot = false;
-  for (int i = 0; i < n; i++) {
-    QString routablePrefix(v[i].prefix.c_str());
-    QString prefix = trimRoutablePrefix(routablePrefix);
+  m_rootDigest = digest;
 
-    Roster_iterator it = m_roster.find(prefix);
+  bool rePlot = false;
+
+  // Update roster info
+  for (int i = 0; i < nodeInfos.size(); i++) {
+    Roster_iterator it = m_roster.find(nodeInfos[i].sessionPrefix);
     if (it == m_roster.end()) {
-      // std::cout << "processUpdate v[" << i << "]: " << prefix.toStdString() << std::endl;
       rePlot = true;
+
       DisplayUserPtr p(new DisplayUser());
-      time_t tempTime = ::time(0) + 1;
-      p->setReceived(tempTime);
-      p->setPrefix(prefix);
-      p->setSeq(v[i].high);
+      p->setPrefix(nodeInfos[i].sessionPrefix);
+      p->setSeq(nodeInfos[i].seqNo);
       m_roster.insert(p->getPrefix(), p);
     }
     else {
-      it.value()->setSeq(v[i].high);
+      it.value()->setSeq(nodeInfos[i].seqNo);
     }
   }
 
-  if (rePlot) {
-    plot(digest);
-    QTimer::singleShot(2100, this, SLOT(emitReplot()));
-  }
+  if (rePlot)
+    // If new nodes exist, we need to re-arrange node
+    plot(m_rootDigest);
   else {
-    for (int i = 0; i < n; i++) {
-      QString routablePrefix(v[i].prefix.c_str());
-      QString prefix = trimRoutablePrefix(routablePrefix);
-
-      Roster_iterator it = m_roster.find(prefix);
+    // No new node, update seqNo & digest
+    for (int i = 0; i < nodeInfos.size(); i++) {
+      Roster_iterator it = m_roster.find(nodeInfos[i].sessionPrefix);
       if (it != m_roster.end()) {
         DisplayUserPtr p = it.value();
         QGraphicsTextItem *item = p->getSeqTextItem();
         QGraphicsRectItem *rectItem = p->getInnerRectItem();
-        std::string s = boost::lexical_cast<std::string>(p->getSeqNo().getSeq());
+        std::string s = boost::lexical_cast<std::string>(p->getSeqNo());
         item->setPlainText(s.c_str());
         QRectF textBR = item->boundingRect();
         QRectF rectBR = rectItem->boundingRect();
@@ -80,14 +77,57 @@
                      rectBR.y() + (rectBR.height() - textBR.height())/2);
       }
     }
-    m_rootDigest->setPlainText(digest);
+    m_displayRootDigest->setPlainText(digest);
   }
 }
 
 void
-DigestTreeScene::emitReplot()
+DigestTreeScene::updateNick(QString sessionPrefix, QString nick)
 {
-  emit replot();
+  Roster_iterator it = m_roster.find(sessionPrefix);
+  if (it != m_roster.end()) {
+    DisplayUserPtr p = it.value();
+    if (nick != p->getNick()) {
+      p->setNick(nick);
+      QGraphicsTextItem *nickItem = p->getNickTextItem();
+      QGraphicsRectItem *nickRectItem = p->getNickRectItem();
+      nickItem->setPlainText(p->getNick());
+      QRectF rectBR = nickRectItem->boundingRect();
+      QRectF nickBR = nickItem->boundingRect();
+      nickItem->setPos(rectBR.x() + (rectBR.width() - nickBR.width())/2, rectBR.y() + 5);
+    }
+  }
+}
+
+void
+DigestTreeScene::messageReceived(QString sessionPrefix)
+{
+  Roster_iterator it = m_roster.find(sessionPrefix);
+  if (it != m_roster.end()) {
+    DisplayUserPtr p = it.value();
+
+    reDrawNode(p, Qt::red);
+
+    if (m_previouslyUpdatedUser != DisplayUserNullPtr && m_previouslyUpdatedUser != p) {
+      reDrawNode(m_previouslyUpdatedUser, Qt::darkBlue);
+    }
+
+    m_previouslyUpdatedUser = p;
+  }
+}
+
+void
+DigestTreeScene::clearAll()
+{
+  clear();
+  m_roster.clear();
+}
+
+void
+DigestTreeScene::removeNode(const QString sessionPrefix)
+{
+  m_roster.remove(sessionPrefix);
+  plot(m_rootDigest);
 }
 
 QStringList
@@ -105,117 +145,36 @@
   return rosterList;
 }
 
-void
-DigestTreeScene::msgReceived(QString routablePrefix, QString nick)
+QStringList
+DigestTreeScene::getRosterPrefixList()
 {
-  QString prefix = trimRoutablePrefix(routablePrefix);
-  Roster_iterator it = m_roster.find(prefix);
-  // std::cout << "msgReceived prefix: " << prefix.toStdString() << std::endl;
-  if (it != m_roster.end()) {
-    // std::cout << "Updating for prefix = " << prefix.toStdString() <<
-    // " nick = " << nick.toStdString() << std::endl;
-    DisplayUserPtr p = it.value();
-    p->setReceived(::time(0) + 1);
-    if (nick != p->getNick()) {
-      // std::cout << "old nick = " << p->getNick().toStdString() << std::endl;
-      p->setNick(nick);
-      QGraphicsTextItem *nickItem = p->getNickTextItem();
-      QGraphicsRectItem *nickRectItem = p->getNickRectItem();
-      nickItem->setPlainText(p->getNick());
-      QRectF rectBR = nickRectItem->boundingRect();
-      QRectF nickBR = nickItem->boundingRect();
-      nickItem->setPos(rectBR.x() + (rectBR.width() - nickBR.width())/2, rectBR.y() + 5);
-      emit rosterChanged(QStringList());
-    }
-
-    reDrawNode(p, Qt::red);
-
-    if (previouslyUpdatedUser != DisplayUserNullPtr && previouslyUpdatedUser != p) {
-      reDrawNode(previouslyUpdatedUser, Qt::darkBlue);
-    }
-
-    previouslyUpdatedUser = p;
-  }
-}
-
-void
-DigestTreeScene::clearAll()
-{
-  clear();
-  m_roster.clear();
-}
-
-bool
-DigestTreeScene::removeNode(const QString prefix)
-{
-  int removedCount = m_roster.remove(prefix);
-  return (removedCount > 0);
-}
-
-void
-DigestTreeScene::plot(QString digest)
-{
-#ifdef _DEBUG
-  std::cout << "Plotting at time: " << ::time(NULL) << std::endl;
-#endif
-  clear();
-
-  int nodeSize = 40;
-
-  int siblingDistance = 100, levelDistance = 100;
-  std::auto_ptr<TreeLayout> layout(new OneLevelTreeLayout());
-  layout->setSiblingDistance(siblingDistance);
-  layout->setLevelDistance(levelDistance);
-
-  // do some cleaning, get rid of stale member info
-  Roster_iterator it = m_roster.begin();
-  QStringList staleUserList;
-  while (it != m_roster.end()) {
+  QStringList prefixList;
+  RosterIterator it(m_roster);
+  while (it.hasNext()) {
+    it.next();
     DisplayUserPtr p = it.value();
     if (p != DisplayUserNullPtr) {
-      time_t now = ::time(NULL);
-      if (now - p->getReceived() >= FRESHNESS) {
-#ifdef _DEBUG
-        std::cout << "Removing user: " << p->getNick().toStdString() << std::endl;
-        std::cout << "now - last = " << now - p->getReceived() << std::endl;
-#endif
-        staleUserList << p->getNick();
-        p = DisplayUserNullPtr;
-        it = m_roster.erase(it);
-      }
-      else {
-        if (!m_currentPrefix.startsWith("/private/local") &&
-            p->getPrefix().startsWith("/private/local")) {
-#ifdef _DEBUG
-          std::cout << "erasing: " << p->getPrefix().toStdString() << std::endl;
-#endif
-          staleUserList << p->getNick();
-          p = DisplayUserNullPtr;
-          it = m_roster.erase(it);
-          continue;
-        }
-        ++it;
-      }
-    }
-    else {
-      it = m_roster.erase(it);
+      prefixList << "- " + p->getPrefix();
     }
   }
+  return prefixList;
+}
 
-  // for simpicity here, whenever we replot, we also redo the roster list
-  emit rosterChanged(staleUserList);
+void
+DigestTreeScene::plot(QString rootDigest)
+{
+  clear();
 
-  int n = m_roster.size();
+  shared_ptr<TreeLayout> layout(new OneLevelTreeLayout());
+  layout->setSiblingDistance(100);
+  layout->setLevelDistance(100);
 
-  std::vector<TreeLayout::Coordinate> childNodesCo(n);
-
+  std::vector<TreeLayout::Coordinate> childNodesCo(m_roster.size());
   layout->setOneLevelLayout(childNodesCo);
+  plotEdge(childNodesCo, NODE_SIZE);
+  plotNode(childNodesCo, rootDigest, NODE_SIZE);
 
-  plotEdge(childNodesCo, nodeSize);
-  plotNode(childNodesCo, digest, nodeSize);
-
-  previouslyUpdatedUser = DisplayUserNullPtr;
-
+  m_previouslyUpdatedUser = DisplayUserNullPtr;
 }
 
 void
@@ -266,7 +225,7 @@
   digestItem->setFont(QFont("Cursive", 12, QFont::Bold));
   digestItem->setPos(- 4.5 * nodeSize + (12 * nodeSize - digestBoundingRect.width()) / 2,
                      - nodeSize + 5);
-  m_rootDigest = digestItem;
+  m_displayRootDigest = digestItem;
 
   // plot child nodes
   for (int i = 0; i < n; i++) {
@@ -288,7 +247,7 @@
                                                QBrush(Qt::lightGray));
     p->setInnerRectItem(innerRectItem);
 
-    std::string s = boost::lexical_cast<std::string>(p->getSeqNo().getSeq());
+    std::string s = boost::lexical_cast<std::string>(p->getSeqNo());
     QGraphicsTextItem *seqItem = addText(s.c_str());
     seqItem->setFont(QFont("Cursive", 12, QFont::Bold));
     QRectF seqBoundingRect = seqItem->boundingRect();
@@ -317,7 +276,7 @@
     QGraphicsRectItem *innerItem = p->getInnerRectItem();
     innerItem->setBrush(QBrush(Qt::lightGray));
     QGraphicsTextItem *seqTextItem = p->getSeqTextItem();
-    std::string s = boost::lexical_cast<std::string>(p->getSeqNo().getSeq());
+    std::string s = boost::lexical_cast<std::string>(p->getSeqNo());
     seqTextItem->setPlainText(s.c_str());
     QRectF textBR = seqTextItem->boundingRect();
     QRectF innerBR = innerItem->boundingRect();
@@ -325,26 +284,6 @@
                         innerBR.y() + (innerBR.height() - textBR.height())/2);
 }
 
-QString
-DigestTreeScene::trimRoutablePrefix(QString prefix)
-{
-  bool encaped = false;
-  ndn::Name prefixName(prefix.toStdString());
-
-  size_t offset = 0;
-  for (ndn::Name::const_iterator it  = prefixName.begin(); it != prefixName.end(); it++, offset++) {
-    if (it->toUri() == "%F0.") {
-      encaped = true;
-      break;
-    }
-  }
-
-  if (!encaped)
-    return prefix;
-  else
-    return QString(prefixName.getSubName(offset+1).toUri().c_str());
-}
-
 } // namespace chronos
 
 #if WAF
diff --git a/src/digest-tree-scene.hpp b/src/digest-tree-scene.hpp
index 138f7f4..51847dc 100644
--- a/src/digest-tree-scene.hpp
+++ b/src/digest-tree-scene.hpp
@@ -18,8 +18,8 @@
 
 #ifndef Q_MOC_RUN
 #include "tree-layout.hpp"
-#include <sync-seq-no.h>
-#include <sync-logic.h>
+#include "chat-dialog-backend.hpp"
+#include <Leaf.hpp>
 #include <ctime>
 #include <vector>
 #include <boost/shared_ptr.hpp>
@@ -49,44 +49,29 @@
   DigestTreeScene(QWidget *parent = 0);
 
   void
-  processUpdate(const std::vector<Sync::MissingDataInfo>& v, QString digest);
+  processSyncUpdate(const std::vector<chronos::NodeInfo>& nodeInfos,
+                    const QString& digest);
 
   void
-  msgReceived(QString prefix, QString nick);
+  updateNick(QString sessionPrefix, QString nick);
+
+  void
+  messageReceived(QString sessionPrefix);
 
   void
   clearAll();
 
-  bool
-  removeNode(const QString prefix);
-
   void
-  plot(QString digest);
+  removeNode(const QString sessionPrefix);
 
   QStringList
   getRosterList();
 
-  void
-  setCurrentPrefix(QString prefix)
-  {
-    m_currentPrefix = prefix;
-  }
-
-  QMap<QString, DisplayUserPtr> getRosterFull()
-  {
-    return m_roster;
-  }
-
-signals:
-  void
-  replot();
+  QStringList
+  getRosterPrefixList();
 
   void
-  rosterChanged(QStringList);
-
-private slots:
-  void
-  emitReplot();
+  plot(QString rootDigest);
 
 private:
   void
@@ -98,29 +83,25 @@
   void
   reDrawNode(DisplayUserPtr p, QColor rimColor);
 
-  QString
-  trimRoutablePrefix(QString prefix);
-
 private:
   Roster m_roster;
-  QGraphicsTextItem* m_rootDigest;
-  DisplayUserPtr previouslyUpdatedUser;
-  QString m_currentPrefix;
+
+  QString m_rootDigest;
+  QGraphicsTextItem* m_displayRootDigest;
+
+  DisplayUserPtr m_previouslyUpdatedUser;
 };
 
 class User
 {
 public:
   User()
-    :m_received(::time(NULL))
   {
   }
 
-  User(QString n, QString p, QString c)
+  User(QString n, QString p)
     : m_nick(n)
     , m_prefix(p)
-    , m_chatroom(c)
-    , m_received(::time(NULL))
   {
   }
 
@@ -137,29 +118,11 @@
   }
 
   void
-  setChatroom(QString chatroom)
-  {
-    m_chatroom = chatroom;
-  }
-
-  void
-  setSeq(Sync::SeqNo seq)
+  setSeq(chronosync::SeqNo seq)
   {
     m_seq = seq;
   }
 
-  void
-  setReceived(time_t t)
-  {
-    m_received = t;
-  }
-
-  void
-  setOriginPrefix(QString originPrefix)
-  {
-    m_originPrefix = originPrefix;
-  }
-
   QString
   getNick()
   {
@@ -171,34 +134,16 @@
     return m_prefix;
   }
 
-  QString getChatroom()
-  {
-    return m_chatroom;
-  }
-
-  QString getOriginPrefix()
-  {
-    return m_originPrefix;
-  }
-
-  Sync::SeqNo
+  chronosync::SeqNo
   getSeqNo()
   {
     return m_seq;
   }
 
-  time_t getReceived()
-  {
-    return m_received;
-  }
-
 private:
   QString m_nick;
   QString m_prefix;
-  QString m_chatroom;
-  QString m_originPrefix;
-  Sync::SeqNo m_seq;
-  time_t m_received;
+  chronosync::SeqNo m_seq;
 };
 
 class DisplayUser : public User
@@ -211,8 +156,8 @@
   {
   }
 
-  DisplayUser(QString n, QString p , QString c)
-    : User(n, p, c)
+  DisplayUser(QString n, QString p)
+    : User(n, p)
     , m_seqTextItem(NULL)
     , m_nickTextItem(NULL)
     , m_rimRectItem(NULL)
