diff --git a/disabled/cert.cc b/disabled/cert.cc
new file mode 100644
index 0000000..b8a170e
--- /dev/null
+++ b/disabled/cert.cc
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+#include "cert.h"
+
+#include <tinyxml.h>
+#include <boost/lexical_cast.hpp>
+
+#include "logging.h"
+
+INIT_LOGGER ("ndn.Cert");
+
+using namespace std;
+
+namespace ndn {
+
+Cert::Cert()
+    : m_pkey(0)
+    , m_meta("", "",  0, 0)
+{
+}
+
+Cert::Cert(const PcoPtr &keyObject, const PcoPtr &metaObject = PcoPtr())
+    : m_pkey(0)
+    , m_meta("", "", 0, 0)
+{
+  m_name = keyObject->name();
+  m_rawKeyBytes = keyObject->content();
+  m_keyHash = *(Hash::FromBytes(m_rawKeyBytes));
+  m_pkey = ccn_d2i_pubkey(head(m_rawKeyBytes), m_rawKeyBytes.size());
+  updateMeta(metaObject);
+}
+
+Cert::~Cert()
+{
+  if (m_pkey != 0)
+  {
+    ccn_pubkey_free(m_pkey);
+    m_pkey = 0;
+  }
+}
+
+void
+Cert::updateMeta(const PcoPtr &metaObject)
+{
+  if (metaObject)
+  {
+    Bytes xml = metaObject->content();
+    // just make sure it's null terminated as it's required by TiXmlDocument::parse
+    xml.push_back('\0');
+    TiXmlDocument doc;
+    doc.Parse((const char *)(head(xml)));
+    if (!doc.Error())
+    {
+      TiXmlElement *root = doc.RootElement();
+      for (TiXmlElement *child = root->FirstChildElement(); child; child = child->NextSiblingElement())
+      {
+        string elemName = child->Value();
+        string text = child->GetText();
+        if (elemName == "Name")
+        {
+          m_meta.realworldID = text;
+          _LOG_TRACE("Name = " << text);
+        }
+        else if (elemName == "Affiliation")
+        {
+          m_meta.affiliation = text;
+          _LOG_TRACE("Affiliation = " << text);
+        }
+        else if (elemName == "Valid_to")
+        {
+          m_meta.validTo = boost::lexical_cast<time_t>(text);
+          _LOG_TRACE("Valid_to = " << text);
+        }
+        else if (elemName == "Valid_from")
+        {
+          // this is not included in the key meta yet
+          // but it should eventually be there
+        }
+        else
+        {
+          // ignore known stuff
+        }
+      }
+    }
+    else
+    {
+      _LOG_ERROR("Cannot parse meta info:" << std::string((const char *)head(xml), xml.size()));
+    }
+  }
+}
+
+Cert::VALIDITY
+Cert::validity()
+{
+  if (m_meta.validFrom == 0 && m_meta.validTo == 0)
+  {
+    return OTHER;
+  }
+
+  time_t now = time(NULL);
+  if (now < m_meta.validFrom)
+  {
+    return NOT_YET_VALID;
+  }
+
+  if (now >= m_meta.validTo)
+  {
+    return EXPIRED;
+  }
+
+  return WITHIN_VALID_TIME_SPAN;
+}
+
+} // ndn
diff --git a/disabled/cert.h b/disabled/cert.h
new file mode 100644
index 0000000..00f432d
--- /dev/null
+++ b/disabled/cert.h
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_CERT_H
+#define NDN_CERT_H
+
+#include "ndn.cxx/common.h"
+#include "ndn.cxx/name.h"
+#include "ndn.cxx/pco.h"
+#include "ndn.cxx/hash.h"
+#include <boost/shared_ptr.hpp>
+
+namespace ndn {
+
+class Cert
+{
+public:
+  enum VALIDITY
+  {
+    NOT_YET_VALID,
+    WITHIN_VALID_TIME_SPAN,
+    EXPIRED,
+    OTHER
+  };
+
+  Cert();
+  Cert(const PcoPtr &keyObject, const PcoPtr &metaObject);
+  ~Cert();
+
+  void
+  updateMeta(const PcoPtr &metaObject);
+
+  Name
+  name() { return m_name; }
+
+  Bytes
+  rawKeyBytes() { return m_rawKeyBytes; }
+
+  Hash
+  keyDigest() { return m_keyHash; }
+
+  std::string
+  realworldID() { return m_meta.realworldID; }
+
+  std::string
+  affilication() { return m_meta.affiliation; }
+
+  ccn_pkey *
+  pkey() { return m_pkey; }
+
+  VALIDITY
+  validity();
+
+private:
+  struct Meta
+  {
+    Meta(std::string id, std::string affi, time_t from, time_t to)
+      : realworldID(id)
+      , affiliation(affi)
+      , validFrom(from)
+      , validTo(to)
+    {
+    }
+    std::string realworldID;
+    std::string affiliation;
+    time_t validFrom;
+    time_t validTo;
+  };
+
+  Name m_name;
+  Hash m_keyHash; // publisherPublicKeyHash
+  Bytes m_rawKeyBytes;
+  ccn_pkey *m_pkey;
+  Meta m_meta;
+};
+
+typedef boost::shared_ptr<Cert> CertPtr;
+
+}
+
+#endif // NDN_CERT_H
diff --git a/disabled/charbuf.cc b/disabled/charbuf.cc
new file mode 100644
index 0000000..12425f6
--- /dev/null
+++ b/disabled/charbuf.cc
@@ -0,0 +1,79 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *                     Zhenkai Zhu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "charbuf.h"
+
+using namespace std;
+
+namespace ndn {
+
+void
+Charbuf::init(ccn_charbuf *buf)
+{
+  if (buf != NULL)
+  {
+    m_buf = ccn_charbuf_create();
+    ccn_charbuf_reserve(m_buf, buf->length);
+    memcpy(m_buf->buf, buf->buf, buf->length);
+    m_buf->length = buf->length;
+  }
+}
+
+Charbuf::Charbuf()
+            : m_buf(NULL)
+{
+  m_buf = ccn_charbuf_create();
+}
+
+Charbuf::Charbuf(ccn_charbuf *buf)
+            : m_buf(NULL)
+{
+  init(buf);
+}
+
+Charbuf::Charbuf(const Charbuf &other)
+            : m_buf (NULL)
+{
+  init(other.m_buf);
+}
+
+Charbuf::Charbuf(const void *buf, size_t length)
+{
+  m_buf = ccn_charbuf_create ();
+  ccn_charbuf_reserve (m_buf, length);
+  memcpy (m_buf->buf, buf, length);
+  m_buf->length = length;
+}
+
+Charbuf::~Charbuf()
+{
+  ccn_charbuf_destroy (&m_buf);
+}
+
+namespace iostreams
+{
+
+charbuf_append_device::charbuf_append_device (Charbuf& cnt)
+  : container (cnt)
+{
+}
+
+std::streamsize
+charbuf_append_device::write (const char_type* s, std::streamsize n)
+{
+  ccn_charbuf_append (container.getBuf (), s, n);
+  return n;
+}
+
+} // iostreams
+
+} // ndn
diff --git a/disabled/charbuf.h b/disabled/charbuf.h
new file mode 100644
index 0000000..ce3ddef
--- /dev/null
+++ b/disabled/charbuf.h
@@ -0,0 +1,100 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *                     Zhenkai Zhu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_NDN_CHARBUF_H
+#define NDN_NDN_CHARBUF_H
+
+#include "ndn.cxx/common.h"
+#include <boost/shared_ptr.hpp>
+#include <boost/iostreams/detail/ios.hpp>
+#include <boost/iostreams/categories.hpp>
+#include <boost/iostreams/stream.hpp>
+
+namespace ndn {
+
+class Charbuf;
+typedef boost::shared_ptr<Charbuf> CharbufPtr;
+
+//  This class is mostly used in Wrapper; users should not be directly using this class
+// The main purpose of this class to is avoid manually create and destroy charbuf everytime
+class Charbuf
+{
+public:
+  Charbuf();
+  Charbuf(ccn_charbuf *buf);
+  Charbuf(const Charbuf &other);
+  Charbuf(const void *buf, size_t length);
+  ~Charbuf();
+
+  // expose internal data structure, use with caution!!
+  ccn_charbuf *
+  getBuf() { return m_buf; }
+
+  const ccn_charbuf *
+  getBuf() const { return m_buf; }
+
+  const unsigned char *
+  buf () const
+  { return m_buf->buf; }
+
+  size_t
+  length () const
+  { return m_buf->length; }
+
+private:
+  void init(ccn_charbuf *buf);
+
+protected:
+  ccn_charbuf *m_buf;
+};
+
+namespace iostreams
+{
+
+class charbuf_append_device {
+public:
+  typedef char  char_type;
+  typedef boost::iostreams::sink_tag       category;
+  
+  charbuf_append_device (Charbuf& cnt);
+  
+  std::streamsize
+  write(const char_type* s, std::streamsize n);
+protected:
+  Charbuf& container;
+};
+
+} // iostreams
+
+struct charbuf_stream : public boost::iostreams::stream<iostreams::charbuf_append_device>
+{
+  charbuf_stream ()
+    : m_device (m_buf)
+  {
+    open (m_device);
+  }
+
+  Charbuf &
+  buf ()
+  {
+    flush ();
+    return m_buf;
+  }
+
+private:
+  Charbuf m_buf;
+  iostreams::charbuf_append_device m_device;
+};
+
+} // ndn
+
+#endif // NDN_NDN_CHARBUF_H
diff --git a/disabled/closure.cc b/disabled/closure.cc
new file mode 100644
index 0000000..a45ef2a
--- /dev/null
+++ b/disabled/closure.cc
@@ -0,0 +1,46 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *                     Zhenkai Zhu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "closure.h"
+
+namespace ndn {
+
+Closure::Closure(const DataCallback &dataCallback, const TimeoutCallback &timeoutCallback)
+  : m_timeoutCallback (timeoutCallback)
+  , m_dataCallback (dataCallback)
+{
+}
+
+Closure::~Closure ()
+{
+}
+
+void
+Closure::runTimeoutCallback(Name interest, const Closure &closure, InterestPtr origInterest)
+{
+  if (!m_timeoutCallback.empty ())
+    {
+      m_timeoutCallback (interest, closure, origInterest);
+    }
+}
+
+
+void
+Closure::runDataCallback(Name name, PcoPtr content)
+{
+  if (!m_dataCallback.empty ())
+    {
+      m_dataCallback (name, content);
+    }
+}
+
+} // ndn
diff --git a/disabled/closure.h b/disabled/closure.h
new file mode 100644
index 0000000..dbcba79
--- /dev/null
+++ b/disabled/closure.h
@@ -0,0 +1,51 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *                     Zhenkai Zhu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_CLOSURE_H
+#define NDN_CLOSURE_H
+
+#include "ndn.cxx/common.h"
+#include "ndn.cxx/fields/name.h"
+#include "ndn.cxx/interest.h"
+
+namespace ndn {
+
+class ParsedContentObject;
+typedef boost::shared_ptr<ParsedContentObject> PcoPtr;
+
+class Closure
+{
+public:
+  typedef boost::function<void (Name, PcoPtr pco)> DataCallback;
+
+  typedef boost::function<void (Name, const Closure &, InterestPtr)> TimeoutCallback;
+
+  Closure(const DataCallback &dataCallback, const TimeoutCallback &timeoutCallback = TimeoutCallback());
+  virtual ~Closure();
+
+  virtual void
+  runDataCallback(Name name, ndn::PcoPtr pco);
+
+  virtual void
+  runTimeoutCallback(Name interest, const Closure &closure, InterestPtr originalInterest);
+
+  virtual Closure *
+  dup () const { return new Closure (*this); }
+
+public:
+  TimeoutCallback m_timeoutCallback;
+  DataCallback m_dataCallback;
+};
+
+} // ndn
+
+#endif
diff --git a/disabled/discovery.cc b/disabled/discovery.cc
new file mode 100644
index 0000000..273402a
--- /dev/null
+++ b/disabled/discovery.cc
@@ -0,0 +1,172 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "discovery.h"
+
+#include "scheduler/scheduler.h"
+#include "scheduler/simple-interval-generator.h"
+#include "scheduler/task.h"
+#include "scheduler/periodic-task.h"
+
+#include <sstream>
+#include <boost/make_shared.hpp>
+#include <boost/bind.hpp>
+
+using namespace std;
+
+namespace ndn
+{
+
+namespace discovery
+{
+
+const string
+TaggedFunction::CHAR_SET = string("abcdefghijklmnopqtrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
+
+TaggedFunction::TaggedFunction(const Callback &callback, const string &tag)
+                   : m_callback(callback)
+                   , m_tag(tag)
+{
+}
+
+string
+TaggedFunction::GetRandomTag()
+{
+  //boost::random::random_device rng;
+  boost::random::uniform_int_distribution<> dist(0, CHAR_SET.size() - 1);
+  ostringstream oss;
+  for (int i = 0; i < DEFAULT_TAG_SIZE; i++)
+  {
+    //oss << CHAR_SET[dist(rng)];
+  }
+  return oss.str();
+}
+
+void
+TaggedFunction::operator()(const Name &name)
+{
+  if (!m_callback.empty())
+  {
+    m_callback(name);
+  }
+}
+
+} // namespace discovery
+
+const double
+Discovery::INTERVAL = 15.0;
+
+Discovery *
+Discovery::instance = NULL;
+
+boost::mutex
+Discovery::mutex;
+
+Discovery::Discovery()
+              : m_scheduler(new Scheduler())
+              , m_localPrefix("/")
+{
+  m_scheduler->start();
+
+  Scheduler::scheduleOneTimeTask (m_scheduler, 0,
+                                  boost::bind(&Discovery::poll, this), "Initial-Local-Prefix-Check");
+  Scheduler::schedulePeriodicTask (m_scheduler,
+                                   boost::make_shared<SimpleIntervalGenerator>(INTERVAL),
+                                   boost::bind(&Discovery::poll, this), "Local-Prefix-Check");
+}
+
+Discovery::~Discovery()
+{
+  m_scheduler->shutdown();
+}
+
+void
+Discovery::addCallback(const discovery::TaggedFunction &callback)
+{
+  m_callbacks.push_back(callback);
+}
+
+int
+Discovery::deleteCallback(const discovery::TaggedFunction &callback)
+{
+  List::iterator it = m_callbacks.begin();
+  while (it != m_callbacks.end())
+  {
+    if ((*it) == callback)
+    {
+      it = m_callbacks.erase(it);
+    }
+    else
+    {
+      ++it;
+    }
+  }
+  return m_callbacks.size();
+}
+
+void
+Discovery::poll()
+{
+  Name localPrefix = Wrapper::getLocalPrefix();
+  if (localPrefix != m_localPrefix)
+  {
+    Lock lock(mutex);
+    for (List::iterator it = m_callbacks.begin(); it != m_callbacks.end(); ++it)
+    {
+      (*it)(localPrefix);
+    }
+    m_localPrefix = localPrefix;
+  }
+}
+
+void
+Discovery::registerCallback(const discovery::TaggedFunction &callback)
+{
+  Lock lock(mutex);
+  if (instance == NULL)
+  {
+    instance = new Discovery();
+  }
+
+  instance->addCallback(callback);
+}
+
+void
+Discovery::deregisterCallback(const discovery::TaggedFunction &callback)
+{
+  Lock lock(mutex);
+  if (instance == NULL)
+  {
+    cerr << "Discovery::deregisterCallback called without instance" << endl;
+  }
+  else
+  {
+    int size = instance->deleteCallback(callback);
+    if (size == 0)
+    {
+      delete instance;
+      instance = NULL;
+    }
+  }
+}
+
+}
+
diff --git a/disabled/discovery.h b/disabled/discovery.h
new file mode 100644
index 0000000..1dc684d
--- /dev/null
+++ b/disabled/discovery.h
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_DISCOVERY_H
+#define NDN_DISCOVERY_H
+
+#include "ndn.cxx/wrapper.h"
+#include "ndn.cxx/common.h"
+#include "ndn.cxx/name.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/random/random_device.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <list>
+
+class Scheduler;
+typedef boost::shared_ptr<Scheduler> SchedulerPtr;
+
+namespace ndn
+{
+
+class Discovery;
+typedef boost::shared_ptr<Discovery> DiscoveryPtr;
+
+namespace discovery
+{
+
+class TaggedFunction
+{
+public:
+  typedef boost::function<void (const Name &)> Callback;
+  TaggedFunction(const Callback &callback, const std::string &tag = GetRandomTag());
+  ~TaggedFunction(){};
+
+  bool
+  operator==(const TaggedFunction &other) { return m_tag == other.m_tag; }
+
+  void
+  operator()(const Name &name);
+
+private:
+  static const std::string CHAR_SET;
+  static const int DEFAULT_TAG_SIZE = 32;
+
+  static std::string
+  GetRandomTag();
+
+private:
+  Callback m_callback;
+  std::string m_tag;
+};
+
+}
+
+class Discovery
+{
+public:
+  const static double INTERVAL;
+  // Add a callback to be invoked when local prefix changes
+  // you must remember to deregister the callback
+  // otherwise you may have undefined behavior if the callback is
+  // bind to a member function of an object and the object is deleted
+  static void
+  registerCallback(const discovery::TaggedFunction &callback);
+
+  // remember to call this before you quit
+  static void
+  deregisterCallback(const discovery::TaggedFunction &callback);
+
+private:
+  Discovery();
+  ~Discovery();
+
+  void
+  poll();
+
+  void
+  addCallback(const discovery::TaggedFunction &callback);
+
+  int
+  deleteCallback(const discovery::TaggedFunction &callback);
+
+private:
+  typedef boost::mutex Mutex;
+  typedef boost::unique_lock<Mutex> Lock;
+  typedef std::list<discovery::TaggedFunction> List;
+
+  static Discovery *instance;
+  static Mutex mutex;
+  List m_callbacks;
+  SchedulerPtr m_scheduler;
+  Name m_localPrefix;
+};
+
+} // ndn
+
+#endif // NDN_DISCOVERY_H
diff --git a/disabled/pco.cc b/disabled/pco.cc
new file mode 100644
index 0000000..f039b54
--- /dev/null
+++ b/disabled/pco.cc
@@ -0,0 +1,138 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *                     Zhenkai Zhu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "pco.h"
+
+namespace ndn {
+
+void
+ParsedContentObject::init(const unsigned char *data, size_t len)
+{
+  readRaw(m_bytes, data, len);
+
+  m_comps = ccn_indexbuf_create();
+  int res = ccn_parse_ContentObject(head (m_bytes), len, &m_pco, m_comps);
+  if (res < 0)
+  {
+    boost::throw_exception(Error::MisformedContentObject());
+  }
+
+}
+
+ParsedContentObject::ParsedContentObject(const unsigned char *data, size_t len, bool verified)
+            : m_comps(NULL)
+            , m_verified(verified)
+{
+  init(data, len);
+}
+
+ParsedContentObject::ParsedContentObject(const Bytes &bytes, bool verified)
+            : m_comps(NULL)
+            , m_verified(verified)
+{
+  init(head(bytes), bytes.size());
+}
+
+ParsedContentObject::ParsedContentObject(const ParsedContentObject &other, bool verified)
+            : m_comps(NULL)
+            , m_verified(verified)
+{
+  init(head(other.m_bytes), other.m_bytes.size());
+}
+
+ParsedContentObject::~ParsedContentObject()
+{
+  ccn_indexbuf_destroy(&m_comps);
+  m_comps = NULL;
+}
+
+Bytes
+ParsedContentObject::content() const
+{
+  const unsigned char *content;
+  size_t len;
+  int res = ccn_content_get_value(head(m_bytes), m_pco.offset[CCN_PCO_E], &m_pco, &content, &len);
+  if (res < 0)
+  {
+    boost::throw_exception(Error::MisformedContentObject());
+  }
+
+  Bytes bytes;
+  readRaw(bytes, content, len);
+  return bytes;
+}
+
+BytesPtr
+ParsedContentObject::contentPtr() const
+{
+  const unsigned char *content;
+  size_t len;
+  int res = ccn_content_get_value(head(m_bytes), m_pco.offset[CCN_PCO_E], &m_pco, &content, &len);
+  if (res < 0)
+  {
+    boost::throw_exception(Error::MisformedContentObject());
+  }
+
+  return readRawPtr (content, len);
+}
+
+Name
+ParsedContentObject::name() const
+{
+  return Name(head(m_bytes), m_comps);
+}
+
+Name
+ParsedContentObject::keyName() const
+{
+  if (m_pco.offset[CCN_PCO_E_KeyName_Name] > m_pco.offset[CCN_PCO_B_KeyName_Name])
+  {
+    CharbufPtr ptr = boost::make_shared<Charbuf>();
+    ccn_charbuf_append(ptr->getBuf(), head(m_bytes) + m_pco.offset[CCN_PCO_B_KeyName_Name], m_pco.offset[CCN_PCO_E_KeyName_Name] - m_pco.offset[CCN_PCO_B_KeyName_Name]);
+
+    return Name(*ptr);
+  }
+  else
+  {
+    return Name();
+  }
+}
+
+HashPtr
+ParsedContentObject::publisherPublicKeyDigest() const
+{
+  const unsigned char *buf = NULL;
+  size_t size = 0;
+  ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, head(m_bytes), m_pco.offset[CCN_PCO_B_PublisherPublicKeyDigest], m_pco.offset[CCN_PCO_E_PublisherPublicKeyDigest], &buf, &size);
+
+  return boost::make_shared<Hash>(buf, size);
+}
+
+ParsedContentObject::Type
+ParsedContentObject::type() const
+{
+  switch (m_pco.type)
+  {
+  case CCN_CONTENT_DATA: return DATA;
+  case CCN_CONTENT_KEY: return KEY;
+  default: break;
+  }
+  return OTHER;
+}
+
+// void
+// ParsedContentObject::verifySignature(const CertPtr &cert)
+// {
+//   m_verified = (ccn_verify_signature(head(m_bytes), m_pco.offset[CCN_PCO_E], &m_pco, cert->pkey()) == 1);
+// }
+
+}
diff --git a/disabled/pco.h b/disabled/pco.h
new file mode 100644
index 0000000..6931022
--- /dev/null
+++ b/disabled/pco.h
@@ -0,0 +1,101 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *                     Zhenkai Zhu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_CONTENT_OBJECT_H
+#define NDN_CONTENT_OBJECT_H
+
+#include "ndn.cxx/wrapper.h"
+#include "ndn.cxx/common.h"
+#include "ndn.cxx/fields/name.h"
+#include "ndn.cxx/helpers/hash.h"
+
+namespace ndn {
+
+// class Cert;
+// typedef boost::shared_ptr<Cert> CertPtr;
+
+class ParsedContentObject
+{
+public:
+  enum Type
+  {
+    DATA,
+    KEY,
+    OTHER
+  };
+  ParsedContentObject(const unsigned char *data, size_t len, bool verified = false);
+  ParsedContentObject(const unsigned char *data, const ccn_parsed_ContentObject &pco, bool verified = false);
+  ParsedContentObject(const Bytes &bytes, bool verified = false);
+  ParsedContentObject(const ParsedContentObject &other, bool verified = false);
+  virtual ~ParsedContentObject();
+
+  Bytes
+  content() const;
+
+  BytesPtr
+  contentPtr() const;
+
+  Name
+  name() const;
+
+  Name
+  keyName() const;
+
+  HashPtr
+  publisherPublicKeyDigest() const;
+
+  Type
+  type() const;
+
+  inline const Bytes &
+  buf () const;
+
+  bool
+  verified() const { return m_verified; }
+
+  // void
+  // verifySignature(const CertPtr &cert);
+
+  const unsigned char *
+  msg() const { return head(m_bytes); }
+
+  const ccn_parsed_ContentObject *
+  pco() const { return &m_pco; }
+
+private:
+  void
+  init(const unsigned char *data, size_t len);
+
+protected:
+  ccn_parsed_ContentObject m_pco;
+  ccn_indexbuf *m_comps;
+  Bytes m_bytes;
+  bool m_verified;
+  bool m_integrityChecked;
+};
+
+typedef boost::shared_ptr<ParsedContentObject> PcoPtr;
+
+namespace Error {
+struct MisformedContentObject : virtual boost::exception, virtual std::exception { };
+}
+
+const Bytes &
+ParsedContentObject::buf () const
+{
+  return m_bytes;
+}
+
+
+}
+
+#endif // NDN_CONTENT_OBJECT_H
diff --git a/disabled/verifier.cc b/disabled/verifier.cc
new file mode 100644
index 0000000..99599bd
--- /dev/null
+++ b/disabled/verifier.cc
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "verifier.h"
+#include "ndn.cxx/wrapper.h"
+#include "logging.h"
+
+INIT_LOGGER ("ndn.Verifier");
+namespace ndn {
+
+static const size_t ROOT_KEY_DIGEST_LEN = 32;  // SHA-256
+static const unsigned char ROOT_KEY_DIGEST[ROOT_KEY_DIGEST_LEN] = {0xa7, 0xd9, 0x8b, 0x81, 0xde, 0x13, 0xfc,
+0x56, 0xc5, 0xa6, 0x92, 0xb4, 0x44, 0x93, 0x6e, 0x56, 0x70, 0x9d, 0x52, 0x6f, 0x70,
+0xed, 0x39, 0xef, 0xb5, 0xe2, 0x3, 0x29, 0xa5, 0x53, 0x3e, 0x68};
+
+Verifier::Verifier(Wrapper *ccnx)
+         : m_ccnx(ccnx)
+         , m_rootKeyDigest(ROOT_KEY_DIGEST, ROOT_KEY_DIGEST_LEN)
+{
+}
+
+Verifier::~Verifier()
+{
+}
+
+bool
+Verifier::verify(PcoPtr pco, double maxWait)
+{
+  _LOG_TRACE("Verifying content [" << pco->name() << "]");
+  HashPtr publisherPublicKeyDigest = pco->publisherPublicKeyDigest();
+
+  {
+    UniqueRecLock lock(m_cacheLock);
+    CertCache::iterator it = m_certCache.find(*publisherPublicKeyDigest);
+    if (it != m_certCache.end())
+    {
+      CertPtr cert = it->second;
+      if (cert->validity() == Cert::WITHIN_VALID_TIME_SPAN)
+      {
+        pco->verifySignature(cert);
+        return pco->verified();
+      }
+      else
+      {
+        // delete the invalid cert cache
+        m_certCache.erase(it);
+      }
+    }
+  }
+
+  // keyName is the name specified in key locator, i.e. without version and segment
+  Name keyName = pco->keyName();
+  int keyNameSize = keyName.size();
+
+  if (keyNameSize < 2)
+  {
+    _LOG_ERROR("Key name is empty or has too few components.");
+    return false;
+  }
+
+  // for keys, we have to make sure key name is strictly prefix of the content name
+  if (pco->type() == ParsedContentObject::KEY)
+  {
+    Name contentName = pco->name();
+    // when checking for prefix, do not include the hash in the key name (which is the last component)
+    Name keyNamePrefix = keyName.getPrefix (keyNameSize - 1);
+    if (keyNamePrefix.size() >= contentName.size() || contentName.getPrefix (keyNamePrefix.size()) != keyNamePrefix)
+    {
+      _LOG_ERROR("Key name prefix [" << keyNamePrefix << "] is not the prefix of content name [" << contentName << "]");
+      return false;
+    }
+  }
+  else
+  {
+    // for now, user can assign any data using his key
+  }
+
+  Name metaName;
+  metaName
+    .append (keyName.getPrefix (keyNameSize - 1))
+    .append ("info")
+    .append (keyName.getSubName (keyNameSize - 1));
+
+  Interest interest;
+  interest.setChildSelector (Interest::CHILD_RIGHT)
+    .setInterestLifetime(maxWait);
+
+  PcoPtr keyObject = m_ccnx->get(Interest (interest).setName (keyName), maxWait);
+  PcoPtr metaObject = m_ccnx->get(Interest (interest).setName (metaName), maxWait);
+  if (!keyObject || !metaObject )
+  {
+    _LOG_ERROR("can not fetch key or meta");
+    return false;
+  }
+
+  HashPtr publisherKeyHashInKeyObject = keyObject->publisherPublicKeyDigest();
+  HashPtr publisherKeyHashInMetaObject = metaObject->publisherPublicKeyDigest();
+
+  // make sure key and meta are signed using the same key
+  if (publisherKeyHashInKeyObject->IsZero() || ! (*publisherKeyHashInKeyObject == *publisherKeyHashInMetaObject))
+  {
+    _LOG_ERROR("Key and Meta not signed by the same publisher");
+    return false;
+  }
+
+  CertPtr cert = boost::make_shared<Cert>(keyObject, metaObject);
+  if (cert->validity() != Cert::WITHIN_VALID_TIME_SPAN)
+  {
+    _LOG_ERROR("Certificate is not valid, validity status is : " << cert->validity());
+    return false;
+  }
+
+  // check pco is actually signed by this key (i.e. we don't trust the publisherPublicKeyDigest given by ccnx c lib)
+  if (! (*pco->publisherPublicKeyDigest() == cert->keyDigest()))
+  {
+    _LOG_ERROR("key digest does not match the publisher public key digest of the content object");
+    return false;
+  }
+
+  // now we only need to make sure the key is trustworthy
+  if (cert->keyDigest() == m_rootKeyDigest)
+  {
+    // the key is the root key
+    // do nothing now
+  }
+  else
+  {
+    // can not verify key or can not verify meta
+    if (!verify(keyObject, maxWait) || !verify(metaObject, maxWait))
+    {
+      _LOG_ERROR("Can not verify key or meta");
+      return false;
+    }
+  }
+
+  // ok, keyObject verified, because metaObject is signed by the same parent key and integrity checked
+  // so metaObject is also verified
+  {
+    UniqueRecLock lock(m_cacheLock);
+    m_certCache.insert(std::make_pair(cert->keyDigest(), cert));
+  }
+
+  pco->verifySignature(cert);
+  if (pco->verified())
+  {
+    _LOG_TRACE("[" << pco->name() << "] VERIFIED.");
+  }
+  else
+  {
+    _LOG_ERROR("[" << pco->name() << "] CANNOT BE VERIFIED.");
+  }
+  return pco->verified();
+}
+
+} // ndn
diff --git a/disabled/verifier.h b/disabled/verifier.h
new file mode 100644
index 0000000..0065d87
--- /dev/null
+++ b/disabled/verifier.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_VERIFIER_H
+#define NDN_VERIFIER_H
+
+#include "ndn.cxx/common.h"
+#include "ndn.cxx/name.h"
+#include "ndn.cxx/cert.h"
+#include "ndn.cxx/pco.h"
+#include <map>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+
+namespace ndn {
+
+class Wrapper;
+
+class Verifier
+{
+public:
+  Verifier(Wrapper *ccnx);
+  ~Verifier();
+
+  bool verify(PcoPtr pco, double maxWait);
+
+private:
+
+private:
+  Wrapper *m_ccnx;
+  Hash m_rootKeyDigest;
+  typedef std::map<Hash, CertPtr> CertCache;
+  CertCache m_certCache;
+  typedef boost::recursive_mutex RecLock;
+  typedef boost::unique_lock<RecLock> UniqueRecLock;
+  RecLock m_cacheLock;
+};
+
+} // ndn
+
+#endif // NDN_VERIFIER_H
diff --git a/disabled/wrapper-tests.cc b/disabled/wrapper-tests.cc
new file mode 100644
index 0000000..c69ca54
--- /dev/null
+++ b/disabled/wrapper-tests.cc
@@ -0,0 +1,248 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *                     Zhenkai Zhu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+
+#include "ndn.cxx.h"
+#include <unistd.h>
+#include <fstream>
+
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/make_shared.hpp>
+
+#include "logging.h"
+
+using namespace ndn;
+using namespace std;
+using namespace boost;
+
+BOOST_AUTO_TEST_SUITE(WrapperTests)
+
+WrapperPtr c1;
+WrapperPtr c2;
+int g_timeout_counter = 0;
+int g_dataCallback_counter = 0;
+
+void publish1(InterestPtr interest)
+{
+  string content = interest->getName ().toUri();
+  c1->publishData(interest->getName (), (const unsigned char*)content.c_str(), content.size(), 5);
+}
+
+void publish2(InterestPtr interest)
+{
+  string content = interest->getName ().toUri();
+  c2->publishData(interest->getName (), (const unsigned char*)content.c_str(), content.size(), 5);
+}
+
+void dataCallback(const Name &name, ndn::PcoPtr pco)
+{
+  cout << " in data callback" << endl;
+  BytesPtr content = pco->contentPtr ();
+  string msg(reinterpret_cast<const char *> (head (*content)), content->size());
+  g_dataCallback_counter ++;
+  BOOST_CHECK_EQUAL(name, msg);
+}
+
+void encapCallback(const Name &name, ndn::PcoPtr pco)
+{
+  cout << " in encap data callback" << endl;
+  BOOST_CHECK(!c1->verify(pco));
+  cout << "++++++++++++++++++ Outer content couldn't be verified, which is expected." << endl;
+  PcoPtr npco = make_shared<ParsedContentObject> (*(pco->contentPtr()));
+  g_dataCallback_counter ++;
+  BOOST_CHECK(npco);
+  BOOST_CHECK(c1->verify(npco));
+}
+
+void
+timeout(const Name &name, const Closure &closure, InterestPtr origInterest)
+{
+  g_timeout_counter ++;
+}
+
+void
+setup()
+{
+  if (!c1)
+  {
+    c1 = make_shared<Wrapper> ();
+  }
+  if (!c2)
+  {
+    c2 = make_shared<Wrapper> ();
+  }
+}
+
+void
+teardown()
+{
+  if (c1)
+  {
+    c1.reset();
+  }
+  if (c2)
+  {
+    c2.reset();
+  }
+}
+
+
+BOOST_AUTO_TEST_CASE (Basic)
+{
+  INIT_LOGGERS ();
+  
+  setup();
+  Name prefix1("/c1");
+  Name prefix2("/c2");
+
+  c1->setInterestFilter(prefix1, bind(publish1, _1));
+  usleep(100000);
+  c2->setInterestFilter(prefix2, bind(publish2, _1));
+
+  Closure closure (bind(dataCallback, _1, _2), bind(timeout, _1, _2, _3));
+
+  c1->sendInterest(Name("/c2/hi"), closure);
+  usleep(100000);
+  c2->sendInterest(Name("/c1/hi"), closure);
+  sleep(1);
+  BOOST_CHECK_EQUAL(g_dataCallback_counter, 2);
+  
+  // reset
+  g_dataCallback_counter = 0;
+  g_timeout_counter = 0;
+
+  teardown();
+}
+
+BOOST_AUTO_TEST_CASE (Selector)
+{
+  setup();
+  Closure closure (bind(dataCallback, _1, _2), bind(timeout, _1, _2, _3));
+
+  Interest interest;
+  interest
+    .setInterestLifetime(1)
+    .setChildSelector (Interest::CHILD_RIGHT);
+
+  string n1 = "/random/01";
+  c1->sendInterest (Interest (interest).setName (Name(n1)), closure);
+  sleep(2);
+  c2->publishData(Name(n1), (const unsigned char *)n1.c_str(), n1.size(), 1);
+  usleep(100000);
+  BOOST_CHECK_EQUAL(g_timeout_counter, 1);
+  BOOST_CHECK_EQUAL(g_dataCallback_counter, 0);
+
+  string n2 = "/random/02";
+  interest.setInterestLifetime(2);
+  c1->sendInterest(Interest (interest).setName (Name(n2)), closure);
+  sleep(1);
+  c2->publishData(Name(n2), (const unsigned char *)n2.c_str(), n2.size(), 1);
+  usleep(100000);
+  BOOST_CHECK_EQUAL(g_timeout_counter, 1);
+  BOOST_CHECK_EQUAL(g_dataCallback_counter, 1);
+
+  // reset
+  g_dataCallback_counter = 0;
+  g_timeout_counter = 0;
+
+  teardown();
+
+}
+
+void
+reexpress(const Name &name, const Closure &closure, InterestPtr origInterest)
+{
+  g_timeout_counter ++;
+  c1->sendInterest (*origInterest, closure);
+}
+
+BOOST_AUTO_TEST_CASE (Timeout)
+{
+  setup();
+  g_dataCallback_counter = 0;
+  g_timeout_counter = 0;
+  Closure closure (bind(dataCallback, _1, _2), bind(reexpress, _1, _2, _3));
+
+  string n1 = "/random/04";
+
+  Interest interest;
+  interest
+    .setInterestLifetime(1)
+    .setName (n1);
+
+  c1->sendInterest(interest, closure);
+  usleep(3500000);
+  c2->publishData(Name(n1), (const unsigned char *)n1.c_str(), n1.size(), 1);
+  usleep(100000);
+  BOOST_CHECK_EQUAL(g_dataCallback_counter, 1);
+  BOOST_CHECK_EQUAL(g_timeout_counter, 3);
+  teardown();
+}
+
+BOOST_AUTO_TEST_CASE (Unsigned)
+{
+  setup();
+  string n1 = "/xxxxxx/unsigned/001";
+  Closure closure (bind(dataCallback, _1, _2), bind(timeout, _1, _2, _3));
+
+  g_dataCallback_counter = 0;
+  c1->sendInterest(Name(n1), closure);
+  usleep(100000);
+  c2->publishUnsignedData(Name(n1), (const unsigned char *)n1.c_str(), n1.size(), 1);
+  usleep(100000);
+  BOOST_CHECK_EQUAL(g_dataCallback_counter, 1);
+
+  string n2 = "/xxxxxx/signed/001";
+  Bytes content = c1->createContentObject(Name(n1), (const unsigned char *)n2.c_str(), n2.size(), 1);
+
+  c1->publishUnsignedData(Name(n2), head(content), content.size(), 1);
+  Closure encapClosure(bind(encapCallback, _1, _2), bind(timeout, _1, _2, _3));
+  c2->sendInterest(Name(n2), encapClosure);
+  usleep(4000000);
+  BOOST_CHECK_EQUAL(g_dataCallback_counter, 2);
+  teardown();
+}
+
+
+ /*
+ BOOST_AUTO_TEST_CASE (ndnWrapperUnsigningTest)
+ {
+   setup();
+   Bytes data;
+   data.resize(1024);
+   for (int i = 0; i < 1024; i++)
+   {
+     data[i] = 'm';
+   }
+
+   Name name("/unsigningtest");
+
+   posix_time::ptime start = posix_time::second_clock::local_time();
+   for (uint64_t i = 0; i < 100000; i++)
+   {
+     Name n = name;
+     n.appendComp(i);
+     c1->publishUnsignedData(n, data, 10);
+   }
+   posix_time::ptime end = posix_time::second_clock::local_time();
+
+   posix_time::time_duration duration = end - start;
+
+   cout << "Publishing 100000 1K size content objects costs " <<duration.total_milliseconds() << " milliseconds" << endl;
+   cout << "Average time to publish one content object is " << (double) duration.total_milliseconds() / 100000.0 << " milliseconds" << endl;
+    teardown();
+ }
+ */
+
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/disabled/wrapper.cc b/disabled/wrapper.cc
new file mode 100644
index 0000000..4ef079e
--- /dev/null
+++ b/disabled/wrapper.cc
@@ -0,0 +1,791 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *                     Zhenkai Zhu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "wrapper.h"
+
+extern "C" {
+#include <ccn/fetch.h>
+}
+#include <poll.h>
+#include <boost/throw_exception.hpp>
+#include <boost/random.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/algorithm/string.hpp>
+
+#include <sstream>
+
+// #include "ndn.cxx/verifier.h"
+#include "executor/executor.h"
+
+#include "logging.h"
+#include "ndn.cxx/wire/ccnb.h"
+
+
+INIT_LOGGER ("ndn.Wrapper");
+
+typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info_str;
+typedef boost::error_info<struct tag_errmsg, int> errmsg_info_int;
+
+using namespace std;
+using namespace boost;
+
+namespace ndn {
+
+// hack to enable fake signatures
+// min length for signature field is 16, as defined in ccn_buf_decoder.c:728
+const int DEFAULT_SIGNATURE_SIZE = 16;
+
+// Although ccn_buf_decoder.c:745 defines minimum length 16, something else is checking and only 32-byte fake value is accepted by ccnd
+const int PUBLISHER_KEY_SIZE = 32;
+
+static int
+ccn_encode_garbage_Signature(struct ccn_charbuf *buf)
+{
+    int res = 0;
+
+    res |= ccn_charbuf_append_tt(buf, CCN_DTAG_Signature, CCN_DTAG);
+
+    // Let's cheat more.  Default signing algorithm in ccnd is SHA256, so we just need add 32 bytes of garbage
+    static char garbage [DEFAULT_SIGNATURE_SIZE];
+
+    // digest and witness fields are optional, so use default ones
+
+    res |= ccn_charbuf_append_tt(buf, CCN_DTAG_SignatureBits, CCN_DTAG);
+    res |= ccn_charbuf_append_tt(buf, DEFAULT_SIGNATURE_SIZE, CCN_BLOB);
+    res |= ccn_charbuf_append(buf, garbage, DEFAULT_SIGNATURE_SIZE);
+    res |= ccn_charbuf_append_closer(buf);
+
+    res |= ccn_charbuf_append_closer(buf);
+
+    return(res == 0 ? 0 : -1);
+}
+
+static int
+ccn_pack_unsigned_ContentObject(struct ccn_charbuf *buf,
+                                const struct ccn_charbuf *Name,
+                                const struct ccn_charbuf *SignedInfo,
+                                const void *data,
+                                size_t size)
+{
+    int res = 0;
+    struct ccn_charbuf *content_header;
+    size_t closer_start;
+
+    content_header = ccn_charbuf_create();
+    res |= ccn_charbuf_append_tt(content_header, CCN_DTAG_Content, CCN_DTAG);
+    if (size != 0)
+        res |= ccn_charbuf_append_tt(content_header, size, CCN_BLOB);
+    closer_start = content_header->length;
+    res |= ccn_charbuf_append_closer(content_header);
+    if (res < 0)
+        return(-1);
+
+    res |= ccn_charbuf_append_tt(buf, CCN_DTAG_ContentObject, CCN_DTAG);
+
+    res |= ccn_encode_garbage_Signature(buf);
+
+    res |= ccn_charbuf_append_charbuf(buf, Name);
+    res |= ccn_charbuf_append_charbuf(buf, SignedInfo);
+    res |= ccnb_append_tagged_blob(buf, CCN_DTAG_Content, data, size);
+    res |= ccn_charbuf_append_closer(buf);
+
+    ccn_charbuf_destroy(&content_header);
+    return(res == 0 ? 0 : -1);
+}
+
+Wrapper::Wrapper()
+  : m_handle (0)
+  , m_running (true)
+  , m_connected (false)
+  , m_executor (new Executor(1))
+  // , m_verifier(new Verifier(this))
+{
+  start ();
+}
+
+void
+Wrapper::connectCcnd()
+{
+  if (m_handle != 0) {
+    ccn_disconnect (m_handle);
+    //ccn_destroy (&m_handle);
+  }
+  else
+    {
+      m_handle = ccn_create ();
+    }
+
+  UniqueRecLock lock(m_mutex);
+  if (ccn_connect(m_handle, NULL) < 0)
+  {
+    BOOST_THROW_EXCEPTION (Error::ndnOperation() << errmsg_info_str("connection to ccnd failed"));
+  }
+  m_connected = true;
+
+  if (!m_registeredInterests.empty())
+  {
+   for (map<Name, InterestCallback>::const_iterator it = m_registeredInterests.begin(); it != m_registeredInterests.end(); ++it)
+    {
+      clearInterestFilter(it->first, false);
+      setInterestFilter(it->first, it->second, false);
+    }
+  }
+}
+
+Wrapper::~Wrapper()
+{
+  shutdown ();
+  // if (m_verifier != 0)
+  // {
+  //   delete m_verifier;
+  //   m_verifier = 0;
+  // }
+}
+
+void
+Wrapper::start () // called automatically in constructor
+{
+  connectCcnd();
+  m_thread = thread (&Wrapper::ccnLoop, this);
+  m_executor->start();
+}
+
+void
+Wrapper::shutdown () // called in destructor, but can called manually
+{
+  m_executor->shutdown();
+
+  {
+    UniqueRecLock lock(m_mutex);
+    m_running = false;
+  }
+
+  _LOG_DEBUG ("+++++++++SHUTDOWN+++++++");
+  if (m_connected)
+    {
+      m_thread.join ();
+
+      ccn_disconnect (m_handle);
+      //ccn_destroy (&m_handle);
+      m_connected = false;
+    }
+}
+
+void
+Wrapper::ccnLoop ()
+{
+  static boost::mt19937 randomGenerator (static_cast<unsigned int> (std::time (0)));
+  static boost::variate_generator<boost::mt19937&, boost::uniform_int<> > rangeUniformRandom (randomGenerator, uniform_int<> (0,1000));
+
+  while (m_running)
+    {
+      try
+        {
+          int res = 0;
+          {
+            UniqueRecLock lock(m_mutex);
+            res = ccn_run (m_handle, 0);
+          }
+
+          if (!m_running) break;
+
+          if (res < 0) {
+            _LOG_ERROR ("ccn_run returned negative status: " << res);
+
+            BOOST_THROW_EXCEPTION (Error::ndnOperation()
+                                   << errmsg_info_str("ccn_run returned error"));
+          }
+
+
+          pollfd pfds[1];
+          {
+            UniqueRecLock lock(m_mutex);
+
+            pfds[0].fd = ccn_get_connection_fd (m_handle);
+            pfds[0].events = POLLIN;
+            if (ccn_output_is_pending (m_handle))
+              pfds[0].events |= POLLOUT;
+          }
+
+          int ret = poll (pfds, 1, 1);
+          if (ret < 0)
+            {
+              BOOST_THROW_EXCEPTION (Error::ndnOperation() << errmsg_info_str("ccnd socket failed (probably ccnd got stopped)"));
+            }
+        }
+        catch (Error::ndnOperation &e)
+        {
+          m_connected = false;
+          // probably ccnd has been stopped
+          // try reconnect with sleep
+          int interval = 1;
+          int maxInterval = 32;
+          while (m_running)
+          {
+            try
+            {
+              this_thread::sleep (boost::get_system_time () +  time::Seconds (interval) + time::Milliseconds (rangeUniformRandom ()));
+
+              connectCcnd ();
+              _LOG_DEBUG("reconnect to ccnd succeeded");
+              break;
+            }
+            catch (Error::ndnOperation &e)
+            {
+              this_thread::sleep (boost::get_system_time () +  time::Seconds (interval) + time::Milliseconds (rangeUniformRandom ()));
+
+              // do exponential backup for reconnect interval
+              if (interval < maxInterval)
+              {
+                interval *= 2;
+              }
+            }
+          }
+        }
+        catch (const std::exception &exc)
+          {
+            // catch anything thrown within try block that derives from std::exception
+            std::cerr << exc.what();
+          }
+        catch (...)
+          {
+            cout << "UNKNOWN EXCEPTION !!!" << endl;
+          }
+     }
+}
+
+Bytes
+Wrapper::createContentObject(const Name  &name, const void *buf, size_t len, int freshness, const Name &keyNameParam)
+{
+  {
+    UniqueRecLock lock(m_mutex);
+    if (!m_running || !m_connected)
+      {
+        _LOG_TRACE ("<< not running or connected");
+        return Bytes ();
+      }
+  }
+
+  ccn_charbuf *content = ccn_charbuf_create();
+
+  struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
+  sp.freshness = freshness;
+
+  Name keyName;
+
+  if (keyNameParam.size() == 0)
+  {
+    // use default key name
+    CharbufPtr defaultKeyNamePtr = boost::make_shared<Charbuf>();
+    ccn_get_public_key_and_name(m_handle, &sp, NULL, NULL, defaultKeyNamePtr->getBuf());
+    keyName = Name(*defaultKeyNamePtr);
+
+    _LOG_DEBUG ("DEFAULT KEY NAME: " << keyName);
+  }
+  else
+  {
+    keyName = keyNameParam;
+  }
+
+  if (sp.template_ccnb == NULL)
+  {
+    sp.template_ccnb = ccn_charbuf_create();
+    ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG);
+  }
+  // no idea what the following 3 lines do, but it was there
+  else if (sp.template_ccnb->length > 0) {
+      sp.template_ccnb->length--;
+  }
+  ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyLocator, CCN_DTAG);
+  ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyName, CCN_DTAG);
+
+  charbuf_stream keyStream;
+  wire::Ccnb::appendName (keyStream, keyName);
+  
+  ccn_charbuf_append(sp.template_ccnb, keyStream.buf ().getBuf ()->buf, keyStream.buf ().getBuf ()->length);
+  ccn_charbuf_append_closer(sp.template_ccnb); // </KeyName>
+  ccn_charbuf_append_closer(sp.template_ccnb); // </KeyLocator>
+  sp.sp_flags |= CCN_SP_TEMPL_KEY_LOCATOR;
+  ccn_charbuf_append_closer(sp.template_ccnb); // </SignedInfo>
+
+  charbuf_stream nameStream;
+  wire::Ccnb::appendName (nameStream, name);
+  
+  if (ccn_sign_content(m_handle, content, nameStream.buf ().getBuf (), &sp, buf, len) != 0)
+  {
+    BOOST_THROW_EXCEPTION(Error::ndnOperation() << errmsg_info_str("sign content failed"));
+  }
+
+  Bytes bytes;
+  readRaw(bytes, content->buf, content->length);
+
+  ccn_charbuf_destroy (&content);
+  if (sp.template_ccnb != NULL)
+  {
+    ccn_charbuf_destroy (&sp.template_ccnb);
+  }
+
+  return bytes;
+}
+
+int
+Wrapper::putToCcnd (const Bytes &contentObject)
+{
+  _LOG_TRACE (">> putToCcnd");
+  UniqueRecLock lock(m_mutex);
+  if (!m_running || !m_connected)
+    {
+      _LOG_TRACE ("<< not running or connected");
+      return -1;
+    }
+
+
+  if (ccn_put(m_handle, head(contentObject), contentObject.size()) < 0)
+  {
+    _LOG_ERROR ("ccn_put failed");
+    // BOOST_THROW_EXCEPTION(Error::ndnOperation() << errmsg_info_str("ccnput failed"));
+  }
+  else
+    {
+      _LOG_DEBUG ("<< putToCcnd");
+    }
+
+  return 0;
+}
+
+int
+Wrapper::publishData (const Name &name, const unsigned char *buf, size_t len, int freshness, const Name &keyName)
+{
+  _LOG_TRACE ("publishData: " << name);
+  Bytes co = createContentObject(name, buf, len, freshness, keyName);
+  return putToCcnd(co);
+}
+
+int
+Wrapper::publishUnsignedData(const Name &name, const unsigned char *buf, size_t len, int freshness)
+{
+  _LOG_TRACE ("publishUnsignedData: " << name);
+  {
+    UniqueRecLock lock(m_mutex);
+    if (!m_running || !m_connected)
+      {
+        _LOG_TRACE ("<< not running or connected");
+        return -1;
+      }
+  }
+
+  ccn_charbuf *content = ccn_charbuf_create();
+  ccn_charbuf *signed_info = ccn_charbuf_create();
+
+  static char fakeKey[PUBLISHER_KEY_SIZE];
+
+  int res = ccn_signed_info_create(signed_info,
+                                   fakeKey, PUBLISHER_KEY_SIZE,
+                                   NULL,
+                                   CCN_CONTENT_DATA,
+                                   freshness,
+                                   NULL,
+                                   NULL  // ccnd is happy with absent key locator and key itself... ha ha
+                                   );
+
+  charbuf_stream nameStream;
+  wire::Ccnb::appendName (nameStream, name);
+
+  ccn_pack_unsigned_ContentObject(content, nameStream.buf ().getBuf (), signed_info, buf, len);
+
+  Bytes bytes;
+  readRaw(bytes, content->buf, content->length);
+
+  ccn_charbuf_destroy (&content);
+  ccn_charbuf_destroy (&signed_info);
+
+  return putToCcnd (bytes);
+}
+
+
+static void
+deleterInInterestTuple (tuple<Wrapper::InterestCallback *, ExecutorPtr> *tuple)
+{
+  delete tuple->get<0> ();
+  delete tuple;
+}
+
+static ccn_upcall_res
+incomingInterest(ccn_closure *selfp,
+                 ccn_upcall_kind kind,
+                 ccn_upcall_info *info)
+{
+  Wrapper::InterestCallback *f;
+  ExecutorPtr executor;
+  tuple<Wrapper::InterestCallback *, ExecutorPtr> *realData = reinterpret_cast< tuple<Wrapper::InterestCallback *, ExecutorPtr>* > (selfp->data);
+  tie (f, executor) = *realData;
+
+  switch (kind)
+    {
+    case CCN_UPCALL_FINAL: // effective in unit tests
+      // delete closure;
+      executor->execute (bind (deleterInInterestTuple, realData));
+
+      delete selfp;
+      _LOG_TRACE ("<< incomingInterest with CCN_UPCALL_FINAL");
+      return CCN_UPCALL_RESULT_OK;
+
+    case CCN_UPCALL_INTEREST:
+      _LOG_TRACE (">> incomingInterest upcall: " << Name(info->interest_ccnb, info->interest_comps));
+      break;
+
+    default:
+      _LOG_TRACE ("<< incomingInterest with CCN_UPCALL_RESULT_OK: " << Name(info->interest_ccnb, info->interest_comps));
+      return CCN_UPCALL_RESULT_OK;
+    }
+
+  InterestPtr interest = make_shared<Interest> (info->pi);
+  interest->setName (Name (info->interest_ccnb, info->interest_comps));
+
+  executor->execute (bind (*f, interest));
+  // this will be run in executor
+  // (*f) (interest);
+  // closure->runInterestCallback(interest);
+
+  return CCN_UPCALL_RESULT_OK;
+}
+
+static void
+deleterInDataTuple (tuple<Closure *, ExecutorPtr, InterestPtr> *tuple)
+{
+  delete tuple->get<0> ();
+  delete tuple;
+}
+
+static ccn_upcall_res
+incomingData(ccn_closure *selfp,
+             ccn_upcall_kind kind,
+             ccn_upcall_info *info)
+{
+  // Closure *cp = static_cast<Closure *> (selfp->data);
+  Closure *cp;
+  ExecutorPtr executor;
+  InterestPtr interest;
+  tuple<Closure *, ExecutorPtr, InterestPtr> *realData = reinterpret_cast< tuple<Closure*, ExecutorPtr, InterestPtr>* > (selfp->data);
+  tie (cp, executor, interest) = *realData;
+
+  switch (kind)
+    {
+    case CCN_UPCALL_FINAL:  // effecitve in unit tests
+      executor->execute (bind (deleterInDataTuple, realData));
+
+      cp = NULL;
+      delete selfp;
+      _LOG_TRACE ("<< incomingData with CCN_UPCALL_FINAL");
+      return CCN_UPCALL_RESULT_OK;
+
+    case CCN_UPCALL_CONTENT:
+      _LOG_TRACE (">> incomingData content upcall: " << Name (info->content_ccnb, info->content_comps));
+      break;
+
+    // this is the case where the intentionally unsigned packets coming (in Encapsulation case)
+    case CCN_UPCALL_CONTENT_BAD:
+      _LOG_TRACE (">> incomingData content bad upcall: " << Name (info->content_ccnb, info->content_comps));
+      break;
+
+    // always ask ccnd to try to fetch the key
+    case CCN_UPCALL_CONTENT_UNVERIFIED:
+      _LOG_TRACE (">> incomingData content unverified upcall: " << Name (info->content_ccnb, info->content_comps));
+      break;
+
+    case CCN_UPCALL_INTEREST_TIMED_OUT: {
+      if (cp != NULL)
+      {
+        Name interestName (info->interest_ccnb, info->interest_comps);
+        _LOG_TRACE ("<< incomingData timeout: " << Name (info->interest_ccnb, info->interest_comps));
+        executor->execute (bind (&Closure::runTimeoutCallback, cp, interestName, *cp, interest));
+      }
+      else
+        {
+          _LOG_TRACE ("<< incomingData timeout, but callback is not set...: " << Name (info->interest_ccnb, info->interest_comps));
+        }
+      return CCN_UPCALL_RESULT_OK;
+    }
+
+    default:
+      _LOG_TRACE(">> unknown upcall type");
+      return CCN_UPCALL_RESULT_OK;
+    }
+
+  PcoPtr pco = make_shared<ParsedContentObject> (info->content_ccnb, info->pco->offset[CCN_PCO_E]);
+
+  // this will be run in executor
+  executor->execute (bind (&Closure::runDataCallback, cp, pco->name (), pco));
+  _LOG_TRACE (">> incomingData");
+
+  return CCN_UPCALL_RESULT_OK;
+}
+
+int Wrapper::sendInterest (const Interest &interest, const Closure &closure)
+{
+  _LOG_TRACE (">> sendInterest: " << interest.getName ());
+  {
+    UniqueRecLock lock(m_mutex);
+    if (!m_running || !m_connected)
+      {
+        _LOG_ERROR ("<< sendInterest: not running or connected");
+        return -1;
+      }
+  }
+
+  ccn_closure *dataClosure = new ccn_closure;
+
+  // Closure *myClosure = new ExecutorClosure(closure, m_executor);
+  Closure *myClosure = closure.dup ();
+  dataClosure->data = new tuple<Closure*, ExecutorPtr, InterestPtr> (myClosure, m_executor, make_shared<Interest> (interest));
+
+  dataClosure->p = &incomingData;
+
+  UniqueRecLock lock(m_mutex);
+
+  charbuf_stream nameStream;
+  wire::Ccnb::appendName (nameStream, interest.getName ());
+
+  charbuf_stream interestStream;
+  wire::Ccnb::appendInterest (interestStream, interest);
+
+  if (ccn_express_interest (m_handle, nameStream.buf ().getBuf (),
+                            dataClosure,
+                            interestStream.buf ().getBuf ()
+                            ) < 0)
+  {
+    _LOG_ERROR ("<< sendInterest: ccn_express_interest FAILED!!!");
+  }
+
+  return 0;
+}
+
+int Wrapper::setInterestFilter (const Name &prefix, const InterestCallback &interestCallback, bool record/* = true*/)
+{
+  _LOG_TRACE (">> setInterestFilter");
+  UniqueRecLock lock(m_mutex);
+  if (!m_running || !m_connected)
+  {
+    return -1;
+  }
+
+  ccn_closure *interestClosure = new ccn_closure;
+
+  // interestClosure->data = new ExecutorInterestClosure(interestCallback, m_executor);
+
+  interestClosure->data = new tuple<Wrapper::InterestCallback *, ExecutorPtr> (new InterestCallback (interestCallback), m_executor); // should be removed when closure is removed
+  interestClosure->p = &incomingInterest;
+
+  charbuf_stream prefixStream;
+  wire::Ccnb::appendName (prefixStream, prefix);
+
+  int ret = ccn_set_interest_filter (m_handle, prefixStream.buf ().getBuf (), interestClosure);
+  if (ret < 0)
+  {
+    _LOG_ERROR ("<< setInterestFilter: ccn_set_interest_filter FAILED");
+  }
+
+  if (record)
+    {
+      m_registeredInterests.insert(pair<Name, InterestCallback>(prefix, interestCallback));
+    }
+
+  _LOG_TRACE ("<< setInterestFilter");
+
+  return ret;
+}
+
+void
+Wrapper::clearInterestFilter (const Name &prefix, bool record/* = true*/)
+{
+  _LOG_TRACE (">> clearInterestFilter");
+  UniqueRecLock lock(m_mutex);
+  if (!m_running || !m_connected)
+    return;
+
+  charbuf_stream prefixStream;
+  wire::Ccnb::appendName (prefixStream, prefix);
+
+  int ret = ccn_set_interest_filter (m_handle, prefixStream.buf ().getBuf (), 0);
+  if (ret < 0)
+  {
+  }
+
+  if (record)
+    {
+      m_registeredInterests.erase(prefix);
+    }
+
+  _LOG_TRACE ("<< clearInterestFilter");
+}
+
+Name
+Wrapper::getLocalPrefix ()
+{
+  struct ccn * tmp_handle = ccn_create ();
+  int res = ccn_connect (tmp_handle, NULL);
+  if (res < 0)
+    {
+      return Name();
+    }
+
+  string retval = "";
+
+  struct ccn_charbuf *templ = ccn_charbuf_create();
+  ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
+  ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
+  ccn_charbuf_append_closer(templ); /* </Name> */
+  // XXX - use pubid if possible
+  ccn_charbuf_append_tt(templ, CCN_DTAG_MaxSuffixComponents, CCN_DTAG);
+  ccnb_append_number(templ, 1);
+  ccn_charbuf_append_closer(templ); /* </MaxSuffixComponents> */
+  ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", 2);
+  ccn_charbuf_append_closer(templ); /* </Interest> */
+
+  struct ccn_charbuf *name = ccn_charbuf_create ();
+  res = ccn_name_from_uri (name, "/local/ndn/prefix");
+  if (res < 0) {
+  }
+  else
+    {
+      struct ccn_fetch *fetch = ccn_fetch_new (tmp_handle);
+
+      struct ccn_fetch_stream *stream = ccn_fetch_open (fetch, name, "/local/ndn/prefix",
+                                                        NULL, 4, CCN_V_HIGHEST, 0);
+      if (stream == NULL) {
+      }
+      else
+        {
+          ostringstream os;
+
+          int counter = 0;
+          char buf[256];
+          while (true) {
+            res = ccn_fetch_read (stream, buf, sizeof(buf));
+
+            if (res == 0) {
+              break;
+            }
+
+            if (res > 0) {
+              os << string(buf, res);
+            } else if (res == CCN_FETCH_READ_NONE) {
+              if (counter < 2)
+                {
+                  ccn_run(tmp_handle, 1000);
+                  counter ++;
+                }
+              else
+                {
+                  break;
+                }
+            } else if (res == CCN_FETCH_READ_END) {
+              break;
+            } else if (res == CCN_FETCH_READ_TIMEOUT) {
+              break;
+            } else {
+              break;
+            }
+          }
+          retval = os.str ();
+          stream = ccn_fetch_close(stream);
+        }
+      fetch = ccn_fetch_destroy(fetch);
+    }
+
+  ccn_charbuf_destroy (&name);
+
+  ccn_disconnect (tmp_handle);
+  ccn_destroy (&tmp_handle);
+
+  boost::algorithm::trim(retval);
+  return Name(retval);
+}
+
+bool
+Wrapper::verify(PcoPtr &pco, double maxWait)
+{
+  return true; // totally fake
+  // return m_verifier->verify(pco, maxWait);
+}
+
+/// @cond include_hidden
+// This is needed just for get function implementation
+struct GetState
+{
+  GetState (double maxWait)
+  {
+    double intPart, fraction;
+    fraction = modf (std::abs(maxWait), &intPart);
+
+    m_maxWait = time::Now ()
+      + time::Seconds (intPart)
+      + time::Microseconds (fraction * 1000000);
+  }
+
+  PcoPtr
+  WaitForResult ()
+  {
+    //_LOG_TRACE("GetState::WaitForResult start");
+    boost::unique_lock<boost::mutex> lock (m_mutex);
+    m_cond.timed_wait (lock, m_maxWait);
+    //_LOG_TRACE("GetState::WaitForResult finish");
+
+    return m_retval;
+  }
+
+  void
+  DataCallback (Name name, PcoPtr pco)
+  {
+    //_LOG_TRACE("GetState::DataCallback, Name [" << name << "]");
+    boost::unique_lock<boost::mutex> lock (m_mutex);
+    m_retval = pco;
+    m_cond.notify_one ();
+  }
+
+  void
+  TimeoutCallback (Name name)
+  {
+    boost::unique_lock<boost::mutex> lock (m_mutex);
+    m_cond.notify_one ();
+  }
+
+private:
+  Time m_maxWait;
+
+  boost::mutex m_mutex;
+  boost::condition_variable    m_cond;
+
+  PcoPtr  m_retval;
+};
+/// @endcond
+
+PcoPtr
+Wrapper::get(const Interest &interest, double maxWait/* = 4.0*/)
+{
+  _LOG_TRACE (">> get: " << interest.getName ());
+  {
+    UniqueRecLock lock(m_mutex);
+    if (!m_running || !m_connected)
+      {
+        _LOG_ERROR ("<< get: not running or connected");
+        return PcoPtr ();
+      }
+  }
+
+  GetState state (maxWait);
+  this->sendInterest (interest, Closure (boost::bind (&GetState::DataCallback, &state, _1, _2),
+                                         boost::bind (&GetState::TimeoutCallback, &state, _1)));
+  return state.WaitForResult ();
+}
+
+}
diff --git a/disabled/wrapper.h b/disabled/wrapper.h
new file mode 100644
index 0000000..517a832
--- /dev/null
+++ b/disabled/wrapper.h
@@ -0,0 +1,161 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *                     Zhenkai Zhu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_WRAPPER_H
+#define NDN_WRAPPER_H
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+
+#include "ndn.cxx/common.h"
+#include "ndn.cxx/fields/name.h"
+#include "ndn.cxx/interest.h"
+#include "ndn.cxx/closure.h"
+#include "ndn.cxx/pco.h"
+
+class Executor;
+typedef boost::shared_ptr<Executor> ExecutorPtr;
+
+namespace ndn {
+
+class Verifier;
+class Wrapper
+{
+public:
+  const static int MAX_FRESHNESS = 2147; // max value for ccnx
+  const static int DEFAULT_FRESHNESS = 60;
+  typedef boost::function<void (InterestPtr)> InterestCallback;
+
+  Wrapper();
+  ~Wrapper();
+
+  void
+  start (); // called automatically in constructor
+
+  /**
+   * @brief Because of uncertainty with executor, in some case it is necessary to call shutdown explicitly (see test-server-and-fetch.cc)
+   */
+  void
+  shutdown (); // called in destructor, but can called manually
+
+  int
+  setInterestFilter (const Name &prefix, const InterestCallback &interestCallback, bool record = true);
+
+  void
+  clearInterestFilter (const Name &prefix, bool record = true);
+
+  int
+  sendInterest (const Interest &interest, const Closure &closure);
+
+  int
+  publishData (const Name &name, const unsigned char *buf, size_t len, int freshness = DEFAULT_FRESHNESS, const Name &keyName=Name());
+
+  inline int
+  publishData (const Name &name, const Bytes &content, int freshness = DEFAULT_FRESHNESS, const Name &keyName=Name());
+
+  inline int
+  publishData (const Name &name, const std::string &content, int freshness = DEFAULT_FRESHNESS, const Name &keyName=Name());
+
+  int
+  publishUnsignedData(const Name &name, const unsigned char *buf, size_t len, int freshness = DEFAULT_FRESHNESS);
+
+  inline int
+  publishUnsignedData(const Name &name, const Bytes &content, int freshness = DEFAULT_FRESHNESS);
+
+  inline int
+  publishUnsignedData(const Name &name, const std::string &content, int freshness = DEFAULT_FRESHNESS);
+
+  static Name
+  getLocalPrefix ();
+
+  Bytes
+  createContentObject(const Name &name, const void *buf, size_t len, int freshness = DEFAULT_FRESHNESS, const Name &keyNameParam=Name());
+
+  int
+  putToCcnd (const Bytes &contentObject);
+
+  bool
+  verify(PcoPtr &pco, double maxWait = 1 /*seconds*/);
+
+  PcoPtr
+  get (const Interest &interest, double maxWait = 4.0/*seconds*/);
+
+private:
+  Wrapper(const Wrapper &other) {}
+
+protected:
+  void
+  connectCcnd();
+
+  /// @cond include_hidden
+  void
+  ccnLoop ();
+
+  /// @endcond
+
+protected:
+  typedef boost::shared_mutex Lock;
+  typedef boost::unique_lock<Lock> WriteLock;
+  typedef boost::shared_lock<Lock> ReadLock;
+
+  typedef boost::recursive_mutex RecLock;
+  typedef boost::unique_lock<RecLock> UniqueRecLock;
+
+  ccn* m_handle;
+  RecLock m_mutex;
+  boost::thread m_thread;
+  bool m_running;
+  bool m_connected;
+  std::map<Name, InterestCallback> m_registeredInterests;
+  ExecutorPtr m_executor;
+  Verifier *m_verifier;
+};
+
+typedef boost::shared_ptr<Wrapper> WrapperPtr;
+
+/**
+ * @brief Namespace holding all exceptions that can be fired by the library
+ */
+namespace Error
+{
+struct ndnOperation : boost::exception, std::exception { };
+}
+
+inline int
+Wrapper::publishData (const Name &name, const Bytes &content, int freshness, const Name &keyName)
+{
+  return publishData(name, head(content), content.size(), freshness, keyName);
+}
+
+inline int
+Wrapper::publishData (const Name &name, const std::string &content, int freshness, const Name &keyName)
+{
+  return publishData(name, reinterpret_cast<const unsigned char *> (content.c_str ()), content.size (), freshness, keyName);
+}
+
+inline int
+Wrapper::publishUnsignedData(const Name &name, const Bytes &content, int freshness)
+{
+  return publishUnsignedData(name, head(content), content.size(), freshness);
+}
+
+inline int
+Wrapper::publishUnsignedData(const Name &name, const std::string &content, int freshness)
+{
+  return publishUnsignedData(name, reinterpret_cast<const unsigned char *> (content.c_str ()), content.size (), freshness);
+}
+
+
+} // ndn
+
+#endif
