remove protobuf dependency

Change-Id: I10bf90ba940bbde27d91df58056f4f558843f697
diff --git a/src/add-contact-panel.cpp b/src/add-contact-panel.cpp
index 354758e..770f039 100644
--- a/src/add-contact-panel.cpp
+++ b/src/add-contact-panel.cpp
@@ -74,22 +74,21 @@
 }
 
 void
-AddContactPanel::onContactEndorseInfoReady(const chronochat::EndorseInfo& endorseInfo)
+AddContactPanel::onContactEndorseInfoReady(const EndorseInfo& endorseInfo)
 {
-  int entrySize = endorseInfo.endorsement_size();
-
-  for (int rowCount = 0; rowCount < entrySize; rowCount++) {
+  std::vector<EndorseInfo::Endorsement> endorsements = endorseInfo.getEndorsements();
+  for (size_t rowCount = 0; rowCount < endorsements.size(); rowCount++) {
     ui->infoView->insertRow(rowCount);
     QTableWidgetItem* type =
-      new QTableWidgetItem(QString::fromStdString(endorseInfo.endorsement(rowCount).type()));
+      new QTableWidgetItem(QString::fromStdString(endorsements[rowCount].type));
     ui->infoView->setItem(rowCount, 0, type);
 
     QTableWidgetItem* value =
-      new QTableWidgetItem(QString::fromStdString(endorseInfo.endorsement(rowCount).value()));
+      new QTableWidgetItem(QString::fromStdString(endorsements[rowCount].value));
     ui->infoView->setItem(rowCount, 1, value);
 
     QTableWidgetItem* endorse =
-      new QTableWidgetItem(QString::fromStdString(endorseInfo.endorsement(rowCount).endorse()));
+      new QTableWidgetItem(QString::fromStdString(endorsements[rowCount].count));
     ui->infoView->setItem(rowCount, 2, endorse);
   }
 }
diff --git a/src/add-contact-panel.hpp b/src/add-contact-panel.hpp
index 5dd3de2..fe8f851 100644
--- a/src/add-contact-panel.hpp
+++ b/src/add-contact-panel.hpp
@@ -15,7 +15,7 @@
 #include <QTableWidgetItem>
 
 #ifndef Q_MOC_RUN
-#include "endorse-info.pb.h"
+#include "endorse-info.hpp"
 #endif
 
 namespace Ui {
@@ -36,7 +36,7 @@
 
 public slots:
   void
-  onContactEndorseInfoReady(const chronochat::EndorseInfo& endorseInfo);
+  onContactEndorseInfoReady(const EndorseInfo& endorseInfo);
 
 private slots:
   void
diff --git a/src/chat-dialog-backend.cpp b/src/chat-dialog-backend.cpp
index bbe17da..ff1a51e 100644
--- a/src/chat-dialog-backend.cpp
+++ b/src/chat-dialog-backend.cpp
@@ -267,20 +267,23 @@
                                    bool needDisplay,
                                    bool isValidated)
 {
-  SyncDemo::ChatMessage msg;
+  ChatMessage msg;
 
-  if (!msg.ParseFromArray(data->getContent().value(), data->getContent().value_size())) {
+  try {
+    msg.wireDecode(data->getContent().blockFromValue());
+  }
+  catch (tlv::Error) {
     _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);
+    msg.setNick("inconnu");
+    msg.setMsgType(ChatMessage::OTHER);
     return;
   }
 
   Name remoteSessionPrefix = data->getName().getPrefix(-1);
 
-  if (msg.type() == SyncDemo::ChatMessage::LEAVE) {
+  if (msg.getMsgType() == ChatMessage::LEAVE) {
     BackendRoster::iterator it = m_roster.find(remoteSessionPrefix);
 
     if (it != m_roster.end()) {
@@ -290,8 +293,8 @@
 
       // notify frontend to remove the remote session (node)
       emit sessionRemoved(QString::fromStdString(remoteSessionPrefix.toUri()),
-                          QString::fromStdString(msg.from()),
-                          msg.timestamp());
+                          QString::fromStdString(msg.getNick()),
+                          msg.getTimestamp());
 
       // remove roster entry
       m_roster.erase(remoteSessionPrefix);
@@ -321,28 +324,28 @@
                                       this, remoteSessionPrefix));
 
     // If chat message, notify the frontend
-    if (msg.type() == SyncDemo::ChatMessage::CHAT) {
+    if (msg.getMsgType() == ChatMessage::CHAT) {
       if (isValidated)
-        emit chatMessageReceived(QString::fromStdString(msg.from()),
-                                 QString::fromStdString(msg.data()),
-                                 msg.timestamp());
+        emit chatMessageReceived(QString::fromStdString(msg.getNick()),
+                                 QString::fromStdString(msg.getData()),
+                                 msg.getTimestamp());
       else
-        emit chatMessageReceived(QString::fromStdString(msg.from() + " (Unverified)"),
-                                 QString::fromStdString(msg.data()),
-                                 msg.timestamp());
+        emit chatMessageReceived(QString::fromStdString(msg.getNick() + " (Unverified)"),
+                                 QString::fromStdString(msg.getData()),
+                                 msg.getTimestamp());
     }
 
     // Notify frontend to plot notification on DigestTree.
 
     // 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].userNick = msg.getNick();
       m_roster[remoteSessionPrefix].hasNick = true;
 
       emit messageReceived(QString::fromStdString(remoteSessionPrefix.toUri()),
-                           QString::fromStdString(msg.from()),
+                           QString::fromStdString(msg.getNick()),
                            seqNo,
-                           msg.timestamp(),
+                           msg.getTimestamp(),
                            true);
 
       emit addInRoster(remoteSessionPrefix.getPrefix(IDENTITY_OFFSET),
@@ -350,9 +353,9 @@
     }
     else
       emit messageReceived(QString::fromStdString(remoteSessionPrefix.toUri()),
-                           QString::fromStdString(msg.from()),
+                           QString::fromStdString(msg.getNick()),
                            seqNo,
-                           msg.timestamp(),
+                           msg.getTimestamp(),
                            false);
   }
 }
@@ -376,21 +379,14 @@
 }
 
 void
-ChatDialogBackend::sendMsg(SyncDemo::ChatMessage& msg)
+ChatDialogBackend::sendMsg(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();
-  }
+  ndn::Block buf = msg.wireEncode();
 
   uint64_t nextSequence = m_sock->getLogic().getSeqNo() + 1;
 
-  m_sock->publishData(os.buf()->buf(), os.buf()->size(), FRESHNESS_PERIOD);
+  m_sock->publishData(buf.wire(), buf.size(), FRESHNESS_PERIOD);
 
   std::vector<NodeInfo> nodeInfos;
   Name sessionName = m_sock->getLogic().getSessionName();
@@ -402,10 +398,10 @@
                        QString::fromStdString(getHexEncodedDigest(m_sock->getRootDigest())));
 
   emit messageReceived(QString::fromStdString(sessionName.toUri()),
-                       QString::fromStdString(msg.from()),
+                       QString::fromStdString(msg.getNick()),
                        nextSequence,
-                       msg.timestamp(),
-                       msg.type() == SyncDemo::ChatMessage::JOIN);
+                       msg.getTimestamp(),
+                       msg.getMsgType() == ChatMessage::JOIN);
 }
 
 void
