diff --git a/src/chatdialog.cpp b/src/chatdialog.cpp
index 43d4860..1c3e37e 100644
--- a/src/chatdialog.cpp
+++ b/src/chatdialog.cpp
@@ -1,1144 +1,39 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
 /*
  * Copyright (c) 2013, Regents of the University of California
- *                     Alexander Afanasyev
- *                     Zhenkai Zhu
+ *                     Yingdi Yu
  *
- * GNU v3.0 license, See the LICENSE file for more information
+ * BSD license, See the LICENSE file for more information
  *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
  */
 
 #include "chatdialog.h"
+#include "ui_chatdialog.h"
 
-#include "settingdialog.h"
+using namespace std;
+using namespace ndn;
 
-#include <QtGui>
-#include <QTimer>
-#include <QMetaType>
-#include <QMessageBox>
-
-#ifndef Q_MOC_RUN
-#include <ctime>
-#include <iostream>
-
-#include <boost/random/random_device.hpp>
-#include <boost/random/uniform_int_distribution.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/make_shared.hpp>
-
-#include <stdio.h>
-#endif
-
-#define BROADCAST_PREFIX_FOR_SYNC_DEMO "/ndn/broadcast/ChronoChat-0.3"
-#define LOCAL_PREFIX_QUERY "/local/ndn/prefix"
-#define DEFAULT_LOCAL_PREFIX "/private/local"
-// #define CCN_EXEC  "/usr/local/bin/ccnpeek"
-
-static const int HELLO_INTERVAL = FRESHNESS * 3 / 4;  // seconds
-
-ChatDialog::ChatDialog(QWidget *parent)
-  : QDialog(parent)
-  , m_sock(NULL)
-  , m_lastMsgTime(0)
-  , m_historyInitialized(false)
-  , m_joined(false)
+ChatDialog::ChatDialog(const Name& chatroomPrefix,
+		       const Name& localPrefix,
+		       QWidget *parent) 
+    : QDialog(parent)
+    , m_chatroomPrefix(chatroomPrefix)
+    , m_localPrefix(localPrefix)
+    , ui(new Ui::ChatDialog)
 {
-  // have to register this, otherwise
-  // the signal-slot system won't recognize this type
-  qRegisterMetaType<std::vector<Sync::MissingDataInfo> >("std::vector<Sync::MissingDataInfo>");
-  qRegisterMetaType<size_t>("size_t");
-
-  setupUi (this);
-
-  m_session = time(NULL);
-  m_scene = new DigestTreeScene(this);
-
-  readSettings();
-
-  updateLabels();
-
-  lineEdit->setFocusPolicy(Qt::StrongFocus);
-
-  treeViewer->setScene(m_scene);
-  treeViewer->hide ();
-  m_scene->plot("Empty");
-  QRectF rect = m_scene->itemsBoundingRect();
-  m_scene->setSceneRect(rect);
-
-  // listView->setStyleSheet("QListView { alternate-background-color: white; background: #F0F0F0; color: darkGreen; font: bold large; }");
-  // listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
-  // listView->setDragDropMode(QAbstractItemView::NoDragDrop);
-  // listView->setSelectionMode(QAbstractItemView::NoSelection);
-
-  m_rosterModel = new QStringListModel(this);
-  listView->setModel(m_rosterModel);
-
-  // refreshButton->setIcon(QIcon(QPixmap(":images/refresh.png")));
-  // reapButton->hide();
-
-  createActions();
-  createTrayIcon();
-  m_timer = new QTimer(this);
-  connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
-  // connect(setButton, SIGNAL(pressed()), this, SLOT(buttonPressed()));
-  connect(treeButton, SIGNAL(pressed()), this, SLOT(treeButtonPressed()));
-  // connect(reapButton, SIGNAL(pressed()), this, SLOT(summonReaper()));
-  // connect(refreshButton, SIGNAL(pressed()), this, SLOT(updateLocalPrefix()));
-
-  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()));
-  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)));
-
-  initializeSync();
-}
-
-void
-ChatDialog::initializeSync()
-{
-  // create sync socket
-  if(!m_user.getChatroom().isEmpty() && !m_user.getNick().isEmpty()) {
-    std::string syncPrefix = BROADCAST_PREFIX_FOR_SYNC_DEMO;
-    syncPrefix += "/";
-    syncPrefix += m_user.getChatroom().toStdString();
-    try
-    {
-      m_sock = new Sync::SyncAppSocket(syncPrefix,
-                                       bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
-                                       bind(&ChatDialog::processRemoveWrapper, this, _1));
-      //QTimer::singleShot(100, this, SLOT(getLocalPrefix()));
-      usleep(100000);
-      if (!getLocalPrefix())
-      {
-        // if getLocalPrefix indicates no prefix change
-        // this sock is going to be used
-        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));
-      }
-      else
-      {
-        // this socket is going to be destroyed anyway
-        // why bother doing the following steps
-
-        // the same steps would be performed for another socket
-        // in settingUpdated
-      }
-    }
-    catch (Sync::CcnxOperationException ex)
-    {
-      QMessageBox::critical(this, tr("Chronos"), tr("Canno connect to ccnd.\n Have you started your ccnd?"), QMessageBox::Ok);
-      std::exit(1);
-    }
-  }
+    ui->setupUi(this);
 }
 
 ChatDialog::~ChatDialog()
 {
-  if (m_sock != NULL)
-  {
-    sendLeave();
-    delete m_sock;
-    m_sock = NULL;
-  }
+    delete ui;
 }
 
 void
