api-changes: Use ndn-cpp-dev

Change-Id: I4540e601106598d51601e59e5fe9524a9080a572
diff --git a/ChronoSync b/ChronoSync
index 531803b..51c8025 160000
--- a/ChronoSync
+++ b/ChronoSync
@@ -1 +1 @@
-Subproject commit 531803bae995976d913c323c454e26f18994daa7
+Subproject commit 51c802519a74cc86aba9e16120bb87a2e86ab229
diff --git a/src/addcontactpanel.cpp b/src/addcontactpanel.cpp
index 52f5483..add341a 100644
--- a/src/addcontactpanel.cpp
+++ b/src/addcontactpanel.cpp
@@ -13,14 +13,14 @@
 #include <QMessageBox>
 
 #ifndef Q_MOC_RUN
-#include <ndn-cpp-dev/security/verifier.hpp>
+#include <ndn-cpp-dev/security/validator.hpp>
 #include <boost/iostreams/stream.hpp>
 #include "endorse-collection.pb.h"
 #include "logging.h"
 #endif
 
 using namespace ndn;
-using namespace ndn::ptr_lib;
+using namespace chronos;
 using namespace std;
 
 INIT_LOGGER("AddContactPanel");
@@ -35,7 +35,7 @@
   ui->setupUi(this);
   
   qRegisterMetaType<ndn::Name>("NdnName");
-  qRegisterMetaType<EndorseCertificate>("EndorseCertificate");
+  qRegisterMetaType<chronos::EndorseCertificate>("EndorseCertificate");
   qRegisterMetaType<ndn::Data>("NdnData");
 
   connect(ui->cancelButton, SIGNAL(clicked()),
@@ -44,16 +44,16 @@
           this, SLOT(onSearchClicked()));
   connect(ui->addButton, SIGNAL(clicked()),
           this, SLOT(onAddClicked()));
-  connect(&*m_contactManager, SIGNAL(contactFetched(const EndorseCertificate&)),
-          this, SLOT(selfEndorseCertificateFetched(const EndorseCertificate&)));
+  connect(&*m_contactManager, SIGNAL(contactFetched(const chronos::EndorseCertificate&)),
+          this, SLOT(selfEndorseCertificateFetched(const chronos::EndorseCertificate&)));
   connect(&*m_contactManager, SIGNAL(contactFetchFailed(const ndn::Name&)),
           this, SLOT(selfEndorseCertificateFetchFailed(const ndn::Name&)));
   connect(&*m_contactManager, SIGNAL(collectEndorseFetched(const ndn::Data&)),
           this, SLOT(onCollectEndorseFetched(const ndn::Data&)));
   connect(&*m_contactManager, SIGNAL(collectEndorseFetchFailed(const ndn::Name&)),
           this, SLOT(onCollectEndorseFetchFailed(const ndn::Name&)));
-  connect(&*m_contactManager, SIGNAL(contactKeyFetched(const EndorseCertificate&)),
-          this, SLOT(onContactKeyFetched(const EndorseCertificate&)));
+  connect(&*m_contactManager, SIGNAL(contactKeyFetched(const chronos::EndorseCertificate&)),
+          this, SLOT(onContactKeyFetched(const chronos::EndorseCertificate&)));
   connect(&*m_contactManager, SIGNAL(contactKeyFetchFailed(const ndn::Name&)),
           this, SLOT(onContactKeyFetchFailed(const ndn::Name&)));
 