@@ -413,8 +409,8 @@
 {
   m_joined = true;
 
-  SyncDemo::ChatMessage msg;
-  prepareControlMessage(msg, SyncDemo::ChatMessage::JOIN);
+  ChatMessage msg;
+  prepareControlMessage(msg, ChatMessage::JOIN);
   sendMsg(msg);
 
   m_helloEventId = m_scheduler->scheduleEvent(HELLO_INTERVAL,
@@ -425,8 +421,8 @@
 void
 ChatDialogBackend::sendHello()
 {
-  SyncDemo::ChatMessage msg;
-  prepareControlMessage(msg, SyncDemo::ChatMessage::HELLO);
+  ChatMessage msg;
+  prepareControlMessage(msg, ChatMessage::HELLO);
   sendMsg(msg);
 
   m_helloEventId = m_scheduler->scheduleEvent(HELLO_INTERVAL,
@@ -436,8 +432,8 @@
 void
 ChatDialogBackend::sendLeave()
 {
-  SyncDemo::ChatMessage msg;
-  prepareControlMessage(msg, SyncDemo::ChatMessage::LEAVE);
+  ChatMessage msg;
+  prepareControlMessage(msg, ChatMessage::LEAVE);
   sendMsg(msg);
 
   // get my own identity with routable prefix by getPrefix(-2)
@@ -449,27 +445,27 @@
 }
 
 void
-ChatDialogBackend::prepareControlMessage(SyncDemo::ChatMessage& msg,
-                                         SyncDemo::ChatMessage::ChatMessageType type)
+ChatDialogBackend::prepareControlMessage(ChatMessage& msg,
+                                         ChatMessage::ChatMessageType type)
 {
-  msg.set_from(m_nick);
-  msg.set_to(m_chatroomName);
+  msg.setNick(m_nick);
+  msg.setChatroomName(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);
+  msg.setTimestamp(seconds);
+  msg.setMsgType(type);
 }
 
 void
 ChatDialogBackend::prepareChatMessage(const QString& text,
                                       time_t timestamp,
-                                      SyncDemo::ChatMessage &msg)
+                                      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);
+  msg.setNick(m_nick);
+  msg.setChatroomName(m_chatroomName);
+  msg.setData(text.toStdString());
+  msg.setTimestamp(timestamp);
+  msg.setMsgType(ChatMessage::CHAT);
 }
 
 void
@@ -502,13 +498,13 @@
 void
 ChatDialogBackend::sendChatMessage(QString text, time_t timestamp)
 {
-  SyncDemo::ChatMessage msg;
+  ChatMessage msg;
   prepareChatMessage(text, timestamp, msg);
   sendMsg(msg);
 
-  emit chatMessageReceived(QString::fromStdString(msg.from()),
-                           QString::fromStdString(msg.data()),
-                           msg.timestamp());
+  emit chatMessageReceived(QString::fromStdString(msg.getNick()),
+                           QString::fromStdString(msg.getData()),
+                           msg.getTimestamp());
 }
 
 void
diff --git a/src/chat-dialog-backend.hpp b/src/chat-dialog-backend.hpp
index 70ebefc..ae7b3da 100644
--- a/src/chat-dialog-backend.hpp
+++ b/src/chat-dialog-backend.hpp
@@ -16,7 +16,7 @@
 #ifndef Q_MOC_RUN
 #include "common.hpp"
 #include "chatroom-info.hpp"
-#include "chatbuf.pb.h"
+#include "chat-message.hpp"
 #include <mutex>
 #include <socket.hpp>
 #include <boost/thread.hpp>
@@ -82,7 +82,7 @@
   remoteSessionTimeout(const Name& sessionPrefix);
 
   void
-  sendMsg(SyncDemo::ChatMessage& msg);
+  sendMsg(ChatMessage& msg);
 
   void
   sendJoin();
@@ -94,13 +94,13 @@
   sendLeave();
 
   void
-  prepareControlMessage(SyncDemo::ChatMessage& msg,
-                        SyncDemo::ChatMessage::ChatMessageType type);
+  prepareControlMessage(ChatMessage& msg,
+                        ChatMessage::ChatMessageType type);
 
   void
   prepareChatMessage(const QString& text,
                      time_t timestamp,
-                     SyncDemo::ChatMessage &msg);
+                     ChatMessage &msg);
 
   void
   updatePrefixes();
diff --git a/src/chat-message.cpp b/src/chat-message.cpp
new file mode 100644
index 0000000..d971072
--- /dev/null
+++ b/src/chat-message.cpp
@@ -0,0 +1,180 @@
+/* -*- 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: Qiuhan Ding <qiuhanding@cs.ucla.edu>
+ */
+
+#include "chat-message.hpp"
+
+namespace chronochat {
+
+BOOST_CONCEPT_ASSERT((ndn::WireEncodable<ChatMessage>));
+BOOST_CONCEPT_ASSERT((ndn::WireDecodable<ChatMessage>));
+
+ChatMessage::ChatMessage()
+{
+}
+
+ChatMessage::ChatMessage(const Block& chatMsgWire)
+{
+  this->wireDecode(chatMsgWire);
+}
+
+template<bool T>
+size_t
+ChatMessage::wireEncode(ndn::EncodingImpl<T>& block) const
+{
+  // ChatMessage := CHAT-MESSAGE-TYPE TLV-LENGTH
+  //                  Nick
+  //                  ChatroomName
+  //                  ChatMessageType
+  //                  ChatData
+  //                  Timestamp
+  //
+  // Nick := NICK-NAME-TYPE TLV-LENGTH
+  //           String
+  //
+  // ChatroomName := CHATROOM-NAME-TYPE TLV-LENGTH
+  //                   String
+  //
+  // ChatMessageType := CHAT-MESSAGE-TYPE TLV-LENGTH
+  //                      nonNegativeInteger
+  //
+  // ChatData := CHAT-DATA-TYPE TLV-LENGTH
+  //               String
+  //
+  // Timestamp := TIMESTAMP-TYPE TLV-LENGTH
+  //                VarNumber
+  //
+  size_t totalLength = 0;
+
+  // Timestamp
+  totalLength += ndn::prependNonNegativeIntegerBlock(block, tlv::Timestamp, m_timestamp);
+
+  // ChatData
+  if (m_msgType == CHAT) {
+    const uint8_t* dataWire = reinterpret_cast<const uint8_t*>(m_data.c_str());
+    totalLength += block.prependByteArrayBlock(tlv::ChatData, dataWire, m_data.length());
+  }
+
+  // ChatMessageType
+  totalLength += ndn::prependNonNegativeIntegerBlock(block, tlv::ChatMessageType, m_msgType);
+
+  // ChatroomName
+  const uint8_t* chatroomWire = reinterpret_cast<const uint8_t*>(m_chatroomName.c_str());
+  totalLength += block.prependByteArrayBlock(tlv::ChatroomName, chatroomWire,
+                                             m_chatroomName.length());
+
+  // Nick
+  const uint8_t* nickWire = reinterpret_cast<const uint8_t*>(m_nick.c_str());
+  totalLength += block.prependByteArrayBlock(tlv::Nick, nickWire, m_nick.length());
+
+  // Chat Message
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::ChatMessage);
+
+  return totalLength;
+}
+
+const Block&
+ChatMessage::wireEncode() const
+{
+  ndn::EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  ndn::EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  m_wire.parse();
+
+  return m_wire;
+}
+
+void
+ChatMessage::wireDecode(const Block& chatMsgWire)
+{
+  m_wire = chatMsgWire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::ChatMessage)
+    throw Error("Unexpected TLV number when decoding chat message packet");
+
+  Block::element_const_iterator i = m_wire.elements_begin();
+  if (i == m_wire.elements_end() || i->type() != tlv::Nick)
+    throw Error("Expect Nick but get ...");
+  m_nick = std::string(reinterpret_cast<const char* >(i->value()),
+                       i->value_size());;
+  i++;
+
+  if (i == m_wire.elements_end() || i->type() != tlv::ChatroomName)
+    throw Error("Expect Chatroom Name but get ...");
+  m_chatroomName = std::string(reinterpret_cast<const char* >(i->value()),
+                       i->value_size());;
+  i++;
+
+  if (i == m_wire.elements_end() || i->type() != tlv::ChatMessageType)
+    throw Error("Expect Chat Message Type but get ...");
+  m_msgType = static_cast<ChatMessageType>(readNonNegativeInteger(*i));
+  i++;
+
+  if (m_msgType != CHAT)
+    m_data = "";
+  else {
+    if (i == m_wire.elements_end() || i->type() != tlv::ChatData)
+      throw Error("Expect Chat Data but get ...");
+    m_data = std::string(reinterpret_cast<const char* >(i->value()),
+                       i->value_size());;
+    i++;
+  }
+
+  if (i == m_wire.elements_end() || i->type() != tlv::Timestamp)
+    throw Error("Expect Timestamp but get ...");
+  m_timestamp = static_cast<time_t>(readNonNegativeInteger(*i));
+  i++;
+
+  if (i != m_wire.elements_end()) {
+    throw Error("Unexpected element");
+  }
+
+}
+
+void
+ChatMessage::setNick(const std::string& nick)
+{
+  m_wire.reset();
+  m_nick = nick;
+}
+
+void
+ChatMessage::setChatroomName(const std::string& chatroomName)
+{
+  m_wire.reset();
+  m_chatroomName = chatroomName;
+}
+
+void
+ChatMessage::setMsgType(const ChatMessageType msgType)
+{
+  m_wire.reset();
+  m_msgType = msgType;
+}
+
+void
+ChatMessage::setData(const std::string& data)
+{
+  m_wire.reset();
+  m_data = data;
+}
+
+void
+ChatMessage::setTimestamp(const time_t timestamp)
+{
+  m_wire.reset();
+  m_timestamp = timestamp;
+}
+
+}// namespace chronochat
diff --git a/src/chat-message.hpp b/src/chat-message.hpp
new file mode 100644
index 0000000..432fac9
--- /dev/null
+++ b/src/chat-message.hpp
@@ -0,0 +1,135 @@
+/* -*- 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: Qiuhan Ding <qiuhanding@cs.ucla.edu>
+ */
+
+#ifndef CHRONOCHAT_CHAT_MESSAGE_HPP
+#define CHRONOCHAT_CHAT_MESSAGE_HPP
+
+#include "common.hpp"
+#include "tlv.hpp"
+#include <ndn-cxx/util/concepts.hpp>
+#include <ndn-cxx/encoding/block.hpp>
+#include <ndn-cxx/encoding/encoding-buffer.hpp>
+#include <boost/concept_check.hpp>
+
+namespace chronochat {
+
+class ChatMessage
+{
+
+public:
+
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  enum ChatMessageType {
+    CHAT = 0,
+    HELLO = 1,
+    LEAVE = 2,
+    JOIN = 3,
+    OTHER = 4,
+  };
+
+public:
+
+  ChatMessage();
+
+  explicit
+  ChatMessage(const Block& chatMsgWire);
+
+  const Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const Block& chatMsgWire);
+
+  const std::string&
+  getNick() const;
+
+  const std::string&
+  getChatroomName() const;
+
+  const ChatMessageType
+  getMsgType() const;
+
+  const std::string&
+  getData() const;
+
+  const time_t
+  getTimestamp() const;
+
+  void
+  setNick(const std::string& nick);
+
+  void
+  setChatroomName(const std::string& chatroomName);
+
+  void
+  setMsgType(const ChatMessageType msgType);
+
+  void
+  setData(const std::string& data);
+
+  void
+  setTimestamp(const time_t timestamp);
+
+private:
+  template<bool T>
+  size_t
+  wireEncode(ndn::EncodingImpl<T>& block) const;
+
+private:
+  mutable Block m_wire;
+  std::string m_nick;
+  std::string m_chatroomName;
+  ChatMessageType m_msgType;
+  std::string m_data;
+  time_t m_timestamp;
+
+};
+
+inline const std::string&
+ChatMessage::getNick() const
+{
+  return m_nick;
+}
+
+inline const std::string&
+ChatMessage::getChatroomName() const
+{
+  return m_chatroomName;
+}
+
+inline const ChatMessage::ChatMessageType
+ChatMessage::getMsgType() const
+{
+  return m_msgType;
+}
+
+inline const std::string&
+ChatMessage::getData() const
+{
+  return m_data;
+}
+
+inline const time_t
+ChatMessage::getTimestamp() const
+{
+  return m_timestamp;
+}
+
+} // namespace chronochat
+
+#endif //CHRONOCHAT_CHAT_MESSAGE_HPP
diff --git a/src/chatbuf.proto b/src/chatbuf.proto
deleted file mode 100644
index 6ea6ea4..0000000
--- a/src/chatbuf.proto
+++ /dev/null
@@ -1,16 +0,0 @@
-package SyncDemo;
-
-message ChatMessage {
-  required string to = 1;
-  required string from = 2;
-  enum ChatMessageType {
-    CHAT = 0;
-    HELLO = 1;
-    LEAVE = 2;
-    JOIN  = 3;
-    OTHER = 4;
-  }
-  required ChatMessageType type = 3 [default = CHAT];
-  optional string data = 4;
-  required int32 timestamp = 5;
-}
diff --git a/src/chatroom-discovery-dialog.cpp b/src/chatroom-discovery-dialog.cpp
deleted file mode 100644
index 7e431ee..0000000
--- a/src/chatroom-discovery-dialog.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-#include "chatroom-discovery-dialog.hpp"
-#include "ui_chatroom-discovery-dialog.h"
-
-namespace chronochat {
-
-using ndn::Name;
-
-ChatroomDiscoveryDialog::ChatroomDiscoveryDialog(QWidget* parent)
-  : QDialog(parent)
-  , ui(new Ui::ChatroomDiscoveryDialog)
-  , m_standardItemModel(new QStandardItemModel(0, 3, this))
-  , m_chatroomDiscoveryViewDialog(new ChatroomDiscoveryViewDialog)
-{
-  ui->setupUi(this);
-
-  connect(ui->cancelButton, SIGNAL(clicked()),
-          this, SLOT(onCancelButtonClicked()));
-  connect(ui->joinButton, SIGNAL(clicked()),
-          this, SLOT(onJoinButtonClicked()));
-  connect(ui->viewButton, SIGNAL(clicked()),
-          this, SLOT(onViewButtonClicked()));
-  connect(ui->chatroomListView, SIGNAL(clicked(QModelIndex)),
-          this, SLOT(onChatroomListViewClicked(QModelIndex)));
-  connect(ui->chatroomListView, SIGNAL(doubleClicked(QModelIndex)),
-          this, SLOT(onChatroomListViewDoubleClicked(QModelIndex)));
-
-  updateChatroomList();
-}
-
-ChatroomDiscoveryDialog::~ChatroomDiscoveryDialog()
-{
-  delete ui;
-}
-
-void
-ChatroomDiscoveryDialog::updateChatroomList()
-{
-  m_standardItemModel->clear();
-
-  m_standardItemModel
-    ->setHorizontalHeaderItem(0, new QStandardItem(QString("Chatroom Name")));
-  m_standardItemModel
-    ->setHorizontalHeaderItem(1, new QStandardItem(QString("Chatroom Trust Model")));
-  m_standardItemModel
-    ->setHorizontalHeaderItem(2, new QStandardItem(QString("Participants or Contacts")));
-
-  QHeaderView *m_headerView = ui->chatroomListView->horizontalHeader();
-  m_headerView->setResizeMode((QHeaderView::ResizeMode)3);
-  m_headerView->setStretchLastSection(true);
-
-  ui->chatroomListView->setModel(m_standardItemModel);
-
-  int i = 0;
-  for (Chatrooms::const_iterator it = m_chatrooms.begin();
-       it != m_chatrooms.end(); ++it, ++i) {
-    QStandardItem *item = new QStandardItem(QString::fromStdString(it->first.toUri()));
-    item->setEditable(false);
-    m_standardItemModel->setItem(i, 0, item);
-
-    if (it->second.getTrustModel() == ChatroomInfo::TRUST_MODEL_WEBOFTRUST)
-      item = new QStandardItem(QString("Web of trust"));
-    else
-      item = new QStandardItem(QString("Hierarchical"));
-    item->setEditable(false);
-    m_standardItemModel->setItem(i, 1, item);
-
-    QString content;
-
-    for (std::list<Name>::const_iterator nameIt = it->second.getParticipants().begin();
-         nameIt != it->second.getParticipants().end(); nameIt++) {
-      content.append(QString::fromStdString(nameIt->toUri())).append(",");
-    }
-    item = new QStandardItem(content);
-    item->setEditable(false);
-    m_standardItemModel->setItem(i, 2, item);
-  }
-}
-
-void
-ChatroomDiscoveryDialog::onDiscoverChatroomChanged(const chronochat::ChatroomInfo& info, bool isAdd)
-{
-  if (isAdd)
-    m_chatrooms[info.getName()] = info;
-  else
-    m_chatrooms.erase(info.getName());
-
-  updateChatroomList();
-}
-
-void
-ChatroomDiscoveryDialog::onCancelButtonClicked()
-{
-  this->close();
-}
-
-void
-ChatroomDiscoveryDialog::onJoinButtonClicked()
-{
-  if(ui->chatroomListView->selectionModel()->selectedRows().size() == 0) {
-    QMessageBox::information(this, tr("ChronoChat"), tr("Please select a chatroom to join"));
-  }
-  else {
-    m_selectedRow = ui->chatroomListView->selectionModel()->selectedRows()[0].row();
-    QStandardItem* selectedChatroomName = m_standardItemModel->item(m_selectedRow, 0);
-    emit startChatroom(selectedChatroomName->text(), false);
-
-    {
-      // Tmp disabled
-      // QStandardItem* selectedChatroomTrustModel = m_standardItemModel->item(m_selectedRow, 1);
-      // if(selectedChatroomTrustModel->text() == "Hierarchical") {
-      //   emit startChatroom(selectedChatroomName->text(), false);
-      // }
-      // else if(selectedChatroomTrustModel->text() == "Web of trust") {
-      //   ChatroomDiscoveryLogic::ChatroomList::const_iterator it;
-      //   it = m_chatroomList->find(Name::Component(selectedChatroomName->text().toStdString()));
-
-      //   if(it->second.getContacts().size() == 0) {
-      //     QMessageBox messageBox;
-      //     messageBox.addButton(QMessageBox::Ok);
-      //     messageBox.setIcon(QMessageBox::Information);
-      //     messageBox.setText
-      //       ("You do not have a contact in this chatroom. Please choose another chatroom to join");
-      //     messageBox.exec();
-      //   }
-      //   else {
-      //     m_sendInvitationRequestDialog->setChatroomName(selectedChatroomName->text());
-      //     m_sendInvitationRequestDialog->setContacts(it->second.getContacts());
-      //     m_sendInvitationRequestDialog->show();
-      //   }
-      // }
-    }
-  }
-}
-
-void
-ChatroomDiscoveryDialog::onChatroomListViewDoubleClicked(const QModelIndex &index)
-{
-  onJoinButtonClicked();
-}
-
-void
-ChatroomDiscoveryDialog::onChatroomListViewClicked(const QModelIndex &index)
-{
-  ui->chatroomListView->selectRow(index.row());
-  m_selectedRow = index.row();
-}
-
-void
-ChatroomDiscoveryDialog::onViewButtonClicked()
-{
-  if(ui->chatroomListView->selectionModel()->selectedRows().size() == 0) {
-    QMessageBox messageBox;
-    messageBox.addButton(QMessageBox::Ok);
-    messageBox.setIcon(QMessageBox::Information);
-    messageBox.setText("Please select a chatroom to view");
-    messageBox.exec();
-  }
-  else {
-    m_selectedRow = ui->chatroomListView->selectionModel()->selectedRows()[0].row();
-
-    QStandardItem* selectedChatroomName = m_standardItemModel->item(m_selectedRow);
-    m_chatroomDiscoveryViewDialog->setChatroomName(selectedChatroomName->text());
-
-    // QStandardItem *m_selectedTrustModel = m_standardItemModel->item(m_selectedRow, 1);
-    // m_chatroomDiscoveryViewDialog->setChatroomTrustModel(m_selectedTrustModel->text());
-
-    //use chatroomlist as parameter to call set participants
-    //maybe for different chatroom with different trust model???
-    //participants can be contacts
-
-    Chatrooms::const_iterator it =
-      m_chatrooms.find(Name::Component(selectedChatroomName->text().toStdString()));
-
-    if (it != m_chatrooms.end()) {
-      m_chatroomDiscoveryViewDialog->setChatroomParticipants(it->second.getParticipants());
-      m_chatroomDiscoveryViewDialog->show();
-    }
-  }
-}
-
-} // namespace chronochat
-
-
-#if WAF
-#include "chatroom-discovery-dialog.moc"
-#endif
diff --git a/src/chatroom-discovery-dialog.hpp b/src/chatroom-discovery-dialog.hpp
deleted file mode 100644
index 916a6d2..0000000
--- a/src/chatroom-discovery-dialog.hpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- 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: Mengjin Yan <jane.yan0129@gmail.com>
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-#ifndef CHRONOCHAT_CHATROOM_DISCOVERY_DIALOG_HPP
-#define CHRONOCHAT_CHATROOM_DISCOVERY_DIALOG_HPP
-
-#include <QDialog>
-#include <QModelIndex>
-#include <QStandardItem>
-#include <QHeaderView>
-#include <QMessageBox>
-#include <QDebug>
-#include "chatroom-discovery-view-dialog.hpp"
-
-#ifndef Q_MOC_RUN
-#include "chatroom-info.hpp"
-#endif
-
-namespace Ui {
-class ChatroomDiscoveryDialog;
-}
-
-namespace chronochat {
-
-class ChatroomDiscoveryDialog : public QDialog
-{
-  Q_OBJECT
-
-public:
-  explicit
-  ChatroomDiscoveryDialog(QWidget* parent = 0);
-
-  ~ChatroomDiscoveryDialog();
-
-  void
-  updateChatroomList();
-
-signals:
-  void
-  startChatroom(const QString& chatroomName, bool secured);
-
-public slots:
-  void
-  onDiscoverChatroomChanged(const chronochat::ChatroomInfo& chatroom, bool isAdd);
-
-private slots:
-  void
-  onCancelButtonClicked();
-
-  void
-  onJoinButtonClicked();
-
-  void
-  onViewButtonClicked();
-
-  void
-  onChatroomListViewDoubleClicked(const QModelIndex& index);
-
-  void
-  onChatroomListViewClicked(const QModelIndex& index);
-
-private:
-
-  typedef std::map<Name::Component, ChatroomInfo> Chatrooms;
-
-  Ui::ChatroomDiscoveryDialog *ui;
-  QStandardItemModel* m_standardItemModel;
-
-  int m_selectedRow;
-
-  Chatrooms m_chatrooms;
-
-
-
-  ChatroomDiscoveryViewDialog* m_chatroomDiscoveryViewDialog;
-};
-
-} //namespace chronochat
-
-#endif // CHRONOCHAT_CHATROOM_DISCOVERY_DIALOG_HPP
diff --git a/src/chatroom-discovery-dialog.ui b/src/chatroom-discovery-dialog.ui
deleted file mode 100644
index 66df7ae..0000000
--- a/src/chatroom-discovery-dialog.ui
+++ /dev/null
@@ -1,94 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ChatroomDiscoveryDialog</class>
- <widget class="QDialog" name="ChatroomDiscoveryDialog">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>570</width>
-    <height>503</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>ChatroomDiscoveryDialog</string>
-  </property>
-  <widget class="QLabel" name="introLabel">
-   <property name="geometry">
-    <rect>
-     <x>50</x>
-     <y>30</y>
-     <width>451</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Here are the ongoing chatrooms:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-   </property>
-  </widget>
-  <widget class="QTableView" name="chatroomListView">
-   <property name="geometry">
-    <rect>
-     <x>40</x>
-     <y>60</y>
-     <width>491</width>
-     <height>371</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="viewButton">
-   <property name="geometry">
-    <rect>
-     <x>260</x>
-     <y>450</y>
-     <width>91</width>
-     <height>32</height>
-    </rect>
-   </property>
-   <property name="contextMenuPolicy">
-    <enum>Qt::DefaultContextMenu</enum>
-   </property>
-   <property name="text">
-    <string>View</string>
-   </property>
-   <property name="autoDefault">
-    <bool>false</bool>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="joinButton">
-   <property name="geometry">
-    <rect>
-     <x>360</x>
-     <y>450</y>
-     <width>91</width>
-     <height>32</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Join</string>
-   </property>
-   <property name="autoDefault">
-    <bool>false</bool>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="cancelButton">
-   <property name="geometry">
-    <rect>
-     <x>460</x>
-     <y>450</y>
-     <width>91</width>
-     <height>32</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Cancel</string>
-   </property>
-   <property name="autoDefault">
-    <bool>false</bool>
-   </property>
-  </widget>
- </widget>
- <layoutdefault spacing="6" margin="11"/>
- <resources/>
- <connections/>
-</ui>
diff --git a/src/chatroom-discovery-logic.cpp b/src/chatroom-discovery-logic.cpp
deleted file mode 100644
index d101706..0000000
--- a/src/chatroom-discovery-logic.cpp
+++ /dev/null
@@ -1,222 +0,0 @@
-/* -*- 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: Mengjin Yan <jane.yan0129@gmail.com>
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "chatroom-discovery-logic.hpp"
-
-
-namespace chronochat {
-
-const size_t ChatroomDiscoveryLogic::OFFSET_CHATROOM_NAME = 4;
-const size_t ChatroomDiscoveryLogic::DISCOVERY_INTEREST_NAME_SIZE = 4;
-const size_t ChatroomDiscoveryLogic::REFRESHING_INTEREST_NAME_SIZE = 5;
-const time::milliseconds ChatroomDiscoveryLogic::DEFAULT_REFRESHING_TIMER(10000);
-const Name ChatroomDiscoveryLogic::DISCOVERY_PREFIX("/ndn/broadcast/chronochat/chatroom-list");
-const time::seconds ChatroomDiscoveryLogic::m_discoveryInterval(600);
-
-ChatroomDiscoveryLogic::ChatroomDiscoveryLogic(shared_ptr<ndn::Face> face,
-                                               const UpdateCallback& updateCallback)
-  : m_face(face)
-  , m_scheduler(face->getIoService())
-  , m_onUpdate(updateCallback)
-{
-
-  m_face->setInterestFilter(DISCOVERY_PREFIX,
-                            bind(&ChatroomDiscoveryLogic::onDiscoveryInterest,
-                                 this, _1, _2),
-                            bind(&ChatroomDiscoveryLogic::onPrefixRegistrationFailed,
-                                 this, _1));
-}
-
-void
-ChatroomDiscoveryLogic::addLocalChatroom(const ChatroomInfo& chatroom)
-{
-  m_localChatrooms[chatroom.getName()] = chatroom;
-  m_chatrooms[chatroom.getName()] = chatroom; // no need to discover local chatroom
-}
-
-void
-ChatroomDiscoveryLogic::removeLocalChatroom(const Name::Component& chatroomName)
-{
-  m_localChatrooms.erase(chatroomName);
-  m_chatrooms.erase(chatroomName);
-}
-
-void
-ChatroomDiscoveryLogic::sendDiscoveryInterest()
-{
-  Interest discovery(DISCOVERY_PREFIX);
-  discovery.setMustBeFresh(true);
-  discovery.setInterestLifetime(time::milliseconds(10000));
-
-  Exclude exclude;
-  Chatrooms::iterator it;
-  for (it = m_chatrooms.begin(); it != m_chatrooms.end(); ++it) {
-    exclude.excludeOne(it->first);
-  }
-  discovery.setExclude(exclude);
-
-  m_face->expressInterest(discovery,
-                          bind(&ChatroomDiscoveryLogic::onReceiveData, this,
-                               _1, _2, false),
-                          bind(&ChatroomDiscoveryLogic::onDiscoveryInterestTimeout, this,
-                               _1));
-
-}
-
-void
-ChatroomDiscoveryLogic::onDiscoveryInterest(const Name& name, const Interest& interest)
-{
-  if (m_localChatrooms.empty())
-    return;
-
-  if (interest.getName() == DISCOVERY_PREFIX) {
-    // discovery
-    for (Chatrooms::const_iterator it = m_localChatrooms.begin();
-         it != m_localChatrooms.end(); ++it) {
-
-      if (!interest.getExclude().empty() &&
-          interest.getExclude().isExcluded(it->first))
-        continue;
-
-
-      Name dataName(interest.getName());
-      dataName.append(it->first);
-
-      shared_ptr<Data> chatroomInfo = make_shared<Data>(dataName);
-      chatroomInfo->setFreshnessPeriod(time::seconds(10));
-      chatroomInfo->setContent(it->second.wireEncode());
-
-      m_keyChain.sign(*chatroomInfo);
-      m_face->put(*chatroomInfo);
-      break;
-    }
-    return;
-  }
-
-  if (DISCOVERY_PREFIX.isPrefixOf(interest.getName()) &&
-      interest.getName().size() == REFRESHING_INTEREST_NAME_SIZE) {
-    // refreshing
-    Chatrooms::const_iterator it =
-      m_localChatrooms.find(interest.getName().get(OFFSET_CHATROOM_NAME));
-
-    if (it == m_localChatrooms.end())
-      return;
-
-    shared_ptr<Data> chatroomInfo = make_shared<Data>(interest.getName());
-    chatroomInfo->setFreshnessPeriod(time::seconds(10));
-    chatroomInfo->setContent(it->second.wireEncode());
-
-    m_keyChain.sign(*chatroomInfo);
-    m_face->put(*chatroomInfo);
-
-    return;
-  }
-}
-
-void
-ChatroomDiscoveryLogic::onPrefixRegistrationFailed(const Name& name)
-{
-}
-
-void
-ChatroomDiscoveryLogic::refreshChatroom(const Name::Component& chatroomName)
-{
-  Name name = DISCOVERY_PREFIX;
-  name.append(chatroomName);
-
-  BOOST_ASSERT(name.size() == REFRESHING_INTEREST_NAME_SIZE);
-
-  Interest discovery(name);
-  discovery.setMustBeFresh(true);
-  discovery.setInterestLifetime(time::milliseconds(10000));
-
-  m_face->expressInterest(discovery,
-                          bind(&ChatroomDiscoveryLogic::onReceiveData, this,
-                               _1, _2, true),
-                          bind(&ChatroomDiscoveryLogic::onRefreshingInterestTimeout, this,
-                               _1));
-
-}
-
-void
-ChatroomDiscoveryLogic::onReceiveData(const ndn::Interest& interest,
-                                      const ndn::Data& data,
-                                      const bool isRefreshing)
-{
-  // Name::Component chatroomName = data.getName().get(OFFSET_CHATROOM_NAME);
-
-  ChatroomInfo chatroom;
-  chatroom.wireDecode(data.getContent().blockFromValue());
-  // chatroom.setName(chatroomName);
-
-  // Tmp Disabled
-  // if (chatroom.getTrustModel() == ChatroomInfo::TRUST_MODEL_WEBOFTRUST)
-  //   addContacts(chatroom);
-
-
-  m_chatrooms[chatroom.getName()] = chatroom;
-  m_onUpdate(chatroom, true); //add
-
-  time::milliseconds refreshingTime;
-  if (data.getFreshnessPeriod() > DEFAULT_REFRESHING_TIMER)
-    refreshingTime = data.getFreshnessPeriod();
-  else
-    refreshingTime = DEFAULT_REFRESHING_TIMER;
-
-  m_scheduler.scheduleEvent(refreshingTime,
-                            bind(&ChatroomDiscoveryLogic::refreshChatroom, this,
-                                 chatroom.getName()));
-
-  if (!isRefreshing)
-    sendDiscoveryInterest();
-}
-
-void
-ChatroomDiscoveryLogic::onRefreshingInterestTimeout(const ndn::Interest& interest)
-{
-  Name::Component chatroomName = interest.getName().get(OFFSET_CHATROOM_NAME);
-
-  Chatrooms::iterator it = m_chatrooms.find(chatroomName);
-  if (it != m_chatrooms.end()) {
-    m_onUpdate(it->second, false); //delete
-    m_chatrooms.erase(it);
-  }
-}
-
-
-void
-ChatroomDiscoveryLogic::onDiscoveryInterestTimeout(const Interest& interest)
-{
-  m_scheduler.scheduleEvent(m_discoveryInterval,
-                            bind(&ChatroomDiscoveryLogic::sendDiscoveryInterest, this));
-}
-
-void
-ChatroomDiscoveryLogic::addContacts(ChatroomInfo& chatroom)
-{
-  // Tmp Disabled
-
-  // std::vector<Name>::const_iterator nameIt;
-  // std::vector<shared_ptr<Contact> >::iterator contactIt;
-  // ContactList contactList;
-  // m_contactManager->getContactList(contactList);
-
-  // for (contactIt = contactList.begin();
-  //      contactIt != contactList.end(); ++contactIt) {
-  //   nameIt = std::find(chatroom.getParticipants().begin(),
-  //                 chatroom.getParticipants().end(), (*contactIt)->getNameSpace());
-  //   if (nameIt != chatroom.getParticipants().end())
-  //     chatroom.addContact(*nameIt);
-  // }
-}
-
-
-} // namespace chronochat
diff --git a/src/chatroom-discovery-logic.hpp b/src/chatroom-discovery-logic.hpp
deleted file mode 100644
index 58b44f9..0000000
--- a/src/chatroom-discovery-logic.hpp
+++ /dev/null
@@ -1,118 +0,0 @@
-/* -*- 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: Mengjin Yan <jane.yan0129@gmail.com>
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef CHRONOCHAT_CHATROOM_DISCOVERY_LOGIC_HPP
-#define CHRONOCHAT_CHATROOM_DISCOVERY_LOGIC_HPP
-
-#include "chatroom-info.hpp"
-#include <ndn-cxx/util/scheduler.hpp>
-
-namespace chronochat {
-
-class ChatroomDiscoveryLogic : noncopyable
-{
-public:
-  typedef function<void(const ChatroomInfo& chatroomName, bool isAdd)> UpdateCallback;
-
-  typedef std::map<Name::Component, chronochat::ChatroomInfo> Chatrooms;
-  static const size_t OFFSET_CHATROOM_NAME;
-  static const size_t DISCOVERY_INTEREST_NAME_SIZE;
-  static const size_t REFRESHING_INTEREST_NAME_SIZE;
-  static const time::milliseconds DEFAULT_REFRESHING_TIMER;
-  static const Name DISCOVERY_PREFIX;
-
-public:
-  explicit
-  ChatroomDiscoveryLogic(shared_ptr<ndn::Face> face,
-                         const UpdateCallback& updateCallback);
-
-
-  /** \brief obtain the ongoing chatroom list
-   */
-  const Chatrooms&
-  getChatrooms() const;
-
-  /** \brief add a local chatroom in the ongoing chatroom list
-   */
-  void
-  addLocalChatroom(const ChatroomInfo& chatroom);
-
-  void
-  removeLocalChatroom(const Name::Component& chatroomName);
-
-  /** \brief send discovery interest
-   */
-  void
-  sendDiscoveryInterest();
-
-CHRONOCHAT_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  /**
-   */
-  void
-  onDiscoveryInterest(const Name& name, const Interest& interest);
-
-  /**
-   */
-  void
-  onPrefixRegistrationFailed(const Name& name);
-
-  /** \brief schedule another discovery
-   */
-  void
-  onDiscoveryInterestTimeout(const Interest& interest);
-
-  /** \brief send interest to find if the certain chatroom exists
-   */
-  void
-  refreshChatroom(const Name::Component& chatroomName);
-
-  /** \brief copy the contact from the participants of the chatroom to contacts of the chatroom
-   */
-  void
-  addContacts(ChatroomInfo& chatroom);
-
-CHRONOCHAT_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-
-  /** \brief erase the chatroom from the ongoing chatroom list
-   */
-  void
-  onRefreshingInterestTimeout(const Interest& interest);
-
-  /** \brief operate the chatroom data and schedule discovery and refreshing process
-   */
-  void
-  onReceiveData(const ndn::Interest& interest, const ndn::Data& data, const bool isRefreshing);
-
-private:
-  static const time::seconds m_discoveryInterval;
-
-  shared_ptr<ndn::Face> m_face;
-
-  ndn::KeyChain m_keyChain;
-
-  Chatrooms m_chatrooms;
-  Chatrooms m_localChatrooms;
-
-  ndn::Scheduler m_scheduler;
-
-  UpdateCallback m_onUpdate;
-
-};
-
-inline const ChatroomDiscoveryLogic::Chatrooms&
-ChatroomDiscoveryLogic::getChatrooms() const
-{
-  return m_chatrooms;
-}
-
-} // namespace chronochat
-
-#endif // CHRONOCHAT_CHATROOM_DISCOVERY_LOGIC_HPP
diff --git a/src/chatroom-discovery-view-dialog.cpp b/src/chatroom-discovery-view-dialog.cpp
deleted file mode 100644
index b0593c9..0000000
--- a/src/chatroom-discovery-view-dialog.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- 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: Mengjin Yan <jane.yan0129@gmail.com>
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-#include "chatroom-discovery-view-dialog.hpp"
-#include "ui_chatroom-discovery-view-dialog.h"
-
-namespace chronochat {
-
-using ndn::Name;
-
-ChatroomDiscoveryViewDialog::ChatroomDiscoveryViewDialog(QWidget* parent)
-  : QDialog(parent)
-  , ui(new Ui::ChatroomDiscoveryViewDialog)
-{
-  ui->setupUi(this);
-
-  ui->participantsBrowser->setReadOnly(true);
-
-  connect(ui->closeButton, SIGNAL(clicked()),
-          this, SLOT(onCloseButtonClicked()));
-}
-
-ChatroomDiscoveryViewDialog::~ChatroomDiscoveryViewDialog()
-{
-  delete ui;
-}
-
-void
-ChatroomDiscoveryViewDialog::onCloseButtonClicked()
-{
-  this->close();
-}
-
-void
-ChatroomDiscoveryViewDialog::setChatroomName(QString chatroomName)
-{
-  ui->chatroomNameLabel->setText("Chatroom Name: "+chatroomName);
-}
-
-void
-ChatroomDiscoveryViewDialog::setChatroomTrustModel(QString chatroomTrustModel)
-{
-  ui->chatroomTrustModelLabel->setText("Chatroom Trust Model: "+chatroomTrustModel);
-}
-
-void
-ChatroomDiscoveryViewDialog::setChatroomParticipants(const std::list<Name>& participants)
-{
-  QString content;
-  for (std::list<Name>::const_iterator it = participants.begin();
-       it != participants.end(); it++) {
-    content.append(QString::fromStdString(it->toUri())).append("\n");
-  }
-
-  ui->participantsBrowser->setPlainText(content);
-}
-
-} // namespace chronochat
-
-#if WAF
-#include "chatroom-discovery-view-dialog.moc"
-#endif
diff --git a/src/chatroom-discovery-view-dialog.hpp b/src/chatroom-discovery-view-dialog.hpp
deleted file mode 100644
index 3ad0639..0000000
--- a/src/chatroom-discovery-view-dialog.hpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- 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: Mengjin Yan <jane.yan0129@gmail.com>
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef CHRONOCHAT_CHATROOM_DISCOVERY_VIEW_DIALOG_HPP
-#define CHRONOCHAT_CHATROOM_DISCOVERY_VIEW_DIALOG_HPP
-
-#include <QDialog>
-
-#ifndef Q_MOC_RUN
-#include "common.hpp"
-#endif
-
-namespace Ui {
-class ChatroomDiscoveryViewDialog;
-}
-
-namespace chronochat {
-
-class ChatroomDiscoveryViewDialog : public QDialog
-{
-  Q_OBJECT
-
-public:
-  explicit ChatroomDiscoveryViewDialog(QWidget* parent = 0);
-  ~ChatroomDiscoveryViewDialog();
-
-  void
-  setChatroomName(QString chatroomName);
-
-  void
-  setChatroomTrustModel(QString chatroomTrustModel);
-
-  void
-  setChatroomParticipants(const std::list<ndn::Name>& chatroomParticipants);
-
-
-private slots:
-  void
-  onCloseButtonClicked();
-
-private:
-  Ui::ChatroomDiscoveryViewDialog* ui;
-};
-
-} //namespace chronochat
-
-#endif // CHRONOCHAT_CHATROOM_DISCOVERY_VIEW_DIALOG_HPP
diff --git a/src/chatroom-discovery-view-dialog.ui b/src/chatroom-discovery-view-dialog.ui
deleted file mode 100644
index 74d6d94..0000000
--- a/src/chatroom-discovery-view-dialog.ui
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ChatroomDiscoveryViewDialog</class>
- <widget class="QDialog" name="ChatroomDiscoveryViewDialog">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>514</width>
-    <height>402</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>ViewChatroom</string>
-  </property>
-  <widget class="QLabel" name="chatroomNameLabel">
-   <property name="geometry">
-    <rect>
-     <x>40</x>
-     <y>50</y>
-     <width>431</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="sizePolicy">
-    <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-     <horstretch>0</horstretch>
-     <verstretch>0</verstretch>
-    </sizepolicy>
-   </property>
-   <property name="text">
-    <string/>
-   </property>
-  </widget>
-  <widget class="QLabel" name="chatroomTrustModelLabel">
-   <property name="geometry">
-    <rect>
-     <x>40</x>
-     <y>80</y>
-     <width>431</width>
-     <height>16</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QLabel" name="chatroomParcitipantsLabel">
-   <property name="geometry">
-    <rect>
-     <x>40</x>
-     <y>110</y>
-     <width>171</width>
-     <height>16</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Participants or Contacts:</string>
-   </property>
-  </widget>
-  <widget class="QTextBrowser" name="participantsBrowser">
-   <property name="geometry">
-    <rect>
-     <x>40</x>
-     <y>140</y>
-     <width>431</width>
-     <height>192</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="closeButton">
-   <property name="geometry">
-    <rect>
-     <x>360</x>
-     <y>350</y>
-     <width>114</width>
-     <height>32</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Close</string>
-   </property>
-  </widget>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/src/chatroom-info.cpp b/src/chatroom-info.cpp
index bd705da..c61babe 100644
--- a/src/chatroom-info.cpp
+++ b/src/chatroom-info.cpp
@@ -6,12 +6,16 @@
  * BSD license, See the LICENSE file for more information
  *
  * Author: Mengjin Yan <jane.yan0129@gmail.com>
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ *         Yingdi Yu <yingdi@cs.ucla.edu>
+ *         Qiuhan Ding <qiuhanding@cs.ucla.edu>
  */
 #include "chatroom-info.hpp"
 
 namespace chronochat {
 
+BOOST_CONCEPT_ASSERT((ndn::WireEncodable<ChatroomInfo>));
+BOOST_CONCEPT_ASSERT((ndn::WireDecodable<ChatroomInfo>));
+
 ChatroomInfo::ChatroomInfo()
 {
 }
@@ -137,33 +141,43 @@
 
   // Chatroom Info
   Block::element_const_iterator i = m_wire.elements_begin();
-  if (i == m_wire.elements_end() || i->type() != tlv::ChatroomName)
-    throw Error("Missing Chatroom Name Info");
+  if (i == m_wire.elements_end())
+    throw Error("Missing Chatroom Name");
+  if (i->type() != tlv::ChatroomName)
+    throw Error("Expect Chatroom Name but get TLV Type " + std::to_string(i->type()));
   m_chatroomName.wireDecode(i->blockFromValue());
   ++i;
 
   // Trust Model
-  if (i == m_wire.elements_end() || i->type() != tlv::TrustModel)
-    throw Error("Missing TrustModel");
+  if (i == m_wire.elements_end())
+    throw Error("Missing Trust Model");
+  if (i->type() != tlv::TrustModel)
+    throw Error("Expect Trust Model but get TLV Type " + std::to_string(i->type()));
   m_trustModel =
       static_cast<TrustModel>(readNonNegativeInteger(*i));
   ++i;
 
   // Chatroom Sync Prefix
-  if (i == m_wire.elements_end() || i->type() != tlv::ChatroomPrefix)
+  if (i == m_wire.elements_end())
     throw Error("Missing Chatroom Prefix");
+  if (i->type() != tlv::ChatroomPrefix)
+    throw Error("Expect Chatroom Prefix but get TLV Type " + std::to_string(i->type()));
   m_syncPrefix.wireDecode(i->blockFromValue());
   ++i;
 
   // Manager Prefix
-  if (i == m_wire.elements_end() || i->type() != tlv::ManagerPrefix)
+  if (i == m_wire.elements_end())
     throw Error("Missing Manager Prefix");
+  if (i->type() != tlv::ManagerPrefix)
+    throw Error("Expect Manager Prefix but get TLV Type " + std::to_string(i->type()));
   m_manager.wireDecode(i->blockFromValue());
   ++i;
 
   // Participants
-  if (i == m_wire.elements_end() || i->type() != tlv::Participants)
+  if (i == m_wire.elements_end())
     throw Error("Missing Participant");
+  if (i->type() != tlv::Participants)
+    throw Error("Expect Participant but get TLV Type " + std::to_string(i->type()));
 
   Block temp = *i;
   temp.parse();
@@ -178,7 +192,7 @@
     throw Error("Unexpected element");
 
   if (m_participants.empty())
-    throw Error("Missing Participant");
+    throw Error("No participant in the chatroom");
 
   ++i;
 
diff --git a/src/chatroom-info.hpp b/src/chatroom-info.hpp
index 80b076b..ac0d602 100644
--- a/src/chatroom-info.hpp
+++ b/src/chatroom-info.hpp
@@ -7,20 +7,17 @@
  *
  * Author: Mengjin Yan <jane.yan0129@gmail.com>
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * Author: Qiuhan Ding <qiuhanding@cs.ucla.edu>
  */
 #ifndef CHRONOCHAT_CHATROOM_INFO_HPP
 #define CHRONOCHAT_CHATROOM_INFO_HPP
 
 #include "common.hpp"
-#include "chatroom-tlv.hpp"
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/security/key-chain.hpp>
+#include "tlv.hpp"
 #include <ndn-cxx/name-component.hpp>
-#include <ndn-cxx/util/time.hpp>
 #include <ndn-cxx/util/concepts.hpp>
 #include <ndn-cxx/encoding/block.hpp>
 #include <ndn-cxx/encoding/encoding-buffer.hpp>
-#include <ndn-cxx/exclude.hpp>
 #include <boost/concept_check.hpp>
 #include <list>
 
@@ -143,10 +140,6 @@
   return m_participants;
 }
 
