diff --git a/ndnx/ndnx-cert.cpp b/ndnx/ndnx-cert.cpp
new file mode 100644
index 0000000..8dacd60
--- /dev/null
+++ b/ndnx/ndnx-cert.cpp
@@ -0,0 +1,127 @@
+/* -*- 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 "ndnx-cert.h"
+#include <tinyxml.h>
+#include <boost/lexical_cast.hpp>
+#include "logging.h"
+
+INIT_LOGGER ("Ndnx.Cert");
+
+using namespace std;
+
+namespace Ndnx {
+
+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 = ndn_d2i_pubkey(head(m_rawKeyBytes), m_rawKeyBytes.size());
+  updateMeta(metaObject);
+}
+
+Cert::~Cert()
+{
+  if (m_pkey != 0)
+  {
+    ndn_pubkey_free(m_pkey);
+    m_pkey = 0;
+  }
+}
+
+void
+Cert::updateMeta(const PcoPtr &metaObject)
+{
+  if (metaObject)
+  {
+    TiXmlDocument doc;
+    Bytes xml = metaObject->content();
+    // just make sure it's null terminated as it's required by TiXmlDocument::parse
+    xml.push_back('\0');
+    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;
+        }
+        else if (elemName == "Affiliation")
+        {
+          m_meta.affiliation = text;
+        }
+        else if (elemName == "Valid_to")
+        {
+          m_meta.validTo = boost::lexical_cast<time_t>(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;
+}
+
+} // Ndnx
diff --git a/ndnx/ndnx-cert.h b/ndnx/ndnx-cert.h
new file mode 100644
index 0000000..17f06d5
--- /dev/null
+++ b/ndnx/ndnx-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 NDNX_CERT_H
+#define NDNX_CERT_H
+
+#include "ndnx-common.h"
+#include "ndnx-name.h"
+#include "ndnx-pco.h"
+#include "hash-helper.h"
+#include <boost/shared_ptr.hpp>
+
+namespace Ndnx {
+
+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; }
+
+  ndn_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;
+  ndn_pkey *m_pkey;
+  Meta m_meta;
+};
+
+typedef boost::shared_ptr<Cert> CertPtr;
+
+}
+
+#endif // NDNX_CERT_H
diff --git a/ndnx/ndnx-charbuf.cc b/ndnx/ndnx-charbuf.cc
new file mode 100644
index 0000000..842c840
--- /dev/null
+++ b/ndnx/ndnx-charbuf.cc
@@ -0,0 +1,71 @@
+/* -*- 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 "ndnx-charbuf.h"
+
+using namespace std;
+
+namespace Ndnx {
+
+void
+NdnxCharbuf::init(ndn_charbuf *buf)
+{
+  if (buf != NULL)
+  {
+    m_buf = ndn_charbuf_create();
+    ndn_charbuf_reserve(m_buf, buf->length);
+    memcpy(m_buf->buf, buf->buf, buf->length);
+    m_buf->length = buf->length;
+  }
+}
+
+NdnxCharbuf::NdnxCharbuf()
+            : m_buf(NULL)
+{
+  m_buf = ndn_charbuf_create();
+}
+
+NdnxCharbuf::NdnxCharbuf(ndn_charbuf *buf)
+            : m_buf(NULL)
+{
+  init(buf);
+}
+
+NdnxCharbuf::NdnxCharbuf(const NdnxCharbuf &other)
+            : m_buf (NULL)
+{
+  init(other.m_buf);
+}
+
+NdnxCharbuf::NdnxCharbuf(const void *buf, size_t length)
+{
+  m_buf = ndn_charbuf_create ();
+  ndn_charbuf_reserve (m_buf, length);
+  memcpy (m_buf->buf, buf, length);
+  m_buf->length = length;
+}
+
+NdnxCharbuf::~NdnxCharbuf()
+{
+  ndn_charbuf_destroy(&m_buf);
+}
+
+}
diff --git a/ndnx/ndnx-charbuf.h b/ndnx/ndnx-charbuf.h
new file mode 100644
index 0000000..3007eee
--- /dev/null
+++ b/ndnx/ndnx-charbuf.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012-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 NDNX_NDNX_CHARBUF_H
+#define NDNX_NDNX_CHARBUF_H
+
+#include "ndnx-common.h"
+#include <boost/shared_ptr.hpp>
+
+namespace Ndnx {
+
+class NdnxCharbuf;
+typedef boost::shared_ptr<NdnxCharbuf> NdnxCharbufPtr;
+
+//  This class is mostly used in NdnxWrapper; users should not be directly using this class
+// The main purpose of this class to is avoid manually create and destroy charbuf everytime
+class NdnxCharbuf
+{
+public:
+  NdnxCharbuf();
+  NdnxCharbuf(ndn_charbuf *buf);
+  NdnxCharbuf(const NdnxCharbuf &other);
+  NdnxCharbuf(const void *buf, size_t length);
+  ~NdnxCharbuf();
+
+  // expose internal data structure, use with caution!!
+  ndn_charbuf *
+  getBuf() { return m_buf; }
+
+  const ndn_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(ndn_charbuf *buf);
+
+protected:
+  ndn_charbuf *m_buf;
+};
+
+}
+
+#endif // NDNX_NDNX_CHARBUF_H
diff --git a/ndnx/ndnx-closure.cpp b/ndnx/ndnx-closure.cpp
new file mode 100644
index 0000000..1a96582
--- /dev/null
+++ b/ndnx/ndnx-closure.cpp
@@ -0,0 +1,112 @@
+/* -*- 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 "ndnx-closure.h"
+
+namespace Ndnx {
+
+Closure::Closure(const DataCallback &dataCallback, const TimeoutCallback &timeoutCallback)
+  : m_timeoutCallback (timeoutCallback)
+  , m_dataCallback (dataCallback)
+{
+}
+
+Closure::~Closure ()
+{
+}
+
+void
+Closure::runTimeoutCallback(Name interest, const Closure &closure, Selectors selectors)
+{
+  if (!m_timeoutCallback.empty ())
+    {
+      m_timeoutCallback (interest, closure, selectors);
+    }
+}
+
+
+void
+Closure::runDataCallback(Name name, PcoPtr content)
+{
+  if (!m_dataCallback.empty ())
+    {
+      m_dataCallback (name, content);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// ExecutorClosure::ExecutorClosure(const Closure &closure, ExecutorPtr executor)
+//   : Closure(closure.m_dataCallback, closure.m_timeoutCallback)
+//   , m_executor(executor)
+// {
+// }
+
+// ExecutorClosure::~ExecutorClosure()
+// {
+// }
+
+// void
+// ExecutorClosure::runDataCallback(Name name, PcoPtr content)
+// {
+//   m_executor->execute(boost::bind(&Closure::runDataCallback, this, name, content));
+// }
+
+// // void
+// // ExecutorClosure::execute(Name name, PcoPtr content)
+// // {
+// //   Closure::runDataCallback(name, content);
+// // }
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+// ExecutorInterestClosure::ExecutorInterestClosure(const InterestCallback &callback, ExecutorPtr executor)
+//   : m_callback(callback)
+//   , m_executor(executor)
+// {
+// }
+
+// void
+// ExecutorInterestClosure::runInterestCallback(Name interest)
+// {
+//   m_executor->execute(boost::bind(&ExecutorInterestClosure::execute, this, interest));
+// }
+
+// void
+// ExecutorInterestClosure::execute(Name interest)
+// {
+//   if (!m_callback.empty())
+//   {
+//     m_callback(interest);
+//   }
+// }
+
+} // Ndnx
diff --git a/ndnx/ndnx-closure.h b/ndnx/ndnx-closure.h
new file mode 100644
index 0000000..91e723a
--- /dev/null
+++ b/ndnx/ndnx-closure.h
@@ -0,0 +1,96 @@
+/* -*- 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 NDNX_CLOSURE_H
+#define NDNX_CLOSURE_H
+
+#include "ndnx-common.h"
+#include "ndnx-name.h"
+#include "ndnx-selectors.h"
+#include "executor.h"
+
+namespace Ndnx {
+
+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 &, Selectors)> TimeoutCallback;
+
+  Closure(const DataCallback &dataCallback, const TimeoutCallback &timeoutCallback = TimeoutCallback());
+  virtual ~Closure();
+
+  virtual void
+  runDataCallback(Name name, Ndnx::PcoPtr pco);
+
+  virtual void
+  runTimeoutCallback(Name interest, const Closure &closure, Selectors selectors);
+
+  virtual Closure *
+  dup () const { return new Closure (*this); }
+
+public:
+  TimeoutCallback m_timeoutCallback;
+  DataCallback m_dataCallback;
+};
+
+// class ExecutorClosure : public Closure
+// {
+// public:
+//   ExecutorClosure(const Closure &closure, ExecutorPtr executor);
+//   virtual ~ExecutorClosure();
+
+//   virtual void
+//   runDataCallback(Name name, PcoPtr pco);
+
+// // private:
+// //   void
+// //   execute(Name nae, PcoPtr content);
+
+// private:
+//   ExecutorPtr m_executor;
+// };
+
+// class ExecutorInterestClosure
+// {
+// public:
+//   typedef boost::function<void (Name)> InterestCallback;
+//   ExecutorInterestClosure(const InterestCallback &callback, ExecutorPtr executor);
+//   virtual ~ExecutorInterestClosure() {}
+
+//   void
+//   runInterestCallback(Name interest);
+
+//   void
+//   execute(Name interest);
+
+// private:
+//   InterestCallback m_callback;
+//   ExecutorPtr m_executor;
+// };
+
+} // Ndnx
+
+#endif
diff --git a/ndnx/ndnx-common.h b/ndnx/ndnx-common.h
new file mode 100644
index 0000000..fae1569
--- /dev/null
+++ b/ndnx/ndnx-common.h
@@ -0,0 +1,176 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012 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 NDNX_COMMON_H
+#define NDNX_COMMON_H
+
+extern "C" {
+#include <ndn/ndn.h>
+#include <ndn/charbuf.h>
+#include <ndn/keystore.h>
+#include <ndn/uri.h>
+#include <ndn/bloom.h>
+#include <ndn/signing.h>
+}
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include <boost/exception/all.hpp>
+#include <boost/function.hpp>
+#include <string>
+#include <sstream>
+#include <map>
+#include <utility>
+#include <string.h>
+#include <boost/iostreams/filter/gzip.hpp>
+#include <boost/iostreams/filtering_stream.hpp>
+#include <boost/iostreams/device/back_inserter.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/make_shared.hpp>
+
+namespace io = boost::iostreams;
+
+namespace Ndnx {
+typedef std::vector<unsigned char> Bytes;
+typedef std::vector<std::string>Comps;
+
+typedef boost::shared_ptr<Bytes> BytesPtr;
+
+inline
+const unsigned char *
+head(const Bytes &bytes)
+{
+  return &bytes[0];
+}
+
+inline
+unsigned char *
+head (Bytes &bytes)
+{
+  return &bytes[0];
+}
+
+// --- Bytes operations start ---
+inline void
+readRaw(Bytes &bytes, const unsigned char *src, size_t len)
+{
+  if (len > 0)
+  {
+    bytes.resize(len);
+    memcpy (head (bytes), src, len);
+  }
+}
+
+inline BytesPtr
+readRawPtr (const unsigned char *src, size_t len)
+{
+  if (len > 0)
+    {
+      BytesPtr ret (new Bytes (len));
+      memcpy (head (*ret), src, len);
+
+      return ret;
+    }
+  else
+    return BytesPtr ();
+}
+
+template<class Msg>
+BytesPtr
+serializeMsg(const Msg &msg)
+{
+  int size = msg.ByteSize ();
+  BytesPtr bytes (new Bytes (size));
+  msg.SerializeToArray (head(*bytes), size);
+  return bytes;
+}
+
+template<class Msg>
+boost::shared_ptr<Msg>
+deserializeMsg (const Bytes &bytes)
+{
+  boost::shared_ptr<Msg> retval (new Msg ());
+  if (!retval->ParseFromArray (head (bytes), bytes.size ()))
+    {
+      // to indicate an error
+      return boost::shared_ptr<Msg> ();
+    }
+  return retval;
+}
+
+template<class Msg>
+boost::shared_ptr<Msg>
+deserializeMsg (const void *buf, size_t length)
+{
+  boost::shared_ptr<Msg> retval (new Msg ());
+  if (!retval->ParseFromArray (buf, length))
+    {
+      // to indicate an error
+      return boost::shared_ptr<Msg> ();
+    }
+  return retval;
+}
+
+
+template<class Msg>
+BytesPtr
+serializeGZipMsg(const Msg &msg)
+{
+  std::vector<char> bytes;   // Bytes couldn't work
+  {
+    boost::iostreams::filtering_ostream out;
+    out.push(boost::iostreams::gzip_compressor()); // gzip filter
+    out.push(boost::iostreams::back_inserter(bytes)); // back_inserter sink
+
+    msg.SerializeToOstream(&out);
+  }
+  BytesPtr uBytes = boost::make_shared<Bytes>(bytes.size());
+  memcpy(&(*uBytes)[0], &bytes[0], bytes.size());
+  return uBytes;
+}
+
+template<class Msg>
+boost::shared_ptr<Msg>
+deserializeGZipMsg(const Bytes &bytes)
+{
+  std::vector<char> sBytes(bytes.size());
+  memcpy(&sBytes[0], &bytes[0], bytes.size());
+  boost::iostreams::filtering_istream in;
+  in.push(boost::iostreams::gzip_decompressor()); // gzip filter
+  in.push(boost::make_iterator_range(sBytes)); // source
+
+  boost::shared_ptr<Msg> retval = boost::make_shared<Msg>();
+  if (!retval->ParseFromIstream(&in))
+    {
+      // to indicate an error
+      return boost::shared_ptr<Msg> ();
+    }
+
+  return retval;
+}
+
+
+// --- Bytes operations end ---
+
+// Exceptions
+typedef boost::error_info<struct tag_errmsg, std::string> error_info_str;
+
+} // Ndnx
+#endif // NDNX_COMMON_H
diff --git a/ndnx/ndnx-discovery.cpp b/ndnx/ndnx-discovery.cpp
new file mode 100644
index 0000000..dce0d98
--- /dev/null
+++ b/ndnx/ndnx-discovery.cpp
@@ -0,0 +1,139 @@
+#include "ndnx-discovery.h"
+#include "simple-interval-generator.h"
+#include "task.h"
+#include "periodic-task.h"
+#include <sstream>
+#include <boost/make_shared.hpp>
+#include <boost/bind.hpp>
+
+using namespace Ndnx;
+using namespace std;
+
+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);
+  }
+}
+
+const double
+NdnxDiscovery::INTERVAL = 15.0;
+
+NdnxDiscovery *
+NdnxDiscovery::instance = NULL;
+
+boost::mutex
+NdnxDiscovery::mutex;
+
+NdnxDiscovery::NdnxDiscovery()
+              : m_scheduler(new Scheduler())
+              , m_localPrefix("/")
+{
+  m_scheduler->start();
+
+  Scheduler::scheduleOneTimeTask (m_scheduler, 0,
+                                  boost::bind(&NdnxDiscovery::poll, this), "Initial-Local-Prefix-Check");
+  Scheduler::schedulePeriodicTask (m_scheduler,
+                                   boost::make_shared<SimpleIntervalGenerator>(INTERVAL),
+                                   boost::bind(&NdnxDiscovery::poll, this), "Local-Prefix-Check");
+}
+
+NdnxDiscovery::~NdnxDiscovery()
+{
+  m_scheduler->shutdown();
+}
+
+void
+NdnxDiscovery::addCallback(const TaggedFunction &callback)
+{
+  m_callbacks.push_back(callback);
+}
+
+int
+NdnxDiscovery::deleteCallback(const 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
+NdnxDiscovery::poll()
+{
+  Name localPrefix = NdnxWrapper::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
+NdnxDiscovery::registerCallback(const TaggedFunction &callback)
+{
+  Lock lock(mutex);
+  if (instance == NULL)
+  {
+    instance = new NdnxDiscovery();
+  }
+
+  instance->addCallback(callback);
+}
+
+void
+NdnxDiscovery::deregisterCallback(const TaggedFunction &callback)
+{
+  Lock lock(mutex);
+  if (instance == NULL)
+  {
+    cerr << "NdnxDiscovery::deregisterCallback called without instance" << endl;
+  }
+  else
+  {
+    int size = instance->deleteCallback(callback);
+    if (size == 0)
+    {
+      delete instance;
+      instance = NULL;
+    }
+  }
+}
+
diff --git a/ndnx/ndnx-discovery.h b/ndnx/ndnx-discovery.h
new file mode 100644
index 0000000..e273364
--- /dev/null
+++ b/ndnx/ndnx-discovery.h
@@ -0,0 +1,108 @@
+/* -*- 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 NDNX_DISCOVERY_H
+#define NDNX_DISCOVERY_H
+
+#include "ndnx-wrapper.h"
+#include "ndnx-common.h"
+#include "ndnx-name.h"
+#include "scheduler.h"
+#include <boost/shared_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/random.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <list>
+
+namespace Ndnx
+{
+
+class NdnxDiscovery;
+typedef boost::shared_ptr<NdnxDiscovery> NdnxDiscoveryPtr;
+
+class TaggedFunction
+{
+public:
+  typedef boost::function<void (const Name &)> Callback;
+  TaggedFunction(const Callback &callback, const 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 NdnxDiscovery
+{
+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 TaggedFunction &callback);
+
+  // remember to call this before you quit
+  static void
+  deregisterCallback(const TaggedFunction &callback);
+
+private:
+  NdnxDiscovery();
+  ~NdnxDiscovery();
+
+  void
+  poll();
+
+  void
+  addCallback(const TaggedFunction &callback);
+
+  int
+  deleteCallback(const TaggedFunction &callback);
+
+private:
+  typedef boost::mutex Mutex;
+  typedef boost::unique_lock<Mutex> Lock;
+  typedef std::list<TaggedFunction> List;
+
+  static NdnxDiscovery *instance;
+  static Mutex mutex;
+  List m_callbacks;
+  SchedulerPtr m_scheduler;
+  Name m_localPrefix;
+};
+
+} // Ndnx
+#endif // NDNX_DISCOVERY_H
diff --git a/ndnx/ndnx-name.cpp b/ndnx/ndnx-name.cpp
new file mode 100644
index 0000000..dcf762e
--- /dev/null
+++ b/ndnx/ndnx-name.cpp
@@ -0,0 +1,361 @@
+/* -*- 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 "ndnx-name.h"
+#include <boost/lexical_cast.hpp>
+#include <ctype.h>
+#include <boost/algorithm/string/join.hpp>
+#include <boost/make_shared.hpp>
+
+using namespace std;
+
+namespace Ndnx{
+
+Name::Name()
+{
+}
+
+Name::Name(const string &name)
+{
+  stringstream ss(name);
+  string compStr;
+  bool first = true;
+  while(getline(ss, compStr, '/'))
+  {
+    // discard the first empty comp before the first '/'
+    if (first)
+    {
+      first = false;
+      continue;
+    }
+    Bytes comp(compStr.begin(), compStr.end());
+    m_comps.push_back(comp);
+  }
+}
+
+Name::Name(const vector<Bytes> &comps)
+{
+  m_comps = comps;
+}
+
+Name::Name(const Name &other)
+{
+  m_comps = other.m_comps;
+}
+
+Name::Name(const unsigned char *data, const ndn_indexbuf *comps)
+{
+  for (unsigned int i = 0; i < comps->n - 1; i++)
+  {
+    const unsigned char *compPtr;
+    size_t size;
+    ndn_name_comp_get(data, comps, i, &compPtr, &size);
+    Bytes comp;
+    readRaw(comp, compPtr, size);
+    m_comps.push_back(comp);
+  }
+}
+
+Name::Name (const void *buf, const size_t length)
+{
+  ndn_indexbuf *idx = ndn_indexbuf_create();
+  const ndn_charbuf namebuf = { length, length, const_cast<unsigned char *> (reinterpret_cast<const unsigned char *> (buf)) };
+  ndn_name_split (&namebuf, idx);
+
+  const unsigned char *compPtr = NULL;
+  size_t size = 0;
+  int i = 0;
+  while (ndn_name_comp_get(namebuf.buf, idx, i, &compPtr, &size) == 0)
+    {
+      Bytes comp;
+      readRaw (comp, compPtr, size);
+      m_comps.push_back(comp);
+      i++;
+    }
+  ndn_indexbuf_destroy(&idx);
+}
+
+Name::Name (const NdnxCharbuf &buf)
+{
+  ndn_indexbuf *idx = ndn_indexbuf_create();
+  ndn_name_split (buf.getBuf (), idx);
+
+  const unsigned char *compPtr = NULL;
+  size_t size = 0;
+  int i = 0;
+  while (ndn_name_comp_get(buf.getBuf ()->buf, idx, i, &compPtr, &size) == 0)
+    {
+      Bytes comp;
+      readRaw (comp, compPtr, size);
+      m_comps.push_back(comp);
+      i++;
+    }
+  ndn_indexbuf_destroy(&idx);
+}
+
+Name::Name (const ndn_charbuf *buf)
+{
+  ndn_indexbuf *idx = ndn_indexbuf_create();
+  ndn_name_split (buf, idx);
+
+  const unsigned char *compPtr = NULL;
+  size_t size = 0;
+  int i = 0;
+  while (ndn_name_comp_get(buf->buf, idx, i, &compPtr, &size) == 0)
+    {
+      Bytes comp;
+      readRaw (comp, compPtr, size);
+      m_comps.push_back(comp);
+      i++;
+    }
+  ndn_indexbuf_destroy(&idx);
+}
+
+Name &
+Name::operator=(const Name &other)
+{
+  m_comps = other.m_comps;
+  return *this;
+}
+bool
+Name::operator==(const string &str) const
+{
+  return this->toString() == str;
+}
+
+bool
+Name::operator!=(const string &str) const
+{
+  return !(*this == str);
+}
+
+Name
+operator+(const Name &n1, const Name &n2)
+{
+  vector<Bytes> comps = n1.m_comps;
+  copy(n2.m_comps.begin(), n2.m_comps.end(), back_inserter(comps));
+  return Name(comps);
+}
+
+string
+Name::toString() const
+{
+  stringstream ss(stringstream::out);
+  ss << *this;
+  return ss.str();
+}
+
+NdnxCharbuf*
+Name::toNdnxCharbufRaw () const
+{
+  NdnxCharbuf *ptr = new NdnxCharbuf ();
+
+  ndn_charbuf *cbuf = ptr->getBuf();
+  ndn_name_init(cbuf);
+  int size = m_comps.size();
+  for (int i = 0; i < size; i++)
+  {
+    ndn_name_append(cbuf, head(m_comps[i]), m_comps[i].size());
+  }
+  return ptr;
+}
+
+
+NdnxCharbufPtr
+Name::toNdnxCharbuf () const
+{
+  return NdnxCharbufPtr (toNdnxCharbufRaw ());
+}
+
+Name &
+Name::appendComp(const Name &comp)
+{
+  m_comps.insert (m_comps.end (),
+                  comp.m_comps.begin (), comp.m_comps.end ());
+  return *this;
+}
+
+Name &
+Name::appendComp(const Bytes &comp)
+{
+  m_comps.push_back(comp);
+  return *this;
+}
+
+Name &
+Name::appendComp(const string &compStr)
+{
+  Bytes comp(compStr.begin(), compStr.end());
+  return appendComp(comp);
+}
+
+Name &
+Name::appendComp (const void *buf, size_t size)
+{
+  Bytes comp (reinterpret_cast<const unsigned char*> (buf), reinterpret_cast<const unsigned char*> (buf) + size);
+  return appendComp(comp);
+}
+
+Name &
+Name::appendComp(uint64_t number)
+{
+  Bytes comp;
+  comp.push_back (0);
+
+  while (number > 0)
+    {
+      comp.push_back (static_cast<unsigned char> (number & 0xFF));
+      number >>= 8;
+    }
+  return appendComp (comp);
+}
+
+uint64_t
+Name::getCompAsInt (int index) const
+{
+  Bytes comp = getComp(index);
+  if (comp.size () < 1 ||
+      comp[0] != 0)
+    {
+      boost::throw_exception(NameException()
+                             << error_info_str("Non integer component: " + getCompAsString(index)));
+    }
+  uint64_t ret = 0;
+  for (int i = comp.size () - 1; i >= 1; i--)
+    {
+      ret <<= 8;
+      ret |= comp [i];
+    }
+  return ret;
+}
+
+const Bytes &
+Name::getComp(int index) const
+{
+  if (index < 0)
+    {
+      boost::throw_exception(NameException() << error_info_str("Negative index: " + boost::lexical_cast<string>(index)));
+    }
+
+  if (static_cast<unsigned int> (index) >= m_comps.size())
+    {
+      boost::throw_exception(NameException() << error_info_str("Index out of range: " + boost::lexical_cast<string>(index)));
+    }
+  return m_comps[index];
+}
+
+string
+Name::getCompAsString(int index) const
+{
+  Bytes comp = getComp(index);
+  stringstream ss(stringstream::out);
+  int size = comp.size();
+  for (int i = 0; i < size; i++)
+  {
+    unsigned char ch = comp[i];
+    if (isprint(ch))
+    {
+      ss << (char) ch;
+    }
+    else
+    {
+      ss << "%" << hex << setfill('0') << setw(2) << (unsigned int)ch;
+    }
+  }
+
+  return ss.str();
+}
+
+Name
+Name::getPartialName(int start, int n) const
+{
+  int size = m_comps.size();
+  if (start < 0 || start >= size || (n > 0 && start + n > size))
+  {
+    stringstream ss(stringstream::out);
+    ss << "getPartialName() parameter out of range! ";
+    ss << "start = " << start;
+    ss << "n = " << n;
+    ss << "size = " << size;
+    boost::throw_exception(NameException() << error_info_str(ss.str()));
+  }
+
+  vector<Bytes> comps;
+  int end;
+  if (n > 0)
+  {
+    end = start + n;
+  }
+  else
+  {
+    end = size;
+  }
+
+  for (int i = start; i < end; i++)
+  {
+    comps.push_back(m_comps[i]);
+  }
+
+  return Name(comps);
+}
+
+ostream &
+operator <<(ostream &os, const Name &name)
+{
+  int size = name.size();
+  vector<string> strComps;
+  for (int i = 0; i < size; i++)
+  {
+    strComps.push_back(name.getCompAsString(i));
+  }
+  string joined = boost::algorithm::join(strComps, "/");
+  os << "/" << joined;
+  return os;
+}
+
+bool
+operator ==(const Name &n1, const Name &n2)
+{
+  stringstream ss1(stringstream::out);
+  stringstream ss2(stringstream::out);
+  ss1 << n1;
+  ss2 << n2;
+  return ss1.str() == ss2.str();
+}
+
+bool
+operator !=(const Name &n1, const Name &n2)
+{
+  return !(n1 == n2);
+}
+
+bool
+operator <(const Name &n1, const Name &n2)
+{
+  stringstream ss1(stringstream::out);
+  stringstream ss2(stringstream::out);
+  ss1 << n1;
+  ss2 << n2;
+  return ss1.str() < ss2.str();
+}
+
+
+} // Ndnx
diff --git a/ndnx/ndnx-name.h b/ndnx/ndnx-name.h
new file mode 100644
index 0000000..2fde71b
--- /dev/null
+++ b/ndnx/ndnx-name.h
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012-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 NDNX_NAME_H
+#define NDNX_NAME_H
+#include <boost/shared_ptr.hpp>
+#include "ndnx-common.h"
+#include "ndnx-charbuf.h"
+
+namespace Ndnx {
+
+struct NameException:
+    virtual boost::exception, virtual std::exception {};
+
+class Name
+{
+public:
+  Name();
+  Name(const std::string &name);
+  Name(const std::vector<Bytes> &comps);
+  Name(const Name &other);
+  Name(const unsigned char *data, const ndn_indexbuf *comps);
+  Name (const void *buf, const size_t length);
+  Name (const NdnxCharbuf &buf);
+  Name (const ndn_charbuf *buf);
+  virtual ~Name() {}
+
+  NdnxCharbufPtr
+  toNdnxCharbuf() const;
+
+  NdnxCharbuf*
+  toNdnxCharbufRaw () const;
+
+  operator NdnxCharbufPtr () const { return toNdnxCharbuf (); }
+
+  Name &
+  appendComp(const Name &comp);
+
+  Name &
+  appendComp(const Bytes &comp);
+
+  Name &
+  appendComp(const std::string &compStr);
+
+  Name &
+  appendComp(const void *buf, size_t size);
+
+  /**
+   * Append int component
+   *
+   * Difference between this and appendComp call is that data is appended in network order
+   *
+   * Also, this function honors naming convention (%00 prefix is added)
+   */
+  Name &
+  appendComp(uint64_t number);
+
+  template<class T>
+  Name &
+  operator ()(const T &comp) { return appendComp (comp); }
+
+  Name &
+  operator ()(const void *buf, size_t size) { return appendComp (buf, size); }
+
+  int
+  size() const {return m_comps.size();}
+
+  const Bytes &
+  getComp (int index) const;
+
+  inline const Bytes &
+  getCompFromBack (int index) const;
+
+  // return std::string format of the comp
+  // if all characters are printable, simply returns the string
+  // if not, print the bytes in hex string format
+  std::string
+  getCompAsString(int index) const;
+
+  uint64_t
+  getCompAsInt (int index) const;
+
+  inline std::string
+  getCompFromBackAsString(int index) const;
+
+  inline uint64_t
+  getCompFromBackAsInt (int index) const;
+
+  Name
+  getPartialName(int start, int n = -1) const;
+
+  inline Name
+  getPartialNameFromBack(int start, int n = -1) const;
+
+  std::string
+  toString() const;
+
+  Name &
+  operator=(const Name &other);
+
+  bool
+  operator==(const std::string &str) const;
+
+  bool
+  operator!=(const std::string &str) const;
+
+  friend Name
+  operator+(const Name &n1, const Name &n2);
+
+private:
+  std::vector<Bytes> m_comps;
+};
+
+typedef boost::shared_ptr<Name> NamePtr;
+
+std::ostream&
+operator <<(std::ostream &os, const Name &name);
+
+bool
+operator ==(const Name &n1, const Name &n2);
+
+bool
+operator !=(const Name &n1, const Name &n2);
+
+bool
+operator <(const Name &n1, const Name &n2);
+
+
+std::string
+Name::getCompFromBackAsString(int index) const
+{
+  return getCompAsString (m_comps.size () - 1 - index);
+}
+
+uint64_t
+Name::getCompFromBackAsInt (int index) const
+{
+  return getCompAsInt (m_comps.size () - 1 - index);
+}
+
+Name
+Name::getPartialNameFromBack(int start, int n/* = -1*/) const
+{
+  return getPartialName (m_comps.size () - 1 - start, n);
+}
+
+const Bytes &
+Name::getCompFromBack (int index) const
+{
+  return getComp (m_comps.size () - 1 - index);
+}
+
+
+} // Ndnx
+#endif
diff --git a/ndnx/ndnx-pco.cpp b/ndnx/ndnx-pco.cpp
new file mode 100644
index 0000000..01c78da
--- /dev/null
+++ b/ndnx/ndnx-pco.cpp
@@ -0,0 +1,149 @@
+/* -*- 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 "ndnx-pco.h"
+#include "ndnx-cert.h"
+#include "hash-helper.h"
+
+namespace Ndnx {
+
+void
+ParsedContentObject::init(const unsigned char *data, size_t len)
+{
+  readRaw(m_bytes, data, len);
+
+  m_comps = ndn_indexbuf_create();
+  int res = ndn_parse_ContentObject(head (m_bytes), len, &m_pco, m_comps);
+  if (res < 0)
+  {
+    boost::throw_exception(MisformedContentObjectException());
+  }
+
+}
+
+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()
+{
+  ndn_indexbuf_destroy(&m_comps);
+  m_comps = NULL;
+}
+
+Bytes
+ParsedContentObject::content() const
+{
+  const unsigned char *content;
+  size_t len;
+  int res = ndn_content_get_value(head(m_bytes), m_pco.offset[NDN_PCO_E], &m_pco, &content, &len);
+  if (res < 0)
+  {
+    boost::throw_exception(MisformedContentObjectException());
+  }
+
+  Bytes bytes;
+  readRaw(bytes, content, len);
+  return bytes;
+}
+
+BytesPtr
+ParsedContentObject::contentPtr() const
+{
+  const unsigned char *content;
+  size_t len;
+  int res = ndn_content_get_value(head(m_bytes), m_pco.offset[NDN_PCO_E], &m_pco, &content, &len);
+  if (res < 0)
+  {
+    boost::throw_exception(MisformedContentObjectException());
+  }
+
+  return readRawPtr (content, len);
+}
+
+Name
+ParsedContentObject::name() const
+{
+  return Name(head(m_bytes), m_comps);
+}
+
+Name
+ParsedContentObject::keyName() const
+{
+  if (m_pco.offset[NDN_PCO_E_KeyName_Name] > m_pco.offset[NDN_PCO_B_KeyName_Name])
+  {
+    NdnxCharbufPtr ptr = boost::make_shared<NdnxCharbuf>();
+    ndn_charbuf_append(ptr->getBuf(), head(m_bytes) + m_pco.offset[NDN_PCO_B_KeyName_Name], m_pco.offset[NDN_PCO_E_KeyName_Name] - m_pco.offset[NDN_PCO_B_KeyName_Name]);
+
+    return Name(*ptr);
+}
+  else
+  {
+    return Name();
+  }
+}
+
+HashPtr
+ParsedContentObject::publisherPublicKeyDigest() const
+{
+  const unsigned char *buf = NULL;
+  size_t size = 0;
+  ndn_ref_tagged_BLOB(NDN_DTAG_PublisherPublicKeyDigest, head(m_bytes), m_pco.offset[NDN_PCO_B_PublisherPublicKeyDigest], m_pco.offset[NDN_PCO_E_PublisherPublicKeyDigest], &buf, &size);
+
+  return boost::make_shared<Hash>(buf, size);
+}
+
+ParsedContentObject::Type
+ParsedContentObject::type() const
+{
+  switch (m_pco.type)
+  {
+  case NDN_CONTENT_DATA: return DATA;
+  case NDN_CONTENT_KEY: return KEY;
+  default: break;
+  }
+  return OTHER;
+}
+
+void
+ParsedContentObject::verifySignature(const CertPtr &cert)
+{
+  m_verified = (ndn_verify_signature(head(m_bytes), m_pco.offset[NDN_PCO_E], &m_pco, cert->pkey()) == 1);
+}
+
+}
diff --git a/ndnx/ndnx-pco.h b/ndnx/ndnx-pco.h
new file mode 100644
index 0000000..6af0f73
--- /dev/null
+++ b/ndnx/ndnx-pco.h
@@ -0,0 +1,110 @@
+/* -*- 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 NDNX_CONTENT_OBJECT_H
+#define NDNX_CONTENT_OBJECT_H
+
+#include "ndnx-wrapper.h"
+#include "ndnx-common.h"
+#include "ndnx-name.h"
+
+class Hash;
+typedef boost::shared_ptr<Hash> HashPtr;
+
+namespace Ndnx {
+
+struct MisformedContentObjectException : virtual boost::exception, virtual std::exception { };
+
+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 ndn_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 ndn_parsed_ContentObject *
+  pco() const { return &m_pco; }
+
+private:
+  void
+  init(const unsigned char *data, size_t len);
+
+protected:
+  ndn_parsed_ContentObject m_pco;
+  ndn_indexbuf *m_comps;
+  Bytes m_bytes;
+  bool m_verified;
+  bool m_integrityChecked;
+};
+
+const Bytes &
+ParsedContentObject::buf () const
+{
+  return m_bytes;
+}
+
+
+typedef boost::shared_ptr<ParsedContentObject> PcoPtr;
+
+}
+
+#endif // NDNX_CONTENT_OBJECT_H
diff --git a/ndnx/ndnx-selectors.cpp b/ndnx/ndnx-selectors.cpp
new file mode 100644
index 0000000..3006d0e
--- /dev/null
+++ b/ndnx/ndnx-selectors.cpp
@@ -0,0 +1,157 @@
+#include "ndnx-selectors.h"
+#include "ndnx-common.h"
+#include <boost/lexical_cast.hpp>
+
+using namespace std;
+
+namespace Ndnx {
+
+Selectors::Selectors()
+          : m_maxSuffixComps(-1)
+          , m_minSuffixComps(-1)
+          , m_answerOriginKind(AOK_DEFAULT)
+          , m_interestLifetime(-1.0)
+          , m_scope(NO_SCOPE)
+          , m_childSelector(DEFAULT)
+{
+}
+
+Selectors::Selectors(const Selectors &other)
+{
+  m_maxSuffixComps = other.m_maxSuffixComps;
+  m_minSuffixComps = other.m_minSuffixComps;
+  m_answerOriginKind = other.m_answerOriginKind;
+  m_interestLifetime = other.m_interestLifetime;
+  m_scope = other.m_scope;
+  m_childSelector = other.m_childSelector;
+  m_publisherPublicKeyDigest = other.m_publisherPublicKeyDigest;
+}
+
+Selectors::Selectors(const ndn_parsed_interest *pi)
+          : m_maxSuffixComps(-1)
+          , m_minSuffixComps(-1)
+          , m_answerOriginKind(AOK_DEFAULT)
+          , m_interestLifetime(-1.0)
+          , m_scope(NO_SCOPE)
+          , m_childSelector(DEFAULT)
+{
+  if (pi != NULL)
+  {
+    m_maxSuffixComps = pi->max_suffix_comps;
+    m_minSuffixComps = pi->min_suffix_comps;
+    switch(pi->orderpref)
+    {
+      case 0: m_childSelector = LEFT; break;
+      case 1: m_childSelector = RIGHT; break;
+      default: break;
+    }
+    switch(pi->answerfrom)
+    {
+      case 0x1: m_answerOriginKind = AOK_CS; break;
+      case 0x2: m_answerOriginKind = AOK_NEW; break;
+      case 0x3: m_answerOriginKind = AOK_DEFAULT; break;
+      case 0x4: m_answerOriginKind = AOK_STALE; break;
+      case 0x10: m_answerOriginKind = AOK_EXPIRE; break;
+      default: break;
+    }
+    m_scope = static_cast<Scope> (pi->scope);
+    // scope and interest lifetime do not really matter to receiving application, it's only meaningful to routers
+  }
+}
+
+bool
+Selectors::operator == (const Selectors &other)
+{
+  return m_maxSuffixComps == other.m_maxSuffixComps
+         && m_minSuffixComps == other.m_minSuffixComps
+         && m_answerOriginKind == other.m_answerOriginKind
+         && (m_interestLifetime - other.m_interestLifetime) < 10e-4
+         && m_scope == other.m_scope
+         && m_childSelector == other.m_childSelector;
+}
+
+bool
+Selectors::isEmpty() const
+{
+  return m_maxSuffixComps == -1
+         && m_minSuffixComps == -1
+         && m_answerOriginKind == AOK_DEFAULT
+         && (m_interestLifetime - (-1.0)) < 10e-4
+         && m_scope == NO_SCOPE
+         && m_childSelector == DEFAULT;
+}
+
+
+NdnxCharbufPtr
+Selectors::toNdnxCharbuf() const
+{
+  if (isEmpty())
+  {
+    return NdnxCharbufPtr ();
+  }
+  NdnxCharbufPtr ptr(new NdnxCharbuf());
+  ndn_charbuf *cbuf = ptr->getBuf();
+  ndn_charbuf_append_tt(cbuf, NDN_DTAG_Interest, NDN_DTAG);
+  ndn_charbuf_append_tt(cbuf, NDN_DTAG_Name, NDN_DTAG);
+  ndn_charbuf_append_closer(cbuf); // </Name>
+
+  if (m_maxSuffixComps < m_minSuffixComps)
+  {
+    boost::throw_exception(InterestSelectorException() << error_info_str("MaxSuffixComps = " + boost::lexical_cast<string>(m_maxSuffixComps) + " is smaller than  MinSuffixComps = " + boost::lexical_cast<string>(m_minSuffixComps)));
+  }
+
+  if (m_minSuffixComps > 0)
+  {
+    ndnb_tagged_putf(cbuf, NDN_DTAG_MinSuffixComponents, "%d", m_minSuffixComps);
+  }
+
+  if (m_maxSuffixComps > 0)
+  {
+    ndnb_tagged_putf(cbuf, NDN_DTAG_MaxSuffixComponents, "%d", m_maxSuffixComps);
+  }
+
+  // publisher digest
+
+  // exclude
+
+  if (m_childSelector != DEFAULT)
+  {
+    ndnb_tagged_putf(cbuf, NDN_DTAG_MinSuffixComponents, "%d", (int)m_minSuffixComps);
+  }
+
+  if (m_answerOriginKind != AOK_DEFAULT)
+  {
+    // it was not using "ndnb_tagged_putf" in ndnx c code, no idea why
+    ndn_charbuf_append_tt(cbuf, NDN_DTAG_AnswerOriginKind, NDN_DTAG);
+    ndnb_append_number(cbuf, m_answerOriginKind);
+    ndn_charbuf_append_closer(cbuf); // <AnswerOriginKind>
+  }
+
+  if (m_scope != NO_SCOPE)
+  {
+    ndnb_tagged_putf(cbuf, NDN_DTAG_Scope, "%d", m_scope);
+  }
+
+  if (m_interestLifetime > 0.0)
+  {
+    // Ndnx timestamp unit is weird 1/4096 second
+    // this is from their code
+    unsigned lifetime = 4096 * (m_interestLifetime + 1.0/8192.0);
+    if (lifetime == 0 || lifetime > (30 << 12))
+    {
+      boost::throw_exception(InterestSelectorException() << error_info_str("Ndnx requires 0 < lifetime < 30.0. lifetime= " + boost::lexical_cast<string>(m_interestLifetime)));
+    }
+    unsigned char buf[3] = {0};
+    for (int i = sizeof(buf) - 1; i >= 0; i--, lifetime >>= 8)
+    {
+      buf[i] = lifetime & 0xff;
+    }
+    ndnb_append_tagged_blob(cbuf, NDN_DTAG_InterestLifetime, buf, sizeof(buf));
+  }
+
+  ndn_charbuf_append_closer(cbuf); // </Interest>
+
+  return ptr;
+}
+
+} // Ndnx
diff --git a/ndnx/ndnx-selectors.h b/ndnx/ndnx-selectors.h
new file mode 100644
index 0000000..f75647d
--- /dev/null
+++ b/ndnx/ndnx-selectors.h
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012-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 NDNX_SELECTORS_H
+#define NDNX_SELECTORS_H
+
+#include "ndnx-common.h"
+#include "ndnx-name.h"
+
+namespace Ndnx {
+
+struct InterestSelectorException:
+    virtual boost::exception, virtual std::exception {};
+
+class Selectors
+{
+public:
+  Selectors();
+  Selectors(const ndn_parsed_interest *);
+  Selectors(const Selectors &other);
+  ~Selectors(){};
+
+  typedef enum
+  {
+    AOK_CS = 0x1,
+    AOK_NEW = 0x2,
+    AOK_DEFAULT = 0x3, // (AOK_CS | AOK_NEW)
+    AOK_STALE = 0x4,
+    AOK_EXPIRE = 0x10
+  } AOK;
+
+  typedef enum
+  {
+    LEFT = 0,
+    RIGHT = 1,
+    DEFAULT = 2
+  } CHILD_SELECTOR;
+
+  enum Scope
+    {
+      NO_SCOPE = -1,
+      SCOPE_LOCAL_NDND = 0,
+      SCOPE_LOCAL_HOST = 1,
+      SCOPE_NEXT_HOST = 2
+    };
+
+  inline Selectors &
+  maxSuffixComps(int maxSCs) {m_maxSuffixComps = maxSCs; return *this;}
+
+  inline Selectors &
+  minSuffixComps(int minSCs) {m_minSuffixComps = minSCs; return *this;}
+
+  inline Selectors &
+  answerOriginKind(AOK kind) {m_answerOriginKind = kind; return *this;}
+
+  inline Selectors &
+  interestLifetime(double lifetime) {m_interestLifetime = lifetime; return *this;}
+
+  inline Selectors &
+  scope(Scope scope) {m_scope = scope; return *this;}
+
+  inline Selectors &
+  childSelector(CHILD_SELECTOR child) {m_childSelector = child; return *this;}
+
+  // this has no effect now
+  inline Selectors &
+  publisherPublicKeyDigest(const Bytes &digest) {m_publisherPublicKeyDigest = digest; return *this;}
+
+  NdnxCharbufPtr
+  toNdnxCharbuf() const;
+
+  bool
+  isEmpty() const;
+
+  bool
+  operator==(const Selectors &other);
+
+private:
+  int m_maxSuffixComps;
+  int m_minSuffixComps;
+  AOK m_answerOriginKind;
+  double m_interestLifetime;
+  Scope m_scope;
+  CHILD_SELECTOR m_childSelector;
+  // not used now
+  Bytes m_publisherPublicKeyDigest;
+};
+
+} // Ndnx
+
+#endif
diff --git a/ndnx/ndnx-verifier.cpp b/ndnx/ndnx-verifier.cpp
new file mode 100644
index 0000000..1bcfad0
--- /dev/null
+++ b/ndnx/ndnx-verifier.cpp
@@ -0,0 +1,169 @@
+/* -*- 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 "ndnx-verifier.h"
+#include "ndnx-wrapper.h"
+
+INIT_LOGGER ("Ndnx.Verifier");
+namespace Ndnx {
+
+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(NdnxWrapper *ndnx)
+         : m_ndnx(ndnx)
+         , m_rootKeyDigest(ROOT_KEY_DIGEST, ROOT_KEY_DIGEST_LEN)
+{
+}
+
+Verifier::~Verifier()
+{
+}
+
+bool
+Verifier::verify(const 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.getPartialName(0, keyNameSize - 1);
+    if (keyNamePrefix.size() >= contentName.size() || contentName.getPartialName(0, 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 = keyName.getPartialName(0, keyNameSize - 1) + Name("/info") + keyName.getPartialName(keyNameSize - 1);
+
+  Selectors selectors;
+
+  selectors.childSelector(Selectors::RIGHT)
+           .interestLifetime(maxWait);
+
+  PcoPtr keyObject = m_ndnx->get(keyName, selectors, maxWait);
+  PcoPtr metaObject = m_ndnx->get(metaName, selectors, 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 ndnx 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();
+}
+
+} // Ndnx
diff --git a/ndnx/ndnx-verifier.h b/ndnx/ndnx-verifier.h
new file mode 100644
index 0000000..ce3d450
--- /dev/null
+++ b/ndnx/ndnx-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 NDNX_VERIFIER_H
+#define NDNX_VERIFIER_H
+
+#include "ndnx-common.h"
+#include "ndnx-name.h"
+#include "ndnx-cert.h"
+#include "ndnx-pco.h"
+#include <map>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+
+namespace Ndnx {
+
+class NdnxWrapper;
+
+class Verifier
+{
+public:
+  Verifier(NdnxWrapper *ndnx);
+  ~Verifier();
+
+  bool verify(const PcoPtr &pco, double maxWait);
+
+private:
+
+private:
+  NdnxWrapper *m_ndnx;
+  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;
+};
+
+} // Ndnx
+
+#endif // NDNX_VERIFIER_H
diff --git a/ndnx/ndnx-wrapper.cpp b/ndnx/ndnx-wrapper.cpp
new file mode 100644
index 0000000..ab177ce
--- /dev/null
+++ b/ndnx/ndnx-wrapper.cpp
@@ -0,0 +1,783 @@
+/* -*- 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 "ndnx-wrapper.h"
+extern "C" {
+#include <ndn/fetch.h>
+}
+#include <poll.h>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/random.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/algorithm/string.hpp>
+#include <sstream>
+
+#include "ndnx-verifier.h"
+#include "logging.h"
+
+INIT_LOGGER ("Ndnx.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 Ndnx {
+
+// hack to enable fake signatures
+// min length for signature field is 16, as defined in ndn_buf_decoder.c:728
+const int DEFAULT_SIGNATURE_SIZE = 16;
+
+// Although ndn_buf_decoder.c:745 defines minimum length 16, something else is checking and only 32-byte fake value is accepted by ndnd
+const int PUBLISHER_KEY_SIZE = 32;
+
+static int
+ndn_encode_garbage_Signature(struct ndn_charbuf *buf)
+{
+    int res = 0;
+
+    res |= ndn_charbuf_append_tt(buf, NDN_DTAG_Signature, NDN_DTAG);
+
+    // Let's cheat more.  Default signing algorithm in ndnd 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 |= ndn_charbuf_append_tt(buf, NDN_DTAG_SignatureBits, NDN_DTAG);
+    res |= ndn_charbuf_append_tt(buf, DEFAULT_SIGNATURE_SIZE, NDN_BLOB);
+    res |= ndn_charbuf_append(buf, garbage, DEFAULT_SIGNATURE_SIZE);
+    res |= ndn_charbuf_append_closer(buf);
+
+    res |= ndn_charbuf_append_closer(buf);
+
+    return(res == 0 ? 0 : -1);
+}
+
+static int
+ndn_pack_unsigned_ContentObject(struct ndn_charbuf *buf,
+                                const struct ndn_charbuf *Name,
+                                const struct ndn_charbuf *SignedInfo,
+                                const void *data,
+                                size_t size)
+{
+    int res = 0;
+    struct ndn_charbuf *content_header;
+    size_t closer_start;
+
+    content_header = ndn_charbuf_create();
+    res |= ndn_charbuf_append_tt(content_header, NDN_DTAG_Content, NDN_DTAG);
+    if (size != 0)
+        res |= ndn_charbuf_append_tt(content_header, size, NDN_BLOB);
+    closer_start = content_header->length;
+    res |= ndn_charbuf_append_closer(content_header);
+    if (res < 0)
+        return(-1);
+
+    res |= ndn_charbuf_append_tt(buf, NDN_DTAG_ContentObject, NDN_DTAG);
+
+    res |= ndn_encode_garbage_Signature(buf);
+
+    res |= ndn_charbuf_append_charbuf(buf, Name);
+    res |= ndn_charbuf_append_charbuf(buf, SignedInfo);
+    res |= ndnb_append_tagged_blob(buf, NDN_DTAG_Content, data, size);
+    res |= ndn_charbuf_append_closer(buf);
+
+    ndn_charbuf_destroy(&content_header);
+    return(res == 0 ? 0 : -1);
+}
+
+NdnxWrapper::NdnxWrapper()
+  : m_handle (0)
+  , m_running (true)
+  , m_connected (false)
+  , m_executor (new Executor(1))
+  , m_verifier(new Verifier(this))
+{
+  start ();
+}
+
+void
+NdnxWrapper::connectNdnd()
+{
+  if (m_handle != 0) {
+    ndn_disconnect (m_handle);
+    //ndn_destroy (&m_handle);
+  }
+  else
+    {
+      m_handle = ndn_create ();
+    }
+
+  UniqueRecLock lock(m_mutex);
+  if (ndn_connect(m_handle, NULL) < 0)
+  {
+    BOOST_THROW_EXCEPTION (NdnxOperationException() << errmsg_info_str("connection to ndnd 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);
+    }
+  }
+}
+
+NdnxWrapper::~NdnxWrapper()
+{
+  shutdown ();
+  if (m_verifier != 0)
+  {
+    delete m_verifier;
+    m_verifier = 0;
+}
+}
+
+void
+NdnxWrapper::start () // called automatically in constructor
+{
+  connectNdnd();
+  m_thread = thread (&NdnxWrapper::ndnLoop, this);
+  m_executor->start();
+}
+
+void
+NdnxWrapper::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 ();
+
+      ndn_disconnect (m_handle);
+      //ndn_destroy (&m_handle);
+      m_connected = false;
+    }
+}
+
+void
+NdnxWrapper::ndnLoop ()
+{
+  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 = ndn_run (m_handle, 0);
+          }
+
+          if (!m_running) break;
+
+          if (res < 0) {
+            _LOG_ERROR ("ndn_run returned negative status: " << res);
+
+            BOOST_THROW_EXCEPTION (NdnxOperationException()
+                                   << errmsg_info_str("ndn_run returned error"));
+          }
+
+
+          pollfd pfds[1];
+          {
+            UniqueRecLock lock(m_mutex);
+
+            pfds[0].fd = ndn_get_connection_fd (m_handle);
+            pfds[0].events = POLLIN;
+            if (ndn_output_is_pending (m_handle))
+              pfds[0].events |= POLLOUT;
+          }
+
+          int ret = poll (pfds, 1, 1);
+          if (ret < 0)
+            {
+              BOOST_THROW_EXCEPTION (NdnxOperationException() << errmsg_info_str("ndnd socket failed (probably ndnd got stopped)"));
+            }
+        }
+        catch (NdnxOperationException &e)
+        {
+          m_connected = false;
+          // probably ndnd has been stopped
+          // try reconnect with sleep
+          int interval = 1;
+          int maxInterval = 32;
+          while (m_running)
+          {
+            try
+            {
+              this_thread::sleep (boost::get_system_time () +  boost::posix_time::seconds (interval) + boost::posix_time::milliseconds (rangeUniformRandom ()));
+
+              connectNdnd ();
+              _LOG_DEBUG("reconnect to ndnd succeeded");
+              break;
+            }
+            catch (NdnxOperationException &e)
+            {
+              this_thread::sleep (boost::get_system_time () +  boost::posix_time::seconds (interval) + boost::posix_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
+NdnxWrapper::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 ();
+      }
+  }
+
+  NdnxCharbufPtr ptr = name.toNdnxCharbuf();
+  ndn_charbuf *pname = ptr->getBuf();
+  ndn_charbuf *content = ndn_charbuf_create();
+
+  struct ndn_signing_params sp = NDN_SIGNING_PARAMS_INIT;
+  sp.freshness = freshness;
+
+  Name keyName;
+
+  if (keyNameParam.size() == 0)
+  {
+    // use default key name
+    NdnxCharbufPtr defaultKeyNamePtr = boost::make_shared<NdnxCharbuf>();
+    ndn_get_public_key_and_name(m_handle, &sp, NULL, NULL, defaultKeyNamePtr->getBuf());
+    keyName = Name(*defaultKeyNamePtr);
+  }
+  else
+  {
+    keyName = keyNameParam;
+  }
+
+  if (sp.template_ndnb == NULL)
+    {
+    sp.template_ndnb = ndn_charbuf_create();
+    ndn_charbuf_append_tt(sp.template_ndnb, NDN_DTAG_SignedInfo, NDN_DTAG);
+    }
+    // no idea what the following 3 lines do, but it was there
+  else if (sp.template_ndnb->length > 0) {
+      sp.template_ndnb->length--;
+    }
+  ndn_charbuf_append_tt(sp.template_ndnb, NDN_DTAG_KeyLocator, NDN_DTAG);
+  ndn_charbuf_append_tt(sp.template_ndnb, NDN_DTAG_KeyName, NDN_DTAG);
+  NdnxCharbufPtr keyPtr = keyName.toNdnxCharbuf();
+  ndn_charbuf *keyBuf = keyPtr->getBuf();
+  ndn_charbuf_append(sp.template_ndnb, keyBuf->buf, keyBuf->length);
+  ndn_charbuf_append_closer(sp.template_ndnb); // </KeyName>
+  ndn_charbuf_append_closer(sp.template_ndnb); // </KeyLocator>
+  sp.sp_flags |= NDN_SP_TEMPL_KEY_LOCATOR;
+  ndn_charbuf_append_closer(sp.template_ndnb); // </SignedInfo>
+
+  if (ndn_sign_content(m_handle, content, pname, &sp, buf, len) != 0)
+  {
+    BOOST_THROW_EXCEPTION(NdnxOperationException() << errmsg_info_str("sign content failed"));
+  }
+
+  Bytes bytes;
+  readRaw(bytes, content->buf, content->length);
+
+  ndn_charbuf_destroy (&content);
+  if (sp.template_ndnb != NULL)
+  {
+    ndn_charbuf_destroy (&sp.template_ndnb);
+  }
+
+  return bytes;
+}
+
+int
+NdnxWrapper::putToNdnd (const Bytes &contentObject)
+{
+  _LOG_TRACE (">> putToNdnd");
+  UniqueRecLock lock(m_mutex);
+  if (!m_running || !m_connected)
+    {
+      _LOG_TRACE ("<< not running or connected");
+      return -1;
+    }
+
+
+  if (ndn_put(m_handle, head(contentObject), contentObject.size()) < 0)
+  {
+    _LOG_ERROR ("ndn_put failed");
+    // BOOST_THROW_EXCEPTION(NdnxOperationException() << errmsg_info_str("ndnput failed"));
+  }
+  else
+    {
+      _LOG_DEBUG ("<< putToNdnd");
+    }
+
+  return 0;
+}
+
+int
+NdnxWrapper::publishData (const Name &name, const unsigned char *buf, size_t len, int freshness, const Name &keyName)
+{
+  Bytes co = createContentObject(name, buf, len, freshness, keyName);
+  return putToNdnd(co);
+}
+
+int
+NdnxWrapper::publishUnsignedData(const Name &name, const unsigned char *buf, size_t len, int freshness)
+{
+  {
+    UniqueRecLock lock(m_mutex);
+    if (!m_running || !m_connected)
+      {
+        _LOG_TRACE ("<< not running or connected");
+        return -1;
+      }
+  }
+
+  NdnxCharbufPtr ptr = name.toNdnxCharbuf();
+  ndn_charbuf *pname = ptr->getBuf();
+  ndn_charbuf *content = ndn_charbuf_create();
+  ndn_charbuf *signed_info = ndn_charbuf_create();
+
+  static char fakeKey[PUBLISHER_KEY_SIZE];
+
+  int res = ndn_signed_info_create(signed_info,
+                                   fakeKey, PUBLISHER_KEY_SIZE,
+                                   NULL,
+                                   NDN_CONTENT_DATA,
+                                   freshness,
+                                   NULL,
+                                   NULL  // ndnd is happy with absent key locator and key itself... ha ha
+                                   );
+  ndn_pack_unsigned_ContentObject(content, pname, signed_info, buf, len);
+
+  Bytes bytes;
+  readRaw(bytes, content->buf, content->length);
+
+  ndn_charbuf_destroy (&content);
+  ndn_charbuf_destroy (&signed_info);
+
+  return putToNdnd (bytes);
+}
+
+
+static void
+deleterInInterestTuple (tuple<NdnxWrapper::InterestCallback *, ExecutorPtr> *tuple)
+{
+  delete tuple->get<0> ();
+  delete tuple;
+}
+
+static ndn_upcall_res
+incomingInterest(ndn_closure *selfp,
+                 ndn_upcall_kind kind,
+                 ndn_upcall_info *info)
+{
+  NdnxWrapper::InterestCallback *f;
+  ExecutorPtr executor;
+  tuple<NdnxWrapper::InterestCallback *, ExecutorPtr> *realData = reinterpret_cast< tuple<NdnxWrapper::InterestCallback *, ExecutorPtr>* > (selfp->data);
+  tie (f, executor) = *realData;
+
+  switch (kind)
+    {
+    case NDN_UPCALL_FINAL: // effective in unit tests
+      // delete closure;
+      executor->execute (bind (deleterInInterestTuple, realData));
+
+      delete selfp;
+      _LOG_TRACE ("<< incomingInterest with NDN_UPCALL_FINAL");
+      return NDN_UPCALL_RESULT_OK;
+
+    case NDN_UPCALL_INTEREST:
+      _LOG_TRACE (">> incomingInterest upcall: " << Name(info->interest_ndnb, info->interest_comps));
+      break;
+
+    default:
+      _LOG_TRACE ("<< incomingInterest with NDN_UPCALL_RESULT_OK: " << Name(info->interest_ndnb, info->interest_comps));
+      return NDN_UPCALL_RESULT_OK;
+    }
+
+  Name interest(info->interest_ndnb, info->interest_comps);
+  Selectors selectors(info->pi);
+
+  executor->execute (bind (*f, interest, selectors));
+  // this will be run in executor
+  // (*f) (interest);
+  // closure->runInterestCallback(interest);
+
+  return NDN_UPCALL_RESULT_OK;
+}
+
+static void
+deleterInDataTuple (tuple<Closure *, ExecutorPtr, Selectors> *tuple)
+{
+  delete tuple->get<0> ();
+  delete tuple;
+}
+
+static ndn_upcall_res
+incomingData(ndn_closure *selfp,
+             ndn_upcall_kind kind,
+             ndn_upcall_info *info)
+{
+  // Closure *cp = static_cast<Closure *> (selfp->data);
+  Closure *cp;
+  ExecutorPtr executor;
+  Selectors selectors;
+  tuple<Closure *, ExecutorPtr, Selectors> *realData = reinterpret_cast< tuple<Closure*, ExecutorPtr, Selectors>* > (selfp->data);
+  tie (cp, executor, selectors) = *realData;
+
+  switch (kind)
+    {
+    case NDN_UPCALL_FINAL:  // effecitve in unit tests
+      executor->execute (bind (deleterInDataTuple, realData));
+
+      cp = NULL;
+      delete selfp;
+      _LOG_TRACE ("<< incomingData with NDN_UPCALL_FINAL");
+      return NDN_UPCALL_RESULT_OK;
+
+    case NDN_UPCALL_CONTENT:
+      _LOG_TRACE (">> incomingData content upcall: " << Name (info->content_ndnb, info->content_comps));
+      break;
+
+    // this is the case where the intentionally unsigned packets coming (in Encapsulation case)
+    case NDN_UPCALL_CONTENT_BAD:
+      _LOG_TRACE (">> incomingData content bad upcall: " << Name (info->content_ndnb, info->content_comps));
+      break;
+
+    // always ask ndnd to try to fetch the key
+    case NDN_UPCALL_CONTENT_UNVERIFIED:
+      _LOG_TRACE (">> incomingData content unverified upcall: " << Name (info->content_ndnb, info->content_comps));
+      break;
+
+    case NDN_UPCALL_INTEREST_TIMED_OUT: {
+      if (cp != NULL)
+      {
+        Name interest(info->interest_ndnb, info->interest_comps);
+        _LOG_TRACE ("<< incomingData timeout: " << Name (info->interest_ndnb, info->interest_comps));
+        executor->execute (bind (&Closure::runTimeoutCallback, cp, interest, *cp, selectors));
+      }
+      else
+        {
+          _LOG_TRACE ("<< incomingData timeout, but callback is not set...: " << Name (info->interest_ndnb, info->interest_comps));
+        }
+      return NDN_UPCALL_RESULT_OK;
+    }
+
+    default:
+      _LOG_TRACE(">> unknown upcall type");
+      return NDN_UPCALL_RESULT_OK;
+    }
+
+  PcoPtr pco = make_shared<ParsedContentObject> (info->content_ndnb, info->pco->offset[NDN_PCO_E]);
+
+  // this will be run in executor
+  executor->execute (bind (&Closure::runDataCallback, cp, pco->name (), pco));
+  _LOG_TRACE (">> incomingData");
+
+  return NDN_UPCALL_RESULT_OK;
+}
+
+int NdnxWrapper::sendInterest (const Name &interest, const Closure &closure, const Selectors &selectors)
+{
+  _LOG_TRACE (">> sendInterest: " << interest);
+  {
+    UniqueRecLock lock(m_mutex);
+    if (!m_running || !m_connected)
+      {
+        _LOG_ERROR ("<< sendInterest: not running or connected");
+        return -1;
+      }
+  }
+
+  NdnxCharbufPtr namePtr = interest.toNdnxCharbuf();
+  ndn_charbuf *pname = namePtr->getBuf();
+  ndn_closure *dataClosure = new ndn_closure;
+
+  // Closure *myClosure = new ExecutorClosure(closure, m_executor);
+  Closure *myClosure = closure.dup ();
+  dataClosure->data = new tuple<Closure*, ExecutorPtr, Selectors> (myClosure, m_executor, selectors);
+
+  dataClosure->p = &incomingData;
+
+  NdnxCharbufPtr selectorsPtr = selectors.toNdnxCharbuf();
+  ndn_charbuf *templ = NULL;
+  if (selectorsPtr)
+  {
+    templ = selectorsPtr->getBuf();
+  }
+
+  UniqueRecLock lock(m_mutex);
+  if (ndn_express_interest (m_handle, pname, dataClosure, templ) < 0)
+  {
+    _LOG_ERROR ("<< sendInterest: ndn_express_interest FAILED!!!");
+  }
+
+  return 0;
+}
+
+int NdnxWrapper::setInterestFilter (const Name &prefix, const InterestCallback &interestCallback, bool record/* = true*/)
+{
+  _LOG_TRACE (">> setInterestFilter");
+  UniqueRecLock lock(m_mutex);
+  if (!m_running || !m_connected)
+  {
+    return -1;
+  }
+
+  NdnxCharbufPtr ptr = prefix.toNdnxCharbuf();
+  ndn_charbuf *pname = ptr->getBuf();
+  ndn_closure *interestClosure = new ndn_closure;
+
+  // interestClosure->data = new ExecutorInterestClosure(interestCallback, m_executor);
+
+  interestClosure->data = new tuple<NdnxWrapper::InterestCallback *, ExecutorPtr> (new InterestCallback (interestCallback), m_executor); // should be removed when closure is removed
+  interestClosure->p = &incomingInterest;
+
+  int ret = ndn_set_interest_filter (m_handle, pname, interestClosure);
+  if (ret < 0)
+  {
+    _LOG_ERROR ("<< setInterestFilter: ndn_set_interest_filter FAILED");
+  }
+
+  if (record)
+    {
+      m_registeredInterests.insert(pair<Name, InterestCallback>(prefix, interestCallback));
+    }
+
+  _LOG_TRACE ("<< setInterestFilter");
+
+  return ret;
+}
+
+void
+NdnxWrapper::clearInterestFilter (const Name &prefix, bool record/* = true*/)
+{
+  _LOG_TRACE (">> clearInterestFilter");
+  UniqueRecLock lock(m_mutex);
+  if (!m_running || !m_connected)
+    return;
+
+  NdnxCharbufPtr ptr = prefix.toNdnxCharbuf();
+  ndn_charbuf *pname = ptr->getBuf();
+
+  int ret = ndn_set_interest_filter (m_handle, pname, 0);
+  if (ret < 0)
+  {
+  }
+
+  if (record)
+    {
+      m_registeredInterests.erase(prefix);
+    }
+
+  _LOG_TRACE ("<< clearInterestFilter");
+}
+
+Name
+NdnxWrapper::getLocalPrefix ()
+{
+  struct ndn * tmp_handle = ndn_create ();
+  int res = ndn_connect (tmp_handle, NULL);
+  if (res < 0)
+    {
+      return Name();
+    }
+
+  string retval = "";
+
+  struct ndn_charbuf *templ = ndn_charbuf_create();
+  ndn_charbuf_append_tt(templ, NDN_DTAG_Interest, NDN_DTAG);
+  ndn_charbuf_append_tt(templ, NDN_DTAG_Name, NDN_DTAG);
+  ndn_charbuf_append_closer(templ); /* </Name> */
+  // XXX - use pubid if possible
+  ndn_charbuf_append_tt(templ, NDN_DTAG_MaxSuffixComponents, NDN_DTAG);
+  ndnb_append_number(templ, 1);
+  ndn_charbuf_append_closer(templ); /* </MaxSuffixComponents> */
+  ndnb_tagged_putf(templ, NDN_DTAG_Scope, "%d", 2);
+  ndn_charbuf_append_closer(templ); /* </Interest> */
+
+  struct ndn_charbuf *name = ndn_charbuf_create ();
+  res = ndn_name_from_uri (name, "/local/ndn/prefix");
+  if (res < 0) {
+  }
+  else
+    {
+      struct ndn_fetch *fetch = ndn_fetch_new (tmp_handle);
+
+      struct ndn_fetch_stream *stream = ndn_fetch_open (fetch, name, "/local/ndn/prefix",
+                                                        NULL, 4, NDN_V_HIGHEST, 0);
+      if (stream == NULL) {
+      }
+      else
+        {
+          ostringstream os;
+
+          int counter = 0;
+          char buf[256];
+          while (true) {
+            res = ndn_fetch_read (stream, buf, sizeof(buf));
+
+            if (res == 0) {
+              break;
+            }
+
+            if (res > 0) {
+              os << string(buf, res);
+            } else if (res == NDN_FETCH_READ_NONE) {
+              if (counter < 2)
+                {
+                  ndn_run(tmp_handle, 1000);
+                  counter ++;
+                }
+              else
+                {
+                  break;
+                }
+            } else if (res == NDN_FETCH_READ_END) {
+              break;
+            } else if (res == NDN_FETCH_READ_TIMEOUT) {
+              break;
+            } else {
+              break;
+            }
+          }
+          retval = os.str ();
+          stream = ndn_fetch_close(stream);
+        }
+      fetch = ndn_fetch_destroy(fetch);
+    }
+
+  ndn_charbuf_destroy (&name);
+
+  ndn_disconnect (tmp_handle);
+  ndn_destroy (&tmp_handle);
+
+  boost::algorithm::trim(retval);
+  return Name(retval);
+}
+
+bool
+NdnxWrapper::verify(PcoPtr &pco, double maxWait)
+{
+  return m_verifier->verify(pco, maxWait);
+}
+
+// This is needed just for get function implementation
+struct GetState
+{
+  GetState (double maxWait)
+  {
+    double intPart, fraction;
+    fraction = modf (std::abs(maxWait), &intPart);
+
+    m_maxWait = date_time::second_clock<boost::posix_time::ptime>::universal_time()
+      + boost::posix_time::seconds (intPart)
+      + boost::posix_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:
+  boost::posix_time::ptime m_maxWait;
+
+  boost::mutex m_mutex;
+  boost::condition_variable    m_cond;
+
+  PcoPtr  m_retval;
+};
+
+
+PcoPtr
+NdnxWrapper::get(const Name &interest, const Selectors &selectors, double maxWait/* = 4.0*/)
+{
+  _LOG_TRACE (">> get: " << interest);
+  {
+    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)),
+                      selectors);
+  return state.WaitForResult ();
+}
+
+}
diff --git a/ndnx/ndnx-wrapper.h b/ndnx/ndnx-wrapper.h
new file mode 100644
index 0000000..9da54f6
--- /dev/null
+++ b/ndnx/ndnx-wrapper.h
@@ -0,0 +1,162 @@
+/* -*- 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 NDNX_WRAPPER_H
+#define NDNX_WRAPPER_H
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+
+#include "ndnx-common.h"
+#include "ndnx-name.h"
+#include "ndnx-selectors.h"
+#include "ndnx-closure.h"
+#include "ndnx-pco.h"
+#include "executor.h"
+
+namespace Ndnx {
+
+struct NdnxOperationException : boost::exception, std::exception { };
+
+class Verifier;
+class NdnxWrapper
+{
+public:
+  const static int MAX_FRESHNESS = 2147; // max value for ndnx
+  const static int DEFAULT_FRESHNESS = 60;
+  typedef boost::function<void (Name, Selectors)> InterestCallback;
+
+  NdnxWrapper();
+  ~NdnxWrapper();
+
+  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 Name &interest, const Closure &closure, const Selectors &selector = Selectors());
+
+  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
+  putToNdnd (const Bytes &contentObject);
+
+  bool
+  verify(PcoPtr &pco, double maxWait = 1 /*seconds*/);
+
+  PcoPtr
+  get (const Name &interest, const Selectors &selector = Selectors(), double maxWait = 4.0/*seconds*/);
+
+private:
+  NdnxWrapper(const NdnxWrapper &other) {}
+
+protected:
+  void
+  connectNdnd();
+
+  /// @cond include_hidden
+  void
+  ndnLoop ();
+
+  /// @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;
+
+  ndn* 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<NdnxWrapper> NdnxWrapperPtr;
+
+inline int
+NdnxWrapper::publishData (const Name &name, const Bytes &content, int freshness, const Name &keyName)
+{
+  return publishData(name, head(content), content.size(), freshness, keyName);
+}
+
+inline int
+NdnxWrapper::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
+NdnxWrapper::publishUnsignedData(const Name &name, const Bytes &content, int freshness)
+{
+  return publishUnsignedData(name, head(content), content.size(), freshness);
+}
+
+inline int
+NdnxWrapper::publishUnsignedData(const Name &name, const std::string &content, int freshness)
+{
+  return publishUnsignedData(name, reinterpret_cast<const unsigned char *> (content.c_str ()), content.size (), freshness);
+}
+
+
+} // Ndnx
+
+#endif