@@ -100,16 +100,13 @@
 bool
 AddContactPanel::isCorrectName(const Name& name)
 {
-  string key("KEY");
-  string idCert("ID-CERT");
-
-  if(name.get(-1).toEscapedString() != idCert)
+  if(name.get(-1).toEscapedString() != "ID-CERT")
     return false;
   
   int keyIndex = -1;
   for(int i = 0; i < name.size(); i++)
     {
-      if(name.get(i).toEscapedString() == key)
+      if(name.get(i).toEscapedString() == "KEY")
         {
           keyIndex = i;
           break;
@@ -128,7 +125,7 @@
   ContactItem contactItem(*m_currentEndorseCertificate);
   try{
     m_contactManager->getContactStorage()->addContact(contactItem);
-  }catch(std::exception& e){
+  }catch(ContactStorage::Error& e){
     QMessageBox::information(this, tr("Chronos"), QString::fromStdString(e.what()));
     _LOG_ERROR("Exception: " << e.what());
     return;
@@ -140,13 +137,9 @@
 void 
 AddContactPanel::selfEndorseCertificateFetched(const EndorseCertificate& endorseCertificate)
 {
-  try{
-    m_currentEndorseCertificate = make_shared<EndorseCertificate>(endorseCertificate);
-  }catch(std::exception& e){
-    QMessageBox::information(this, tr("Chronos"), QString::fromStdString(e.what()));
-    _LOG_ERROR("Exception: " << e.what());
-    return;
-  }
+
+  m_currentEndorseCertificate = make_shared<EndorseCertificate>(endorseCertificate);
+
   m_currentEndorseCertificateReady = true;
 
   if(m_currentCollectEndorseReady == true)
@@ -162,13 +155,7 @@
 void
 AddContactPanel::onContactKeyFetched(const EndorseCertificate& endorseCertificate)
 {
-  try{
-    m_currentEndorseCertificate = make_shared<EndorseCertificate>(endorseCertificate);
-  }catch(std::exception& e){
-    QMessageBox::information(this, tr("Chronos"), QString::fromStdString(e.what()));
-    _LOG_ERROR("Exception: " << e.what());
-    return;
-  }
+  m_currentEndorseCertificate = make_shared<EndorseCertificate>(endorseCertificate);
 
   m_currentCollectEndorseReady = false;
 
@@ -185,6 +172,7 @@
 AddContactPanel::onCollectEndorseFetched(const Data& data)
 {
   m_currentCollectEndorse = make_shared<Data>(data);
+
   m_currentCollectEndorseReady = true;
 
   if(m_currentEndorseCertificateReady == true)
@@ -195,6 +183,7 @@
 AddContactPanel::onCollectEndorseFetchFailed(const Name& identity)
 {
   m_currentCollectEndorse = shared_ptr<Data>();
+
   m_currentCollectEndorseReady = true;
   
   if(m_currentEndorseCertificateReady == true)
@@ -205,13 +194,11 @@
 AddContactPanel::displayContactInfo()
 {
   // _LOG_TRACE("displayContactInfo");
-  const Profile& profile = m_currentEndorseCertificate->getProfileData().getProfile();
-  const Block& profileContent = m_currentEndorseCertificate->getProfileData().getContent();
-  Buffer profileBlock(profileContent.value(), profileContent.value_size());
+  const Profile& profile = m_currentEndorseCertificate->getProfile();
 
   map<string, int> endorseCount;
 
-  if(static_cast<bool>(m_currentCollectEndorse))
+  if(!static_cast<bool>(m_currentCollectEndorse))
     {
       Chronos::EndorseCollection endorseCollection;
       
@@ -229,29 +216,27 @@
                                   endorseCollection.endorsement(i).blob().size()));
             EndorseCertificate endorseCert(data);
             
-            Name signerKeyName = endorseCert.getSigner();
-            Name signerName = signerKeyName.getPrefix(-1);
+            Name signerName = endorseCert.getSigner().getPrefix(-1);
           
             shared_ptr<ContactItem> contact = m_contactManager->getContact(signerName);
-            if(static_cast<bool>(contact))
+            if(!static_cast<bool>(contact))
               continue;
 
-            if(!contact->isIntroducer() || !contact->canBeTrustedFor(m_currentEndorseCertificate->getProfileData().getIdentityName()))
+            if(!contact->isIntroducer() || !contact->canBeTrustedFor(m_currentEndorseCertificate->getProfile().getIdentityName()))
               continue;
           
-            if(!Verifier::verifySignature(data, data.getSignature(), contact->getSelfEndorseCertificate().getPublicKeyInfo()))
+            if(!Validator::verifySignature(data, data.getSignature(), contact->getSelfEndorseCertificate().getPublicKeyInfo()))
               continue;
 
-            const Block& tmpProfileContent = endorseCert.getProfileData().getContent();
-            Buffer tmpProfileBlock(tmpProfileContent.value(), tmpProfileContent.value_size());
-            if(profileBlock != tmpProfileBlock)
+            const Profile& tmpProfile = endorseCert.getProfile();
+            if(!(profile == tmpProfile))
               continue;
 
           const vector<string>& endorseList = endorseCert.getEndorseList();
           vector<string>::const_iterator it = endorseList.begin();
           for(; it != endorseList.end(); it++)
             endorseCount[*it] += 1;
-          }catch(std::exception& e){
+          }catch(std::runtime_error& e){
             continue;
           }
         }  
@@ -289,27 +274,6 @@
   }
 }
 
-// bool
-// AddContactPanel::isSameBlob(const ndn::Blob& blobA, const ndn::Blob& blobB)
-// {
-//   size_t size = blobA.size();
-
-//   if(size != blobB.size())
-//     return false;
-
-//   const uint8_t* ap = blobA.buf();
-//   const uint8_t* bp = blobB.buf();
-  
-//   for(int i = 0; i < size; i++)
-//     {
-//       if(ap[i] != bp[i])
-//         return false;
-//     }
-
-//   return true;
-
-// }
-
 
 #if WAF
 #include "addcontactpanel.moc"
diff --git a/src/addcontactpanel.h b/src/addcontactpanel.h
index 2264b9e..a65635a 100644
--- a/src/addcontactpanel.h
+++ b/src/addcontactpanel.h
@@ -27,7 +27,7 @@
 
 Q_DECLARE_METATYPE(ndn::Name)
 
-Q_DECLARE_METATYPE(EndorseCertificate)
+Q_DECLARE_METATYPE(chronos::EndorseCertificate)
 
 Q_DECLARE_METATYPE(ndn::Data)
 
@@ -36,7 +36,7 @@
   Q_OBJECT
 
 public:
-  explicit AddContactPanel(ndn::ptr_lib::shared_ptr<ContactManager> contactManager,
+  explicit AddContactPanel(ndn::shared_ptr<chronos::ContactManager> contactManager,
                            QWidget *parent = 0);
 
   ~AddContactPanel();
@@ -62,13 +62,13 @@
   onAddClicked();
 
   void
-  selfEndorseCertificateFetched(const EndorseCertificate& endorseCertificate);
+  selfEndorseCertificateFetched(const chronos::EndorseCertificate& endorseCertificate);
 
   void
   selfEndorseCertificateFetchFailed(const ndn::Name& identity);
 
   void
-  onContactKeyFetched(const EndorseCertificate& endorseCertificate);
+  onContactKeyFetched(const chronos::EndorseCertificate& endorseCertificate);
 
   void
   onContactKeyFetchFailed(const ndn::Name& identity);
@@ -87,10 +87,10 @@
 
   Ui::AddContactPanel *ui;
   ndn::Name m_searchIdentity;
-  ndn::ptr_lib::shared_ptr<ContactManager> m_contactManager;
+  ndn::shared_ptr<chronos::ContactManager> m_contactManager;
   WarningDialog* m_warningDialog;
-  ndn::ptr_lib::shared_ptr<EndorseCertificate> m_currentEndorseCertificate;
-  ndn::ptr_lib::shared_ptr<ndn::Data> m_currentCollectEndorse;
+  ndn::shared_ptr<chronos::EndorseCertificate> m_currentEndorseCertificate;
+  ndn::shared_ptr<ndn::Data> m_currentCollectEndorse;
   bool m_currentEndorseCertificateReady;
   bool m_currentCollectEndorseReady;
 };
diff --git a/src/browsecontactdialog.cpp b/src/browsecontactdialog.cpp
index 281ecba..ba0664d 100644
--- a/src/browsecontactdialog.cpp
+++ b/src/browsecontactdialog.cpp
@@ -17,12 +17,11 @@
 #include <boost/asio.hpp>
 #include <boost/tokenizer.hpp>
 #include "logging.h"
-// #include "ndn.cxx/error.h"
 #endif
 
 using namespace std;
 using namespace ndn;
-using namespace ndn::ptr_lib;
+using namespace chronos;
 
 INIT_LOGGER("BrowseContactDialog");
 
@@ -65,7 +64,7 @@
 
 
 void
-BrowseContactDialog::getCertNames(std::vector<std::string> &names)
+BrowseContactDialog::getCertNames(vector<string> &names)
 {
   try{
     using namespace boost::asio::ip;
@@ -215,7 +214,7 @@
   _LOG_DEBUG("Fetch: " << certNameNoVersion.toUri());
   m_certificateMap.insert(pair<Name, IdentityCertificate>(certNameNoVersion, identityCertificate));
   m_profileMap.insert(pair<Name, Profile>(certNameNoVersion, Profile(identityCertificate)));
-  string name = m_profileMap[certNameNoVersion].getProfileEntry("name");
+  string name = m_profileMap[certNameNoVersion].get("name");
   // Name contactName = m_profileMap[certNameNoVersion].getIdentityName();
   {
       UniqueRecLock lock(m_mutex);
@@ -249,8 +248,8 @@
 }
 
 void
-BrowseContactDialog::updateSelection(const QItemSelection &selected,
-				     const QItemSelection &deselected)
+BrowseContactDialog::updateSelection(const QItemSelection& selected,
+				     const QItemSelection& deselected)
 {
   QModelIndexList items = selected.indexes();
   Name certName = m_contactNameList[items.first().row()];
diff --git a/src/browsecontactdialog.h b/src/browsecontactdialog.h
index bab431d..5cd610f 100644
--- a/src/browsecontactdialog.h
+++ b/src/browsecontactdialog.h
@@ -35,7 +35,7 @@
   Q_OBJECT
   
 public:
-  explicit BrowseContactDialog(ndn::ptr_lib::shared_ptr<ContactManager> contactManager,
+  explicit BrowseContactDialog(ndn::shared_ptr<chronos::ContactManager> contactManager,
                                QWidget *parent = 0);
 
   ~BrowseContactDialog();
@@ -46,7 +46,7 @@
 
 private:
   void
-  getCertNames(std::vector<std::string> &names);
+  getCertNames(std::vector<std::string>& names);
 
   void
   updateCertificateMap(bool filter = false);
@@ -95,7 +95,7 @@
 private:
   Ui::BrowseContactDialog *ui;
   
-  ndn::ptr_lib::shared_ptr<ContactManager> m_contactManager;
+  ndn::shared_ptr<chronos::ContactManager> m_contactManager;
 
   WarningDialog* m_warningDialog;
   QStringListModel* m_contactListModel;
@@ -104,11 +104,9 @@
   std::vector<ndn::Name> m_contactNameList;
   std::vector<ndn::Name> m_certificateNameList;
   std::map<ndn::Name, ndn::IdentityCertificate> m_certificateMap;
-  std::map<ndn::Name, Profile> m_profileMap;
+  std::map<ndn::Name, chronos::Profile> m_profileMap;
 
   RecLock m_mutex;
-
-
 };
 
 #endif // BROWSECONTACTDIALOG_H
diff --git a/src/chatdialog.cpp b/src/chatdialog.cpp
index 14dd7a5..e43aa78 100644
--- a/src/chatdialog.cpp
+++ b/src/chatdialog.cpp
@@ -18,8 +18,12 @@
 #include <QCloseEvent>
 
 #ifndef Q_MOC_RUN
+#include "invitation.h"
+
+#ifdef WITH_SECURITY
 #include <sync-intro-certificate.h>
-#include "chronos-invitation.h"
+#endif
+
 #include <boost/random/random_device.hpp>
 #include <boost/random/uniform_int_distribution.hpp>
 #include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
@@ -27,37 +31,42 @@
 #endif
 
 using namespace std;
+using namespace ndn;
+using namespace chronos;
 
 INIT_LOGGER("ChatDialog");
 
 static const int HELLO_INTERVAL = FRESHNESS * 3 / 4;
 
 Q_DECLARE_METATYPE(std::vector<Sync::MissingDataInfo> )
+Q_DECLARE_METATYPE(ndn::shared_ptr<const ndn::Data> )
 Q_DECLARE_METATYPE(size_t)
 
-ChatDialog::ChatDialog(ndn::ptr_lib::shared_ptr<ContactManager> contactManager,
-                       const ndn::Name& chatroomPrefix,
-		       const ndn::Name& localPrefix,
-                       const ndn::Name& defaultIdentity,
-                       const std::string& nick,
-                       bool trial,
+ChatDialog::ChatDialog(shared_ptr<ContactManager> contactManager,
+                       shared_ptr<Face> face,
+                       const Name& chatroomPrefix,
+		       const Name& localPrefix,
+                       const Name& defaultIdentity,
+                       const string& nick,
 		       QWidget *parent) 
-: QDialog(parent)
+  : QDialog(parent)
   , ui(new Ui::ChatDialog)
   , m_contactManager(contactManager)
+  , m_face(face)
+  , m_ioService(face->ioService())
   , m_chatroomPrefix(chatroomPrefix)
   , m_localPrefix(localPrefix)
   , m_defaultIdentity(defaultIdentity)
-  , m_invitationPolicy(new SecPolicyChronoChatInvitation(m_chatroomPrefix.get(-1).toEscapedString(), m_defaultIdentity))
-  , m_keyChain(new ndn::KeyChain())
   , m_nick(nick)
+  , m_scheduler(*face->ioService())
+  , m_keyChain(new KeyChain())
   , m_sock(NULL)
-  , m_lastMsgTime(0)
-  // , m_historyInitialized(false)
+  , m_lastMsgTime(time::now())
   , m_joined(false)
   , m_inviteListDialog(new InviteListDialog(m_contactManager))
 {
   qRegisterMetaType<std::vector<Sync::MissingDataInfo> >("std::vector<Sync::MissingDataInfo>");
+  qRegisterMetaType<ndn::shared_ptr<const ndn::Data> >("ndn::shared_ptr<const ndn::Data>");
   qRegisterMetaType<size_t>("size_t");
 
   ui->setupUi(this);
@@ -67,7 +76,7 @@
   m_localChatPrefix.append("%F0.").append(m_defaultIdentity);
   m_localChatPrefix.append("chronos").append(m_chatroomPrefix.get(-1)).append(randString.toStdString());
 
-  m_session = time(NULL);
+  m_session = static_cast<uint64_t>(time::now());
   m_scene = new DigestTreeScene(this);
 
   initializeSetting();
@@ -85,14 +94,13 @@
   createActions();
   createTrayIcon();
 
-  m_timer = new QTimer(this);
-
-  startFace();
-  m_verifier = ndn::ptr_lib::make_shared<ndn::Verifier>(m_invitationPolicy);
-  m_verifier->setFace(m_face);
-
-  ndn::Name certificateName = m_keyChain->getDefaultCertificateNameForIdentity(m_defaultIdentity);
-  m_syncPolicy = ndn::ptr_lib::make_shared<SecPolicySync>(m_defaultIdentity, certificateName, m_chatroomPrefix, m_face);
+#ifndef SECURITY
+  m_invitationValidator = make_shared<ValidatorNull>();
+  m_syncValidator = make_shared<ValidatorNull>();
+#else
+  m_invitationValidator = make_shared<chronos::ValidatorInvitation>();
+  m_syncValidator = ...;
+#endif
 
   connect(ui->inviteButton, SIGNAL(clicked()),
           this, SLOT(openInviteListDialog()));
@@ -102,12 +110,10 @@
           this, SLOT(returnPressed()));
   connect(ui->treeButton, SIGNAL(pressed()), 
           this, SLOT(treeButtonPressed()));
-  connect(this, SIGNAL(dataReceived(QString, const char *, size_t, bool, bool)), 
-          this, SLOT(processData(QString, const char *, size_t, bool, bool)));
+  connect(this, SIGNAL(dataReceived(ndn::shared_ptr<const ndn::Data>, bool, bool)), 
+          this, SLOT(processData(ndn::shared_ptr<const ndn::Data>, bool, bool)));
   connect(this, SIGNAL(treeUpdated(const std::vector<Sync::MissingDataInfo>)), 
           this, SLOT(processTreeUpdate(const std::vector<Sync::MissingDataInfo>)));
-  connect(m_timer, SIGNAL(timeout()), 
-          this, SLOT(replot()));
   connect(m_scene, SIGNAL(replot()), 
           this, SLOT(replot()));
   connect(trayIcon, SIGNAL(messageClicked()), 
@@ -130,67 +136,9 @@
       delete m_sock;
       m_sock = NULL;
     }
-  shutdownFace();
 }
 
 void
-ChatDialog::startFace()
-{
-  m_face = ndn::ptr_lib::make_shared<ndn::Face>();
-  
-  connectToDaemon();
-
-  m_running = true;
-  m_thread = boost::thread (&ChatDialog::eventLoop, this);  
-}
-
-void
-ChatDialog::shutdownFace()
-{
-  {
-    boost::unique_lock<boost::recursive_mutex> lock(m_mutex);
-    m_running = false;
-  }
-  
-  m_thread.join();
-  m_face->shutdown();
-}
-
-void
-ChatDialog::eventLoop()
-{
-  while (m_running)
-    {
-      try{
-        m_face->processEvents();
-        usleep(1000);
-      }catch(std::exception& e){
-        _LOG_DEBUG(" " << e.what() );
-      }
-    }
-}
-
-void
-ChatDialog::connectToDaemon()
-{
-  //Hack! transport does not connect to daemon unless an interest is expressed.
-  ndn::Name name("/ndn");
-  ndn::ptr_lib::shared_ptr<ndn::Interest> interest = ndn::ptr_lib::make_shared<ndn::Interest>(name);
-  m_face->expressInterest(*interest, 
-                          boost::bind(&ChatDialog::onConnectionData, this, _1, _2),
-                          boost::bind(&ChatDialog::onConnectionDataTimeout, this, _1));
-}
-
-void
-ChatDialog::onConnectionData(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest,
-                             const ndn::ptr_lib::shared_ptr<ndn::Data>& data)
-{ _LOG_DEBUG("onConnectionData"); }
-
-void
-ChatDialog::onConnectionDataTimeout(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest)
-{ _LOG_DEBUG("onConnectionDataTimeout"); }
-
-void
 ChatDialog::initializeSetting()
 {
   m_user.setNick(QString::fromStdString(m_nick));
@@ -221,93 +169,72 @@
 }
 
 void
+ChatDialog::initializeSync()
+{
+  
+  m_sock = new Sync::SyncSocket(m_chatroomPrefix.toUri(),
+                                m_syncValidator,
+                                m_face,
+                                bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
+                                bind(&ChatDialog::processRemoveWrapper, this, _1));
+  
+  usleep(100000);
+
+  m_scheduler.scheduleEvent(time::milliseconds(600), bind(&ChatDialog::sendJoin, this));
+
+  if(static_cast<bool>(m_replotEventId))
+    m_scheduler.cancelEvent(m_replotEventId);
+  m_replotEventId = m_scheduler.schedulePeriodicEvent(time::seconds(0), time::milliseconds(FRESHNESS * 1000),
+                                                      bind(&ChatDialog::replot, this));
+  disableTreeDisplay();
+  m_scheduler.scheduleEvent(time::milliseconds(2200), bind(&ChatDialog::enableTreeDisplay, this));
+}
+
+void
 ChatDialog::sendInterest(const ndn::Interest& interest,
-                         const ndn::OnVerified& onVerified,
-                         const ndn::OnVerifyFailed& onVerifyFailed,
+                         const OnDataValidated& onValidated,
+                         const OnDataValidationFailed& onValidationFailed,
                          const OnEventualTimeout& timeoutNotify,
                          int retry /* = 1 */)
 {
   m_face->expressInterest(interest, 
-                          boost::bind(&ChatDialog::onTargetData, 
-                                      this,
-                                      _1,
-                                      _2,
-                                      onVerified, 
-                                      onVerifyFailed),
-                          boost::bind(&ChatDialog::onTargetTimeout,
-                                      this,
-                                      _1,
-                                      retry,
-                                      onVerified,
-                                      onVerifyFailed,
-                                      timeoutNotify));
+                          bind(&ChatDialog::onTargetData, 
+                               this, _1, _2, onValidated, onValidationFailed),
+                          bind(&ChatDialog::onTargetTimeout,
+                               this, _1, retry, 
+                               onValidated, onValidationFailed, timeoutNotify));
 }
 
 void
-ChatDialog::onTargetData(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest, 
-                         const ndn::ptr_lib::shared_ptr<ndn::Data>& data,
-                         const ndn::OnVerified& onVerified,
-                         const ndn::OnVerifyFailed& onVerifyFailed)
+ChatDialog::sendInvitation(shared_ptr<ContactItem> contact, bool isIntroducer)
 {
-  m_verifier->verifyData(data, onVerified, onVerifyFailed);
-}
+#ifdef WITH_SECURITY
+  m_invitationValidator->addTrustAnchor(contact->getSelfEndorseCertificate());
+#endif
 
-void
-ChatDialog::onTargetTimeout(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest, 
-                            int retry,
-                            const ndn::OnVerified& onVerified,
-                            const ndn::OnVerifyFailed& onVerifyFailed,
-                            const OnEventualTimeout& timeoutNotify)
-{
-  if(retry > 0)
-    sendInterest(*interest, onVerified, onVerifyFailed, timeoutNotify, retry-1);
-  else
-    {
-      _LOG_DEBUG("Interest: " << interest->getName().toUri() << " eventually times out!");
-      timeoutNotify();
-    }
-}
+  Invitation invitation(contact->getNameSpace(),
+                               m_chatroomPrefix.get(-1),
+                               m_localPrefix);
+  ndn::Interest interest(invitation.getUnsignedInterestName());
 
-void
-ChatDialog::sendInvitation(ndn::ptr_lib::shared_ptr<ContactItem> contact, bool isIntroducer)
-{
-  m_invitationPolicy->addTrustAnchor(contact->getSelfEndorseCertificate());
+  m_keyChain->signByIdentity(interest, m_defaultIdentity);
 
-  ndn::Name certificateName = m_keyChain->getDefaultCertificateNameForIdentity(m_defaultIdentity);
+  OnDataValidated onValidated = bind(&ChatDialog::onInviteReplyValidated,
+                                     this, _1, contact->getNameSpace(), isIntroducer);
 
-  ChronosInvitation invitation(contact->getNameSpace(),
-                               m_chatroomPrefix.getSubName(m_chatroomPrefix.size()-1, 1), //!!Should be changed!
-                               m_localPrefix,
-                               certificateName);
+  OnDataValidationFailed onValidationFailed = bind(&ChatDialog::onInviteReplyValidationFailed,
+                                                   this, _1, contact->getNameSpace());
 
-  const ndn::Buffer &signedBlob = invitation.getSignedBlob();
-  ndn::Signature sig = m_keyChain->sign(signedBlob.buf(), signedBlob.size(), certificateName);
-  invitation.setSignatureValue(sig.getValue());
-
-  ndn::Interest interest(invitation.getInterestName());
-  ndn::OnVerified onVerified = boost::bind(&ChatDialog::onInviteReplyVerified,
-                                           this,
-                                           _1,
-                                           contact->getNameSpace(),
-                                           isIntroducer);
-
-  ndn::OnVerifyFailed onVerifyFailed = boost::bind(&ChatDialog::onInviteReplyVerifyFailed,
-                                                   this,
-                                                   _1,
-                                                   contact->getNameSpace());
-
-  OnEventualTimeout timeoutNotify = boost::bind(&ChatDialog::onInviteReplyTimeout,
-                                                     this,
-                                                     contact->getNameSpace());
+  OnEventualTimeout timeoutNotify = bind(&ChatDialog::onInviteReplyTimeout,
+                                         this, contact->getNameSpace());
                                                  
-
-  sendInterest(interest, onVerified, onVerifyFailed, timeoutNotify);
+  sendInterest(interest, onValidated, onValidationFailed, timeoutNotify);
 }
 
 void 
-ChatDialog::onInviteReplyVerified(const ndn::ptr_lib::shared_ptr<ndn::Data>& data, 
-                                  const ndn::Name& identity, 
-                                  bool isIntroducer)
+ChatDialog::onInviteReplyValidated(const shared_ptr<const Data>& data, 
+                                   const Name& identity, 
+                                   bool isIntroducer)
 {
   string content(reinterpret_cast<const char*>(data->getContent().value()), data->getContent().value_size());
   if(content == string("nack"))
@@ -317,45 +244,49 @@
 }
 
 void
-ChatDialog::onInviteReplyVerifyFailed(const ndn::ptr_lib::shared_ptr<ndn::Data>& data,
-                                      const ndn::Name& identity)
+ChatDialog::onInviteReplyValidationFailed(const shared_ptr<const Data>& data,
+                                          const Name& identity)
 {
-  _LOG_DEBUG("Reply from " << identity.toUri() << " cannot be verified!");
   QString msg = QString::fromUtf8("Reply from ") + QString::fromStdString(identity.toUri()) + " cannot be verified!";
   emit inivationRejection(msg);
 }
 
 
 void
-ChatDialog::onInviteReplyTimeout(const ndn::Name& identity)
+ChatDialog::onInviteReplyTimeout(const Name& identity)
 {
-  _LOG_DEBUG("Your invitation to " << identity.toUri() << " times out!");
   QString msg = QString::fromUtf8("Your invitation to ") + QString::fromStdString(identity.toUri()) + " times out!";
   emit inivationRejection(msg);
 }
 
 void
-ChatDialog::invitationRejected(const ndn::Name& identity)
+ChatDialog::invitationRejected(const Name& identity)
 {
-  _LOG_DEBUG(" " << identity.toUri() << " Rejected your invitation!");
   QString msg = QString::fromStdString(identity.toUri()) + " Rejected your invitation!";
   emit inivationRejection(msg);
 }
 
 void
-ChatDialog::invitationAccepted(const ndn::Name& identity, ndn::ptr_lib::shared_ptr<ndn::Data> data, const string& inviteePrefix, bool isIntroducer)
+ChatDialog::invitationAccepted(const Name& identity, 
+                               shared_ptr<const Data> data, 
+                               const string& inviteePrefix, 
+                               bool isIntroducer)
 {
   _LOG_DEBUG(" " << identity.toUri() << " Accepted your invitation!");
-  ndn::SignatureSha256WithRsa sig(data->getSignature());
-  const ndn::Name & keyLocatorName = sig.getKeyLocator().getName();
-  ndn::ptr_lib::shared_ptr<ndn::IdentityCertificate> dskCertificate = m_invitationPolicy->getValidatedDskCertificate(keyLocatorName);
+
+#ifdef WITH_SECURITY
+  SignatureSha256WithRsa sig(data->getSignature());
+  const Name & keyLocatorName = sig.getKeyLocator().getName();
+  shared_ptr<IdentityCertificate> dskCertificate = m_invitationValidator->getValidatedDskCertificate(keyLocatorName);
   m_syncPolicy->addSyncDataRule(inviteePrefix, *dskCertificate, isIntroducer);
   publishIntroCert(*dskCertificate, isIntroducer);
+#endif
 }
 
 void
-ChatDialog::publishIntroCert(const ndn::IdentityCertificate& dskCertificate, bool isIntroducer)
+ChatDialog::publishIntroCert(const IdentityCertificate& dskCertificate, bool isIntroducer)
 {
+#ifdef WITH_SECURITY
   SyncIntroCertificate syncIntroCertificate(m_chatroomPrefix,
                                             dskCertificate.getPublicKeyName(),
                                             m_keyChain->getDefaultKeyNameForIdentity(m_defaultIdentity),
@@ -367,40 +298,28 @@
   _LOG_DEBUG("Publish Intro Certificate: " << syncIntroCertificate.getName());
   m_keyChain->sign(syncIntroCertificate, certName);
   m_face->put(syncIntroCertificate);
+#endif
 }
 
 void
-ChatDialog::addTrustAnchor(const EndorseCertificate& selfEndorseCertificate)
-{ m_invitationPolicy->addTrustAnchor(selfEndorseCertificate); }
-
-void
-ChatDialog::addChatDataRule(const ndn::Name& prefix, 
-                            const ndn::IdentityCertificate& identityCertificate,
+ChatDialog::addChatDataRule(const Name& prefix, 
+                            const IdentityCertificate& identityCertificate,
                             bool isIntroducer)
-{ m_syncPolicy->addSyncDataRule(prefix, identityCertificate, isIntroducer); }
-
- 
+{ 
+#ifdef WITH_SECURITY
+  m_syncValidator->addSyncDataRule(prefix, identityCertificate, isIntroducer); 
+#endif
+}
 
 void
-ChatDialog::initializeSync()
+ChatDialog::addTrustAnchor(const EndorseCertificate& cert)
 {
-  
-  m_sock = new Sync::SyncSocket(m_chatroomPrefix.toUri(),
-                                m_syncPolicy,
-                                m_face,
-                                boost::bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
-                                boost::bind(&ChatDialog::processRemoveWrapper, this, _1));
-  
-  usleep(100000);
-
-  QTimer::singleShot(600, this, SLOT(sendJoin()));
-  m_timer->start(FRESHNESS * 1000);
-  disableTreeDisplay();
-  QTimer::singleShot(2200, this, SLOT(enableTreeDisplay()));
-  // Sync::CcnxWrapperPtr handle = boost::make_shared<Sync::CcnxWrapper> ();
-  // handle->setInterestFilter(m_user.getPrefix().toStdString(), bind(&ChatDialog::respondHistoryRequest, this, _1));
+#ifdef WITH_SECURITY
+  m_syncValidator->addTrustAnchor(cert);
+#endif
 }
 
+
 void
 ChatDialog::returnPressed()
 {
@@ -467,20 +386,20 @@
 }
 
 void
-ChatDialog::processTreeUpdateWrapper(const std::vector<Sync::MissingDataInfo> v, Sync::SyncSocket *sock)
+ChatDialog::processTreeUpdateWrapper(const vector<Sync::MissingDataInfo>& v, Sync::SyncSocket *sock)
 {
   emit treeUpdated(v);
   _LOG_DEBUG("<<< Tree update signal emitted");
 }
 
 void
-ChatDialog::processRemoveWrapper(std::string prefix)
+ChatDialog::processRemoveWrapper(string prefix)
 {
   _LOG_DEBUG("Sync REMOVE signal received for prefix: " << prefix);
 }
 
 void
-ChatDialog::processTreeUpdate(const std::vector<Sync::MissingDataInfo> v)
+ChatDialog::processTreeUpdate(const vector<Sync::MissingDataInfo>& v)
 {
   _LOG_DEBUG("<<< processing Tree Update");
 
@@ -524,72 +443,30 @@
 }
 
 void
-ChatDialog::processDataWrapper(const ndn::ptr_lib::shared_ptr<ndn::Data>& data)
+ChatDialog::processDataWrapper(const shared_ptr<const Data>& data)
 {
-  string name = data->getName().toUri();
-  const char* buf = reinterpret_cast<const char*>(data->getContent().value());
-  size_t len = data->getContent().value_size();
-
-  char *tempBuf = new char[len];
-  memcpy(tempBuf, buf, len);
-  emit dataReceived(name.c_str(), tempBuf, len, true, false);
-  _LOG_DEBUG("<<< " << name << " fetched");
+  emit dataReceived(data, true, false);
+  _LOG_DEBUG("<<< " << data->getName() << " fetched");
 }
 
 void
-ChatDialog::processDataNoShowWrapper(const ndn::ptr_lib::shared_ptr<ndn::Data>& data)
-{
-  string name = data->getName().toUri();
-  const char* buf = reinterpret_cast<const char*>(data->getContent().value());
-  size_t len = data->getContent().value_size();
-
-  char *tempBuf = new char[len];
-  memcpy(tempBuf, buf, len);
-  emit dataReceived(name.c_str(), tempBuf, len, false, false);
-
-  // if (!m_historyInitialized)
-  // {
-  //   fetchHistory(name);
-  //   m_historyInitialized = true;
-  // }
-}
-
-// void
-// ChatDialog::fetchHistory(std::string name)
-// {
-
-//   /****************************/
-//   /* TODO: fix following part */
-//   /****************************/
-//   string nameWithoutSeq = name.substr(0, name.find_last_of('/'));
-//   string prefix = nameWithoutSeq.substr(0, nameWithoutSeq.find_last_of('/'));
-//   prefix += "/history";
-//   // Ptr<Wrapper>CcnxWrapperPtr handle = boost::make_shared<Sync::CcnxWrapper> ();
-//   // QString randomString = getRandomString();
-//   // for (int i = 0; i < MAX_HISTORY_ENTRY; i++)
-//   // {
-//   //   QString interest = QString("%1/%2/%3").arg(prefix.c_str()).arg(randomString).arg(i);
-//   //   handle->sendInterest(interest.toStdString(), bind(&ChatDialog::processDataHistoryWrapper, this, _1, _2, _3));
-//   // }
-// }
+ChatDialog::processDataNoShowWrapper(const shared_ptr<const Data>& data)
+{ emit dataReceived(data, false, false); }
 
 void
-ChatDialog::processData(QString name, const char *buf, size_t len, bool show, bool isHistory)
+ChatDialog::processData(shared_ptr<const Data> data, bool show, bool isHistory)
 {
   SyncDemo::ChatMessage msg;
   bool corrupted = false;
-  if (!msg.ParseFromArray(buf, len))
+  if (!msg.ParseFromArray(data->getContent().value(), data->getContent().value_size()))
   {
-    _LOG_DEBUG("Errrrr.. Can not parse msg with name: " << name.toStdString() << ". what is happening?");
+    _LOG_DEBUG("Errrrr.. Can not parse msg with name: " << data->getName() << ". what is happening?");
     // nasty stuff: as a remedy, we'll form some standard msg for inparsable msgs
     msg.set_from("inconnu");
     msg.set_type(SyncDemo::ChatMessage::OTHER);
     corrupted = true;
   }
 
-  delete [] buf;
-  buf = NULL;
-
   // display msg received from network
   // we have to do so; this function is called by ccnd thread
   // so if we call appendMsg directly
@@ -603,7 +480,7 @@
   if (!isHistory)
   {
     // update the tree view
-    std::string stdStrName = name.toStdString();
+    std::string stdStrName = data->getName().toUri();
     std::string stdStrNameWithoutSeq = stdStrName.substr(0, stdStrName.find_last_of('/'));
     std::string prefix = stdStrNameWithoutSeq.substr(0, stdStrNameWithoutSeq.find_last_of('/'));
     _LOG_DEBUG("<<< updating scene for" << prefix << ": " << msg.from());
@@ -643,14 +520,14 @@
   boost::random::random_device rng;
   boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
   m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
-  QTimer::singleShot(m_randomizedInterval, this, SLOT(sendHello()));
+  m_scheduler.scheduleEvent(time::milliseconds(m_randomizedInterval), bind(&ChatDialog::sendHello, this));
 }
 
 void
 ChatDialog::sendHello()
 {
-  time_t now = time(NULL);
-  int elapsed = now - m_lastMsgTime;
+  int64_t now = time::now();
+  int elapsed = (now - m_lastMsgTime) / 1000000000;
   if (elapsed >= m_randomizedInterval / 1000)
   {
     SyncDemo::ChatMessage msg;
@@ -659,11 +536,12 @@
     boost::random::random_device rng;
     boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
     m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
-    QTimer::singleShot(m_randomizedInterval, this, SLOT(sendHello()));
+    m_scheduler.scheduleEvent(time::milliseconds(m_randomizedInterval), bind(&ChatDialog::sendHello, this));
   }
   else
   {
-    QTimer::singleShot((m_randomizedInterval - elapsed * 1000), this, SLOT(sendHello()));
+    m_scheduler.scheduleEvent(time::milliseconds(m_randomizedInterval - elapsed * 1000), 
+                              bind(&ChatDialog::sendHello, this));
   }
 }
 
@@ -738,7 +616,8 @@
     _LOG_DEBUG("Reaped: prefix = " << prefix);
     m_zombieIndex++;
     // reap again in 10 seconds
-    QTimer::singleShot(10000, this, SLOT(reap()));
+    m_scheduler.scheduleEvent(time::milliseconds(10000), 
+                              bind(&ChatDialog::reap, this));
   }
 }
 
@@ -811,8 +690,6 @@
     }
     // resume new prefix
     m_user.setPrefix(newPrefix);
-    // Sync::CcnxWrapperPtr handle = Sync::CcnxWrapper::Create();
-    // handle->clearInterestFilter(oldPrefix.toStdString());
     delete m_sock;
     m_sock = NULL;
 
@@ -820,18 +697,19 @@
     {
       usleep(100000);
       m_sock = new Sync::SyncSocket(m_chatroomPrefix.toUri(),
-                                    m_syncPolicy,
+                                    m_syncValidator,
                                     m_face,
                                     bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
                                     bind(&ChatDialog::processRemoveWrapper, this, _1));
       usleep(100000);
-      // Sync::CcnxWrapperPtr handle = boost::make_shared<Sync::CcnxWrapper> ();
-      // handle->setInterestFilter(m_user.getPrefix().toStdString(), bind(&ChatDialog::respondHistoryRequest, this, _1));
-      QTimer::singleShot(600, this, SLOT(sendJoin()));
-      m_timer->start(FRESHNESS * 1000);
+      m_scheduler.scheduleEvent(time::milliseconds(600), bind(&ChatDialog::sendJoin, this));
+      if(static_cast<bool>(m_replotEventId))
+        m_scheduler.cancelEvent(m_replotEventId);
+      m_replotEventId = m_scheduler.schedulePeriodicEvent(time::seconds(0), time::milliseconds(FRESHNESS * 1000),
+                                                          bind(&ChatDialog::replot, this));
       disableTreeDisplay();
-      QTimer::singleShot(2200, this, SLOT(enableTreeDisplay()));
-    }catch(std::exception& e){
+      m_scheduler.scheduleEvent(time::milliseconds(2200), bind(&ChatDialog::enableTreeDisplay, this));
+    }catch(Face::Error& e){
       emit noNdnConnection(QString::fromStdString("Cannot conect to ndnd!\n Have you started your ndnd?"));
     }
   }
@@ -951,7 +829,7 @@
   msg.set_from(m_user.getNick().toStdString());
   msg.set_to(m_user.getChatroom().toStdString());
   msg.set_data(text.toUtf8().constData());
-  time_t seconds = time(NULL);
+  int32_t seconds = static_cast<int32_t>(time::now()/1000000000);
   msg.set_timestamp(seconds);
   msg.set_type(SyncDemo::ChatMessage::CHAT);
 }
@@ -961,7 +839,7 @@
 {
   msg.set_from(m_user.getNick().toStdString());
   msg.set_to(m_user.getChatroom().toStdString());
-  time_t seconds = time(NULL);
+  int32_t seconds = static_cast<int32_t>(time::now()/1000000000);
   msg.set_timestamp(seconds);
   msg.set_type(type);
 }
@@ -969,23 +847,37 @@
 void
 ChatDialog::updateLocalPrefix()
 {
-  m_newLocalPrefixReady = false;
   ndn::Name interestName("/local/ndn/prefix");
   ndn::Interest interest(interestName);
   interest.setInterestLifetime(1000);
 
   m_face->expressInterest(interest, 
                           bind(&ChatDialog::onLocalPrefix, this, _1, _2), 
-                          bind(&ChatDialog::onLocalPrefixTimeout, this, _1));
-  
-  while(m_newLocalPrefixReady == false)
-    {
-#if BOOST_VERSION >= 1050000
-      boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
-#else
-      boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-#endif
-    }
+                          bind(&ChatDialog::onLocalPrefixTimeout, this, _1));  
+}
+
+
+void
+ChatDialog::onLocalPrefix(const ndn::Interest& interest, 
+                          ndn::Data& data)
+{
+  string dataString(reinterpret_cast<const char*>(data.getContent().value()), data.getContent().value_size());
+  QString originPrefix = QString::fromStdString (dataString).trimmed ();
+  string trimmedString = originPrefix.toStdString();
+  m_newLocalPrefix = Name(trimmedString);
+
+  _LOG_DEBUG("now the prefix is " << m_newLocalPrefix.toUri());
+  _LOG_DEBUG("in use prefix is " << m_user.getOriginPrefix().toStdString());
+    
+  if (originPrefix != "" && m_user.getOriginPrefix () != originPrefix)
+    emit settingUpdated(m_user.getNick (), m_user.getChatroom (), originPrefix);
+}
+
+void
+ChatDialog::onLocalPrefixTimeout(const ndn::Interest& interest)
+{
+  m_newLocalPrefix = m_localPrefix;
+
   _LOG_DEBUG("now the prefix is " << m_newLocalPrefix.toUri());
   _LOG_DEBUG("in use prefix is " << m_user.getOriginPrefix().toStdString());
   QString originPrefix = QString::fromStdString(m_newLocalPrefix.toUri());
@@ -994,25 +886,6 @@
     emit settingUpdated(m_user.getNick (), m_user.getChatroom (), originPrefix);
 }
 
-
-void
-ChatDialog::onLocalPrefix(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest, 
-                          const ndn::ptr_lib::shared_ptr<ndn::Data>& data)
-{
-  string dataString(reinterpret_cast<const char*>(data->getContent().value()), data->getContent().value_size());
-  QString originPrefix = QString::fromStdString (dataString).trimmed ();
-  string trimmedString = originPrefix.toStdString();
-  m_newLocalPrefix = ndn::Name(trimmedString);
-  m_newLocalPrefixReady = true;
-}
-
-void
-ChatDialog::onLocalPrefixTimeout(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest)
-{
-  m_newLocalPrefix = m_localPrefix;
-  m_newLocalPrefixReady = true;
-}
-
 static std::string chars2("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789");
 
 QString
@@ -1193,6 +1066,7 @@
   size_t size = msg.ByteSize();
   char *buf = new char[size];
   msg.SerializeToArray(buf, size);
+  
   if (!msg.IsInitialized())
   {
     _LOG_DEBUG("Errrrr.. msg was not probally initialized "<<__FILE__ <<":"<<__LINE__<<". what is happening?");
@@ -1200,11 +1074,11 @@
   }
   m_sock->publishData(m_user.getPrefix().toStdString(), m_session, buf, size, FRESHNESS);
 
-  delete buf;
+  delete[] buf;
 
-  m_lastMsgTime = time(NULL);
+  m_lastMsgTime = time::now();
 
-  int nextSequence = m_sock->getNextSeq(m_user.getPrefix().toStdString(), m_session);
+  uint64_t nextSequence = m_sock->getNextSeq(m_user.getPrefix().toStdString(), m_session);
   Sync::MissingDataInfo mdi = {m_user.getPrefix().toStdString(), Sync::SeqNo(0), Sync::SeqNo(nextSequence - 1)};
   std::vector<Sync::MissingDataInfo> v;
   v.push_back(mdi);
@@ -1225,8 +1099,8 @@
 void
 ChatDialog::sendInvitationWrapper(QString invitee, bool isIntroducer)
 {
-  ndn::Name inviteeNamespace(invitee.toStdString());
-  ndn::ptr_lib::shared_ptr<ContactItem> inviteeItem = m_contactManager->getContact(inviteeNamespace);
+  Name inviteeNamespace(invitee.toStdString());
+  shared_ptr<ContactItem> inviteeItem = m_contactManager->getContact(inviteeNamespace);
   sendInvitation(inviteeItem, isIntroducer);
 }
 
diff --git a/src/chatdialog.h b/src/chatdialog.h
index 4dc5061..742b4ee 100644
--- a/src/chatdialog.h
+++ b/src/chatdialog.h
@@ -23,23 +23,25 @@
 #include "invitelistdialog.h"
 
 #ifndef Q_MOC_RUN
-#include <ndn-cpp-dev/data.hpp>
-#include <ndn-cpp-dev/face.hpp>
-#include <ndn-cpp-dev/security/key-chain.hpp>
-#include "sec-policy-chrono-chat-invitation.h"
 #include "contact-item.h"
-
-#include <sync-socket.h>
-#include <sync-seq-no.h>
 #include "chatbuf.pb.h"
 #include "digesttreescene.h"
+#include <sync-socket.h>
+#include <sync-seq-no.h>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#ifdef WITH_SECURITY
+#include "validator-invitation.h"
+#include <validator-sync.h>
+#else
+#include <ndn-cpp-dev/security/validator-null.hpp>
+#endif
 
 #include <boost/thread/locks.hpp>
 #include <boost/thread/recursive_mutex.hpp>
 #include <boost/thread/thread.hpp>
 #endif
 
-typedef ndn::func_lib::function<void()> OnEventualTimeout;
+typedef ndn::function<void()> OnEventualTimeout;
 
 #define MAX_HISTORY_ENTRY   20
 
@@ -52,20 +54,14 @@
   Q_OBJECT
 
 public:
-  explicit ChatDialog(ndn::ptr_lib::shared_ptr<ContactManager> contactManager,
+  explicit ChatDialog(ndn::shared_ptr<chronos::ContactManager> contactManager,
+                      ndn::shared_ptr<ndn::Face> face,
                       const ndn::Name& chatroomPrefix,
                       const ndn::Name& localPrefix,
                       const ndn::Name& defaultIdentity,
                       const std::string& nick,
-                      bool trial = false,
                       QWidget *parent = 0);
 
-  // explicit ChatDialog(const ndn::Name& chatroomPrefix,
-  //                     const ndn::Name& localPrefix,
-  //                     const ndn::Name& defaultIdentity,
-  //                     const ndn::security::IdentityCertificate& identityCertificate,
-  //                     QWidget *parent = 0);
-
   ~ChatDialog();
 
   const ndn::Name&
@@ -77,27 +73,27 @@
   { return m_localPrefix; }
 
   void
-  sendInvitation(ndn::ptr_lib::shared_ptr<ContactItem> contact, bool isIntroducer);
-
-  void
-  addTrustAnchor(const EndorseCertificate& selfEndorseCertificate);
+  sendInvitation(ndn::shared_ptr<chronos::ContactItem> contact, bool isIntroducer);
 
   void
   addChatDataRule(const ndn::Name& prefix, 
                   const ndn::IdentityCertificate& identityCertificate,
                   bool isIntroducer);
 
+  void
+  addTrustAnchor(const chronos::EndorseCertificate& selfEndorseCertificate);
+
   void 
   appendMessage(const SyncDemo::ChatMessage msg, bool isHistory = false);
 
   void 
-  processTreeUpdateWrapper(const std::vector<Sync::MissingDataInfo>, Sync::SyncSocket *);
+  processTreeUpdateWrapper(const std::vector<Sync::MissingDataInfo>&, Sync::SyncSocket *);
 
   void 
-  processDataWrapper(const ndn::ptr_lib::shared_ptr<ndn::Data>& data);
+  processDataWrapper(const ndn::shared_ptr<const ndn::Data>& data);
 
   void 
-  processDataNoShowWrapper(const ndn::ptr_lib::shared_ptr<ndn::Data>& data);
+  processDataNoShowWrapper(const ndn::shared_ptr<const ndn::Data>& data);
 
   void 
   processRemoveWrapper(std::string);
@@ -114,25 +110,6 @@
 
 private:
 
-  void 
-  startFace();
-
-  void
-  shutdownFace();
-
-  void
-  eventLoop();
-
-  void
-  connectToDaemon();
-
-  void
-  onConnectionData(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest,
-                   const ndn::ptr_lib::shared_ptr<ndn::Data>& data);
- 
-  void
-  onConnectionDataTimeout(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest);
-
   void
   initializeSetting();
 
@@ -146,32 +123,39 @@
   initializeSync();
 
   void
-  onTargetData(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest, 
-               const ndn::ptr_lib::shared_ptr<ndn::Data>& data,
-               const ndn::OnVerified& onVerified,
-               const ndn::OnVerifyFailed& onVerifyFailed);
+  onTargetData(const ndn::Interest& interest, 
+               const ndn::Data& data,
+               const ndn::OnDataValidated& onValidated,
+               const ndn::OnDataValidationFailed& onValidationFailed)
+  { m_invitationValidator->validate(data, onValidated, onValidationFailed); }
 
   void
-  onTargetTimeout(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest, 
+  onTargetTimeout(const ndn::Interest& interest, 
                   int retry,
-                  const ndn::OnVerified& onVerified,
-                  const ndn::OnVerifyFailed& onVerifyFailed,
-                  const OnEventualTimeout& timeoutNotify);
+                  const ndn::OnDataValidated& onValidated,
+                  const ndn::OnDataValidationFailed& onValidationFailed,
+                  const OnEventualTimeout& timeoutNotify)
+  {
+    if(retry > 0)
+      sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, retry-1);
+    else
+      timeoutNotify();
+  }
 
   void
   sendInterest(const ndn::Interest& interest,
-               const ndn::OnVerified& onVerified,
-               const ndn::OnVerifyFailed& onVerifyFailed,
+               const ndn::OnDataValidated& onValidated,
+               const ndn::OnDataValidationFailed& onValidationFailed,
                const OnEventualTimeout& timeoutNotify,
                int retry = 1);
   
   void 
-  onInviteReplyVerified(const ndn::ptr_lib::shared_ptr<ndn::Data>& data, 
-                        const ndn::Name& identity, 
-                        bool isIntroduce);
+  onInviteReplyValidated(const ndn::shared_ptr<const ndn::Data>& data, 
+                         const ndn::Name& identity, 
+                         bool isIntroduce);
 
   void
-  onInviteReplyVerifyFailed(const ndn::ptr_lib::shared_ptr<ndn::Data>& data,
+  onInviteReplyValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
                             const ndn::Name& identity);
 
   void 
@@ -183,16 +167,16 @@
   
   void 
   invitationAccepted(const ndn::Name& identity, 
-                     ndn::ptr_lib::shared_ptr<ndn::Data> data, 
+                     ndn::shared_ptr<const ndn::Data> data, 
                      const std::string& inviteePrefix, 
                      bool isIntroducer);
 
   void
-  onLocalPrefix(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest, 
-                const ndn::ptr_lib::shared_ptr<ndn::Data>& data);
+  onLocalPrefix(const ndn::Interest& interest, 
+                ndn::Data& data);
 
   void
-  onLocalPrefixTimeout(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest);
+  onLocalPrefixTimeout(const ndn::Interest& interest);
 
   // void 
   // fetchHistory(std::string name);
@@ -230,10 +214,10 @@
   void 
   disableTreeDisplay();
 
-signals:
-  void 
-  dataReceived(QString name, const char *buf, size_t len, bool show, bool isHistory);
-  
+signals:  
+  void
+  dataReceived(ndn::shared_ptr<const ndn::Data> data, bool show, bool isHistory);
+
   void 
   treeUpdated(const std::vector<Sync::MissingDataInfo>);
   
@@ -251,10 +235,10 @@
 
 public slots:
   void 
-  processTreeUpdate(const std::vector<Sync::MissingDataInfo>);
+  processTreeUpdate(const std::vector<Sync::MissingDataInfo>&);
 
   void 
-  processData(QString name, const char *buf, size_t len, bool show, bool isHistory);
+  processData(ndn::shared_ptr<const ndn::Data> data, bool show, bool isHistory);
 
   void 
   processRemove(QString prefix);
@@ -316,34 +300,42 @@
     
 private:
   Ui::ChatDialog *ui;
-  ndn::ptr_lib::shared_ptr<ContactManager> m_contactManager;
+  ndn::shared_ptr<chronos::ContactManager> m_contactManager;
+  ndn::shared_ptr<ndn::Face> m_face;
+  ndn::shared_ptr<boost::asio::io_service> m_ioService;
+
   ndn::Name m_chatroomPrefix;
   ndn::Name m_localPrefix;
   ndn::Name m_localChatPrefix;
   ndn::Name m_defaultIdentity;
-  ndn::ptr_lib::shared_ptr<SecPolicyChronoChatInvitation> m_invitationPolicy;
-  ndn::ptr_lib::shared_ptr<SecPolicySync> m_syncPolicy; 
-  ndn::ptr_lib::shared_ptr<ndn::Verifier> m_verifier;
-  ndn::ptr_lib::shared_ptr<ndn::KeyChain> m_keyChain;
-  ndn::ptr_lib::shared_ptr<ndn::Face> m_face;
+  User m_user; 
+  std::string m_nick;
 
-  boost::recursive_mutex m_mutex;
-  boost::thread m_thread;
-  bool m_running;
+  ndn::Scheduler m_scheduler;
+  ndn::EventId m_replotEventId;
+
+#ifndef WITH_SECURITY
+  ndn::shared_ptr<ndn::Validator> m_invitationValidator;
+  ndn::shared_ptr<ndn::Validator> m_syncValidator; 
+#else
+  ndn::shared_ptr<chronos::ValidatorInvitation> m_invitationValidator;
+  ndn::shared_ptr<Sync::ValidatorSync> m_syncValidator;
+#endif
+  ndn::shared_ptr<ndn::KeyChain> m_keyChain;
 
   ndn::Name m_newLocalPrefix;
   bool m_newLocalPrefixReady;
 
-  User m_user; 
-  std::string m_nick;
+
   Sync::SyncSocket *m_sock;
-  uint32_t m_session;
+  uint64_t m_session;
   DigestTreeScene *m_scene;
   boost::recursive_mutex m_msgMutex;
   boost::recursive_mutex m_sceneMutex;
-  time_t m_lastMsgTime;
+  int64_t m_lastMsgTime;
   int m_randomizedInterval;
-  QTimer *m_timer;
+
+
   QStringListModel *m_rosterModel;
   QSystemTrayIcon *trayIcon;
 
@@ -354,8 +346,6 @@
   QAction *quitAction;
   QMenu *trayIconMenu;
 
-  // QQueue<SyncDemo::ChatMessage> m_history;
-  // bool m_historyInitialized;
   bool m_joined;
 
   QList<QString> m_zombieList;
diff --git a/src/chronos-invitation.cpp b/src/chronos-invitation.cpp
deleted file mode 100644
index b6084ab..0000000
--- a/src/chronos-invitation.cpp
+++ /dev/null
@@ -1,114 +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: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "chronos-invitation.h"
-
-#include <ndn-cpp-dev/security/identity-certificate.hpp>
-#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
-
-#include "logging.h"
-
-using namespace std;
-using namespace ndn;
-
-INIT_LOGGER("ChronosInvitation");
-
-
-const size_t ChronosInvitation::NAME_SIZE_MIN = 8;
-const size_t ChronosInvitation::INVITEE_START = 4;
-const ssize_t SIGNATURE      = -1;
-const ssize_t KEY_LOCATOR    = -2;
-const ssize_t INVITER_PREFIX = -3;
-const ssize_t CHATROOM       = -4;
-const Name ChronosInvitation::INVITATION_PREFIX("/ndn/broadcast/chronos/chat-invitation");
-
-
-ChronosInvitation::ChronosInvitation(const Name& originalInterestName)
-  : m_interestName(originalInterestName)
-{
-
-  size_t nameSize = originalInterestName.size();
-
-  if(nameSize < NAME_SIZE_MIN)
-    throw Error("Wrong ChronosInvitation Name: Wrong length"); 
- 
-  if(!INVITATION_PREFIX.isPrefixOf(originalInterestName))
-    throw Error("Wrong ChronosInvitation Name: Wrong invitation prefix");
-
-  //hack! should be more efficient.
-  Name signedName = originalInterestName.getPrefix(-1);
-  m_signedBlob = Buffer(signedName.wireEncode().value(), signedName.wireEncode().value_size());
-
-  Block signatureBlock(originalInterestName.get(SIGNATURE).getValue().buf(),
-                       originalInterestName.get(SIGNATURE).getValue().size());
-  Block signatureInfo(originalInterestName.get(KEY_LOCATOR).getValue().buf(),
-                      originalInterestName.get(KEY_LOCATOR).getValue().size());
-  m_signature = Signature(Signature(signatureInfo, signatureBlock));
-
-  SignatureSha256WithRsa sha256RsaSig(m_signature); 
-  m_inviterCertificateName = sha256RsaSig.getKeyLocator().getName();
-  
-  m_inviterNameSpace = IdentityCertificate::certificateNameToPublicKeyName(m_inviterCertificateName).getPrefix(-1);
-
-  m_inviterRoutingPrefix.wireDecode(Block(originalInterestName.get(INVITER_PREFIX).getValue().buf(),
-                                          originalInterestName.get(INVITER_PREFIX).getValue().size()));
-  
-  m_chatroom.wireDecode(Block(originalInterestName.get(CHATROOM).getValue().buf(),
-                              originalInterestName.get(CHATROOM).getValue().size()));
-
-  m_inviteeNameSpace = originalInterestName.getSubName(INVITEE_START, nameSize - NAME_SIZE_MIN);  
-  
-  m_isSigned = true;
-}
-
-ChronosInvitation::ChronosInvitation(const Name &inviteeNameSpace,
-                                     const Name &chatroom,
-                                     const Name &inviterRoutingPrefix,
-                                     const Name &inviterCertificateName)
-  : m_inviteeNameSpace(inviteeNameSpace)
-  , m_chatroom(chatroom)
-  , m_inviterRoutingPrefix(inviterRoutingPrefix)
-  , m_inviterCertificateName(inviterCertificateName)
-{
-  //implicit conversion, we do not keep version number in KeyLocator;
-  SignatureSha256WithRsa sha256RsaSig; 
-  sha256RsaSig.setKeyLocator(KeyLocator(inviterCertificateName.getPrefix(-1)));
-  m_signature.setInfo(sha256RsaSig.getInfo());
-  m_inviterNameSpace = IdentityCertificate::certificateNameToPublicKeyName(m_inviterCertificateName).getPrefix(-1);
-  
-  m_interestName = INVITATION_PREFIX;
-  m_interestName.append(inviteeNameSpace).append(chatroom.wireEncode()).append(inviterRoutingPrefix.wireEncode()).append(m_signature.getInfo());
-
-  m_signedBlob = Buffer(m_interestName.wireEncode().value(), m_interestName.wireEncode().value_size());
-  m_isSigned = false;
-}
-
-ChronosInvitation::ChronosInvitation(const ChronosInvitation& invitation)
-  : m_interestName(invitation.m_interestName)
-  , m_signedBlob(invitation.m_signedBlob)
-  , m_inviteeNameSpace(invitation.m_inviteeNameSpace)
-  , m_chatroom(invitation.m_chatroom)
-  , m_inviterRoutingPrefix(invitation.m_inviterRoutingPrefix)
-  , m_inviterCertificateName(invitation.m_inviterCertificateName)
-  , m_signature(invitation.m_signature)
-  , m_inviterNameSpace(invitation.m_inviterNameSpace)
-  , m_isSigned(invitation.m_isSigned)
-{}
-
-void
-ChronosInvitation::setSignatureValue(const ndn::Block &signatureValue)
-{
-  if(m_isSigned)
-    return;
-
-  m_interestName.append(signatureValue);
-  m_signature.setValue(signatureValue);
-  m_isSigned = true;
-}
diff --git a/src/chronos-invitation.h b/src/chronos-invitation.h
deleted file mode 100644
index d17a144..0000000
--- a/src/chronos-invitation.h
+++ /dev/null
@@ -1,103 +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: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef CHRONOS_INVITATION_H
-#define CHRONOS_INVITATION_H
-
-
-#include <ndn-cpp-dev/name.hpp>
-#include <ndn-cpp-dev/signature.hpp>
-
-class ChronosInvitation
-{
-/*
- * /ndn/broadcast/chronos/invitation/[invitee_namespace]/<chatroom_name>/<inviter_routing_prefix>/<keylocator>/<signature>
- */
-  static const size_t NAME_SIZE_MIN;
-  static const size_t INVITEE_START;
-  static const ssize_t SIGNATURE;
-  static const ssize_t KEY_LOCATOR;
-  static const ssize_t INVITER_PREFIX;
-  static const ssize_t CHATROOM;
-  static const ndn::Name INVITATION_PREFIX;
-
-public:
-  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
-
-  ChronosInvitation() {}
-
-  ChronosInvitation(const ndn::Name& interestName);
-
-  ChronosInvitation(const ndn::Name &inviteeNameSpace,
-                    const ndn::Name &chatroom,
-                    const ndn::Name &inviterRoutingPrefix,
-                    const ndn::Name &inviterCertificateName);
-
-  ChronosInvitation(const ChronosInvitation& invitation);
-
-  virtual
-  ~ChronosInvitation() {};
-
-  const ndn::Name&
-  getInviteeNameSpace() const
-  { return m_inviteeNameSpace; }
-
-  const ndn::Name&
-  getChatroom() const
-  { return m_chatroom; }
-
-  const ndn::Name&
-  getInviterRoutingPrefix() const
-  { return m_inviterRoutingPrefix; }
-
-  const ndn::Name&
-  getInviterCertificateName() const
-  { return m_inviterCertificateName; }
-
-  const ndn::Signature&
-  getSignature() const
-  { return m_signature; }
-
-  const ndn::Name&
-  getInviterNameSpace() const
-  { return m_inviterNameSpace; }
-
-  const ndn::Buffer&
-  getSignedBlob() const
-  { return m_signedBlob; }
-  
-  const ndn::Name&
-  getInterestName() const
-  {
-    if(m_isSigned)
-      return m_interestName; 
-    else
-      throw Error("Invitation is not signed!");
-  }
-
-  void
-  setSignatureValue(const ndn::Block &signatureValue);
-
-private:
-  ndn::Name m_interestName;
-  ndn::Buffer m_signedBlob;
-
-  ndn::Name m_inviteeNameSpace;
-  ndn::Name m_chatroom;
-  ndn::Name m_inviterRoutingPrefix;
-  ndn::Name m_inviterCertificateName;
-  ndn::Signature m_signature;
-
-  ndn::Name m_inviterNameSpace;
-
-  bool m_isSigned;
-};
-
-#endif
diff --git a/src/contact-item.cpp b/src/contact-item.cpp
index 3ea941b..13201ae 100644
--- a/src/contact-item.cpp
+++ b/src/contact-item.cpp
@@ -14,10 +14,11 @@
 
 using namespace std;
 using namespace ndn;
-using namespace ndn::ptr_lib;
 
 INIT_LOGGER("ContactItem");
 
+namespace chronos{
+
 ContactItem::ContactItem(const EndorseCertificate& selfEndorseCertificate,
                          bool isIntroducer,
                          const string& alias)
@@ -29,10 +30,9 @@
   m_namespace = endorsedkeyName.getSubName(0, endorsedkeyName.size() - 1);
 
 
-  const ProfileData& profileData = selfEndorseCertificate.getProfileData();
-  m_name = profileData.getProfile().getProfileEntry("name");
+  m_name = selfEndorseCertificate.getProfile().get("name");
   m_alias = alias.empty() ? m_name : alias;
-  m_institution = profileData.getProfile().getProfileEntry("institution");
+  m_institution = selfEndorseCertificate.getProfile().get("institution");
 }
 
 ContactItem::ContactItem(const ContactItem& contactItem)
@@ -43,16 +43,6 @@
   , m_institution(contactItem.m_institution)
   , m_isIntroducer(contactItem.m_isIntroducer)
   , m_trustScope(contactItem.m_trustScope)
-  , m_trustScopeName(contactItem.m_trustScopeName)
 {}
 
-bool 
-ContactItem::canBeTrustedFor(const Name& name)
-{
-  vector<shared_ptr<Regex> >::iterator it = m_trustScope.begin();
-
-  for(; it != m_trustScope.end(); it++)
-    if((*it)->match(name))
-      return true;
-  return false;
 }
diff --git a/src/contact-item.h b/src/contact-item.h
index 4442ada..bd3ab8a 100644
--- a/src/contact-item.h
+++ b/src/contact-item.h
@@ -8,22 +8,25 @@
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
  */
 
-#ifndef LINKNDN_CONTACT_ITEM_H
-#define LINKNDN_CONTACT_ITEM_H
+#ifndef CHRONOS_CONTACT_ITEM_H
+#define CHRONOS_CONTACT_ITEM_H
 
-#include <ndn-cpp-dev/data.hpp>
-#include <ndn-cpp-et/regex/regex.hpp>
-#include <vector>
 #include "endorse-certificate.h"
+#include <ndn-cpp-dev/util/regex.hpp>
+#include <vector>
+
+
+namespace chronos{
 
 class ContactItem
 {
-  typedef std::vector<ndn::ptr_lib::shared_ptr<EndorseCertificate> > EndorseCertificateList;
-
 public:
+  typedef std::map<ndn::Name, ndn::shared_ptr<ndn::Regex> >::const_iterator const_iterator;
+  typedef std::map<ndn::Name, ndn::shared_ptr<ndn::Regex> >::iterator iterator;
+
   ContactItem(const EndorseCertificate& selfEndorseCertificate,
               bool isIntroducer = false,
-              const std::string& alias = std::string());
+              const std::string& alias = "");
 
   ContactItem(const ContactItem& contactItem);
   
@@ -50,7 +53,7 @@
   getInstitution() const
   { return m_institution; }
 
-  const ndn::Name
+  const ndn::Name&
   getPublicKeyName() const
   { return m_selfEndorseCertificate.getPublicKeyName(); }
 
@@ -64,17 +67,43 @@
 
   void
   addTrustScope(const ndn::Name& nameSpace)
+  { m_trustScope[nameSpace] = ndn::Regex::fromName(nameSpace); }
+
+  void
+  deleteTrustScope(const ndn::Name& nameSpace)
   {
-    m_trustScopeName.push_back(nameSpace);
-    m_trustScope.push_back(ndn::Regex::fromName(nameSpace)); 
+    std::map<ndn::Name, ndn::shared_ptr<ndn::Regex> >::iterator it = m_trustScope.find(nameSpace);
+    if(it != m_trustScope.end())
+      m_trustScope.erase(it);
   }
 
   bool
-  canBeTrustedFor(const ndn::Name& name);
+  canBeTrustedFor(const ndn::Name& name)
+  {
+    std::map<ndn::Name, ndn::shared_ptr<ndn::Regex> >::iterator it = m_trustScope.begin();
 
-  const std::vector<ndn::Name>&
-  getTrustScopeList() const
-  { return m_trustScopeName; }
+    for(; it != m_trustScope.end(); it++)
+      if(it->second->match(name))
+        return true;
+    return false;
+  }
+
+  const_iterator
+  trustScopeBegin() const
+  { return m_trustScope.begin(); }
+
+  const_iterator
+  trustScopeEnd() const
+  { return m_trustScope.end(); }
+
+  iterator
+  trustScopeBegin()
+  { return m_trustScope.begin(); }
+
+  iterator
+  trustScopeEnd()
+  { return m_trustScope.end(); }
+
 
 protected:
   EndorseCertificate m_selfEndorseCertificate;
@@ -87,8 +116,9 @@
 
   bool m_isIntroducer;
 
-  std::vector<ndn::ptr_lib::shared_ptr<ndn::Regex> > m_trustScope;
-  std::vector<ndn::Name> m_trustScopeName;
+  std::map<ndn::Name, ndn::shared_ptr<ndn::Regex> > m_trustScope;
 };
 
+}//chronos
+
 #endif
diff --git a/src/contact-manager.cpp b/src/contact-manager.cpp
index f2ff6cc..f755965 100644
--- a/src/contact-manager.cpp
+++ b/src/contact-manager.cpp
@@ -9,15 +9,7 @@
  */
 
 #if __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wreorder"
 #pragma clang diagnostic ignored "-Wtautological-compare"
-#pragma clang diagnostic ignored "-Wunused-variable"
-#pragma clang diagnostic ignored "-Wunused-function"
-#elif __GNUC__
-#pragma GCC diagnostic ignored "-Wreorder"
-#pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-function"
 #endif
 
 
@@ -26,31 +18,33 @@
 #ifndef Q_MOC_RUN
 #include <ndn-cpp-dev/face.hpp>
 #include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
-#include <ndn-cpp-dev/security/verifier.hpp>
+
+#ifndef WITH_SECURITY
+#include <ndn-cpp-dev/security/validator-null.hpp>
+#else
+#include <ndn-cpp-dev/security/validator-regex.hpp>
 #include <cryptopp/base64.h>
-#include <ndn-cpp-et/policy/sec-rule-relative.hpp>
-#include <ndn-cpp-et/policy/sec-policy-simple.hpp>
-#include <fstream>
+#include <ndn-cpp-dev/security/sec-rule-relative.hpp>
+#endif
+
 #include "endorse-collection.pb.h"
 #include "logging.h"
 #endif
 
 using namespace ndn;
-using namespace ndn::ptr_lib;
 using namespace std;
 
 INIT_LOGGER("ContactManager");
 
-ContactManager::ContactManager(shared_ptr<KeyChain> keyChain, 
-                               shared_ptr<Face> face,
-                               QObject* parent)
-  : QObject(parent),
-    m_face(face)
-{
-  m_keyChain = keyChain;
-  m_contactStorage = make_shared<ContactStorage>();
-  m_dnsStorage = make_shared<DnsStorage>();
+namespace chronos{
 
+ContactManager::ContactManager(shared_ptr<Face> face,
+                               QObject* parent)
+  : QObject(parent)
+  , m_contactStorage(new ContactStorage())
+  , m_dnsStorage(new DnsStorage())
+  , m_face(face)
+{
   initializeSecurity();
 }
 
@@ -60,6 +54,14 @@
 void
 ContactManager::initializeSecurity()
 {
+  
+#ifndef WITH_SECURITY
+  
+  m_keyChain = make_shared<KeyChain>();
+  m_validator = make_shared<ValidatorNull>();
+
+#else
+
   shared_ptr<SecPolicySimple> policy = make_shared<SecPolicySimple>();
   m_verifier = make_shared<Verifier>(policy);
   m_verifier->setFace(m_face);
@@ -116,37 +118,6 @@
   data.wireDecode(Block(reinterpret_cast<const uint8_t*>(decoded.c_str()), decoded.size()));
   shared_ptr<IdentityCertificate> anchor = make_shared<IdentityCertificate>(data);
   policy->addTrustAnchor(anchor);  
-
-#ifdef _DEBUG
-
-  const string FakeAnchor("BIICqgOyEIVAaoHnQZIx5osAuY2fKte4HBSrxyam7MY6/kp+w47O1bGdd2KjeZKV\
-zZzQd3EQorDC3KUPbB6ql30jYfspvo4OPSlIuDrkyROaoZ+MSKyzQYpB6CZcTjBa\
-qcWYFOfwUlcWvkbd00X4bkc5PkcWpVdRrx+NCTiq9EXes//hOHpEJHMNsJUi45O+\
-6M4OE6/sNEqs/ryHn2w1vCqwPpG8xzcd0prQUdCH2MGE77F+H0XFDuWp8mrT37Uw\
-DUy7Ltm+7nDTHSQy2J3Zk4Q+0tjxCzSw4owEpwOHr+afdkuE3v9aB2NRQBBDCEmL\
-Ykz4sYX3XE8MVFqRn1HHWCkszjDg+F0UAADy+p1uZG4A+p1LRVkA+vVrc2stMTM4\
-MjkzNDE5OAD6vUlELUNFUlQA+s39/////95rc7MAAAGiA+IChaK1eVvzlkg6BJAw\
-qiOpxRoezQ0hAHOBbPRLeBllxMN7AAK6tQUm3mtztQAB4gHq8vqdbmRuAPqdS0VZ\
-APr1a3NrLTEzODI5MzQxOTgA+r1JRC1DRVJUAAAAAAABmhblMIIBaDAiGA8yMDEz\
-MTAyODAwMDAwMFoYDzIwMzMxMDI4MDAwMDAwWjAcMBoGA1UEKRMTL25kbi9rc2st\
-MTM4MjkzNDE5ODCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2htIFF\
-/PH+SJsGOA6jhpFT74xfLJlgZNJOnKzl27HI2gupE0mainWj/HqVzdGxD6jOOReI\
-sul+eQyEyBYq4e35pLmdJGlux/+UPQ51DD8jg04GrUPewV7+iGm6usp/7xEGHbah\
-H2Grv/bsGrt6aRA8cKmdIc+rehxZCVFtiwSEHTnOWzn3lfZR5xnjF9aGX+uGo1hA\
-gMwu1ECxg4H3O4z1tbTzji5+WH0RDsPRlgzQX6wAQH8btlQyoFJfljEA3QaOtDaB\
-OcfegIlClzutmgJnK9i5ZLz2Mjvx49dlCWAVKg65vOXMLC/33jD9F+V8urwsBlOb\
-F7Wh5ayeo8NBKDsCAwEAAQAA");
-
-  string decoded2;
-  CryptoPP::StringSource ss2(reinterpret_cast<const unsigned char *>(FakeAnchor.c_str()), 
-                            FakeAnchor.size(), 
-                            true,
-                            new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded2)));
-  Data data2;
-  data2.wireDecode(Block(reinterpret_cast<const uint8_t*>(decoded.c_str()), decoded.size()));
-  shared_ptr<IdentityCertificate>anchor2 = make_shared<IdentityCertificate>(data2);
-  policy->addTrustAnchor(anchor2);  
-
 #endif
 }
 
@@ -158,206 +129,94 @@
   interestName.append("DNS").append("PROFILE");
   
   Interest interest(interestName);
+  interest.setMustBeFresh(true);
 
-  OnVerified onVerified = func_lib::bind(&ContactManager::onDnsSelfEndorseCertificateVerified, this, _1, identity);
-  OnVerifyFailed onVerifyFailed = func_lib::bind(&ContactManager::onDnsSelfEndorseCertificateVerifyFailed, this, _1, identity);
-  TimeoutNotify timeoutNotify = func_lib::bind(&ContactManager::onDnsSelfEndorseCertificateTimeoutNotify, this, identity);
+  OnDataValidated onValidated = bind(&ContactManager::onDnsSelfEndorseCertValidated, this, _1, identity);
+  OnDataValidationFailed onValidationFailed = bind(&ContactManager::onDnsSelfEndorseCertValidationFailed, this, _1, identity);
+  TimeoutNotify timeoutNotify = bind(&ContactManager::onDnsSelfEndorseCertTimeoutNotify, this, identity);
 
-  sendInterest(interest, onVerified, onVerifyFailed, timeoutNotify);
+  sendInterest(interest, onValidated, onValidationFailed, timeoutNotify);
 }
 
 void
-ContactManager::onDnsSelfEndorseCertificateTimeoutNotify(const Name& identity)
-{ emit contactFetchFailed(identity); }
-
-void
-ContactManager::onDnsSelfEndorseCertificateVerified(const shared_ptr<Data>& data, 
-                                                    const Name& identity)
+ContactManager::onDnsSelfEndorseCertValidated(const shared_ptr<const Data>& data, 
+                                              const Name& identity)
 {
   try{
     Data plainData;
-    plainData.wireDecode(Block(data->getContent().value(), data->getContent().value_size()));
+    plainData.wireDecode(data->getContent().blockFromValue());
     EndorseCertificate selfEndorseCertificate(plainData);
-    if(Verifier::verifySignature(plainData, plainData.getSignature(), selfEndorseCertificate.getPublicKeyInfo()))
-      emit contactFetched (selfEndorseCertificate); 
+    if(Validator::verifySignature(plainData, plainData.getSignature(), selfEndorseCertificate.getPublicKeyInfo()))
+      emit contactFetched(selfEndorseCertificate); 
     else
-      emit contactFetchFailed (identity);
-  }catch(std::exception& e){
-    _LOG_ERROR("Exception: " << e.what());
+      emit contactFetchFailed(identity);
+  }catch(...){
     emit contactFetchFailed (identity);
   }
 }
 
 void
-ContactManager::onDnsSelfEndorseCertificateVerifyFailed(const shared_ptr<Data>& data, 
-                                                        const Name& identity)
-{ emit contactFetchFailed (identity); }
-
-void
-ContactManager::fetchCollectEndorse(const ndn::Name& identity)
+ContactManager::fetchCollectEndorse(const Name& identity)
 {
   Name interestName = identity;
   interestName.append("DNS").append("ENDORSED");
 
   Interest interest(interestName);
   interest.setInterestLifetime(1000);
+  interest.setMustBeFresh(true);
 
-  OnVerified onVerified = func_lib::bind(&ContactManager::onDnsCollectEndorseVerified, this, _1, identity);
-  OnVerifyFailed onVerifyFailed = func_lib::bind(&ContactManager::onDnsCollectEndorseVerifyFailed, this, _1, identity);
-  TimeoutNotify timeoutNotify = func_lib::bind(&ContactManager::onDnsCollectEndorseTimeoutNotify, this, identity);
+  OnDataValidated onValidated = bind(&ContactManager::onDnsCollectEndorseValidated, this, _1, identity);
+  OnDataValidationFailed onValidationFailed = bind(&ContactManager::onDnsCollectEndorseValidationFailed, this, _1, identity);
+  TimeoutNotify timeoutNotify = bind(&ContactManager::onDnsCollectEndorseTimeoutNotify, this, identity);
 
-  sendInterest(interest, onVerified, onVerifyFailed, timeoutNotify);
+  sendInterest(interest, onValidated, onValidationFailed, timeoutNotify);
 }
 
 void
-ContactManager::onDnsCollectEndorseTimeoutNotify(const Name& identity)
-{
-  emit collectEndorseFetchFailed (identity);
-}
-
-void
-ContactManager::onDnsCollectEndorseVerified(const shared_ptr<Data>& data, const Name& identity)
-{ emit collectEndorseFetched (*data); }
-
-void
-ContactManager::onDnsCollectEndorseVerifyFailed(const shared_ptr<Data>& data, const Name& identity)
-{ emit collectEndorseFetchFailed (identity); }
-
-
-void
-ContactManager::fetchKey(const ndn::Name& certName)
+ContactManager::fetchKey(const Name& certName)
 {
   Name interestName = certName;
   
   Interest interest(interestName);
   interest.setInterestLifetime(1000);
+  interest.setMustBeFresh(true);
 
-  OnVerified onVerified = func_lib::bind(&ContactManager::onKeyVerified, this, _1, certName);
-  OnVerifyFailed onVerifyFailed = func_lib::bind(&ContactManager::onKeyVerifyFailed, this, _1, certName);
-  TimeoutNotify timeoutNotify = func_lib::bind(&ContactManager::onKeyTimeoutNotify, this, certName);
+  OnDataValidated onValidated = bind(&ContactManager::onKeyValidated, this, _1, certName);
+  OnDataValidationFailed onValidationFailed = bind(&ContactManager::onKeyValidationFailed, this, _1, certName);
+  TimeoutNotify timeoutNotify = bind(&ContactManager::onKeyTimeoutNotify, this, certName);
 
-  sendInterest(interest, onVerified, onVerifyFailed, timeoutNotify);
+  sendInterest(interest, onValidated, onValidationFailed, timeoutNotify);
 }
 
-
 void
-ContactManager::onKeyVerified(const shared_ptr<Data>& data, const Name& identity)
+ContactManager::onKeyValidated(const shared_ptr<const Data>& data, const Name& identity)
 {
   IdentityCertificate identityCertificate(*data);
-
   Profile profile(identityCertificate);
-  ProfileData profileData(profile);
-
-  Name certificateName = m_keyChain->getDefaultCertificateName();
-  m_keyChain->sign(profileData, certificateName);
 
   try{
-    EndorseCertificate endorseCertificate(identityCertificate, profileData);
-    m_keyChain->sign(endorseCertificate, certificateName);
+    EndorseCertificate endorseCertificate(identityCertificate, profile);
+    m_keyChain->sign(endorseCertificate);
     emit contactKeyFetched (endorseCertificate); 
-  }catch(std::exception& e){
-    _LOG_ERROR("Exception: " << e.what());
+  }catch(...){
     return;
   }
 }
 
 void
-ContactManager::onKeyVerifyFailed(const shared_ptr<Data>& data, const Name& identity)
-{ 
-  _LOG_DEBUG("Key cannot be verified!");
-  emit contactKeyFetchFailed (identity); 
-}
-
-void
-ContactManager::onKeyTimeoutNotify(const Name& identity)
-{ 
-  _LOG_DEBUG("Key timeout!");
-  emit contactKeyFetchFailed(identity); 
-}
-
-void
 ContactManager::fetchIdCertificate(const Name& certName)
 {
   Name interestName = certName;
   
   Interest interest(interestName);
   interest.setInterestLifetime(1000);
+  interest.setMustBeFresh(true);
 
-  OnVerified onVerified = boost::bind(&ContactManager::onIdCertificateVerified, this, _1, certName);
-  OnVerifyFailed onVerifyFailed = boost::bind(&ContactManager::onIdCertificateVerifyFailed, this, _1, certName);
-  TimeoutNotify timeoutNotify = boost::bind(&ContactManager::onIdCertificateTimeoutNotify, this, certName);
+  OnDataValidated onValidated = bind(&ContactManager::onIdCertValidated, this, _1, certName);
+  OnDataValidationFailed onValidationFailed = bind(&ContactManager::onIdCertValidationFailed, this, _1, certName);
+  TimeoutNotify timeoutNotify = bind(&ContactManager::onIdCertTimeoutNotify, this, certName);
 
-  sendInterest(interest, onVerified, onVerifyFailed, timeoutNotify);
-}
-
-void
-ContactManager::onIdCertificateTimeoutNotify(const Name& identity)
-{ 
-  emit contactCertificateFetchFailed (identity); 
-}
-
-
-void
-ContactManager::onIdCertificateVerified(const shared_ptr<Data>& data, const Name& identity)
-{
-  IdentityCertificate identityCertificate(*data);
-  emit contactCertificateFetched(identityCertificate);
-}
-
-void
-ContactManager::onIdCertificateVerifyFailed(const shared_ptr<Data>& data, const Name& identity)
-{ 
-  emit contactCertificateFetchFailed (identity); 
-}
-
-void
-ContactManager::onTargetData(const shared_ptr<const ndn::Interest>& interest, 
-                             const shared_ptr<Data>& data,
-                             const OnVerified& onVerified,
-                             const OnVerifyFailed& onVerifyFailed)
-{
-  m_verifier->verifyData(data, onVerified, onVerifyFailed);
-}
-
-void
-ContactManager::onTargetTimeout(const shared_ptr<const ndn::Interest>& interest, 
-                                int retry,
-                                const OnVerified& onVerified,
-                                const OnVerifyFailed& onVerifyFailed,
-                                const TimeoutNotify& timeoutNotify)
-{
-  if(retry > 0)
-    sendInterest(*interest, onVerified, onVerifyFailed, timeoutNotify, retry-1);
-  else
-    {
-      _LOG_DEBUG("Interest: " << interest->getName().toUri() << " eventually times out!");
-      timeoutNotify();
-    }
-}
-
-void
-ContactManager::sendInterest(const Interest& interest,
-                             const OnVerified& onVerified,
-                             const OnVerifyFailed& onVerifyFailed,
-                             const TimeoutNotify& timeoutNotify,
-                             int retry /* = 1 */)
-{
-  uint64_t id = m_face->expressInterest(interest, 
-                          boost::bind(&ContactManager::onTargetData, 
-                                      this,
-                                      _1,
-                                      _2,
-                                      onVerified, 
-                                      onVerifyFailed),
-                          boost::bind(&ContactManager::onTargetTimeout,
-                                      this,
-                                      _1,
-                                      retry,
-                                      onVerified,
-                                      onVerifyFailed,
-                                      timeoutNotify));
-
-  // _LOG_DEBUG("id: " << id << " entry id: " << m_face->getNode().getEntryIndexForExpressedInterest(interest.getName()));
+  sendInterest(interest, onValidated, onValidationFailed, timeoutNotify);
 }
 
 void
@@ -365,21 +224,15 @@
 {
   // Get current profile;
   shared_ptr<Profile> newProfile = m_contactStorage->getSelfProfile(identity);
-  if(static_cast<bool>(newProfile))
+  if(!static_cast<bool>(newProfile))
     return;
 
   shared_ptr<EndorseCertificate> newEndorseCertificate = getSignedSelfEndorseCertificate(identity, *newProfile);
 
-  if(static_cast<bool>(newEndorseCertificate))
+  if(!static_cast<bool>(newEndorseCertificate))
     return;
 
-  // Check if profile exists
-  try{
-    Block profileDataBlob = m_contactStorage->getSelfEndorseCertificate(identity);
-    m_contactStorage->updateSelfEndorseCertificate(*newEndorseCertificate, identity);
-  }catch(ContactStorage::Error &e){
-    m_contactStorage->addSelfEndorseCertificate(*newEndorseCertificate, identity);
-  }
+  m_contactStorage->addSelfEndorseCertificate(*newEndorseCertificate, identity);
 
   publishSelfEndorseCertificateInDNS(*newEndorseCertificate);
 }
@@ -389,15 +242,10 @@
 {
   shared_ptr<EndorseCertificate> newEndorseCertificate = generateEndorseCertificate(identity, signerIdentity);
 
-  if(static_cast<bool>(newEndorseCertificate))
+  if(!static_cast<bool>(newEndorseCertificate))
     return;
 
-  try{
-    Block oldEndorseCertificateBlob = m_contactStorage->getEndorseCertificate(identity);
-    m_contactStorage->updateEndorseCertificate(*newEndorseCertificate, identity);
-  }catch(ContactStorage::Error &e){
-    m_contactStorage->addEndorseCertificate(*newEndorseCertificate, identity);
-  }
+  m_contactStorage->addEndorseCertificate(*newEndorseCertificate, identity);
 
   publishEndorseCertificateInDNS(*newEndorseCertificate, signerIdentity);
 }
@@ -406,34 +254,23 @@
 ContactManager::generateEndorseCertificate(const Name& identity, const Name& signerIdentity)
 {
   shared_ptr<ContactItem> contact = getContact(identity);
-  if(static_cast<bool>(contact))
+  if(!static_cast<bool>(contact))
     return shared_ptr<EndorseCertificate>();
 
   Name signerKeyName = m_keyChain->getDefaultKeyNameForIdentity(signerIdentity);
-  Name signerCertName = m_keyChain->getDefaultCertificateNameForIdentity(signerIdentity);
 
   vector<string> endorseList;
   m_contactStorage->getEndorseList(identity, endorseList);
 
-  
   try{
     shared_ptr<EndorseCertificate> cert = make_shared<EndorseCertificate>(contact->getSelfEndorseCertificate(), signerKeyName, endorseList); 
-    m_keyChain->sign(*cert, signerCertName);
+    m_keyChain->signByIdentity(*cert, signerIdentity);
     return cert;
-  }catch(std::exception& e){
-    _LOG_ERROR("Exception: " << e.what());
+  }catch(...){
     return shared_ptr<EndorseCertificate>();
   } 
 }
 
-void
-ContactManager::getContactItemList(vector<shared_ptr<ContactItem> >& contacts)
-{ return m_contactStorage->getAllContacts(contacts); }
-
-shared_ptr<ContactItem>
-ContactManager::getContact(const ndn::Name& contactNamespace)
-{ return m_contactStorage->getContact(contactNamespace); }
-
 shared_ptr<EndorseCertificate>
 ContactManager::getSignedSelfEndorseCertificate(const Name& identity,
                                                 const Profile& profile)
@@ -442,33 +279,28 @@
   if(0 == certificateName.size())
     return shared_ptr<EndorseCertificate>();
 
-  ProfileData profileData(profile);
-  m_keyChain->sign(profileData, certificateName);
-
-  shared_ptr<IdentityCertificate> signingCert = m_keyChain->getCertificate(certificateName);
-  if(static_cast<bool>(signingCert))
-    return shared_ptr<EndorseCertificate>();
-
-  Name signingKeyName = IdentityCertificate::certificateNameToPublicKeyName(signingCert->getName());
-
+  Name signingKeyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
   shared_ptr<IdentityCertificate> kskCert;
-  if(signingKeyName.get(-1).toEscapedString().substr(0,4) == string("dsk-"))
+
+  if(signingKeyName.get(-1).toEscapedString().substr(0,4) == "dsk-")
     {
-      SignatureSha256WithRsa dskCertSig(signingCert->getSignature());
-      // HACK! KSK certificate should be retrieved from network.
-      Name keyName = IdentityCertificate::certificateNameToPublicKeyName(dskCertSig.getKeyLocator().getName());
+      shared_ptr<IdentityCertificate> signingCert = m_keyChain->getCertificate(certificateName);
+      if(!static_cast<bool>(signingCert))
+        return shared_ptr<EndorseCertificate>();
 
-      // TODO: check null existing cases.
-      Name kskCertName = m_keyChain->getDefaultCertificateNameForIdentity(keyName.getPrefix(-1));
-
-      kskCert = m_keyChain->getCertificate(kskCertName);
-    }
+      try{
+        SignatureSha256WithRsa dskCertSig(signingCert->getSignature());
+        Name keyName = IdentityCertificate::certificateNameToPublicKeyName(dskCertSig.getKeyLocator().getName());
+        Name kskCertName = m_keyChain->getDefaultCertificateNameForKey(keyName);
+        kskCert = m_keyChain->getCertificate(kskCertName);
+      }catch(...){
+        return shared_ptr<EndorseCertificate>();
+      }
+    }      
   else