-BOOST_CONCEPT_ASSERT((ndn::WireEncodable<ChatroomInfo>));
-BOOST_CONCEPT_ASSERT((ndn::WireDecodable<ChatroomInfo>));
-
-
 } // namespace chronochat
 
 #endif // CHRONOCHAT_CHATROOM_INFO_HPP
diff --git a/src/chatroom-tlv.hpp b/src/chatroom-tlv.hpp
deleted file mode 100644
index be02217..0000000
--- a/src/chatroom-tlv.hpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef CHRONOCHAT_CHATROOM_TLV_HPP
-#define CHRONOCHAT_CHATROOM_TLV_HPP
-
-namespace chronochat {
-
-namespace tlv {
-
-enum {
-  ChatroomInfo = 128,
-  ChatroomName = 129,
-  TrustModel = 130,
-  ChatroomPrefix = 131,
-  ManagerPrefix = 132,
-  Participants = 133,
-};
-
-} // namespace tlv
-
-} // namespace chronochat
-
-#endif // CHRONOCHAT_CHATROOM_TLV_HPP
diff --git a/src/conf.cpp b/src/conf.cpp
new file mode 100644
index 0000000..fba36b8
--- /dev/null
+++ b/src/conf.cpp
@@ -0,0 +1,123 @@
+/* -*- 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: Qiuhan Ding <qiuhanding@cs.ucla.edu>
+ */
+
+#include "conf.hpp"
+
+namespace chronochat {
+
+BOOST_CONCEPT_ASSERT((ndn::WireEncodable<Conf>));
+BOOST_CONCEPT_ASSERT((ndn::WireDecodable<Conf>));
+
+Conf::Conf()
+{
+}
+
+Conf::Conf(const Block& confWire)
+{
+  this->wireDecode(confWire);
+}
+
+template<bool T>
+size_t
+Conf::wireEncode(ndn::EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  // Conf := CONF-TYPE TLV-LENGTH
+  //           Name
+  //           Nick
+  //
+  // Nick := NICK-TYPE TLV-LENGTH
+  //            String
+
+  // Nick
+  const uint8_t* nickWire = reinterpret_cast<const uint8_t*>(m_nick.c_str());
+  totalLength += block.prependByteArrayBlock(tlv::Nick, nickWire, m_nick.length());
+
+  // Identity
+  totalLength += m_identity.wireEncode(block);
+
+  // Conf
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::Conf);
+
+  return totalLength;
+}
+
+const Block&
+Conf::wireEncode() const
+{
+  ndn::EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  ndn::EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  m_wire.parse();
+
+  return m_wire;
+}
+
+void
+Conf::wireDecode(const Block& confWire)
+{
+  m_wire = confWire;
+  m_wire.parse();
+
+  // Conf := CONF-TYPE TLV-LENGTH
+  //           Name
+  //           Nick
+  //
+  // Nick := NICK-TYPE TLV-LENGTH
+  //            String
+
+  if (m_wire.type() != tlv::Conf)
+    throw Error("Unexpected TLV number when decoding conf packet");
+
+  // Identity
+  Block::element_const_iterator i = m_wire.elements_begin();
+  if (i == m_wire.elements_end())
+    throw Error("Missing Identity");
+  if (i->type() != tlv::Name)
+    throw Error("Expect Identity but get TLV Type " + std::to_string(i->type()));
+
+  m_identity.wireDecode(*i);
+  ++i;
+
+  // Nick
+  if (i == m_wire.elements_end())
+    return;
+  if (i->type() != tlv::Nick)
+    throw Error("Expect Nick but get TLV Type " + std::to_string(i->type()));
+
+  m_nick = std::string(reinterpret_cast<const char* >(i->value()),
+                       i->value_size());
+  ++i;
+
+  if (i != m_wire.elements_end()) {
+    throw Error("Unexpected element");
+  }
+}
+
+void
+Conf::setIdentity(const Name& identity)
+{
+  m_wire.reset();
+  m_identity = identity;
+}
+
+void
+Conf::setNick(const std::string& nick)
+{
+  m_wire.reset();
+  m_nick = nick;
+}
+
+} // namespace chronochat
diff --git a/src/conf.hpp b/src/conf.hpp
new file mode 100644
index 0000000..0626bf1
--- /dev/null
+++ b/src/conf.hpp
@@ -0,0 +1,87 @@
+/* -*- 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: Qiuhan Ding <qiuhanding@cs.ucla.edu>
+ */
+
+#ifndef CHRONOCHAT_CONFIG_HPP
+#define CHRONOCHAT_CONFIG_HPP
+
+#include "common.hpp"
+#include "tlv.hpp"
+#include <ndn-cxx/util/concepts.hpp>
+#include <ndn-cxx/encoding/block.hpp>
+#include <ndn-cxx/encoding/encoding-buffer.hpp>
+#include <list>
+
+namespace chronochat {
+
+class Conf
+{
+
+public:
+
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+
+  Conf();
+
+  explicit
+  Conf(const Block& confWire);
+
+  const Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const Block& confWire);
+
+  const Name&
+  getIdentity() const;
+
+  const std::string&
+  getNick() const;
+
+  void
+  setIdentity(const Name& identity);
+
+  void
+  setNick(const std::string& nick);
+
+private:
+  template<bool T>
+  size_t
+  wireEncode(ndn::EncodingImpl<T>& block) const;
+
+private:
+  mutable Block m_wire;
+  Name m_identity;
+  std::string m_nick;
+};
+
+inline const Name&
+Conf::getIdentity() const
+{
+  return m_identity;
+}
+
+inline const std::string&
+Conf::getNick() const
+{
+  return m_nick;
+}
+
+} // namespace chronochat
+
+#endif //CHRONOCHAT_CONF_HPP
diff --git a/src/config.proto b/src/config.proto
deleted file mode 100644
index 59cd8cc..0000000
--- a/src/config.proto
+++ /dev/null
@@ -1,6 +0,0 @@
-package ChronoChat;
-
-message Conf {
-  required string identity = 1;
-  optional string nick = 2;
-}
\ No newline at end of file
diff --git a/src/contact-manager.cpp b/src/contact-manager.cpp
index e377d4a..b98c40a 100644
--- a/src/contact-manager.cpp
+++ b/src/contact-manager.cpp
@@ -6,6 +6,7 @@
  * BSD license, See the LICENSE file for more information
  *
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ *         Qiuhan Ding <qiuhanding@cs.ucla.edu>
  */
 
 #if __clang__