-ChatDialog::sendLeave()
+ChatDialog::sendInvitation()
 {
-  SyncDemo::ChatMessage msg;
-  formControlMessage(msg, SyncDemo::ChatMessage::LEAVE);
-  sendMsg(msg);
-  usleep(500000);
-  m_sock->remove(m_user.getPrefix().toStdString());
-  usleep(5000);
-  m_joined = false;
-#ifdef __DEBUG
-  std::cout << "Sync REMOVE signal sent" << std::endl;
-#endif
-}
-
-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 ();
-  std::map<std::string, bool> branches = logic.getBranchPrefixes();
-  QMap<QString, DisplayUserPtr> roster = m_scene->getRosterFull();
-
-  m_zombieList.clear();
-
-  QMapIterator<QString, DisplayUserPtr> it(roster);
-  std::map<std::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())
-  {
-    std::string prefix = m_zombieList.at(m_zombieIndex).toStdString();
-    m_sock->remove(prefix);
-    std::cout << "Reaped: prefix = " << prefix << std::endl;
-    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::setVisible(bool visible)
-{
-  minimizeAction->setEnabled(visible);
-  maximizeAction->setEnabled(!isMaximized());
-  // restoreAction->setEnabled(isMaximized() || !visible);
-
-  raise();  // for MacOS
-  activateWindow(); // for Windows
-
-  QDialog::setVisible(visible);
-}
-
-void
-ChatDialog::closeEvent(QCloseEvent *e)
-{
-  if (trayIcon->isVisible() && !m_minimaniho)
-  {
-    QMessageBox::information(this, tr("Chronos"),
-			     tr("The program will keep running in the "
-				"system tray. To terminate the program"
-				"choose <b>Quit</b> in the context memu"
-				"of the system tray entry."));
-    hide();
-    e->ignore();
-    m_minimaniho = true;
-    writeSettings();
-  }
-}
-
-void
-ChatDialog::changeEvent(QEvent *e)
-{
-  switch(e->type())
-  {
-  case QEvent::ActivationChange:
-    if (isActiveWindow())
-    {
-      trayIcon->setIcon(QIcon(":/images/icon_small.png"));
-    }
-    break;
-  default:
-    break;
-  }
-}
-
-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(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(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(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 = textEdit->verticalScrollBar();
-  bar->setValue(bar->maximum());
-}
-
-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));
-}
-
-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::processTreeUpdateWrapper(const std::vector<Sync::MissingDataInfo> v, Sync::SyncAppSocket *sock)
-{
-  emit treeUpdated(v);
-#ifdef __DEBUG
-  std::cout << "<<< Tree update signal emitted" << std::endl;
-#endif
-}
-
-void
-ChatDialog::processTreeUpdate(const std::vector<Sync::MissingDataInfo> v)
-{
-#ifdef __DEBUG
-  std::cout << "<<< processing Tree Update" << std::endl;
-#endif
-  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->fetchRaw(v[i].prefix, seq, bind(&ChatDialog::processDataWrapper, this, _1, _2, _3), 2);
-#ifdef __DEBUG
-        std::cout << "<<< Fetching " << v[i].prefix << "/" <<seq.getSession() <<"/" << seq.getSeq() << std::endl;
-#endif
-      }
-    }
-    else
-    {
-        m_sock->fetchRaw(v[i].prefix, v[i].high, bind(&ChatDialog::processDataNoShowWrapper, this, _1, _2, _3), 2);
-    }
-  }
-
-  // adjust the view
-  fitView();
-
-}
-
-void
-ChatDialog::processDataWrapper(std::string name, const char *buf, size_t len)
-{
-  char *tempBuf = new char[len];
-  memcpy(tempBuf, buf, len);
-  emit dataReceived(name.c_str(), tempBuf, len, true, false);
-#ifdef __DEBUG
-  std::cout <<"<<< " << name << " fetched" << std::endl;
-#endif
-}
-
-void
-ChatDialog::processDataNoShowWrapper(std::string name, const char *buf, size_t len)
-{
-  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::processDataHistoryWrapper(std::string name, const char *buf, size_t len)
-{
-  char *tempBuf = new char[len];
-  memcpy(tempBuf, buf, len);
-  emit dataReceived(name.c_str(), tempBuf, len, true, true);
-}
-
-void
-ChatDialog::fetchHistory(std::string name)
-{
-  std::string nameWithoutSeq = name.substr(0, name.find_last_of('/'));
-  std::string prefix = nameWithoutSeq.substr(0, nameWithoutSeq.find_last_of('/'));
-  prefix += "/history";
-  Sync::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::respondHistoryRequest(std::string interest)
-{
-  std::string seqStr = interest.substr(interest.find_last_of('/') + 1);
-  int seq = boost::lexical_cast<int>(seqStr);
-  if (seq >= 0 && seq < m_history.size())
-  {
-    Sync::CcnxWrapperPtr handle = boost::make_shared<Sync::CcnxWrapper> ();
-    SyncDemo::ChatMessage msg = m_history.at(seq);
-    size_t size = msg.ByteSize();
-    char *buf = new char[size];
-    msg.SerializeToArray(buf, size);
-    handle->publishRawData(interest, buf, size, 1);
-    delete buf;
-  }
-}
-
-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))
-  {
-    std::cerr << "Errrrr.. Can not parse msg with name: " << name.toStdString() << ". what is happening?" << std::endl;
-    // 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('/'));
-#ifdef __DEBUG
-    std::cout <<"<<< updating scene for" << prefix << ": " << msg.from()  << std::endl;
-#endif
-    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::processRemoveWrapper(std::string prefix)
-{
-#ifdef __DEBUG
-  std::cout << "Sync REMOVE signal received for prefix: " << prefix << std::endl;
-#endif
-  //emit removeReceived(prefix.c_str());
-}
-
-void
-ChatDialog::processRemove(QString prefix)
-{
-#ifdef __DEBUG
-  std::cout << "<<< remove node for prefix" << prefix.toStdString() << std::endl;
-#endif
-  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::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);
-}
-
-static std::string chars("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789");
-
-QString
-ChatDialog::getRandomString()
-{
-  std::string randStr;
-  boost::random::random_device rng;
-  boost::random::uniform_int_distribution<> index_dist(0, chars.size() - 1);
-  for (int i = 0; i < 10; i ++)
-  {
-    randStr += chars[index_dist(rng)];
-  }
-  return randStr.c_str();
-}
-
-bool
-ChatDialog::getLocalPrefix()
-{
-//   /*
-//    * this method tries to use ccncat
-//    * however, it does not work in Mac OS X app bundle
-//    * it works well in command line though
-//    */
-
-//   std::string cmd = CCN_EXEC;
-//   cmd += " -c -v ";
-//   cmd += LOCAL_PREFIX_QUERY;
-//   QString localPrefix;
-// #define MAX_PREFIX_LEN 100
-//   FILE *fp = popen(cmd.c_str(), "r");
-//   if (fp != NULL)
-//   {
-//     char prefix[MAX_PREFIX_LEN];
-//     if (fgets(prefix, MAX_PREFIX_LEN, fp) != NULL)
-//     {
-//       localPrefix = prefix;
-//       localPrefix.remove('\n');
-//     }
-//     else
-//     {
-//       localPrefix = DEFAULT_LOCAL_PREFIX;
-//     }
-//     pclose(fp);
-//   }
-//   else
-//   {
-//     localPrefix = DEFAULT_LOCAL_PREFIX;
-//   }
-//   return localPrefix;
-  std::cerr << "trying to get local prefix" << std::endl;
-
-  if (m_sock != NULL)
-  {
-    QString originPrefix = QString::fromStdString (m_sock->GetLocalPrefix()).trimmed ();
-    std::cerr << "got: " << originPrefix.toStdString () << std::endl;
-
-    if (originPrefix != "" && m_user.getOriginPrefix () != originPrefix)
-    {
-      emit settingUpdated(m_user.getNick (), m_user.getChatroom (), originPrefix);
-      // prefix updated
-      return true;
-    }
-  }
-
-  // prefix not changed
-  return false;
-}
-
-void
-ChatDialog::updateLocalPrefix()
-{
-  getLocalPrefix();
-}
-
-bool
-ChatDialog::readSettings()
-{
-  QSettings settings (QSettings::NativeFormat, QSettings::UserScope, ORGANIZATION, APPLICATION);
-
-  QString nick = settings.value("nick", "").toString();
-  QString chatroom = settings.value("chatroom", "").toString();
-  // QString originPrefix = settings.value("originPrefix", "").toString();
-
-  // Sync::CcnxWrapperPtr wrapper = Sync::CcnxWrapper::Create ();
-  // QString originPrefix = QString::fromStdString (wrapper->getLocalPrefix());
-  // Sync::CcnxWrapper::Destroy ();
-
-  QString originPrefix = DEFAULT_LOCAL_PREFIX;
-
-  m_minimaniho = settings.value("minimaniho", false).toBool();
-  if (nick == "" || chatroom == "" || originPrefix == "") {
-    m_user.setOriginPrefix(DEFAULT_LOCAL_PREFIX);
-    m_user.setChatroom("clue");
-    QTimer::singleShot(500, this, SLOT(buttonPressed()));
-    return false;
-  }
-  else {
-    m_user.setNick(nick);
-    m_user.setChatroom(chatroom);
-    m_user.setOriginPrefix(originPrefix);
-    m_user.setPrefix(originPrefix + "/" + chatroom + "/" + getRandomString());
-    m_scene->setCurrentPrefix(originPrefix + "/" + chatroom + "/" + getRandomString());
-    return true;
-  }
-
-//  QTimer::singleShot(500, this, SLOT(buttonPressed()));
- // return false;
-}
-
-void
-ChatDialog::writeSettings()
-{
-  QSettings settings (QSettings::NativeFormat, QSettings::UserScope, ORGANIZATION, APPLICATION);
-
-  settings.setValue("nick", m_user.getNick());
-  settings.setValue("chatroom", m_user.getChatroom());
-  //settings.setValue("originPrefix", m_user.getOriginPrefix());
-  settings.setValue("minimaniho", m_minimaniho);
-}
-
-void
-ChatDialog::updateLabels()
-{
-  QString settingDisp = QString("Chatroom: %1").arg(m_user.getChatroom());
-  infoLabel->setStyleSheet("QLabel {color: #630; font-size: 16px; font: bold \"Verdana\";}");
-  infoLabel->setText(settingDisp);
-  QString prefixDisp;
-  if (m_user.getPrefix().startsWith(DEFAULT_LOCAL_PREFIX))
-  {
-    prefixDisp = QString("<Warning: no connection to hub or hub does not support prefix autoconfig.>\n <Prefix = %1>").arg(m_user.getPrefix());
-    prefixLabel->setStyleSheet("QLabel {color: red; font-size: 12px; font: bold \"Verdana\";}");
-  }
-  else
-  {
-    prefixDisp = QString("<Prefix = %1>").arg(m_user.getPrefix());
-    prefixLabel->setStyleSheet("QLabel {color: Green; font-size: 12px; font: bold \"Verdana\";}");
-  }
-  prefixLabel->setText(prefixDisp);
-}
-
-void
-ChatDialog::returnPressed()
-{
-  QString text = lineEdit->text();
-  if (text.isEmpty())
-    return;
-
-  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::sendMsg(SyncDemo::ChatMessage &msg)
-{
-  // send msg
-  size_t size = msg.ByteSize();
-  char *buf = new char[size];
-  msg.SerializeToArray(buf, size);
-  if (!msg.IsInitialized())
-  {
-    std::cerr << "Errrrr.. msg was not probally initialized "<<__FILE__ <<":"<<__LINE__<<". what is happening?" << std::endl;
-    abort();
-  }
-  m_sock->publishRaw(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::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::buttonPressed()
-{
-  if (m_sock != NULL)
-  {
-    Sync::SyncLogic &logic = m_sock->getLogic ();
-    logic.printState ();
-  }
-
-  SettingDialog dialog(this, m_user.getNick(), m_user.getChatroom(), m_user.getOriginPrefix());
-  connect(&dialog, SIGNAL(updated(QString, QString, QString)), this, SLOT(settingUpdated(QString, QString, QString)));
-  dialog.exec();
-  QTimer::singleShot(100, this, SLOT(checkSetting()));
-}
-
-void ChatDialog::treeButtonPressed()
-{
-  if (treeViewer->isVisible())
-  {
-    treeViewer->hide();
-    treeButton->setText("Show ChronoSync Tree");
-  }
-  else
-  {
-    treeViewer->show();
-    treeButton->setText("Hide ChronoSync Tree");
-  }
-
-  fitView();
-}
-
-void ChatDialog::enableTreeDisplay()
-{
-  treeButton->setEnabled(true);
-  // treeViewer->show();
-  // fitView();
-}
-
-void ChatDialog::disableTreeDisplay()
-{
-  treeButton->setEnabled(false);
-  treeViewer->hide();
-  fitView();
-}
-
-void
-ChatDialog::checkSetting()
-{
-  if (m_user.getNick().isEmpty() || m_user.getChatroom().isEmpty() || m_user.getOriginPrefix().isEmpty())
-  {
-    buttonPressed();
-  }
-
-}
-
-void
-ChatDialog::settingUpdated(QString nick, QString chatroom, QString originPrefix)
-{
-  QString randString = getRandomString();
-  bool needWrite = false;
-  bool needFresh = false;
-  if (!nick.isEmpty() && nick != m_user.getNick()) {
-    m_user.setNick(nick);
-    needWrite = true;
-  }
-  QString oldPrefix = m_user.getPrefix();
-  if (!originPrefix.isEmpty() && originPrefix != m_user.getOriginPrefix()) {
-    m_user.setOriginPrefix(originPrefix);
-    m_user.setPrefix(originPrefix + "/" + m_user.getChatroom() + "/" + randString);
-    m_scene->setCurrentPrefix(originPrefix + "/" + m_user.getChatroom() + "/" + randString);
-    needWrite = true;
-    needFresh = true;
-  }
-  if (!chatroom.isEmpty() && chatroom != m_user.getChatroom()) {
-    m_user.setChatroom(chatroom);
-    m_user.setPrefix(m_user.getOriginPrefix() + "/" + chatroom + "/" + randString);
-    m_scene->setCurrentPrefix(m_user.getOriginPrefix() + "/" + chatroom + "/" + randString);
-    needWrite = true;
-    needFresh = true;
-  }
-
-  if (needWrite) {
-    writeSettings();
-    updateLabels();
-  }
-
-  if (needFresh && m_sock != NULL)
-  {
-
-    {
-      boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
-      m_scene->clearAll();
-      m_scene->plot("Empty");
-    }
-
-    textEdit->clear();
-
-    // keep the new prefix
-    QString newPrefix = m_user.getPrefix();
-    // send leave for the old
-    m_user.setPrefix(oldPrefix);
-    // there is no point to send leave if we haven't joined yet
-    if (m_joined)
-    {
-      sendLeave();
-    }
-    // resume new prefix
-    m_user.setPrefix(newPrefix);
-    // Sync::CcnxWrapperPtr handle = Sync::CcnxWrapper::Create();
-    // handle->clearInterestFilter(oldPrefix.toStdString());
-    m_history.clear();
-    m_historyInitialized = false;
-    delete m_sock;
-    m_sock = NULL;
-
-    std::string syncPrefix = BROADCAST_PREFIX_FOR_SYNC_DEMO;
-    syncPrefix += "/";
-    syncPrefix += m_user.getChatroom().toStdString();
-    try
-    {
-      usleep(100000);
-      m_sock = new Sync::SyncAppSocket(syncPrefix, bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2), bind(&ChatDialog::processRemoveWrapper, this, _1));
-      usleep(100000);
-      Sync::CcnxWrapperPtr handle = boost::make_shared<Sync::CcnxWrapper> ();
-      handle->setInterestFilter(m_user.getPrefix().toStdString(), bind(&ChatDialog::respondHistoryRequest, this, _1));
-      QTimer::singleShot(600, this, SLOT(sendJoin()));
-      m_timer->start(FRESHNESS * 1000);
-      disableTreeDisplay();
-      QTimer::singleShot(2200, this, SLOT(enableTreeDisplay()));
-    }
-    catch (Sync::CcnxOperationException ex)
-    {
-      QMessageBox::critical(this, tr("Chronos"), tr("Canno connect to ccnd.\n Have you started your ccnd?"), QMessageBox::Ok);
-      std::exit(1);
-    }
-
-
-  }
-  else if (needFresh && m_sock == NULL)
-  {
-    m_history.clear();
-    m_historyInitialized = false;
-    initializeSync();
-  }
-  else if (m_sock == NULL)
-  {
-    initializeSync();
-  }
-  else
-  {
-#ifdef __DEBUG
-    std::cout << "Just changing nicks, we're good. " << std::endl;
-#endif
-  }
-
-  fitView();
-}
-
-void
-ChatDialog::iconActivated(QSystemTrayIcon::ActivationReason reason)
-{
-  switch (reason)
-  {
-  case QSystemTrayIcon::Trigger:
-  case QSystemTrayIcon::DoubleClick:
-    break;
-  case QSystemTrayIcon::MiddleClick:
-    // showMessage();
-    break;
-  default:;
-  }
-}
-
-void
-ChatDialog::showMessage(QString from, QString data)
-{
-  //  std::cout <<"Showing Message: " << from.toStdString() << ": " << data.toStdString() << std::endl;
-  if (!isActiveWindow())
-  {
-    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::messageClicked()
-{
-  this->showMaximized();
-}
-
-void
-ChatDialog::createActions()
-{
-  minimizeAction = new QAction(tr("Mi&nimize"), this);
-  connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));
-
-  maximizeAction = new QAction(tr("Ma&ximize"), this);
-  connect(maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized()));
-
-  restoreAction = new QAction(tr("&Restore"), this);
-  connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));
-
-  settingsAction = new QAction(tr("Settings"), this);
-  connect (settingsAction, SIGNAL(triggered()), this, SLOT(buttonPressed()));
-
-  settingsAction->setMenuRole (QAction::PreferencesRole);
-
-  updateLocalPrefixAction = new QAction(tr("Update local prefix"), this);
-  connect (updateLocalPrefixAction, SIGNAL(triggered()), this, SLOT(updateLocalPrefix()));
-
-  quitAction = new QAction(tr("Quit"), this);
-  connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
-}
-
-void
-ChatDialog::createTrayIcon()
-{
-  trayIconMenu = new QMenu(this);
-  trayIconMenu->addAction(minimizeAction);
-  trayIconMenu->addAction(maximizeAction);
-  trayIconMenu->addAction(restoreAction);
-  trayIconMenu->addSeparator();
-  trayIconMenu->addAction(settingsAction);
-  trayIconMenu->addSeparator();
-  trayIconMenu->addAction(updateLocalPrefixAction);
-  trayIconMenu->addSeparator();
-  trayIconMenu->addAction(quitAction);
-
-  trayIcon = new QSystemTrayIcon(this);
-  trayIcon->setContextMenu(trayIconMenu);
-
-  QIcon icon(":/images/icon_small.png");
-  trayIcon->setIcon(icon);
-  setWindowIcon(icon);
-  trayIcon->setToolTip("Chronos System Tray Icon");
-  trayIcon->setVisible(true);
-
-  // // QApplication::getMenu ()->addMenu (trayIconMenu);
-  // QMenuBar *bar = new QMenuBar ();
-  // bar->setMenu (trayIconMenu);
-  // setMenuBar (bar);
-}
-
-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);
-  treeViewer->fitInView(m_scene->itemsBoundingRect(), Qt::KeepAspectRatio);
+  
 }
 
 #if WAF