-    {
-      kskCert = signingCert;
-    }
+    kskCert = m_keyChain->getCertificate(certificateName);
 
-  if(static_cast<bool>(kskCert))
+  if(!static_cast<bool>(kskCert))
     return shared_ptr<EndorseCertificate>();
 
   vector<string> endorseList;
@@ -477,40 +309,28 @@
     endorseList.push_back(it->first);
   
   try{
-    shared_ptr<EndorseCertificate> selfEndorseCertificate = make_shared<EndorseCertificate>(*kskCert, profileData, endorseList);
+    shared_ptr<EndorseCertificate> selfEndorseCertificate = make_shared<EndorseCertificate>(*kskCert, profile, endorseList);
     m_keyChain->sign(*selfEndorseCertificate, kskCert->getName());
-
     return selfEndorseCertificate;
-  }catch(std::exception& e){
-    _LOG_ERROR("Exception: " << e.what());
+  }catch(...){
     return shared_ptr<EndorseCertificate>();
   } 
 }
 
-
 void
 ContactManager::publishSelfEndorseCertificateInDNS(const EndorseCertificate& selfEndorseCertificate)
 {
   Data data;
 
-  Name keyName = selfEndorseCertificate.getPublicKeyName();
-  Name identity = keyName.getSubName(0, keyName.size()-1);
-
-  time_t nowSeconds = time(NULL);
-  struct tm current = *gmtime(&nowSeconds);
-  MillisecondsSince1970 version = timegm(&current) * 1000.0;
+  Name identity = selfEndorseCertificate.getPublicKeyName().getPrefix(-1);
 
   Name dnsName = identity;
-  dnsName.append("DNS").append("PROFILE").appendVersion(version);
+  dnsName.append("DNS").append("PROFILE").appendVersion();
   data.setName(dnsName);
-
   data.setContent(selfEndorseCertificate.wireEncode());
 
-  Name signCertName = m_keyChain->getDefaultCertificateNameForIdentity(identity);
-  m_keyChain->sign(data, signCertName);
-
+  m_keyChain->signByIdentity(data, identity);
   m_dnsStorage->updateDnsSelfProfileData(data, identity);
-  
   m_face->put(data);
 }
 
@@ -519,38 +339,26 @@
 {
   Data data;
 
-  Name keyName = endorseCertificate.getPublicKeyName();
-  Name endorsee = keyName.getSubName(0, keyName.size()-1);
-
-  time_t nowSeconds = time(NULL);
-  struct tm current = *gmtime(&nowSeconds);
-  MillisecondsSince1970 version = timegm(&current) * 1000.0;
+  Name endorsee = endorseCertificate.getPublicKeyName().getPrefix(-1);
 
   Name dnsName = signerIdentity;
-  dnsName.append("DNS").append(endorsee).append("ENDORSEE").appendVersion(version);
+  dnsName.append("DNS").append(endorsee.wireEncode()).append("ENDORSEE").appendVersion();
   data.setName(dnsName);
 
   data.setContent(endorseCertificate.wireEncode());
 
-  Name signCertName = m_keyChain->getDefaultCertificateNameForIdentity(signerIdentity);
-  m_keyChain->sign(data, signCertName);
-
+  m_keyChain->signByIdentity(data, signerIdentity);
   m_dnsStorage->updateDnsEndorseOthers(data, signerIdentity, endorsee);
-
   m_face->put(data);
 }
 
 void
-ContactManager::publishEndorsedDataInDns(const Name& identity)
+ContactManager::publishCollectEndorsedDataInDNS(const Name& identity)
 {
   Data data;
 
-  time_t nowSeconds = time(NULL);
-  struct tm current = *gmtime(&nowSeconds);
-  MillisecondsSince1970 version = timegm(&current) * 1000.0;
-
   Name dnsName = identity;
-  dnsName.append("DNS").append("ENDORSED").appendVersion(version);
+  dnsName.append("DNS").append("ENDORSED").appendVersion();
   data.setName(dnsName);
   
   vector<Buffer> collectEndorseList;
@@ -570,27 +378,18 @@
 
   data.setContent(reinterpret_cast<const uint8_t*>(encoded.c_str()), encoded.size());
   
-  Name signCertName = m_keyChain->getDefaultCertificateNameForIdentity(identity);
-  m_keyChain->sign(data, signCertName);
-
+  m_keyChain->signByIdentity(data, identity);
   m_dnsStorage->updateDnsOthersEndorse(data, identity);
-
   m_face->put(data);
 }
 
 void
 ContactManager::addContact(const IdentityCertificate& identityCertificate, const Profile& profile)
 {
-  ProfileData profileData(profile);
-  
-  Name certificateName = m_keyChain->getDefaultCertificateNameForIdentity (m_defaultIdentity);
-  m_keyChain->sign(profileData, certificateName);
-
-
   try{
-    EndorseCertificate endorseCertificate(identityCertificate, profileData);
+    EndorseCertificate endorseCertificate(identityCertificate, profile);
     
-    m_keyChain->sign(endorseCertificate, certificateName);
+    m_keyChain->signByIdentity(endorseCertificate, m_defaultIdentity);
 
     ContactItem contactItem(endorseCertificate);
 
@@ -598,7 +397,7 @@
 
     emit contactAdded(contactItem.getNameSpace());
 
-  }catch(std::exception& e){
+  }catch(std::runtime_error& e){
     emit warning(e.what());
     _LOG_ERROR("Exception: " << e.what());
     return;
@@ -606,15 +405,17 @@
 }
 
 void
-ContactManager::removeContact(const ndn::Name& contactNameSpace)
+ContactManager::removeContact(const Name& contactNameSpace)
 {
   shared_ptr<ContactItem> contact = getContact(contactNameSpace);
-  if(static_cast<bool>(contact))
+  if(!static_cast<bool>(contact))
     return;
   m_contactStorage->removeContact(contactNameSpace);
   emit contactRemoved(contact->getPublicKeyName());
 }
 
+}//chronos
+
 
 #if WAF
 #include "contact-manager.moc"
diff --git a/src/contact-manager.h b/src/contact-manager.h
index 84f1d22..c61a720 100644
--- a/src/contact-manager.h
+++ b/src/contact-manager.h
@@ -8,8 +8,8 @@
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
  */
 
-#ifndef LINKNDN_CONTACT_MANAGER_H
-#define LINKNDN_CONTACT_MANAGER_H
+#ifndef CHRONOS_CONTACT_MANAGER_H
+#define CHRONOS_CONTACT_MANAGER_H
 
 #include <QObject>
 
@@ -20,18 +20,19 @@
 #include "profile.h"
 #include <ndn-cpp-dev/face.hpp>
 #include <ndn-cpp-dev/security/key-chain.hpp>
-#include <ndn-cpp-dev/security/verifier.hpp>
+#include <ndn-cpp-dev/security/validator.hpp>
 #endif
 