@@ -156,15 +157,15 @@
 }
 
 void
-ContactManager::fetchEndorseCertificateInternal(const Name& identity, int certIndex)
+ContactManager::fetchEndorseCertificateInternal(const Name& identity, size_t certIndex)
 {
   shared_ptr<EndorseCollection> endorseCollection =
     m_bufferedContacts[identity].m_endorseCollection;
 
-  if(certIndex >= endorseCollection->endorsement_size())
+  if(certIndex >= endorseCollection->getCollectionEntries().size())
     prepareEndorseInfo(identity);
 
-  Name interestName(endorseCollection->endorsement(certIndex).certname());
+  Name interestName(endorseCollection->getCollectionEntries()[certIndex].certName);
 
   Interest interest(interestName);
   interest.setInterestLifetime(time::milliseconds(1000));
@@ -173,7 +174,7 @@
   m_face.expressInterest(interest,
                          bind(&ContactManager::onEndorseCertificateInternal,
                               this, _1, _2, identity, certIndex,
-                              endorseCollection->endorsement(certIndex).hash()),
+                              endorseCollection->getCollectionEntries()[certIndex].hash),
                          bind(&ContactManager::onEndorseCertificateInternalTimeout,
                               this, _1, identity, certIndex));
 }
@@ -184,16 +185,16 @@
   // _LOG_DEBUG("prepareEndorseInfo");
   const Profile& profile = m_bufferedContacts[identity].m_selfEndorseCert->getProfile();
 