diff --git a/src/chatdialog.h b/src/chatdialog.h
index ba6c6c8..77feea1 100644
--- a/src/chatdialog.h
+++ b/src/chatdialog.h
@@ -1,145 +1,51 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
 /*
  * Copyright (c) 2013, Regents of the University of California
- *                     Alexander Afanasyev
- *                     Zhenkai Zhu
+ *                     Yingdi Yu
  *
- * GNU v3.0 license, See the LICENSE file for more information
+ * BSD license, See the LICENSE file for more information
  *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
  */
 
 #ifndef CHATDIALOG_H
 #define CHATDIALOG_H
 
-#ifndef Q_MOC_RUN
-#include <boost/function.hpp>
-#include <boost/thread/recursive_mutex.hpp>
+#include <QDialog>
 
-#include <vector>
-#include "digesttreescene.h"
-#include "ui_chatdialog.h"
-#include "chatbuf.pb.h"
-#include <ccnx/sync-app-socket.h>
-#include <sync-logic.h>
-#include <sync-seq-no.h>
+#ifndef Q_MOC_RUN
+#include <ndn.cxx/data.h>
 #endif
 
-#include <QSystemTrayIcon>
-#include <QMainWindow>
-#include <QQueue>
+namespace Ui {
+class ChatDialog;
+}
 