-typedef ndn::func_lib::function<void()> TimeoutNotify;
+namespace chronos{
+
+typedef ndn::function<void()> TimeoutNotify;
 
 class ContactManager : public QObject
 {
   Q_OBJECT
 
 public:
-  ContactManager(ndn::ptr_lib::shared_ptr<ndn::KeyChain> keyChain,
-                 ndn::ptr_lib::shared_ptr<ndn::Face> m_face,
+  ContactManager(ndn::shared_ptr<ndn::Face> m_face,
                  QObject* parent = 0);
 
   ~ContactManager();
@@ -54,17 +55,17 @@
   void
   updateEndorseCertificate(const ndn::Name& identity, const ndn::Name& signerIdentity);
 
-  void
-  getContactItemList(std::vector<ndn::ptr_lib::shared_ptr<ContactItem> >& contacts);
+  inline void
+  getContactItemList(std::vector<ndn::shared_ptr<ContactItem> >& contacts);
 
-  ndn::ptr_lib::shared_ptr<ContactStorage>
+  ndn::shared_ptr<ContactStorage>
   getContactStorage()
   { return m_contactStorage; }
 
-  ndn::ptr_lib::shared_ptr<ContactItem>
+  inline ndn::shared_ptr<ContactItem>
   getContact(const ndn::Name& contactNamespace);
 
-  ndn::ptr_lib::shared_ptr<DnsStorage>
+  ndn::shared_ptr<DnsStorage>
   getDnsStorage()
   { return m_dnsStorage; }
 
@@ -73,7 +74,7 @@
   { return m_keyChain->getDefaultIdentity(); }
 
   void
-  publishEndorsedDataInDns(const ndn::Name& identity);
+  publishCollectEndorsedDataInDNS(const ndn::Name& identity);
 
   void
   setDefaultIdentity(const ndn::Name& identity)
@@ -85,18 +86,14 @@
   void
   removeContact(const ndn::Name& contactNameSpace);
   
-  // ndn::ptr_lib::shared_ptr<ndn::KeyChain>
-  // getKeyChain()
-  // { return m_keyChain; }
-
 private:  
   void
   initializeSecurity();
 
-  ndn::ptr_lib::shared_ptr<EndorseCertificate>
+  ndn::shared_ptr<EndorseCertificate>
   getSignedSelfEndorseCertificate(const ndn::Name& identity, const Profile& profile);
 
-  ndn::ptr_lib::shared_ptr<EndorseCertificate> 
+  ndn::shared_ptr<EndorseCertificate> 
   generateEndorseCertificate(const ndn::Name& identity, const ndn::Name& signerIdentity);
 
   void
@@ -105,65 +102,64 @@
   void
   publishEndorseCertificateInDNS(const EndorseCertificate& endorseCertificate, const ndn::Name& signerIdentity);
 
-  void
+  inline void
   sendInterest(const ndn::Interest& interest,
-               const ndn::OnVerified& onVerified,
-               const ndn::OnVerifyFailed& onVerifyFailed,
+               const ndn::OnDataValidated& onValidated,
+               const ndn::OnDataValidationFailed& onValidationFailed,
                const TimeoutNotify& timeoutNotify,
                int retry = 1);
 
-  void
-  onTargetData(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest, 
-               const ndn::ptr_lib::shared_ptr<ndn::Data>& data,
-               const ndn::OnVerified& onVerified,
-               const ndn::OnVerifyFailed& onVerifyFailed);
+  inline void
+  onTargetData(const ndn::Interest& interest, 
+               const ndn::Data& data,
+               const ndn::OnDataValidated& onValidated,
+               const ndn::OnDataValidationFailed& onValidationFailed);
 
-  void
-  onTargetTimeout(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest, 
+  inline void
+  onTargetTimeout(const ndn::Interest& interest, 
                   int retry,
-                  const ndn::OnVerified& onVerified,
-                  const ndn::OnVerifyFailed& onVerifyFailed,
+                  const ndn::OnDataValidated& onValidated,
+                  const ndn::OnDataValidationFailed& onValidationFailed,
                   const TimeoutNotify& timeoutNotify);
 
-
-  void
-  onDnsSelfEndorseCertificateTimeoutNotify(const ndn::Name& identity);
-
   void 
-  onDnsSelfEndorseCertificateVerified(const ndn::ptr_lib::shared_ptr<ndn::Data>& selfEndorseCertificate, const ndn::Name& identity);
+  onDnsSelfEndorseCertValidated(const ndn::shared_ptr<const ndn::Data>& selfEndorseCertificate, const ndn::Name& identity);
 
-  void
-  onDnsSelfEndorseCertificateVerifyFailed(const ndn::ptr_lib::shared_ptr<ndn::Data>& selfEndorseCertificate, const ndn::Name& identity);
+  inline void
+  onDnsSelfEndorseCertValidationFailed(const ndn::shared_ptr<const ndn::Data>& selfEndorseCertificate, const ndn::Name& identity);
+
+  inline void
+  onDnsSelfEndorseCertTimeoutNotify(const ndn::Name& identity);
  
 
-  void
-  onDnsCollectEndorseVerified(const ndn::ptr_lib::shared_ptr<ndn::Data>& data, const ndn::Name& identity);
+  inline void
+  onDnsCollectEndorseValidated(const ndn::shared_ptr<const ndn::Data>& data, const ndn::Name& identity);
 
-  void
-  onDnsCollectEndorseVerifyFailed(const ndn::ptr_lib::shared_ptr<ndn::Data>& data, const ndn::Name& identity);
+  inline void
+  onDnsCollectEndorseValidationFailed(const ndn::shared_ptr<const ndn::Data>& data, const ndn::Name& identity);
 
-  void
+  inline void
   onDnsCollectEndorseTimeoutNotify(const ndn::Name& identity);
 
 
   void
-  onKeyVerified(const ndn::ptr_lib::shared_ptr<ndn::Data>& data, const ndn::Name& identity);
+  onKeyValidated(const ndn::shared_ptr<const ndn::Data>& data, const ndn::Name& identity);
 
-  void
-  onKeyVerifyFailed(const ndn::ptr_lib::shared_ptr<ndn::Data>& data, const ndn::Name& identity);
+  inline void
+  onKeyValidationFailed(const ndn::shared_ptr<const ndn::Data>& data, const ndn::Name& identity);
 
-  void
+  inline void
   onKeyTimeoutNotify(const ndn::Name& identity);
 
 
-  void
-  onIdCertificateVerified(const ndn::ptr_lib::shared_ptr<ndn::Data>& data, const ndn::Name& identity);
+  inline void
+  onIdCertValidated(const ndn::shared_ptr<const ndn::Data>& data, const ndn::Name& identity);
 
-  void
-  onIdCertificateVerifyFailed(const ndn::ptr_lib::shared_ptr<ndn::Data>& data, const ndn::Name& identity);
+  inline void
+  onIdCertValidationFailed(const ndn::shared_ptr<const ndn::Data>& data, const ndn::Name& identity);
 
-  void
-  onIdCertificateTimeoutNotify(const ndn::Name& identity);
+  inline void
+  onIdCertTimeoutNotify(const ndn::Name& identity);
   
 
 signals:
@@ -171,13 +167,13 @@
   noNdnConnection(const QString& msg);
   
   void 
-  contactFetched(const EndorseCertificate& endorseCertificate);
+  contactFetched(const chronos::EndorseCertificate& endorseCertificate);
   
   void
   contactFetchFailed(const ndn::Name& identity);
 
   void
-  contactKeyFetched(const EndorseCertificate& endorseCertificate);
+  contactKeyFetched(const chronos::EndorseCertificate& endorseCertificate);
 
   void
   contactKeyFetchFailed(const ndn::Name& identity);
@@ -208,12 +204,106 @@
   
 private:
 
-  ndn::ptr_lib::shared_ptr<ContactStorage> m_contactStorage;
-  ndn::ptr_lib::shared_ptr<DnsStorage> m_dnsStorage;
-  ndn::ptr_lib::shared_ptr<ndn::Verifier> m_verifier;
-  ndn::ptr_lib::shared_ptr<ndn::KeyChain> m_keyChain;
-  ndn::ptr_lib::shared_ptr<ndn::Face> m_face;
+  ndn::shared_ptr<ContactStorage> m_contactStorage;
+  ndn::shared_ptr<DnsStorage> m_dnsStorage;
+  ndn::shared_ptr<ndn::Validator> m_validator;
+  ndn::shared_ptr<ndn::Face> m_face;
+  ndn::shared_ptr<ndn::KeyChain> m_keyChain;
   ndn::Name m_defaultIdentity;
 };
 
+void
+ContactManager::sendInterest(const ndn::Interest& interest,
+                             const ndn::OnDataValidated& onValidated,
+                             const ndn::OnDataValidationFailed& onValidationFailed,
+                             const TimeoutNotify& timeoutNotify,
+                             int retry /* = 1 */)
+{
+  m_face->expressInterest(interest, 
+                          bind(&ContactManager::onTargetData, 
+                               this, _1, _2, onValidated, onValidationFailed),
+                          bind(&ContactManager::onTargetTimeout,
+                               this, _1, retry, onValidated, onValidationFailed, timeoutNotify));
+}
+
+void
+ContactManager::onTargetData(const ndn::Interest& interest, 
+                             const ndn::Data& data,
+                             const ndn::OnDataValidated& onValidated,
+                             const ndn::OnDataValidationFailed& onValidationFailed)
+{ m_validator->validate(data, onValidated, onValidationFailed); }
+
+void
+ContactManager::onTargetTimeout(const ndn::Interest& interest, 
+                                int retry,
+                                const ndn::OnDataValidated& onValidated,
+                                const ndn::OnDataValidationFailed& onValidationFailed,
+                                const TimeoutNotify& timeoutNotify)
+{
+  if(retry > 0)
+    sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, retry-1);
+  else
+    timeoutNotify();
+}
+
+
+void
+ContactManager::onDnsSelfEndorseCertValidationFailed(const ndn::shared_ptr<const ndn::Data>& data, 
+                                                     const ndn::Name& identity)
+{ emit contactFetchFailed (identity); }
+
+void
+ContactManager::onDnsSelfEndorseCertTimeoutNotify(const ndn::Name& identity)
+{ emit contactFetchFailed(identity); }
+
+void
+ContactManager::onDnsCollectEndorseValidated(const ndn::shared_ptr<const ndn::Data>& data, 
+                                            const ndn::Name& identity)
+{ emit collectEndorseFetched (*data); }
+
+void
+ContactManager::onDnsCollectEndorseValidationFailed(const ndn::shared_ptr<const ndn::Data>& data, 
+                                                const ndn::Name& identity)
+{ emit collectEndorseFetchFailed (identity); }
+
+void
+ContactManager::onDnsCollectEndorseTimeoutNotify(const ndn::Name& identity)
+{ emit collectEndorseFetchFailed (identity); }
+
+void
+ContactManager::onKeyValidationFailed(const ndn::shared_ptr<const ndn::Data>& data, 
+                                  const ndn::Name& identity)
+{ emit contactKeyFetchFailed (identity); }
+
+void
+ContactManager::onKeyTimeoutNotify(const ndn::Name& identity)
+{ emit contactKeyFetchFailed(identity); }
+
+void
+ContactManager::onIdCertValidated(const ndn::shared_ptr<const ndn::Data>& data, 
+                                        const ndn::Name& identity)
+{
+  ndn::IdentityCertificate identityCertificate(*data);
+  emit contactCertificateFetched(identityCertificate);
+}
+
+void
+ContactManager::onIdCertValidationFailed(const ndn::shared_ptr<const ndn::Data>& data, 
+                                            const ndn::Name& identity)
+{ emit contactCertificateFetchFailed (identity); }
+
+void
+ContactManager::onIdCertTimeoutNotify(const ndn::Name& identity)
+{ emit contactCertificateFetchFailed (identity); }
+
+ndn::shared_ptr<ContactItem>
+ContactManager::getContact(const ndn::Name& contactNamespace)
+{ return m_contactStorage->getContact(contactNamespace); }
+
+void
+ContactManager::getContactItemList(std::vector<ndn::shared_ptr<ContactItem> >& contacts)
+{ return m_contactStorage->getAllContacts(contacts); }
+
+}//chronos
+
 #endif
diff --git a/src/contact-storage.cpp b/src/contact-storage.cpp
index 384e74e..f107f0c 100644
--- a/src/contact-storage.cpp
+++ b/src/contact-storage.cpp
@@ -15,11 +15,12 @@
 
 using namespace std;
 using namespace ndn;
-using namespace ndn::ptr_lib;
 namespace fs = boost::filesystem;
 
 INIT_LOGGER ("ContactStorage");
 
+namespace chronos{
+
 const string INIT_SP_TABLE = "\
 CREATE TABLE IF NOT EXISTS                                           \n \
   SelfProfile(                                                       \n \
@@ -118,187 +119,52 @@
   if (res != SQLITE_OK)
     throw Error("Chronos DB cannot be open/created");
 
-  // Check if SelfProfile table exists
-  sqlite3_stmt *stmt;
-  sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='SelfProfile'", -1, &stmt, 0);
-  res = sqlite3_step (stmt);
+  initializeTable("SelfProfile", INIT_SP_TABLE);
+  initializeTable("SelfEndorse", INIT_SE_TABLE);
+  initializeTable("Contact", INIT_CONTACT_TABLE);
+  initializeTable("TrustScope", INIT_TS_TABLE);
+  initializeTable("ContactProfile", INIT_CP_TABLE);
+  initializeTable("ProfileEndorse", INIT_PE_TABLE);
+  initializeTable("CollectEndorse", INIT_CE_TABLE);
 
-  bool spTableExist = false;
-  if (res == SQLITE_ROW)
-      spTableExist = true;
-  sqlite3_finalize (stmt);
-
-  if(!spTableExist)
-    {
-      char *errmsg = 0;
-      res = sqlite3_exec (m_db, INIT_SP_TABLE.c_str (), NULL, NULL, &errmsg);
-      if (res != SQLITE_OK && errmsg != 0)
-        throw Error("Init \"error\" in SelfProfile");
-    }
-
-  // Check if SelfEndorse table exists
-  sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='SelfEndorse'", -1, &stmt, 0);
-  res = sqlite3_step (stmt);
-
-  bool seTableExist = false;
-  if (res == SQLITE_ROW)
-      seTableExist = true;
-  sqlite3_finalize (stmt);
-
-  if(!seTableExist)
-    {
-      char *errmsg = 0;
-      res = sqlite3_exec (m_db, INIT_SE_TABLE.c_str (), NULL, NULL, &errmsg);
-      if (res != SQLITE_OK && errmsg != 0)
-        throw Error("Init \"error\" in SelfEndorse");
-    }
-
-
-  // Check if Contact table exists
-  sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='Contact'", -1, &stmt, 0);
-  res = sqlite3_step (stmt);
-
-  bool contactTableExist = false;
-  if (res == SQLITE_ROW)
-      contactTableExist = true;
-  sqlite3_finalize (stmt);
-
-  if(!contactTableExist)
-    {
-      char *errmsg = 0;
-      res = sqlite3_exec (m_db, INIT_CONTACT_TABLE.c_str (), NULL, NULL, &errmsg);
-      if (res != SQLITE_OK && errmsg != 0)
-        throw Error("Init \"error\" in Contact");
-    }
-
-  // Check if TrustScope table exists
-  sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='TrustScope'", -1, &stmt, 0);
-  res = sqlite3_step (stmt);
-
-  bool tsTableExist = false;
-  if (res == SQLITE_ROW)
-      tsTableExist = true;
-  sqlite3_finalize (stmt);
-
-  if(!tsTableExist)
-    {
-      char *errmsg = 0;
-      res = sqlite3_exec (m_db, INIT_TS_TABLE.c_str (), NULL, NULL, &errmsg);
-      if (res != SQLITE_OK && errmsg != 0)
-        throw Error("Init \"error\" in TrustScope");
-    }
-
-  // Check if ContactProfile table exists
-  sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='ContactProfile'", -1, &stmt, 0);
-  res = sqlite3_step (stmt);
-
-  bool cpTableExist = false;
-  if (res == SQLITE_ROW)
-      cpTableExist = true;
-  sqlite3_finalize (stmt);
-
-  if(!cpTableExist)
-    {
-      char *errmsg = 0;
-      res = sqlite3_exec (m_db, INIT_CP_TABLE.c_str (), NULL, NULL, &errmsg);
-      if (res != SQLITE_OK && errmsg != 0)
-        throw Error("Init \"error\" in ContactProfile");
-    }
-
-  // Check if ProfileEndorse table exists
-  sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='ProfileEndorse'", -1, &stmt, 0);
-  res = sqlite3_step (stmt);
-
-  bool peTableExist = false;
-  if (res == SQLITE_ROW)
-      peTableExist = true;
-  sqlite3_finalize (stmt);
-
-  if(!peTableExist)
-    {
-      char *errmsg = 0;
-      res = sqlite3_exec (m_db, INIT_PE_TABLE.c_str (), NULL, NULL, &errmsg);
-      if (res != SQLITE_OK && errmsg != 0)
-        throw Error("Init \"error\" in ProfileEndorse");
-    }
-
-  // Check if CollectEndorse table exists
-  sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='CollectEndorse'", -1, &stmt, 0);
-  res = sqlite3_step (stmt);
-
-  bool ceTableExist = false;
-  if (res == SQLITE_ROW)
-      ceTableExist = true;
-  sqlite3_finalize (stmt);
-
-  if(!ceTableExist)
-    {
-      char *errmsg = 0;
-      res = sqlite3_exec (m_db, INIT_CE_TABLE.c_str (), NULL, NULL, &errmsg);
-      if (res != SQLITE_OK && errmsg != 0)
-        throw Error("Init \"error\" in CollectEndorse");
-    }
-}
-
-bool
-ContactStorage::doesSelfEntryExist(const Name& identity, const string& profileType)
-{
-  bool result = false;
-  
-  sqlite3_stmt *stmt;
-  sqlite3_prepare_v2 (m_db, "SELECT count(*) FROM SelfProfile WHERE profile_type=? and profile_identity=?", -1, &stmt, 0);
-  sqlite3_bind_text(stmt, 1, profileType.c_str(), profileType.size(), SQLITE_TRANSIENT);
-  sqlite3_bind_text(stmt, 2, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
-
-  int res = sqlite3_step (stmt);
-    
-  if (res == SQLITE_ROW)
-    {
-      int countAll = sqlite3_column_int (stmt, 0);
-      if (countAll > 0)
-        result = true;
-    } 
-  sqlite3_finalize (stmt); 
-  return result;
 }
 
 void
-ContactStorage::setSelfProfileEntry(const Name& identity, const string& profileType, const Buffer &profileValue)
+ContactStorage::initializeTable(const string& tableName, const string& sqlCreateStmt)
 {
-  sqlite3_stmt *stmt;  
-  if(doesSelfEntryExist(identity, profileType))
-    {
-      sqlite3_prepare_v2 (m_db, "UPDATE SelfProfile SET profile_value=? WHERE profile_type=? and profile_identity=?", -1, &stmt, 0);
-      sqlite3_bind_text(stmt, 1, reinterpret_cast<const char*>(profileValue.buf()), profileValue.size(), SQLITE_TRANSIENT);
-      sqlite3_bind_text(stmt, 2, profileType.c_str(), profileType.size(), SQLITE_TRANSIENT);
-      sqlite3_bind_text(stmt, 3, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
-    }
-  else
-    {
-      sqlite3_prepare_v2 (m_db, "INSERT INTO SelfProfile (profile_identity, profile_type, profile_value) values (?, ?, ?)", -1, &stmt, 0);
-      sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
-      sqlite3_bind_text(stmt, 2, profileType.c_str(), profileType.size(), SQLITE_TRANSIENT);
-      sqlite3_bind_text(stmt, 3, reinterpret_cast<const char*>(profileValue.buf()), profileValue.size(), SQLITE_TRANSIENT);
-    }
-  sqlite3_step (stmt);
+  sqlite3_stmt *stmt;
+  sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name=?", -1, &stmt, 0);
+  sqlite3_bind_text(stmt, 1, tableName.c_str(), tableName.size(), SQLITE_TRANSIENT);
+  int res = sqlite3_step (stmt);
+
+  bool tableExist = false;
+  if (res == SQLITE_ROW)
+      tableExist = true;
   sqlite3_finalize (stmt);
+
+  if(!tableExist)
+    {
+      char *errmsg = 0;
+      res = sqlite3_exec (m_db, sqlCreateStmt.c_str (), NULL, NULL, &errmsg);
+      if (res != SQLITE_OK && errmsg != 0)
+        throw Error("Init \"error\" in " + tableName);
+    }
 }
 
 shared_ptr<Profile>
-ContactStorage::getSelfProfile(const Name& identity)
-{
+ContactStorage::getSelfProfile(const Name& identity) const
+{  
+  shared_ptr<Profile> profile;
   sqlite3_stmt *stmt;
-  shared_ptr<Profile> profile = make_shared<Profile>(identity);
-  
-  sqlite3_prepare_v2(m_db, "SELECT profile_type, profile_value FROM SelfProfile WHERE profile_identity=?", -1, &stmt, 0);
-  sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
+  sqlite3_prepare_v2 (m_db, "SELECT profile_type, profile_value FROM SelfProfile WHERE profile_identity=?", -1, &stmt, 0);
+  sqlite3_bind_text (stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
 
-  while(sqlite3_step (stmt) == SQLITE_ROW)
+  while( sqlite3_step (stmt) == SQLITE_ROW)
     {
+      profile = make_shared<Profile>(identity);
       string profileType(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
       string profileValue(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1));
-
-      profile->setProfileEntry(profileType, profileValue );
+      (*profile)[profileType] = profileValue;
     }
 
   sqlite3_finalize(stmt);
@@ -306,15 +172,132 @@
   return profile;
 }
 
+// Block
+// ContactStorage::getSelfEndorseCertificate(const Name& identity)
+// {
+//   sqlite3_stmt *stmt;
+//   sqlite3_prepare_v2 (m_db, "SELECT endorse_data FROM SelfEndorse where identity=?", -1, &stmt, 0);
+//   sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
+
+//   if(sqlite3_step (stmt) == SQLITE_ROW)
+//     {
+//       Block result(reinterpret_cast<const uint8_t*>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
+//       sqlite3_finalize (stmt);
+//       return result;
+//     }
+
+//   sqlite3_finalize (stmt);
+
+//   throw Error("ContactStorage: No self-endorse certificate found!");
+// }
+
+void
+ContactStorage::addSelfEndorseCertificate(const EndorseCertificate& newEndorseCertificate, const Name& identity)
+{
+  const Block& newEndorseCertificateBlock = newEndorseCertificate.wireEncode();
+
+  sqlite3_stmt *stmt;
+  sqlite3_prepare_v2 (m_db, "INSERT OR REPLACE INTO SelfEndorse (identity, endorse_data) values (?, ?)", -1, &stmt, 0);
+  sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 2, reinterpret_cast<const char*>(newEndorseCertificateBlock.wire()), newEndorseCertificateBlock.size(), SQLITE_TRANSIENT);
+  sqlite3_step(stmt);
+
+  sqlite3_finalize (stmt);
+}
+
+// Block
+// ContactStorage::getEndorseCertificate(const Name& identity)
+// {
+//   sqlite3_stmt *stmt;
+//   sqlite3_prepare_v2 (m_db, "SELECT endorse_data FROM ProfileEndorse where identity=?", -1, &stmt, 0);
+//   sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
+
+  
+//   if(sqlite3_step (stmt) == SQLITE_ROW)
+//     {
+//       Block result(reinterpret_cast<const uint8_t*>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
+//       sqlite3_finalize (stmt);
+//       return result;
+//     }
+
+//   sqlite3_finalize (stmt);
+
+//   throw Error("ContactStorage: No endorse certificate found!");
+  
+//   return Block();
+// }
+
+void
+ContactStorage::addEndorseCertificate(const EndorseCertificate& endorseCertificate, const Name& identity)
+{
+  const Block& newEndorseCertificateBlock = endorseCertificate.wireEncode();
+
+  sqlite3_stmt *stmt;
+  sqlite3_prepare_v2 (m_db, "INSERT OR REPLACE INTO ProfileEndorse (identity, endorse_data) values (?, ?)", -1, &stmt, 0);
+  sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 2, reinterpret_cast<const char*>(newEndorseCertificateBlock.value()), newEndorseCertificateBlock.size(), SQLITE_TRANSIENT);
+  sqlite3_step(stmt);
+
+  sqlite3_finalize (stmt);
+}
+
+void
+ContactStorage::updateCollectEndorse(const EndorseCertificate& endorseCertificate)
+{
+  Name endorserName = endorseCertificate.getSigner();
+  Name keyName = endorseCertificate.getPublicKeyName();
+  Name endorseeName = keyName.getPrefix(keyName.size()-1);
+  Name getCertName = endorseCertificate.getName();
+
+  sqlite3_stmt *stmt;
+  sqlite3_prepare_v2 (m_db, "INSERT OR REPLACE INTO CollectEndorse (endorser, endorsee, endorse_name, endorse_data) VALUES (?, ?, ?, ?)", -1, &stmt, 0);
+  sqlite3_bind_text(stmt, 1, endorserName.toUri().c_str(), endorserName.toUri().size(), SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 2, endorseeName.toUri().c_str(), endorseeName.toUri().size(), SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 3, getCertName.toUri().c_str(), getCertName.toUri().size(), SQLITE_TRANSIENT);
+  const Block &block = endorseCertificate.wireEncode();
+  sqlite3_bind_text(stmt, 4, reinterpret_cast<const char*>(block.wire()), block.size(), SQLITE_TRANSIENT);
+  int res = sqlite3_step (stmt);
+  sqlite3_finalize (stmt); 
+  return;
+}
+
+void
+ContactStorage::getCollectEndorseList(const Name& name, vector<Buffer>& endorseList)
+{
+  sqlite3_stmt *stmt;
+  sqlite3_prepare_v2 (m_db, "SELECT endorse_data FROM CollectEndorse WHERE endorsee=?", -1, &stmt, 0);
+  sqlite3_bind_text(stmt, 1, name.toUri().c_str(), name.toUri().size(), SQLITE_TRANSIENT);
+
+  while(sqlite3_step (stmt) == SQLITE_ROW)
+    {
+      Buffer blob(reinterpret_cast<const uint8_t*>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
+      endorseList.push_back(blob);
+    }
+
+  sqlite3_finalize (stmt);
+}
+
+void
+ContactStorage::getEndorseList(const Name& identity, vector<string>& endorseList)
+{
+  sqlite3_stmt *stmt;
+  sqlite3_prepare_v2 (m_db, "SELECT profile_type FROM ContactProfile WHERE profile_identity=? AND endorse=1 ORDER BY profile_type", -1, &stmt, 0);
+  sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
+
+  while( sqlite3_step (stmt) == SQLITE_ROW)
+    {
+      string profileType(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
+      endorseList.push_back(profileType);      
+    }
+  sqlite3_finalize (stmt);  
+}
+
+
 void 
 ContactStorage::removeContact(const Name& contactNameSpace)
 {
-  shared_ptr<ContactItem> contact = getContact(contactNameSpace);
   string identity = contactNameSpace.toUri();
   
-  if(contact == NULL)
-    return;
-
   sqlite3_stmt *stmt;  
   sqlite3_prepare_v2 (m_db, "DELETE FROM Contact WHERE contact_namespace=?", -1, &stmt, 0);
   sqlite3_bind_text(stmt, 1, identity.c_str(), identity.size (), SQLITE_TRANSIENT);
@@ -326,13 +309,10 @@
   res = sqlite3_step (stmt);
   sqlite3_finalize (stmt);
   
-  if(contact->isIntroducer())
-    {
-      sqlite3_prepare_v2 (m_db, "DELETE FROM TrustScope WHERE contact_namespace=?", -1, &stmt, 0);
-      sqlite3_bind_text(stmt, 1, identity.c_str(),  identity.size (), SQLITE_TRANSIENT);
-      res = sqlite3_step (stmt);
-      sqlite3_finalize (stmt);         
-    }
+  sqlite3_prepare_v2 (m_db, "DELETE FROM TrustScope WHERE contact_namespace=?", -1, &stmt, 0);
+  sqlite3_bind_text(stmt, 1, identity.c_str(),  identity.size (), SQLITE_TRANSIENT);
+  res = sqlite3_step (stmt);
+  sqlite3_finalize (stmt);         
 }
   
 void
@@ -359,7 +339,7 @@
   int res = sqlite3_step (stmt);
   sqlite3_finalize (stmt);
 
-  const Profile&  profile = contact.getSelfEndorseCertificate().getProfileData().getProfile();
+  const Profile&  profile = contact.getSelfEndorseCertificate().getProfile();
   Profile::const_iterator it = profile.begin();
   string identity = contact.getNameSpace().toUri();
   for(; it != profile.end(); it++)
@@ -378,11 +358,10 @@
 
   if(isIntroducer)
     {
-      const vector<Name>& scopeList = contact.getTrustScopeList();
-      vector<Name>::const_iterator it = scopeList.begin();
+      ContactItem::const_iterator it = contact.trustScopeBegin();
       string nameSpace = contact.getNameSpace().toUri();
       
-      while(it != scopeList.end())
+      while(it != contact.trustScopeEnd())
         {
           sqlite3_prepare_v2 (m_db, 
                               "INSERT INTO TrustScope (contact_namespace, trust_scope) values (?, ?)", 
@@ -390,7 +369,7 @@
                               &stmt, 
                               0);
           sqlite3_bind_text(stmt, 1, nameSpace.c_str(),  nameSpace.size (), SQLITE_TRANSIENT);
-          sqlite3_bind_text(stmt, 2, it->toUri().c_str(), it->toUri().size(), SQLITE_TRANSIENT);
+          sqlite3_bind_text(stmt, 2, it->first.toUri().c_str(), it->first.toUri().size(), SQLITE_TRANSIENT);
           res = sqlite3_step (stmt);
           sqlite3_finalize (stmt);          
           it++;
@@ -398,8 +377,49 @@
     }
 }
 
+
+shared_ptr<ContactItem>
+ContactStorage::getContact(const Name& name)
+{
+  sqlite3_stmt *stmt;
+  sqlite3_prepare_v2 (m_db, "SELECT contact_alias, self_certificate, is_introducer FROM Contact where contact_namespace=?", -1, &stmt, 0);
+  sqlite3_bind_text (stmt, 1, name.toUri().c_str(), name.toUri().size(), SQLITE_TRANSIENT);
+  
+  if( sqlite3_step (stmt) == SQLITE_ROW)
+    {
+      string alias(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
+
+      Data certData;
+      certData.wireDecode(Block(reinterpret_cast<const uint8_t*>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1)));
+      EndorseCertificate endorseCertificate(certData);
+
+      int isIntroducer = sqlite3_column_int (stmt, 2);
+
+      sqlite3_finalize (stmt);
+      
+      shared_ptr<ContactItem> contact = make_shared<ContactItem>(endorseCertificate, isIntroducer, alias);
+
+      if(contact->isIntroducer())
+        {
+          sqlite3_prepare_v2 (m_db, "SELECT trust_scope FROM TrustScope WHERE contact_namespace=?", -1, &stmt, 0);
+          sqlite3_bind_text(stmt, 1, name.toUri().c_str(), name.toUri().size(), SQLITE_TRANSIENT);
+
+          while( sqlite3_step (stmt) == SQLITE_ROW)
+            {
+              Name scope(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
+              contact->addTrustScope(scope);
+            }
+          sqlite3_finalize (stmt);  
+        }
+
+      return contact;      
+    } 
+  return shared_ptr<ContactItem>();
+}
+
+
 void
-ContactStorage::updateIsIntroducer(const ndn::Name& identity, bool isIntroducer)
+ContactStorage::updateIsIntroducer(const Name& identity, bool isIntroducer)
 {
   sqlite3_stmt *stmt;
   sqlite3_prepare_v2 (m_db, "UPDATE Contact SET is_introducer=? WHERE contact_namespace=?", -1, &stmt, 0);
@@ -411,7 +431,7 @@
 }
 
 void 
-ContactStorage::updateAlias(const ndn::Name& identity, std::string alias)
+ContactStorage::updateAlias(const Name& identity, string alias)
 {
   sqlite3_stmt *stmt;
   sqlite3_prepare_v2 (m_db, "UPDATE Contact SET contact_alias=? WHERE contact_namespace=?", -1, &stmt, 0);
@@ -481,242 +501,4 @@
     }
 }
 
-shared_ptr<ContactItem>
-ContactStorage::getContact(const Name& name)
-{
-  sqlite3_stmt *stmt;
-  sqlite3_prepare_v2 (m_db, "SELECT contact_alias, self_certificate, is_introducer FROM Contact where contact_namespace=?", -1, &stmt, 0);
-  sqlite3_bind_text (stmt, 1, name.toUri().c_str(), name.toUri().size(), SQLITE_TRANSIENT);
-  
-  if( sqlite3_step (stmt) == SQLITE_ROW)
-    {
-      string alias(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
-
-      Data certData;
-      certData.wireDecode(Block(reinterpret_cast<const uint8_t*>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1)));
-      EndorseCertificate endorseCertificate(certData);
-
-      int isIntroducer = sqlite3_column_int (stmt, 2);
-
-      sqlite3_finalize (stmt);
-      
-      shared_ptr<ContactItem> contact = make_shared<ContactItem>(endorseCertificate, isIntroducer, alias);
-
-      if(contact->isIntroducer())
-        {
-          sqlite3_prepare_v2 (m_db, "SELECT trust_scope FROM TrustScope WHERE contact_namespace=?", -1, &stmt, 0);
-          sqlite3_bind_text(stmt, 1, name.toUri().c_str(), name.toUri().size(), SQLITE_TRANSIENT);
-
-          while( sqlite3_step (stmt) == SQLITE_ROW)
-            {
-              Name scope(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
-              contact->addTrustScope(scope);
-            }
-          sqlite3_finalize (stmt);  
-        }
-
-      return contact;      
-    } 
-  return shared_ptr<ContactItem>();
-}
-
-shared_ptr<Profile>
-ContactStorage::getSelfProfile(const Name& identity) const
-{  
-  shared_ptr<Profile> profile = make_shared<Profile>(identity);
-  sqlite3_stmt *stmt;
-  sqlite3_prepare_v2 (m_db, "SELECT profile_type, profile_value FROM SelfProfile WHERE profile_identity=?", -1, &stmt, 0);
-  sqlite3_bind_text (stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
-
-  while( sqlite3_step (stmt) == SQLITE_ROW)
-    {
-      string profileType(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
-      string profileValue(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1));
-      profile->setProfileEntry(profileType, profileValue);
-    }
-
-  sqlite3_finalize(stmt);
-
-  return profile;
-}
-
-Block
-ContactStorage::getSelfEndorseCertificate(const Name& identity)
-{
-  sqlite3_stmt *stmt;
-  sqlite3_prepare_v2 (m_db, "SELECT endorse_data FROM SelfEndorse where identity=?", -1, &stmt, 0);
-  sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
-
-  if(sqlite3_step (stmt) == SQLITE_ROW)
-    {
-      Block result(reinterpret_cast<const uint8_t*>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
-      sqlite3_finalize (stmt);
-      return result;
-    }
-
-  sqlite3_finalize (stmt);
-
-  throw Error("ContactStorage: No self-endorse certificate found!");
-
-  return Block();
-}
-
-void
-ContactStorage::updateSelfEndorseCertificate(const EndorseCertificate& newEndorseCertificate, const Name& identity)
-{
-  const Block& newEndorseCertificateBlock = newEndorseCertificate.wireEncode();
-
-  sqlite3_stmt *stmt;
-  sqlite3_prepare_v2 (m_db, "UPDATE SelfEndorse SET endorse_data=? WHERE identity=?", -1, &stmt, 0);
-  sqlite3_bind_text(stmt, 1, reinterpret_cast<const char*>(newEndorseCertificateBlock.wire()), newEndorseCertificateBlock.size(), SQLITE_TRANSIENT);
-  sqlite3_bind_text(stmt, 2, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
-  sqlite3_step(stmt);
-  
-  sqlite3_finalize (stmt);
-}
-
-void
-ContactStorage::addSelfEndorseCertificate(const EndorseCertificate& newEndorseCertificate, const Name& identity)
-{
-  const Block& newEndorseCertificateBlock = newEndorseCertificate.wireEncode();
-
-  sqlite3_stmt *stmt;
-  sqlite3_prepare_v2 (m_db, "INSERT INTO SelfEndorse (identity, endorse_data) values (?, ?)", -1, &stmt, 0);
-  sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
-  sqlite3_bind_text(stmt, 2, reinterpret_cast<const char*>(newEndorseCertificateBlock.wire()), newEndorseCertificateBlock.size(), SQLITE_TRANSIENT);
-  sqlite3_step(stmt);
-
-  sqlite3_finalize (stmt);
-}
-
-Block
-ContactStorage::getEndorseCertificate(const Name& identity)
-{
-  sqlite3_stmt *stmt;
-  sqlite3_prepare_v2 (m_db, "SELECT endorse_data FROM ProfileEndorse where identity=?", -1, &stmt, 0);
-  sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
-
-  
-  if(sqlite3_step (stmt) == SQLITE_ROW)
-    {
-      Block result(reinterpret_cast<const uint8_t*>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
-      sqlite3_finalize (stmt);
-      return result;
-    }
-
-  sqlite3_finalize (stmt);
-
-  throw Error("ContactStorage: No endorse certificate found!");
-  
-  return Block();
-}
-
-void
-ContactStorage::updateEndorseCertificate(const EndorseCertificate& endorseCertificate, const Name& identity)
-{
-  const Block& newEndorseCertificateBlock = endorseCertificate.wireEncode();
-
-  sqlite3_stmt *stmt;
-  sqlite3_prepare_v2 (m_db, "UPDATE ProfileEndorse SET endorse_data=? WHERE identity=?", -1, &stmt, 0);
-  sqlite3_bind_text(stmt, 1, reinterpret_cast<const char*>(newEndorseCertificateBlock.wire()), newEndorseCertificateBlock.size(), SQLITE_TRANSIENT);
-  sqlite3_bind_text(stmt, 2, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
-  sqlite3_step(stmt);
-
-  sqlite3_finalize (stmt);
-}
-
-void
-ContactStorage::addEndorseCertificate(const EndorseCertificate& endorseCertificate, const Name& identity)
-{
-  const Block& newEndorseCertificateBlock = endorseCertificate.wireEncode();
-
-  sqlite3_stmt *stmt;
-  sqlite3_prepare_v2 (m_db, "INSERT INTO ProfileEndorse (identity, endorse_data) values (?, ?)", -1, &stmt, 0);
-  sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
-  sqlite3_bind_text(stmt, 2, reinterpret_cast<const char*>(newEndorseCertificateBlock.value()), newEndorseCertificateBlock.size(), SQLITE_TRANSIENT);
-  sqlite3_step(stmt);
-
-  sqlite3_finalize (stmt);
-}
-
-void
-ContactStorage::getEndorseList(const Name& identity, vector<string>& endorseList)
-{
-  sqlite3_stmt *stmt;
-  sqlite3_prepare_v2 (m_db, "SELECT profile_type FROM ContactProfile WHERE profile_identity=? AND endorse=1 ORDER BY profile_type", -1, &stmt, 0);
-  sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
-
-  while( sqlite3_step (stmt) == SQLITE_ROW)
-    {
-      string profileType(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
-      endorseList.push_back(profileType);      
-    }
-  sqlite3_finalize (stmt);  
-}
-
-void
-ContactStorage::updateCollectEndorse(const EndorseCertificate& endorseCertificate)
-{
-  Name endorserName = endorseCertificate.getSigner();
-  Name keyName = endorseCertificate.getPublicKeyName();
-  Name endorseeName = keyName.getPrefix(keyName.size()-1);
-  Name getCertName = endorseCertificate.getName();
-  Name oldCertName;
-  bool insert = true;
-  bool update = true;
-
-  sqlite3_stmt *stmt;
-  sqlite3_prepare_v2 (m_db, "SELECT endorse_name FROM CollectEndorse WHERE endorser=? AND endorsee=?", -1, &stmt, 0);
-  sqlite3_bind_text(stmt, 1, endorserName.toUri().c_str(), endorserName.toUri().size(), SQLITE_TRANSIENT);
-  sqlite3_bind_text(stmt, 2, endorseeName.toUri().c_str(), endorseeName.toUri().size(), SQLITE_TRANSIENT);
-
-  if(sqlite3_step (stmt) == SQLITE_ROW)
-    {
-      insert = false;
-      oldCertName = Name(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
-      if(getCertName == oldCertName)
-        update = false;
-    }
-  sqlite3_finalize (stmt);  
-  
-  if(insert)
-    {
-      sqlite3_prepare_v2 (m_db, "INSERT INTO CollectEndorse (endorser, endorsee, endorse_name, endorse_data) VALUES (?, ?, ?, ?)", -1, &stmt, 0);
-      sqlite3_bind_text(stmt, 1, endorserName.toUri().c_str(), endorserName.toUri().size(), SQLITE_TRANSIENT);
-      sqlite3_bind_text(stmt, 2, endorseeName.toUri().c_str(), endorseeName.toUri().size(), SQLITE_TRANSIENT);
-      sqlite3_bind_text(stmt, 3, getCertName.toUri().c_str(), getCertName.toUri().size(), SQLITE_TRANSIENT);
-      const Block &block = endorseCertificate.wireEncode();
-      sqlite3_bind_text(stmt, 4, reinterpret_cast<const char*>(block.wire()), block.size(), SQLITE_TRANSIENT);
-      int res = sqlite3_step (stmt);
-      sqlite3_finalize (stmt); 
-      return;
-    }
-  if(update)
-    {
-      sqlite3_prepare_v2 (m_db, "UPDATE CollectEndorse SET endorse_name=?, endorse_data=? WHERE endorser=? AND endorsee=?", -1, &stmt, 0);
-      sqlite3_bind_text(stmt, 1, getCertName.toUri().c_str(), getCertName.toUri().size(), SQLITE_TRANSIENT);
-      const Block &block = endorseCertificate.wireEncode();
-      sqlite3_bind_text(stmt, 2, reinterpret_cast<const char*>(block.value()), block.size(), SQLITE_TRANSIENT);
-      sqlite3_bind_text(stmt, 3, endorserName.toUri().c_str(), endorserName.toUri().size(), SQLITE_TRANSIENT);
-      sqlite3_bind_text(stmt, 4, endorseeName.toUri().c_str(), endorseeName.toUri().size(), SQLITE_TRANSIENT);
-      int res = sqlite3_step (stmt);
-      sqlite3_finalize (stmt); 
-      return;
-    }
-}
-
-void
-ContactStorage::getCollectEndorseList(const Name& name, vector<Buffer>& endorseList)
-{
-  sqlite3_stmt *stmt;
-  sqlite3_prepare_v2 (m_db, "SELECT endorse_data FROM CollectEndorse WHERE endorsee=?", -1, &stmt, 0);
-  sqlite3_bind_text(stmt, 1, name.toUri().c_str(), name.toUri().size(), SQLITE_TRANSIENT);
-
-  while(sqlite3_step (stmt) == SQLITE_ROW)
-    {
-      Buffer blob(reinterpret_cast<const uint8_t*>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
-      endorseList.push_back(blob);
-    }
-
-  sqlite3_finalize (stmt);
-}
+}//chronos
diff --git a/src/contact-storage.h b/src/contact-storage.h
index dfc06ef..da6c812 100644
--- a/src/contact-storage.h
+++ b/src/contact-storage.h
@@ -8,14 +8,15 @@
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
  */
 
-#ifndef LINKNDN_CONTACT_STORAGE_H
-#define LINKNDN_CONTACT_STORAGE_H
+#ifndef CHRONOS_CONTACT_STORAGE_H
+#define CHRONOS_CONTACT_STORAGE_H
 
-#include <sqlite3.h>
 #include "contact-item.h"
-#include "endorse-certificate.h"
+#include <sqlite3.h>
 
 
+namespace chronos{
+
 class ContactStorage
 {
 
@@ -25,13 +26,33 @@
   ContactStorage();
   
   ~ContactStorage() 
-  {sqlite3_close(m_db);}
+  { sqlite3_close(m_db); }
+
+  ndn::shared_ptr<Profile>
+  getSelfProfile(const ndn::Name& identity) const;
+
+  // ndn::Block
+  // getSelfEndorseCertificate(const ndn::Name& identity);
+  
+  void
+  addSelfEndorseCertificate(const EndorseCertificate& endorseCertificate, const ndn::Name& identity);
+
+  // ndn::Block
+  // getEndorseCertificate(const ndn::Name& identity);
 
   void
-  setSelfProfileEntry(const ndn::Name& identity, const std::string& profileType, const ndn::Buffer& profileValue);
+  addEndorseCertificate(const EndorseCertificate& endorseCertificate, const ndn::Name& identity);
 
-  ndn::ptr_lib::shared_ptr<Profile>
-  getSelfProfile(const ndn::Name& identity);
+  void
+  updateCollectEndorse(const EndorseCertificate& endorseCertificate);
+
+  void
+  getCollectEndorseList(const ndn::Name& name, std::vector<ndn::Buffer>& endorseList);
+
+  void
+  getEndorseList(const ndn::Name& identity, std::vector<std::string>& endorseList);
+
+
 
   void
   removeContact(const ndn::Name& identity);
@@ -39,6 +60,9 @@
   void
   addContact(const ContactItem& contactItem);
 
+  ndn::shared_ptr<ContactItem>
+  getContact(const ndn::Name& name);
+
   void
   updateIsIntroducer(const ndn::Name& identity, bool isIntroducer);
 
@@ -46,51 +70,14 @@
   updateAlias(const ndn::Name& identity, std::string alias);
 
   void
-  getAllContacts(std::vector<ndn::ptr_lib::shared_ptr<ContactItem> >& contacts) const;
+  getAllContacts(std::vector<ndn::shared_ptr<ContactItem> >& contacts) const;
 
-  ndn::ptr_lib::shared_ptr<ContactItem>
-  getContact(const ndn::Name& name);
-    
-  ndn::ptr_lib::shared_ptr<Profile>
-  getSelfProfile(const ndn::Name& identity) const;
-
-
-  //SelfEndorse
-  ndn::Block
-  getSelfEndorseCertificate(const ndn::Name& identity);
-
-  void
-  updateSelfEndorseCertificate(const EndorseCertificate& endorseCertificate, const ndn::Name& identity);
-
-  void
-  addSelfEndorseCertificate(const EndorseCertificate& endorseCertificate, const ndn::Name& identity);
-
-
-  //ProfileEndorse
-  ndn::Block
-  getEndorseCertificate(const ndn::Name& identity);
-
-  void
-  updateEndorseCertificate(const EndorseCertificate& endorseCertificate, const ndn::Name& identity);
-
-  void
-  addEndorseCertificate(const EndorseCertificate& endorseCertificate, const ndn::Name& identity);
-
-  void
-  getEndorseList(const ndn::Name& identity, std::vector<std::string>& endorseList);
-
-  
-  //CollectEndorse
-  void
-  updateCollectEndorse(const EndorseCertificate& endorseCertificate);
-
-  void
-  getCollectEndorseList(const ndn::Name& name, std::vector<ndn::Buffer>& endorseList);
+ 
   
 
 private:
-  bool
-  doesSelfEntryExist(const ndn::Name& identity, const std::string& profileType);
+  void
+  initializeTable(const std::string& tableName, const std::string& sqlCreateStmt);
 
   bool
   doesContactExist(const ndn::Name& name);
@@ -99,4 +86,5 @@
   sqlite3 *m_db;
 };
 
+}//chronos
 #endif
diff --git a/src/contactpanel.cpp b/src/contactpanel.cpp
index 0c0c5b8..413f32b 100644
--- a/src/contactpanel.cpp
+++ b/src/contactpanel.cpp
@@ -21,7 +21,7 @@
 #include <QtSql/QSqlError>
 
 #ifndef Q_MOC_RUN
-#include <ndn-cpp-dev/security/verifier.hpp>
+#include <ndn-cpp-dev/security/validator.hpp>
 #include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/random/random_device.hpp>
@@ -31,16 +31,15 @@
 
 namespace fs = boost::filesystem;
 using namespace ndn;
-using namespace ndn::ptr_lib;
-
+using namespace chronos;
 using namespace std;
 
 INIT_LOGGER("ContactPanel");
 
 Q_DECLARE_METATYPE(ndn::IdentityCertificate)
-Q_DECLARE_METATYPE(ChronosInvitation)
 
-ContactPanel::ContactPanel(QWidget *parent) 
+ContactPanel::ContactPanel(shared_ptr<Face> face,
+                           QWidget *parent) 
   : QDialog(parent)
   , ui(new Ui::ContactPanel)
   , m_warningDialog(new WarningDialog)
@@ -48,20 +47,23 @@
   , m_startChatDialog(new StartChatDialog)
   , m_invitationDialog(new InvitationDialog)
   , m_settingDialog(new SettingDialog)
-  , m_policy(new SecPolicyChronoChatPanel())
+  , m_keyChain(new KeyChain)
+  , m_face(face)
+  , m_ioService(face->ioService())
+  , m_contactManager(new ContactManager(m_face))
 {
-  qRegisterMetaType<IdentityCertificate>("IdentityCertificate");
-  qRegisterMetaType<ChronosInvitation>("ChronosInvitation");
 
-  startFace();  
+  qRegisterMetaType<ndn::IdentityCertificate>("IdentityCertificate");
 
   createAction();
 
-  m_keyChain = make_shared<KeyChain>();
-  m_verifier = make_shared<Verifier>(m_policy);
-  m_verifier->setFace(m_face);
-
-  m_contactManager = make_shared<ContactManager>(m_keyChain, m_face);
+#ifdef WITH_SECURITY
+  m_panelValidator = make_shared<chronos::ValidatorPanel>();
+  m_invitationValidator = make_shared<chronos::ValidatorInvitation>();
+#else
+  m_panelValidator = make_shared<ndn::ValidatorNull>();
+  m_invitationValidator = make_shared<ndn::ValidatorNull>();
+#endif
 
   connect(&*m_contactManager, SIGNAL(noNdnConnection(const QString&)),
           this, SLOT(showError(const QString&)));
@@ -73,12 +75,11 @@
   loadTrustAnchor();
 
   m_defaultIdentity = m_keyChain->getDefaultIdentity();
+
   if(m_defaultIdentity.size() == 0)
     showError(QString::fromStdString("certificate of ") + QString::fromStdString(m_defaultIdentity.toUri()) + " is missing!\nHave you installed the certificate?");
-  Name defaultCertName = m_keyChain->getDefaultCertificateNameForIdentity(m_defaultIdentity);
-  if(defaultCertName.size() == 0)
-    showError(QString::fromStdString("certificate of ") + QString::fromStdString(m_defaultIdentity.toUri()) + " is missing!\nHave you installed the certificate?");
 
+  m_keyChain->createIdentity(m_defaultIdentity);
 
   m_contactManager->setDefaultIdentity(m_defaultIdentity);
   m_nickName = m_defaultIdentity.get(-1).toEscapedString();
@@ -131,6 +132,9 @@
    
   connect(ui->settingButton, SIGNAL(clicked()),
           this, SLOT(openSettingDialog()));
+  
+  connect(ui->chatButton, SIGNAL(clicked()),
+          this, SLOT(openStartChatDialog()));
    
   connect(m_addContactPanel, SIGNAL(newContactAdded()),
           this, SLOT(refreshContactList()));
@@ -139,25 +143,22 @@
   connect(m_setAliasDialog, SIGNAL(aliasChanged()),
           this, SLOT(refreshContactList()));
 
-  connect(m_startChatDialog, SIGNAL(chatroomConfirmed(const QString&, const QString&, bool)),
-          this, SLOT(startChatroom(const QString&, const QString&, bool)));
+  connect(m_startChatDialog, SIGNAL(chatroomConfirmed(const QString&)),
+          this, SLOT(startChatroom(const QString&)));
 
-  connect(m_invitationDialog, SIGNAL(invitationAccepted(const ChronosInvitation&, const ndn::IdentityCertificate&)),
-          this, SLOT(acceptInvitation(const ChronosInvitation&, const ndn::IdentityCertificate&)));
-  connect(m_invitationDialog, SIGNAL(invitationRejected(const ChronosInvitation&)),
-          this, SLOT(rejectInvitation(const ChronosInvitation&)));
+  connect(m_invitationDialog, SIGNAL(invitationAccepted(const ndn::Name&)),
+          this, SLOT(acceptInvitation(const ndn::Name&)));
+  connect(m_invitationDialog, SIGNAL(invitationRejected(const ndn::Name&)),
+          this, SLOT(rejectInvitation(const ndn::Name&)));
   
   connect(&*m_contactManager, SIGNAL(contactAdded(const ndn::Name&)),
-          this, SLOT(addContactIntoPanelPolicy(const ndn::Name&)));
+          this, SLOT(addContactIntoValidator(const ndn::Name&)));
   connect(&*m_contactManager, SIGNAL(contactRemoved(const ndn::Name&)),
-          this, SLOT(removeContactFromPanelPolicy(const ndn::Name&)));
+          this, SLOT(removeContactFromValidator(const ndn::Name&)));
 
   connect(m_settingDialog, SIGNAL(identitySet(const QString&, const QString&)),
           this, SLOT(updateDefaultIdentity(const QString&, const QString&)));
 
-  connect(this, SIGNAL(newInvitationReady()),
-          this, SLOT(openInvitationDialog()));
-
   connect(ui->isIntroducer, SIGNAL(stateChanged(int)),
           this, SLOT(isIntroducerChanged(int)));
 
@@ -189,77 +190,16 @@
   delete m_endorseDataModel;
   delete m_endorseComboBoxDelegate;
 
-  delete m_menuInvite;
   delete m_menuAlias;
 
   map<Name, ChatDialog*>::iterator it = m_chatDialogs.begin();
   for(; it != m_chatDialogs.end(); it++)
     delete it->second;
-
-  shutdownFace();
 }
 
 void
-ContactPanel::startFace()
-{
-  m_face = make_shared<Face>();
-  
-  connectToDaemon();
-
-  m_running = true;
-  m_thread = boost::thread (&ContactPanel::eventLoop, this);  
-}
-
-void
-ContactPanel::shutdownFace()
-{
-  {
-    boost::unique_lock<boost::recursive_mutex> lock(m_mutex);
-    m_running = false;
-  }
-  
-  m_thread.join();
-  m_face->shutdown();
-}
-
-void
-ContactPanel::eventLoop()
-{
-  while (m_running)
-    {
-      try{
-        m_face->processEvents();
-        usleep(100);
-      }catch(std::exception& e){
-        _LOG_DEBUG(" " << e.what() );
-      }
-    }
-}
-
-void
-ContactPanel::connectToDaemon()
-{
-  //Hack! transport does not connect to daemon unless an interest is expressed.
-  Name name("/ndn");
-  ndn::Interest interest(name);
-  m_face->expressInterest(interest, 
-                          func_lib::bind(&ContactPanel::onConnectionData, this, _1, _2),
-                          func_lib::bind(&ContactPanel::onConnectionDataTimeout, this, _1));
-}
-
-void
-ContactPanel::onConnectionData(const shared_ptr<const ndn::Interest>& interest,
-                               const shared_ptr<Data>& data)
-{ _LOG_DEBUG("onConnectionData"); }
-
-void
-ContactPanel::onConnectionDataTimeout(const shared_ptr<const ndn::Interest>& interest)
-{ _LOG_DEBUG("onConnectionDataTimeout"); }
-
-void
 ContactPanel::createAction()
 {
-  m_menuInvite = new QAction("&Chat", this);
   m_menuAlias = new QAction("&Set Alias", this);
 }
 
@@ -281,12 +221,15 @@
 void 
 ContactPanel::loadTrustAnchor()
 {
+#ifdef WITH_SECURITY
   vector<shared_ptr<ContactItem> >::const_iterator it = m_contactList.begin();
   for(; it != m_contactList.end(); it++)
     {
       _LOG_DEBUG("load contact: " << (*it)->getNameSpace().toUri());
-      m_policy->addTrustAnchor((*it)->getSelfEndorseCertificate());
+      m_invitationValidator->addTrustAnchor((*it)->getSelfEndorseCertificate());
+      m_panelValidator->addTrustAnchor((*it)->getSelfEndorseCertificate());
     }
+#endif
 }
 
 void
@@ -296,34 +239,29 @@
   Interest interest(interestName);
 
   m_face->expressInterest(interest, 
-                          func_lib::bind(&ContactPanel::onLocalPrefix, this, _1, _2), 
-                          func_lib::bind(&ContactPanel::onLocalPrefixTimeout, this, _1, 10));
+                          bind(&ContactPanel::onLocalPrefix, this, _1, _2), 
+                          bind(&ContactPanel::onLocalPrefixTimeout, this, _1, 10));
   
 }
 
 void
-ContactPanel::onLocalPrefix(const shared_ptr<const Interest>& interest, 
-                            const shared_ptr<Data>& data)
+ContactPanel::onLocalPrefix(const Interest& interest, Data& data)
 {
-  string originPrefix((const char*)data->getContent().value(), data->getContent().value_size());
-  string prefix = QString::fromStdString (originPrefix).trimmed ().toUtf8().constData();
-  string randomSuffix = getRandomString();
+  string originPrefix(reinterpret_cast<const char*>(data.getContent().value()), data.getContent().value_size());
+  string prefix = QString::fromStdString (originPrefix).trimmed ().toStdString();
   m_localPrefix = Name(prefix);
-  
 }
 
 void
-ContactPanel::onLocalPrefixTimeout(const shared_ptr<const Interest>& interest,
-                                   int retry)
+ContactPanel::onLocalPrefixTimeout(const Interest& interest, int retry)
 { 
   if(retry > 0)
     {
       setLocalPrefix(retry - 1);
       return;
     }
-  else{
+  else
     m_localPrefix = Name("/private/local");
-  }
 }
 
 void
@@ -333,175 +271,87 @@
   m_inviteListenPrefix.append(m_defaultIdentity);
   _LOG_DEBUG("Listening for invitation on prefix: " << m_inviteListenPrefix.toUri());
   m_invitationListenerId = m_face->setInterestFilter(m_inviteListenPrefix, 
-                                                     func_lib::bind(&ContactPanel::onInvitation, this, _1, _2, _3, _4),
-                                                     func_lib::bind(&ContactPanel::onInvitationRegisterFailed, this, _1));
+                                                     bind(&ContactPanel::onInvitation, this, _1, _2),
+                                                     bind(&ContactPanel::onInvitationRegisterFailed, this, _1, _2));
 }
 
 void
 ContactPanel::sendInterest(const Interest& interest,
-                           const OnVerified& onVerified,
-                           const OnVerifyFailed& onVerifyFailed,
+                           const OnDataValidated& onValidated,
+                           const OnDataValidationFailed& onValidationFailed,
                            const TimeoutNotify& timeoutNotify,
                            int retry /* = 1 */)
 {
   m_face->expressInterest(interest, 
-                          func_lib::bind(&ContactPanel::onTargetData, 
-                                      this,
-                                      _1,
-                                      _2,
-                                      onVerified, 
-                                      onVerifyFailed),
-                          func_lib::bind(&ContactPanel::onTargetTimeout,
-                                      this,
-                                      _1,
-                                      retry,
-                                      onVerified,
-                                      onVerifyFailed,
-                                      timeoutNotify));
+                          bind(&ContactPanel::onTargetData, 
+                               this, _1, _2, onValidated, onValidationFailed),
+                          bind(&ContactPanel::onTargetTimeout,
+                               this, _1, retry, onValidated, onValidationFailed, timeoutNotify));
 }
 
 void
-ContactPanel::onTargetData(const shared_ptr<const ndn::Interest>& interest, 
-                           const shared_ptr<Data>& data,
-                           const OnVerified& onVerified,
-                           const OnVerifyFailed& onVerifyFailed)
+ContactPanel::onTargetData(const ndn::Interest& interest, 
+                           Data& data,
+                           const OnDataValidated& onValidated,
+                           const OnDataValidationFailed& onValidationFailed)
 {
-  m_verifier->verifyData(data, onVerified, onVerifyFailed);
+  m_panelValidator->validate(data, onValidated, onValidationFailed);
 }
 
 void
-ContactPanel::onTargetTimeout(const shared_ptr<const ndn::Interest>& interest, 
+ContactPanel::onTargetTimeout(const ndn::Interest& interest, 
                               int retry,
-                              const OnVerified& onVerified,
-                              const OnVerifyFailed& onVerifyFailed,
+                              const OnDataValidated& onValidated,
+                              const OnDataValidationFailed& onValidationFailed,
                               const TimeoutNotify& timeoutNotify)
 {
   if(retry > 0)
-    sendInterest(*interest, onVerified, onVerifyFailed, timeoutNotify, retry-1);
+    sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, retry-1);
   else
     {
-      _LOG_DEBUG("Interest: " << interest->getName().toUri() << " eventually times out!");
+      _LOG_DEBUG("Interest: " << interest.getName() << " eventually times out!");
       timeoutNotify();
     }
 }
 
 void
-ContactPanel::onInvitationRegisterFailed(const shared_ptr<const Name>& prefix)
+ContactPanel::onInvitationRegisterFailed(const Name& prefix, const string& msg)
 {
-  showError(QString::fromStdString("Cannot register invitation listening prefix"));
+  showError(QString::fromStdString("Cannot register invitation listening prefix! " + msg));
 }
 
 void
-ContactPanel::onInvitation(const shared_ptr<const Name>& prefix, 
-                           const shared_ptr<const Interest>& interest, 
-                           Transport& transport, 
-                           uint64_t registeredPrefixId)
+ContactPanel::onInvitation(const Name& prefix, const Interest& interest)
 {
-  _LOG_DEBUG("Receive invitation!" << interest->getName().toUri());
+  _LOG_DEBUG("Receive invitation!" << interest.getName() << " " << prefix);
 
-  
-  shared_ptr<ChronosInvitation> invitation;
-  try{
-    invitation = make_shared<ChronosInvitation>(interest->getName());
-  }catch(std::exception& e){
-    _LOG_ERROR("Exception: " << e.what());
-    return;
-  }
-  
-  Name chatroomName("/ndn/broadcast/chronos");
-  chatroomName.append(invitation->getChatroom());
-  map<Name, ChatDialog*>::iterator it = m_chatDialogs.find(chatroomName);
-  if(it != m_chatDialogs.end())
-    {
-      _LOG_ERROR("Exisiting chatroom!");
-      return;
-    }
-
-  const SignatureSha256WithRsa& invitationSig = invitation->getSignature();
-  shared_ptr<PublicKey> keyPtr = m_policy->getTrustedKey(invitation->getInviterCertificateName());
-
-  if(static_cast<bool>(keyPtr) && Verifier::verifySignature(invitation->getSignedBlob(), invitationSig, *keyPtr))
-    {
-      shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
-      // hack: incomplete certificate, we don't send it to the wire nor store it anywhere, we only use it to pass information
-      certificate->setName(invitation->getInviterCertificateName());
-      bool findCert = false;
-      vector<shared_ptr<ContactItem> >::const_iterator it = m_contactList.begin();
-      for(; it != m_contactList.end(); it++)
-        {
-          if((*it)->getNameSpace() == invitation->getInviterNameSpace())
-            {
-              certificate->setNotBefore((*it)->getSelfEndorseCertificate().getNotBefore());
-              certificate->setNotAfter((*it)->getSelfEndorseCertificate().getNotAfter());
-              findCert = true;
-              break;
-            }
-        }
-      if(findCert == false)
-        {
-          _LOG_ERROR("No SelfEndorseCertificate found!");
-          return;
-        }
-      certificate->setPublicKeyInfo(*keyPtr);
-      popChatInvitation(invitation, invitation->getInviterNameSpace(), certificate);
-      return;
-    }
-
-  _LOG_DEBUG("Cannot find the inviter's key in trust anchors");
-
-  Interest newInterest(invitation->getInviterCertificateName());
-  OnVerified onVerified = func_lib::bind(&ContactPanel::onInvitationCertVerified, this, _1, invitation);
-  OnVerifyFailed onVerifyFailed = func_lib::bind(&ContactPanel::onInvitationCertVerifyFailed, this, _1);
-  TimeoutNotify timeoutNotify = func_lib::bind(&ContactPanel::onInvitationCertTimeoutNotify, this);
-
-  sendInterest(newInterest, onVerified, onVerifyFailed, timeoutNotify);
+  OnInterestValidated onValidated = bind(&ContactPanel::onInvitationValidated, this, _1);
+  OnInterestValidationFailed onValidationFailed = bind(&ContactPanel::onInvitationValidationFailed, this, _1);
+  m_invitationValidator->validate(interest, onValidated, onValidationFailed);
 }
 
 void
-ContactPanel::onInvitationCertVerified(const shared_ptr<Data>& data, 
-                                       shared_ptr<ChronosInvitation> invitation)
+ContactPanel::popChatInvitation(const Name& interestName)
 {
-  shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>(*data);
-
-  SignatureSha256WithRsa invitationSig(invitation->getSignature());
-  
-  if(Verifier::verifySignature(invitation->getSignedBlob(), invitationSig, certificate->getPublicKeyInfo()))
-    {
-      Name keyName = certificate->getPublicKeyName();
-      Name inviterNameSpace = keyName.getPrefix(-1);
-      popChatInvitation(invitation, inviterNameSpace, certificate);
-    }
-}
-
-void
-ContactPanel::onInvitationCertVerifyFailed(const shared_ptr<Data>& data)
-{ _LOG_DEBUG("Cannot verify invitation certificate!"); }
-
-void
-ContactPanel::onInvitationCertTimeoutNotify()
-{ _LOG_DEBUG("interest for invitation certificate times out eventually!"); }
-
-void
-ContactPanel::popChatInvitation(shared_ptr<ChronosInvitation> invitation,
-                                const Name& inviterNameSpace,
-                                shared_ptr<IdentityCertificate> certificate)
-{
+  Invitation invitation(interestName);
   string alias;
+
   vector<shared_ptr<ContactItem> >::iterator it = m_contactList.begin();
   for(; it != m_contactList.end(); it++)
-    if((*it)->getNameSpace() == inviterNameSpace)
+    if((*it)->getNameSpace() == invitation.getInviteeNameSpace())
       alias = (*it)->getAlias();
 
   if(it != m_contactList.end())
     return;
 
-  m_invitationDialog->setInvitation(alias, invitation, certificate);
-  emit newInvitationReady();
+  m_invitationDialog->setInvitation(alias, interestName);
+  m_invitationDialog->show(); 
 }
 
 void
 ContactPanel::collectEndorsement()
 {
+#ifdef WITH_SECURITY
   m_collectStatus = make_shared<vector<bool> >();
   m_collectStatus->assign(m_contactList.size(), false);
 
@@ -514,16 +364,17 @@
       Interest interest(interestName);
       interest.setInterestLifetime(1000);
 
-      OnVerified onVerified = func_lib::bind(&ContactPanel::onDnsEndorseeVerified, this, _1, count);
-      OnVerifyFailed onVerifyFailed = func_lib::bind(&ContactPanel::onDnsEndorseeVerifyFailed, this, _1, count);
-      TimeoutNotify timeoutNotify = func_lib::bind(&ContactPanel::onDnsEndorseeTimeoutNotify, this, count);
+      OnDataValidated onValidated = bind(&ContactPanel::onDnsEndorseeValidated, this, _1, count);
+      OnDataValidationFailed onValidationFailed = bind(&ContactPanel::onDnsEndorseeValidationFailed, this, _1, count);
+      TimeoutNotify timeoutNotify = bind(&ContactPanel::onDnsEndorseeTimeoutNotify, this, count);
   
-      sendInterest(interest, onVerified, onVerifyFailed, timeoutNotify, 0);
+      sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, 0);
     }
+#endif
 }
 
 void
-ContactPanel::onDnsEndorseeVerified(const shared_ptr<Data>& data, int count)
+ContactPanel::onDnsEndorseeValidated(const shared_ptr<const Data>& data, int count)
 {
   Data endorseData;
   endorseData.wireDecode(Block(data->getContent().value(), data->getContent().value_size()));
@@ -539,7 +390,7 @@
 { updateCollectStatus(count); }
 
 void
-ContactPanel::onDnsEndorseeVerifyFailed(const shared_ptr<Data>& data, int count)
+ContactPanel::onDnsEndorseeValidationFailed(const shared_ptr<const Data>& data, int count)
 { updateCollectStatus(count); }
 
 void 
@@ -551,7 +402,7 @@
     if(*it == false)
       return;
 
-  m_contactManager->publishEndorsedDataInDns(m_defaultIdentity);
+  m_contactManager->publishCollectEndorsedDataInDNS(m_defaultIdentity);
 }
 
 static std::string chars("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789");
@@ -673,16 +524,13 @@
 ContactPanel::updateDefaultIdentity(const QString& identity, const QString& nickName)
 { 
   // _LOG_DEBUG(identity.toStdString());
-  Name defaultIdentity = Name(identity.toStdString());
-  Name defaultCertName = m_keyChain->getDefaultCertificateNameForIdentity(defaultIdentity);
-  if(defaultCertName.size() == 0)
-    {
-      showWarning(QString::fromStdString("Corresponding certificate is missing!\nHave you installed the certificate?"));
-      return;
-    }
+  Name defaultIdentity(identity.toStdString());
+  Name defaultCertName = m_keyChain->createIdentity(defaultIdentity);
+
   m_defaultIdentity = defaultIdentity;
   m_profileEditor->setCurrentIdentity(m_defaultIdentity);
   m_nickName = nickName.toStdString();
+  
   m_face->unsetInterestFilter(m_invitationListenerId);
   m_contactManager->setDefaultIdentity(m_defaultIdentity);
   setInvitationListener();
@@ -728,20 +576,26 @@
 }
 
 void
-ContactPanel::openInvitationDialog()
-{ m_invitationDialog->show(); }
-
-void
-ContactPanel::addContactIntoPanelPolicy(const Name& contactNameSpace)
+ContactPanel::addContactIntoValidator(const Name& contactNameSpace)
 {
+#ifdef WITH_SECURITY
   shared_ptr<ContactItem> contact = m_contactManager->getContact(contactNameSpace);
   if(static_cast<bool>(contact))
-    m_policy->addTrustAnchor(contact->getSelfEndorseCertificate());
+    {
+      m_panelValidator->addTrustAnchor(contact->getSelfEndorseCertificate());
+      m_invitationValidator->addTrustAnchor(contact->getSelfEndorseCertificate());
+    }
+#endif
 }
 
 void
-ContactPanel::removeContactFromPanelPolicy(const Name& keyName)
-{ m_policy->removeTrustAnchor(keyName); }
+ContactPanel::removeContactFromValidator(const Name& keyName)
+{ 
+#ifdef WITH_SECURITY
+  m_panelValidator->removeTrustAnchor(keyName);
+  m_invitationValidator->removeTrustAnchor(keyName);
+#endif
+}
 
 void
 ContactPanel::refreshContactList()
@@ -759,10 +613,6 @@
 ContactPanel::showContextMenu(const QPoint& pos)
 {
   QMenu menu(ui->ContactList);
-  menu.addAction(m_menuInvite);
-  connect(m_menuInvite, SIGNAL(triggered()),
-          this, SLOT(openStartChatDialog()));
-  menu.addSeparator();
   menu.addAction(m_menuAlias);
   connect(m_menuAlias, SIGNAL(triggered()),
           this, SLOT(openSetAliasDialog()));
@@ -790,22 +640,18 @@
   Name chatroom("/ndn/broadcast/chronos");
   chatroom.append(string("chatroom-") + getRandomString());
 
-  m_startChatDialog->setInvitee(m_currentSelectedContact->getNameSpace().toUri(), chatroom.toUri());
+  m_startChatDialog->setChatroom(chatroom.toUri());
   m_startChatDialog->show();
 }
 
 // For inviter
 void
-ContactPanel::startChatroom(const QString& chatroom, const QString& invitee, bool isIntroducer)
+ContactPanel::startChatroom(const QString& chatroom)
 {
   Name chatroomName(chatroom.toStdString());
 
-  Name inviteeNamespace(invitee.toStdString());
-  shared_ptr<ContactItem> inviteeItem = m_contactManager->getContact(inviteeNamespace);
-
-  ChatDialog* chatDialog = new ChatDialog(m_contactManager, chatroomName, m_localPrefix, m_defaultIdentity, m_nickName);
-  m_chatDialogs.insert(pair <Name, ChatDialog*> (chatroomName, chatDialog));
-
+  ChatDialog* chatDialog = new ChatDialog(m_contactManager, m_face, chatroomName, m_localPrefix, m_defaultIdentity, m_nickName);
+  m_chatDialogs[chatroomName] = chatDialog;
   connect(chatDialog, SIGNAL(closeChatDialog(const ndn::Name&)),
           this, SLOT(removeChatDialog(const ndn::Name&)));
   connect(chatDialog, SIGNAL(noNdnConnection(const QString&)),
@@ -813,24 +659,18 @@
   connect(chatDialog, SIGNAL(inivationRejection(const QString&)),
           this, SLOT(showWarning(const QString&)));
 
-  // send invitation
-  chatDialog->sendInvitation(inviteeItem, isIntroducer); 
-  
   chatDialog->show();
 }
 
 // For Invitee
 void
-ContactPanel::startChatroom2(const ChronosInvitation& invitation, 
-                             const IdentityCertificate& identityCertificate)
+ContactPanel::startChatroom2(const Name& invitationInterest)
 {
-  shared_ptr<ContactItem> inviterItem = m_contactManager->getContact(invitation.getInviterNameSpace());
-
+  Invitation invitation(invitationInterest);
   Name chatroomName("/ndn/broadcast/chronos");
   chatroomName.append(invitation.getChatroom());
 
-  ChatDialog* chatDialog = new ChatDialog(m_contactManager, chatroomName, m_localPrefix, m_defaultIdentity, m_nickName, true);
-
+  ChatDialog* chatDialog = new ChatDialog(m_contactManager, m_face, chatroomName, m_localPrefix, m_defaultIdentity, m_nickName);
   connect(chatDialog, SIGNAL(closeChatDialog(const ndn::Name&)),
           this, SLOT(removeChatDialog(const ndn::Name&)));
   connect(chatDialog, SIGNAL(noNdnConnection(const QString&)),
@@ -838,57 +678,40 @@
   connect(chatDialog, SIGNAL(inivationRejection(const QString&)),
           this, SLOT(showWarning(const QString&)));
 
-  chatDialog->addChatDataRule(invitation.getInviterRoutingPrefix(), identityCertificate, true);
-  chatDialog->publishIntroCert(identityCertificate, true);
-
-  chatDialog->addTrustAnchor(inviterItem->getSelfEndorseCertificate());
+  Block signatureBlock = invitationInterest.get(-1).blockFromValue();
+  Block signatureInfo = invitationInterest.get(-2).blockFromValue();
+  Signature signature(signatureInfo, signatureBlock);
   
-  m_chatDialogs.insert(pair <Name, ChatDialog*> (chatroomName, chatDialog));
+  SignatureSha256WithRsa sig(signature);
+  Name keyLocatorName = sig.getKeyLocator().getName();
+  Name inviter = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName).getPrefix(-1);
+
+#ifdef WITH_SECURITY
+  shared_ptr<IdentityCertificate> idCert = m_invitationValidator->getValidatedDskCertificate(keyLocatorName);
+  chatDialog->addChatDataRule(invitation.getInviterRoutingPrefix(), *idCert, true);
+  chatDialog->publishIntroCert(*idCert, true);
+  shared_ptr<ContactItem> inviterItem = m_contactManager->getContact(inviter);
+  chatDialog->addTrustAnchor(inviterItem->getSelfEndorseCertificate());
+#endif
+  
+  m_chatDialogs[chatroomName] = chatDialog;
 
   chatDialog->show();
 }
 
 void
-ContactPanel::acceptInvitation(const ChronosInvitation& invitation, 
-                               const IdentityCertificate& identityCertificate)
+ContactPanel::prepareInvitationReply(const Name& invitationInterest, const string& content)
 {
-  Name dataName = invitation.getInterestName();
-  time_t nowSeconds = time(NULL);
-  struct tm current = *gmtime(&nowSeconds);
-  MillisecondsSince1970 version = timegm(&current) * 1000.0;
-  dataName.appendVersion(version);
+  Invitation invitation(invitationInterest);
+
+  Name dataName = invitationInterest;
+  dataName.appendVersion();
+
   Data data(dataName);
-  string content = m_localPrefix.toUri();
-  data.setContent((const uint8_t *)&content[0], content.size());
+  data.setContent(reinterpret_cast<const uint8_t*>(content.c_str()), content.size());
+  data.setFreshnessPeriod(1000);
 
-  Name certificateName;
-  Name inferredIdentity = m_policy->inferSigningIdentity(data.getName());
-
-  if(inferredIdentity.getComponentCount() == 0)
-    certificateName = m_keyChain->getDefaultCertificateName();
-  else
-    certificateName = m_keyChain->getDefaultCertificateNameForIdentity(inferredIdentity);   
-  m_keyChain->sign(data, certificateName);
-
-  m_face->put(data);
-
-  startChatroom2(invitation, identityCertificate);
-}
-
-void
-ContactPanel::rejectInvitation(const ChronosInvitation& invitation)
-{
-  Data data(invitation.getInterestName());
-  string content("nack");
-  data.setContent((const uint8_t *)&content[0], content.size());
-
-  Name certificateName;
-  Name inferredIdentity = m_policy->inferSigningIdentity(data.getName());
-  if(inferredIdentity.getComponentCount() == 0)
-    certificateName = m_keyChain->getDefaultCertificateName();
-  else
-    certificateName = m_keyChain->getDefaultCertificateNameForIdentity(inferredIdentity);   
-  m_keyChain->sign(data, certificateName);
+  m_keyChain->signByIdentity(data, invitation.getInviteeNameSpace());
 
   m_face->put(data);
 }
diff --git a/src/contactpanel.h b/src/contactpanel.h
index 4d9eb8d..9e0c3b3 100644
--- a/src/contactpanel.h
+++ b/src/contactpanel.h
@@ -30,11 +30,15 @@
 
 #ifndef Q_MOC_RUN
 #include "contact-manager.h"
-#include "chronos-invitation.h"
-#include "sec-policy-chrono-chat-panel.h"
-#include <boost/thread/locks.hpp>
-#include <boost/thread/recursive_mutex.hpp>
-#include <boost/thread/thread.hpp>
+#include "invitation.h"
+
+#ifdef WITH_SECURITY
+#include "validator-panel.h"
+#include "validator-invitation.h"
+#else
+#include <ndn-cpp-dev/security/validator-null.hpp>
+#endif
+
 #endif
 
 
@@ -47,31 +51,12 @@
   Q_OBJECT
 
 public:
-  explicit ContactPanel(QWidget *parent = 0);
+  explicit ContactPanel(ndn::shared_ptr<ndn::Face> face,
+                        QWidget *parent = 0);
 
   ~ContactPanel();
 
-private:
-  
-  void 
-  startFace();
-
-  void
-  shutdownFace();
-
-  void
-  eventLoop();
-  
-  void 
-  connectToDaemon();
-
-  void
-  onConnectionData(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest,
-                   const ndn::ptr_lib::shared_ptr<ndn::Data>& data);
- 
-  void
-  onConnectionDataTimeout(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest);
-
+private:  
   void
   createAction();
 
@@ -85,80 +70,57 @@
   setLocalPrefix(int retry = 10);
 
   void
-  onLocalPrefix(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest, 
-                const ndn::ptr_lib::shared_ptr<ndn::Data>& data);
+  onLocalPrefix(const ndn::Interest& interest, ndn::Data& data);
   
   void
-  onLocalPrefixTimeout(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest,
-                       int retry);
+  onLocalPrefixTimeout(const ndn::Interest& interest, int retry);
 
   void
   setInvitationListener();
 
   void
-  onInvitation(const ndn::ptr_lib::shared_ptr<const ndn::Name>& prefix, 
-               const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest, 
-               ndn::Transport& transport, 
-               uint64_t registeredPrefixI);
+  onInvitation(const ndn::Name& prefix, const ndn::Interest& interest);
 
   void
-  onInvitationRegisterFailed(const ndn::ptr_lib::shared_ptr<const ndn::Name>& prefix);
+  onInvitationRegisterFailed(const ndn::Name& prefix, const std::string& msg);
+
+  inline void
+  onInvitationValidated(const ndn::shared_ptr<const ndn::Interest>& interest);
+  
+  inline void
+  onInvitationValidationFailed(const ndn::shared_ptr<const ndn::Interest>& interest);
+
+  void
+  popChatInvitation(const ndn::Name& interestName);
 
   void
   sendInterest(const ndn::Interest& interest,
-               const ndn::OnVerified& onVerified,
-               const ndn::OnVerifyFailed& onVerifyFailed,
-               const TimeoutNotify& timeoutNotify,
+               const ndn::OnDataValidated& onValidated,
+               const ndn::OnDataValidationFailed& onValidationFailed,
+               const chronos::TimeoutNotify& timeoutNotify,
                int retry = 1);
 
   void
-  onTargetData(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest, 
-               const ndn::ptr_lib::shared_ptr<ndn::Data>& data,
-               const ndn::OnVerified& onVerified,
-               const ndn::OnVerifyFailed& onVerifyFailed);
+  onTargetData(const ndn::Interest& interest, 
+               ndn::Data& data,
+               const ndn::OnDataValidated& onValidated,
+               const ndn::OnDataValidationFailed& onValidationFailed);
 
   void
-  onTargetTimeout(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest, 
+  onTargetTimeout(const ndn::Interest& interest, 
                   int retry,
-                  const ndn::OnVerified& onVerified,
-                  const ndn::OnVerifyFailed& onVerifyFailed,
-                  const TimeoutNotify& timeoutNotify);
-
-
-  void
-  onCertData(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest, 
-             const ndn::ptr_lib::shared_ptr<ndn::Data>& cert,
-             ndn::ptr_lib::shared_ptr<ndn::ValidationRequest> previousStep);
-
-  void
-  onCertTimeout(const ndn::ptr_lib::shared_ptr<const ndn::Interest>& interest,
-                const ndn::OnVerifyFailed& onVerifyFailed,
-                const ndn::ptr_lib::shared_ptr<ndn::Data>& data,
-                ndn::ptr_lib::shared_ptr<ndn::ValidationRequest> nextStep);
-    
-  void
-  onInvitationCertVerified(const ndn::ptr_lib::shared_ptr<ndn::Data>& data, 
-                           ndn::ptr_lib::shared_ptr<ChronosInvitation> invitation);
-
-  void
-  onInvitationCertVerifyFailed(const ndn::ptr_lib::shared_ptr<ndn::Data>& data);
-
-  void
-  onInvitationCertTimeoutNotify();
-
-  void
-  popChatInvitation(ndn::ptr_lib::shared_ptr<ChronosInvitation> invitation,
-                    const ndn::Name& inviterNameSpace,
-                    ndn::ptr_lib::shared_ptr<ndn::IdentityCertificate> certificate);
+                  const ndn::OnDataValidated& onValidated,
+                  const ndn::OnDataValidationFailed& onValidationFailed,
+                  const chronos::TimeoutNotify& timeoutNotify);
 
   void
   collectEndorsement();
 
   void
-  onDnsEndorseeVerified(const ndn::ptr_lib::shared_ptr<ndn::Data>& data, int count);
+  onDnsEndorseeValidated(const ndn::shared_ptr<const ndn::Data>& data, int count);
 
   void
-  onDnsEndorseeVerifyFailed(const ndn::ptr_lib::shared_ptr<ndn::Data>& data, int count);
+  onDnsEndorseeValidationFailed(const ndn::shared_ptr<const ndn::Data>& data, int count);
 
   void
   onDnsEndorseeTimeoutNotify(int count);
@@ -171,9 +133,6 @@
 
 signals:
   void
-  newInvitationReady();
-
-  void
   refreshCertDirectory();
 
 private slots:
@@ -213,29 +172,25 @@
   openSettingDialog();
 
   void
-  openInvitationDialog();
-
-  void
   refreshContactList();
 
   void
   showContextMenu(const QPoint& pos);
 
   void
-  startChatroom(const QString& chatroom, 
-                const QString& invitee, 
-                bool isIntroducer);
+  startChatroom(const QString& chatroom);
 
   void 
-  startChatroom2(const ChronosInvitation& invitation, 
-                 const ndn::IdentityCertificate& identityCertificate);
+  startChatroom2(const ndn::Name& invitationInterest);
+
+  inline void
+  acceptInvitation(const ndn::Name& invitationInterest);
+
+  inline void
+  rejectInvitation(const ndn::Name& invitationInterest);
 
   void
-  acceptInvitation(const ChronosInvitation& invitation, 
-                   const ndn::IdentityCertificate& identityCertificate);
-
-  void
-  rejectInvitation(const ChronosInvitation& invitation);
+  prepareInvitationReply(const ndn::Name& invitationInterest, const std::string& content);
 
   void
   isIntroducerChanged(int state);
@@ -256,17 +211,16 @@
   removeChatDialog(const ndn::Name& chatroomName);
 
   void 
-  addContactIntoPanelPolicy(const ndn::Name& nameSpace);
+  addContactIntoValidator(const ndn::Name& nameSpace);
 
   void 
-  removeContactFromPanelPolicy(const ndn::Name& keyName);
+  removeContactFromValidator(const ndn::Name& keyName);
   
 
 private:
 
   Ui::ContactPanel *ui;
   WarningDialog* m_warningDialog;
-  ndn::ptr_lib::shared_ptr<ContactManager> m_contactManager;
   QStringListModel* m_contactListModel;
   ProfileEditor* m_profileEditor;
   AddContactPanel* m_addContactPanel;
@@ -276,31 +230,56 @@
   InvitationDialog* m_invitationDialog;
   SettingDialog* m_settingDialog;
   std::map<ndn::Name, ChatDialog*> m_chatDialogs;
-  QAction* m_menuInvite;
   QAction* m_menuAlias;
-  std::vector<ndn::ptr_lib::shared_ptr<ContactItem> > m_contactList;
-  ndn::ptr_lib::shared_ptr<std::vector<bool> > m_collectStatus;
 
-  ndn::ptr_lib::shared_ptr<SecPolicyChronoChatPanel> m_policy;
-  ndn::ptr_lib::shared_ptr<ndn::Verifier> m_verifier;
-  ndn::ptr_lib::shared_ptr<ndn::KeyChain> m_keyChain;
-  ndn::ptr_lib::shared_ptr<ndn::Face> m_face;
+#ifdef WITH_SECURITY
+  ndn::shared_ptr<chronos::ValidatorPanel> m_panelValidator;
+  ndn::shared_ptr<chronos::ValidatorInvitation> m_invitationValidator;
+#else
+  ndn::shared_ptr<ndn::Validator> m_panelValidator;
+  ndn::shared_ptr<ndn::Validator> m_invitationValidator;
+#endif
 
-  boost::recursive_mutex m_mutex;
-  boost::thread m_thread;
-  bool m_running;
+  ndn::shared_ptr<ndn::KeyChain> m_keyChain;
+  ndn::shared_ptr<ndn::Face> m_face;
+  ndn::shared_ptr<boost::asio::io_service> m_ioService;
 
-  uint64_t m_invitationListenerId;
+  ndn::shared_ptr<chronos::ContactManager> m_contactManager;
+
+  std::vector<ndn::shared_ptr<chronos::ContactItem> > m_contactList;
+  ndn::shared_ptr<std::vector<bool> > m_collectStatus;
+
+  const ndn::RegisteredPrefixId* m_invitationListenerId;
 
   ndn::Name m_defaultIdentity;
   std::string m_nickName;
   ndn::Name m_localPrefix;
   ndn::Name m_inviteListenPrefix;
 
-  ndn::ptr_lib::shared_ptr<ContactItem> m_currentSelectedContact;
+  ndn::shared_ptr<chronos::ContactItem> m_currentSelectedContact;
   QSqlTableModel* m_trustScopeModel;
   QSqlTableModel* m_endorseDataModel;
   EndorseComboBoxDelegate* m_endorseComboBoxDelegate;
 };
 
+void
+ContactPanel::onInvitationValidated(const ndn::shared_ptr<const ndn::Interest>& interest)
+{ popChatInvitation(interest->getName()); }
+
+void
+ContactPanel::onInvitationValidationFailed(const ndn::shared_ptr<const ndn::Interest>& interest)
+{}
+
+void
+ContactPanel::acceptInvitation(const ndn::Name& invitationInterest)
+{ 
+  prepareInvitationReply(invitationInterest, m_localPrefix.toUri()); 
+  startChatroom2(invitationInterest);
+}
+
+void
+ContactPanel::rejectInvitation(const ndn::Name& invitationInterest)
+{ prepareInvitationReply(invitationInterest, "nack"); }
+
+
 #endif // CONTACTPANEL_H
diff --git a/src/contactpanel.ui b/src/contactpanel.ui
index 2f31a1a..5410c2e 100644
--- a/src/contactpanel.ui
+++ b/src/contactpanel.ui
@@ -22,7 +22,7 @@
   <property name="windowTitle">
    <string>ChronoChat Contacts</string>
   </property>
-  <widget class="QWidget" name="">
+  <widget class="QWidget" name="layoutWidget">
    <property name="geometry">
     <rect>
      <x>12</x>
@@ -279,7 +279,7 @@
      </layout>
     </item>
     <item>
-     <layout class="QHBoxLayout" name="horizontalLayout_6" stretch="1,1,1">
+     <layout class="QHBoxLayout" name="horizontalLayout_6" stretch="4,3,3,3">
       <item>
        <layout class="QHBoxLayout" name="horizontalLayout_5" stretch="1,1">
         <property name="spacing">
@@ -308,6 +308,13 @@
        </layout>
       </item>
       <item>
+       <widget class="QPushButton" name="chatButton">
+        <property name="text">
+         <string>Chat!</string>
+        </property>
+       </widget>
+      </item>
+      <item>
        <widget class="QPushButton" name="settingButton">
         <property name="text">
          <string>Setting</string>
diff --git a/src/digesttreescene.cpp b/src/digesttreescene.cpp
index 5c785e6..c2aa865 100644
--- a/src/digesttreescene.cpp
+++ b/src/digesttreescene.cpp
@@ -152,7 +152,7 @@
 void
 DigestTreeScene::plot(QString digest)
 {
-#ifdef __DEBUG
+#ifdef _DEBUG
   std::cout << "Plotting at time: " << time(NULL) << std::endl;
 #endif
   clear();
@@ -175,7 +175,7 @@
       time_t now = time(NULL);
       if (now - p->getReceived() >= FRESHNESS)
       {
-#ifdef __DEBUG
+#ifdef _DEBUG
         std::cout << "Removing user: " << p->getNick().toStdString() << std::endl;
         std::cout << "now - last = " << now - p->getReceived() << std::endl;
 #endif
@@ -187,7 +187,7 @@
       {
         if (!m_currentPrefix.startsWith("/private/local") && p->getPrefix().startsWith("/private/local"))
         {
-#ifdef __DEBUG
+#ifdef _DEBUG
           std::cout << "erasing: " << p->getPrefix().toStdString() << std::endl;
 #endif
           staleUserList << p->getNick();
diff --git a/src/dns-storage.cpp b/src/dns-storage.cpp
index c26b725..5391edf 100644
--- a/src/dns-storage.cpp
+++ b/src/dns-storage.cpp
@@ -21,6 +21,8 @@
 
 INIT_LOGGER("DnsStorage");
 
+namespace chronos{
+
 const string INIT_DD_TABLE = "\
 CREATE TABLE IF NOT EXISTS                                           \n \
   DnsData(                                                           \n \
@@ -64,75 +66,18 @@
     }
 }
 
-DnsStorage::~DnsStorage()
-{
-  sqlite3_close(m_db);
-}
-
 void
 DnsStorage::updateDnsData(const ndn::Block& data, const std::string& identity, const std::string& name, const std::string& type, const string& dataName)
 {  
   sqlite3_stmt *stmt;
-  sqlite3_prepare_v2 (m_db, "SELECT data_name FROM DnsData where dns_identity=? and dns_name=? and dns_type=?", -1, &stmt, 0);
+  sqlite3_prepare_v2 (m_db, "INSERT OR REPLACE INTO DnsData (dns_identity, dns_name, dns_type, dns_value, data_name) VALUES (?, ?, ?, ?, ?)", -1, &stmt, 0);
   sqlite3_bind_text(stmt, 1, identity.c_str(), identity.size(), SQLITE_TRANSIENT);
   sqlite3_bind_text(stmt, 2, name.c_str(), name.size(), SQLITE_TRANSIENT);
   sqlite3_bind_text(stmt, 3, type.c_str(), type.size(), SQLITE_TRANSIENT);
-
-  if(sqlite3_step (stmt) != SQLITE_ROW)
-    {
-      sqlite3_finalize(stmt);
-      sqlite3_prepare_v2 (m_db, "INSERT INTO DnsData (dns_identity, dns_name, dns_type, dns_value, data_name) VALUES (?, ?, ?, ?, ?)", -1, &stmt, 0);
-      sqlite3_bind_text(stmt, 1, identity.c_str(), identity.size(), SQLITE_TRANSIENT);
-      sqlite3_bind_text(stmt, 2, name.c_str(), name.size(), SQLITE_TRANSIENT);
-      sqlite3_bind_text(stmt, 3, type.c_str(), type.size(), SQLITE_TRANSIENT);
-      sqlite3_bind_text(stmt, 4, (const char*)data.wire(), data.size(), SQLITE_TRANSIENT); 
-      sqlite3_bind_text(stmt, 5, dataName.c_str(), dataName.size(), SQLITE_TRANSIENT);
-      sqlite3_step(stmt);
-      sqlite3_finalize(stmt);
-    }
-  else
-    {
-      sqlite3_finalize(stmt);
-      sqlite3_prepare_v2 (m_db, "UPDATE DnsData SET dns_value=?, data_name=? WHERE dns_identity=? and dns_name=?, dns_type=?", -1, &stmt, 0);
-      sqlite3_bind_text(stmt, 1, (const char*)data.wire(), data.size(), SQLITE_TRANSIENT);
-      sqlite3_bind_text(stmt, 2, dataName.c_str(), dataName.size(), SQLITE_TRANSIENT);
-      sqlite3_bind_text(stmt, 3, identity.c_str(), identity.size(), SQLITE_TRANSIENT);
-      sqlite3_bind_text(stmt, 4, name.c_str(), name.size(), SQLITE_TRANSIENT);
-      sqlite3_bind_text(stmt, 5, type.c_str(), type.size(), SQLITE_TRANSIENT);
-      sqlite3_step(stmt);
-      sqlite3_finalize(stmt);
-    }
-}
-
-void
-DnsStorage::updateDnsSelfProfileData(const Data& data, const Name& identity)
-{
-  string dnsIdentity = identity.toUri();
-  string dnsName("N/A");
-  string dnsType("PROFILE");
-  
-
-  updateDnsData(data.wireEncode(), dnsIdentity, dnsName, dnsType, data.getName().toUri());
-}
-
-void
-DnsStorage::updateDnsEndorseOthers(const Data& data, const Name& identity, const Name& endorsee)
-{
-  string dnsIdentity = identity.toUri();
-  string dnsName = endorsee.toUri();
-  string dnsType("ENDORSEE");
-
-  updateDnsData(data.wireEncode(), dnsIdentity, dnsName, dnsType, data.getName().toUri());
-}
-  
-void
-DnsStorage::updateDnsOthersEndorse(const Data& data, const Name& identity)
-{
-  string dnsIdentity = identity.toUri();
-  string dnsName("N/A");
-  string dnsType("ENDORSED");
-
-  updateDnsData(data.wireEncode(), dnsIdentity, dnsName, dnsType, data.getName().toUri());
+  sqlite3_bind_text(stmt, 4, (const char*)data.wire(), data.size(), SQLITE_TRANSIENT); 
+  sqlite3_bind_text(stmt, 5, dataName.c_str(), dataName.size(), SQLITE_TRANSIENT);
+  sqlite3_step(stmt);
+  sqlite3_finalize(stmt);
 }
 
 shared_ptr<Data>
@@ -153,3 +98,5 @@
 
   return shared_ptr<Data>();
 }
+
+}//chronos
diff --git a/src/dns-storage.h b/src/dns-storage.h
index 8b0880d..89d3876 100644
--- a/src/dns-storage.h
+++ b/src/dns-storage.h
@@ -8,12 +8,15 @@
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
  */
 
-#ifndef LINKNDN_DNS_STORAGE_H
-#define LINKNDN_DNS_STORAGE_H
+#ifndef CHRONOS_DNS_STORAGE_H
+#define CHRONOS_DNS_STORAGE_H
 
+#include "config.h"
 #include <sqlite3.h>
 #include <ndn-cpp-dev/data.hpp>
 
+namespace chronos{
+
 class DnsStorage
 {
 public:
@@ -21,16 +24,20 @@
 
   DnsStorage();
 
-  ~DnsStorage();
+  ~DnsStorage()
+  { sqlite3_close(m_db); }
 
   void
-  updateDnsSelfProfileData(const ndn::Data& data, const ndn::Name& identity);
+  updateDnsSelfProfileData(const ndn::Data& data, const ndn::Name& identity)
+  { updateDnsData(data.wireEncode(), identity.toUri(), "N/A", "PROFILE", data.getName().toUri()); }
 
   void
-  updateDnsEndorseOthers(const ndn::Data& data, const ndn::Name& identity, const ndn::Name& endorsee);
+  updateDnsEndorseOthers(const ndn::Data& data, const ndn::Name& identity, const ndn::Name& endorsee)
+  { updateDnsData(data.wireEncode(), identity.toUri(), endorsee.toUri(), "ENDORSEE", data.getName().toUri()); }
   
   void
-  updateDnsOthersEndorse(const ndn::Data& data, const ndn::Name& identity);
+  updateDnsOthersEndorse(const ndn::Data& data, const ndn::Name& identity)
+  { updateDnsData(data.wireEncode(), identity.toUri(), "N/A", "ENDORSED", data.getName().toUri()); }
 
   ndn::ptr_lib::shared_ptr<ndn::Data>
   getData(const ndn::Name& name);
@@ -43,4 +50,6 @@
   sqlite3 *m_db;
 };
 
+}//chronos
+
 #endif
diff --git a/src/endorse-certificate.cpp b/src/endorse-certificate.cpp
index 0fd6ba0..21f5053 100644
--- a/src/endorse-certificate.cpp
+++ b/src/endorse-certificate.cpp
@@ -15,90 +15,44 @@
 
 using namespace std;
 using namespace ndn;
-using namespace ndn::ptr_lib;
+
 
 INIT_LOGGER("EndorseCertificate");
 
-ProfileExtension::ProfileExtension(const ProfileData & profileData)
-  : CertificateExtension("1.3.6.1.5.32.2.1", true, Buffer(profileData.wireEncode().wire(), profileData.wireEncode().size()))
-{}
+namespace chronos{
 
-ProfileExtension::ProfileExtension(const ProfileExtension& profileExtension)
-  : CertificateExtension("1.3.6.1.5.32.2.1", true, profileExtension.extensionValue_)
-{}
+const OID EndorseCertificate::PROFILE_EXT_OID("1.3.6.1.5.32.2.1");
+const OID EndorseCertificate::ENDORSE_EXT_OID("1.3.6.1.5.32.2.2");
 
-ProfileExtension::ProfileExtension(const CertificateExtension& extension)
-  : CertificateExtension(extension.getOid(), extension.getIsCritical(), extension.getValue())
-{
-  if(extensionId_ != OID("1.3.6.1.5.32.2.1"))
-    throw Error("Wrong ProfileExtension Number!");
-}
-
-shared_ptr<ProfileData>
-ProfileExtension::getProfileData()
-{
-  Data data;
-  data.wireDecode(Block(extensionValue_.buf(), extensionValue_.size()));
-  return make_shared<ProfileData>(data);
-}
-
-EndorseExtension::EndorseExtension(const vector<string>& endorseList)
-  : CertificateExtension("1.3.6.1.5.32.2.2", true, EndorseExtension::encodeEndorseList(endorseList))
-{}
-
-EndorseExtension::EndorseExtension(const EndorseExtension& endorseExtension)
-  : CertificateExtension("1.3.6.1.5.32.2.2", true, endorseExtension.extensionValue_)
-{}
-
-EndorseExtension::EndorseExtension(const CertificateExtension& extension)
-  : CertificateExtension(extension.getOid(), extension.getIsCritical(), extension.getValue())
-{
-  if(extensionId_ != OID("1.3.6.1.5.32.2.2"))
-    throw Error("Wrong EndorseExtension Number!");
-}
-
-vector<string>
-EndorseExtension::getEndorseList()
-{
-  Chronos::EndorseExtensionMsg endorseExtension;
-
-  boost::iostreams::stream
-    <boost::iostreams::array_source> is ((const char*)extensionValue_.buf(), extensionValue_.size());
-
-  endorseExtension.ParseFromIstream(&is);
-
-  vector<string> endorseList;
-
-  for(int i = 0; i < endorseExtension.endorseentry_size(); i ++)
-    endorseList.push_back(endorseExtension.endorseentry(i).name());
-  
-  return endorseList;
-}
-
-Buffer
-EndorseExtension::encodeEndorseList(const vector<string>& endorseList)
-{
-  Chronos::EndorseExtensionMsg endorseExtension;
-  
+Chronos::EndorseExtensionMsg&
+operator << (Chronos::EndorseExtensionMsg& endorseExtension, const vector<string>& endorseList)
+{ 
   vector<string>::const_iterator it = endorseList.begin();
   for(; it != endorseList.end(); it++)
     endorseExtension.add_endorseentry()->set_name(*it);
 
-  string encoded;
-  endorseExtension.SerializeToString(&encoded);
-  
-  return Buffer(encoded.c_str(), encoded.size());
+  return endorseExtension;
+}
+
+Chronos::EndorseExtensionMsg&
+operator >> (Chronos::EndorseExtensionMsg& endorseExtension, vector<string>& endorseList)
+{
+  for(int i = 0; i < endorseExtension.endorseentry_size(); i ++)
+    endorseList.push_back(endorseExtension.endorseentry(i).name());
+
+  return endorseExtension;
 }
 
 EndorseCertificate::EndorseCertificate(const IdentityCertificate& kskCertificate,
-                                       const ProfileData& profileData,
+                                       const Profile& profile,
                                        const vector<string>& endorseList)
   : Certificate()
-  , m_keyName(kskCertificate.getPublicKeyName())
-  , m_signer(kskCertificate.getPublicKeyName())
-  , m_profileData(profileData)
+  , m_profile(profile)
   , m_endorseList(endorseList)
 {
+  m_keyName = IdentityCertificate::certificateNameToPublicKeyName(kskCertificate.getName());
+  m_signer = m_keyName;
+
   Name dataName = m_keyName;
   dataName.append("PROFILE-CERT").append(m_signer.wireEncode()).appendVersion();
   setName(dataName);
@@ -107,8 +61,16 @@
   setNotAfter(kskCertificate.getNotAfter());
   addSubjectDescription(CertificateSubjectDescription("2.5.4.41", m_keyName.toUri()));
   setPublicKeyInfo(kskCertificate.getPublicKeyInfo());  
-  addExtension(ProfileExtension(m_profileData));
-  addExtension(EndorseExtension(m_endorseList));
+
+  OBufferStream profileStream;
+  m_profile.encode(profileStream);
+  addExtension(CertificateExtension(PROFILE_EXT_OID, true, *profileStream.buf()));
+
+  OBufferStream endorseStream;
+  Chronos::EndorseExtensionMsg endorseExtension;
+  endorseExtension << m_endorseList;
+  endorseExtension.SerializeToOstream(&endorseStream);
+  addExtension(CertificateExtension(ENDORSE_EXT_OID, true, *endorseStream.buf()));
   
   encode();
 }
@@ -119,9 +81,9 @@
   : Certificate()
   , m_keyName(endorseCertificate.m_keyName)
   , m_signer(signer)
-  , m_profileData(endorseCertificate.m_profileData)
+  , m_profile(endorseCertificate.m_profile)
   , m_endorseList(endorseList)
-{  
+{
   Name dataName = m_keyName;
   dataName.append("PROFILE-CERT").append(m_signer.wireEncode()).appendVersion();
   setName(dataName);
@@ -130,8 +92,16 @@
   setNotAfter(endorseCertificate.getNotAfter());
   addSubjectDescription(CertificateSubjectDescription("2.5.4.41", m_keyName.toUri()));
   setPublicKeyInfo(endorseCertificate.getPublicKeyInfo());
-  addExtension(ProfileExtension(m_profileData));
-  addExtension(EndorseExtension(m_endorseList));
+
+  OBufferStream profileStream;
+  m_profile.encode(profileStream);
+  addExtension(CertificateExtension(PROFILE_EXT_OID, true, *profileStream.buf()));
+
+  OBufferStream endorseStream;
+  Chronos::EndorseExtensionMsg endorseExtension;
+  endorseExtension << m_endorseList;
+  endorseExtension.SerializeToOstream(&endorseStream);
+  addExtension(CertificateExtension(ENDORSE_EXT_OID, true, *endorseStream.buf()));
 
   encode();
 }
@@ -140,7 +110,7 @@
   : Certificate(endorseCertificate)
   , m_keyName(endorseCertificate.m_keyName)
   , m_signer(endorseCertificate.m_signer)
-  , m_profileData(endorseCertificate.m_profileData)
+  , m_profile(endorseCertificate.m_profile)
   , m_endorseList(endorseCertificate.m_endorseList)
 {}
 
@@ -149,28 +119,32 @@
 {
   const Name& dataName = data.getName();
 
-  if(dataName.size() < 3 || !dataName.get(-3).equals("PROFILE-CERT"))
+  if(dataName.size() < 3 || dataName.get(-3).toEscapedString() != "PROFILE-CERT")
     throw Error("No PROFILE-CERT component in data name!");    
 
   m_keyName = dataName.getPrefix(-3);
-  m_signer.wireDecode(Block(dataName.get(-2).getValue().buf(),
-                            dataName.get(-2).getValue().size()));
-
-  OID profileExtensionOID("1.3.6.1.5.32.2.1");
-  OID endorseExtensionOID("1.3.6.1.5.32.2.2");
+  m_signer.wireDecode(dataName.get(-2).blockFromValue());
 
   ExtensionList::iterator it = extensionList_.begin();
   for(; it != extensionList_.end(); it++)
     {
-      if(profileExtensionOID == it->getOid())
+      if(PROFILE_EXT_OID == it->getOid())
 	{
-          ProfileExtension profileExtension(*it);
-	  m_profileData = *profileExtension.getProfileData();
+          boost::iostreams::stream<boost::iostreams::array_source> is 
+            (reinterpret_cast<const char*>(it->getValue().buf()), it->getValue().size());
+	  m_profile.decode(is);
 	}
-      if(endorseExtensionOID == it->getOid())
+      if(ENDORSE_EXT_OID == it->getOid())
         {
-          EndorseExtension endorseExtension(*it);
-          m_endorseList = endorseExtension.getEndorseList();
+          Chronos::EndorseExtensionMsg endorseExtension;
+
+          boost::iostreams::stream<boost::iostreams::array_source> is 
+            (reinterpret_cast<const char*>(it->getValue().buf()), it->getValue().size());          
+          endorseExtension.ParseFromIstream(&is);
+
+          endorseExtension >> m_endorseList;
         }
     }
 }
+
+}//chronos
diff --git a/src/endorse-certificate.h b/src/endorse-certificate.h
index 4d011d6..7352a4d 100644
--- a/src/endorse-certificate.h
+++ b/src/endorse-certificate.h
@@ -8,53 +8,16 @@
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
  */
 
-#ifndef LINKNDN_ENDORSE_CERTIFICATE_H
-#define LINKNDN_ENDORSE_CERTIFICATE_H
+#ifndef CHRONOS_ENDORSE_CERTIFICATE_H
+#define CHRONOS_ENDORSE_CERTIFICATE_H
 
+#include "profile.h"
 #include <vector>
-#include <ndn-cpp-dev/data.hpp>
 #include <ndn-cpp-dev/security/identity-certificate.hpp>
-#include <ndn-cpp-dev/security/certificate-extension.hpp>
 
-#include "profile-data.h"
 
-class ProfileExtension : public ndn::CertificateExtension
-{
-public:
-  struct Error : public ndn::CertificateExtension::Error { Error(const std::string &what) : ndn::CertificateExtension::Error(what) {} };
 
-  ProfileExtension(const ProfileData& profileData);
-  
-  ProfileExtension(const ProfileExtension& profileExtension);
-
-  ProfileExtension(const CertificateExtension& extension);
-
-  ~ProfileExtension() {}
-
-  ndn::ptr_lib::shared_ptr<ProfileData>
-  getProfileData();
-};
-
-class EndorseExtension : public ndn::CertificateExtension
-{
-public:
-  struct Error : public ndn::CertificateExtension::Error { Error(const std::string &what) : ndn::CertificateExtension::Error(what) {} };
-
-  EndorseExtension(const std::vector<std::string>& endorseList);
-
-  EndorseExtension(const EndorseExtension& endorseExtension);
-
-  EndorseExtension(const CertificateExtension& extension);
-
-  ~EndorseExtension() {}
-
-  std::vector<std::string>
-  getEndorseList();
-
-private:
-  static ndn::Buffer
-  encodeEndorseList(const std::vector<std::string>& endorsedList);
-};
+namespace chronos{
 
 class EndorseCertificate : public ndn::Certificate
 {
@@ -64,7 +27,7 @@
   EndorseCertificate() {}
 
   EndorseCertificate(const ndn::IdentityCertificate& kskCertificate,
-                     const ProfileData& profileData,
+                     const Profile& profile,
                      const std::vector<std::string>& endorseList = std::vector<std::string>());
 
   EndorseCertificate(const EndorseCertificate& endorseCertificate,
@@ -83,23 +46,28 @@
   getSigner() const
   { return m_signer; }
 
-  const ProfileData&
-  getProfileData() const
-  { return m_profileData; }
+  const Profile&
+  getProfile() const
+  { return m_profile; }
 
   const std::vector<std::string>&
   getEndorseList() const
   { return m_endorseList; }
 
-  virtual ndn::Name
+  const ndn::Name&
   getPublicKeyName () const
   { return m_keyName; }
 
-protected:
+private:
+  static const ndn::OID PROFILE_EXT_OID;
+  static const ndn::OID ENDORSE_EXT_OID;
+
   ndn::Name m_keyName;
   ndn::Name m_signer;
-  ProfileData m_profileData;
+  Profile m_profile;
   std::vector<std::string> m_endorseList;
 };
 
+}//chronos
+
 #endif
diff --git a/src/endorse-combobox-delegate.h b/src/endorse-combobox-delegate.h
index d0822b3..4b16172 100644
--- a/src/endorse-combobox-delegate.h
+++ b/src/endorse-combobox-delegate.h
@@ -8,8 +8,8 @@
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
  */
 
-#ifndef LINKNDN_ENDORSE_COMBOBOX_DELEGATE_H
-#define LINKNDN_ENDORSE_COMBOBOX_DELEGATE_H
+#ifndef ENDORSE_COMBOBOX_DELEGATE_H
+#define ENDORSE_COMBOBOX_DELEGATE_H
 
 #include <QItemDelegate>
 #include <string>
diff --git a/src/invitation.cpp b/src/invitation.cpp
new file mode 100644
index 0000000..9495cec
--- /dev/null
+++ b/src/invitation.cpp
@@ -0,0 +1,70 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "invitation.h"
+
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
+
+#include "logging.h"
+
+using namespace std;
+using namespace ndn;
+
+INIT_LOGGER("Invitation");
+
+
+namespace chronos{
+
+const size_t  Invitation::NAME_SIZE_MIN  = 9;
+const size_t  Invitation::INVITEE_START  = 4;
+const ssize_t Invitation::SIGNATURE      = -1;
+const ssize_t Invitation::KEY_LOCATOR    = -2;
+const ssize_t Invitation::TIMESTAMP      = -3;
+const ssize_t Invitation::INVITER_PREFIX = -4;
+const ssize_t Invitation::CHATROOM       = -5;
+const Name    Invitation::INVITATION_PREFIX("/ndn/broadcast/chronos/chat-invitation");
+
+
+Invitation::Invitation(const Name& interestName)
+{
+  size_t nameSize = interestName.size();
+
+  if(nameSize < NAME_SIZE_MIN)
+    throw Error("Wrong Invitation Name: Wrong length"); 
+ 
+  if(!INVITATION_PREFIX.isPrefixOf(interestName))
+    throw Error("Wrong Invitation Name: Wrong invitation prefix");
+
+  m_interestName = interestName.getPrefix(-3);
+  m_inviterRoutingPrefix.wireDecode(interestName.get(INVITER_PREFIX).blockFromValue());
+  m_chatroom.wireDecode(interestName.get(CHATROOM).blockFromValue());
+  m_inviteeNameSpace = interestName.getSubName(INVITEE_START, nameSize - NAME_SIZE_MIN);  
+}
+
+Invitation::Invitation(const Name &inviteeNameSpace,
+                       const Name &chatroom,
+                       const Name &inviterRoutingPrefix)
+  : m_inviteeNameSpace(inviteeNameSpace)
+  , m_chatroom(chatroom)
+  , m_inviterRoutingPrefix(inviterRoutingPrefix)
+{  
+  m_interestName = INVITATION_PREFIX;
+  m_interestName.append(inviteeNameSpace).append(chatroom.wireEncode()).append(inviterRoutingPrefix.wireEncode());
+}
+
+Invitation::Invitation(const Invitation& invitation)
+  : m_interestName(invitation.m_interestName)
+  , m_inviteeNameSpace(invitation.m_inviteeNameSpace)
+  , m_chatroom(invitation.m_chatroom)
+  , m_inviterRoutingPrefix(invitation.m_inviterRoutingPrefix)
+{}
+
+}//chronos
diff --git a/src/invitation.h b/src/invitation.h
new file mode 100644
index 0000000..ba850ac
--- /dev/null
+++ b/src/invitation.h
@@ -0,0 +1,76 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef CHRONOS_INVITATION_H
+#define CHRONOS_INVITATION_H
+
+
+#include <ndn-cpp-dev/name.hpp>
+#include <ndn-cpp-dev/signature.hpp>
+
+namespace chronos{
+
+class Invitation
+{
+/*
+ * /ndn/broadcast/chronos/invitation/[invitee_namespace]/<chatroom_name>/<inviter_routing_prefix>/<timestamp>/<keylocator>/<signature>
+ */
+  static const size_t NAME_SIZE_MIN;
+  static const size_t INVITEE_START;
+  static const ssize_t SIGNATURE;
+  static const ssize_t KEY_LOCATOR;
+  static const ssize_t TIMESTAMP;
+  static const ssize_t INVITER_PREFIX;
+  static const ssize_t CHATROOM;
+  static const ndn::Name INVITATION_PREFIX;
+
+public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+  Invitation() {}
+
+  Invitation(const ndn::Name& interestName);
+
+  Invitation(const ndn::Name &inviteeNameSpace,
+             const ndn::Name &chatroom,
+             const ndn::Name &inviterRoutingPrefix);
+
+  Invitation(const Invitation& invitation);
+
+  virtual
+  ~Invitation() {};
+
+  const ndn::Name&
+  getInviteeNameSpace() const
+  { return m_inviteeNameSpace; }
+
+  const ndn::Name&
+  getChatroom() const
+  { return m_chatroom; }
+
+  const ndn::Name&
+  getInviterRoutingPrefix() const
+  { return m_inviterRoutingPrefix; }
+  
+  const ndn::Name&
+  getUnsignedInterestName() const
+  { return m_interestName; }
+
+private:
+  ndn::Name m_interestName;
+
+  ndn::Name m_inviteeNameSpace;
+  ndn::Name m_chatroom;
+  ndn::Name m_inviterRoutingPrefix;
+};
+
+}//chronos
+
+#endif
diff --git a/src/invitationdialog.cpp b/src/invitationdialog.cpp
index c142014..2a1d21f 100644
--- a/src/invitationdialog.cpp
+++ b/src/invitationdialog.cpp
@@ -14,7 +14,7 @@
 
 using namespace std;
 using namespace ndn;
-using namespace ndn::ptr_lib;
+using namespace chronos;
 
 InvitationDialog::InvitationDialog(QWidget *parent) :
     QDialog(parent),
@@ -35,24 +35,22 @@
 
 void
 InvitationDialog::setInvitation(const string& alias,
-                                shared_ptr<ChronosInvitation> invitation, 
-                                shared_ptr<IdentityCertificate> identityCertificate)
+                                const Name& interestName)
 {
   m_inviterAlias = alias;
   string msg = alias;
   msg.append("\ninvites you to join the chat room: ");
   ui->msgLabel->setText(QString::fromStdString(msg));
 
-  m_invitation = invitation;
-  ui->chatroomLine->setText(QString::fromStdString(invitation->getChatroom().get(0).toEscapedString()));
-
-  m_identityCertificate = identityCertificate;
+  m_invitationInterest = interestName;
+  Invitation invitation(interestName);
+  ui->chatroomLine->setText(QString::fromStdString(invitation.getChatroom().get(0).toEscapedString()));
 }
 
 void
 InvitationDialog::onOkClicked()
 { 
-  emit invitationAccepted(*m_invitation, *m_identityCertificate); 
+  emit invitationAccepted(m_invitationInterest); 
   this->close();
 }
   
@@ -62,10 +60,9 @@
   ui->msgLabel->clear();
   ui->chatroomLine->clear();
 
-  emit invitationRejected(*m_invitation); 
+  emit invitationRejected(m_invitationInterest); 
 
-  m_invitation = make_shared<ChronosInvitation>();
-  m_identityCertificate = make_shared<IdentityCertificate>();
+  m_invitationInterest.clear();
   m_inviterAlias.clear();
 
   this->close();
diff --git a/src/invitationdialog.h b/src/invitationdialog.h
index 2e01fd9..8edc04d 100644
--- a/src/invitationdialog.h
+++ b/src/invitationdialog.h
@@ -16,7 +16,7 @@
 #ifndef Q_MOC_RUN
 #include <ndn-cpp-dev/data.hpp>
 #include <ndn-cpp-dev/security/identity-certificate.hpp>
-#include "chronos-invitation.h"
+#include "invitation.h"
 #endif
 
 namespace Ui {
@@ -33,16 +33,14 @@
 
   void
   setInvitation(const std::string& alias,
-                ndn::ptr_lib::shared_ptr<ChronosInvitation> invitation, 
-                ndn::ptr_lib::shared_ptr<ndn::IdentityCertificate> identityCertificate);
+                const ndn::Name& invitationInterest);
 
 signals:
   void
-  invitationAccepted(const ChronosInvitation& invitation, 
-                     const ndn::IdentityCertificate& identityCertificate);
+  invitationAccepted(const ndn::Name& invitationInterest);
   
   void
-  invitationRejected(const ChronosInvitation& invitation);
+  invitationRejected(const ndn::Name& invitationInterest);
 
 private slots:
   void
@@ -55,8 +53,7 @@
 private:
   Ui::InvitationDialog *ui;
   std::string m_inviterAlias;
-  ndn::ptr_lib::shared_ptr<ChronosInvitation> m_invitation;
-  ndn::ptr_lib::shared_ptr<ndn::IdentityCertificate> m_identityCertificate;
+  ndn::Name m_invitationInterest;
 };
 
 #endif // INVITATIONDIALOG_H
diff --git a/src/invitelistdialog.cpp b/src/invitelistdialog.cpp
index ea6b790..50fa50f 100644
--- a/src/invitelistdialog.cpp
+++ b/src/invitelistdialog.cpp
@@ -12,8 +12,9 @@
 #include "ui_invitelistdialog.h"
 
 using namespace std;
+using namespace chronos;
 
-InviteListDialog::InviteListDialog(ndn::ptr_lib::shared_ptr<ContactManager> contactManager,
+InviteListDialog::InviteListDialog(ndn::shared_ptr<ContactManager> contactManager,
 				   QWidget *parent) 
   :QDialog(parent)
   , ui(new Ui::InviteListDialog)
diff --git a/src/invitelistdialog.h b/src/invitelistdialog.h
index dc91c7a..83e1b50 100644
--- a/src/invitelistdialog.h
+++ b/src/invitelistdialog.h
@@ -27,7 +27,7 @@
   Q_OBJECT
 
 public:
-  explicit InviteListDialog(ndn::ptr_lib::shared_ptr<ContactManager> contactManager,
+  explicit InviteListDialog(ndn::shared_ptr<chronos::ContactManager> contactManager,
                             QWidget *parent = 0);
   ~InviteListDialog();
 
@@ -50,9 +50,9 @@
 
 private:
   Ui::InviteListDialog *ui;
-  ndn::ptr_lib::shared_ptr<ContactManager> m_contactManager;
+  ndn::shared_ptr<chronos::ContactManager> m_contactManager;
   QStringListModel* m_contactListModel;
-  std::vector<ndn::ptr_lib::shared_ptr<ContactItem> > m_contactList;
+  std::vector<ndn::shared_ptr<chronos::ContactItem> > m_contactList;
   std::vector<std::string> m_invitedContacts;
 };
 
diff --git a/src/main.cpp b/src/main.cpp
index 219151e..030ba43 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -16,6 +16,8 @@
 #include "dns-storage.h"
 #include "contact-manager.h"
 #include "logging.h"
+#include <ndn-cpp-dev/face.hpp>
+#include <boost/thread/thread.hpp>
 
 INIT_LOGGER("MAIN");
 
@@ -41,15 +43,27 @@
   }
 };
 
+void runIO(shared_ptr<boost::asio::io_service> ioService)
+{
+  try{
+    ioService->run();
+  }catch(std::runtime_error& e){
+    std::cerr << e.what() << std::endl;
+  }
+}
+
 int main(int argc, char *argv[])
 {
   NewApp app(argc, argv);
-
-  ContactPanel contactPanel;
+  
+  shared_ptr<Face> face = make_shared<Face>();
+  ContactPanel contactPanel(face);
 
   contactPanel.show ();
   contactPanel.activateWindow ();
   contactPanel.raise ();
+
+  boost::thread (runIO, face->ioService());
   
   return app.exec();
 }
diff --git a/src/profile-data.cpp b/src/profile-data.cpp
index 2288f9d..98ce957 100644
--- a/src/profile-data.cpp
+++ b/src/profile-data.cpp
@@ -9,16 +9,16 @@
  */
 
 #include "profile-data.h"
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include "logging.h"
 
+#include "logging.h"
 
 using namespace ndn;
 using namespace std;
-using namespace boost::posix_time;
 
 INIT_LOGGER("ProfileData");
 
+namespace chronos{
+
 ProfileData::ProfileData()
   : Data()
 {}
@@ -29,45 +29,26 @@
   , m_profile(profile)
 {
   Name dataName = m_identity;
-  
-  time_duration now = microsec_clock::universal_time () - ptime(boost::gregorian::date (1970, boost::gregorian::Jan, 1));
-  uint64_t version = (now.total_seconds () << 12) | (0xFFF & (now.fractional_seconds () / 244));
-  dataName.append("PROFILE").appendVersion(version);
+  dataName.append("PROFILE").appendVersion();
   setName(dataName);
 
-  string content;
-  profile.encode(&content);
-  setContent((const uint8_t *)&content[0], content.size());
-
+  OBufferStream os;
+  profile.encode(os);
+  setContent(os.buf());
 }
 
-// ProfileData::ProfileData(const ProfileData& profileData)
-//   : Data(profileData)
-//   , m_identity(profileData.m_identity)
-//   , m_profile(profileData.m_profile)
-// {}
-
 ProfileData::ProfileData(const Data& data)
   : Data(data)
 {
-  const Name& dataName = data.getName();
-  Name::Component appFlag(Name::fromEscapedString("PROFILE"));  
-
-  int profileIndex = -1;
-  for(int i = 0; i < dataName.size(); i++)
-    {
-      if(0 == dataName.get(i).compare(appFlag))
-	{
-	  profileIndex = i;
-	  break;
-	}
-    }
-
-  if(profileIndex < 0)
+  if(data.getName().get(-2).toEscapedString() == "PROFILE")
     throw Error("No PROFILE component in data name!");
 
-  m_identity = dataName.getPrefix(profileIndex);
+  m_identity = data.getName().getPrefix(-2);
 
-  string encoded(reinterpret_cast<const char*>(data.getContent().value()), data.getContent().value_size());
-  m_profile = *Profile::decode(encoded);
+  boost::iostreams::stream <boost::iostreams::array_source> is 
+    (reinterpret_cast<const char*>(data.getContent().value()), data.getContent().value_size());
+
+  m_profile.decode(is);
 }
+
+}//chronos
diff --git a/src/profile-data.h b/src/profile-data.h
index 46a926d..47fe910 100644
--- a/src/profile-data.h
+++ b/src/profile-data.h
@@ -8,11 +8,14 @@
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
  */
 
-#ifndef LINKNDN_PROFILE_DATA_H
-#define LINKNDN_PROFILE_DATA_H
+#ifndef CHRONOS_PROFILE_DATA_H
+#define CHRONOS_PROFILE_DATA_H
 
-#include <ndn-cpp-dev/data.hpp>
 #include "profile.h"
+#include <ndn-cpp-dev/data.hpp>
+
+
+namespace chronos{
 
 class ProfileData : public ndn::Data
 {
@@ -23,8 +26,6 @@
 
   ProfileData(const Profile& profile);
 
-  // ProfileData(const ProfileData& profileData);
-
   ProfileData(const ndn::Data& data);
 
   ~ProfileData() {}
@@ -42,4 +43,6 @@
   Profile m_profile;
 };
 
+}//chronos
+
 #endif
diff --git a/src/profile.cpp b/src/profile.cpp
index d662a70..40a7aee 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -13,26 +13,23 @@
 
 using namespace std;
 using namespace ndn;
-using namespace ndn::ptr_lib;
 
 INIT_LOGGER("Profile");
 
-static string nameOid("2.5.4.41");
-static string orgOid("2.5.4.11");
-static string groupOid("2.5.4.1");
-static string homepageOid("2.5.4.3");
-static string advisor("2.5.4.80");
-static string emailOid("1.2.840.113549.1.9.1");
+namespace chronos{
 
-Profile::Profile(const IdentityCertificate& oldIdentityCertificate)
+const string Profile::OID_NAME("2.5.4.41");
+const string Profile::OID_ORG("2.5.4.11");
+const string Profile::OID_GROUP("2.5.4.1");
+const string Profile::OID_HOMEPAGE("2.5.4.3");
+const string Profile::OID_ADVISOR("2.5.4.80");
+const string Profile::OID_EMAIL("1.2.840.113549.1.9.1");
+
+Profile::Profile(const IdentityCertificate& identityCertificate)
 {
-  IdentityCertificate identityCertificate(oldIdentityCertificate);
+  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(identityCertificate.getName());
 
-  Name keyName = identityCertificate.getPublicKeyName();
-  m_identityName = keyName.getPrefix(-1);
-
-  const string& identityString = m_identityName.toUri();
-  m_entries[string("IDENTITY")] = identityString;
+  m_entries[string("IDENTITY")] = keyName.getPrefix(-1).toUri();
   
   const vector<CertificateSubjectDescription>& subList = identityCertificate.getSubjectDescriptionList();
   vector<CertificateSubjectDescription>::const_iterator it = subList.begin();
@@ -40,94 +37,80 @@
     {
       const string oidStr = it->getOidString();
       string valueStr = it->getValue();
-      if(oidStr == nameOid)
-        m_entries[string("name")] = valueStr;
-      else if(oidStr == orgOid)
-        m_entries[string("institution")] = valueStr;
-      else if(oidStr == groupOid)
-        m_entries[string("group")] = valueStr;
-      else if(oidStr == homepageOid)
-        m_entries[string("homepage")] = valueStr;
-      else if(oidStr == advisor)
-        m_entries[string("advisor")] = valueStr;
-      else if(oidStr == emailOid)
-        m_entries[string("email")] = valueStr;
+      if(oidStr == OID_NAME)
+        m_entries["name"] = valueStr;
+      else if(oidStr == OID_ORG)
+        m_entries["institution"] = valueStr;
+      else if(oidStr == OID_GROUP)
+        m_entries["group"] = valueStr;
+      else if(oidStr == OID_HOMEPAGE)
+        m_entries["homepage"] = valueStr;
+      else if(oidStr == OID_ADVISOR)
+        m_entries["advisor"] = valueStr;
+      else if(oidStr == OID_EMAIL)
+        m_entries["email"] = valueStr;
       else
         m_entries[oidStr] = valueStr;
     }
 }
 
 Profile::Profile(const Name& identityName)
-  : m_identityName(identityName)
 {
-  const string& identityString = identityName.toUri();
-  m_entries[string("IDENTITY")] = identityString;
+  m_entries["IDENTITY"] = identityName.toUri();
 }
 
 Profile::Profile(const Name& identityName,
 		 const string& name,
 		 const string& institution)
-  : m_identityName(identityName)
 {
-  const string& identityString = identityName.toUri();
-  m_entries[string("IDENTITY")] = identityString;
-
-  m_entries[string("name")] = name;
-  m_entries[string("institution")] = institution;
+  m_entries["IDENTITY"] = identityName.toUri();
+  m_entries["name"] = name;
+  m_entries["institution"] = institution;
 }
 
 Profile::Profile(const Profile& profile)
-  : m_identityName(profile.m_identityName)
-  , m_entries(profile.m_entries)
+  : m_entries(profile.m_entries)
 {}
 
 void
-Profile::setProfileEntry(const string& profileType,
-			 const string& profileValue)
-{ m_entries[profileType] = profileValue; }
-
-string
-Profile::getProfileEntry(const string& profileType) const
+Profile::encode(ostream& os) const
 {
-  if(m_entries.find(profileType) != m_entries.end())
-    return m_entries.at(profileType);
-
-  return string();
+  Chronos::ProfileMsg profileMsg;
+  profileMsg << (*this);
+  profileMsg.SerializeToOstream(&os);
 }
 
 void
-Profile::encode(string* output) const
+Profile::decode(istream& is)
 {
+  Chronos::ProfileMsg profileMsg;    
+  profileMsg.ParseFromIstream(&is);
+  profileMsg >> (*this);
+}
 
-  Chronos::ProfileMsg profileMsg;
-
-  profileMsg.set_identityname(m_identityName.toUri());
-  
-  map<string, string>::const_iterator it = m_entries.begin();
-  for(; it != m_entries.end(); it++)
+Chronos::ProfileMsg&
+operator << (Chronos::ProfileMsg& profileMsg, const Profile& profile)
+{
+  map<string, string>::const_iterator it = profile.begin();
+  for(; it != profile.end(); it++)
     {
       Chronos::ProfileMsg::ProfileEntry* profileEntry = profileMsg.add_entry();
       profileEntry->set_oid(it->first);
       profileEntry->set_data(it->second);
     }
-
-  profileMsg.SerializeToString(output);
+  return profileMsg;
 }
 
-shared_ptr<Profile>
-Profile::decode(const string& input)
+Chronos::ProfileMsg&
+operator >> (Chronos::ProfileMsg& profileMsg, Profile& profile)
 {
-  Chronos::ProfileMsg profileMsg;
-    
-  profileMsg.ParseFromString(input);
-
-  shared_ptr<Profile> profile = make_shared<Profile>(profileMsg.identityname());
-
   for(int i = 0; i < profileMsg.entry_size(); i++)
     {
       const Chronos::ProfileMsg::ProfileEntry& profileEntry = profileMsg.entry(i);
-      profile->setProfileEntry(profileEntry.oid(), profileEntry.data());
+      profile[profileEntry.oid()] = profileEntry.data();
     }
-
-  return profile;
+  
+  return profileMsg;
 }
+
+}//chronos
diff --git a/src/profile.h b/src/profile.h
index 2afef31..e085e77 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -8,21 +8,24 @@
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
  */
 
-#ifndef LINKNDN_PROFILE_H
-#define LINKNDN_PROFILE_H
+#ifndef CHRONOS_PROFILE_H
+#define CHRONOS_PROFILE_H
 
+#include "config.h"
 #include <ndn-cpp-dev/name.hpp>
 #include <ndn-cpp-dev/security/identity-certificate.hpp>
 #include <map>
 #include <string>
 #include "profile.pb.h"
 
+namespace chronos{
+
 class Profile
 {
 public:
   typedef std::map<std::string, std::string>::iterator iterator;
   typedef std::map<std::string, std::string>::const_iterator const_iterator;
-public:
+
   Profile() {}
 
   Profile(const ndn::IdentityCertificate& identityCertificate);
@@ -35,15 +38,21 @@
   
   Profile(const Profile& profile);
   
-  virtual
   ~Profile() {}
 
-  void
-  setProfileEntry(const std::string& profileType,
-                  const std::string& profileValue);
-  
-  std::string
-  getProfileEntry(const std::string& profileType) const;
+  std::string&
+  operator [] (const std::string& profileKey)
+  { return m_entries[profileKey]; }
+
+  std::string 
+  get (const std::string& profileKey) const
+  {
+    std::map<std::string, std::string>::const_iterator it = m_entries.find(profileKey);
+    if(it != m_entries.end())
+      return it->second;
+    else
+      return std::string();
+  }
 
   inline Profile::iterator
   begin()
@@ -62,22 +71,54 @@
   { return m_entries.end(); }
 
   void
-  encode(std::string* output) const;
+  encode(std::ostream& os) const;
 
-  static ndn::ptr_lib::shared_ptr<Profile>
-  decode(const std::string& input);
+  void
+  decode(std::istream& is);
 
-  const std::map<std::string, std::string>&
-  getEntries() const
-  { return m_entries; }
-
-  const ndn::Name&
+  ndn::Name
   getIdentityName() const
-  { return m_identityName; }
+  { return ndn::Name(m_entries.at("IDENTITY")); }
 
-protected:
-  ndn::Name m_identityName;
+  inline bool
+  operator == (const Profile& profile) const;
+
+private:
+  static const std::string OID_NAME;
+  static const std::string OID_ORG;
+  static const std::string OID_GROUP;
+  static const std::string OID_HOMEPAGE;
+  static const std::string OID_ADVISOR;
+  static const std::string OID_EMAIL;
+
   std::map<std::string, std::string> m_entries;
 };
 
+Chronos::ProfileMsg&
+operator << (Chronos::ProfileMsg& msg, const Profile& profile);
+
+Chronos::ProfileMsg&
+operator >> (Chronos::ProfileMsg& msg, Profile& profile);
+
+bool
+Profile::operator == (const Profile& profile) const
+{
+  if(m_entries.size() != profile.m_entries.size())
+    return false;
+
+  std::map<std::string, std::string>::const_iterator it = m_entries.begin();
+  for(; it != m_entries.end(); it++)
+    {
+      std::map<std::string, std::string>::const_iterator found = profile.m_entries.find(it->first);
+      if(found == profile.m_entries.end())
+        return false;
+      if(found->second != it->second)
+        return false;
+    }
+
+  return true;
+}
+
+}//chronos
+
 #endif
diff --git a/src/profile.proto b/src/profile.proto
index 34f79da..e9b15e8 100644
--- a/src/profile.proto
+++ b/src/profile.proto
@@ -2,7 +2,6 @@
 
 message ProfileMsg
 {
-  required string identityName = 1;
   message ProfileEntry
   {
     required string oid = 1;
diff --git a/src/profileeditor.cpp b/src/profileeditor.cpp
index 9d0d844..17931d0 100644
--- a/src/profileeditor.cpp
+++ b/src/profileeditor.cpp
@@ -20,7 +20,7 @@
 
 using namespace ndn;
 using namespace std;
-using namespace ndn::ptr_lib;
+using namespace chronos;
 
 INIT_LOGGER("ProfileEditor");
 
@@ -84,13 +84,6 @@
 void
 ProfileEditor::onOkClicked()
 {
-  Name defaultCertName = m_keyChain->getDefaultCertificateNameForIdentity(m_currentIdentity);
-  if(defaultCertName.size() == 0)
-    {
-      emit noKeyOrCert(QString::fromStdString("Corresponding certificate is missing!\nHave you installed the certificate?"));
-      return;
-    }
-
   m_tableModel->submitAll();
   m_contactManager->updateProfileData(m_currentIdentity);
   this->hide();
diff --git a/src/profileeditor.h b/src/profileeditor.h
index 0bf1b30..e36a695 100644
--- a/src/profileeditor.h
+++ b/src/profileeditor.h
@@ -28,7 +28,7 @@
     Q_OBJECT
 
 public:
-  explicit ProfileEditor(ndn::ptr_lib::shared_ptr<ContactManager> contactManager, 
+  explicit ProfileEditor(ndn::shared_ptr<chronos::ContactManager> contactManager, 
                          QWidget *parent = 0);
   
   ~ProfileEditor();
@@ -57,8 +57,8 @@
 private:
   Ui::ProfileEditor *ui;
   QSqlTableModel* m_tableModel;
-  ndn::ptr_lib::shared_ptr<ContactManager> m_contactManager;
-  ndn::ptr_lib::shared_ptr<ndn::KeyChain> m_keyChain;
+  ndn::shared_ptr<chronos::ContactManager> m_contactManager;
+  ndn::shared_ptr<ndn::KeyChain> m_keyChain;
   ndn::Name m_currentIdentity;
 };
 
diff --git a/src/sec-policy-chrono-chat-invitation.cpp b/src/sec-policy-chrono-chat-invitation.cpp
deleted file mode 100644
index f0daf90..0000000
--- a/src/sec-policy-chrono-chat-invitation.cpp
+++ /dev/null
@@ -1,250 +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: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "sec-policy-chrono-chat-invitation.h"
-#include <ndn-cpp-dev/security/verifier.hpp>
-#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
-
-#include "logging.h"
-
-using namespace std;
-using namespace ndn;
-using namespace ndn::ptr_lib;
-
-INIT_LOGGER("SecPolicyChronoChatInvitation");
-
-SecPolicyChronoChatInvitation::SecPolicyChronoChatInvitation(const string& chatroomName,
-                                                 const Name& signingIdentity,
-                                                 int stepLimit)
-  : m_chatroomName(chatroomName)
-  , m_signingIdentity(signingIdentity)
-  , m_stepLimit(stepLimit)
-{
-  m_invitationPolicyRule = make_shared<SecRuleRelative>("^<ndn><broadcast><chronos><invitation>([^<chatroom>]*)<chatroom>", 
-                                                           "^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT>$", 
-                                                           "==", "\\1", "\\1\\2", true);
-
-  m_kskRegex = make_shared<Regex>("^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT><>$", "\\1\\2");
-
-  m_dskRule = make_shared<SecRuleRelative>("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT><>$", 
-                                              "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$", 
-                                              "==", "\\1", "\\1\\2", true);
-
-  m_keyNameRegex = make_shared<Regex>("^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT>$", "\\1\\2");
-} 
-
-SecPolicyChronoChatInvitation::~SecPolicyChronoChatInvitation()
-{}
-
-bool 
-SecPolicyChronoChatInvitation::skipVerifyAndTrust (const Data& data)
-{ return false; }
-
-bool
-SecPolicyChronoChatInvitation::requireVerify (const Data& data)
-{ return true; }
-
-shared_ptr<ValidationRequest>
-SecPolicyChronoChatInvitation::checkVerificationPolicy(const shared_ptr<Data>& data, 
-                                                 int stepCount, 
-                                                 const OnVerified& onVerified,
-                                                 const OnVerifyFailed& onVerifyFailed)
-{
-  if(m_stepLimit == stepCount)
-    {
-      _LOG_ERROR("Reach the maximum steps of verification!");
-      onVerifyFailed(data);
-      return shared_ptr<ValidationRequest>();
-    }
-
-  try{
-    SignatureSha256WithRsa sig(data->getSignature());    
-
-    const Name & keyLocatorName = sig.getKeyLocator().getName();
-
-    if(m_invitationPolicyRule->satisfy(*data))
-      {
-        // Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
-        // map<Name, PublicKey>::iterator it = m_trustAnchors.find(keyName);
-        // if(m_trustAnchors.end() != it)
-        //   {
-        //     if(Sha256WithRsaHandler::verifySignature(*data, it->second))
-        //       onVerified(data);
-        //     else
-        //       onVerifyFailed(data);
-
-        //     return shared_ptr<ValidationRequest>();
-        //   }
-
-        shared_ptr<const Certificate> trustedCert = m_certificateCache.getCertificate(keyLocatorName);
-      
-        if(static_cast<bool>(trustedCert)){
-          if(Verifier::verifySignature(*data, sig, trustedCert->getPublicKeyInfo()))
-            onVerified(data);
-          else
-            onVerifyFailed(data);
-
-          return shared_ptr<ValidationRequest>();
-        }
-
-        OnVerified recursiveVerifiedCallback = boost::bind(&SecPolicyChronoChatInvitation::onDskCertificateVerified, 
-                                                           this, 
-                                                           _1, 
-                                                           data, 
-                                                           onVerified, 
-                                                           onVerifyFailed);
-      
-        OnVerifyFailed recursiveUnverifiedCallback = boost::bind(&SecPolicyChronoChatInvitation::onDskCertificateVerifyFailed, 
-                                                                 this, 
-                                                                 _1, 
-                                                                 data, 
-                                                                 onVerifyFailed);
-
-
-        shared_ptr<Interest> interest = make_shared<Interest>(keyLocatorName);
-      
-        shared_ptr<ValidationRequest> nextStep = make_shared<ValidationRequest>(interest, 
-                                                                                recursiveVerifiedCallback,
-                                                                                recursiveUnverifiedCallback,
-                                                                                0,
-                                                                                stepCount + 1);
-        return nextStep;
-      }
-
-    if(m_kskRegex->match(data->getName()))
-      {
-        Name keyName = m_kskRegex->expand();
-        map<Name, PublicKey>::iterator it = m_trustAnchors.find(keyName);
-        if(m_trustAnchors.end() != it)
-          {
-            IdentityCertificate identityCertificate(*data);
-            if(it->second == identityCertificate.getPublicKeyInfo())
-              {
-                onVerified(data);
-              }
-            else
-              onVerifyFailed(data);
-          }
-        else
-          onVerifyFailed(data);
-
-        return shared_ptr<ValidationRequest>();
-      }
-
-    if(m_dskRule->satisfy(*data))
-      {
-        m_keyNameRegex->match(keyLocatorName);
-        Name keyName = m_keyNameRegex->expand();
-
-        if(m_trustAnchors.end() != m_trustAnchors.find(keyName))
-          if(Verifier::verifySignature(*data, sig, m_trustAnchors[keyName]))
-            onVerified(data);
-          else
-            onVerifyFailed(data);
-        else
-          onVerifyFailed(data);
-
-        return shared_ptr<ValidationRequest>();	
-      }
-  }catch(SignatureSha256WithRsa::Error &e){
-    _LOG_DEBUG("checkVerificationPolicy " << e.what());
-    onVerifyFailed(data);
-    return shared_ptr<ValidationRequest>();
-  }catch(KeyLocator::Error &e){
-    _LOG_DEBUG("checkVerificationPolicy " << e.what());
-    onVerifyFailed(data);
-    return shared_ptr<ValidationRequest>();
-  }
-
-  onVerifyFailed(data);
-  return shared_ptr<ValidationRequest>();
-}
-
-bool 
-SecPolicyChronoChatInvitation::checkSigningPolicy(const Name& dataName, 
-                                            const Name& certificateName)
-{
-  return true;
-}
-    
-Name 
-SecPolicyChronoChatInvitation::inferSigningIdentity(const Name& dataName)
-{
-  return m_signingIdentity;
-}
-
-void
-SecPolicyChronoChatInvitation::addTrustAnchor(const EndorseCertificate& selfEndorseCertificate)
-{ m_trustAnchors.insert(pair <Name, PublicKey > (selfEndorseCertificate.getPublicKeyName(), selfEndorseCertificate.getPublicKeyInfo())); }
-
-
-// void
-// SecPolicyChronoChatInvitation::addChatDataRule(const Name& prefix, 
-//                                        const IdentityCertificate identityCertificate)
-// {
-//   Name dataPrefix = prefix;
-//   dataPrefix.append("chronos").append(m_chatroomName);
-//   Ptr<Regex> dataRegex = Regex::fromName(prefix);
-//   Name certName = identityCertificate.getName();
-//   Name signerName = certName.getPrefix(certName.size()-1);
-//   Ptr<Regex> signerRegex = Regex::fromName(signerName, true);
-  
-//   ChatPolicyRule rule(dataRegex, signerRegex);
-//   map<Name, ChatPolicyRule>::iterator it = m_chatDataRules.find(dataPrefix);
-//   if(it != m_chatDataRules.end())
-//     it->second = rule;
-//   else
-//     m_chatDataRules.insert(pair <Name, ChatPolicyRule > (dataPrefix, rule));
-// }
-
-
-void 
-SecPolicyChronoChatInvitation::onDskCertificateVerified(const shared_ptr<Data>& certData, 
-                                                  shared_ptr<Data> originalData,
-                                                  const OnVerified& onVerified, 
-                                                  const OnVerifyFailed& onVerifyFailed)
-{
-  shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>(*certData);
-
-  if(!certificate->isTooLate() && !certificate->isTooEarly())
-    {
-      Name certName = certificate->getName().getPrefix(-1);
-      map<Name, shared_ptr<IdentityCertificate> >::iterator it = m_dskCertificates.find(certName);
-      if(it == m_dskCertificates.end())
-        m_dskCertificates.insert(pair <Name, shared_ptr<IdentityCertificate> > (certName, certificate));
-
-      if(Verifier::verifySignature(*originalData, originalData->getSignature(), certificate->getPublicKeyInfo()))
-        {
-          onVerified(originalData);
-          return;
-        }
-    }
-  else
-    {
-      onVerifyFailed(originalData);
-      return;
-    }
-}
-
-void
-SecPolicyChronoChatInvitation::onDskCertificateVerifyFailed(const shared_ptr<Data>& certData, 
-                                                      shared_ptr<Data> originalData,
-                                                      const OnVerifyFailed& onVerifyFailed)
-{ onVerifyFailed(originalData); }
-
-shared_ptr<IdentityCertificate> 
-SecPolicyChronoChatInvitation::getValidatedDskCertificate(const ndn::Name& certName)
-{
-  map<Name, shared_ptr<IdentityCertificate> >::iterator it = m_dskCertificates.find(certName);
-  if(m_dskCertificates.end() != it)
-    return it->second;
-  else
-    return shared_ptr<IdentityCertificate>();
-}
diff --git a/src/sec-policy-chrono-chat-invitation.h b/src/sec-policy-chrono-chat-invitation.h
deleted file mode 100644
index 28b5903..0000000
--- a/src/sec-policy-chrono-chat-invitation.h
+++ /dev/null
@@ -1,95 +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: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef SEC_POLICY_CHRONO_CHAT_INVITATION_H
-#define SEC_POLICY_CHRONO_CHAT_INVITATION_H
-
-#include <ndn-cpp-dev/security/sec-policy.hpp>
-#include <ndn-cpp-et/policy/sec-rule-relative.hpp>
-#include <ndn-cpp-et/policy/sec-rule-specific.hpp>
-#include <ndn-cpp-et/cache/ttl-certificate-cache.hpp>
-#include <ndn-cpp-et/regex/regex.hpp>
-#include <map>
-
-#include "endorse-certificate.h"
-
-class SecPolicyChronoChatInvitation : public ndn::SecPolicy
-{
-public:
-  SecPolicyChronoChatInvitation(const std::string& chatroomName,
-                                const ndn::Name& signingIdentity,
-                                int stepLimit = 10);
-  
-  virtual
-  ~SecPolicyChronoChatInvitation();
-
-  bool 
-  skipVerifyAndTrust (const ndn::Data& data);
-
-  bool
-  requireVerify (const ndn::Data& data);
-
-  ndn::ptr_lib::shared_ptr<ndn::ValidationRequest>
-  checkVerificationPolicy(const ndn::ptr_lib::shared_ptr<ndn::Data>& data, 
-                          int stepCount, 
-                          const ndn::OnVerified& onVerified,
-                          const ndn::OnVerifyFailed& onVerifyFailed);
-
-  bool 
-  checkSigningPolicy(const ndn::Name& dataName, 
-                     const ndn::Name& certificateName);
-    
-  ndn::Name 
-  inferSigningIdentity(const ndn::Name& dataName);
-
-  void
-  addTrustAnchor(const EndorseCertificate& selfEndorseCertificate);
-  
-  // void 
-  // addChatDataRule(const ndn::Name& prefix, 
-  //                 const ndn::security::IdentityCertificate identityCertificate);
-
-  ndn::ptr_lib::shared_ptr<ndn::IdentityCertificate> 
-  getValidatedDskCertificate(const ndn::Name& certName);
-
-private:
-  void 
-  onDskCertificateVerified(const ndn::ptr_lib::shared_ptr<ndn::Data>& certData, 
-                           ndn::ptr_lib::shared_ptr<ndn::Data> originalData,
-                           const ndn::OnVerified& onVerified, 
-                           const ndn::OnVerifyFailed& onVerifyFailed);
-
-  void
-  onDskCertificateVerifyFailed(const ndn::ptr_lib::shared_ptr<ndn::Data>& certData, 
-                               ndn::ptr_lib::shared_ptr<ndn::Data> originalData,
-                               const ndn::OnVerifyFailed& onVerifyFailed);
-
-private:
-  std::string m_chatroomName;
-  ndn::Name m_signingIdentity;
-
-  int m_stepLimit;
-
-  ndn::TTLCertificateCache m_certificateCache;
-
-  ndn::ptr_lib::shared_ptr<ndn::SecRuleRelative> m_invitationPolicyRule;
-  ndn::ptr_lib::shared_ptr<ndn::SecRuleRelative> m_dskRule;
-  std::map<ndn::Name, ndn::SecRuleSpecific> m_chatDataRules;
-
-  ndn::ptr_lib::shared_ptr<ndn::Regex> m_kskRegex;
-  ndn::ptr_lib::shared_ptr<ndn::Regex> m_keyNameRegex;
-
-  std::map<ndn::Name, ndn::PublicKey> m_trustAnchors;
-
-  std::map<ndn::Name, ndn::ptr_lib::shared_ptr<ndn::IdentityCertificate> > m_dskCertificates;
-
-};
-
-#endif //CHATROOM_POLICY_MANAGER_H
diff --git a/src/sec-policy-chrono-chat-panel.cpp b/src/sec-policy-chrono-chat-panel.cpp
deleted file mode 100644
index 4ecc799..0000000
--- a/src/sec-policy-chrono-chat-panel.cpp
+++ /dev/null
@@ -1,196 +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: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "sec-policy-chrono-chat-panel.h"
-#include <ndn-cpp-dev/security/verifier.hpp>
-#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
-// #include <boost/bind.hpp>
-
-#include "logging.h"
-
-using namespace std;
-using namespace ndn;
-using namespace ndn::ptr_lib;
-
-INIT_LOGGER("SecPolicyChronoChatPanel");
-
-SecPolicyChronoChatPanel::SecPolicyChronoChatPanel(const int & stepLimit)
-  : m_stepLimit(stepLimit)
-  , m_certificateCache()
-{
-  m_localPrefixRegex = make_shared<Regex>("^<local><ndn><prefix><><>$");
-
-  m_invitationDataSigningRule = make_shared<SecRuleRelative>("^<ndn><broadcast><chronos><invitation>([^<chatroom>]*)<chatroom>", 
-                                                                "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT><>$", 
-                                                                "==", "\\1", "\\1\\2", true);
-  
-  m_dskRule = make_shared<SecRuleRelative>("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT><>$", 
-                                              "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$", 
-                                              "==", "\\1", "\\1\\2", true);
-  
-  m_endorseeRule = make_shared<SecRuleRelative>("^([^<DNS>]*)<DNS><>*<ENDORSEE><>$", 
-                                                   "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$", 
-                                                   "==", "\\1", "\\1\\2", true);
-  
-  m_kskRegex = make_shared<Regex>("^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT><>$", "\\1\\2");
-
-  m_keyNameRegex = make_shared<Regex>("^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT>$", "\\1\\2");
-
-  m_signingCertificateRegex = make_shared<Regex>("^<ndn><broadcast><chronos><invitation>([^<chatroom>]*)<chatroom>", "\\1");
-}
-
-bool 
-SecPolicyChronoChatPanel::skipVerifyAndTrust (const Data & data)
-{
-  if(m_localPrefixRegex->match(data.getName()))
-    return true;
-  
-  return false;
-}
-
-bool
-SecPolicyChronoChatPanel::requireVerify (const Data & data)
-{
-  // if(m_invitationDataRule->matchDataName(data))
-  //   return true;
-  if(m_kskRegex->match(data.getName()))
-     return true;
-  if(m_dskRule->matchDataName(data))
-    return true;
-
-  if(m_endorseeRule->matchDataName(data))
-    return true;
-
-
-  return false;
-}
-
-shared_ptr<ValidationRequest>
-SecPolicyChronoChatPanel::checkVerificationPolicy(const shared_ptr<Data>& data, 
-                                            int stepCount, 
-                                            const OnVerified& onVerified,
-                                            const OnVerifyFailed& onVerifyFailed)
-{
-  if(m_stepLimit == stepCount)
-    {
-      _LOG_ERROR("Reach the maximum steps of verification!");
-      onVerifyFailed(data);
-      return shared_ptr<ValidationRequest>();
-    }
-
-  try{
-    SignatureSha256WithRsa sig(data->getSignature());    
-    const Name & keyLocatorName = sig.getKeyLocator().getName();
-
-    if(m_kskRegex->match(data->getName()))
-      {
-        Name keyName = m_kskRegex->expand();
-        map<Name, PublicKey>::iterator it = m_trustAnchors.find(keyName);
-        if(m_trustAnchors.end() != it)
-          {
-            // _LOG_DEBUG("found key!");
-            IdentityCertificate identityCertificate(*data);
-            if(it->second == identityCertificate.getPublicKeyInfo())
-              onVerified(data);
-            else
-              onVerifyFailed(data);
-          }
-        else
-          onVerifyFailed(data);
-
-        return shared_ptr<ValidationRequest>();
-      }
-
-    if(m_dskRule->satisfy(*data))
-      {
-        m_keyNameRegex->match(keyLocatorName);
-        Name keyName = m_keyNameRegex->expand();
-
-        if(m_trustAnchors.end() != m_trustAnchors.find(keyName))
-          if(Verifier::verifySignature(*data, sig, m_trustAnchors[keyName]))
-            onVerified(data);
-          else
-            onVerifyFailed(data);
-        else
-          onVerifyFailed(data);
-
-        return shared_ptr<ValidationRequest>();	
-      }
-
-    if(m_endorseeRule->satisfy(*data))
-      {
-        m_keyNameRegex->match(keyLocatorName);
-        Name keyName = m_keyNameRegex->expand();
-        if(m_trustAnchors.end() != m_trustAnchors.find(keyName))
-          if(Verifier::verifySignature(*data, sig, m_trustAnchors[keyName]))
-            onVerified(data);
-          else
-            onVerifyFailed(data);
-        else
-          onVerifyFailed(data);
-
-        return shared_ptr<ValidationRequest>();
-      }
-  }catch(SignatureSha256WithRsa::Error &e){
-    _LOG_DEBUG("checkVerificationPolicy: " << e.what());
-    onVerifyFailed(data);
-    return shared_ptr<ValidationRequest>();
-  }catch(KeyLocator::Error &e){
-    _LOG_DEBUG("checkVerificationPolicy: " << e.what());
-    onVerifyFailed(data);
-    return shared_ptr<ValidationRequest>();
-  }
-
-  _LOG_DEBUG("Unverified!");
-
-  onVerifyFailed(data);
-  return shared_ptr<ValidationRequest>();
-}
-
-bool 
-SecPolicyChronoChatPanel::checkSigningPolicy(const Name & dataName, const Name & certificateName)
-{
-  return m_invitationDataSigningRule->satisfy(dataName, certificateName);
-}
-
-Name 
-SecPolicyChronoChatPanel::inferSigningIdentity(const Name & dataName)
-{
-  if(m_signingCertificateRegex->match(dataName))
-    return m_signingCertificateRegex->expand();
-  else
-    return Name();
-}
-
-void
-SecPolicyChronoChatPanel::addTrustAnchor(const EndorseCertificate& selfEndorseCertificate)
-{ 
-  _LOG_DEBUG("Add Anchor: " << selfEndorseCertificate.getPublicKeyName().toUri());
-  m_trustAnchors.insert(pair <Name, PublicKey > (selfEndorseCertificate.getPublicKeyName(), selfEndorseCertificate.getPublicKeyInfo())); 
-}
-
-void
-SecPolicyChronoChatPanel::removeTrustAnchor(const Name& keyName)
-{  
-  m_trustAnchors.erase(keyName); 
-}
-
-shared_ptr<PublicKey>
-SecPolicyChronoChatPanel::getTrustedKey(const Name& inviterCertName)
-{
-  Name keyLocatorName = inviterCertName.getPrefix(-1);
-  _LOG_DEBUG("inviter cert name: " << inviterCertName.toUri());
-  m_keyNameRegex->match(keyLocatorName);
-  Name keyName = m_keyNameRegex->expand();
-
-  if(m_trustAnchors.end() != m_trustAnchors.find(keyName))
-    return make_shared<PublicKey>(m_trustAnchors[keyName]);
-  return shared_ptr<PublicKey>();
-}
diff --git a/src/sec-policy-chrono-chat-panel.h b/src/sec-policy-chrono-chat-panel.h
deleted file mode 100644
index 221e943..0000000
--- a/src/sec-policy-chrono-chat-panel.h
+++ /dev/null
@@ -1,101 +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: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef SEC_POLICY_CHRONO_CHAT_PANEL_H
-#define SEC_POLICY_CHRONO_CHAT_PANEL_H
-
-#include <ndn-cpp-dev/security/sec-policy.hpp>
-#include <ndn-cpp-et/policy/sec-rule-relative.hpp>
-#include <ndn-cpp-et/cache/ttl-certificate-cache.hpp>
-#include <map>
-
-#include "endorse-certificate.h"
-
-class SecPolicyChronoChatPanel : public ndn::SecPolicy
-{
-public:
-  SecPolicyChronoChatPanel(const int & stepLimit = 10);
-
-  ~SecPolicyChronoChatPanel()
-  {}
-
-  /**
-   * @brief check if the received data packet can escape from verification
-   * @param data the received data packet
-   * @return true if the data does not need to be verified, otherwise false
-   */
-  bool 
-  skipVerifyAndTrust (const ndn::Data & data);
-
-  /**
-   * @brief check if PolicyManager has the verification rule for the received data
-   * @param data the received data packet
-   * @return true if the data must be verified, otherwise false
-   */
-  bool
-  requireVerify (const ndn::Data & data);
-
-  /**
-   * @brief check whether received data packet complies with the verification policy, and get the indication of next verification step
-   * @param data the received data packet
-   * @param stepCount the number of verification steps that have been done, used to track the verification progress
-   * @param verifiedCallback the callback function that will be called if the received data packet has been validated
-   * @param unverifiedCallback the callback function that will be called if the received data packet cannot be validated
-   * @return the indication of next verification step, NULL if there is no further step
-   */
-  ndn::ptr_lib::shared_ptr<ndn::ValidationRequest>
-  checkVerificationPolicy(const ndn::ptr_lib::shared_ptr<ndn::Data>& data, 
-                          int stepCount, 
-                          const ndn::OnVerified& onVerified,
-                          const ndn::OnVerifyFailed& onVerifyFailed);
-
-    
-  /**
-   * @brief check if the signing certificate name and data name satify the signing policy 
-   * @param dataName the name of data to be signed
-   * @param certificateName the name of signing certificate
-   * @return true if the signing certificate can be used to sign the data, otherwise false
-   */
-  bool 
-  checkSigningPolicy(const ndn::Name & dataName, const ndn::Name & certificateName);
-  
-  /**
-   * @brief Infer signing identity name according to policy, if the signing identity cannot be inferred, it should return empty name
-   * @param dataName, the name of data to be signed
-   * @return the signing identity. 
-   */
-  ndn::Name 
-  inferSigningIdentity(const ndn::Name & dataName);
-
-  
-  void
-  addTrustAnchor(const EndorseCertificate& selfEndorseCertificate);
-
-  void
-  removeTrustAnchor(const ndn::Name& keyName);
-
-  ndn::ptr_lib::shared_ptr<ndn::PublicKey>
-  getTrustedKey(const ndn::Name& inviterCertName);
-
-private:
-  int m_stepLimit;
-  ndn::TTLCertificateCache m_certificateCache;
-  ndn::ptr_lib::shared_ptr<ndn::Regex> m_localPrefixRegex;
-  ndn::ptr_lib::shared_ptr<ndn::SecRuleRelative> m_invitationDataSigningRule;
-  ndn::ptr_lib::shared_ptr<ndn::Regex> m_kskRegex;
-  ndn::ptr_lib::shared_ptr<ndn::SecRuleRelative> m_dskRule;
-  ndn::ptr_lib::shared_ptr<ndn::SecRuleRelative> m_endorseeRule;
-  ndn::ptr_lib::shared_ptr<ndn::Regex> m_keyNameRegex;
-  ndn::ptr_lib::shared_ptr<ndn::Regex> m_signingCertificateRegex;
-  std::map<ndn::Name, ndn::PublicKey> m_trustAnchors;
-  
-};
-
-#endif
diff --git a/src/setaliasdialog.cpp b/src/setaliasdialog.cpp
index 42d8b2d..553b15c 100644
--- a/src/setaliasdialog.cpp
+++ b/src/setaliasdialog.cpp
@@ -13,10 +13,9 @@
 
 
 using namespace ndn;
-using namespace ndn::ptr_lib;
 using namespace std;
 
-SetAliasDialog::SetAliasDialog(shared_ptr<ContactManager> contactManager,
+SetAliasDialog::SetAliasDialog(shared_ptr<chronos::ContactManager> contactManager,
 			       QWidget *parent) 
   : QDialog(parent)
   , ui(new Ui::SetAliasDialog)
diff --git a/src/setaliasdialog.h b/src/setaliasdialog.h
index 4de2255..2358425 100644
--- a/src/setaliasdialog.h
+++ b/src/setaliasdialog.h
@@ -26,7 +26,7 @@
   Q_OBJECT
 
 public:
-  explicit SetAliasDialog(ndn::ptr_lib::shared_ptr<ContactManager> contactManager,
+  explicit SetAliasDialog(ndn::shared_ptr<chronos::ContactManager> contactManager,
 			  QWidget *parent = 0);
   ~SetAliasDialog();
 
@@ -46,7 +46,7 @@
 
 private:
   Ui::SetAliasDialog *ui;
-  ndn::ptr_lib::shared_ptr<ContactManager> m_contactManager;
+  ndn::shared_ptr<chronos::ContactManager> m_contactManager;
   std::string m_target;
 };
 
diff --git a/src/startchatdialog.cpp b/src/startchatdialog.cpp
index 64795c0..444f9c7 100644
--- a/src/startchatdialog.cpp
+++ b/src/startchatdialog.cpp
@@ -25,25 +25,17 @@
 }
 
 StartChatDialog::~StartChatDialog()
-{
-    delete ui;
-}
+{ delete ui; }
 
 void
-StartChatDialog::setInvitee(const string& invitee, const string& chatroom)
-{ 
-  m_invitee = invitee;
-  ui->chatroomInput->setText(QString::fromStdString(chatroom));
-}
+StartChatDialog::setChatroom(const string& chatroom)
+{ ui->chatroomInput->setText(QString::fromStdString(chatroom)); }
 
-void 
+void
 StartChatDialog::onOkClicked()
 {
   QString chatroom = ui->chatroomInput->text();
-  QString invitee = QString::fromStdString(m_invitee);
-  // bool isIntroducer = ui->introCheckBox->isChecked();
-  bool isIntroducer = true;
-  emit chatroomConfirmed(chatroom, invitee, isIntroducer);
+  emit chatroomConfirmed(chatroom);
   this->close();
 }
 
@@ -51,7 +43,6 @@
 StartChatDialog::onCancelClicked()
 { this->close(); }
 
-
 #if WAF
 #include "startchatdialog.moc"
 #include "startchatdialog.cpp.moc"
diff --git a/src/startchatdialog.h b/src/startchatdialog.h
index f317ec6..056ef9a 100644
--- a/src/startchatdialog.h
+++ b/src/startchatdialog.h
@@ -27,14 +27,15 @@
 
 public:
   explicit StartChatDialog(QWidget *parent = 0);
+
   ~StartChatDialog();
 
   void
-  setInvitee(const std::string& invitee, const std::string& chatroom);
+  setChatroom(const std::string& chatroom);
 
 signals:
   void
-  chatroomConfirmed(const QString& chatroomName, const QString& invitee, bool isIntroducer);
+  chatroomConfirmed(const QString& chatroomName);
     
 private slots:
   void
@@ -45,7 +46,6 @@
 
 private:
   Ui::StartChatDialog *ui;
-  std::string m_invitee;
 };
 
 #endif // STARTCHATDIALOG_H
diff --git a/src/startchatdialog.ui b/src/startchatdialog.ui
index d22cde3..c6ec4d6 100644
--- a/src/startchatdialog.ui
+++ b/src/startchatdialog.ui
@@ -68,22 +68,6 @@
     <string>Cancel</string>
    </property>
   </widget>
-  <widget class="QCheckBox" name="introCheckBox">
-   <property name="geometry">
-    <rect>
-     <x>20</x>
-     <y>110</y>
-     <width>260</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Set invitee as introducer</string>
-   </property>
-   <property name="checkable">
-    <bool>true</bool>
-   </property>
-  </widget>
  </widget>
  <resources/>
  <connections/>
diff --git a/src/validator-invitation.cpp b/src/validator-invitation.cpp
new file mode 100644
index 0000000..d22d55b
--- /dev/null
+++ b/src/validator-invitation.cpp
@@ -0,0 +1,228 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "validator-invitation.h"
+
+#include "logging.h"
+
+using namespace std;
+using namespace ndn;
+
+INIT_LOGGER("ValidatorInvitation");
+
+namespace chronos{
+
+const shared_ptr<CertificateCache> ValidatorInvitation::DefaultCertificateCache = shared_ptr<CertificateCache>();
+
+ValidatorInvitation::ValidatorInvitation(shared_ptr<Face> face,                                        
+                                         const string& chatroomName,
+                                         const Name& signingIdentity,
+                                         shared_ptr<CertificateCache> certificateCache,
+                                         int stepLimit)
+  : Validator(face)
+  , m_stepLimit(stepLimit)
+  , m_certificateCache(certificateCache)
+  , m_chatroomName(chatroomName)
+  , m_signingIdentity(signingIdentity)
+{
+  m_invitationRule = make_shared<SecRuleRelative>("^<ndn><broadcast><chronos><invitation>([^<chatroom>]*)<chatroom>", 
+                                                  "^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT>$", 
+                                                  "==", "\\1", "\\1\\2", true);
+
+  m_dskRule = make_shared<SecRuleRelative>("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT><>$", 
+                                           "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$", 
+                                           "==", "\\1", "\\1\\2", true);
+} 
+
+void
+ValidatorInvitation::checkPolicy (const shared_ptr<const Data>& data, 
+                                  int stepCount, 
+                                  const OnDataValidated& onValidated, 
+                                  const OnDataValidationFailed& onValidationFailed,
+                                  vector<shared_ptr<ValidationRequest> >& nextSteps)
+{
+  if(m_stepLimit == stepCount)
+    {
+      _LOG_DEBUG("reach the maximum steps of verification");
+      onValidationFailed(data);
+      return;
+    }
+
+   try{
+    SignatureSha256WithRsa sig(data->getSignature());    
+    const Name & keyLocatorName = sig.getKeyLocator().getName();
+    const uint8_t* buf = data->wireEncode().wire();
+    const size_t size = data->wireEncode().size();
+
+    if(m_invitationRule->satisfy(data->getName(), keyLocatorName))
+      processSignature(buf, size,
+                       sig, keyLocatorName, 
+                       bind(onValidated, data),
+                       bind(onValidationFailed, data),
+                       stepCount,
+                       nextSteps);
+
+    if(m_dskRule->satisfy(data->getName(), keyLocatorName))
+      processFinalSignature(buf, size,
+                            sig, keyLocatorName,
+                            bind(onValidated, data),
+                            bind(onValidationFailed, data));
+
+  }catch(...){
+    onValidationFailed(data);
+    return;
+  }
+}
+
+void
+ValidatorInvitation::checkPolicy (const shared_ptr<const Interest>& interest, 
+                                  int stepCount, 
+                                  const OnInterestValidated& onValidated, 
+                                  const OnInterestValidationFailed& onValidationFailed,
+                                  vector<shared_ptr<ValidationRequest> >& nextSteps)
+{
+  try{    
+    Name interestName  = interest->getName();
+
+    Block signatureBlock = interestName.get(-1).blockFromValue();
+    Block signatureInfo = interestName.get(-2).blockFromValue();
+    Signature signature(signatureInfo, signatureBlock);
+    
+    SignatureSha256WithRsa sig(signature);
+    const Name & keyLocatorName = sig.getKeyLocator().getName();
+
+    Name signedName = interestName.getPrefix(-1);
+    Buffer signedBlob = Buffer(signedName.wireEncode().value(), signedName.wireEncode().value_size());
+
+    processSignature(signedBlob.buf(), signedBlob.size(),
+                     sig, keyLocatorName, 
+                     bind(onValidated, interest),
+                     bind(onValidationFailed, interest),
+                     stepCount,
+                     nextSteps);
+
+  }catch(...){
+    onValidationFailed(interest);
+    return;
+  }
+
+}
+
+void
+ValidatorInvitation::processSignature (const uint8_t* buf, 
+                                       const size_t size,
+                                       const SignatureSha256WithRsa& signature,
+                                       const Name& keyLocatorName,
+                                       const OnValidated& onValidated, 
+                                       const OnValidationFailed& onValidationFailed,
+                                       int stepCount,
+                                       vector<shared_ptr<ValidationRequest> >& nextSteps)
+{
+  try{
+    Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
+    
+    if(m_trustAnchors.find(keyName) != m_trustAnchors.end())
+      {
+        if(Validator::verifySignature(buf, size, signature, m_trustAnchors[keyName]))
+          onValidated();
+        else
+          onValidationFailed();
+        return;
+      }
+
+    if(static_cast<bool>(m_certificateCache))
+      {
+        shared_ptr<const IdentityCertificate> trustedCert = m_certificateCache->getCertificate(keyLocatorName);
+        if(static_cast<bool>(trustedCert)){
+          if(Validator::verifySignature(buf, size, signature, trustedCert->getPublicKeyInfo()))
+            onValidated();
+          else
+            onValidationFailed();
+          return;
+        }
+      }
+    
+    OnDataValidated onKeyLocatorValidated = 
+      bind(&ValidatorInvitation::onDskKeyLocatorValidated, 
+           this, _1, buf, size, signature, onValidated, onValidationFailed);
+    
+    OnDataValidationFailed onKeyLocatorValidationFailed = 
+      bind(&ValidatorInvitation::onDskKeyLocatorValidationFailed, 
+           this, _1, onValidationFailed);
+    
+    Interest interest(keyLocatorName);
+    interest.setMustBeFresh(true);
+    
+    shared_ptr<ValidationRequest> nextStep = make_shared<ValidationRequest>
+      (interest, onKeyLocatorValidated, onKeyLocatorValidationFailed, 0, stepCount + 1);
+
+    nextSteps.push_back(nextStep);
+    return;
+  }catch(...){
+    onValidationFailed();
+    return;
+  }
+}
+ 
+void
+ValidatorInvitation::processFinalSignature (const uint8_t* buf, 
+                                            const size_t size,
+                                            const SignatureSha256WithRsa& signature,
+                                            const Name& keyLocatorName,
+                                            const OnValidated& onValidated, 
+                                            const OnValidationFailed& onValidationFailed)
+{
+  try{
+    Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
+
+    if(m_trustAnchors.end() != m_trustAnchors.find(keyName) && Validator::verifySignature(buf, size, signature, m_trustAnchors[keyName]))
+      onValidated();
+    else
+      onValidationFailed();
+    return;
+  }catch(...){
+    onValidationFailed();
+    return;
+  }
+}
+
+
+void 
+ValidatorInvitation::onDskKeyLocatorValidated(const shared_ptr<const Data>& certData, 
+                                              const uint8_t* buf,
+                                              const size_t size,
+                                              const SignatureSha256WithRsa& signature,
+                                              const OnValidated& onValidated, 
+                                              const OnValidationFailed& onValidationFailed)
+{
+  shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>(*certData);
+
+  if(!certificate->isTooLate() && !certificate->isTooEarly())
+    {
+      Name certName = certificate->getName().getPrefix(-1);
+      m_dskCertificates[certName] = certificate;
+
+      if(Validator::verifySignature(buf, size, signature, certificate->getPublicKeyInfo()))
+        {
+          onValidated();
+          return;
+        }
+    }
+
+  onValidationFailed();
+  return;
+}
+
+void
+ValidatorInvitation::onDskKeyLocatorValidationFailed(const shared_ptr<const Data>& certData, 
+                                                     const OnValidationFailed& onValidationFailed)
+{ onValidationFailed(); }
+
+}//chronos
diff --git a/src/validator-invitation.h b/src/validator-invitation.h
new file mode 100644
index 0000000..ede1799
--- /dev/null
+++ b/src/validator-invitation.h
@@ -0,0 +1,132 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef CHRONOS_VALIDATOR_INVITATION_H
+#define CHRONOS_VALIDATOR_INVITATION_H
+
+#include <ndn-cpp-dev/security/validator.hpp>
+#include <ndn-cpp-dev/security/certificate-cache.hpp>
+#include <ndn-cpp-dev/security/sec-rule-relative.hpp>
+#include <map>
+
+#include "endorse-certificate.h"
+
+namespace chronos{
+
+class ValidatorInvitation : public ndn::Validator
+{
+  typedef ndn::function< void () > OnValidationFailed;
+  typedef ndn::function< void () > OnValidated;
+
+public:
+  struct Error : public Validator::Error { Error(const std::string &what) : Validator::Error(what) {} };
+
+  static const ndn::shared_ptr<ndn::CertificateCache> DefaultCertificateCache;
+
+  ValidatorInvitation(ndn::shared_ptr<ndn::Face> face,                      
+                      const std::string& chatroomName,
+                      const ndn::Name& signingIdentity,
+                      ndn::shared_ptr<ndn::CertificateCache> certificateCache = DefaultCertificateCache,
+                      int stepLimit = 10);
+  
+  virtual
+  ~ValidatorInvitation() {};
+
+  void
+  addTrustAnchor(const EndorseCertificate& cert)
+  { m_trustAnchors[cert.getPublicKeyName()] = cert.getPublicKeyInfo(); }
+
+  void
+  removeTrustAnchor(const ndn::Name& keyName)
+  { m_trustAnchors.erase(keyName); }
+
+  ndn::shared_ptr<ndn::IdentityCertificate> 
+  getValidatedDskCertificate(const ndn::Name& certName)
+  {
+    ValidatedCertifcates::iterator it = m_dskCertificates.find(certName);
+    if(m_dskCertificates.end() != it)
+      return it->second;
+    else
+      return ndn::shared_ptr<ndn::IdentityCertificate>();
+  }
+
+
+protected:
+  void
+  checkPolicy (const ndn::shared_ptr<const ndn::Data>& data, 
+               int stepCount, 
+               const ndn::OnDataValidated& onValidated, 
+               const ndn::OnDataValidationFailed& onValidationFailed,
+               std::vector<ndn::shared_ptr<ndn::ValidationRequest> >& nextSteps);
+
+  void
+  checkPolicy (const ndn::shared_ptr<const ndn::Interest>& interest, 
+               int stepCount, 
+               const ndn::OnInterestValidated& onValidated, 
+               const ndn::OnInterestValidationFailed& onValidationFailed,
+               std::vector<ndn::shared_ptr<ndn::ValidationRequest> >& nextSteps);
+
+private:
+  void 
+  onDskKeyLocatorValidated(const ndn::shared_ptr<const ndn::Data>& certData, 
+                           const uint8_t* buf,
+                           const size_t size,
+                           const ndn::SignatureSha256WithRsa& signature,
+                           const OnValidated& onValidated, 
+                           const OnValidationFailed& onValidationFailed);
+  
+  void
+  onDskKeyLocatorValidationFailed(const ndn::shared_ptr<const ndn::Data>& certData, 
+                                  const OnValidationFailed& onValidationFailed);
+
+  void
+  processSignature (const uint8_t* buf, 
+                    const size_t size,
+                    const ndn::SignatureSha256WithRsa& signature,
+                    const ndn::Name& keyLocatorName,
+                    const OnValidated& onValidated, 
+                    const OnValidationFailed& onValidationFailed,
+                    int stepCount,
+                    std::vector<ndn::shared_ptr<ndn::ValidationRequest> >& nextSteps);
+
+  void
+  processFinalSignature (const uint8_t* buf, 
+                         const size_t size,
+                         const ndn::SignatureSha256WithRsa& signature,
+                         const ndn::Name& keyLocatorName,
+                         const OnValidated& onValidated, 
+                         const OnValidationFailed& onValidationFailed);
+
+private:
+
+  typedef std::map<ndn::Name, ndn::PublicKey> TrustAnchors;
+  typedef std::map<ndn::Name, ndn::shared_ptr<ndn::IdentityCertificate> > ValidatedCertifcates;
+
+  int m_stepLimit;
+  ndn::shared_ptr<ndn::CertificateCache> m_certificateCache;
+
+  std::string m_chatroomName;
+  ndn::Name m_signingIdentity;
+
+  ndn::shared_ptr<ndn::SecRuleRelative> m_invitationRule;
+  ndn::shared_ptr<ndn::SecRuleRelative> m_dskRule;
+
+  ndn::shared_ptr<ndn::Regex> m_kskRegex;
+  ndn::shared_ptr<ndn::Regex> m_keyNameRegex;
+
+  TrustAnchors m_trustAnchors;
+
+  ValidatedCertifcates m_dskCertificates;
+
+};
+
+}//chronos
+
+#endif //CHRONOS_VALIDATOR_INVITATION_H
diff --git a/src/validator-panel.cpp b/src/validator-panel.cpp
new file mode 100644
index 0000000..5622bc6
--- /dev/null
+++ b/src/validator-panel.cpp
@@ -0,0 +1,75 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "validator-panel.h"
+
+#include "logging.h"
+
+using namespace std;
+using namespace ndn;
+using namespace ndn::ptr_lib;
+
+INIT_LOGGER("ValidatorPanel");
+
+namespace chronos{
+
+const shared_ptr<CertificateCache> ValidatorPanel::DEFAULT_CERT_CACHE = shared_ptr<CertificateCache>();
+
+ValidatorPanel::ValidatorPanel(int stepLimit /* = 10 */,
+                               const shared_ptr<CertificateCache> certificateCache/* = DEFAULT_CERT_CACHE */)
+  : m_stepLimit(stepLimit)
+  , m_certificateCache(certificateCache)
+{  
+  m_endorseeRule = make_shared<SecRuleRelative>("^([^<DNS>]*)<DNS><>*<ENDORSEE><>$", 
+                                                "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$", 
+                                                "==", "\\1", "\\1\\2", true);
+}
+
+
+
+void
+ValidatorPanel::checkPolicy (const Data& data, 
+                             int stepCount, 
+                             const OnDataValidated& onValidated, 
+                             const OnDataValidationFailed& onValidationFailed,
+                             vector<shared_ptr<ValidationRequest> >& nextSteps)
+{
+  if(m_stepLimit == stepCount)
+    {
+      _LOG_ERROR("Reach the maximum steps of verification!");
+      onValidationFailed(data.shared_from_this());
+      return;
+    }
+
+  try{
+    SignatureSha256WithRsa sig(data.getSignature());    
+    const Name& keyLocatorName = sig.getKeyLocator().getName();
+
+    if(m_endorseeRule->satisfy(data.getName(), keyLocatorName))
+      {
+        Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
+
+        if(m_trustAnchors.end() != m_trustAnchors.find(keyName) && Validator::verifySignature(data, sig, m_trustAnchors[keyName]))
+          onValidated(data.shared_from_this());
+        else
+          onValidationFailed(data.shared_from_this());
+      }
+    else
+      onValidationFailed(data.shared_from_this());
+
+    return;
+
+  }catch(...){
+    onValidationFailed(data.shared_from_this());
+    return;
+  }  
+}
+
+}//chronos
diff --git a/src/validator-panel.h b/src/validator-panel.h
new file mode 100644
index 0000000..2bcc226
--- /dev/null
+++ b/src/validator-panel.h
@@ -0,0 +1,75 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef CHRONOS_VALIDATOR_PANEL_H
+#define CHRONOS_VALIDATOR_PANEL_H
+
+#include <ndn-cpp-dev/security/validator.hpp>
+#include <ndn-cpp-dev/security/sec-rule-relative.hpp>
+#include <ndn-cpp-dev/security/certificate-cache.hpp>
+#include <map>
+
+#include "endorse-certificate.h"
+
+namespace chronos{
+
+class ValidatorPanel : public ndn::Validator
+{
+public:
+  
+  static const ndn::shared_ptr<ndn::CertificateCache> DEFAULT_CERT_CACHE;
+
+  ValidatorPanel(int stepLimit = 10,
+                 const ndn::shared_ptr<ndn::CertificateCache> certificateCache = DEFAULT_CERT_CACHE);
+
+  ~ValidatorPanel()
+  {}
+  
+  inline void
+  addTrustAnchor(const EndorseCertificate& selfEndorseCertificate);
+
+  inline void
+  removeTrustAnchor(const ndn::Name& keyName);
+
+protected:
+  virtual void
+  checkPolicy (const ndn::Data& data, 
+               int stepCount, 
+               const ndn::OnDataValidated& onValidated, 
+               const ndn::OnDataValidationFailed& onValidationFailed,
+               std::vector<ndn::shared_ptr<ndn::ValidationRequest> >& nextSteps);
+
+  virtual void
+  checkPolicy (const ndn::Interest& interest, 
+               int stepCount, 
+               const ndn::OnInterestValidated& onValidated, 
+               const ndn::OnInterestValidationFailed& onValidationFailed,
+               std::vector<ndn::shared_ptr<ndn::ValidationRequest> >& nextSteps)
+  { onValidationFailed(interest.shared_from_this()); }
+
+private:
+  int m_stepLimit;
+  ndn::shared_ptr<ndn::CertificateCache> m_certificateCache;
+  ndn::shared_ptr<ndn::SecRuleRelative> m_endorseeRule;
+  std::map<ndn::Name, ndn::PublicKey> m_trustAnchors;
+  
+};
+
+void
+ValidatorPanel::addTrustAnchor(const EndorseCertificate& cert)
+{ m_trustAnchors[cert.getPublicKeyName()] = cert.getPublicKeyInfo(); }
+
+void 
+ValidatorPanel::removeTrustAnchor(const ndn::Name& keyName)
+{ m_trustAnchors.erase(keyName); }
+
+}//chronos
+
+#endif
diff --git a/test/endorse-certificate-test.cc b/test/endorse-certificate-test.cc
deleted file mode 100644
index 23075e3..0000000
--- a/test/endorse-certificate-test.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (C) 2013 Regents of the University of California.
- * @author: Yingdi Yu <yingdi@cs.ucla.edu>
- * See COPYING for copyright and distribution information.
- */
-
-#if __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wreorder"
-#pragma clang diagnostic ignored "-Wtautological-compare"
-#pragma clang diagnostic ignored "-Wunused-variable"
-#pragma clang diagnostic ignored "-Wunused-function"
-#elif __GNUC__
-#pragma GCC diagnostic ignored "-Wreorder"
-#pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-function"
-#endif
-
-#include <boost/test/unit_test.hpp>
-
-#include <iostream>
-#include <iomanip>
-#include <cryptopp/base64.h>
-#include <ndn-cpp/security/key-chain.hpp>
-#include "endorse-certificate.h"
-
-using namespace ndn;
-using namespace ndn::ptr_lib;
-using namespace std;
-
-BOOST_AUTO_TEST_SUITE(EndorseCertificateTests)
-
-const string aliceCert("BIICqgOyEIUBbIk+NUYUb6QYOBmPyWrhj9WiEKgoAzXAjQ+gz6iAmeX4srvcH3dQ\
-a/Y1H4Vf/LmNrXUsqbEJn1tmGoxGoQlkMtuKZ9K9X40R2SbH8d01IOIHILodRdG3\
-KXlsXS13vBkuGB8RwhMCh3RCBc6K10LQ87TkkpLdYpIjS8n2stQn2HgiHPsIUGyE\
-yLXqJ8ght2ZLVUYzHcpW4D0asckiQGXJuFmkGnbQVNHEBuirY8R1Zak6uDopoZi1\
-xvFCH6UkUXBzh3FhXrk/GA5Y6sZTKTDqo1fwz6GRubyhPq1+nHOM7ud5k4DoC6zI\
-Xstlhi5LSrCInSBItBaSNd2RPO3dbp0QAADy+p1uZG4A+sV1Y2xhLmVkdQD6nUtF\
-WQD6rWFsaWNlAPr1a3NrLTEzODI5MzQyMDEA+r1JRC1DRVJUAPrN/f/////ea6GX\
-AAABogPiAoX4UXq6YdztiNp79l71bcPBOBnRKOJBPKxDZTeC3YrfSgACurUFJt5r\
-oZgAAeIB6vL6nW5kbgD6xXVjbGEuZWR1APqdS0VZAPr1ZHNrLTEzODI5MzQyMDAA\
-+r1JRC1DRVJUAAAAAAABmhfdMIIBdzAiGA8yMDEzMTAyODAwMDAwMFoYDzIwMzMx\
-MDI4MDAwMDAwWjArMCkGA1UEKRMiL25kbi91Y2xhLmVkdS9hbGljZS9rc2stMTM4\
-MjkzNDIwMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ9b5S6MJIDz\
-EyYDYL6/1PeeM1ZIr9lyDJojyLBa/nxvCkTykdeUEIEsQb0+B5UDcyS9iGZRlBUf\
-CXOjRlnbo5BtD0IWw2aR048RT3pDh2U+dsOsJQMdPwTAaegwv+BEBvWVX+A93xya\
-qoYQcJF56q6ktvxfFj5c4G6vuuuf8ZSGbIeesXy1P5wYdSu1ceTL8mnawR0+Nj2D\
-VG71gn1A9NiIBKKQcT0rUgxo3NOaPHBUdQP67qLdfBOj0HrktGndVDxD5pWbnxKU\
-V3zd/aD1DJuP826RJ8b/7eftdIF7/8gVRN5fz3wbjFtNzAE5RLmXP+ik8MhnHMx+\
-B2QkdwR+8gcCAwEAAQAA");
-
-KeyChain keyChain;
-
-BOOST_AUTO_TEST_CASE(ProfileDataEncodeDecode)
-{
-  string decoded;
-  CryptoPP::StringSource ss(reinterpret_cast<const unsigned char *>(aliceCert.c_str()), 
-                            aliceCert.size(), 
-                            true,
-                            new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded)));
-  Data data;
-  data.wireDecode(Block(decoded.c_str(), decoded.size()));
-  IdentityCertificate identityCertificate(data);
-  
-  Profile profile(identityCertificate);
-  ProfileData profileData(profile);
-
-  Name certificateName = keyChain.getDefaultCertificateName();
-  keyChain.sign(profileData, certificateName);
-
-  const Block& profileDataBlock = profileData.wireEncode();
-  Data decodedProfileData;
-  
-  decodedProfileData.wireDecode(profileDataBlock);
-  ProfileData decodedProfile(decodedProfileData);
-  BOOST_CHECK_EQUAL(decodedProfile.getProfile().getProfileEntry("IDENTITY"), string("/ndn/ucla.edu/alice"));
-  BOOST_CHECK_EQUAL(decodedProfile.getProfile().getProfileEntry("name"), string("/ndn/ucla.edu/alice/ksk-1382934201"));
-}
-
-BOOST_AUTO_TEST_CASE(EndorseCertifiicateEncodeDecode)
-{
-  string decoded;
-  CryptoPP::StringSource ss(reinterpret_cast<const unsigned char *>(aliceCert.c_str()), 
-                            aliceCert.size(), 
-                            true,
-                            new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded)));
-  Data data;
-  data.wireDecode(Block(decoded.c_str(), decoded.size()));
-  IdentityCertificate identityCertificate(data);
-
-  Profile profile(identityCertificate);
-  ProfileData profileData(profile);
-  
-  Name certificateName = keyChain.getDefaultCertificateName();
-  keyChain.sign(profileData, certificateName);
-
-  EndorseCertificate endorseCertificate(identityCertificate, profileData);
-
-  keyChain.sign(endorseCertificate, certificateName);
-  
-  const Block& endorseDataBlock = endorseCertificate.wireEncode();
-
-  Data decodedEndorseData;
-
-  decodedEndorseData.wireDecode(endorseDataBlock);
-  EndorseCertificate decodedEndorse(decodedEndorseData);
-  BOOST_CHECK_EQUAL(decodedEndorse.getProfileData().getProfile().getProfileEntry("IDENTITY"), string("/ndn/ucla.edu/alice"));
-  BOOST_CHECK_EQUAL(decodedEndorse.getProfileData().getProfile().getProfileEntry("name"), string("/ndn/ucla.edu/alice/ksk-1382934201"));
-}
-
-
-
-BOOST_AUTO_TEST_SUITE_END()
-
diff --git a/test/main.cc b/test/main.cc
new file mode 100644
index 0000000..6b0a14a
--- /dev/null
+++ b/test/main.cc
@@ -0,0 +1,13 @@
+/* -*- 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: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#define BOOST_TEST_MAIN 1
+#define BOOST_TEST_DYN_LINK 1
+
+#include <boost/test/unit_test.hpp>
diff --git a/test/profile-test.cc b/test/profile-test.cc
deleted file mode 100644
index b50f024..0000000
--- a/test/profile-test.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (C) 2013 Regents of the University of California.
- * @author: Yingdi Yu <yingdi@cs.ucla.edu>
- * See COPYING for copyright and distribution information.
- */
-
-#include <profile.h>
-
-#define BOOST_TEST_MODULE ChronoChat
-#include <boost/test/unit_test.hpp>
-
-using namespace ndn;
-using namespace std;
-
-BOOST_AUTO_TEST_SUITE(ProfileTests)
-
-BOOST_AUTO_TEST_CASE(WriteRead)
-{
-  Name identity("/ndn/ucla/yingdi");
-  Profile profile(identity);
-  profile.setProfileEntry(string("name"), string("Yingdi Yu"));
-  profile.setProfileEntry(string("school"), string("UCLA"));
-
-  string encoded;
-  profile.encode(&encoded);
-
-  ptr_lib::shared_ptr<Profile> decodedProfile = Profile::decode(encoded);
-  
-  BOOST_CHECK_EQUAL(decodedProfile->getIdentityName().toUri(), string("/ndn/ucla/yingdi"));
-  BOOST_CHECK_EQUAL(decodedProfile->getProfileEntry(string("name")), string("Yingdi Yu"));
-  BOOST_CHECK_EQUAL(decodedProfile->getProfileEntry(string("school")), string("UCLA"));
-}
-
-BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/test-endorse-certificate.cc b/test/test-endorse-certificate.cc
new file mode 100644
index 0000000..14dda41
--- /dev/null
+++ b/test/test-endorse-certificate.cc
@@ -0,0 +1,93 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#if __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wtautological-compare"
+#pragma clang diagnostic ignored "-Wunused-function"
+#elif __GNUC__
+#pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
+#include <boost/test/unit_test.hpp>
+
+#include <cryptopp/base64.h>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <ndn-cpp-dev/util/time.hpp>
+#include "endorse-certificate.h"
+
+using namespace ndn;
+using namespace std;
+using namespace chronos;
+
+BOOST_AUTO_TEST_SUITE(TestEndorseCertificate)
+
+const string testCert("Av0DgANRBBdFbmRvcnNlQ2VydGlmaWNhdGVUZXN0cwQMRW5jb2RlRGVjb2RlBANL\
+RVkEEWtzay0xMzkxNzM0NzY0MzE2BAdJRC1DRVJUBAf9AUQJ9fu/EAMUAQIR/QHP\
+MIIByzAiGA8yMDE0MDEwMTAwMDAwMFoYDzIwMTUwMTAxMDAwMDAwWjB/MCwGA1UE\
+KRMlL0VuZG9yc2VDZXJ0aWZpY2F0ZVRlc3RzL0VuY29kZURlY29kZTASBgkqhkiG\
+9w0BCQETBWFAYi5jMAoGA1UECxMDbmRuMA4GA1UEARMHdWNsYSBjczATBgNVBAMT\
+DGh0dHA6Ly9hLmIuYzAKBgNVBFATA25kbjCCASIwDQYJKoZIhvcNAQEBBQADggEP\
+ADCCAQoCggEBALX3RJhGUUQp+i6nJRMWgCbCxxrpmSOGlUfLNAFQh/zizdFdpG0O\
++fjI82ilUzOsi4KnCBxpEez+tEMFzRTOFaLYj6bGQhTKhMsDb/d5mtjjKRBE69+R\
+H4IC9rUsD+pD/qh4lEZwoxz74DmsbAL4sCXyNLOTJFAokKpD5GB5/enwkMyC8425\
+seQXCZw/rlhpeIZkh19ULOvq4GXPk6fVPW/HsnReNa2J8toQepoh5nk1KAZjc/ed\
+GdegTAn4rBUH65chfoztBMli7sE9BJMkVf0OHSXTbRGqGSR/u0uOs+F69QisS+du\
+xyEZJFqJGOv7ZROo9C6cRZFpCJH+pjLen00CAwEAARJPFgEBF0oDSAQXRW5kb3Jz\
+ZUNlcnRpZmljYXRlVGVzdHMEDEVuY29kZURlY29kZQQDS0VZBBFrc2stMTM5MTcz\
+NDc2NDMxNgQHSUQtQ0VSVBP9AQBOUc/C6yrGQ9A3FYlwklNz9WrK7FhvkMmynugY\
+Ejasc6rVeMgigCIwgLau+bnIbO0rfMLSGdrvB/XSiWFzZSt1fQj/uJ29he+tIBf+\
+B5tP0MJL5hFNtSxgHgMCXkSRl9cC356GPpEcG+vMCoYMQLILukXfTwhP8qUB/hoy\
+5/1OxXMUAFnU2EoX90DJYvpVlD6nZt04okLVBUpNJSODEzFJrNbgpapzkb4djGol\
+6uRDV8iGhMfFtCmf+ZtcXyr49uBF2npqwgz01lTnXAB6jExD+EQ9rxospGkMgKVz\
+camQA/xj3G2PdPylszVO6qfv2clQxr9atW2Vt1BeI1ZtFbd/");
+
+KeyChain keyChain;
+
+BOOST_AUTO_TEST_CASE(EncodeDecode)
+{
+  string decoded;
+  CryptoPP::StringSource ss(reinterpret_cast<const uint8_t*>(testCert.c_str()), 
+                            testCert.size(), true,
+                            new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded)));
+  Data data;
+  data.wireDecode(Block(decoded.c_str(), decoded.size()));
+  IdentityCertificate identityCertificate(data);
+
+  Profile profile(identityCertificate);
+  vector<string> endorseList;
+  endorseList.push_back("email");
+  endorseList.push_back("homepage");
+
+  EndorseCertificate endorseCertificate(identityCertificate, profile, endorseList);
+
+  KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> keyChain;
+  Name signingIdentity("/EndorseCertificateTests/EncodeDecode/"+boost::lexical_cast<string>(time::now()));
+  keyChain.createIdentity(signingIdentity);
+
+  keyChain.signByIdentity(endorseCertificate, signingIdentity);
+  
+  const Block& endorseDataBlock = endorseCertificate.wireEncode();
+
+  Data decodedEndorseData;
+
+  decodedEndorseData.wireDecode(endorseDataBlock);
+  EndorseCertificate decodedEndorse(decodedEndorseData);
+  BOOST_CHECK_EQUAL(decodedEndorse.getProfile().get("IDENTITY"), "/EndorseCertificateTests/EncodeDecode");
+  BOOST_CHECK_EQUAL(decodedEndorse.getProfile().get("name"), "/EndorseCertificateTests/EncodeDecode");
+  BOOST_CHECK_EQUAL(decodedEndorse.getProfile().get("homepage"), "http://a.b.c");
+  BOOST_CHECK_EQUAL(decodedEndorse.getEndorseList().size(), 2);
+  BOOST_CHECK_EQUAL(decodedEndorse.getEndorseList().at(0), "email");
+  BOOST_CHECK_EQUAL(decodedEndorse.getEndorseList().at(1), "homepage");
+
+  keyChain.deleteIdentity(signingIdentity);
+}
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/test-profile.cc b/test/test-profile.cc
new file mode 100644
index 0000000..56b7d4b
--- /dev/null
+++ b/test/test-profile.cc
@@ -0,0 +1,73 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#include <boost/test/unit_test.hpp>
+
+#include "profile-data.h"
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <ndn-cpp-dev/util/time.hpp>
+
+using namespace ndn;
+using namespace std;
+using namespace chronos;
+
+BOOST_AUTO_TEST_SUITE(TestProfile)
+
+BOOST_AUTO_TEST_CASE(EncodeDecodeProfile)
+{
+  Name identity("/ndn/ucla/yingdi");
+  Profile profile(identity);
+  profile["name"] = "Yingdi Yu";
+  profile["school"] = "UCLA";
+
+  OBufferStream os;
+  profile.encode(os);
+
+  shared_ptr<Buffer> encoded = os.buf();
+  
+  boost::iostreams::stream
+    <boost::iostreams::array_source> is (reinterpret_cast<const char*>(encoded->buf ()), encoded->size ());
+
+  Profile decodedProfile; 
+  decodedProfile.decode(is);
+  
+  BOOST_CHECK_EQUAL(decodedProfile.getIdentityName().toUri(), string("/ndn/ucla/yingdi"));
+  BOOST_CHECK_EQUAL(decodedProfile["name"], string("Yingdi Yu"));
+  BOOST_CHECK_EQUAL(decodedProfile["school"], string("UCLA"));
+}
+
+BOOST_AUTO_TEST_CASE(EncodeDecodeProfileData)
+{
+  Name identity("/ndn/ucla/yingdi");
+  Profile profile(identity);
+  profile["name"] = "Yingdi Yu";
+  profile["school"] = "UCLA";
+
+  ProfileData profileData(profile);
+  
+  KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> keyChain;
+  Name signingIdentity("/EncodeDecodeProfile/EncodeDecodeProfileData");
+  keyChain.createIdentity(signingIdentity);
+  keyChain.signByIdentity(profileData, signingIdentity);
+
+  Block encodedBlock = profileData.wireEncode();
+
+  Data decodedData;
+  decodedData.wireDecode(encodedBlock);
+  
+  ProfileData decodedProfileData(decodedData);
+  Profile decodedProfile = decodedProfileData.getProfile();
+
+  BOOST_CHECK_EQUAL(profileData.getIdentityName(), string("/ndn/ucla/yingdi"));
+  BOOST_CHECK_EQUAL(decodedProfile["name"], string("Yingdi Yu"));
+  BOOST_CHECK_EQUAL(decodedProfile["school"], string("UCLA"));
+  
+  keyChain.deleteIdentity(signingIdentity);
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/wscript b/wscript
index 9f65988..acf100c 100644
--- a/wscript
+++ b/wscript
@@ -6,8 +6,9 @@
 
 def options(opt):
     opt.add_option('--debug',action='store_true',default=False,dest='debug',help='''debugging mode''')
-    opt.add_option('--log4cxx',action='store_true',default=False,dest='log4cxx',help='''Enable log4cxx''')
-    opt.add_option('--with-test', action='store_true',default=False,dest='with_tests',help='''build unit tests''')
+    opt.add_option('--with-log4cxx',action='store_true',default=False,dest='log4cxx',help='''Enable log4cxx''')
+    opt.add_option('--with-tests', action='store_true',default=False,dest='with_tests',help='''build unit tests''')
+    opt.add_option('--without-security', action='store_false',default=True,dest='with_security',help='''Enable security''')
     
     opt.load('compiler_c compiler_cxx qt4')
 
@@ -32,6 +33,7 @@
                  '-fcolor-diagnostics',       # only clang supports
                  '-Qunused-arguments',        # only clang supports
                  '-Wno-deprecated-declarations',
+                 '-Wno-unneeded-internal-declaration',
                  ]
 
         conf.add_supported_cxxflags (cxxflags = flags)
@@ -50,20 +52,24 @@
 
     conf.check_boost(lib='system random thread filesystem unit_test_framework')
 
-    conf.write_config_header('config.h')
-
     if conf.options.with_tests:
-      conf.define('WITH_TESTS', 1)
+        conf.define('WITH_TESTS', 1)
+
+
+    if conf.options.with_security:
+        conf.define('WITH_SECURITY', 1)
+
+    conf.write_config_header('src/config.h')
 		
 def build (bld):
     qt = bld (
         target = "ChronoChat",
         features = "qt4 cxx cxxprogram",
-        #        features= "qt4 cxx cxxshlib",
+        # features= "qt4 cxx cxxshlib",
         defines = "WAF",
         source = bld.path.ant_glob(['src/*.cpp', 'src/*.ui', '*.qrc', 'logging.cc', 'src/*.proto']),
         includes = "src .",
-        use = "QTCORE QTGUI QTWIDGETS QTSQL SQLITE3 NDN_CPP BOOST LOG4CXX SYNC",
+        use = "QTCORE QTGUI QTWIDGETS QTSQL NDN_CPP BOOST LOG4CXX SYNC",
         )
 
     # Unit tests
@@ -73,8 +79,10 @@
     #       source = bld.path.ant_glob(['test/**/*.cc']),
     #       features=['cxx', 'cxxprogram'],
     #       use = 'BOOST ChronoChat',
+    #       includes = "src",
     #       install_path = None,
     #       )
+      
       # Tmp disable
     if Utils.unversioned_sys_platform () == "darwin":
         app_plist = '''<?xml version="1.0" encoding="UTF-8"?>