-  shared_ptr<chronochat::EndorseInfo> endorseInfo = make_shared<chronochat::EndorseInfo>();
+  shared_ptr<EndorseInfo> endorseInfo = make_shared<EndorseInfo>();
   m_bufferedContacts[identity].m_endorseInfo = endorseInfo;
 
-  map<string, int> endorseCount;
+  map<string, size_t> endorseCount;
   for (Profile::const_iterator pIt = profile.begin(); pIt != profile.end(); pIt++) {
     // _LOG_DEBUG("prepareEndorseInfo: profile[" << pIt->first << "]: " << pIt->second);
     endorseCount[pIt->first] = 0;
   }
 
-  int endorseCertCount = 0;
+  size_t endorseCertCount = 0;
 
   vector<shared_ptr<EndorseCertificate> >::const_iterator cIt =
     m_bufferedContacts[identity].m_endorseCertList.begin();
@@ -222,12 +223,9 @@
   }
 
   for (Profile::const_iterator pIt = profile.begin(); pIt != profile.end(); pIt++) {
-    chronochat::EndorseInfo::Endorsement* endorsement = endorseInfo->add_endorsement();
-    endorsement->set_type(pIt->first);
-    endorsement->set_value(pIt->second);
     std::stringstream ss;
     ss << endorseCount[pIt->first] << "/" << endorseCertCount;
-    endorsement->set_endorse(ss.str());
+    endorseInfo->addEndorsement(pIt->first, pIt->second, ss.str());
   }
 
   emit contactEndorseInfoReady (*endorseInfo);
@@ -283,14 +281,15 @@
 ContactManager::onDnsCollectEndorseValidated(const shared_ptr<const Data>& data,
                                              const Name& identity)
 {
-  shared_ptr<EndorseCollection> endorseCollection = make_shared<EndorseCollection>();
-  if (!endorseCollection->ParseFromArray(data->getContent().value(),
-                                         data->getContent().value_size())) {
+  try {
+    shared_ptr<EndorseCollection> endorseCollection =
+      make_shared<EndorseCollection>(data->getContent());
     m_bufferedContacts[identity].m_endorseCollection = endorseCollection;
     fetchEndorseCertificateInternal(identity, 0);
   }
-  else
+  catch (tlv::Error) {
     prepareEndorseInfo(identity);
+  }
 }
 
 void
@@ -310,7 +309,8 @@
 
 void
 ContactManager::onEndorseCertificateInternal(const Interest& interest, Data& data,
-                                             const Name& identity, int certIndex, string hash)
+                                             const Name& identity, size_t certIndex,
+                                             string hash)
 {
   std::stringstream ss;
   {
@@ -333,7 +333,7 @@
 void
 ContactManager::onEndorseCertificateInternalTimeout(const Interest& interest,
                                                     const Name& identity,
-                                                    int certIndex)
+                                                    size_t certIndex)
 {
   fetchEndorseCertificateInternal(identity, certIndex+1);
 }
@@ -390,7 +390,7 @@
 void
 ContactManager::decreaseCollectStatus()
 {
-  int count;
+  size_t count;
   {
     boost::recursive_mutex::scoped_lock lock(m_collectCountMutex);
     m_collectCount--;
@@ -413,10 +413,7 @@
   EndorseCollection endorseCollection;
   m_contactStorage->getCollectEndorse(endorseCollection);
 
-  OBufferStream os;
-  endorseCollection.SerializeToOstream(&os);
-
-  data->setContent(os.buf());
+  data->setContent(endorseCollection.wireEncode());
   m_keyChain.signByIdentity(*data, m_identity);
 
   m_contactStorage->updateDnsOthersEndorse(*data);
@@ -449,7 +446,7 @@
 void
 ContactManager::decreaseIdCertCount()
 {
-  int count;
+  size_t count;
   {
     boost::recursive_mutex::scoped_lock lock(m_idCertCountMutex);
     m_idCertCount--;
@@ -753,7 +750,7 @@
     std::stringstream response_stream(line1);
     string http_version;
     response_stream >> http_version;
-    unsigned int status_code;
+    size_t status_code;
     response_stream >> status_code;
     string status_message;
     std::getline(response_stream,status_message);
diff --git a/src/contact-manager.hpp b/src/contact-manager.hpp
index 635f5a1..5ef7983 100644
--- a/src/contact-manager.hpp
+++ b/src/contact-manager.hpp
@@ -6,6 +6,7 @@
  * BSD license, See the LICENSE file for more information
  *
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ *         Qiuhan Ding <qiuhanding@cs.ucla.edu>
  */
 
 #ifndef CHRONOCHAT_CONTACT_MANAGER_HPP
@@ -18,8 +19,8 @@
 #include "contact-storage.hpp"
 #include "endorse-certificate.hpp"
 #include "profile.hpp"
-#include "endorse-info.pb.h"
-#include "endorse-collection.pb.h"
+#include "endorse-info.hpp"
+#include "endorse-collection.hpp"
 #include <ndn-cxx/security/key-chain.hpp>
 #include <ndn-cxx/security/validator.hpp>
 #include <boost/thread/locks.hpp>
@@ -63,7 +64,7 @@
   fetchCollectEndorse(const Name& identity);
 
   void
-  fetchEndorseCertificateInternal(const Name& identity, int certIndex);
+  fetchEndorseCertificateInternal(const Name& identity, size_t certIndex);
 
   void
   prepareEndorseInfo(const Name& identity);
@@ -97,12 +98,13 @@
   // PROFILE-CERT: endorse-certificate
   void
   onEndorseCertificateInternal(const Interest& interest, Data& data,
-                               const Name& identity, int certIndex, std::string hash);
+                               const Name& identity, size_t certIndex,
+                               std::string hash);
 
   void
   onEndorseCertificateInternalTimeout(const Interest& interest,
                                       const Name& identity,
-                                      int certIndex);
+                                      size_t certIndex);
 
   // Collect endorsement
   void
@@ -181,7 +183,7 @@
 
 signals:
   void
-  contactEndorseInfoReady(const chronochat::EndorseInfo& endorseInfo);
+  contactEndorseInfoReady(const EndorseInfo& endorseInfo);
 
   void
   contactInfoFetchFailed(const QString& identity);
@@ -257,7 +259,7 @@
     shared_ptr<EndorseCertificate> m_selfEndorseCert;
     shared_ptr<EndorseCollection> m_endorseCollection;
     std::vector<shared_ptr<EndorseCertificate> > m_endorseCertList;
-    shared_ptr<chronochat::EndorseInfo> m_endorseInfo;
+    shared_ptr<EndorseInfo> m_endorseInfo;
   };
 
   typedef std::map<Name, FetchedInfo> BufferedContacts;
@@ -282,10 +284,10 @@
   const ndn::RegisteredPrefixId* m_dnsListenerId;
 
   RecLock m_collectCountMutex;
-  int m_collectCount;
+  size_t m_collectCount;
 
   RecLock m_idCertCountMutex;
-  int m_idCertCount;
+  size_t m_idCertCount;
 };
 
 } // namespace chronochat
diff --git a/src/contact-storage.cpp b/src/contact-storage.cpp
index bc91ac6..d59a707 100644
--- a/src/contact-storage.cpp
+++ b/src/contact-storage.cpp
@@ -6,6 +6,7 @@
  * BSD license, See the LICENSE file for more information
  *
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * Author: Qiuhan Ding <qiuhanding@cs.ucla.edu>
  */
 
 #include "contact-storage.hpp"