-#define ORGANIZATION "irl.cs.ucla.edu"
-#define APPLICATION "ChronoChat"
-#define MAX_HISTORY_ENTRY   20
-
-class QAction;
-class QMenu;
-class QStringListModel;
-class QTextTable;
-
-class ChatDialog : public QDialog, private Ui::ChatDialog
+class ChatDialog : public QDialog
 {
-	Q_OBJECT
+  Q_OBJECT
 
 public:
-  ChatDialog(QWidget *parent = 0);
+  explicit ChatDialog(const ndn::Name& chatroomPrefix,
+                      const ndn::Name& localPrefix,
+                      QWidget *parent = 0);
   ~ChatDialog();
-  void setVisible(bool visible);
-  void appendMessage(const SyncDemo::ChatMessage msg, bool isHistory = false);
-  void processTreeUpdateWrapper(const std::vector<Sync::MissingDataInfo>, Sync::SyncAppSocket *);
-  void processDataWrapper(std::string, const char *buf, size_t len);
-  void processDataNoShowWrapper(std::string, const char *buf, size_t len);
-  void processDataHistoryWrapper(std::string, const char *buf, size_t len);
-  void processRemoveWrapper(std::string);
-  void respondHistoryRequest(std::string interest);
 
-protected:
-  void closeEvent(QCloseEvent *e);
-  void changeEvent(QEvent *e);
+  const ndn::Name&
+  getChatroomPrefix() const
+  { return m_chatroomPrefix; }
 
-public slots:
-  void processTreeUpdate(const std::vector<Sync::MissingDataInfo>);
-  void processData(QString name, const char *buf, size_t len, bool show, bool isHistory);
-  void processRemove(QString);
+  const ndn::Name&
+  getLocalPrefix() const
+  { return m_localPrefix; }
+
+  void
+  sendInvitation();
 
 private:
-  void fetchHistory(std::string name);
-  QString getRandomString();
-  void formChatMessage(const QString &text, SyncDemo::ChatMessage &msg);
-  void formControlMessage(SyncDemo::ChatMessage &msg, SyncDemo::ChatMessage::ChatMessageType type);
-  void sendMsg(SyncDemo::ChatMessage &msg);
-  bool readSettings();
-  void writeSettings();
-  void updateLabels();
-  void resizeEvent(QResizeEvent *);
-  void showEvent(QShowEvent *);
-  void fitView();
-  void testDraw();
-  void createTrayIcon();
-  void createActions();
-  QString formatTime(time_t);
-  void printTimeInCell(QTextTable *, time_t);
-  void disableTreeDisplay();
-  bool getLocalPrefix();
-  void initializeSync();
-
-private slots:
-  void returnPressed();
-  void buttonPressed();
-  void treeButtonPressed();
-  void checkSetting();
-  void settingUpdated(QString, QString, QString);
-  void sendHello();
-  void sendJoin();
-  void sendLeave();
-  void replot();
-  void updateRosterList(QStringList);
-  void enableTreeDisplay();
-  void updateLocalPrefix();
-  void reap();
-  void summonReaper();
-
-  // icon related
-  void iconActivated(QSystemTrayIcon::ActivationReason reason);
-  void showMessage(QString, QString);
-  void messageClicked();
-
-signals:
-  void dataReceived(QString name, const char *buf, size_t len, bool show, bool isHistory);
-  void treeUpdated(const std::vector<Sync::MissingDataInfo>);
-  void removeReceived(QString prefix);
-
-private:
-  User m_user; 
-  Sync::SyncAppSocket *m_sock;
-  uint32_t m_session;
-  DigestTreeScene *m_scene;
-  boost::recursive_mutex m_msgMutex;
-  boost::recursive_mutex m_sceneMutex;
-  time_t m_lastMsgTime;
-  int m_randomizedInterval;
-  QTimer *m_timer;
-  QStringListModel *m_rosterModel;
-  bool m_minimaniho;
-
-  QQueue<SyncDemo::ChatMessage> m_history;
-  bool m_historyInitialized;
-  bool m_joined;
-
-  QList<QString> m_zombieList;
-  int m_zombieIndex;
-
-  // icon related
-  QAction *minimizeAction;
-  QAction *maximizeAction;
-  QAction *restoreAction;
-  QAction *settingsAction;
-  QAction *updateLocalPrefixAction;
-  QAction *quitAction;
-  QSystemTrayIcon *trayIcon;
-  // QMenu *menuBar;
-  QMenu *trayIconMenu;
+  Ui::ChatDialog *ui;
+  ndn::Name m_chatroomPrefix;
+  ndn::Name m_localPrefix;
 };
-#endif
+
+#endif // ChatDIALOG_H