@@ -15,7 +16,7 @@
 #include "logging.h"
 
 
-// INIT_LOGGER ("chronos.ContactStorage");
+// INIT_LOGGER ("chronochat.ContactStorage");
 
 namespace chronochat {
 
@@ -308,9 +309,7 @@
       StringSource(sqlite3_column_text(stmt, 1), sqlite3_column_bytes (stmt, 1), true,
                    new HashFilter(hash, new FileSink(ss)));
     }
-    EndorseCollection::Endorsement* endorsement = endorseCollection.add_endorsement();
-    endorsement->set_certname(certName);
-    endorsement->set_hash(ss.str());
+    endorseCollection.addCollectionEntry(Name(certName), ss.str());
   }
 
   sqlite3_finalize(stmt);
diff --git a/src/contact-storage.hpp b/src/contact-storage.hpp
index 833c7d6..aa137b4 100644
--- a/src/contact-storage.hpp
+++ b/src/contact-storage.hpp
@@ -6,13 +6,14 @@
  * BSD license, See the LICENSE file for more information
  *
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ *         Qiuhan Ding <qiuhanding@cs.ucla.edu>
  */
 
 #ifndef CHRONOCHAT_CONTACT_STORAGE_HPP
 #define CHRONOCHAT_CONTACT_STORAGE_HPP
 
 #include "contact.hpp"
-#include "endorse-collection.pb.h"
+#include "endorse-collection.hpp"
 #include <sqlite3.h>
 
 namespace chronochat {
diff --git a/src/controller.cpp b/src/controller.cpp
index 6121f2b..dd2392c 100644
--- a/src/controller.cpp
+++ b/src/controller.cpp
@@ -20,9 +20,9 @@
 #include <boost/lexical_cast.hpp>
 #include <ndn-cxx/util/random.hpp>
 #include "cryptopp.hpp"
-#include "config.pb.h"
-#include "endorse-info.pb.h"
 #include "logging.h"
+#include "conf.hpp"
+#include "endorse-info.hpp"
 #endif
 
 INIT_LOGGER("chronochat.Controller");
@@ -111,9 +111,9 @@
   connect(m_addContactPanel, SIGNAL(addContact(const QString&)),
           m_backend.getContactManager(), SLOT(onAddFetchedContact(const QString&)));
   connect(m_backend.getContactManager(),
-          SIGNAL(contactEndorseInfoReady(const chronochat::EndorseInfo&)),
+          SIGNAL(contactEndorseInfoReady(const EndorseInfo&)),
           m_addContactPanel,
-          SLOT(onContactEndorseInfoReady(const chronochat::EndorseInfo&)));
+          SLOT(onContactEndorseInfoReady(const EndorseInfo&)));
 
   // Connection to BrowseContactDialog
   connect(m_browseContactDialog, SIGNAL(directAddClicked()),
@@ -310,12 +310,21 @@
   fs::create_directories (chronosDir);
 
   std::ifstream is((chronosDir / "config").c_str ());
-  ChronoChat::Conf conf;
-  if (conf.ParseFromIstream(&is)) {
+  Conf conf;
+  bool hasConfig = true;
+  Block confBlock;
+  try {
+    confBlock = ndn::Block::fromStream(is);
+  }
+  catch (tlv::Error) {
+    hasConfig = false;
+  }
+  if (hasConfig) {
+    conf.wireDecode(confBlock);
     m_identity.clear();
-    m_identity.append(conf.identity());
-    if (conf.has_nick())
-      m_nick = conf.nick();
+    m_identity.append(conf.getIdentity());
+    if (conf.getNick().length() != 0)
+      m_nick = conf.getNick();
     else
       m_nick = m_identity.get(-1).toUri();
   }
@@ -338,11 +347,12 @@
   fs::create_directories (chronosDir);
 
   std::ofstream os((chronosDir / "config").c_str ());
-  ChronoChat::Conf conf;
-  conf.set_identity(m_identity.toUri());
+  Conf conf;
+  conf.setIdentity(m_identity);
   if (!m_nick.empty())
-    conf.set_nick(m_nick);
-  conf.SerializeToOstream(&os);
+    conf.setNick(m_nick);
+  Block confWire = conf.wireEncode();
+  os.write(reinterpret_cast<const char*>(confWire.wire()), confWire.size());
 
   os.close();
 }
diff --git a/src/endorse-certificate.cpp b/src/endorse-certificate.cpp
index b72d57e..cbeb18c 100644
--- a/src/endorse-certificate.cpp
+++ b/src/endorse-certificate.cpp
@@ -6,12 +6,14 @@
  * BSD license, See the LICENSE file for more information
  *
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ *         Qiuhan Ding <qiuhanding@cs.ucla.edu>
  */
 
 #include "endorse-certificate.hpp"
-#include "endorse-extension.pb.h"
 #include <boost/iostreams/stream.hpp>
 #include <ndn-cxx/encoding/buffer-stream.hpp>
+#include "endorse-extension.hpp"
+#include <list>
 
 namespace chronochat {
 
@@ -30,20 +32,21 @@
 
 const vector<string> EndorseCertificate::DEFAULT_ENDORSE_LIST;
 
-chronochat::EndorseExtensionMsg&
-operator<<(chronochat::EndorseExtensionMsg& endorseExtension, const vector<string>& endorseList)
+EndorseExtension&
+operator<<(EndorseExtension& endorseExtension, const vector<string>& endorseList)
 {
-  for (vector<string>::const_iterator it = endorseList.begin(); it != endorseList.end(); it++)
-    endorseExtension.add_endorseentry()->set_name(*it);
+  for (const auto& entry : endorseList)
+    endorseExtension.addEntry(entry);
 
   return endorseExtension;
 }
 
-chronochat::EndorseExtensionMsg&
-operator>>(chronochat::EndorseExtensionMsg& endorseExtension, vector<string>& endorseList)
+EndorseExtension&
+operator>>(EndorseExtension& endorseExtension, vector<string>& endorseList)
 {
-  for (int i = 0; i < endorseExtension.endorseentry_size(); i ++)
-    endorseList.push_back(endorseExtension.endorseentry(i).name());
+  const std::list<string>& endorseEntries = endorseExtension.getEntries();
+  for (const auto& entry: endorseEntries)
+    endorseList.push_back(entry);
 
   return endorseExtension;
 }
@@ -67,15 +70,15 @@
   addSubjectDescription(CertificateSubjectDescription(OID("2.5.4.41"), m_keyName.toUri()));
   setPublicKeyInfo(kskCertificate.getPublicKeyInfo());
 
-  OBufferStream profileStream;
-  m_profile.encode(profileStream);
-  addExtension(CertificateExtension(PROFILE_EXT_OID, true, *profileStream.buf()));
+  Block profileWire = m_profile.wireEncode();
+  addExtension(CertificateExtension(PROFILE_EXT_OID, true, ndn::Buffer(profileWire.wire(),
+                                                                       profileWire.size())));
 
-  OBufferStream endorseStream;
-  chronochat::EndorseExtensionMsg endorseExtension;
+  EndorseExtension endorseExtension;
   endorseExtension << m_endorseList;
-  endorseExtension.SerializeToOstream(&endorseStream);
-  addExtension(CertificateExtension(ENDORSE_EXT_OID, true, *endorseStream.buf()));
+  Block endorseWire = endorseExtension.wireEncode();
+  addExtension(CertificateExtension(ENDORSE_EXT_OID, true, ndn::Buffer(endorseWire.wire(),
+                                                                       endorseWire.size())));
 
   encode();
 }
@@ -98,15 +101,15 @@
   addSubjectDescription(CertificateSubjectDescription(OID("2.5.4.41"), m_keyName.toUri()));
   setPublicKeyInfo(endorseCertificate.getPublicKeyInfo());
 
-  OBufferStream profileStream;
-  m_profile.encode(profileStream);
-  addExtension(CertificateExtension(PROFILE_EXT_OID, true, *profileStream.buf()));
+  Block profileWire = m_profile.wireEncode();
+  addExtension(CertificateExtension(PROFILE_EXT_OID, true, ndn::Buffer(profileWire.wire(),
+                                                                       profileWire.size())));
 
-  OBufferStream endorseStream;
-  chronochat::EndorseExtensionMsg endorseExtension;
+  EndorseExtension endorseExtension;
   endorseExtension << m_endorseList;
-  endorseExtension.SerializeToOstream(&endorseStream);
-  addExtension(CertificateExtension(ENDORSE_EXT_OID, true, *endorseStream.buf()));
+  Block endorseWire = endorseExtension.wireEncode();
+  addExtension(CertificateExtension(ENDORSE_EXT_OID, true, ndn::Buffer(endorseWire.wire(),
+                                                                       endorseWire.size())));
 
   encode();
 }
@@ -133,15 +136,15 @@
   addSubjectDescription(CertificateSubjectDescription(OID("2.5.4.41"), m_keyName.toUri()));
   setPublicKeyInfo(key);
 
-  OBufferStream profileStream;
-  m_profile.encode(profileStream);
-  addExtension(CertificateExtension(PROFILE_EXT_OID, true, *profileStream.buf()));
+  Block profileWire = m_profile.wireEncode();
+  addExtension(CertificateExtension(PROFILE_EXT_OID, true, ndn::Buffer(profileWire.wire(),
+                                                                       profileWire.size())));
 
-  OBufferStream endorseStream;
-  chronochat::EndorseExtensionMsg endorseExtension;
+  EndorseExtension endorseExtension;
   endorseExtension << m_endorseList;
-  endorseExtension.SerializeToOstream(&endorseStream);
-  addExtension(CertificateExtension(ENDORSE_EXT_OID, true, *endorseStream.buf()));
+  Block endorseWire = endorseExtension.wireEncode();
+  addExtension(CertificateExtension(ENDORSE_EXT_OID, true, ndn::Buffer(endorseWire.wire(),
+                                                                       endorseWire.size())));
 
   encode();
 }
@@ -167,18 +170,13 @@
   m_signer.wireDecode(dataName.get(-2).blockFromValue());
 
 
-  for (ExtensionList::iterator it = m_extensionList.begin() ; it != m_extensionList.end(); it++) {
-    if (PROFILE_EXT_OID == it->getOid()) {
-      boost::iostreams::stream<boost::iostreams::array_source> is
-        (reinterpret_cast<const char*>(it->getValue().buf()), it->getValue().size());
-      m_profile.decode(is);
+  for (const auto& entry : m_extensionList) {
+    if (PROFILE_EXT_OID == entry.getOid()) {
+      m_profile.wireDecode(Block(entry.getValue().buf(), entry.getValue().size()));
     }
-    if (ENDORSE_EXT_OID == it->getOid()) {
-      chronochat::EndorseExtensionMsg endorseExtension;
-
-      boost::iostreams::stream<boost::iostreams::array_source> is
-        (reinterpret_cast<const char*>(it->getValue().buf()), it->getValue().size());
-      endorseExtension.ParseFromIstream(&is);
+    if (ENDORSE_EXT_OID == entry.getOid()) {
+      EndorseExtension endorseExtension;
+      endorseExtension.wireDecode(Block(entry.getValue().buf(), entry.getValue().size()));
 
       endorseExtension >> m_endorseList;
     }
diff --git a/src/endorse-certificate.hpp b/src/endorse-certificate.hpp
index d215a22..51b3b50 100644
--- a/src/endorse-certificate.hpp
+++ b/src/endorse-certificate.hpp
@@ -6,6 +6,7 @@
  * BSD license, See the LICENSE file for more information
  *
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ *         Qiuhan Ding <qiuhanding@cs.ucla.edu>
  */
 
 #ifndef CHRONOCHAT_ENDORSE_CERTIFICATE_HPP
diff --git a/src/endorse-collection.cpp b/src/endorse-collection.cpp
new file mode 100644
index 0000000..c8dafe6
--- /dev/null
+++ b/src/endorse-collection.cpp
@@ -0,0 +1,138 @@
+/* -*- 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: Qiuhan Ding <qiuhanding@cs.ucla.edu>
+ */
+
+#include "endorse-collection.hpp"
+
+namespace chronochat {
+
+BOOST_CONCEPT_ASSERT((ndn::WireEncodable<EndorseCollection>));
+BOOST_CONCEPT_ASSERT((ndn::WireDecodable<EndorseCollection>));
+
+EndorseCollection::EndorseCollection()
+{
+}
+
+EndorseCollection::EndorseCollection(const Block& endorseWire)
+{
+  this->wireDecode(endorseWire);
+}
+
+template<bool T>
+size_t
+EndorseCollection::wireEncode(ndn::EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  // EndorseCollection := ENDORSE-COLLECTION-TYPE TLV-LENGTH
+  //                        EndorseCollectionEntry+
+  //
+  // EndorseCollectionEntry := ENDORSE-COLLECTION-ENTRY-TYPE TLV-LENGTH
+  //                             Name
+  //                             Hash
+  //
+  // Hash := HASH-TYPE TLV-LENGTH
+  //           String
+
+  // Entries
+  size_t entryLength = 0;
+  for (std::vector<CollectionEntry>::const_reverse_iterator it = m_entries.rbegin();
+       it != m_entries.rend(); it++) {
+    // Hash
+    const uint8_t* dataWire = reinterpret_cast<const uint8_t*>(it->hash.c_str());
+    entryLength += block.prependByteArrayBlock(tlv::Hash, dataWire, it->hash.length());
+    // CertName
+    entryLength += it->certName.wireEncode(block);
+    // Entry
+    entryLength += block.prependVarNumber(entryLength);
+    entryLength += block.prependVarNumber(tlv::EndorseCollectionEntry);
+    totalLength += entryLength;
+    entryLength = 0;
+  }
+
+  // Profile
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::EndorseCollection);
+
+  return totalLength;
+
+}
+
+const Block&
+EndorseCollection::wireEncode() const
+{
+  ndn::EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  ndn::EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  m_wire.parse();
+
+  return m_wire;
+}
+
+void
+EndorseCollection::wireDecode(const Block& endorseWire)
+{
+  m_wire = endorseWire;
+  m_wire.parse();
+  m_entries.clear();
+
+  if (m_wire.type() != tlv::EndorseCollection)
+    throw Error("Unexpected TLV number when decoding endorse collection packet");
+
+  Block::element_const_iterator i = m_wire.elements_begin();
+  if (i == m_wire.elements_end())
+    throw Error("Missing Endorse Collection Entry");
+  if (i->type() != tlv::EndorseCollectionEntry)
+    throw Error("Expect Endorse Collection Entry but get TLV Type " + std::to_string(i->type()));
+
+  while (i != m_wire.elements_end() && i->type() == tlv::EndorseCollectionEntry) {
+    CollectionEntry entry;
+    Block temp = *i;
+    temp.parse();
+    Block::element_const_iterator j = temp.elements_begin();
+    if (j == temp.elements_end())
+      throw Error("Missing Cert Name");
+    if (j->type() != tlv::Name)
+      throw Error("Expect Cert Name but get TLV Type " + std::to_string(j->type()));
+
+    entry.certName.wireDecode(*j);
+
+    ++j;
+    if (j == temp.elements_end())
+      throw Error("Missing Hash");
+    if (j->type() != tlv::Hash)
+      throw Error("Expect Hash but get TLV Type " + std::to_string(j->type()));
+
+    entry.hash = std::string(reinterpret_cast<const char* >(j->value()),
+                             j->value_size());
+    ++j;
+    if (j != temp.elements_end()) {
+      throw Error("Unexpected element");
+    }
+    m_entries.push_back(entry);
+    ++i;
+  }
+
+  if (i != m_wire.elements_end()) {
+      throw Error("Unexpected element");
+  }
+}
+
+void
+EndorseCollection::addCollectionEntry(const Name& certName, const std::string& hash) {
+  CollectionEntry entry;
+  entry.certName = certName;
+  entry.hash = hash;
+  m_entries.push_back(entry);
+}
+
+} // namespace chronochat
diff --git a/src/endorse-collection.hpp b/src/endorse-collection.hpp
new file mode 100644
index 0000000..42a0979
--- /dev/null
+++ b/src/endorse-collection.hpp
@@ -0,0 +1,80 @@
+/* -*- 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: Qiuhan Ding <qiuhanding@cs.ucla.edu>
+ */
+
+#ifndef CHRONOCHAT_ENDORSE_COLLECTION_HPP
+#define CHRONOCHAT_ENDORSE_COLLECTION_HPP
+
+#include "common.hpp"
+#include "tlv.hpp"
+#include <ndn-cxx/util/concepts.hpp>
+#include <ndn-cxx/encoding/block.hpp>
+#include <ndn-cxx/encoding/encoding-buffer.hpp>
+
+namespace chronochat {
+
+class EndorseCollection
+{
+
+public:
+
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  class CollectionEntry
+  {
+  public:
+    Name certName;
+    std::string hash;
+  };
+
+public:
+
+  EndorseCollection();
+
+  explicit
+  EndorseCollection(const Block& endorseWire);
+
+  const Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const Block& endorseWire);
+
+  const std::vector<CollectionEntry>&
+  getCollectionEntries() const;
+
+  void
+  addCollectionEntry(const Name& certName, const std::string& hash);
+
+private:
+  template<bool T>
+  size_t
+  wireEncode(ndn::EncodingImpl<T>& block) const;
+
+private:
+  mutable Block m_wire;
+  std::vector<CollectionEntry> m_entries;
+};
+
+inline const std::vector<EndorseCollection::CollectionEntry>&
+EndorseCollection::getCollectionEntries() const
+{
+  return m_entries;
+}
+
+} // namespace chronochat
+
+#endif //CHRONOCHAT_ENDORSE_COLLECTION_HPP
diff --git a/src/endorse-collection.proto b/src/endorse-collection.proto
deleted file mode 100644
index f989516..0000000
--- a/src/endorse-collection.proto
+++ /dev/null
@@ -1,11 +0,0 @@
-package chronochat;
-
-message EndorseCollection
-{
-  message Endorsement
-  {
-    required string certname = 1;
-    required string hash     = 2;
-  }
-  repeated Endorsement endorsement = 1;
-}
\ No newline at end of file
diff --git a/src/endorse-extension.cpp b/src/endorse-extension.cpp
new file mode 100644
index 0000000..ac862ac
--- /dev/null
+++ b/src/endorse-extension.cpp
@@ -0,0 +1,116 @@
+/* -*- 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: Qiuhan Ding <qiuhanding@cs.ucla.edu>
+ */
+
+#include "endorse-extension.hpp"
+
+namespace chronochat {
+
+BOOST_CONCEPT_ASSERT((ndn::WireEncodable<EndorseExtension>));
+BOOST_CONCEPT_ASSERT((ndn::WireDecodable<EndorseExtension>));
+
+EndorseExtension::EndorseExtension()
+{
+}
+
+EndorseExtension::EndorseExtension(const Block& endorseWire)
+{
+  this->wireDecode(endorseWire);
+}
+
+template<bool T>
+size_t
+EndorseExtension::wireEncode(ndn::EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  // EndorseExtension := ENDORSE-EXTENSION-TYPE TLV-LENGTH
+  //                       EntryData+
+  //
+  // EntryData := ENTRYDATA-TYPE TLV-LENGTH
+  //                String
+  //
+
+  // EntryData
+  for (std::list<std::string>::const_reverse_iterator it = m_entries.rbegin();
+       it != m_entries.rend(); it++) {
+    const uint8_t *entryWire = reinterpret_cast<const uint8_t*>(it->c_str());
+    totalLength += block.prependByteArrayBlock(tlv::EntryData, entryWire, it->length());
+  }
+
+  // EndorseExtension
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::EndorseExtension);
+
+  return totalLength;
+}
+
+const Block&
+EndorseExtension::wireEncode() const
+{
+  ndn::EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  ndn::EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  m_wire.parse();
+
+  return m_wire;
+}
+
+void
+EndorseExtension::wireDecode(const Block& endorseWire)
+{
+  m_wire = endorseWire;
+  m_wire.parse();
+
+  // EndorseExtension := ENDORSE-EXTENSION-TYPE TLV-LENGTH
+  //                       EntryData+
+  //
+  // EntryData := ENTRYDATA-TYPE TLV-LENGTH
+  //                String
+  //
+
+  if (m_wire.type() != tlv::EndorseExtension)
+    throw Error("Unexpected TLV number when decoding endorse extension packet");
+
+  // EntryData
+  Block::element_const_iterator i = m_wire.elements_begin();
+  if (i == m_wire.elements_end())
+    throw Error("Missing Entry Data");
+  if (i->type() != tlv::EntryData)
+    throw Error("Expect Entry Data but get TLV Type " + std::to_string(i->type()));
+
+   while (i != m_wire.elements_end() && i->type() == tlv::EntryData) {
+     m_entries.push_back(std::string(reinterpret_cast<const char* >(i->value()),
+                                     i->value_size()));
+     ++i;
+  }
+
+  if (i != m_wire.elements_end()) {
+    throw Error("Unexpected element");
+  }
+}
+
+void
+EndorseExtension::addEntry(const std::string& entry)
+{
+  if (find(m_entries.begin(), m_entries.end(), entry) == m_entries.end()) {
+    m_entries.push_back(entry);
+  }
+}
+
+void
+EndorseExtension::removeEntry(const std::string& entry)
+{
+  m_entries.remove(entry);
+}
+
+} // namespace chronochat
diff --git a/src/endorse-extension.hpp b/src/endorse-extension.hpp
new file mode 100644
index 0000000..844c55c
--- /dev/null
+++ b/src/endorse-extension.hpp
@@ -0,0 +1,78 @@
+/* -*- 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: Qiuhan Ding <qiuhanding@cs.ucla.edu>
+ */
+
+#ifndef CHRONOCHAT_ENDORSE_EXTENSION_HPP
+#define CHRONOCHAT_ENDORSE_EXTENSION_HPP
+
+#include "common.hpp"
+#include "tlv.hpp"
+#include <ndn-cxx/util/concepts.hpp>
+#include <ndn-cxx/encoding/block.hpp>
+#include <ndn-cxx/encoding/encoding-buffer.hpp>
+#include <list>
+
+namespace chronochat {
+
+class EndorseExtension
+{
+
+public:
+
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+
+  EndorseExtension();
+
+  explicit
+  EndorseExtension(const Block& endorseWire);
+
+  const Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const Block& endorseWire);
+
+  const std::list<std::string>&
+  getEntries() const;
+
+  void
+  addEntry(const std::string& entry);
+
+  void
+  removeEntry(const std::string& entry);
+
+private:
+  template<bool T>
+  size_t
+  wireEncode(ndn::EncodingImpl<T>& block) const;
+
+private:
+  mutable Block m_wire;
+  std::list<std::string> m_entries;
+};
+
+inline const std::list<std::string>&
+EndorseExtension::getEntries() const
+{
+  return m_entries;
+}
+
+
+} // namespace chronochat
+
+#endif //CHRONOCHAT_ENDORSE_EXTENSION_HPP
diff --git a/src/endorse-extension.proto b/src/endorse-extension.proto
deleted file mode 100644
index 2cee133..0000000
--- a/src/endorse-extension.proto
+++ /dev/null
@@ -1,10 +0,0 @@
-package chronochat;
-
-message EndorseExtensionMsg
-{
-  message EndorseEntry
-  {
-    required string name = 1;
-  }
-  repeated EndorseEntry endorseEntry = 1;
-}
\ No newline at end of file
diff --git a/src/endorse-info.cpp b/src/endorse-info.cpp
new file mode 100644
index 0000000..985c304
--- /dev/null
+++ b/src/endorse-info.cpp
@@ -0,0 +1,170 @@
+/* -*- 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: Qiuhan Ding <qiuhanding@cs.ucla.edu>
+ */
+
+#include "endorse-info.hpp"
+
+namespace chronochat {
+
+BOOST_CONCEPT_ASSERT((ndn::WireEncodable<EndorseInfo>));
+BOOST_CONCEPT_ASSERT((ndn::WireDecodable<EndorseInfo>));
+
+
+EndorseInfo::EndorseInfo()
+{
+}
+
+EndorseInfo::EndorseInfo(const Block& endorseWire)
+{
+  this->wireDecode(endorseWire);
+}
+
+template<bool T>
+size_t
+EndorseInfo::wireEncode(ndn::EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  // EndorseInfo := ENDORSE-INFO-TYPE TLV-LENGTH
+  //                  ENDORSEMENT+
+  //
+  // Endorsement := ENDORSEMENT-TYPE TLV-LENGTH
+  //                  EndorseType
+  //                  EndorseValue
+  //                  EndorseCount
+  //
+  // EndorseType := ENDORSETYPE-TYPE TLV-LENGTH
+  //                  String
+  //
+  // EndorseValue := ENDORSEVALUE-TYPE TLV-LENGTH
+  //                   String
+  // EndorseCount := ENDORSECOUNT-TYPE TLV-LENGTH
+  //                   String
+
+  // Entries
+  size_t entryLength = 0;
+  for (std::vector<Endorsement>::const_reverse_iterator it = m_endorsements.rbegin();
+       it != m_endorsements.rend(); it++) {
+
+    // Endorse Count
+    const uint8_t *countWire = reinterpret_cast<const uint8_t*>(it->count.c_str());
+    entryLength += block.prependByteArrayBlock(tlv::EndorseCount, countWire, it->count.length());
+
+    // Endorse Value
+    const uint8_t *valueWire = reinterpret_cast<const uint8_t*>(it->value.c_str());
+    entryLength += block.prependByteArrayBlock(tlv::EndorseValue, valueWire, it->value.length());
+
+    // Endorse Type
+    const uint8_t *typeWire = reinterpret_cast<const uint8_t*>(it->type.c_str());
+    entryLength += block.prependByteArrayBlock(tlv::EndorseType, typeWire, it->type.length());
+
+    // Endorsement
+    entryLength += block.prependVarNumber(entryLength);
+    entryLength += block.prependVarNumber(tlv::Endorsement);
+    totalLength += entryLength;
+    entryLength = 0;
+  }
+
+  // Profile
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::EndorseInfo);
+
+  return totalLength;
+
+}
+
+const Block&
+EndorseInfo::wireEncode() const
+{
+  ndn::EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  ndn::EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  m_wire.parse();
+
+  return m_wire;
+}
+
+void
+EndorseInfo::wireDecode(const Block& endorseWire)
+{
+  m_wire = endorseWire;
+  m_wire.parse();
+  m_endorsements.clear();
+
+  if (m_wire.type() != tlv::EndorseInfo)
+    throw Error("Unexpected TLV number when decoding endorse info packet");
+
+  // Endorsement
+  Block::element_const_iterator i = m_wire.elements_begin();
+  if (i == m_wire.elements_end())
+    throw Error("Missing Endorsement");
+  if (i->type() != tlv::Endorsement)
+    throw Error("Expect Endorsement but get TLV Type " + std::to_string(i->type()));
+
+  while (i != m_wire.elements_end() && i->type() == tlv::Endorsement) {
+    Endorsement endorsement;
+    Block temp = *i;
+    temp.parse();
+    Block::element_const_iterator j = temp.elements_begin();
+
+    // Endorse Type
+    if (j == temp.elements_end())
+      throw Error("Missing Endorse Type");
+    if (j->type() != tlv::EndorseType)
+      throw Error("Expect Endorse Type but get TLV Type " + std::to_string(j->type()));
+
+    endorsement.type = std::string(reinterpret_cast<const char* >(j->value()),
+                                   j->value_size());;
+    ++j;
+
+    // Endorse Value
+    if (j == temp.elements_end())
+      throw Error("Missing Endorse Value");
+    if (j->type() != tlv::EndorseValue)
+      throw Error("Expect Endorse Value but get TLV Type " + std::to_string(j->type()));
+
+    endorsement.value = std::string(reinterpret_cast<const char* >(j->value()),
+                                    j->value_size());
+    ++j;
+
+    // Endorse Count
+    if (j == temp.elements_end())
+      throw Error("Missing Endorse Count");
+    if (j->type() != tlv::EndorseCount)
+      throw Error("Expect Endorse Count but get TLV Type " + std::to_string(j->type()));
+
+    endorsement.count = std::string(reinterpret_cast<const char* >(j->value()),
+                                    j->value_size());
+    ++j;
+    if (j != temp.elements_end()) {
+      throw Error("Unexpected element");
+    }
+    m_endorsements.push_back(endorsement);
+    ++i;
+  }
+
+  if (i != m_wire.elements_end()) {
+      throw Error("Unexpected element");
+  }
+}
+
+void
+EndorseInfo::addEndorsement(const std::string& type, const std::string& value,
+                            const std::string& count) {
+  Endorsement endorsement;
+  endorsement.type = type;
+  endorsement.value = value;
+  endorsement.count = count;
+  m_endorsements.push_back(endorsement);
+}
+
+} // namespace chronochat
diff --git a/src/endorse-info.hpp b/src/endorse-info.hpp
new file mode 100644
index 0000000..921e711
--- /dev/null
+++ b/src/endorse-info.hpp
@@ -0,0 +1,81 @@
+/* -*- 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: Qiuhan Ding <qiuhanding@cs.ucla.edu>
+ */
+
+#ifndef CHRONOCHAT_ENDORSE_INFO_HPP
+#define CHRONOCHAT_ENDORSE_INFO_HPP
+
+#include "common.hpp"
+#include "tlv.hpp"
+#include <ndn-cxx/util/concepts.hpp>
+#include <ndn-cxx/encoding/block.hpp>
+#include <ndn-cxx/encoding/encoding-buffer.hpp>
+
+namespace chronochat {
+
+class EndorseInfo
+{
+
+public:
+
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  class Endorsement {
+  public:
+    std::string type;
+    std::string value;
+    std::string count;
+  };
+
+public:
+
+  EndorseInfo();
+
+  explicit
+  EndorseInfo(const Block& endorseWire);
+
+  const Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const Block& endorseWire);
+
+  const std::vector<Endorsement>&
+  getEndorsements() const;
+
+  void
+  addEndorsement(const std::string& type, const std::string& value, const std::string& count);
+
+private:
+  template<bool T>
+  size_t
+  wireEncode(ndn::EncodingImpl<T>& block) const;
+
+private:
+  mutable Block m_wire;
+  std::vector<Endorsement> m_endorsements;
+};
+
+inline const std::vector<EndorseInfo::Endorsement>&
+EndorseInfo::getEndorsements() const
+{
+  return m_endorsements;
+}
+
+
+} // namespace chronochat
+
+#endif //CHRONOCHAT_ENDORSE_INFO_HPP
diff --git a/src/endorse-info.proto b/src/endorse-info.proto
deleted file mode 100644
index b1657d6..0000000
--- a/src/endorse-info.proto
+++ /dev/null
@@ -1,12 +0,0 @@
-package chronochat;
-
-message EndorseInfo
-{
-  message Endorsement
-  {
-    required string type    = 1;
-    required string value   = 2;
-    required string endorse = 3;
-  }
-  repeated Endorsement endorsement = 1;
-}
\ No newline at end of file
diff --git a/src/intro-cert-list.proto b/src/intro-cert-list.proto
deleted file mode 100644
index b365aa4..0000000
--- a/src/intro-cert-list.proto
+++ /dev/null
@@ -1,6 +0,0 @@
-package chronochat;
-
-message IntroCertListMsg
-{
-  repeated string certname = 1;
-}
\ No newline at end of file
diff --git a/src/invitation-request-dialog.hpp b/src/invitation-request-dialog.hpp
index bd2bd1d..c15fce2 100644
--- a/src/invitation-request-dialog.hpp
+++ b/src/invitation-request-dialog.hpp
@@ -8,8 +8,8 @@
  *         Yingdi Yu <yingdi@cs.ucla.edu>
  */
 
-#ifndef CHRONOS_INVITATION_REQUEST_DIALOG_HPP
-#define CHRONOS_INVITATION_REQUEST_DIALOG_HPP
+#ifndef CHRONOCHAT_INVITATION_REQUEST_DIALOG_HPP
+#define CHRONOCHAT_INVITATION_REQUEST_DIALOG_HPP
 
 #include <QDialog>
 
@@ -56,4 +56,4 @@
 
 } // namespace chronochat
 
-#endif // CHRONOS_INVITATION_REQUEST_DIALOG_HPP
+#endif // CHRONOCHAT_INVITATION_REQUEST_DIALOG_HPP
diff --git a/src/profile.cpp b/src/profile.cpp
index 47c873a..38f7b63 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -6,6 +6,7 @@
  * BSD license, See the LICENSE file for more information
  *
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ *         Qiuhan Ding <qiuhanding@cs.ucla.edu>
  */
 
 #include "profile.hpp"
@@ -76,20 +77,111 @@
 {
 }
 
-void
-Profile::encode(std::ostream& os) const
+template<bool T>
+size_t
+Profile::wireEncode(ndn::EncodingImpl<T>& block) const
 {
-  chronochat::ProfileMsg profileMsg;
-  profileMsg << (*this);
-  profileMsg.SerializeToOstream(&os);
+  size_t totalLength = 0;
+
+  // Profile := PROFILE-TYPE TLV-LENGTH
+  //             ProfileEntry+
+  //
+  // ProfileEntry := PROFILEENTRY-TYPE TLV-LENGTH
+  //                   Oid
+  //                   EntryData
+  //
+  // Oid := OID-TYPE TLV-LENGTH
+  //            String
+  //
+  // EntryData := ENTRYDATA-TYPE TLV-LENGTH
+  //                  String
+
+  // Entries
+  size_t entryLength = 0;
+  for (map<string, string>::const_reverse_iterator it = m_entries.rbegin();
+       it != m_entries.rend(); it++) {
+    // Entry Data
+    const uint8_t* dataWire = reinterpret_cast<const uint8_t*>(it->second.c_str());
+    entryLength += block.prependByteArrayBlock(tlv::EntryData, dataWire, it->second.length());
+    // Oid
+    const uint8_t* oidWire = reinterpret_cast<const uint8_t*>(it->first.c_str());
+    entryLength += block.prependByteArrayBlock(tlv::Oid, oidWire, it->first.length());
+    entryLength += block.prependVarNumber(entryLength);
+    entryLength += block.prependVarNumber(tlv::ProfileEntry);
+    totalLength += entryLength;
+    entryLength = 0;
+  }
+
+  // Profile
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::Profile);
+
+  return totalLength;
+}
+
+
+
+const Block&
+Profile::wireEncode() const
+{
+  ndn::EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  ndn::EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  m_wire.parse();
+
+  return m_wire;
 }
 
 void
-Profile::decode(std::istream& is)
+Profile::wireDecode(const Block& profileWire)
 {
-  chronochat::ProfileMsg profileMsg;
-  profileMsg.ParseFromIstream(&is);
-  profileMsg >> (*this);
+  m_wire = profileWire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::Profile)
+    throw Error("Unexpected TLV number when decoding profile packet");
+
+  Block::element_const_iterator i = m_wire.elements_begin();
+  if (i == m_wire.elements_end())
+    throw Error("Missing Profile Entry");
+  if (i->type() != tlv::ProfileEntry)
+    throw Error("Expect Profile Entry but get TLV Type " + std::to_string(i->type()));
+
+  while (i != m_wire.elements_end() && i->type() == tlv::ProfileEntry) {
+    Block temp = *i;
+    temp.parse();
+    Block::element_const_iterator j = temp.elements_begin();
+    if (j == temp.elements_end())
+      throw Error("Missing Oid");
+    if (j->type() != tlv::Oid)
+      throw Error("Expect Oid but get TLV Type" + std::to_string(j->type()));
+
+    string Oid = std::string(reinterpret_cast<const char* >(j->value()),
+                             j->value_size());
+    ++j;
+    if (j == temp.elements_end())
+      throw Error("Missing EntryData");
+    if (j->type() != tlv::EntryData)
+      throw Error("Expect EntryData but get TLV Type " + std::to_string(j->type()));
+
+    string EntryData = std::string(reinterpret_cast<const char* >(j->value()),
+                                   j->value_size());
+    ++j;
+    if (j != temp.elements_end()) {
+      throw Error("Unexpected element");
+    }
+    m_entries[Oid] = EntryData;
+    ++i;
+  }
+
+  if (i != m_wire.elements_end()) {
+      throw Error("Unexpected element");
+  }
+
 }
 
 bool
@@ -115,27 +207,4 @@
   return !(*this == profile);
 }
 
-chronochat::ProfileMsg&
-operator<<(chronochat::ProfileMsg& profileMsg, const Profile& profile)
-{
-;
-  for (map<string, string>::const_iterator it = profile.begin(); it != profile.end(); it++) {
-    chronochat::ProfileMsg::ProfileEntry* profileEntry = profileMsg.add_entry();
-    profileEntry->set_oid(it->first);
-    profileEntry->set_data(it->second);
-  }
-  return profileMsg;
-}
-
-chronochat::ProfileMsg&
-operator>>(chronochat::ProfileMsg& profileMsg, Profile& profile)
-{
-  for (int i = 0; i < profileMsg.entry_size(); i++) {
-    const chronochat::ProfileMsg::ProfileEntry& profileEntry = profileMsg.entry(i);
-    profile[profileEntry.oid()] = profileEntry.data();
-  }
-
-  return profileMsg;
-}
-
 } // namespace chronochat
diff --git a/src/profile.hpp b/src/profile.hpp
index cd70cb5..a89a800 100644
--- a/src/profile.hpp
+++ b/src/profile.hpp
@@ -6,6 +6,7 @@
  * BSD license, See the LICENSE file for more information
  *
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ *         Qiuhan Ding <qiuhanding@cs.ucla.edu>
  */
 
 #ifndef CHRONOCHAT_PROFILE_HPP
@@ -13,13 +14,28 @@
 
 #include "common.hpp"
 
+#include "tlv.hpp"
+#include <ndn-cxx/util/concepts.hpp>
+#include <ndn-cxx/encoding/block.hpp>
+#include <ndn-cxx/encoding/encoding-buffer.hpp>
 #include <ndn-cxx/security/identity-certificate.hpp>
-#include "profile.pb.h"
 
 namespace chronochat {
 
 class Profile
 {
+
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
 public:
   typedef std::map<std::string, std::string>::iterator iterator;
   typedef std::map<std::string, std::string>::const_iterator const_iterator;
@@ -42,6 +58,12 @@
   {
   }
 
+  const Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const Block& profileWire);
+
   std::string&
   operator[](const std::string& profileKey)
   {
@@ -82,12 +104,6 @@
     return m_entries.end();
   }
 
-  void
-  encode(std::ostream& os) const;
-
-  void
-  decode(std::istream& is);
-
   Name
   getIdentityName() const
   {
@@ -101,6 +117,12 @@
   operator!=(const Profile& profile) const;
 
 private:
+  template<bool T>
+  size_t
+  wireEncode(ndn::EncodingImpl<T>& block) const;
+
+
+private:
   static const std::string OID_NAME;
   static const std::string OID_ORG;
   static const std::string OID_GROUP;
@@ -108,15 +130,11 @@
   static const std::string OID_ADVISOR;
   static const std::string OID_EMAIL;
 
+  mutable Block m_wire;
+
   std::map<std::string, std::string> m_entries;
 };
 
-chronochat::ProfileMsg&
-operator<<(chronochat::ProfileMsg& msg, const Profile& profile);
-
-chronochat::ProfileMsg&
-operator>>(chronochat::ProfileMsg& msg, Profile& profile);
-
 } // namespace chronochat
 
 #endif // CHRONOCHAT_PROFILE_HPP
diff --git a/src/profile.proto b/src/profile.proto
deleted file mode 100644
index 3f435af..0000000
--- a/src/profile.proto
+++ /dev/null
@@ -1,11 +0,0 @@
-package chronochat;
-
-message ProfileMsg
-{
-  message ProfileEntry
-  {
-    required string oid = 1;
-    required string data = 2;
-  }
-  repeated ProfileEntry entry = 1;
-}
\ No newline at end of file
diff --git a/src/tlv.hpp b/src/tlv.hpp
new file mode 100644
index 0000000..b793c01
--- /dev/null
+++ b/src/tlv.hpp
@@ -0,0 +1,40 @@
+#ifndef CHRONOCHAT_TLV_HPP
+#define CHRONOCHAT_TLV_HPP
+
+namespace chronochat {
+
+namespace tlv {
+
+enum {
+  ChatroomInfo = 128,
+  ChatroomName = 129,
+  TrustModel = 130,
+  ChatroomPrefix = 131,
+  ManagerPrefix = 132,
+  Participants = 133,
+  Conf = 134,
+  Nick = 135,
+  Profile = 136,
+  ProfileEntry = 137,
+  Oid = 138,
+  EntryData = 139,
+  EndorseExtension = 140,
+  EndorseCollection = 141,
+  EndorseCollectionEntry = 142,
+  Hash = 143,
+  EndorseInfo = 144,
+  Endorsement = 145,
+  EndorseType = 146,
+  EndorseValue = 147,
+  EndorseCount = 148,
+  ChatMessage = 149,
+  ChatMessageType = 150,
+  ChatData = 151,
+  Timestamp = 152,
+};
+
+} // namespace tlv
+
+} // namespace chronochat
+
+#endif // CHRONOCHAT_TLV_HPP