renaming: ndn-cpp to ndn-cpp-dev

Change-Id: Iff3e4ff53a0005b7dd35c57d03da76b347170d03
diff --git a/include/ndn-cpp-dev/c/common.h b/include/ndn-cpp-dev/c/common.h
new file mode 100644
index 0000000..42edcef
--- /dev/null
+++ b/include/ndn-cpp-dev/c/common.h
@@ -0,0 +1,33 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_COMMON_H
+#define NDN_COMMON_H
+
+#include <ndn-cpp-dev/ndn-cpp-config.h>
+#include <stdint.h>
+// TODO: Is stddef.h portable?
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A time interval represented as the number of milliseconds.
+ */
+typedef int64_t ndn_Milliseconds;
+   
+/**
+ * The calendar time represented as the number of milliseconds since 1/1/1970.
+ */
+typedef int64_t ndn_MillisecondsSince1970;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp-dev/c/data-types.h b/include/ndn-cpp-dev/c/data-types.h
new file mode 100644
index 0000000..668786b
--- /dev/null
+++ b/include/ndn-cpp-dev/c/data-types.h
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_DATA_TYPES_H
+#define NDN_DATA_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+  ndn_ContentType_DATA = 0,
+  ndn_ContentType_ENCR = 1,
+  ndn_ContentType_GONE = 2,
+  ndn_ContentType_KEY =  3,
+  ndn_ContentType_LINK = 4,
+  ndn_ContentType_NACK = 5
+} ndn_ContentType;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp-dev/c/encoding/element-listener.h b/include/ndn-cpp-dev/c/encoding/element-listener.h
new file mode 100644
index 0000000..af88a85
--- /dev/null
+++ b/include/ndn-cpp-dev/c/encoding/element-listener.h
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_ELEMENT_LISTENER_H
+#define NDN_ELEMENT_LISTENER_H
+
+#include "../common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** An ndn_ElementListener struct holds a function pointer onReceivedElement.  You can extend this struct with data that
+ * will be passed to onReceivedElement.
+ */
+struct ndn_ElementListener {
+  void (*onReceivedElement)(struct ndn_ElementListener *self, uint8_t *element, size_t elementLength); /**< see ndn_ElementListener_initialize */
+};
+
+/**
+ * Initialize an ndn_ElementListener struct to use the onReceivedElement function pointer.
+ * @param self pointer to the ndn_ElementListener struct
+ * @param onReceivedElement pointer to a function which is called when an entire binary XML element is received.
+ * self is the pointer to this ndn_ElementListener struct.  See ndn_BinaryXmlElementReader_onReceivedData.
+ */
+static inline void ndn_ElementListener_initialize
+  (struct ndn_ElementListener *self, void (*onReceivedElement)(struct ndn_ElementListener *self, uint8_t *element, size_t elementLength))
+{
+  self->onReceivedElement = onReceivedElement;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp-dev/c/forwarding-flags.h b/include/ndn-cpp-dev/c/forwarding-flags.h
new file mode 100644
index 0000000..863bf04
--- /dev/null
+++ b/include/ndn-cpp-dev/c/forwarding-flags.h
@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_FORWARDING_FLAGS_H
+#define NDN_FORWARDING_FLAGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * An ndn_ForwardingFlags object holds the flags which specify how the forwarding daemon should forward an interest for
+ * a registered prefix.  We use a separate ForwardingFlags object to retain future compatibility if the daemon forwarding
+ * bits are changed, amended or deprecated.
+ */
+struct ndn_ForwardingFlags {
+  int active; /**< 1 if the flag is set, 0 if cleared. */
+  int childInherit;
+  int advertise;
+  int last;
+  int capture;
+  int local;
+  int tap;
+  int captureOk;  
+};
+
+/**
+ * Initialize an ndn_ForwardingFlags struct with the default with "active" and "childInherit" set and all other flags cleared.
+ * @param self A pointer to the ndn_ForwardingFlags struct.
+ */
+void ndn_ForwardingFlags_initialize(struct ndn_ForwardingFlags *self);
+
+/**
+ * Get an integer with the bits set according to the flags as used by the ForwardingEntry message.
+ * @param self A pointer to the ndn_ForwardingFlags struct.
+ * @return An integer with the bits set.
+ */
+int ndn_ForwardingFlags_getForwardingEntryFlags(struct ndn_ForwardingFlags *self);
+
+/**
+ * Set the flags according to the bits in forwardingEntryFlags as used by the ForwardingEntry message.
+ * @param self A pointer to the ndn_ForwardingFlags struct.
+ * @param flags An integer with the bits set.
+ */
+void ndn_ForwardingFlags_setForwardingEntryFlags(struct ndn_ForwardingFlags *self, int forwardingEntryFlags);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp-dev/c/interest-types.h b/include/ndn-cpp-dev/c/interest-types.h
new file mode 100644
index 0000000..a464e17
--- /dev/null
+++ b/include/ndn-cpp-dev/c/interest-types.h
@@ -0,0 +1,36 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_INTEREST_TYPES_H
+#define NDN_INTEREST_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+  ndn_Exclude_COMPONENT = 0,
+  ndn_Exclude_ANY = 1  
+} ndn_ExcludeType;
+
+enum {
+  ndn_Interest_CHILD_SELECTOR_LEFT = 0,
+  ndn_Interest_CHILD_SELECTOR_RIGHT = 1,
+
+  ndn_Interest_ANSWER_NO_CONTENT_STORE = 0,
+  ndn_Interest_ANSWER_CONTENT_STORE = 1,
+  ndn_Interest_ANSWER_GENERATED = 2,
+  ndn_Interest_ANSWER_STALE = 4,    // Stale answer OK
+  ndn_Interest_MARK_STALE = 16,      // Must have scope 0.  Michael calls this a "hack"
+
+  ndn_Interest_DEFAULT_ANSWER_ORIGIN_KIND = ndn_Interest_ANSWER_CONTENT_STORE | ndn_Interest_ANSWER_GENERATED
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp-dev/c/key-types.h b/include/ndn-cpp-dev/c/key-types.h
new file mode 100644
index 0000000..712aee8
--- /dev/null
+++ b/include/ndn-cpp-dev/c/key-types.h
@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_KEY_TYPES_H
+#define NDN_KEY_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+  ndn_KeyLocatorType_KEY = 1,
+  ndn_KeyLocatorType_CERTIFICATE = 2,
+  ndn_KeyLocatorType_KEYNAME = 3
+} ndn_KeyLocatorType;
+
+typedef enum {
+  ndn_KeyNameType_PUBLISHER_PUBLIC_KEY_DIGEST = 1,
+  ndn_KeyNameType_PUBLISHER_CERTIFICATE_DIGEST = 2,
+  ndn_KeyNameType_PUBLISHER_ISSUER_KEY_DIGEST = 3,
+  ndn_KeyNameType_PUBLISHER_ISSUER_CERTIFICATE_DIGEST = 4
+} ndn_KeyNameType;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp-dev/c/util/crypto.h b/include/ndn-cpp-dev/c/util/crypto.h
new file mode 100644
index 0000000..43d47eb
--- /dev/null
+++ b/include/ndn-cpp-dev/c/util/crypto.h
@@ -0,0 +1,30 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_CRYPTO_H
+#define NDN_CRYPTO_H
+
+#include <openssl/ssl.h>
+#include <openssl/rsa.h>
+#include <ndn-cpp-dev/c/common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Compute the sha-256 digest of data.
+ * @param data Pointer to the input byte array.
+ * @param dataLength The length of data.
+ * @param digest A pointer to a buffer of size SHA256_DIGEST_LENGTH to receive the data.
+ */
+void ndn_digestSha256(const uint8_t *data, size_t dataLength, uint8_t *digest);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp-dev/common.hpp b/include/ndn-cpp-dev/common.hpp
new file mode 100644
index 0000000..59c49b5
--- /dev/null
+++ b/include/ndn-cpp-dev/common.hpp
@@ -0,0 +1,101 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_COMMON_HPP
+#define NDN_COMMON_HPP
+
+#include <vector>
+// common.h include ndn-cpp-config.h.
+#include "c/common.h"
+
+#if NDN_CPP_HAVE_CXX11
+
+#if (__cplusplus < 201103L)
+#error "NDN-CPP-DEV library is configured and compiled in C++11 mode, but the current compiler is not C++11 enabled"
+#endif
+
+// Depending on where ./configure found shared_ptr, define the ptr_lib namespace.
+// We always use ndn::ptr_lib.
+// #if NDN_CPP_HAVE_STD_SHARED_PTR
+#include <memory>
+namespace ndn { namespace ptr_lib = std; }
+
+// #if NDN_CPP_HAVE_STD_FUNCTION
+#include <functional>
+namespace ndn { namespace func_lib = std; }
+
+#elif NDN_CPP_USE_SYSTEM_BOOST
+
+// #if NDN_CPP_HAVE_BOOST_SHARED_PTR
+#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
+namespace ndn { namespace ptr_lib = boost; }
+
+// #if NDN_CPP_HAVE_BOOST_FUNCTION
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+namespace ndn { namespace func_lib = boost; }
+
+#else // use embedded boost headers
+/* Use the boost header files in this distribution that were extracted with:
+cd <BOOST DEVELOPMENT DIRECTORY WITH boost SUBDIRECTORY>
+dist/bin/bcp --namespace=ndnboost shared_ptr make_shared weak_ptr function bind any iostreams <NDN-CPP-DEV ROOT>/include
+cd <NDN-CPP-DEV ROOT>/include
+rm -rf boost.css boost.png Jamroot libs
+mv boost ndnboost
+cd ndnboost
+# Replace when including files.
+(unset LANG; find . -type f -exec sed -i '' 's/\<boost\//\<ndnboost\//g' {} +)
+(unset LANG; find . -type f -exec sed -i '' 's/\"boost\//\"ndnboost\//g' {} +)
+(unset LANG; find . -type f -exec sed -i '' 's/ boost\// ndnboost\//g' {} +)
+(unset LANG; find . -type f -exec sed -i '' 's/(boost\//(ndnboost\//g' {} +)
+# Replace macro definitions.
+(unset LANG; find . -type f -exec sed -i '' 's/BOOST_/NDNBOOST_/g' {} +)
+# Replace header include guards which don't start with BOOST_ .  This may result in some with NDNBOOST twice, but that is OK.
+(unset LANG; find . -type f -exec sed -i '' 's/_DWA/_NDNBOOST_DWA/g' {} +)
+(unset LANG; find . -type f -exec sed -i '' 's/ UUID_/ NDNBOOST_UUID_/g' {} +)
+(unset LANG; find . -type f -exec sed -i '' 's/ FILE_boost/ FILE_ndnboost/g' {} +)
+# Replace the mpl_ barrier namespace.  This should only change file adl_barrier.hpp.
+(unset LANG; find . -type f -exec sed -i '' 's/ mpl_/ ndnboost_mpl_/g' {} +)
+ */
+#include <ndnboost/shared_ptr.hpp>
+#include <ndnboost/make_shared.hpp>
+namespace ndn { namespace ptr_lib = ndnboost; }
+
+// Use the boost header files in this distribution that were extracted as above:
+#include <ndnboost/function.hpp>
+#include <ndnboost/bind.hpp>
+namespace ndn { namespace func_lib = ndnboost; }
+
+#endif
+
+namespace ndn {
+
+/**
+ * A time interval represented as the number of milliseconds.
+ */
+typedef int64_t Milliseconds;
+   
+/**
+ * The calendar time represented as the number of milliseconds since 1/1/1970.
+ */
+typedef int64_t MillisecondsSince1970;
+
+/**
+ * Return the hex representation of the bytes in array.
+ * @param array The array of bytes.
+ * @return Hex string.
+ */
+std::string 
+toHex(const std::vector<uint8_t>& array);
+
+MillisecondsSince1970
+getNow();
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/data.hpp b/include/ndn-cpp-dev/data.hpp
new file mode 100644
index 0000000..e2d9451
--- /dev/null
+++ b/include/ndn-cpp-dev/data.hpp
@@ -0,0 +1,289 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_DATA_HPP
+#define NDN_DATA_HPP
+
+#include "common.hpp"
+#include "name.hpp"
+#include "encoding/block.hpp"
+
+#include "signature.hpp"
+#include "meta-info.hpp"
+#include "key-locator.hpp"
+
+namespace ndn {
+  
+class Data {
+public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+  
+  /**
+   * @brief Create an empty Data object
+   */
+  inline
+  Data();
+  
+  /**
+   * @brief Create a new Data object with the given name
+   * @param name A reference to the name which is copied.
+   */
+  inline
+  Data(const Name& name);
+  
+  /**
+   * @brief The virtual destructor.
+   */
+  inline virtual
+  ~Data();
+  
+  /**
+   * @brief Encode this Data for a wire format.
+   * @return The encoded byte array.
+   */
+  const Block& 
+  wireEncode() const;
+  
+  /**
+   * @brief Decode the input using a particular wire format and update this Data. 
+   * @param input The input byte array to be decoded.
+   */
+  void
+  wireDecode(const Block &wire);
+
+  inline const Name& 
+  getName() const;
+  
+  /**
+   * @brief Set name to a copy of the given Name.
+   *
+   * @param name The Name which is copied.
+   * @return This Data so that you can chain calls to update values.
+   */
+  inline void
+  setName(const Name& name);
+
+  inline const MetaInfo& 
+  getMetaInfo() const;
+  
+  /**
+   * @brief Set metaInfo to a copy of the given MetaInfo.
+   * @param metaInfo The MetaInfo which is copied.
+   * @return This Data so that you can chain calls to update values.
+   */
+  inline void
+  setMetaInfo(const MetaInfo& metaInfo);
+
+  ///////////////////////////////////////////////////////////////
+  // MetaInfo proxy methods
+  inline uint32_t 
+  getContentType() const;
+  
+  inline void 
+  setContentType(uint32_t type);
+  
+  inline Milliseconds 
+  getFreshnessPeriod() const;
+  
+  inline void 
+  setFreshnessPeriod(Milliseconds freshnessPeriod);
+  
+  /**
+   * @brief Get content Block
+   *
+   * To access content value, one can use value()/value_size() or
+   * value_begin()/value_end() methods of the Block class
+   */
+  inline const Block& 
+  getContent() const;
+
+  /**
+   * @brief Set the content to a copy of the data in the vector.
+   * @param content A vector whose contents are copied.
+   * @return This Data so that you can chain calls to update values.
+   */
+  inline void
+  setContent(const uint8_t* content, size_t contentLength);
+
+  inline void
+  setContent(const Block& content);
+
+  inline void
+  setContent(const ConstBufferPtr &contentValue);
+  
+  inline const Signature&
+  getSignature() const;
+  
+  /**
+   * @brief Set the signature to a copy of the given signature.
+   * @param signature The signature object which is cloned.
+   */
+  inline void
+  setSignature(const Signature& signature);
+
+  inline void
+  setSignatureValue(const Block &value);
+  
+private:
+  /**
+   * @brief Clear the wire encoding.
+   */
+  inline void 
+  onChanged();
+
+private:
+  Name name_;
+  MetaInfo metaInfo_;
+  mutable Block content_;
+  Signature signature_;
+
+  mutable Block wire_;
+};
+
+inline
+Data::Data()
+  : content_(Tlv::Content) // empty content
+{
+}
+
+inline
+Data::Data(const Name& name)
+  : name_(name)
+{
+}
+
+inline
+Data::~Data()
+{
+}
+
+inline const Name& 
+Data::getName() const
+{
+  return name_;
+}
+  
+inline void
+Data::setName(const Name& name)
+{ 
+  onChanged();
+  name_ = name; 
+}
+  
+inline const MetaInfo& 
+Data::getMetaInfo() const
+{
+  return metaInfo_;
+}
+  
+inline void
+Data::setMetaInfo(const MetaInfo& metaInfo) 
+{ 
+  onChanged();
+  metaInfo_ = metaInfo; 
+}
+
+inline uint32_t 
+Data::getContentType() const
+{
+  return metaInfo_.getType();
+}
+  
+inline void 
+Data::setContentType(uint32_t type)
+{
+  onChanged();
+  metaInfo_.setType(type);
+}
+  
+inline Milliseconds 
+Data::getFreshnessPeriod() const
+{
+  return metaInfo_.getFreshnessPeriod();
+}
+  
+inline void 
+Data::setFreshnessPeriod(Milliseconds freshnessPeriod)
+{
+  onChanged();
+  metaInfo_.setFreshnessPeriod(freshnessPeriod);
+}
+
+inline const Block& 
+Data::getContent() const
+{
+  if (!content_.hasWire())
+      content_.encode();
+  return content_;
+}
+
+inline void
+Data::setContent(const uint8_t* content, size_t contentLength) 
+{
+  onChanged();
+
+  content_ = dataBlock(Tlv::Content, content, contentLength);
+}
+
+inline void
+Data::setContent(const ConstBufferPtr &contentValue)
+{
+  onChanged();
+
+  content_ = Block(Tlv::Content, contentValue); // not real a wire encoding yet
+}
+  
+inline void
+Data::setContent(const Block& content) 
+{
+  onChanged();
+
+  if (content.type() == Tlv::Content)
+    content_ = content;
+  else {
+    content_ = Block(Tlv::Content, content);
+  }
+}
+
+inline const Signature&
+Data::getSignature() const
+{
+  return signature_;
+}
+  
+inline void
+Data::setSignature(const Signature& signature) 
+{
+  onChanged();
+  signature_ = signature;
+}
+
+inline void
+Data::setSignatureValue(const Block &value)
+{
+  onChanged();
+  signature_.setValue(value);
+}
+
+
+inline void 
+Data::onChanged()
+{
+  // The values have changed, so the wire format is invalidated
+
+  // !!!Note!!! Signature is not invalidated and it is responsibility of
+  // the application to do proper re-signing if necessary
+  
+  wire_.reset();
+}
+
+std::ostream&
+operator << (std::ostream &os, const Data &data);
+
+} // namespace ndn
+
+#endif
diff --git a/include/ndn-cpp-dev/encoding/binary-xml-wire-format.hpp b/include/ndn-cpp-dev/encoding/binary-xml-wire-format.hpp
new file mode 100644
index 0000000..cb4f0aa
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/binary-xml-wire-format.hpp
@@ -0,0 +1,88 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_BINARYXMLWIREFORMAT_HPP
+#define NDN_BINARYXMLWIREFORMAT_HPP
+
+#include "wire-format.hpp"
+
+namespace ndn {
+
+/**
+ * A BinaryXmlWireFormat extends WireFormat to override its virtual methods to implement encoding and decoding
+ * using binary XML.
+ */
+class BinaryXmlWireFormat : public WireFormat {
+public:
+  /**
+   * Encode interest in binary XML and return the encoding.
+   * @param interest The Interest object to encode.
+   * @return A Blob containing the encoding.
+   */  
+  virtual Blob 
+  encodeInterest(const Interest& interest);
+    
+  /**
+   * Decode input as an interest in binary XML and set the fields of the interest object.
+   * @param interest The Interest object whose fields are updated.
+   * @param input A pointer to the input buffer to decode.
+   * @param inputLength The number of bytes in input.
+   */
+  virtual void 
+  decodeInterest(Interest& interest, const uint8_t *input, size_t inputLength);
+
+  /**
+   * Encode data with binary XML and return the encoding.
+   * @param data The Data object to encode.
+   * @param signedPortionBeginOffset Return the offset in the encoding of the beginning of the signed portion.
+   * If you are not encoding in order to sign, you can call encodeData(const Data& data) to ignore this returned value.
+   * @param signedPortionEndOffset Return the offset in the encoding of the end of the signed portion.
+   * If you are not encoding in order to sign, you can call encodeData(const Data& data) to ignore this returned value.
+   * @return A Blob containing the encoding.
+   */
+  virtual Blob 
+  encodeData
+    (const Data& data, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset);
+  
+  /**
+   * Decode input as a data packet in binary XML and set the fields in the data object.
+   * @param data The Data object whose fields are updated.
+   * @param input A pointer to the input buffer to decode.
+   * @param inputLength The number of bytes in input.
+   * @param signedPortionBeginOffset Return the offset in the input buffer of the beginning of the signed portion.
+   * If you are not decoding in order to verify, you can call 
+   * decodeData(Data& data, const uint8_t *input, size_t inputLength) to ignore this returned value.
+   * @param signedPortionEndOffset Return the offset in the input buffer of the end of the signed portion.
+   * If you are not decoding in order to verify, you can call 
+   * decodeData(Data& data, const uint8_t *input, size_t inputLength) to ignore this returned value.
+   */  
+  virtual void 
+  decodeData
+    (Data& data, const uint8_t *input, size_t inputLength, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset);
+
+  /**
+   * Encode forwardingEntry in binary XML and return the encoding. 
+   * @param forwardingEntry The ForwardingEntry object to encode.
+   * @return A Blob containing the encoding.
+   */
+  virtual Blob 
+  encodeForwardingEntry(const ForwardingEntry& forwardingEntry);
+  
+  /**
+   * Decode input as a forwarding entry in binary XML and set the fields of the forwardingEntry object. 
+   * @param forwardingEntry The ForwardingEntry object whose fields are updated.
+   * @param input A pointer to the input buffer to decode.
+   * @param inputLength The number of bytes in input.
+   */
+  virtual void 
+  decodeForwardingEntry(ForwardingEntry& forwardingEntry, const uint8_t *input, size_t inputLength);
+};
+  
+}
+
+#endif
+
diff --git a/include/ndn-cpp-dev/encoding/block-helpers.hpp b/include/ndn-cpp-dev/encoding/block-helpers.hpp
new file mode 100644
index 0000000..c3ae196
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/block-helpers.hpp
@@ -0,0 +1,62 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_BLOCK_HELPERS_HPP
+#define NDN_BLOCK_HELPERS_HPP
+
+#include "block.hpp"
+
+namespace ndn {
+
+inline Block
+nonNegativeIntegerBlock(uint32_t type, uint64_t value)
+{
+  OBufferStream os;
+  Tlv::writeVarNumber(os, type);
+  Tlv::writeVarNumber(os, Tlv::sizeOfNonNegativeInteger(value));
+  Tlv::writeNonNegativeInteger(os, value);
+  return Block(os.buf());
+}
+
+inline uint64_t
+readNonNegativeInteger(const Block &block)
+{
+  Buffer::const_iterator begin = block.value_begin();
+  return Tlv::readNonNegativeInteger(block.value_size(), begin, block.value_end());
+}
+
+inline Block
+booleanBlock(uint32_t type)
+{
+  OBufferStream os;
+  Tlv::writeVarNumber(os, type);
+  Tlv::writeVarNumber(os, 0);
+  return Block(os.buf());
+}
+
+inline Block
+dataBlock(uint32_t type, const char *data, size_t dataSize)
+{
+  OBufferStream os;
+  Tlv::writeVarNumber(os, type);
+  Tlv::writeVarNumber(os, dataSize);
+  os.write(data, dataSize);
+
+  return Block(os.buf());
+}
+
+inline Block
+dataBlock(uint32_t type, const unsigned char *data, size_t dataSize)
+{
+  return dataBlock(type, reinterpret_cast<const char*>(data), dataSize);
+}
+
+} // namespace ndn
+
+#endif // NDN_BLOCK_HELPERS_HPP
diff --git a/include/ndn-cpp-dev/encoding/block.hpp b/include/ndn-cpp-dev/encoding/block.hpp
new file mode 100644
index 0000000..85cdaf5
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/block.hpp
@@ -0,0 +1,423 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_BLOCK_HPP
+#define NDN_BLOCK_HPP
+
+#include <ndn-cpp-dev/common.hpp>
+
+#include <list>
+#include <exception>
+
+#include "buffer.hpp"
+#include "tlv.hpp"
+
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+
+/**
+ * @brief Class representing wire element of the NDN packet
+ */
+class Block
+{
+public:
+  typedef std::list<Block>::iterator element_iterator;
+  typedef std::list<Block>::const_iterator element_const_iterator;
+
+  /// @brief Error that can be thrown from the block
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+  
+  /**
+   * @brief Default constructor to create an empty Block
+   */
+  Block();
+
+  /**
+   * @brief A helper version of a constructor to create Block from the raw buffer (type and value-length parsing)
+   */
+  Block(const ConstBufferPtr &buffer);
+
+  /**
+   * @brief A helper version of a constructor to create Block from the raw buffer (type and value-length parsing)
+   */
+  Block(const uint8_t *buffer, size_t maxlength);
+
+  Block(const void *buffer, size_t maxlength);
+  
+  /**
+   * @brief Create Block from the wire buffer (no parsing)
+   *
+   * This version of the constructor does not do any parsing
+   */
+  Block(const ConstBufferPtr &wire,
+        uint32_t type,
+        const Buffer::const_iterator &begin, Buffer::const_iterator &end,
+        const Buffer::const_iterator &valueBegin, Buffer::const_iterator &valueEnd);
+
+  /**
+   * @brief Create Block of a specific type with empty wire buffer
+   */
+  explicit
+  Block(uint32_t type);
+
+  /**
+   * @brief Create Block of a specific type with the specified value
+   *
+   * The underlying buffer hold only value, additional operations are needed
+   * to construct wire encoding, one need to prepend the wire buffer with type
+   * and value-length VAR-NUMBERs
+   */
+  Block(uint32_t type, const ConstBufferPtr &value);
+
+  /**
+   * @brief Create nested Block of a specific type with the specified value
+   *
+   * The underlying buffer hold only value, additional operations are needed
+   * to construct wire encoding, one need to prepend the wire buffer with type
+   * and value-length VAR-NUMBERs
+   */
+  explicit
+  Block(uint32_t type, const Block &value);
+  
+  /**
+   * @brief Check if the Block has fully encoded wire
+   */
+  inline bool
+  hasWire() const;
+
+  /**
+   * @brief Check if the Block has value block (no type and length are encoded)
+   */
+  inline bool
+  hasValue() const;
+  
+  /**
+   * @brief Reset wire buffer of the element
+   */
+  inline void
+  reset();
+
+  void
+  parse();
+
+  void
+  encode();
+  
+  inline uint32_t
+  type() const;
+
+  /**
+   * @brief Get the first subelement of the requested type
+   */
+  inline const Block &
+  get(uint32_t type) const;
+
+  inline Block &
+  get(uint32_t type);
+  
+  inline element_iterator
+  find(uint32_t type);
+
+  inline element_const_iterator
+  find(uint32_t type) const;
+
+  inline void
+  remove(uint32_t type);
+
+  inline element_iterator
+  erase(element_iterator position);
+
+  inline element_iterator
+  erase(element_iterator first, element_iterator last);
+  
+  inline void
+  push_back(const Block &element);
+  
+  /**
+   * @brief Get all subelements
+   */
+  inline const std::list<Block>&
+  getAll () const;
+
+  inline std::list<Block>&
+  getAll ();
+  
+  /**
+   * @brief Get all elements of the requested type
+   */
+  std::list<Block>
+  getAll(uint32_t type) const;
+
+  inline Buffer::const_iterator
+  begin() const;
+
+  inline Buffer::const_iterator
+  end() const;
+
+  inline size_t
+  size() const;
+
+  inline Buffer::const_iterator
+  value_begin() const;
+
+  inline Buffer::const_iterator
+  value_end() const;
+
+  inline const uint8_t*
+  wire() const;
+  
+  inline const uint8_t*
+  value() const;
+
+  inline size_t
+  value_size() const;
+
+protected:
+  ConstBufferPtr m_buffer;
+
+  uint32_t m_type;
+  
+  Buffer::const_iterator m_begin;
+  Buffer::const_iterator m_end;
+  uint32_t m_size;
+  
+  Buffer::const_iterator m_value_begin;
+  Buffer::const_iterator m_value_end;
+
+  std::list<Block> m_subBlocks;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+inline bool
+Block::hasWire() const
+{
+  return m_buffer && (m_begin != m_end);
+}
+
+inline bool
+Block::hasValue() const
+{
+  return static_cast<bool>(m_buffer);
+}
+
+inline void
+Block::reset()
+{
+  m_buffer.reset(); // reset of the shared_ptr
+  m_subBlocks.clear(); // remove all parsed subelements
+
+  m_type = std::numeric_limits<uint32_t>::max();
+  m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator(); // not really necessary, but for safety
+}
+
+inline uint32_t
+Block::type() const
+{
+  return m_type;
+}
+
+inline const Block &
+Block::get(uint32_t type) const
+{
+  for (element_const_iterator i = m_subBlocks.begin ();
+       i != m_subBlocks.end();
+       i++)
+    {
+      if (i->type () == type)
+        {
+          return *i;
+        }
+    }
+
+  throw Error("(Block::get) Requested a non-existed type [" + boost::lexical_cast<std::string>(type) + "] from Block");
+}
+
+inline Block &
+Block::get(uint32_t type)
+{
+  for (element_iterator i = m_subBlocks.begin ();
+       i != m_subBlocks.end();
+       i++)
+    {
+      if (i->type () == type)
+        {
+          return *i;
+        }
+    }
+
+  throw Error("(Block::get) Requested a non-existed type [" + boost::lexical_cast<std::string>(type) + "] from Block");
+}
+  
+inline Block::element_const_iterator
+Block::find(uint32_t type) const
+{
+  for (element_const_iterator i = m_subBlocks.begin ();
+       i != m_subBlocks.end();
+       i++)
+    {
+      if (i->type () == type)
+        {
+          return i;
+        }
+    }
+  return m_subBlocks.end();
+}
+
+inline Block::element_iterator
+Block::find(uint32_t type)
+{
+  for (element_iterator i = m_subBlocks.begin ();
+       i != m_subBlocks.end();
+       i++)
+    {
+      if (i->type () == type)
+        {
+          return i;
+        }
+    }
+  return m_subBlocks.end();
+}
+
+struct block_type
+{
+  block_type(uint32_t type)
+    : m_type(type)
+  {
+  }
+  
+  inline bool
+  operator()(const Block &block)
+  {
+    return (block.type() == m_type);
+  }
+private:
+  uint32_t m_type;
+};
+
+inline void
+Block::remove(uint32_t type)
+{
+  m_subBlocks.remove_if(block_type(type));
+}
+
+inline Block::element_iterator
+Block::erase(Block::element_iterator position)
+{
+  return m_subBlocks.erase(position);
+}
+
+inline Block::element_iterator
+Block::erase(Block::element_iterator first, Block::element_iterator last)
+{
+  return m_subBlocks.erase(first, last);
+}
+
+
+inline void
+Block::push_back(const Block &element)
+{
+  m_subBlocks.push_back(element);
+}
+
+
+inline const std::list<Block>&
+Block::getAll () const
+{
+  return m_subBlocks;
+}
+
+inline std::list<Block>&
+Block::getAll ()
+{
+  return m_subBlocks;
+}
+
+
+inline Buffer::const_iterator
+Block::begin() const
+{
+  if (!hasWire())
+      throw Error("Underlying wire buffer is empty");
+
+  return m_begin;
+}
+
+inline Buffer::const_iterator
+Block::end() const
+{
+  if (!hasWire())
+      throw Error("Underlying wire buffer is empty");
+
+  return m_end;
+}
+
+inline size_t
+Block::size() const
+{
+  if (hasWire() || hasValue()) {
+    return m_size;
+  }
+  else
+    throw Error("Block size cannot be determined (undefined block size)");
+}
+
+inline Buffer::const_iterator
+Block::value_begin() const
+{
+  if (!hasValue())
+      throw Error("(Block::value_begin) Underlying value buffer is empty");
+
+  return m_value_begin;
+}
+
+inline Buffer::const_iterator
+Block::value_end() const
+{
+  if (!hasValue())
+      throw Error("(Block::value_end) Underlying value buffer is empty");
+
+  return m_value_end;
+}
+
+inline const uint8_t*
+Block::wire() const
+{
+  if (!hasWire())
+      throw Error("(Block::wire) Underlying wire buffer is empty");
+
+  return &*m_begin;
+}
+
+inline const uint8_t*
+Block::value() const
+{
+  if (!hasValue())
+      throw Error("(Block::value) Underlying value buffer is empty");
+  
+  return &*m_value_begin;
+}
+
+inline size_t
+Block::value_size() const
+{
+  if (!hasValue())
+    throw Error("(Block::value_size) Underlying value buffer is empty");
+
+  return m_value_end - m_value_begin;
+}
+
+} // ndn
+
+#include "block-helpers.hpp"
+
+#endif // NDN_BLOCK_HPP
diff --git a/include/ndn-cpp-dev/encoding/buffer.hpp b/include/ndn-cpp-dev/encoding/buffer.hpp
new file mode 100644
index 0000000..368b445
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/buffer.hpp
@@ -0,0 +1,199 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_BUFFER_HPP
+#define NDN_BUFFER_HPP
+
+#include <ndn-cpp-dev/common.hpp>
+
+#include <boost/iostreams/detail/ios.hpp>
+#include <boost/iostreams/categories.hpp>
+#include <boost/iostreams/stream.hpp>
+
+#include <vector>
+
+namespace ndn {
+
+class Buffer;
+typedef ptr_lib::shared_ptr<const Buffer> ConstBufferPtr;
+typedef ptr_lib::shared_ptr<Buffer> BufferPtr;
+
+/**
+ * @brief Class representing a general-use automatically managed/resized buffer
+ *
+ * In most respect, Buffer class is equivalent to std::vector<uint8_t> and is in fact
+ * uses it as a base class.  In addition to that, it provides buf() and buf<T>() helper
+ * method for easier access to the underlying data (buf<T>() casts pointer to the requested class)
+ */
+class Buffer : public std::vector<uint8_t>
+{
+public:
+  /**
+   * @brief Creates an empty buffer
+   */
+  Buffer ()
+  {
+  }
+
+  /**
+   * @brief Create a buffer by copying the supplied data from a const buffer
+   * @param buf const pointer to buffer
+   * @param length length of the buffer to copy
+   */
+  Buffer (const void *buf, size_t length)
+    : std::vector<uint8_t> (reinterpret_cast<const uint8_t*> (buf), reinterpret_cast<const uint8_t*> (buf) + length)
+  {
+  }
+
+  /**
+   * @brief Create a buffer by copying the supplied data using iterator interface
+   *
+   * Note that the supplied iterators must be compatible with std::vector<uint8_t> interface
+   *
+   * @param first iterator to a first element to copy
+   * @param last  iterator to an element immediately following the last element to copy
+   */
+  template <class InputIterator>
+  Buffer (InputIterator first, InputIterator last)
+    : std::vector<uint8_t> (first, last)
+  {
+  }
+  
+  /**
+   * @brief Get pointer to the first byte of the buffer
+   */
+  inline uint8_t*
+  get ()
+  {
+    return &front ();
+  }
+
+  /**
+   * @brief Get pointer to the first byte of the buffer (alternative version)
+   */
+  inline uint8_t*
+  buf ()
+  {
+    return &front ();
+  }
+
+  /**
+   * @brief Get pointer to the first byte of the buffer and cast
+   * it (reinterpret_cast) to the requested type T
+   */
+  template<class T>
+  inline T*
+  get ()
+  {
+    return reinterpret_cast<T *>(&front ());
+  }
+
+  /**
+   * @brief Get pointer to the first byte of the buffer (alternative version)
+   */
+  inline const uint8_t*
+  buf () const
+  {
+    return &front ();
+  }
+
+  /**
+   * @brief Get const pointer to the first byte of the buffer
+   */
+  inline const uint8_t*
+  get () const
+  {
+    return &front ();
+  }
+
+  /**
+   * @brief Get const pointer to the first byte of the buffer and cast
+   * it (reinterpret_cast) to the requested type T
+   */
+  template<class T>
+  inline const T*
+  get () const
+  {
+    return reinterpret_cast<const T *>(&front ());
+  }  
+};
+
+/// @cond include_hidden
+namespace iostreams
+{
+
+class buffer_append_device {
+public:
+  typedef char  char_type;
+  typedef boost::iostreams::sink_tag       category;
+  
+  buffer_append_device (Buffer& container)
+  : m_container (container)
+  {
+  }
+  
+  std::streamsize
+  write(const char_type* s, std::streamsize n)
+  {
+    std::copy (s, s+n, std::back_inserter(m_container));
+    return n;
+  }
+  
+protected:
+  Buffer& m_container;
+};
+
+} // iostreams
+/// @endcond
+
+/**
+ * Class implementing interface similar to ostringstream, but to construct ndn::Buffer
+ *
+ * The benefit of using stream interface is that it provides automatic buffering of written data
+ * and eliminates (or reduces) overhead of resizing the underlying buffer when writing small pieces of data.
+ *
+ * Usage example:
+ * @code
+ *      OBufferStream obuf;
+ *      obuf.put(0);
+ *      obuf.write(another_buffer, another_buffer_size);
+ *      ptr_lib::shared_ptr<Buffer> buf = obuf.get();
+ * @endcode
+ */
+struct OBufferStream : public boost::iostreams::stream<iostreams::buffer_append_device>
+{
+  /**
+   * Default constructor
+   */
+  OBufferStream ()
+    : m_buffer (ptr_lib::make_shared<Buffer> ())
+    , m_device (*m_buffer)
+  {
+    open (m_device);
+  }
+
+  /**
+   * Flush written data to the stream and return shared pointer to the underlying buffer
+   */
+  ptr_lib::shared_ptr<Buffer>
+  buf ()
+  {
+    flush ();
+    return m_buffer;
+  }
+
+private:
+  BufferPtr m_buffer;
+  iostreams::buffer_append_device m_device;
+};
+
+
+} // ndn
+
+#endif // NDN_BUFFER_HPP
diff --git a/include/ndn-cpp-dev/encoding/element-listener.hpp b/include/ndn-cpp-dev/encoding/element-listener.hpp
new file mode 100644
index 0000000..7d13312
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/element-listener.hpp
@@ -0,0 +1,48 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_ELEMENT_LISTENER_HPP
+#define NDN_ELEMENT_LISTENER_HPP
+
+#include "../c/encoding/element-listener.h"
+
+namespace ndn {
+
+/**
+ * An ElementListener extends an ndn_ElementListener struct to proved an abstract virtual onReceivedElement function which wraps
+ * the onReceivedElement used by the ndn_ElementListener struct.  You must extend this class to override onReceivedElement.
+ */
+class ElementListener : public ndn_ElementListener {
+public:
+  ElementListener() 
+  {
+    ndn_ElementListener_initialize(this, staticOnReceivedElement);
+  }
+  
+  /**
+   * This is called when an entire binary XML element is received.  You must extend this class to override this method.
+   * @param element pointer to the binary XML element.  This buffer is only valid during this call.  If you need the data
+   * later, you must copy.
+   * @param elementLength length of element
+   */
+  virtual void 
+  onReceivedElement(const uint8_t *element, size_t elementLength) = 0;
+  
+private:
+  /**
+   * Call the virtual method onReceivedElement. This is used to initialize the base ndn_ElementListener struct.
+   * @param self
+   * @param element
+   * @param elementLength
+   */
+  static void 
+  staticOnReceivedElement(struct ndn_ElementListener *self, uint8_t *element, size_t elementLength);
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/encoding/endian.h b/include/ndn-cpp-dev/encoding/endian.h
new file mode 100644
index 0000000..9ea5c96
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/endian.h
@@ -0,0 +1,39 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Junxiao Shi <shijunxiao@email.arizona.edu>
+ */
+
+#ifdef __linux__
+
+#include <endian.h>
+
+#endif
+
+#ifdef __FreeBSD__
+
+#include <sys/endian.h>
+
+#endif
+
+#ifdef __APPLE__
+
+#include <libkern/OSByteOrder.h>
+#define htobe16(x) OSSwapHostToBigInt16(x)
+#define htole16(x) OSSwapHostToLittleInt16(x)
+#define be16toh(x) OSSwapBigToHostInt16(x)
+#define le16toh(x) OSSwapLittleToHostInt16(x)
+#define htobe32(x) OSSwapHostToBigInt32(x)
+#define htole32(x) OSSwapHostToLittleInt32(x)
+#define be32toh(x) OSSwapBigToHostInt32(x)
+#define le32toh(x) OSSwapLittleToHostInt32(x)
+#define htobe64(x) OSSwapHostToBigInt64(x)
+#define htole64(x) OSSwapHostToLittleInt64(x)
+#define be64toh(x) OSSwapBigToHostInt64(x)
+#define le64toh(x) OSSwapLittleToHostInt64(x)
+
+#endif
+
diff --git a/include/ndn-cpp-dev/encoding/oid.hpp b/include/ndn-cpp-dev/encoding/oid.hpp
new file mode 100644
index 0000000..e755c05
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/oid.hpp
@@ -0,0 +1,78 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_OID_HPP
+#define NDN_OID_HPP
+
+#include <vector>
+#include <string>
+
+namespace CryptoPP { class BufferedTransformation; }
+
+namespace ndn {
+
+class OID {
+public:
+  OID () 
+  {
+  }
+    
+  OID(const char *oid);
+
+  OID(const std::string& oid);
+
+  OID(const std::vector<int>& oid)
+  : oid_(oid)
+  {
+  }
+
+  const std::vector<int> &
+  getIntegerList() const
+  {
+    return oid_;
+  }
+
+  void
+  setIntegerList(const std::vector<int>& value){
+    oid_ = value;
+  }
+
+  std::string 
+  toString() const;
+
+  bool operator == (const OID& oid) const
+  {
+    return equal(oid);
+  }
+
+  bool operator != (const OID& oid) const
+  {
+    return !equal(oid);
+  }
+
+  void
+  encode(CryptoPP::BufferedTransformation &out) const;
+
+  void
+  decode(CryptoPP::BufferedTransformation &in);
+
+
+private:
+  void
+  construct(const std::string &value);
+  
+  bool
+  equal(const OID& oid) const;
+
+private:
+  std::vector<int> oid_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/encoding/tlv-face-management.hpp b/include/ndn-cpp-dev/encoding/tlv-face-management.hpp
new file mode 100644
index 0000000..86798df
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/tlv-face-management.hpp
@@ -0,0 +1,50 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_TLV_FACE_MANAGEMENT_HPP
+#define NDN_TLV_FACE_MANAGEMENT_HPP
+
+#include "tlv.hpp"
+
+namespace ndn {
+namespace Tlv {
+namespace FaceManagement {
+
+enum {
+  FaceInstance       = 128,
+  ForwardingEntry    = 129,
+  StatusResponse     = 130,
+  Action             = 131,
+  FaceID             = 132,
+  IPProto            = 133,
+  Host               = 134,
+  Port               = 135,
+  MulticastInterface = 136,
+  MulticastTTL       = 137,
+  ForwardingFlags    = 138,
+  StatusCode         = 139,
+  StatusText         = 140
+};
+
+enum {
+  FORW_ACTIVE         = 1,
+  FORW_CHILD_INHERIT  = 2,
+  FORW_ADVERTISE      = 4,
+  FORW_LAST           = 8,
+  FORW_CAPTURE       = 16,
+  FORW_LOCAL         = 32,
+  FORW_TAP           = 64,
+  FORW_CAPTURE_OK   = 128
+};
+
+} // namespace FaceManagement
+} // namespace Tlv
+} // namespace ndn
+
+#endif // NDN_TLV_FACE_MANAGEMENT_HPP
diff --git a/include/ndn-cpp-dev/encoding/tlv.hpp b/include/ndn-cpp-dev/encoding/tlv.hpp
new file mode 100644
index 0000000..dfa11fe
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/tlv.hpp
@@ -0,0 +1,327 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_TLV_HPP
+#define NDN_TLV_HPP
+
+#include <stdexcept>
+#include "buffer.hpp"
+#include "endian.h"
+
+namespace ndn {
+
+/**
+ * @brief Namespace defining NDN-TLV related constants and procedures
+ */
+namespace Tlv {
+
+struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+enum {
+  Interest      = 1,
+  Data          = 2,
+  Name          = 3,
+  NameComponent = 4,
+  Selectors     = 5,
+  Nonce         = 6,
+  Scope         = 7,
+  InterestLifetime          = 8,
+  MinSuffixComponents       = 9,
+  MaxSuffixComponents       = 10,
+  PublisherPublicKeyLocator = 11,
+  Exclude       = 12,
+  ChildSelector = 13,
+  MustBeFresh   = 14,
+  Any           = 15,
+  MetaInfo      = 16,
+  Content       = 17,
+  SignatureInfo = 18,
+  SignatureValue = 19,
+  ContentType   = 20,
+  FreshnessPeriod = 21,
+  SignatureType = 22,
+  KeyLocator    = 23,
+  KeyLocatorDigest = 24,
+
+  AppPrivateBlock1 = 128,
+  AppPrivateBlock2 = 32767
+};
+
+enum SignatureType {
+  DigestSha256 = 0,
+  SignatureSha256WithRsa = 1,
+};
+
+enum ConentType {
+  ContentType_Default = 0,
+  ContentType_Link = 1,
+  ContentType_Key = 2,
+};
+
+/**
+ * @brief Read VAR-NUMBER in NDN-TLV encoding
+ *
+ * This call will throw ndn::Tlv::Error (aka std::runtime_error) if number cannot be read
+ *
+ * Note that after call finished, begin will point to the first byte after the read VAR-NUMBER
+ */
+template<class InputIterator>
+inline uint64_t
+readVarNumber(InputIterator &begin, const InputIterator &end);
+
+/**
+ * @brief Read TLV Type
+ *
+ * This call is largely equivalent to tlv::readVarNumber, but exception will be thrown if type
+ * is larger than 2^32-1 (type in this library is implemented as uint32_t)
+ */
+template<class InputIterator>
+inline uint32_t
+readType(InputIterator &begin, const InputIterator &end);
+
+/**
+ * @brief Get number of bytes necessary to hold value of VAR-NUMBER
+ */
+inline size_t
+sizeOfVarNumber(uint64_t varNumber);
+
+/**
+ * @brief Write VAR-NUMBER to the specified stream
+ */
+inline size_t
+writeVarNumber(std::ostream &os, uint64_t varNumber);
+
+/**
+ * @brief Read nonNegativeInteger in NDN-TLV encoding
+ *
+ * This call will throw ndn::Tlv::Error (aka std::runtime_error) if number cannot be read
+ *
+ * Note that after call finished, begin will point to the first byte after the read VAR-NUMBER
+ *
+ * How many bytes will be read is directly controlled by the size parameter, which can be either
+ * 1, 2, 4, or 8.  If the value of size is different, then an exception will be thrown.
+ */
+template<class InputIterator>
+inline uint64_t
+readNonNegativeInteger(size_t size, InputIterator &begin, const InputIterator &end);
+
+/**
+ * @brief Get number of bytes necessary to hold value of nonNegativeInteger
+ */
+inline size_t
+sizeOfNonNegativeInteger(uint64_t varNumber);
+
+/**
+ * @brief Write nonNegativeInteger to the specified stream
+ */
+inline size_t
+writeNonNegativeInteger(std::ostream &os, uint64_t varNumber);
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+
+// Inline implementations
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+
+template<class InputIterator>
+inline uint64_t
+readVarNumber(InputIterator &begin, const InputIterator &end)
+{
+  if (begin == end)
+    throw Error("Empty buffer during TLV processing");
+  
+  uint8_t value = *begin;
+  ++begin;
+  if (value < 253)
+    {
+      return value;
+    }
+  else if (value == 253)
+    {
+      if (end - begin < 2)
+        throw Error("Insufficient data during TLV processing");
+      
+      uint16_t value = *reinterpret_cast<const uint16_t*>(&*begin); // kind of dangerous... but should be efficient
+      begin += 2;
+      return be16toh(value);
+    }
+  else if (value == 254)
+    {
+      if (end - begin < 4)
+        throw Error("Insufficient data during TLV processing");
+      
+      uint32_t value = *reinterpret_cast<const uint32_t*>(&*begin); // kind of dangerous... but should be efficient
+      begin += 4;
+      return be32toh(value);
+    }
+  else // if (value == 255)
+    {
+      if (end - begin < 8)
+        throw Error("Insufficient data during TLV processing");
+      
+      uint64_t value = *reinterpret_cast<const uint64_t*>(&*begin);
+      begin += 8;
+
+      return be64toh(value);
+    }
+}
+
+template<class InputIterator>
+inline uint32_t
+readType(InputIterator &begin, const InputIterator &end)
+{
+  uint64_t type   = readVarNumber(begin, end);
+  if (type > std::numeric_limits<uint32_t>::max())
+    {
+      throw Error("TLV type code exceeds allowed maximum");
+    }
+
+  return static_cast<uint32_t> (type);
+}
+
+size_t
+sizeOfVarNumber(uint64_t varNumber)
+{
+  if (varNumber < 253) {
+    return 1;
+  }
+  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
+    return 3;
+  }
+  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
+    return 5;
+  }
+  else {
+    return 9;
+  }
+}
+
+inline size_t
+writeVarNumber(std::ostream &os, uint64_t varNumber)
+{
+  if (varNumber < 253) {
+    os.put(static_cast<uint8_t> (varNumber));
+    return 1;
+  }
+  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
+    os.put(253);
+    uint16_t value = htobe16(static_cast<uint16_t> (varNumber));
+    os.write(reinterpret_cast<const char*> (&value), 2);
+    return 3;
+  }
+  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
+    os.put(254);
+    uint32_t value = htobe32(static_cast<uint32_t> (varNumber));
+    os.write(reinterpret_cast<const char*> (&value), 4);
+    return 5;
+  }
+  else {
+    os.put(255);
+    uint64_t value = htobe64(varNumber);
+    os.write(reinterpret_cast<const char*> (&value), 8);
+    return 9;
+  }
+}
+
+template<class InputIterator>
+inline uint64_t
+readNonNegativeInteger(size_t size, InputIterator &begin, const InputIterator &end)
+{
+  switch (size) {
+  case 1:
+    {
+      if (end - begin < 1)
+        throw Error("Insufficient data during TLV processing");
+      
+      uint8_t value = *begin;
+      begin++;
+      return value;
+    }
+  case 2:
+    {
+      if (end - begin < 2)
+        throw Error("Insufficient data during TLV processing");
+      
+      uint16_t value = *reinterpret_cast<const uint16_t*>(&*begin); // kind of dangerous... but should be efficient
+      begin += 2;
+      return be16toh(value);
+    }
+  case 4:
+    {
+      if (end - begin < 4)
+        throw Error("Insufficient data during TLV processing");
+      
+      uint32_t value = *reinterpret_cast<const uint32_t*>(&*begin); // kind of dangerous... but should be efficient
+      begin += 4;
+      return be32toh(value);
+    }
+  case 8:
+    {
+      if (end - begin < 8)
+        throw Error("Insufficient data during TLV processing");
+      
+      uint64_t value = *reinterpret_cast<const uint64_t*>(&*begin);
+      begin += 8;
+      return be64toh(value);
+    }
+  }
+  throw Error("Invalid length for nonNegativeInteger (only 1, 2, 4, and 8 are allowed)");
+}
+
+inline size_t
+sizeOfNonNegativeInteger(uint64_t varNumber)
+{
+  if (varNumber < 253) {
+    return 1;
+  }
+  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
+    return 2;
+  }
+  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
+    return 4;
+  }
+  else {
+    return 8;
+  }
+}
+
+
+inline size_t
+writeNonNegativeInteger(std::ostream &os, uint64_t varNumber)
+{
+  if (varNumber < 253) {
+    os.put(static_cast<uint8_t> (varNumber));
+    return 1;
+  }
+  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
+    uint16_t value = htobe16(static_cast<uint16_t> (varNumber));
+    os.write(reinterpret_cast<const char*> (&value), 2);
+    return 2;
+  }
+  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
+    uint32_t value = htobe32(static_cast<uint32_t> (varNumber));
+    os.write(reinterpret_cast<const char*> (&value), 4);
+    return 4;
+  }
+  else {
+    uint64_t value = htobe64(varNumber);
+    os.write(reinterpret_cast<const char*> (&value), 8);
+    return 8;
+  }
+}
+
+
+} // namespace tlv
+} // namespace ndn
+
+#endif // NDN_TLV_HPP
diff --git a/include/ndn-cpp-dev/encoding/wire-format.hpp b/include/ndn-cpp-dev/encoding/wire-format.hpp
new file mode 100644
index 0000000..1a40cd1
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/wire-format.hpp
@@ -0,0 +1,146 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_WIREFORMAT_HPP
+#define NDN_WIREFORMAT_HPP
+
+#include "../common.hpp"
+#include "../util/blob.hpp"
+
+namespace ndn {
+  
+class Interest;
+class Data;
+class ForwardingEntry;
+  
+class WireFormat {
+public:
+  /**
+   * Encode interest and return the encoding.  Your derived class should override.
+   * @param interest The Interest object to encode.
+   * @return A Blob containing the encoding.
+   * @throw logic_error for unimplemented if the derived class does not override.
+   */
+  virtual Blob 
+  encodeInterest(const Interest& interest);
+  
+  /**
+   * Decode input as an interest and set the fields of the interest object.  Your derived class should override.
+   * @param interest The Interest object whose fields are updated.
+   * @param input A pointer to the input buffer to decode.
+   * @param inputLength The number of bytes in input.
+   * @throw logic_error for unimplemented if the derived class does not override.
+   */
+  virtual void 
+  decodeInterest(Interest& interest, const uint8_t *input, size_t inputLength);
+
+  /**
+   * Encode data and return the encoding.  Your derived class should override.
+   * @param data The Data object to encode.
+   * @param signedPortionBeginOffset Return the offset in the encoding of the beginning of the signed portion.
+   * If you are not encoding in order to sign, you can call encodeData(const Data& data) to ignore this returned value.
+   * @param signedPortionEndOffset Return the offset in the encoding of the end of the signed portion.
+   * If you are not encoding in order to sign, you can call encodeData(const Data& data) to ignore this returned value.
+   * @return A Blob containing the encoding.
+   * @throw logic_error for unimplemented if the derived class does not override.
+   */
+  virtual Blob 
+  encodeData
+    (const Data& data, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset);
+
+  /**
+   * Encode data and return the encoding.
+   * @param data The Data object to encode.
+   * @return A Blob containing the encoding.
+   * @throw logic_error for unimplemented if the derived class does not override.
+   */
+  Blob 
+  encodeData(const Data& data)
+  {
+    size_t dummyBeginOffset, dummyEndOffset;
+    return encodeData(data, &dummyBeginOffset, &dummyEndOffset);
+  }
+
+  /**
+   * Decode input as a data packet and set the fields in the data object.  Your derived class should override.
+   * @param data The Data object whose fields are updated.
+   * @param input A pointer to the input buffer to decode.
+   * @param inputLength The number of bytes in input.
+   * @param signedPortionBeginOffset Return the offset in the input buffer of the beginning of the signed portion.
+   * If you are not decoding in order to verify, you can call 
+   * decodeData(Data& data, const uint8_t *input, size_t inputLength) to ignore this returned value.
+   * @param signedPortionEndOffset Return the offset in the input buffer of the end of the signed portion.
+   * If you are not decoding in order to verify, you can call 
+   * decodeData(Data& data, const uint8_t *input, size_t inputLength) to ignore this returned value.
+   * @throw logic_error for unimplemented if the derived class does not override.
+   */  
+  virtual void 
+  decodeData
+    (Data& data, const uint8_t *input, size_t inputLength, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset);
+
+  void 
+  decodeData(Data& data, const uint8_t *input, size_t inputLength)
+  {
+    size_t dummyBeginOffset, dummyEndOffset;
+    decodeData(data, input, inputLength, &dummyBeginOffset, &dummyEndOffset);
+  }
+  
+  /**
+   * Encode forwardingEntry and return the encoding.  Your derived class should override.
+   * @param forwardingEntry The ForwardingEntry object to encode.
+   * @return A Blob containing the encoding.
+   * @throw logic_error for unimplemented if the derived class does not override.
+   */
+  virtual Blob 
+  encodeForwardingEntry(const ForwardingEntry& forwardingEntry);
+  
+  /**
+   * Decode input as a forwarding entry and set the fields of the forwardingEntry object.  Your derived class should override.
+   * @param forwardingEntry The ForwardingEntry object whose fields are updated.
+   * @param input A pointer to the input buffer to decode.
+   * @param inputLength The number of bytes in input.
+   * @throw logic_error for unimplemented if the derived class does not override.
+   */
+  virtual void 
+  decodeForwardingEntry(ForwardingEntry& forwardingEntry, const uint8_t *input, size_t inputLength);
+
+  /**
+   * Set the static default WireFormat used by default encoding and decoding methods.
+   * @param wireFormat A Pointer to an object of a subclass of WireFormat.  This does not make a copy and
+   * the caller must ensure that the object remains allocated.
+   */
+  static void 
+  setDefaultWireFormat(WireFormat *wireFormat) 
+  {
+    defaultWireFormat_ = wireFormat;
+  }
+  
+  /**
+   * Return the default WireFormat used by default encoding and decoding methods which was set with
+   * setDefaultWireFormat.
+   * @return A pointer to the WireFormat object.
+   */
+  static WireFormat*
+  getDefaultWireFormat();
+  
+private:
+  /**
+   * This is implemented by only one of the subclasses of WireFormat to return a new object used
+   * as the initial value for the default WireFormat.  If the application doesn't include that class, then the application
+   * needs to include another subclass which defines WireFormat::newInitialDefaultWireFormat.
+   * @return a new object, which is held by a shared_ptr and freed when the application exits.
+   */
+  static WireFormat*
+  newInitialDefaultWireFormat();
+  
+  static WireFormat *defaultWireFormat_;
+};
+
+}
+
+#endif
+
diff --git a/include/ndn-cpp-dev/exclude.hpp b/include/ndn-cpp-dev/exclude.hpp
new file mode 100644
index 0000000..e26ec31
--- /dev/null
+++ b/include/ndn-cpp-dev/exclude.hpp
@@ -0,0 +1,233 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_EXCLUDE_H
+#define NDN_EXCLUDE_H
+
+#include "name.hpp"
+
+#include <map>
+
+namespace ndn {
+
+/**
+ * @brief Class to represent Exclude component in NDN interests
+ */
+class Exclude
+{
+public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+  
+  typedef std::map< Name::Component, bool /*any*/, std::greater<Name::Component> > exclude_type;
+
+  typedef exclude_type::iterator iterator;
+  typedef exclude_type::const_iterator const_iterator;
+  typedef exclude_type::reverse_iterator reverse_iterator;
+  typedef exclude_type::const_reverse_iterator const_reverse_iterator;
+
+  /**
+   * @brief Default constructor an empty exclude
+   */
+  Exclude ();
+
+  /**
+   * @brief Check if name component is excluded
+   * @param comp Name component to check against exclude filter
+   */
+  bool
+  isExcluded (const Name::Component &comp) const;
+
+  /**
+   * @brief Exclude specific name component
+   * @param comp component to exclude
+   * @returns *this to allow chaining
+   */
+  Exclude &
+  excludeOne (const Name::Component &comp);
+
+  /**
+   * @brief Exclude components from range [from, to]
+   * @param from first element of the range
+   * @param to last element of the range
+   * @returns *this to allow chaining
+   */
+  Exclude &
+  excludeRange (const Name::Component &from, const Name::Component &to);
+
+  /**
+   * @brief Exclude all components from range [/, to]
+   * @param to last element of the range
+   * @returns *this to allow chaining
+   */
+  inline Exclude &
+  excludeBefore (const Name::Component &to);
+
+  /**
+   * @brief Exclude all components from range [from, +Inf]
+   * @param to last element of the range
+   * @returns *this to allow chaining
+   */
+  Exclude &
+  excludeAfter (const Name::Component &from);
+
+  /**
+   * @brief Method to directly append exclude element
+   * @param name excluded name component
+   * @param any  flag indicating if there is a postfix ANY component after the name
+   *
+   * This method is used during conversion from wire format of exclude filter
+   *
+   * If there is an error with ranges (e.g., order of components is wrong) an exception is thrown
+   */
+  inline void
+  appendExclude (const Name::Component &name, bool any);
+
+  /**
+   * @brief Check if exclude filter is empty
+   */
+  inline bool
+  empty () const;
+
+  /**
+   * @brief Clear the exclude filter
+   */
+  inline void
+  clear();
+  
+  /**
+   * @brief Get number of exclude terms
+   */
+  inline size_t
+  size () const;
+
+  /**
+   * @brief Get begin iterator of the exclude terms
+   */
+  inline const_iterator
+  begin () const;
+
+  /**
+   * @brief Get end iterator of the exclude terms
+   */
+  inline const_iterator
+  end () const;
+
+  /**
+   * @brief Get begin iterator of the exclude terms
+   */
+  inline const_reverse_iterator
+  rbegin () const;
+
+  /**
+   * @brief Get end iterator of the exclude terms
+   */
+  inline const_reverse_iterator
+  rend () const;
+
+  /**
+   * @brief Get escaped string representation (e.g., for use in URI) of the exclude filter
+   */
+  inline std::string
+  toUri () const;
+
+  /**
+   * Encode this Interest for a particular wire format.
+   * @return The encoded byte array.
+   */
+  const Block&
+  wireEncode() const;
+  
+  /**
+   * Decode the input using a particular wire format and update this Interest.
+   * @param input The input byte array to be decoded.
+   */
+  void 
+  wireDecode(const Block &wire);
+  
+private:
+  Exclude &
+  excludeRange (iterator fromLowerBound, iterator toLowerBound);
+
+private:
+  exclude_type m_exclude;
+
+  mutable Block wire_;
+};
+
+std::ostream&
+operator << (std::ostream &os, const Exclude &name);
+
+inline Exclude &
+Exclude::excludeBefore (const Name::Component &to)
+{
+  return excludeRange (Name::Component (), to);
+}
+
+inline void
+Exclude::appendExclude (const Name::Component &name, bool any)
+{
+  m_exclude[name] = any;
+}
+
+inline bool
+Exclude::empty () const
+{
+  return m_exclude.empty ();
+}
+
+inline void
+Exclude::clear ()
+{
+  m_exclude.clear ();
+}
+
+
+inline size_t
+Exclude::size () const
+{
+  return m_exclude.size ();
+}
+
+inline Exclude::const_iterator
+Exclude::begin () const
+{
+  return m_exclude.begin ();
+}
+
+inline Exclude::const_iterator
+Exclude::end () const
+{
+  return m_exclude.end ();
+}
+
+inline Exclude::const_reverse_iterator
+Exclude::rbegin () const
+{
+  return m_exclude.rbegin ();
+}
+
+inline Exclude::const_reverse_iterator
+Exclude::rend () const
+{
+  return m_exclude.rend ();
+}
+
+inline std::string
+Exclude::toUri () const
+{
+  std::ostringstream os;
+  os << *this;
+  return os.str();
+}
+
+} // ndn
+
+#endif // NDN_EXCLUDE_H
diff --git a/include/ndn-cpp-dev/face-instance.hpp b/include/ndn-cpp-dev/face-instance.hpp
new file mode 100644
index 0000000..74feee1
--- /dev/null
+++ b/include/ndn-cpp-dev/face-instance.hpp
@@ -0,0 +1,344 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_FACE_INSTANCE_HPP
+#define NDN_FACE_INSTANCE_HPP
+
+#include "encoding/tlv-face-management.hpp"
+#include "name.hpp"
+#include "encoding/block.hpp"
+
+namespace ndn {
+
+/**
+ * An FaceInstance holds an action and  Name prefix and other fields for an forwarding entry.
+ */
+class FaceInstance {
+public:    
+  FaceInstance(const std::string &action,
+               int64_t     faceId,
+               uint32_t    ipProto,
+               const std::string &host,
+               const std::string &port,
+               const std::string &multicastInterface,
+               uint32_t    multicastTtl,
+               Milliseconds freshnessPeriod) 
+    : action_(action)
+    , faceId_(faceId)
+    , ipProto_(ipProto)
+    , host_(host)
+    , port_(port)
+    , multicastInterface_(multicastInterface)
+    , multicastTtl_(multicastTtl)
+    , freshnessPeriod_(freshnessPeriod)
+  {
+  }
+
+  FaceInstance()
+    : faceId_(-1)
+    , ipProto_(-1)
+    , multicastTtl_(-1)
+    , freshnessPeriod_(-1)
+  {
+  }
+
+  // Action
+  const std::string& 
+  getAction() const { return action_; }
+
+  void 
+  setAction(const std::string& action) { action_ = action; wire_.reset(); }
+
+  // FaceID
+  int64_t
+  getFaceId() const { return faceId_; }
+
+  void 
+  setFaceId(int64_t faceId) { faceId_ = faceId; wire_.reset(); }
+
+  // IPProto
+  int32_t 
+  getIpProto() const { return ipProto_; }
+
+  void 
+  setIpProto(int32_t ipProto) { ipProto_ = ipProto; wire_.reset(); }
+
+  // Host
+  const std::string& 
+  getHost() const { return host_; }
+
+  void 
+  setHost(const std::string& host) { host_ = host; wire_.reset(); }
+
+  // Port
+  const std::string&
+  getPort() const { return port_; }
+
+  void 
+  setPort(const std::string &port) { port_ = port; wire_.reset(); }
+
+  // MulticastInterface
+  const std::string& 
+  getMulticastInterface() const { return multicastInterface_; }
+
+  void 
+  setMulticastInterface(const std::string& multicastInterface) { multicastInterface_ = multicastInterface; wire_.reset(); }
+
+  // MulticastTTL
+  int32_t
+  getMulticastTtl() const { return multicastTtl_; }
+
+  void 
+  setMulticastTtl(int32_t multicastTtl) { multicastTtl_ = multicastTtl; wire_.reset(); }
+
+  // Freshness
+  int 
+  getFreshnessPeriod() const { return freshnessPeriod_; }
+
+  void 
+  setFreshnessPeriod(int freshnessPeriod) { freshnessPeriod_ = freshnessPeriod; wire_.reset(); }
+
+  // Wire
+  inline const Block&
+  wireEncode() const;
+  
+  inline void 
+  wireDecode(const Block &wire);
+  
+private:
+  std::string action_;
+  int64_t     faceId_;
+  int32_t     ipProto_;
+  std::string host_;
+  std::string port_;
+  std::string multicastInterface_;
+  int32_t     multicastTtl_;
+  Milliseconds freshnessPeriod_;
+  
+  mutable Block wire_;
+};
+
+inline const Block&
+FaceInstance::wireEncode() const
+{
+  if (wire_.hasWire())
+    return wire_;
+
+  // FaceInstance ::= FACE-INSTANCE-TYPE TLV-LENGTH
+  //                  Action?
+  //                  FaceID?
+  //                  IPProto?
+  //                  Host?
+  //                  Port?
+  //                  MulticastInterface?
+  //                  MulticastTTL?
+  //                  FreshnessPeriod?
+  
+  wire_ = Block(Tlv::FaceManagement::FaceInstance);
+
+  // Action
+  if (!action_.empty())
+    {
+      wire_.push_back
+        (dataBlock(Tlv::FaceManagement::Action, action_.c_str(), action_.size()));
+    }
+
+  // FaceID
+  if (faceId_ >= 0)
+    {
+      wire_.push_back
+        (nonNegativeIntegerBlock(Tlv::FaceManagement::FaceID, faceId_));
+    }
+
+  // IPProto
+  if (ipProto_ >= 0)
+    {
+      wire_.push_back
+        (nonNegativeIntegerBlock(Tlv::FaceManagement::IPProto, ipProto_));
+    }
+  
+  // Host
+  if (!host_.empty())
+    {
+      wire_.push_back
+        (dataBlock(Tlv::FaceManagement::Host, host_.c_str(), host_.size()));
+    }
+
+  // Port
+  if (!port_.empty())
+    {
+      wire_.push_back
+        (dataBlock(Tlv::FaceManagement::Port, port_.c_str(), port_.size()));
+    }
+
+  // MulticastInterface
+  if (!multicastInterface_.empty())
+    {
+      wire_.push_back
+        (dataBlock(Tlv::FaceManagement::MulticastInterface, multicastInterface_.c_str(), multicastInterface_.size()));
+    }
+
+  // MulticastTTL
+  if (multicastTtl_ >= 0)
+    {
+      wire_.push_back
+        (nonNegativeIntegerBlock(Tlv::FaceManagement::MulticastTTL, multicastTtl_));
+    }
+
+  // FreshnessPeriod
+  if (freshnessPeriod_ >= 0)
+    {
+      wire_.push_back
+        (nonNegativeIntegerBlock(Tlv::FreshnessPeriod, freshnessPeriod_));
+    }
+  
+  wire_.encode();
+  return wire_;    
+}
+  
+inline void 
+FaceInstance::wireDecode(const Block &wire)
+{
+  action_.clear();
+  faceId_ = -1;
+  ipProto_ = -1;
+  host_.clear();
+  port_.clear();
+  multicastInterface_.clear();
+  multicastTtl_ = -1;
+  freshnessPeriod_ = -1;
+
+  wire_ = wire;
+  wire_.parse();
+
+  // FaceInstance ::= FACE-INSTANCE-TYPE TLV-LENGTH
+  //                  Action?
+  //                  FaceID?
+  //                  IPProto?
+  //                  Host?
+  //                  Port?
+  //                  MulticastInterface?
+  //                  MulticastTTL?
+  //                  FreshnessPeriod?
+
+  // Action
+  Block::element_iterator val = wire_.find(Tlv::FaceManagement::Action);
+  if (val != wire_.getAll().end())
+    {
+      action_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
+    }
+
+  // FaceID
+  val = wire_.find(Tlv::FaceManagement::FaceID);
+  if (val != wire_.getAll().end())
+    {
+      faceId_ = readNonNegativeInteger(*val);
+    }
+
+  // IPProto
+  val = wire_.find(Tlv::FaceManagement::IPProto);
+  if (val != wire_.getAll().end())
+    {
+      ipProto_ = readNonNegativeInteger(*val);
+    }
+
+  // Host
+  val = wire_.find(Tlv::FaceManagement::Host);
+  if (val != wire_.getAll().end())
+    {
+      host_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
+    }
+
+  // Port
+  val = wire_.find(Tlv::FaceManagement::Port);
+  if (val != wire_.getAll().end())
+    {
+      port_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
+    }
+
+  // MulticastInterface
+  val = wire_.find(Tlv::FaceManagement::MulticastInterface);
+  if (val != wire_.getAll().end())
+    {
+      multicastInterface_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
+    }
+
+  // MulticastTTL
+  val = wire_.find(Tlv::FaceManagement::MulticastTTL);
+  if (val != wire_.getAll().end())
+    {
+      multicastTtl_ = readNonNegativeInteger(*val);
+    }
+
+  // FreshnessPeriod
+  val = wire_.find(Tlv::FreshnessPeriod);
+  if (val != wire_.getAll().end())
+    {
+      freshnessPeriod_ = readNonNegativeInteger(*val);
+    }
+}
+
+inline std::ostream&
+operator << (std::ostream &os, const FaceInstance &entry)
+{
+  os << "FaceInstance(";
+  
+  // Action
+  if (!entry.getAction().empty())
+    {
+      os << "Action:" << entry.getAction() << ", ";
+    }
+
+  // FaceID
+  if (entry.getFaceId() >= 0)
+    {
+      os << "FaceID:" << entry.getFaceId() << ", ";
+    }
+
+  // IPProto
+  if (entry.getIpProto() >= 0)
+    {
+      os << "IPProto:" << entry.getIpProto() << ", ";
+    }
+
+  // Host
+  if (!entry.getHost().empty())
+    {
+      os << "Host:" << entry.getHost() << ", ";
+    }
+
+  // Port
+  if (!entry.getPort().empty())
+    {
+      os << "Port:" << entry.getPort() << ", ";
+    }
+
+  // MulticastInterface
+  if (!entry.getMulticastInterface().empty())
+    {
+      os << "MulticastInterface:" << entry.getMulticastInterface() << ", ";
+    }
+
+  // MulticastTTL
+  if (entry.getMulticastTtl() >= 0)
+    {
+      os << "MulticastTTL:" << entry.getMulticastTtl() << ", ";
+    }
+
+  // FreshnessPeriod
+  if (entry.getFreshnessPeriod() >= 0)
+    {
+      os << "FreshnessPeriod:" << entry.getFreshnessPeriod() << ", ";
+    }
+
+  os << ")";
+  return os;
+}
+
+}
+
+#endif // FACE_INSTANCE
diff --git a/include/ndn-cpp-dev/face.hpp b/include/ndn-cpp-dev/face.hpp
new file mode 100644
index 0000000..e006458
--- /dev/null
+++ b/include/ndn-cpp-dev/face.hpp
@@ -0,0 +1,193 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_FACE_HPP
+#define NDN_FACE_HPP
+
+#include "node.hpp"
+#include "transport/transport.hpp"
+#include "transport/unix-transport.hpp"
+
+namespace ndn {
+
+/**
+ * The Face class provides the main methods for NDN communication.
+ */
+class Face {
+public:
+  /**
+   * Create a new Face for communication with an NDN hub at host:port using the default TcpTransport.
+   * @param host The host of the NDN hub.
+   * @param port The port of the NDN hub. If omitted. use 6363.
+   */
+  Face()
+  : node_(ptr_lib::shared_ptr<UnixTransport>(new UnixTransport()))
+  {
+  }
+
+  /**
+   * Create a new Face for communication with an NDN hub with the given Transport object and connectionInfo.
+   * @param transport A shared_ptr to a Transport object used for communication.
+   * @param transport A shared_ptr to a Transport::ConnectionInfo to be used to connect to the transport.
+   */
+  Face(const ptr_lib::shared_ptr<Transport>& transport)
+  : node_(transport)
+  {
+  }
+  
+  /**
+   * Create a new Face for communication with an NDN hub at host:port using the default TcpTransport.
+   * @param host The host of the NDN hub.
+   * @param port The port of the NDN hub. If omitted. use 6363.
+   */
+  // Face(const char *host, unsigned short port = 6363)
+  // : node_(ptr_lib::shared_ptr<TcpTransport>(new TcpTransport(host, port)))
+  // {
+  // }
+    
+  /**
+   * Send the Interest through the transport, read the entire response and call onData(interest, data).
+   * @param interest A reference to the Interest.  This copies the Interest.
+   * @param onData A function object to call when a matching data packet is received.  This copies the function object, so you may need to
+   * use func_lib::ref() as appropriate.
+   * @param onTimeout A function object to call if the interest times out.  If onTimeout is an empty OnTimeout(), this does not use it.
+   * This copies the function object, so you may need to use func_lib::ref() as appropriate.
+   * @param wireFormat A WireFormat object used to encode the message. If omitted, use WireFormat getDefaultWireFormat().
+   * @return The pending interest ID which can be used with removePendingInterest.
+   */
+  uint64_t 
+  expressInterest
+    (const Interest& interest, const OnData& onData, const OnTimeout& onTimeout = OnTimeout())
+  {
+    return node_.expressInterest(interest, onData, onTimeout);
+  }
+
+  /**
+   * Encode name as an Interest. If interestTemplate is not 0, use its interest selectors.
+   * Send the interest through the transport, read the entire response and call onData(interest, data).
+   * @param name A reference to a Name for the interest.  This copies the Name.
+   * @param interestTemplate if not 0, copy interest selectors from the template.   This does not keep a pointer to the Interest object.
+   * @param onData A function object to call when a matching data packet is received.  This copies the function object, so you may need to
+   * use func_lib::ref() as appropriate.
+   * @param onTimeout A function object to call if the interest times out.  If onTimeout is an empty OnTimeout(), this does not use it.
+   * This copies the function object, so you may need to use func_lib::ref() as appropriate.
+   * @param wireFormat A WireFormat object used to encode the message. If omitted, use WireFormat getDefaultWireFormat().
+   * @return The pending interest ID which can be used with removePendingInterest.
+   */
+  uint64_t 
+  expressInterest
+    (const Name& name, const Interest *interestTemplate, const OnData& onData, const OnTimeout& onTimeout = OnTimeout());
+
+  /**
+   * Encode name as an Interest, using a default interest lifetime.
+   * Send the interest through the transport, read the entire response and call onData(interest, data).
+   * @param name A reference to a Name for the interest.  This copies the Name.
+   * @param onData A function object to call when a matching data packet is received.  This copies the function object, so you may need to
+   * use func_lib::ref() as appropriate.
+   * @param onTimeout A function object to call if the interest times out.  If onTimeout is an empty OnTimeout(), this does not use it.
+   * This copies the function object, so you may need to use func_lib::ref() as appropriate.
+   * @param wireFormat A WireFormat object used to encode the message. If omitted, use WireFormat getDefaultWireFormat().
+   * @return The pending interest ID which can be used with removePendingInterest.
+   */
+  uint64_t 
+  expressInterest
+    (const Name& name, const OnData& onData, const OnTimeout& onTimeout = OnTimeout()) 
+  {
+    return expressInterest(name, 0, onData, onTimeout);
+  }
+
+  /**
+   * Remove the pending interest entry with the pendingInterestId from the pending interest table.
+   * This does not affect another pending interest with a different pendingInterestId, even it if has the same interest name.
+   * If there is no entry with the pendingInterestId, do nothing.
+   * @param pendingInterestId The ID returned from expressInterest.
+   */
+  void
+  removePendingInterest(uint64_t pendingInterestId)
+  {
+    node_.removePendingInterest(pendingInterestId);
+  }
+  
+  /**
+   * Register prefix with the connected NDN hub and call onInterest when a matching interest is received.
+   * @param prefix A reference to a Name for the prefix to register.  This copies the Name.
+   * @param onInterest A function object to call when a matching interest is received.  This copies the function object, so you may need to
+   * use func_lib::ref() as appropriate.
+   * @param onRegisterFailed A function object to call if failed to retrieve the connected hub’s ID or failed to register the prefix.
+   * This calls onRegisterFailed(prefix) where prefix is the prefix given to registerPrefix.
+   * @param flags The flags for finer control of which interests are forward to the application.  If omitted, use 
+   * the default flags defined by the default ForwardingFlags constructor.
+   * @param wireFormat A WireFormat object used to encode the message. If omitted, use WireFormat getDefaultWireFormat().
+   * @return The registered prefix ID which can be used with removeRegisteredPrefix.
+   */
+  uint64_t 
+  setInterestFilter
+    (const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags = ForwardingFlags())
+  {
+    return node_.registerPrefix(prefix, onInterest, onRegisterFailed, flags);
+  }
+
+  /**
+   * Remove the registered prefix entry with the registeredPrefixId from the pending interest table.  
+   * This does not affect another registered prefix with a different registeredPrefixId, even it if has the same prefix name.
+   * If there is no entry with the registeredPrefixId, do nothing.
+   * @param registeredPrefixId The ID returned from registerPrefix.
+   */
+  void
+  unsetInterestFilter(uint64_t registeredPrefixId)
+  {
+    node_.removeRegisteredPrefix(registeredPrefixId);
+  }
+
+  /**
+   * @brief Publish data packet
+   *
+   * This method can be called to satisfy the incoming Interest or to put Data packet into the cache
+   * of the local NDN forwarder
+   */
+  void
+  put(const Data &data)
+  {
+    node_.put(data);
+  }
+  
+  /**
+   * Process any data to receive or call timeout callbacks.
+   *
+   * This call will block forever (default timeout == 0) to process IO on the face.
+   * To exit, one expected to call face.shutdown() from one of the callback methods.
+   *
+   * If positive timeout is specified, then processEvents will exit after this timeout,
+   * if not stopped earlier with face.shutdown() or when all active events finish.
+   * The call can be called repeatedly, if desired.
+   *
+   * If negative timeout is specified, then processEvents will not block and process only pending
+   * events.
+   *
+   * @throw This may throw an exception for reading data or in the callback for processing the data.  If you
+   * call this from an main event loop, you may want to catch and log/disregard all exceptions.
+   */
+  void 
+  processEvents(Milliseconds timeout = 0, bool keepThread = false)
+  {
+    // Just call Node's processEvents.
+    node_.processEvents(timeout, keepThread);
+  }
+
+  /**
+   * Shut down and disconnect this Face.
+   */
+  void 
+  shutdown();
+  
+private:
+  Node node_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/forwarding-entry.hpp b/include/ndn-cpp-dev/forwarding-entry.hpp
new file mode 100644
index 0000000..182dc38
--- /dev/null
+++ b/include/ndn-cpp-dev/forwarding-entry.hpp
@@ -0,0 +1,226 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_FORWARDING_ENTRY_HPP
+#define NDN_FORWARDING_ENTRY_HPP
+
+#include "encoding/tlv-face-management.hpp"
+#include "name.hpp"
+#include "forwarding-flags.hpp"
+#include "encoding/block.hpp"
+
+namespace ndn {
+
+/**
+ * An ForwardingEntry holds an action and  Name prefix and other fields for an forwarding entry.
+ */
+class ForwardingEntry {
+public:    
+  ForwardingEntry(const std::string& action,
+                  const Name& prefix,
+                  int faceId = -1,
+                  const ForwardingFlags& forwardingFlags = ForwardingFlags(),
+                  int freshnessPeriod = -1) 
+    : action_(action)
+    , prefix_(prefix)
+    , faceId_(faceId)
+    , forwardingFlags_(forwardingFlags)
+    , freshnessPeriod_(freshnessPeriod)
+  {
+  }
+
+  ForwardingEntry()
+  : faceId_(-1)
+  , freshnessPeriod_(-1)
+  {
+  }
+  
+  const std::string& 
+  getAction() const { return action_; }
+
+  void 
+  setAction(const std::string& action) { action_ = action; wire_.reset(); }
+    
+  const Name& 
+  getPrefix() const { return prefix_; }
+  
+  void
+  setPrefix(const Name &prefix) { prefix_ = prefix; wire_.reset(); }
+  
+  int 
+  getFaceId() const { return faceId_; }
+
+  void 
+  setFaceId(int faceId) { faceId_ = faceId; wire_.reset(); }
+      
+  const ForwardingFlags& 
+  getForwardingFlags() const { return forwardingFlags_; }
+
+  void 
+  setForwardingFlags(const ForwardingFlags& forwardingFlags) { forwardingFlags_ = forwardingFlags; wire_.reset(); }
+      
+  int 
+  getFreshnessPeriod() const { return freshnessPeriod_; }
+
+  void 
+  setFreshnessPeriod(int freshnessPeriod) { freshnessPeriod_ = freshnessPeriod; wire_.reset(); }
+
+  inline const Block&
+  wireEncode() const;
+  
+  inline void 
+  wireDecode(const Block &wire);
+  
+private:
+  std::string action_;   /**< empty for none. */
+  Name prefix_;
+  int faceId_;           /**< -1 for none. */
+  ForwardingFlags forwardingFlags_;
+  int freshnessPeriod_; /**< -1 for none. */
+
+  mutable Block wire_;
+};
+
+inline const Block&
+ForwardingEntry::wireEncode() const
+{
+  if (wire_.hasWire())
+    return wire_;
+
+  // ForwardingEntry ::= FORWARDING-ENTRY TLV-LENGTH
+  //                       Action?
+  //                       Name?
+  //                       FaceID?
+  //                       ForwardingFlags?
+  //                       FreshnessPeriod?
+  
+  wire_ = Block(Tlv::FaceManagement::ForwardingEntry);
+
+  // Action
+  if (!action_.empty())
+    {
+      wire_.push_back
+        (dataBlock(Tlv::FaceManagement::Action, action_.c_str(), action_.size()));
+    }
+
+  // Name
+  wire_.push_back
+    (prefix_.wireEncode());
+
+  // FaceID
+  if (faceId_ >= 0)
+    {
+      wire_.push_back
+        (nonNegativeIntegerBlock(Tlv::FaceManagement::FaceID, faceId_));
+    }
+
+  // ForwardingFlags
+  wire_.push_back
+    (forwardingFlags_.wireEncode());
+
+  // FreshnessPeriod
+  if (freshnessPeriod_ >= 0)
+    {
+      wire_.push_back
+        (nonNegativeIntegerBlock(Tlv::FreshnessPeriod, freshnessPeriod_));
+    }
+  
+  wire_.encode();
+  return wire_;    
+}
+  
+inline void 
+ForwardingEntry::wireDecode(const Block &wire)
+{
+  action_.clear();
+  prefix_.clear();
+  faceId_ = -1;
+  forwardingFlags_ = ForwardingFlags();
+  freshnessPeriod_ = -1;
+
+  wire_ = wire;
+  wire_.parse();
+
+  // ForwardingEntry ::= FORWARDING-ENTRY TLV-LENGTH
+  //                       Action?
+  //                       Name?
+  //                       FaceID?
+  //                       ForwardingFlags?
+  //                       FreshnessPeriod?
+
+  // Action
+  Block::element_iterator val = wire_.find(Tlv::FaceManagement::Action);
+  if (val != wire_.getAll().end())
+    {
+      action_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
+    }
+
+  // Name
+  val = wire_.find(Tlv::Name);
+  if (val != wire_.getAll().end())
+    {
+      prefix_.wireDecode(*val);
+    }
+
+  // FaceID
+  val = wire_.find(Tlv::FaceManagement::FaceID);
+  if (val != wire_.getAll().end())
+    {
+      faceId_ = readNonNegativeInteger(*val);
+    }
+
+  // ForwardingFlags
+  val = wire_.find(Tlv::FaceManagement::ForwardingFlags);
+  if (val != wire_.getAll().end())
+    {
+      forwardingFlags_.wireDecode(*val);
+    }
+
+  // FreshnessPeriod
+  val = wire_.find(Tlv::FreshnessPeriod);
+  if (val != wire_.getAll().end())
+    {
+      freshnessPeriod_ = readNonNegativeInteger(*val);
+    }
+}
+
+inline std::ostream&
+operator << (std::ostream &os, const ForwardingEntry &entry)
+{
+  os << "ForwardingEntry(";
+  
+  // Action
+  if (!entry.getAction().empty())
+    {
+      os << "Action:" << entry.getAction() << ", ";
+    }
+
+  // Name
+  os << "Prefix:" << entry.getPrefix() << ", ";
+
+  // FaceID
+  if (entry.getFaceId() >= 0)
+    {
+      os << "FaceID:" << entry.getFaceId() << ", ";
+    }
+
+  // ForwardingFlags
+  os << "ForwardingFlags:" << entry.getForwardingFlags() << ", ";
+
+  // FreshnessPeriod
+  if (entry.getFreshnessPeriod() >= 0)
+    {
+      os << "FreshnessPeriod:" << entry.getFreshnessPeriod() << ", ";
+    }
+
+  os << ")";
+  return os;
+}
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/forwarding-flags.hpp b/include/ndn-cpp-dev/forwarding-flags.hpp
new file mode 100644
index 0000000..a0c81c1
--- /dev/null
+++ b/include/ndn-cpp-dev/forwarding-flags.hpp
@@ -0,0 +1,224 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_FORWARDING_FLAGS_HPP
+#define NDN_FORWARDING_FLAGS_HPP
+
+#include "encoding/block.hpp"
+#include "encoding/tlv-face-management.hpp"
+
+namespace ndn {
+
+/**
+ * A ForwardingFlags object holds the flags which specify how the forwarding daemon should forward an interest for
+ * a registered prefix.  We use a separate ForwardingFlags object to retain future compatibility if the daemon forwarding
+ * bits are changed, amended or deprecated.
+ */
+class ForwardingFlags {
+public:
+  /**
+   * Create a new ForwardingFlags with "active" and "childInherit" set and all other flags cleared.
+   */
+  ForwardingFlags() 
+    : active_(true)
+    , childInherit_(true)
+    , advertise_(false)
+    , last_(false)
+    , capture_(false)
+    , local_(false)
+    , tap_(false)
+    , captureOk_(false)
+  {
+  }
+
+  /**
+   * Get the value of the "active" flag.
+   * @return true if the flag is set, false if it is cleared.
+   */
+  bool getActive() const { return active_; }
+  
+  /**
+   * Get the value of the "childInherit" flag.
+   * @return true if the flag is set, false if it is cleared.
+   */
+  bool getChildInherit() const { return childInherit_; }
+  
+  /**
+   * Get the value of the "advertise" flag.
+   * @return true if the flag is set, false if it is cleared.
+   */
+  bool getAdvertise() const { return advertise_; }
+  
+  /**
+   * Get the value of the "last" flag.
+   * @return true if the flag is set, false if it is cleared.
+   */
+  bool getLast() const { return last_; }
+  
+  /**
+   * Get the value of the "capture" flag.
+   * @return true if the flag is set, false if it is cleared.
+   */
+  bool getCapture() const { return capture_; }
+  
+  /**
+   * Get the value of the "local" flag.
+   * @return true if the flag is set, false if it is cleared.
+   */
+  bool getLocal() const { return local_; }
+  
+  /**
+   * Get the value of the "tap" flag.
+   * @return true if the flag is set, false if it is cleared.
+   */
+  bool getTap() const { return tap_; }
+  
+  /**
+   * Get the value of the "captureOk" flag.
+   * @return true if the flag is set, false if it is cleared.
+   */
+  bool getCaptureOk() const { return captureOk_; }
+
+  /**
+   * Set the value of the "active" flag
+   * @param active true to set the flag, false to clear it.
+   */  
+  void setActive(bool active) { this->active_ = active; wire_.reset(); }
+  
+  /**
+   * Set the value of the "childInherit" flag
+   * @param childInherit true to set the flag, false to clear it.
+   */  
+  void setChildInherit(bool childInherit) { this->childInherit_ = childInherit; wire_.reset(); }
+  
+  /**
+   * Set the value of the "advertise" flag
+   * @param advertise true to set the flag, false to clear it.
+   */  
+  void setAdvertise(bool advertise) { this->advertise_ = advertise; wire_.reset(); }
+  
+  /**
+   * Set the value of the "last" flag
+   * @param last true to set the flag, false to clear it.
+   */  
+  void setLast(bool last) { this->last_ = last; wire_.reset(); }
+  
+  /**
+   * Set the value of the "capture" flag
+   * @param capture true to set the flag, false to clear it.
+   */  
+  void setCapture(bool capture) { this->capture_ = capture; wire_.reset(); }
+  
+  /**
+   * Set the value of the "local" flag
+   * @param local true to set the flag, false to clear it.
+   */  
+  void setLocal(bool local) { this->local_ = local; wire_.reset(); }
+  
+  /**
+   * Set the value of the "tap" flag
+   * @param tap true to set the flag, false to clear it.
+   */  
+  void setTap(bool tap) { this->tap_ = tap; wire_.reset(); }
+  
+  /**
+   * Set the value of the "captureOk" flag
+   * @param captureOk true to set the flag, false to clear it.
+   */  
+  void setCaptureOk(bool captureOk) { this->captureOk_ = captureOk; wire_.reset(); }
+
+  inline const Block&
+  wireEncode() const;
+
+  inline void
+  wireDecode(const Block &block);
+  
+private:
+  bool active_;
+  bool childInherit_;
+  bool advertise_;
+  bool last_;
+  bool capture_;
+  bool local_;
+  bool tap_;
+  bool captureOk_;
+
+  mutable Block wire_;
+};
+
+inline const Block&
+ForwardingFlags::wireEncode() const
+{
+  if (wire_.hasWire())
+    return wire_;
+
+  uint32_t result = 0;
+  if (active_)
+    result |= Tlv::FaceManagement::FORW_ACTIVE;
+  if (childInherit_)
+    result |= Tlv::FaceManagement::FORW_CHILD_INHERIT;
+  if (advertise_)
+    result |= Tlv::FaceManagement::FORW_ADVERTISE;
+  if (last_)
+    result |= Tlv::FaceManagement::FORW_LAST;
+  if (capture_)
+    result |= Tlv::FaceManagement::FORW_CAPTURE;
+  if (local_)
+    result |= Tlv::FaceManagement::FORW_LOCAL;
+  if (tap_)
+    result |= Tlv::FaceManagement::FORW_TAP;
+  if (captureOk_)
+    result |= Tlv::FaceManagement::FORW_CAPTURE_OK;
+  
+  wire_ = nonNegativeIntegerBlock(Tlv::FaceManagement::ForwardingFlags, result);
+
+  return wire_;
+}
+
+inline void
+ForwardingFlags::wireDecode(const Block &wire)
+{
+  wire_ = wire;
+
+  uint32_t flags = readNonNegativeInteger(wire_);
+  
+  active_       = (flags & Tlv::FaceManagement::FORW_ACTIVE)        ? true : false;
+  childInherit_ = (flags & Tlv::FaceManagement::FORW_CHILD_INHERIT) ? true : false;
+  advertise_    = (flags & Tlv::FaceManagement::FORW_ADVERTISE)     ? true : false;
+  last_         = (flags & Tlv::FaceManagement::FORW_LAST)          ? true : false;
+  capture_      = (flags & Tlv::FaceManagement::FORW_CAPTURE)       ? true : false;
+  local_        = (flags & Tlv::FaceManagement::FORW_LOCAL)         ? true : false;
+  tap_          = (flags & Tlv::FaceManagement::FORW_TAP)           ? true : false;
+  captureOk_    = (flags & Tlv::FaceManagement::FORW_CAPTURE_OK)    ? true : false;
+}
+
+inline std::ostream&
+operator << (std::ostream &os, const ForwardingFlags &flags)
+{
+  if (flags.getActive())
+    os << "ACTIVE ";
+  if (flags.getChildInherit())
+    os << "CHILE_INHERIT ";
+  if (flags.getAdvertise())
+    os << "ADVERTISE ";
+  if (flags.getLast())
+    os << "LAST ";
+  if (flags.getCapture())
+    os << "CAPTURE ";
+  if (flags.getLocal())
+    os << "LOCAL ";
+  if (flags.getTap())
+    os << "TAP ";
+  if (flags.getCaptureOk())
+    os << "CAPTURE_OK ";
+
+  return os;
+}
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/interest.hpp b/include/ndn-cpp-dev/interest.hpp
new file mode 100644
index 0000000..8fe3119
--- /dev/null
+++ b/include/ndn-cpp-dev/interest.hpp
@@ -0,0 +1,243 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_INTEREST_HPP
+#define NDN_INTEREST_HPP
+
+#include "name.hpp"
+#include "exclude.hpp"
+#include "encoding/block.hpp"
+
+namespace ndn {
+  
+/**
+ * An Interest holds a Name and other fields for an interest.
+ */
+class Interest {
+public:    
+  /**
+   * Create a new Interest for the given name and values.
+   * @param name
+   * @param minSuffixComponents
+   * @param maxSuffixComponents
+   * @param exclude
+   * @param childSelector
+   * @param mustBeFresh
+   * @param scope
+   * @param interestLifetime
+   * @param nonce
+   */
+  Interest(const Name& name,
+           int minSuffixComponents, int maxSuffixComponents, 
+           const Exclude& exclude,
+           int childSelector,
+           bool mustBeFresh, 
+           int scope,
+           Milliseconds interestLifetime,
+           uint32_t nonce = 0) 
+  : name_(name)
+  , minSuffixComponents_(minSuffixComponents)
+  , maxSuffixComponents_(maxSuffixComponents)
+  , exclude_(exclude), childSelector_(childSelector)
+  , mustBeFresh_(mustBeFresh)
+  , scope_(scope)
+  , interestLifetime_(interestLifetime)
+  , nonce_(nonce)
+  {
+  }
+
+  /**
+   * Create a new Interest with the given name and interest lifetime and "none" for other values.
+   * @param name The name for the interest.
+   * @param interestLifetimeMilliseconds The interest lifetime in milliseconds, or -1 for none.
+   */
+  Interest(const Name& name, Milliseconds interestLifetime) 
+  : name_(name)
+  {
+    construct();
+    interestLifetime_ = interestLifetime;
+  }
+
+  /**
+   * Create a new Interest with the given name and "none" for other values.
+   * @param name The name for the interest.
+   */
+  Interest(const Name& name) 
+  : name_(name)
+  {
+    construct();
+  }
+
+  /**
+   * Create a new Interest with an empty name and "none" for all values.
+   */
+  Interest() 
+  {
+    construct();
+  }
+  
+  /**
+   * Encode this Interest for a particular wire format.
+   * @return The encoded byte array.
+   */
+  const Block&
+  wireEncode() const;
+  
+  /**
+   * Decode the input using a particular wire format and update this Interest.
+   * @param input The input byte array to be decoded.
+   */
+  void 
+  wireDecode(const Block &wire);
+  
+  /**
+   * Encode the name according to the "NDN URI Scheme".  If there are interest selectors, append "?" and
+   * added the selectors as a query string.  For example "/test/name?ndn.ChildSelector=1".
+   * @return The URI string.
+   */
+  inline std::string
+  toUri() const;
+
+  Name& 
+  getName() { return name_; }
+  
+  const Name& 
+  getName() const { return name_; }
+  
+  int 
+  getMinSuffixComponents() const { return minSuffixComponents_; }
+  
+  int 
+  getMaxSuffixComponents() const { return maxSuffixComponents_; }
+
+  Exclude& 
+  getExclude() { return exclude_; }
+  
+  const Exclude& 
+  getExclude() const { return exclude_; }
+  
+  int 
+  getChildSelector() const { return childSelector_; }
+
+  int 
+  getMustBeFresh() const { return mustBeFresh_; }
+
+  int 
+  getScope() const { return scope_; }
+
+  Milliseconds 
+  getInterestLifetime() const { return interestLifetime_; }
+
+  /**
+   * @brief Get Interest's nonce
+   *
+   * If nonce was not set before this call, it will be automatically assigned to a random value
+   *
+   * Const reference needed for C decoding
+   */
+  const uint32_t&
+  getNonce() const;
+    
+  void
+  setName(const Name& name) { name_ = name; }
+  
+  void 
+  setMinSuffixComponents(int minSuffixComponents) { minSuffixComponents_ = minSuffixComponents; }
+  
+  void 
+  setMaxSuffixComponents(int maxSuffixComponents) { maxSuffixComponents_ = maxSuffixComponents; }
+  
+  void 
+  setChildSelector(int childSelector) { childSelector_ = childSelector; }
+
+  void 
+  setMustBeFresh(bool mustBeFresh) { mustBeFresh_ = mustBeFresh; }
+
+  void 
+  setScope(int scope) { scope_ = scope; }
+
+  void 
+  setInterestLifetime(Milliseconds interestLifetime) { interestLifetime_ = interestLifetime; }
+
+  void 
+  setNonce(uint32_t nonce) { nonce_ = nonce; }
+
+  inline bool
+  hasSelectors() const;
+
+  inline bool
+  hasGuiders() const;
+
+  /**
+   * @brief Check if Interest name matches the given name (using ndn_Name_match) and the given name also conforms to the 
+   * interest selectors.
+   * @param self A pointer to the ndn_Interest struct.
+   * @param name A pointer to the name to check.
+   * @return 1 if the name and interest selectors match, 0 otherwise.
+   */
+  bool
+  matchesName(const Name &name) const;
+  
+private:
+  void 
+  construct() 
+  {
+    minSuffixComponents_ = -1;
+    maxSuffixComponents_ = -1;  
+    childSelector_ = -1;
+    mustBeFresh_ = false; // default
+    scope_ = -1;
+    interestLifetime_ = -1.0;
+    nonce_ = 0;
+  }
+  
+  Name name_;
+  int minSuffixComponents_;
+  int maxSuffixComponents_;  
+  Exclude exclude_;
+  int childSelector_;
+  bool mustBeFresh_;
+  int scope_;
+  Milliseconds interestLifetime_;
+  mutable uint32_t nonce_;
+
+  mutable Block wire_;
+};
+
+std::ostream &
+operator << (std::ostream &os, const Interest &interest);
+
+inline std::string
+Interest::toUri() const
+{
+  std::ostringstream os;
+  os << *this;
+  return os.str();
+}
+
+inline bool
+Interest::hasSelectors() const
+{
+  return minSuffixComponents_ >= 0 ||
+    maxSuffixComponents_ >= 0 ||
+    !exclude_.empty() ||
+    childSelector_ >= 0 ||
+    mustBeFresh_ == true ||
+    scope_ >= 0;
+}
+
+inline bool
+Interest::hasGuiders() const
+{
+  return scope_ >= 0 ||
+    interestLifetime_ >= 0 ||
+    nonce_ > 0;
+}
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/key-locator.hpp b/include/ndn-cpp-dev/key-locator.hpp
new file mode 100644
index 0000000..2ff85f0
--- /dev/null
+++ b/include/ndn-cpp-dev/key-locator.hpp
@@ -0,0 +1,135 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_KEY_LOCATOR_HPP
+#define NDN_KEY_LOCATOR_HPP
+
+#include "encoding/block.hpp"
+#include "name.hpp"
+
+namespace ndn {
+
+class KeyLocator {
+public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+  
+  enum {
+    KeyLocator_None = -1,
+    KeyLocator_Name = 0,
+    
+    KeyLocator_Unknown = 255
+  };
+
+  inline
+  KeyLocator()
+    : type_(KeyLocator_None)
+  {
+  }
+
+  inline
+  KeyLocator(const Name &name);
+
+  inline const Block& 
+  wireEncode() const;
+
+  inline void 
+  wireDecode(const Block &value);
+  
+  inline bool
+  empty() const
+  {
+    return type_ == KeyLocator_None;
+  }
+  
+  uint32_t 
+  getType() const { return type_; }
+      
+  ////////////////////////////////////////////////////////
+  // Helper methods for different types of key locators
+  //
+  // For now only Name type is actually supported
+  
+  inline const Name&
+  getName() const;
+
+  inline void
+  setName(const Name &name);
+  
+private:
+  uint32_t type_;
+  Name name_;
+  
+  mutable Block wire_;
+};
+
+inline
+KeyLocator::KeyLocator(const Name &name)
+{
+  setName(name);
+}
+
+inline const Block& 
+KeyLocator::wireEncode() const
+{
+  if (wire_.hasWire())
+    return wire_;
+
+  // KeyLocator
+
+  switch (type_) {
+  case KeyLocator_None:
+    wire_ = dataBlock(Tlv::KeyLocator, reinterpret_cast<const uint8_t*>(0), 0);
+    break;
+  case KeyLocator_Name:
+    wire_ = Block(Tlv::KeyLocator);
+    wire_.push_back(name_.wireEncode());
+    wire_.encode();
+    break;
+  default:
+    throw Error("Unsupported KeyLocator type");
+  }
+  
+  return wire_;
+}
+
+inline void 
+KeyLocator::wireDecode(const Block &value)
+{
+  wire_ = value;
+  wire_.parse();
+  
+  if (!wire_.getAll().empty() && wire_.getAll().front().type() == Tlv::Name)
+    {
+      type_ = KeyLocator_Name;
+      name_.wireDecode(wire_.getAll().front());
+    }
+  else
+    {
+      type_ = KeyLocator_Unknown;
+    }
+}
+
+inline const Name&
+KeyLocator::getName() const
+{
+  if (type_ != KeyLocator_Name)
+    throw Error("Requested Name, but KeyLocator is not of the Name type");
+
+  return name_;
+}
+
+inline void
+KeyLocator::setName(const Name &name)
+{
+  type_ = KeyLocator_Name;
+  name_ = name;
+}
+
+
+} // namespace ndn
+
+#endif
diff --git a/include/ndn-cpp-dev/meta-info.hpp b/include/ndn-cpp-dev/meta-info.hpp
new file mode 100644
index 0000000..5ad07f6
--- /dev/null
+++ b/include/ndn-cpp-dev/meta-info.hpp
@@ -0,0 +1,127 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_META_INFO_HPP
+#define NDN_META_INFO_HPP
+
+namespace ndn {
+
+/**
+ * An MetaInfo holds the meta info which is signed inside the data packet.
+ */
+class MetaInfo {
+public:
+  enum {
+    TYPE_DEFAULT = 0,
+    TYPE_LINK = 1,
+    TYPE_KEY = 2
+  };
+  
+  MetaInfo()
+    : type_(TYPE_DEFAULT)
+    , freshnessPeriod_(-1)
+  {   
+  }
+  
+  uint32_t 
+  getType() const
+  { return type_; }
+  
+  void 
+  setType(uint32_t type)
+  { type_ = type; }
+  
+  Milliseconds 
+  getFreshnessPeriod() const
+  { return freshnessPeriod_; }
+  
+  void 
+  setFreshnessPeriod(Milliseconds freshnessPeriod)
+  { freshnessPeriod_ = freshnessPeriod; }
+
+  inline const Block& 
+  wireEncode() const;
+  
+  inline void
+  wireDecode(const Block &wire);  
+  
+private:
+  uint32_t type_;
+  Milliseconds freshnessPeriod_;
+
+  mutable Block wire_;
+};
+
+inline const Block& 
+MetaInfo::wireEncode() const
+{
+  if (wire_.hasWire())
+    return wire_;
+
+  // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
+  //                ContentType?
+  //                FreshnessPeriod?
+  
+  wire_ = Block(Tlv::MetaInfo);
+
+  // ContentType
+  if (type_ != TYPE_DEFAULT) {
+    wire_.push_back
+      (nonNegativeIntegerBlock(Tlv::ContentType, type_));
+  }
+
+  // FreshnessPeriod
+  if (freshnessPeriod_ >= 0) {
+    wire_.push_back
+      (nonNegativeIntegerBlock(Tlv::FreshnessPeriod, freshnessPeriod_));
+  }
+  
+  wire_.encode();
+  return wire_;  
+}
+  
+inline void
+MetaInfo::wireDecode(const Block &wire)
+{
+  wire_ = wire;
+  wire_.parse();
+
+  // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
+  //                ContentType?
+  //                FreshnessPeriod?
+  
+  // ContentType
+  Block::element_iterator val = wire_.find(Tlv::ContentType);
+  if (val != wire_.getAll().end())
+    {
+      type_ = readNonNegativeInteger(*val);
+    }
+
+  // FreshnessPeriod
+  val = wire_.find(Tlv::FreshnessPeriod);
+  if (val != wire_.getAll().end())
+    {
+      freshnessPeriod_ = readNonNegativeInteger(*val);
+    }
+}
+
+inline std::ostream&
+operator << (std::ostream &os, const MetaInfo &info)
+{
+  // ContentType
+  os << "ContentType: " << info.getType();
+
+  // FreshnessPeriod
+  if (info.getFreshnessPeriod() >= 0) {
+    os << ", FreshnessPeriod: " << info.getFreshnessPeriod();
+  }
+  return os;
+}
+
+} // namespace ndn
+
+#endif // NDN_META_INFO_HPP
diff --git a/include/ndn-cpp-dev/name.hpp b/include/ndn-cpp-dev/name.hpp
new file mode 100644
index 0000000..c4e7e5c
--- /dev/null
+++ b/include/ndn-cpp-dev/name.hpp
@@ -0,0 +1,799 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * @author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * @author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_NAME_HPP
+#define NDN_NAME_HPP
+
+#include <vector>
+#include <string>
+#include <sstream>
+#include <string.h>
+#include "encoding/block.hpp"
+
+namespace ndn {
+    
+/**
+ * A Name holds an array of Name::Component and represents an NDN name.
+ */
+class Name {
+public:
+  /**
+   * A Name::Component holds a read-only name component value.
+   */
+  class Component
+  {
+  public:
+    /**
+     * Create a new Name::Component with a null value.
+     */
+    Component() 
+    {    
+    }
+
+    // copy constructor OK
+  
+    /**
+     * Create a new Name::Component, taking another pointer to the Blob value.
+     * @param value A blob with a pointer to an immutable array.  The pointer is copied.
+     */
+    Component(const ConstBufferPtr &buffer)
+    : value_ (buffer)
+    {
+    }
+  
+    /**
+     * Create a new Name::Component, copying the given value.
+     * @param value The value byte array.
+     */
+    Component(const Buffer& value) 
+      : value_ (new Buffer(value))
+    {
+    }
+
+    /**
+     * Create a new Name::Component, copying the given value.
+     * @param value Pointer to the value byte array.
+     * @param valueLen Length of value.
+     */
+    Component(const uint8_t *value, size_t valueLen) 
+      : value_ (new Buffer(value, valueLen))
+    {
+    }
+
+    template<class InputIterator>
+    Component(InputIterator begin, InputIterator end)
+      : value_ (new Buffer(begin, end))
+    {
+    }
+    
+    Component(const char *string)
+      : value_ (new Buffer(string, ::strlen(string)))
+    {
+    }
+
+    const Buffer& 
+    getValue() const { return *value_; }
+
+    /**
+     * Write this component value to result, escaping characters according to the NDN URI Scheme.
+     * This also adds "..." to a value with zero or more ".".
+     * @param result the string stream to write to.
+     */
+    void 
+    toEscapedString(std::ostream& result) const
+    {
+      Name::toEscapedString(*value_, result);
+    }
+
+    /**
+     * Convert this component value by escaping characters according to the NDN URI Scheme.
+     * This also adds "..." to a value with zero or more ".".
+     * @return The escaped string.
+     */
+    std::string
+    toEscapedString() const
+    {
+      return Name::toEscapedString(*value_);
+    }
+    
+    /**
+     * Interpret this name component as a network-ordered number and return an integer.
+     * @return The integer number.
+     */
+    uint64_t
+    toNumber() const;
+
+    /**
+     * Interpret this name component as a network-ordered number with a marker and return an integer.
+     * @param marker The required first byte of the component.
+     * @return The integer number.
+     * @throw runtime_error If the first byte of the component does not equal the marker.
+     */
+    uint64_t
+    toNumberWithMarker(uint8_t marker) const;
+    
+    /**
+     * Interpret this name component as a segment number according to NDN name conventions (a network-ordered number 
+     * where the first byte is the marker 0x00).
+     * @return The integer segment number.
+     * @throw runtime_error If the first byte of the component is not the expected marker.
+     */
+    uint64_t
+    toSegment() const
+    {
+      return toNumberWithMarker(0x00);
+    }
+    
+    /**
+     * @deprecated Use toSegment.
+     */
+    uint64_t
+    toSeqNum() const
+    {
+      return toSegment();
+    }
+        
+    /**
+     * Interpret this name component as a version number according to NDN name conventions (a network-ordered number 
+     * where the first byte is the marker 0xFD).  Note that this returns the exact number from the component
+     * without converting it to a time representation.
+     * @return The integer segment number.
+     * @throw runtime_error If the first byte of the component is not the expected marker.
+     */
+    uint64_t
+    toVersion() const
+    {
+      return toNumberWithMarker(0xFD);
+    }
+    
+    /**
+     * Create a component whose value is the network-ordered encoding of the number.
+     * Note: if the number is zero, the result is empty.
+     * @param number The number to be encoded.
+     * @return The component value.
+     */
+    static Component 
+    fromNumber(uint64_t number);
+    
+    /**
+     * Create a component whose value is the marker appended with the network-ordered encoding of the number.
+     * Note: if the number is zero, no bytes are used for the number - the result will have only the marker.
+     * @param number The number to be encoded.  
+     * @param marker The marker to use as the first byte of the component.
+     * @return The component value.
+     */
+    static Component 
+    fromNumberWithMarker(uint64_t number, uint8_t marker);
+
+    /**
+     * Check if this is the same component as other.
+     * @param other The other Component to compare with.
+     * @return true if the components are equal, otherwise false.
+     */
+    bool
+    equals(const Component& other) const
+    {
+      return *value_ == *other.value_;
+    }
+
+    bool
+    empty() const
+    {
+      return !value_ || value_->empty();
+    }
+    
+    /**
+     * Check if this is the same component as other.
+     * @param other The other Component to compare with.
+     * @return true if the components are equal, otherwise false.
+     */
+    bool
+    operator == (const Component& other) const { return equals(other); }
+
+    /**
+     * Check if this is not the same component as other.
+     * @param other The other Component to compare with.
+     * @return true if the components are not equal, otherwise false.
+     */
+    bool
+    operator != (const Component& other) const { return !equals(other); }
+    
+    /**
+     * Compare this to the other Component using NDN canonical ordering.
+     * @param other The other Component to compare with.
+     * @return 0 If they compare equal, -1 if *this comes before other in the canonical ordering, or
+     * 1 if *this comes after other in the canonical ordering.
+     *
+     * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+     */
+    int
+    compare(const Component& other) const;
+  
+    /**
+     * Return true if this is less than or equal to the other Component in the NDN canonical ordering.
+     * @param other The other Component to compare with.
+     *
+     * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+     */
+    bool
+    operator <= (const Component& other) const { return compare(other) <= 0; }
+  
+    /**
+     * Return true if this is less than the other Component in the NDN canonical ordering.
+     * @param other The other Component to compare with.
+     *
+     * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+     */
+    bool
+    operator < (const Component& other) const { return compare(other) < 0; }
+
+    /**
+     * Return true if this is less than or equal to the other Component in the NDN canonical ordering.
+     * @param other The other Component to compare with.
+     *
+     * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+     */
+    bool
+    operator >= (const Component& other) const { return compare(other) >= 0; }
+
+    /**
+     * Return true if this is greater than the other Component in the NDN canonical ordering.
+     * @param other The other Component to compare with.
+     *
+     * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+     */
+    bool
+    operator > (const Component& other) const { return compare(other) > 0; }
+  private:
+    ConstBufferPtr value_;
+  };
+
+  /**
+   * Create a new Name with no components.
+   */
+  Name() {
+  }
+  
+  /**
+   * Create a new Name, copying the name components.
+   * @param components A vector of Component
+   */
+  Name(const std::vector<Component>& components)
+  : components_(components)
+  {
+  }
+
+  Name(const Block &name)
+  {
+    for (Block::element_const_iterator i = name.getAll().begin();
+         i != name.getAll().end();
+         ++i)
+      {
+        append(Component(i->value_begin(), i->value_end()));
+      }
+  }
+  
+  /**
+   * Parse the uri according to the NDN URI Scheme and create the name with the components.
+   * @param uri The URI string.
+   */
+  Name(const char* uri)
+  {
+    set(uri);
+  }
+  
+  /**
+   * Parse the uri according to the NDN URI Scheme and create the name with the components.
+   * @param uri The URI string.
+   */
+  Name(const std::string& uri)
+  {
+    set(uri.c_str());
+  }
+
+  const Block &
+  wireEncode() const;
+
+  void
+  wireDecode(const Block &wire);
+  
+  /**
+   * Parse the uri according to the NDN URI Scheme and set the name with the components.
+   * @param uri The null-terminated URI string.
+   */
+  void 
+  set(const char *uri);  
+
+  /**
+   * Parse the uri according to the NDN URI Scheme and set the name with the components.
+   * @param uri The URI string.
+   */
+  void 
+  set(const std::string& uri) { set(uri.c_str()); }  
+  
+  /**
+   * Append a new component, copying from value of length valueLength.
+   * @return This name so that you can chain calls to append.
+   */
+  Name& 
+  append(const uint8_t *value, size_t valueLength) 
+  {
+    components_.push_back(Component(value, valueLength));
+    return *this;
+  }
+
+  /**
+   * Append a new component, copying from value.
+   * @return This name so that you can chain calls to append.
+   */
+  Name& 
+  append(const Buffer& value) 
+  {
+    components_.push_back(value);
+    return *this;
+  }
+  
+  Name& 
+  append(const ConstBufferPtr &value)
+  {
+    components_.push_back(value);
+    return *this;
+  }
+  
+  Name& 
+  append(const Component &value)
+  {
+    components_.push_back(value);
+    return *this;
+  }
+
+  /**
+   * @brief Append name component that represented as a string
+   *
+   * Note that this method is necessary to ensure correctness and unambiguity of
+   * ``append("string")`` operations (both Component and Name can be implicitly
+   * converted from string, each having different outcomes
+   */
+  Name& 
+  append(const char *value)
+  {
+    components_.push_back(Component(value));
+    return *this;
+  }
+  
+  Name&
+  append(const Block &value)
+  {
+    components_.push_back(Component(value.begin(), value.end()));
+    return *this;
+  }
+  
+  /**
+   * Append the components of the given name to this name.
+   * @param name The Name with components to append.
+   * @return This name so that you can chain calls to append.
+   */
+  Name&
+  append(const Name& name);
+  
+  /**
+   * @deprecated Use append.
+   */
+  Name& 
+  appendComponent(const uint8_t *value, size_t valueLength) 
+  {
+    return append(value, valueLength);
+  }
+
+  /**
+   * @deprecated Use append.
+   */
+  Name& 
+  appendComponent(const Buffer& value) 
+  {
+    return append(value);
+  }
+  
+  /**
+   * @deprecated Use append.
+   */
+  Name& 
+  appendComponent(const ConstBufferPtr &value)
+  {
+    return append(value);
+  }
+
+  /**
+   * @deprecated Use append.
+   */
+  Name& 
+  addComponent(const uint8_t *value, size_t valueLength) 
+  {
+    return append(value, valueLength);
+  }
+
+  /**
+   * @deprecated Use append.
+   */
+  Name& 
+  addComponent(const Buffer& value) 
+  {
+    return append(value);
+  }
+  
+  /**
+   * @deprecated Use append.
+   */
+  Name& 
+  addComponent(const ConstBufferPtr &value)
+  {
+    return append(value);
+  }
+  
+  /**
+   * Clear all the components.
+   */
+  void 
+  clear() {
+    components_.clear();
+  }
+  
+  /**
+   * @deprecated use size().
+   */
+  size_t 
+  getComponentCount() const { return size(); }
+  
+  /**
+   * @deprecated Use get(i).
+   */
+  const Component& 
+  getComponent(size_t i) const { return get(i); }
+  
+  /**
+   * Get a new name, constructed as a subset of components.
+   * @param iStartComponent The index if the first component to get.
+   * @param nComponents The number of components starting at iStartComponent.
+   * @return A new name.
+   */
+  Name
+  getSubName(size_t iStartComponent, size_t nComponents) const;
+
+  /**
+   * Get a new name, constructed as a subset of components starting at iStartComponent until the end of the name.
+   * @param iStartComponent The index if the first component to get.
+   * @return A new name.
+   */
+  Name
+  getSubName(size_t iStartComponent) const;
+  
+  /**
+   * Return a new Name with the first nComponents components of this Name.
+   * @param nComponents The number of prefix components.  If nComponents is -N then return the prefix up
+   * to name.size() - N. For example getPrefix(-1) returns the name without the final component.
+   * @return A new Name.
+   */
+  Name
+  getPrefix(int nComponents) const
+  {
+    if (nComponents < 0)
+      return getSubName(0, components_.size() + nComponents);
+    else
+      return getSubName(0, nComponents);
+  }
+  
+  /**
+   * Encode this name as a URI.
+   * @return The encoded URI.
+   */
+  std::string 
+  toUri() const;
+  
+  /**
+   * Append a component with the encoded segment number.
+   * @param segment The segment number.
+   * @return This name so that you can chain calls to append.
+   */  
+  Name& 
+  appendSegment(uint64_t segment)
+  {
+    components_.push_back(Component::fromNumberWithMarker(segment, 0x00));
+    return *this;
+  }
+
+  /**
+   * Append a component with the encoded version number.
+   * Note that this encodes the exact value of version without converting from a time representation.
+   * @param version The version number.
+   * @return This name so that you can chain calls to append.
+   */  
+  Name& 
+  appendVersion(uint64_t version)
+  {
+    components_.push_back(Component::fromNumberWithMarker(version, 0xFD));
+    return *this;
+  }
+
+  /**
+   * @brief Append a component with the encoded version number.
+   * 
+   * This version of the method creates version number based on the current timestamp
+   * @return This name so that you can chain calls to append.
+   */  
+  Name& 
+  appendVersion();
+  
+  /**
+   * Check if this name has the same component count and components as the given name.
+   * @param name The Name to check.
+   * @return true if the names are equal, otherwise false.
+   */
+  bool
+  equals(const Name& name) const;
+  
+  /**
+   * Check if the N components of this name are the same as the first N components of the given name.
+   * @param name The Name to check.
+   * @return true if this matches the given name, otherwise false.  This always returns true if this name is empty.
+   */
+  bool 
+  isPrefixOf(const Name& name) const;
+
+  bool
+  match(const Name& name) const
+  {
+    return isPrefixOf(name);
+  }
+  
+  /**
+   * Make a Blob value by decoding the escapedString between beginOffset and endOffset according to the NDN URI Scheme.
+   * If the escaped string is "", "." or ".." then return a Blob with a null pointer, 
+   * which means the component should be skipped in a URI name.
+   * @param escapedString The escaped string.  It does not need to be null-terminated because we only scan to endOffset.
+   * @param beginOffset The offset in escapedString of the beginning of the portion to decode.
+   * @param endOffset The offset in escapedString of the end of the portion to decode.
+   * @return The Blob value. If the escapedString is not a valid escaped component, then the Blob is a null pointer.
+   */
+  static Component 
+  fromEscapedString(const char *escapedString, size_t beginOffset, size_t endOffset);
+
+  /**
+   * Make a Blob value by decoding the escapedString according to the NDN URI Scheme.
+   * If the escaped string is "", "." or ".." then return a Blob with a null pointer, 
+   * which means the component should be skipped in a URI name.
+   * @param escapedString The null-terminated escaped string.
+   * @return The Blob value. If the escapedString is not a valid escaped component, then the Blob is a null pointer.
+   */
+  static Component 
+  fromEscapedString(const char *escapedString);
+
+  /**
+   * Make a Blob value by decoding the escapedString according to the NDN URI Scheme.
+   * If the escaped string is "", "." or ".." then return a Blob with a null pointer, 
+   * which means the component should be skipped in a URI name.
+   * @param escapedString The escaped string.
+   * @return The Blob value. If the escapedString is not a valid escaped component, then the Blob is a null pointer.
+   */
+  static Component 
+  fromEscapedString(const std::string& escapedString) { return fromEscapedString(escapedString.c_str()); }
+
+  /**
+   * Write the value to result, escaping characters according to the NDN URI Scheme.
+   * This also adds "..." to a value with zero or more ".".
+   * @param value the buffer with the value to escape
+   * @param result the string stream to write to.
+   */
+  static void 
+  toEscapedString(const uint8_t *value, size_t valueSize, std::ostream& result);
+
+  inline static void 
+  toEscapedString(const std::vector<uint8_t>& value, std::ostream& result)
+  {
+    toEscapedString(&*value.begin(), value.size(), result);
+  }
+  
+  /**
+   * Convert the value by escaping characters according to the NDN URI Scheme.
+   * This also adds "..." to a value with zero or more ".".
+   * @param value the buffer with the value to escape
+   * @return The escaped string.
+   */
+  inline static std::string
+  toEscapedString(const uint8_t *value, size_t valueSize)
+  {
+    std::ostringstream result;
+    toEscapedString(value, valueSize, result);
+    return result.str();
+  }
+
+  static inline std::string
+  toEscapedString(const std::vector<uint8_t>& value)
+  {
+    return toEscapedString(&*value.begin(), value.size());
+  }
+  
+  //
+  // vector equivalent interface.
+  //
+
+  /**
+   * @brief Check if name is emtpy
+   */
+  bool
+  empty() const { return components_.empty(); }
+  
+  /**
+   * Get the number of components.
+   * @return The number of components.
+   */
+  size_t 
+  size() const { return components_.size(); }
+
+  /**
+   * Get the component at the given index.
+   * @param i The index of the component, starting from 0.
+   * @return The name component at the index.
+   */
+  const Component& 
+  get(ssize_t i) const
+  {
+    if (i >= 0)
+      return components_[i];
+    else
+      return components_[size() + i];
+  }
+  
+
+  const Component&
+  operator [] (int i) const
+  {
+    return get(i);
+  }
+
+  /**
+   * Append the component
+   * @param component The component of type T.
+   */
+  template<class T> void
+  push_back(const T &component)
+  {
+    append(component);
+  }
+  
+  /**
+   * Check if this name has the same component count and components as the given name.
+   * @param name The Name to check.
+   * @return true if the names are equal, otherwise false.
+   */
+  bool
+  operator == (const Name &name) const { return equals(name); }
+
+  /**
+   * Check if this name has the same component count and components as the given name.
+   * @param name The Name to check.
+   * @return true if the names are not equal, otherwise false.
+   */
+  bool
+  operator != (const Name &name) const { return !equals(name); }
+
+  /**
+   * Compare two names for "less than" using breadth first.  If the first components of each name are not equal, 
+   * this returns true if the first comes before the second using the NDN canonical ordering for name components.
+   * If they are equal, this compares the second components of each name, etc.  If both names are the same up to
+   * the size of the shorter name, this returns true if the first name is shorter than the second.  For example, if you
+   * use breadthFirstLess in std::sort, it gives: /a/b/d	/a/b/cc /c /c/a /bb .  This is intuitive because all names
+   * with the prefix /a are next to each other.  But it may be also be counter-intuitive because /c comes before /bb 
+   * according to NDN canonical ordering since it is shorter.  Note: We don't define this directly as the Name
+   * less than operation because there are other valid ways to sort names.
+   * @param name1 The first name to compare.
+   * @param name2 The second name to compare.
+   * @return True if the first name is less than the second using breadth first comparison.
+   */
+  static bool
+  breadthFirstLess(const Name& name1, const Name& name2);
+  
+  /**
+   * Name::BreadthFirstLess is a function object which calls breadthFirstLess, for use as the "less" operator in map, etc.
+   * For example, you can use Name as the key type in a map as follows: map<Name, int, Name::BreadthFirstLess>.
+   */
+  struct BreadthFirstLess {
+    bool operator() (const Name& name1, const Name& name2) const { return breadthFirstLess(name1, name2); }
+  };
+  
+  //
+  // Iterator interface to name components.
+  //
+  typedef std::vector<Component>::iterator iterator;
+  typedef std::vector<Component>::const_iterator const_iterator;
+  typedef std::vector<Component>::reverse_iterator reverse_iterator;
+  typedef std::vector<Component>::const_reverse_iterator const_reverse_iterator;
+  typedef std::vector<Component>::reference reference;
+  typedef std::vector<Component>::const_reference const_reference;
+
+  typedef std::vector<Component>::difference_type difference_type;
+  typedef std::vector<Component>::size_type size_type;
+  
+  typedef std::vector<Component>::value_type value_type;
+
+  /**
+   * Begin iterator (const).
+   */
+  const_iterator
+  begin() const { return components_.begin(); }
+
+  /**
+   * Begin iterator.
+   */
+  iterator
+  begin() { return components_.begin(); }
+
+  /**
+   * End iterator (const).
+   */
+  const_iterator
+  end() const { return components_.end(); }
+
+  /**
+   * End iterator.
+   */
+  iterator
+  end() { return components_.end(); }
+
+  /**
+   * Reverse begin iterator (const).
+   */
+  const_reverse_iterator
+  rbegin() const { return components_.rbegin(); }
+
+  /**
+   * Reverse begin iterator.
+   */
+  reverse_iterator
+  rbegin() { return components_.rbegin(); }
+
+  /**
+   * Reverse end iterator (const).
+   */
+  const_reverse_iterator
+  rend() const { return components_.rend(); }
+
+  /**
+   * Reverse end iterator.
+   */
+  reverse_iterator
+  rend() { return components_.rend(); }
+
+private:
+  std::vector<Component> components_;
+
+  mutable Block wire_;
+};
+
+std::ostream &
+operator << (std::ostream &os, const Name &name);
+
+inline std::ostream &
+operator << (std::ostream &os, const Name::Component &component)
+{
+  component.toEscapedString(os);
+  return os;
+}
+
+inline std::string 
+Name::toUri() const
+{
+  std::ostringstream os;
+  os << *this;
+  return os.str();
+}
+
+}
+
+#endif
+
diff --git a/include/ndn-cpp-dev/node.hpp b/include/ndn-cpp-dev/node.hpp
new file mode 100644
index 0000000..b5e4e97
--- /dev/null
+++ b/include/ndn-cpp-dev/node.hpp
@@ -0,0 +1,340 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_NODE_HPP
+#define NDN_NODE_HPP
+
+#include "common.hpp"
+#include "interest.hpp"
+#include "data.hpp"
+#include "forwarding-flags.hpp"
+#include "transport/transport.hpp"
+
+
+namespace ndn {
+
+/**
+ * An OnData function object is used to pass a callback to expressInterest.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<const Interest>&, const ptr_lib::shared_ptr<Data>&)> OnData;
+
+/**
+ * An OnTimeout function object is used to pass a callback to expressInterest.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<const Interest>&)> OnTimeout;
+
+/**
+ * An OnInterest function object is used to pass a callback to registerPrefix.
+ */
+typedef func_lib::function<void
+  (const ptr_lib::shared_ptr<const Name>&, const ptr_lib::shared_ptr<const Interest>&, Transport&, uint64_t)> OnInterest;
+
+/**
+ * An OnRegisterFailed function object is used to report when registerPrefix fails.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<const Name>&)> OnRegisterFailed;
+
+class Face;
+    
+class Node {
+public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+  /**
+   * Create a new Node for communication with an NDN hub with the given Transport object and connectionInfo.
+   * @param transport A shared_ptr to a Transport object used for communication.
+   * @param transport A shared_ptr to a Transport::ConnectionInfo to be used to connect to the transport.
+   */
+  Node(const ptr_lib::shared_ptr<Transport>& transport);
+
+  /**
+   * @brief Alternative (special use case) version of the constructor, can be used to aggregate
+   *        several Faces within one processing thread
+   *
+   * <code>
+   *     Face face1(...);
+   *     Face face2(..., face1.getAsyncService());
+   *
+   *     // Now the following ensures that events on both faces are processed
+   *     face1.processEvents();
+   * </code>
+   */
+  Node(const ptr_lib::shared_ptr<Transport>& transport, const ptr_lib::shared_ptr<boost::asio::io_service> &ioService);
+  
+  /**
+   * Send the Interest through the transport, read the entire response and call onData(interest, data).
+   * @param interest A reference to the Interest.  This copies the Interest.
+   * @param onData A function object to call when a matching data packet is received.  This copies the function object, so you may need to
+   * use func_lib::ref() as appropriate.
+   * @param onTimeout A function object to call if the interest times out.  If onTimeout is an empty OnTimeout(), this does not use it.
+   * This copies the function object, so you may need to use func_lib::ref() as appropriate.
+   * @param wireFormat A WireFormat object used to encode the message.
+   * @return The pending interest ID which can be used with removePendingInterest.
+   */
+  uint64_t 
+  expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout);
+  
+  /**
+   * Remove the pending interest entry with the pendingInterestId from the pending interest table.
+   * This does not affect another pending interest with a different pendingInterestId, even it if has the same interest name.
+   * If there is no entry with the pendingInterestId, do nothing.
+   * @param pendingInterestId The ID returned from expressInterest.
+   */
+  void
+  removePendingInterest(uint64_t pendingInterestId);
+  
+  /**
+   * Register prefix with the connected NDN hub and call onInterest when a matching interest is received.
+   * @param prefix A reference to a Name for the prefix to register.  This copies the Name.
+   * @param onInterest A function object to call when a matching interest is received.  This copies the function object, so you may need to
+   * use func_lib::ref() as appropriate.
+   * @param onRegisterFailed A function object to call if failed to retrieve the connected hub’s ID or failed to register the prefix.
+   * This calls onRegisterFailed(prefix) where prefix is the prefix given to registerPrefix.
+   * @param flags The flags for finer control of which interests are forward to the application.
+   * @param wireFormat A WireFormat object used to encode the message.
+   * @return The registered prefix ID which can be used with removeRegisteredPrefix.
+   */
+  uint64_t 
+  registerPrefix
+    (const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags);
+
+  /**
+   * Remove the registered prefix entry with the registeredPrefixId from the pending interest table.  
+   * This does not affect another registered prefix with a different registeredPrefixId, even it if has the same prefix name.
+   * If there is no entry with the registeredPrefixId, do nothing.
+   * @param registeredPrefixId The ID returned from registerPrefix.
+   */
+  void
+  removeRegisteredPrefix(uint64_t registeredPrefixId);
+
+   /**
+   * @brief Publish data packet
+   *
+   * This method can be called to satisfy the incoming Interest or to put Data packet into the cache
+   * of the local NDN forwarder
+   */
+  void
+  put(const Data &data);
+ 
+  /**
+   * Process any data to receive or call timeout callbacks.
+   *
+   * This call will block forever (default timeout == 0) to process IO on the face.
+   * To exit, one expected to call face.shutdown() from one of the callback methods.
+   *
+   * If positive timeout is specified, then processEvents will exit after this timeout,
+   * if not stopped earlier with face.shutdown() or when all active events finish.
+   * The call can be called repeatedly, if desired.
+   *
+   * If negative timeout is specified, then processEvents will not block and process only pending
+   * events.
+   *
+   * @throw This may throw an exception for reading data or in the callback for processing the data.  If you
+   * call this from an main event loop, you may want to catch and log/disregard all exceptions.
+   */
+  void 
+  processEvents(Milliseconds timeout = 0, bool keepThread = false);
+  
+  const ptr_lib::shared_ptr<Transport>& 
+  getTransport() { return transport_; }
+  
+  void 
+  shutdown();
+
+private:
+  void 
+  onReceiveElement(const Block &wire);
+
+  struct ProcessEventsTimeout {};  
+  static void
+  fireProcessEventsTimeout(const boost::system::error_code& error);
+
+private:
+  class PendingInterest {
+  public:
+    /**
+     * Create a new PitEntry and set the timeoutTime_ based on the current time and the interest lifetime.
+     * @param pendingInterestId A unique ID for this entry, which you should get with getNextPendingInteresId().
+     * @param interest A shared_ptr for the interest.
+     * @param onData A function object to call when a matching data packet is received.
+     * @param onTimeout A function object to call if the interest times out.  If onTimeout is an empty OnTimeout(), this does not use it.
+     */
+    PendingInterest
+      (uint64_t pendingInterestId, const ptr_lib::shared_ptr<const Interest>& interest, const OnData& onData, 
+       const OnTimeout& onTimeout);
+    
+    /**
+     * Return the next unique pending interest ID.
+     */
+    static uint64_t 
+    getNextPendingInterestId()
+    {
+      return ++lastPendingInterestId_;
+    }
+    
+    /**
+     * Return the pendingInterestId given to the constructor.
+     */
+    uint64_t 
+    getPendingInterestId() { return pendingInterestId_; }
+    
+    const ptr_lib::shared_ptr<const Interest>& 
+    getInterest() { return interest_; }
+    
+    const OnData& 
+    getOnData() { return onData_; }
+    
+    /**
+     * Check if this interest is timed out.
+     * @param nowMilliseconds The current time in milliseconds from ndn_getNowMilliseconds.
+     * @return true if this interest timed out, otherwise false.
+     */
+    bool 
+    isTimedOut(MillisecondsSince1970 nowMilliseconds)
+    {
+      return timeoutTimeMilliseconds_ >= 0.0 && nowMilliseconds >= timeoutTimeMilliseconds_;
+    }
+
+    /**
+     * Call onTimeout_ (if defined).  This ignores exceptions from the onTimeout_.
+     */
+    void 
+    callTimeout();
+    
+  private:
+    static uint64_t lastPendingInterestId_; /**< A class variable used to get the next unique ID. */
+
+    uint64_t pendingInterestId_;            /**< A unique identifier for this entry so it can be deleted */
+    ptr_lib::shared_ptr<const Interest> interest_;
+    const OnData onData_;
+    const OnTimeout onTimeout_;
+    
+    MillisecondsSince1970 timeoutTimeMilliseconds_; /**< The time when the interest times out in milliseconds according to ndn_getNowMilliseconds, or -1 for no timeout. */
+  };
+
+  class RegisteredPrefix {
+  public:
+    /**
+     * Create a new PrefixEntry.
+     * @param registeredPrefixId A unique ID for this entry, which you should get with getNextRegisteredPrefixId().
+     * @param prefix A shared_ptr for the prefix.
+     * @param onInterest A function object to call when a matching data packet is received.
+     */
+    RegisteredPrefix(uint64_t registeredPrefixId, const ptr_lib::shared_ptr<const Name>& prefix, const OnInterest& onInterest)
+      : registeredPrefixId_(registeredPrefixId)
+      , prefix_(prefix)
+      , onInterest_(onInterest)
+    {
+    }
+    
+    /**
+     * Return the next unique entry ID.
+     */
+    static uint64_t 
+    getNextRegisteredPrefixId()
+    {
+      return ++lastRegisteredPrefixId_;
+    }
+    
+    /**
+     * Return the registeredPrefixId given to the constructor.
+     */
+    uint64_t 
+    getRegisteredPrefixId()
+    {
+      return registeredPrefixId_;
+    }
+    
+    const ptr_lib::shared_ptr<const Name>& 
+    getPrefix()
+    {
+      return prefix_;
+    }
+    
+    const OnInterest& 
+    getOnInterest()
+    {
+      return onInterest_;
+    }
+    
+  private:
+    static uint64_t lastRegisteredPrefixId_; /**< A class variable used to get the next unique ID. */
+
+    uint64_t registeredPrefixId_;            /**< A unique identifier for this entry so it can be deleted */
+    ptr_lib::shared_ptr<const Name> prefix_;
+    const OnInterest onInterest_;
+  };
+  
+  typedef std::vector<ptr_lib::shared_ptr<PendingInterest> > PendingInterestTable;
+  typedef std::vector<ptr_lib::shared_ptr<RegisteredPrefix> > RegisteredPrefixTable;
+  
+  /**
+   * Find the entry from the pit_ where the name conforms to the entry's interest selectors, and
+   * the entry interest name is the longest that matches name.
+   * @param name The name to find the interest for (from the incoming data packet).
+   * @return The index in pit_ of the pit entry, or -1 if not found.
+   */
+  PendingInterestTable::iterator 
+  getEntryIndexForExpressedInterest(const Name& name);
+  
+  /**
+   * Find the first entry from the registeredPrefixTable_ where the entry prefix is the longest that matches name.
+   * @param name The name to find the PrefixEntry for (from the incoming interest packet).
+   * @return A pointer to the entry, or 0 if not found.
+   */
+  RegisteredPrefixTable::iterator
+  getEntryForRegisteredPrefix(const Name& name);
+
+  /**
+   * Do the work of registerPrefix once we know we are connected with an ndndId_.
+   * @param registeredPrefixId The PrefixEntry::getNextRegisteredPrefixId() which registerPrefix got so it could return it to the caller.
+   * @param prefix
+   * @param onInterest
+   * @param onRegisterFailed
+   * @param flags
+   * @param wireFormat
+   */  
+  void 
+  registerPrefixHelper
+    (uint64_t registeredPrefixId, const ptr_lib::shared_ptr<const Name>& prefix, const OnInterest& onInterest, 
+     const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags);
+
+  /**
+   * @brief Final stage of prefix registration, invoked when registration succeeded
+   *
+   * This method actually sets entry in a local interest filter table
+   */
+  void
+  registerPrefixFinal(uint64_t registeredPrefixId,
+                      const ptr_lib::shared_ptr<const Name>& prefix,
+                      const OnInterest& onInterest,
+                      const OnRegisterFailed& onRegisterFailed,
+                      const ptr_lib::shared_ptr<const Interest>&, const ptr_lib::shared_ptr<Data>&);
+  
+  void
+  checkPitExpire();
+  
+private:
+  ptr_lib::shared_ptr<boost::asio::io_service> ioService_;
+  ptr_lib::shared_ptr<boost::asio::io_service::work> ioServiceWork_; // needed if thread needs to be preserved
+  ptr_lib::shared_ptr<boost::asio::deadline_timer> pitTimeoutCheckTimer_;
+  bool pitTimeoutCheckTimerActive_;
+  ptr_lib::shared_ptr<boost::asio::deadline_timer> processEventsTimeoutTimer_;
+  
+  ptr_lib::shared_ptr<Transport> transport_;
+
+  PendingInterestTable pendingInterestTable_;
+  RegisteredPrefixTable registeredPrefixTable_;
+  Interest ndndIdFetcherInterest_;
+
+  int64_t faceId_; // internal face ID (needed for prefix de-registration)
+  Buffer ndndId_;
+};
+
+} // namespace ndn
+
+#endif
diff --git a/include/ndn-cpp-dev/security/certificate-extension.hpp b/include/ndn-cpp-dev/security/certificate-extension.hpp
new file mode 100644
index 0000000..61f7dd2
--- /dev/null
+++ b/include/ndn-cpp-dev/security/certificate-extension.hpp
@@ -0,0 +1,78 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_CERTIFICATE_EXTENSION_HPP
+#define NDN_CERTIFICATE_EXTENSION_HPP
+
+#include "../common.hpp"
+#include "../encoding/buffer.hpp"
+#include "../encoding/oid.hpp"
+
+namespace CryptoPP { class BufferedTransformation; }
+
+namespace ndn {
+
+/**
+ * A CertificateExtension represents the Extension entry in a certificate.
+ */
+class CertificateExtension
+{
+public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+  CertificateExtension(CryptoPP::BufferedTransformation &in)
+  {
+    decode(in);
+  }
+
+  /**
+   * Create a new CertificateExtension.
+   * @param oid The oid of subject description entry.
+   * @param isCritical If true, the extension must be handled.
+   * @param value The extension value.
+   */
+  CertificateExtension(const OID& oid, const bool isCritical, const Buffer& value)
+    : extensionId_(oid), isCritical_(isCritical), extensionValue_(value)
+  {
+  }
+
+  CertificateExtension(const OID& oid, const bool isCritical, const uint8_t* value, size_t valueSize)
+    : extensionId_(oid), isCritical_(isCritical), extensionValue_(value, valueSize)
+  {
+  }
+  
+  /**
+   * The virtual destructor.
+   */
+  virtual
+  ~CertificateExtension() {}
+
+  void
+  encode(CryptoPP::BufferedTransformation &out) const;
+
+  void
+  decode(CryptoPP::BufferedTransformation &in);
+  
+  inline const OID& 
+  getOid() const { return extensionId_; }
+
+  inline const bool 
+  getIsCritical() const { return isCritical_; }
+
+  inline const Buffer& 
+  getValue() const { return extensionValue_; }
+    
+protected:
+  OID extensionId_;
+  bool isCritical_;
+  Buffer extensionValue_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/certificate-subject-description.hpp b/include/ndn-cpp-dev/security/certificate-subject-description.hpp
new file mode 100644
index 0000000..fc26d37
--- /dev/null
+++ b/include/ndn-cpp-dev/security/certificate-subject-description.hpp
@@ -0,0 +1,64 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_CERTIFICATE_SUBJECT_DESCRIPTION_HPP
+#define NDN_CERTIFICATE_SUBJECT_DESCRIPTION_HPP
+
+#include "../common.hpp"
+#include "../encoding/oid.hpp"
+
+namespace CryptoPP { class BufferedTransformation; }
+
+namespace ndn {
+
+/**
+ * A CertificateSubjectDescription represents the SubjectDescription entry in a Certificate.
+ */
+class CertificateSubjectDescription {
+public:
+  CertificateSubjectDescription(CryptoPP::BufferedTransformation &in)
+  {
+    decode(in);
+  }
+  
+  /**
+   * Create a new CertificateSubjectDescription.
+   * @param oid The oid of the subject description entry.
+   * @param value The value of the subject description entry.
+   */
+  CertificateSubjectDescription(const OID &oid, const std::string &value)
+  : oid_(oid), value_(value)
+  {
+  }
+
+  void
+  encode(CryptoPP::BufferedTransformation &out) const;
+
+  void
+  decode(CryptoPP::BufferedTransformation &in);
+  
+  std::string
+  getOidString() const
+  {
+    return oid_.toString();
+  }
+
+  const std::string &
+  getValue() const
+  {
+    return value_;
+  }
+  
+private:
+  OID oid_;
+  std::string value_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/certificate.hpp b/include/ndn-cpp-dev/security/certificate.hpp
new file mode 100644
index 0000000..9871733
--- /dev/null
+++ b/include/ndn-cpp-dev/security/certificate.hpp
@@ -0,0 +1,156 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_CERTIFICATE_HPP
+#define NDN_CERTIFICATE_HPP
+
+#include "../data.hpp"
+#include "../common.hpp"
+
+#include "certificate-subject-description.hpp"
+#include "certificate-extension.hpp"
+#include "public-key.hpp"
+
+namespace ndn {
+
+class Certificate : public Data {
+public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+  typedef std::vector<CertificateSubjectDescription> SubjectDescriptionList;
+  typedef std::vector<CertificateExtension> ExtensionList;
+
+  /**
+   * The default constructor.
+   */
+  Certificate();
+
+  /**
+   * Create a Certificate from the content in the data packet.
+   * @param data The data packet with the content to decode.
+   */
+  Certificate(const Data& data);
+ 
+  /**
+   * The virtual destructor.
+   */
+  virtual 
+  ~Certificate();
+
+  inline void
+  wireDecode(const Block &wire);
+  
+  /**
+   * encode certificate info into content
+   */
+  void
+  encode();
+
+  /**
+   * Add a subject description.
+   * @param description The description to be added.
+   */
+  void 
+  addSubjectDescription(const CertificateSubjectDescription& description) { subjectDescriptionList_.push_back(description); }
+
+  const SubjectDescriptionList& 
+  getSubjectDescriptionList() const { return subjectDescriptionList_; }
+  
+  SubjectDescriptionList& 
+  getSubjectDescriptionList() { return subjectDescriptionList_; }
+ 
+  /**
+   * Add a certificate extension.
+   * @param extension the extension to be added
+   */
+  void 
+  addExtension(const CertificateExtension& extension) { extensionList_.push_back(extension); }
+
+  const ExtensionList&
+  getExtensionList() const { return extensionList_; }
+  
+  ExtensionList&
+  getExtensionList() { return extensionList_; }
+
+  void 
+  setNotBefore(const MillisecondsSince1970& notBefore) { notBefore_ = notBefore; }
+
+  MillisecondsSince1970& 
+  getNotBefore() { return notBefore_; }
+  
+  const MillisecondsSince1970& 
+  getNotBefore() const { return notBefore_; }
+
+  void
+  setNotAfter(const MillisecondsSince1970& notAfter) { notAfter_ = notAfter; }
+
+  MillisecondsSince1970& 
+  getNotAfter() { return notAfter_; }
+
+  const MillisecondsSince1970& 
+  getNotAfter() const { return notAfter_; }
+
+  void
+  setPublicKeyInfo(const PublicKey& key) { key_ = key; }
+  
+  PublicKey& 
+  getPublicKeyInfo() { return key_; }
+
+  const PublicKey& 
+  getPublicKeyInfo() const { return key_; }
+
+  // virtual Name 
+  // getPublicKeyName() const = 0;
+  
+  /**
+   * Check if the certificate is valid.
+   * @return True if the current time is earlier than notBefore.
+   */
+  bool 
+  isTooEarly();
+
+  /**
+   * Check if the certificate is valid.
+   * @return True if the current time is later than notAfter.
+   */
+  bool
+  isTooLate();
+
+  void 
+  printCertificate(std::ostream &os) const;
+
+protected:
+  void
+  decode();
+
+protected:
+  SubjectDescriptionList subjectDescriptionList_;
+  MillisecondsSince1970 notBefore_;
+  MillisecondsSince1970 notAfter_;
+  PublicKey key_;
+  ExtensionList extensionList_;
+};
+
+inline void
+Certificate::wireDecode(const Block &wire)
+{
+  Data::wireDecode(wire);
+  decode();
+}
+
+
+inline std::ostream&
+operator <<(std::ostream &os, const Certificate &cert)
+{
+  cert.printCertificate(os);
+  return os;
+}
+
+} // namespace ndn
+
+#endif
diff --git a/include/ndn-cpp-dev/security/encryption-manager.hpp b/include/ndn-cpp-dev/security/encryption-manager.hpp
new file mode 100644
index 0000000..44eafb7
--- /dev/null
+++ b/include/ndn-cpp-dev/security/encryption-manager.hpp
@@ -0,0 +1,34 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_ENCRYPTION_MANAGER_HPP
+#define NDN_ENCRYPTION_MANAGER_HPP
+
+#include "../../name.hpp"
+#include "../security-common.hpp"
+
+namespace ndn {
+
+class EncryptionManager {
+public:
+  virtual ~EncryptionManager() {}
+    
+  virtual void 
+  createSymmetricKey(const Name& keyName, KeyType keyType, const Name& signkeyName = Name(), bool isSymmetric = true) = 0;
+
+  virtual ConstBufferPtr
+  encrypt(const Name& keyName, const uint8_t* data, size_t dataLength, bool useSymmetric = false, 
+          EncryptMode encryptMode = ENCRYPT_MODE_DEFAULT) = 0;
+
+  virtual ConstBufferPtr
+  decrypt(const Name& keyName, const uint8_t* data, size_t dataLength, bool useSymmetric = false, 
+          EncryptMode encryptMode = ENCRYPT_MODE_DEFAULT) = 0;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/identity-certificate.hpp b/include/ndn-cpp-dev/security/identity-certificate.hpp
new file mode 100644
index 0000000..65b07af
--- /dev/null
+++ b/include/ndn-cpp-dev/security/identity-certificate.hpp
@@ -0,0 +1,112 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_IDENTITY_CERTIFICATE_HPP
+#define NDN_IDENTITY_CERTIFICATE_HPP
+
+#include "certificate.hpp"
+
+namespace ndn {
+
+class IdentityCertificate : public Certificate
+{
+public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+  /**
+   * The default constructor.
+   */
+  inline
+  IdentityCertificate();
+
+  // Note: The copy constructor works because publicKeyName_ has a copy constructor.
+
+  /**
+   * Create an IdentityCertificate from the content in the data packet.
+   * @param data The data packet with the content to decode.
+   */
+  inline
+  IdentityCertificate(const Data& data);
+  
+  /**
+   * The virtual destructor.
+   */
+  inline virtual 
+  ~IdentityCertificate();
+  
+  inline void
+  wireDecode(const Block &wire);
+
+  inline void
+  setName(const Name &name);
+  
+  inline const Name &
+  getPublicKeyName () const;
+
+  static bool
+  isIdentityCertificate(const Certificate& certificate);
+
+  /**
+   * Get the public key name from the full certificate name.
+   * @param certificateName The full certificate name.
+   * @return The related public key name.
+   */
+  static Name
+  certificateNameToPublicKeyName(const Name& certificateName);
+  
+private:
+  static bool
+  isCorrectName(const Name& name);
+  
+  void
+  setPublicKeyName();
+    
+protected:
+  Name publicKeyName_;
+};
+
+inline
+IdentityCertificate::IdentityCertificate()
+{
+}
+
+inline
+IdentityCertificate::IdentityCertificate(const Data& data)
+  : Certificate(data)
+{
+  setPublicKeyName();
+}
+  
+inline
+IdentityCertificate::~IdentityCertificate()
+{
+}
+
+inline void
+IdentityCertificate::wireDecode(const Block &wire)
+{
+  Certificate::wireDecode(wire);
+  setPublicKeyName();
+}
+
+inline void
+IdentityCertificate::setName(const Name &name)
+{
+  Certificate::setName(name);
+  setPublicKeyName();
+}
+
+inline const Name &
+IdentityCertificate::getPublicKeyName () const
+{
+  return publicKeyName_;
+}
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/key-chain.hpp b/include/ndn-cpp-dev/security/key-chain.hpp
new file mode 100644
index 0000000..fffa05d
--- /dev/null
+++ b/include/ndn-cpp-dev/security/key-chain.hpp
@@ -0,0 +1,366 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_KEY_CHAIN_HPP
+#define NDN_KEY_CHAIN_HPP
+
+#include "identity-certificate.hpp"
+#include "public-key.hpp"
+#include "signature-sha256-with-rsa.hpp"
+
+#include "sec-public-info-sqlite3.hpp"
+#include "sec-public-info-memory.hpp"
+#include "sec-tpm-osx.hpp"
+#include "sec-tpm-memory.hpp"
+
+
+namespace ndn {
+
+/**
+ * KeyChain is one of the main classes of the security library.
+ *
+ * The KeyChain class provides a set of interfaces of identity management and private key related operations.
+ */
+template<class Info, class Tpm>
+class KeyChainImpl : public Info, public Tpm
+{
+public:
+  // struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+  
+  /**
+   * Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a self-signed certificate of the KSK.
+   * @param identityName The name of the identity.
+   * @return The key name of the auto-generated KSK of the identity.
+   */
+  Name
+  createIdentity(const Name& identityName)
+  {
+    if (!Info::doesIdentityExist(identityName)) {
+      Info::addIdentity(identityName);
+  
+      Name keyName = generateRSAKeyPairAsDefault(identityName, true);
+
+      ptr_lib::shared_ptr<IdentityCertificate> selfCert = selfSign(keyName); 
+  
+      Info::addCertificateAsDefault(*selfCert);
+
+      return keyName;
+    }
+    else
+      return Name();
+  }
+    
+  /**
+   * Generate a pair of RSA keys for the specified identity.
+   * @param identityName The name of the identity.
+   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
+   * @param keySize The size of the key.
+   * @return The generated key name.
+   */
+  Name
+  generateRSAKeyPair(const Name& identityName, bool isKsk = false, int keySize = 2048)
+  {
+    return generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
+  }
+  
+  /**
+   * Generate a pair of RSA keys for the specified identity and set it as default key for the identity.
+   * @param identityName The name of the identity.
+   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
+   * @param keySize The size of the key.
+   * @return The generated key name.
+   */
+  Name
+  generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk = false, int keySize = 2048)
+  {
+    Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
+
+    Info::setDefaultKeyNameForIdentity(keyName);
+  
+    return keyName;
+  }
+
+  /**
+   * Create an identity certificate for a public key managed by this IdentityManager.
+   * @param certificatePrefix The name of public key to be signed.
+   * @param signerCertificateName The name of signing certificate.
+   * @param notBefore The notBefore value in the validity field of the generated certificate.
+   * @param notAfter The notAfter vallue in validity field of the generated certificate.
+   * @return The name of generated identity certificate.
+   */
+  ptr_lib::shared_ptr<IdentityCertificate>
+  createIdentityCertificate
+    (const Name& certificatePrefix,
+     const Name& signerCertificateName,
+     const MillisecondsSince1970& notBefore, 
+     const MillisecondsSince1970& notAfter)
+  {
+    Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
+    
+    ptr_lib::shared_ptr<PublicKey> pubKey = Info::getPublicKey(keyName);
+    if (!pubKey)
+      throw std::runtime_error("Requested public key [" + keyName.toUri() + "] doesn't exist");
+    
+    ptr_lib::shared_ptr<IdentityCertificate> certificate =
+      createIdentityCertificate(certificatePrefix,
+                                *pubKey,
+                                signerCertificateName,
+                                notBefore, notAfter);
+
+    Info::addCertificate(*certificate);
+  
+    return certificate;
+  }
+
+
+  /**
+   * Create an identity certificate for a public key supplied by the caller.
+   * @param certificatePrefix The name of public key to be signed.
+   * @param publickey The public key to be signed.
+   * @param signerCertificateName The name of signing certificate.
+   * @param notBefore The notBefore value in the validity field of the generated certificate.
+   * @param notAfter The notAfter vallue in validity field of the generated certificate.
+   * @return The generated identity certificate.
+   */
+  ptr_lib::shared_ptr<IdentityCertificate>
+  createIdentityCertificate
+    (const Name& certificatePrefix,
+     const PublicKey& publicKey,
+     const Name& signerCertificateName, 
+     const MillisecondsSince1970& notBefore,
+     const MillisecondsSince1970& notAfter)
+  {
+    ptr_lib::shared_ptr<IdentityCertificate> certificate (new IdentityCertificate());
+    Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
+  
+    Name certificateName = certificatePrefix;
+    certificateName.append("ID-CERT").appendVersion();
+  
+    certificate->setName(certificateName);
+    certificate->setNotBefore(notBefore);
+    certificate->setNotAfter(notAfter);
+    certificate->setPublicKeyInfo(publicKey);
+    certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
+    certificate->encode();
+
+    sign(*certificate, signerCertificateName);
+
+    return certificate;
+  }
+
+  void
+  sign(Data &data)
+  {
+    if (!Info::defaultCertificate())
+      {
+        Info::refreshDefaultCertificate();
+
+        if(!Info::defaultCertificate())
+          throw std::runtime_error("Default IdentityCertificate cannot be determined");
+      }
+
+    sign(data, *Info::defaultCertificate());
+  }
+  
+  /**
+   * Wire encode the Data object, sign it and set its signature.
+   * @param data The Data object to be signed.  This updates its signature and key locator field and wireEncoding.
+   * @param certificateName The certificate name of the key to use for signing.  If omitted, infer the signing identity from the data packet name.
+   */
+  void 
+  sign(Data& data, const Name& certificateName)
+  {
+    ptr_lib::shared_ptr<IdentityCertificate> cert = Info::getCertificate(certificateName);
+    if (!cert)
+      throw std::runtime_error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
+
+    SignatureSha256WithRsa signature;
+    signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
+    data.setSignature(signature);
+
+    // For temporary usage, we support RSA + SHA256 only, but will support more.
+    Tpm::signInTpm(data, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
+  }
+
+  void
+  sign(Data& data, const IdentityCertificate& certificate)
+  {
+    SignatureSha256WithRsa signature;
+    signature.setKeyLocator(certificate.getName().getPrefix(-1));
+    data.setSignature(signature);
+
+    // For temporary usage, we support RSA + SHA256 only, but will support more.
+    Tpm::signInTpm(data, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
+  }
+  
+  /**
+   * Sign the byte array using a certificate name and return a Signature object.
+   * @param buffer The byte array to be signed.
+   * @param bufferLength the length of buffer.
+   * @param certificateName The certificate name used to get the signing key and which will be put into KeyLocator.
+   * @return The Signature.
+   */
+  Signature
+  sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
+  {
+    ptr_lib::shared_ptr<IdentityCertificate> cert = Info::getCertificate(certificateName);
+    if (!cert)
+      throw std::runtime_error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
+
+    SignatureSha256WithRsa signature;
+    signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
+  
+    // For temporary usage, we support RSA + SHA256 only, but will support more.
+    signature.setValue(Tpm::signInTpm(buffer, bufferLength, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
+    return signature;
+  }
+
+  /**
+   * Wire encode the Data object, sign it and set its signature.
+   * @param data The Data object to be signed.  This updates its signature and key locator field and wireEncoding.
+   * @param identityName The identity name for the key to use for signing.  If omitted, infer the signing identity from the data packet name.
+   */
+  void 
+  signByIdentity(Data& data, const Name& identityName = Name())
+  {
+    Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
+
+    if (signingCertificateName.getComponentCount() == 0)
+      throw std::runtime_error("No qualified certificate name found!");
+
+    sign(data, signingCertificateName);
+  }
+
+  /**
+   * Sign the byte array using an identity name and return a Signature object.
+   * @param buffer The byte array to be signed.
+   * @param bufferLength the length of buffer.
+   * @param identityName The identity name.
+   * @return The Signature.
+   */
+  Signature
+  signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName = Name())
+  {
+    Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
+    
+    if (signingCertificateName.size() == 0)
+      throw std::runtime_error("No qualified certificate name found!");
+
+    return sign(buffer, bufferLength, signingCertificateName);
+  }
+
+  /**
+   * Generate a self-signed certificate for a public key.
+   * @param keyName The name of the public key.
+   * @return The generated certificate.
+   */
+  ptr_lib::shared_ptr<IdentityCertificate>
+  selfSign(const Name& keyName)
+  {
+    if(keyName.empty())
+      throw std::runtime_error("Incorrect key name: " + keyName.toUri());
+
+    ptr_lib::shared_ptr<IdentityCertificate> certificate = ptr_lib::make_shared<IdentityCertificate>();
+    
+    Name certificateName = keyName.getPrefix(-1);
+    certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
+    
+    ptr_lib::shared_ptr<PublicKey> pubKey = Info::getPublicKey(keyName);
+    if (!pubKey)
+      throw std::runtime_error("Requested public key [" + keyName.toUri() + "] doesn't exist");
+  
+    certificate->setName(certificateName);
+    certificate->setNotBefore(getNow());
+    certificate->setNotAfter(getNow() + 630720000 /* 20 years*/);
+    certificate->setPublicKeyInfo(*pubKey);
+    certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
+    certificate->encode();
+
+    selfSign(*certificate);
+    return certificate;
+  }
+
+  /**
+   * @brief Self-sign the supplied identity certificate
+   */
+  void
+  selfSign (IdentityCertificate& cert)
+  {
+    SignatureSha256WithRsa signature;
+    signature.setKeyLocator(cert.getName().getPrefix(-1)); // implicit conversion should take care
+    cert.setSignature(signature);
+
+    // For temporary usage, we support RSA + SHA256 only, but will support more.
+    Tpm::signInTpm(cert, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
+  }
+
+
+private:
+  /**
+   * Generate a key pair for the specified identity.
+   * @param identityName The name of the specified identity.
+   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
+   * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
+   * @param keySize The size of the key pair.
+   * @return The name of the generated key.
+   */
+  Name
+  generateKeyPair(const Name& identityName, bool isKsk = false, KeyType keyType = KEY_TYPE_RSA, int keySize = 2048)
+  {
+    Name keyName = Info::getNewKeyName(identityName, isKsk);
+
+    Tpm::generateKeyPairInTpm(keyName.toUri(), keyType, keySize);
+
+    ptr_lib::shared_ptr<PublicKey> pubKey = Tpm::getPublicKeyFromTpm(keyName.toUri());
+    Info::addPublicKey(keyName, keyType, *pubKey);
+
+    return keyName;
+  }
+
+  static Name
+  getKeyNameFromCertificatePrefix(const Name& certificatePrefix)
+  {
+    Name result;
+
+    std::string keyString("KEY");
+    int i = 0;
+    for(; i < certificatePrefix.size(); i++) {
+      if (certificatePrefix.get(i).toEscapedString() == keyString)
+        break;
+    }
+    
+    if (i >= certificatePrefix.size())
+      throw std::runtime_error("Identity Certificate Prefix does not have a KEY component");
+
+    result.append(certificatePrefix.getSubName(0, i));
+    result.append(certificatePrefix.getSubName(i + 1, certificatePrefix.size()-i-1));
+    
+    return result;
+  }
+
+};
+
+}
+
+#ifdef NDN_CPP_HAVE_OSX_SECURITY
+
+namespace ndn
+{
+typedef KeyChainImpl<SecPublicInfoSqlite3, SecTpmOsx> KeyChain;
+};
+
+#else
+
+namespace ndn
+{
+typedef KeyChainImpl<SecPublicInfoMemory, SecTpmMemory> KeyChain;
+};
+
+#endif //NDN_CPP_HAVE_OSX_SECURITY
+
+#endif
diff --git a/include/ndn-cpp-dev/security/public-key.hpp b/include/ndn-cpp-dev/security/public-key.hpp
new file mode 100644
index 0000000..5a70e38
--- /dev/null
+++ b/include/ndn-cpp-dev/security/public-key.hpp
@@ -0,0 +1,84 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_PUBLIC_KEY_HPP
+#define NDN_PUBLIC_KEY_HPP
+
+#include <stdexcept>
+#include "../encoding/oid.hpp"
+#include "../encoding/buffer.hpp"
+#include "security-common.hpp"
+
+namespace ndn {
+
+class PublicKey {
+public:    
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+  /**
+   * The default constructor.
+   */
+  PublicKey();
+
+  /**
+   * Create a new PublicKey with the given values.
+   * @param algorithm The algorithm of the public key.
+   * @param keyDer The blob of the PublicKeyInfo in terms of DER.
+   *
+   * @throws PublicKey::Error If algorithm is not supported or keyDer cannot be decoded
+   */
+  PublicKey(const uint8_t *keyDerBuf, size_t keyDerSize);
+
+  inline const Buffer&
+  get() const
+  {
+    return key_;
+  }
+
+  inline void
+  set(const uint8_t *keyDerBuf, size_t keyDerSize)
+  {
+    Buffer buf(keyDerBuf, keyDerSize);
+    key_.swap(buf);
+  }
+
+  void
+  encode(CryptoPP::BufferedTransformation &out) const;
+
+  void
+  decode(CryptoPP::BufferedTransformation &in);
+
+  // /*
+  //  * Get the digest of the public key.
+  //  * @param digestAlgorithm The digest algorithm. If omitted, use DIGEST_ALGORITHM_SHA256 by default.
+  //  */
+  // Blob 
+  // getDigest(DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256) const;
+
+  inline bool
+  operator ==(const PublicKey &key) const
+  {
+    return key_ == key.key_;
+  }
+
+  inline bool
+  operator !=(const PublicKey &key) const
+  {
+    return key_ != key.key_;
+  }
+  
+private:
+  Buffer key_;
+};
+
+std::ostream &
+operator <<(std::ostream &os, const PublicKey &key);
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-policy-no-verify.hpp b/include/ndn-cpp-dev/security/sec-policy-no-verify.hpp
new file mode 100644
index 0000000..1d2927e
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-policy-no-verify.hpp
@@ -0,0 +1,72 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_POLICY_NO_VERIFY_HPP
+#define NDN_SEC_POLICY_NO_VERIFY_HPP
+
+#include "sec-policy.hpp"
+
+namespace ndn {
+
+class SecPolicyNoVerify : public SecPolicy {
+public:
+  /**
+   * The virtual destructor.
+   */
+  virtual
+  ~SecPolicyNoVerify();
+
+  /**
+   * Override to always skip verification and trust as valid.
+   * @param data The received data packet.
+   * @return true.
+   */
+  virtual bool 
+  skipVerifyAndTrust(const Data& data);
+
+  /**
+   * Override to return false for no verification rule for the received data.
+   * @param data The received data packet.
+   * @return false.
+   */
+  virtual bool
+  requireVerify(const Data& data);
+
+  /**
+   * Override to call onVerified(data) and to indicate no further verification step.
+   * @param data The Data object with the signature to check.
+   * @param stepCount The number of verification steps that have been done, used to track the verification progress.
+   * @param onVerified This does override to call onVerified(data).
+   * @param onVerifyFailed Override to ignore this.
+   * @return null for no further step.
+   */
+  virtual ptr_lib::shared_ptr<ValidationRequest>
+  checkVerificationPolicy
+    (const ptr_lib::shared_ptr<Data>& data, int stepCount, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed);
+    
+  /**
+   * Override to always indicate that the signing certificate name and data name satisfy the signing policy.
+   * @param dataName The name of data to be signed.
+   * @param certificateName The name of signing certificate.
+   * @return true to indicate that the signing certificate can be used to sign the data.
+   */
+  virtual bool 
+  checkSigningPolicy(const Name& dataName, const Name& certificateName);
+    
+  /**
+   * Override to indicate that the signing identity cannot be inferred.
+   * @param dataName The name of data to be signed.
+   * @return An empty name because cannot infer. 
+   */
+  virtual Name 
+  inferSigningIdentity(const Name& dataName);
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-policy-self-verify.hpp b/include/ndn-cpp-dev/security/sec-policy-self-verify.hpp
new file mode 100644
index 0000000..111b61a
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-policy-self-verify.hpp
@@ -0,0 +1,91 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_POLICY_SELF_VERIFY_HPP
+#define NDN_SEC_POLICY_SELF_VERIFY_HPP
+
+#include "sec-policy.hpp"
+
+namespace ndn {
+
+/**
+ * A SecPolicySelfVerify implements a PolicyManager to use the public key DER in the data packet's KeyLocator (if available)
+ * or look in the IdentityStorage for the public key with the name in the KeyLocator (if available) and use
+ * it to verify the data packet, without searching a certificate chain.  If the public key can't be found, the
+ * verification fails.
+ */
+class SecPolicySelfVerify : public SecPolicy {
+public:
+  /**
+   * Create a new SecPolicySelfVerify which will look up the public key in the given identityManager.
+   * @param identityManager (optional) The IdentityManager for looking up the public key.  This points to an object must which remain 
+   * valid during the life of this SecPolicySelfVerify.  If omitted, then don't look for a public key with the name 
+   * in the KeyLocator and rely on the KeyLocator having the full public key DER.
+   */
+  SecPolicySelfVerify()
+  {
+  }
+  
+  /**
+   * The virtual destructor.
+   */
+  virtual
+  ~SecPolicySelfVerify();
+
+  /**
+   * Never skip verification.
+   * @param data The received data packet.
+   * @return false.
+   */
+  virtual bool 
+  skipVerifyAndTrust(const Data& data);
+
+  /**
+   * Always return true to use the self-verification rule for the received data.
+   * @param data The received data packet.
+   * @return true.
+   */
+  virtual bool
+  requireVerify(const Data& data);
+
+  /**
+   * Use the public key DER in the data packet's KeyLocator (if available) or look in the IdentityStorage for the 
+   * public key with the name in the KeyLocator (if available) and use it to verify the data packet.  If the public key can't 
+   * be found, call onVerifyFailed.
+   * @param data The Data object with the signature to check.
+   * @param stepCount The number of verification steps that have been done, used to track the verification progress.
+   * (stepCount is ignored.)
+   * @param onVerified If the signature is verified, this calls onVerified(data).
+   * @param onVerifyFailed If the signature check fails or can't find the public key, this calls onVerifyFailed(data).
+   * @return null for no further step for looking up a certificate chain.
+   */
+  virtual ptr_lib::shared_ptr<ValidationRequest>
+  checkVerificationPolicy
+    (const ptr_lib::shared_ptr<Data>& data, int stepCount, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed);
+    
+  /**
+   * Override to always indicate that the signing certificate name and data name satisfy the signing policy.
+   * @param dataName The name of data to be signed.
+   * @param certificateName The name of signing certificate.
+   * @return true to indicate that the signing certificate can be used to sign the data.
+   */
+  virtual bool 
+  checkSigningPolicy(const Name& dataName, const Name& certificateName);
+    
+  /**
+   * Override to indicate that the signing identity cannot be inferred.
+   * @param dataName The name of data to be signed.
+   * @return An empty name because cannot infer. 
+   */
+  virtual Name 
+  inferSigningIdentity(const Name& dataName);
+  
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-policy.hpp b/include/ndn-cpp-dev/security/sec-policy.hpp
new file mode 100644
index 0000000..e3879bb
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-policy.hpp
@@ -0,0 +1,79 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_POLICY_HPP
+#define NDN_SEC_POLICY_HPP
+
+#include "../data.hpp"
+#include "validation-request.hpp"
+
+namespace ndn {
+  
+/**
+ * A SecPolicy is an abstract base class to represent the policy for verifying data packets.
+ * You must create an object of a subclass.
+ */
+class SecPolicy {
+public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+  /**
+   * The virtual destructor.
+   */
+  virtual
+  ~SecPolicy() {}
+
+  /**
+   * Check if the received data packet can escape from verification and be trusted as valid.
+   * @param data The received data packet.
+   * @return true if the data does not need to be verified to be trusted as valid, otherwise false.
+   */
+  virtual bool 
+  skipVerifyAndTrust(const Data& data) = 0;
+
+  /**
+   * Check if this SecPolicy has a verification rule for the received data.
+   * @param data The received data packet.
+   * @return true if the data must be verified, otherwise false.
+   */
+  virtual bool
+  requireVerify(const Data& data) = 0;
+
+  /**
+   * Check whether the received data packet complies with the verification policy, and get the indication of the next verification step.
+   * @param data The Data object with the signature to check.
+   * @param stepCount The number of verification steps that have been done, used to track the verification progress.
+   * @param onVerified If the signature is verified, this calls onVerified(data).
+   * @param onVerifyFailed If the signature check fails, this calls onVerifyFailed(data).
+   * @return the indication of next verification step, null if there is no further step.
+   */
+  virtual ptr_lib::shared_ptr<ValidationRequest>
+  checkVerificationPolicy
+    (const ptr_lib::shared_ptr<Data>& data, int stepCount, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed) = 0;
+    
+  /**
+   * Check if the signing certificate name and data name satisfy the signing policy.
+   * @param dataName The name of data to be signed.
+   * @param certificateName The name of signing certificate.
+   * @return true if the signing certificate can be used to sign the data, otherwise false.
+   */
+  virtual bool 
+  checkSigningPolicy(const Name& dataName, const Name& certificateName) = 0;
+    
+  /**
+   * Infer the signing identity name according to the policy. If the signing identity cannot be inferred, return an empty name.
+   * @param dataName The name of data to be signed.
+   * @return The signing identity or an empty name if cannot infer. 
+   */
+  virtual Name 
+  inferSigningIdentity(const Name& dataName) = 0;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-public-info-memory.hpp b/include/ndn-cpp-dev/security/sec-public-info-memory.hpp
new file mode 100644
index 0000000..c991f1a
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-public-info-memory.hpp
@@ -0,0 +1,217 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_PUBLIC_INFO_MEMORY_HPP
+#define NDN_SEC_PUBLIC_INFO_MEMORY_HPP
+
+#include <vector>
+#include <map>
+#include "sec-public-info.hpp"
+
+namespace ndn {
+
+/**
+ * MemoryKeyMetaInfo extends IdentityStorage and implements its methods to store identity, public key and certificate objects in memory.
+ * The application must get the objects through its own means and add the objects to the MemoryKeyMetaInfo object.
+ * To use permanent file-based storage, see BasicKeyMetaInfo.
+ */
+class SecPublicInfoMemory : public SecPublicInfo {
+public:
+  struct Error : public SecPublicInfo::Error { Error(const std::string &what) : SecPublicInfo::Error(what) {} };
+
+  /**
+   * The virtual Destructor.
+   */
+  virtual 
+  ~SecPublicInfoMemory();
+
+  /**
+   * Check if the specified identity already exists.
+   * @param identityName The identity name.
+   * @return true if the identity exists, otherwise false.
+   */
+  virtual bool 
+  doesIdentityExist(const Name& identityName);
+
+  /**
+   * Add a new identity. An exception will be thrown if the identity already exists.
+   * @param identityName The identity name to be added.
+   */
+  virtual void
+  addIdentity(const Name& identityName);
+
+  /**
+   * Revoke the identity.
+   * @return true if the identity was revoked, false if not.
+   */
+  virtual bool 
+  revokeIdentity();
+
+  /**
+   * Check if the specified key already exists.
+   * @param keyName The name of the key.
+   * @return true if the key exists, otherwise false.
+   */
+  virtual bool 
+  doesPublicKeyExist(const Name& keyName);
+
+  /**
+   * Add a public key to the identity storage.
+   * @param keyName The name of the public key to be added.
+   * @param keyType Type of the public key to be added.
+   * @param publicKeyDer A blob of the public key DER to be added.
+   */
+  virtual void 
+  addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer);
+
+  /**
+   * Get the public key DER blob from the identity storage.
+   * @param keyName The name of the requested public key.
+   * @return The DER Blob.  If not found, return a Blob with a null pointer.
+   */
+  virtual ptr_lib::shared_ptr<PublicKey>
+  getPublicKey(const Name& keyName);
+
+  /**
+   * Activate a key.  If a key is marked as inactive, its private part will not be used in packet signing.
+   * @param keyName name of the key
+   */
+  virtual void 
+  activatePublicKey(const Name& keyName);
+
+  /**
+   * Deactivate a key. If a key is marked as inactive, its private part will not be used in packet signing.
+   * @param keyName name of the key
+   */
+  virtual void 
+  deactivatePublicKey(const Name& keyName);
+
+  /**
+   * Check if the specified certificate already exists.
+   * @param certificateName The name of the certificate.
+   * @return true if the certificate exists, otherwise false.
+   */
+  virtual bool
+  doesCertificateExist(const Name& certificateName);
+
+  /**
+   * Add a certificate to the identity storage.
+   * @param certificate The certificate to be added.  This makes a copy of the certificate.
+   */
+  virtual void 
+  addCertificate(const IdentityCertificate& certificate);
+
+  /**
+   * Get a certificate from the identity storage.
+   * @param certificateName The name of the requested certificate.
+   * @param allowAny If false, only a valid certificate will be returned, otherwise validity is disregarded.
+   * @return The requested certificate.  If not found, return a shared_ptr with a null pointer.
+   */
+  virtual ptr_lib::shared_ptr<IdentityCertificate> 
+  getCertificate(const Name &certificateName);
+
+
+  /*****************************************
+   *           Get/Set Default             *
+   *****************************************/
+
+  /**
+   * Get the default identity. 
+   * @param return The name of default identity, or an empty name if there is no default.
+   */
+  virtual Name 
+  getDefaultIdentity();
+
+  /**
+   * Get the default key name for the specified identity.
+   * @param identityName The identity name.
+   * @return The default key name.
+   */
+  virtual Name 
+  getDefaultKeyNameForIdentity(const Name& identityName);
+
+  /**
+   * Get the default certificate name for the specified key.
+   * @param keyName The key name.
+   * @return The default certificate name.
+   */
+  virtual Name 
+  getDefaultCertificateNameForKey(const Name& keyName);
+
+  virtual std::vector<Name>
+  getAllIdentities(bool isDefault);
+
+  virtual std::vector<Name>
+  getAllKeyNames(bool isDefault);
+
+  virtual std::vector<Name>
+  getAllKeyNamesOfIdentity(const Name& identity, bool isDefault);
+    
+  virtual std::vector<Name>
+  getAllCertificateNames(bool isDefault);
+
+  virtual std::vector<Name>
+  getAllCertificateNamesOfKey(const Name& keyName, bool isDefault);
+
+protected:
+  /**
+   * Set the default identity.  If the identityName does not exist, then clear the default identity
+   * so that getDefaultIdentity() returns an empty name.
+   * @param identityName The default identity name.
+   */
+  virtual void 
+  setDefaultIdentityInternal(const Name& identityName);
+
+  /**
+   * Set the default key name for the specified identity.
+   * @param keyName The key name.
+   * @param identityNameCheck (optional) The identity name to check the keyName.
+   */
+  virtual void 
+  setDefaultKeyNameForIdentityInternal(const Name& keyName);
+
+  /**
+   * Set the default key name for the specified identity.
+   * @param keyName The key name.
+   * @param certificateName The certificate name.
+   */
+  virtual void 
+  setDefaultCertificateNameForKeyInternal(const Name& certificateName);  
+
+  
+private:
+  class KeyRecord {
+  public:
+    KeyRecord(KeyType keyType, const PublicKey &key)
+    : keyType_(keyType), key_(key)
+    {
+    }
+    
+    const KeyType getKeyType() const { return keyType_; }
+    
+    const PublicKey& getKey() { return key_; }
+    
+  private:
+    KeyType   keyType_;
+    PublicKey key_;
+  };
+  
+  std::vector<std::string> identityStore_; /**< A list of name URI. */
+  std::string defaultIdentity_;            /**< The default identity in identityStore_, or "" if not defined. */
+  Name defaultKeyName_;
+  Name defaultCert_;
+
+  typedef std::map< std::string, ptr_lib::shared_ptr<KeyRecord> > KeyStore; /**< The map key is the keyName.toUri() */
+  typedef std::map< std::string, ptr_lib::shared_ptr<IdentityCertificate> > CertificateStore; /**< The map key is the certificateName.toUri() */
+  
+  KeyStore keyStore_; 
+  CertificateStore certificateStore_;                    
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-public-info-sqlite3.hpp b/include/ndn-cpp-dev/security/sec-public-info-sqlite3.hpp
new file mode 100644
index 0000000..f83c27e
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-public-info-sqlite3.hpp
@@ -0,0 +1,223 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_PUBLIC_INFO_SQLITE3_HPP
+#define NDN_SEC_PUBLIC_INFO_SQLITE3_HPP
+
+// Only compile if ndn-cpp-config.h defines NDN_CPP_HAVE_SQLITE3.
+#include <ndn-cpp-dev/ndn-cpp-config.h>
+#ifdef NDN_CPP_HAVE_SQLITE3
+
+#include <sqlite3.h>
+#include "../common.hpp"
+#include "sec-public-info.hpp"
+
+namespace ndn
+{
+  
+/**
+ * BasicIdentityStorage extends IdentityStorage to implement a basic storage of identity, public keys and certificates
+ * using SQLite.
+ */
+class SecPublicInfoSqlite3 : public SecPublicInfo {
+public:
+  struct Error : public SecPublicInfo::Error { Error(const std::string &what) : SecPublicInfo::Error(what) {} };
+
+  SecPublicInfoSqlite3();
+  
+  /**
+   * The virtual Destructor.
+   */
+  virtual 
+  ~SecPublicInfoSqlite3();
+
+  // from SecPublicInfo
+  /**
+   * Check if the specified identity already exists.
+   * @param identityName The identity name.
+   * @return true if the identity exists, otherwise false.
+   */
+  virtual bool 
+  doesIdentityExist(const Name& identityName);
+
+  /**
+   * Add a new identity. An exception will be thrown if the identity already exists.
+   * @param identityName The identity name to be added.
+   */
+  virtual void
+  addIdentity(const Name& identityName);
+
+  /**
+   * Revoke the identity.
+   * @return true if the identity was revoked, false if not.
+   */
+  virtual bool 
+  revokeIdentity();
+
+  /**
+   * Check if the specified key already exists.
+   * @param keyName The name of the key.
+   * @return true if the key exists, otherwise false.
+   */
+  virtual bool 
+  doesPublicKeyExist(const Name& keyName);
+
+  /**
+   * Add a public key to the identity storage.
+   * @param keyName The name of the public key to be added.
+   * @param keyType Type of the public key to be added.
+   * @param publicKeyDer A blob of the public key DER to be added.
+   */
+  virtual void 
+  addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer);
+
+  /**
+   * Get the public key DER blob from the identity storage.
+   * @param keyName The name of the requested public key.
+   * @return The DER Blob.  If not found, return a Blob with a null pointer.
+   */
+  virtual ptr_lib::shared_ptr<PublicKey>
+  getPublicKey(const Name& keyName);
+
+  /**
+   * Activate a key.  If a key is marked as inactive, its private part will not be used in packet signing.
+   * @param keyName name of the key
+   */
+  virtual inline void 
+  activatePublicKey(const Name& keyName);
+
+  /**
+   * Deactivate a key. If a key is marked as inactive, its private part will not be used in packet signing.
+   * @param keyName name of the key
+   */
+  virtual inline void 
+  deactivatePublicKey(const Name& keyName);
+
+  /**
+   * Check if the specified certificate already exists.
+   * @param certificateName The name of the certificate.
+   * @return true if the certificate exists, otherwise false.
+   */
+  virtual bool
+  doesCertificateExist(const Name& certificateName);
+
+  /**
+   * Add a certificate in to the identity storage without checking if the identity and key exists.
+   * @param certificate The certificate to be added.
+   */
+  virtual void
+  addAnyCertificate (const IdentityCertificate& certificate);
+
+  /**
+   * Add a certificate to the identity storage.
+   * @param certificate The certificate to be added.  This makes a copy of the certificate.
+   */
+  virtual void 
+  addCertificate(const IdentityCertificate& certificate);
+
+  /**
+   * Get a certificate from the identity storage.
+   * @param certificateName The name of the requested certificate.
+   * @param allowAny If false, only a valid certificate will be returned, otherwise validity is disregarded.
+   * @return The requested certificate.  If not found, return a shared_ptr with a null pointer.
+   */
+  virtual ptr_lib::shared_ptr<IdentityCertificate> 
+  getCertificate(const Name &certificateName);
+
+
+  /*****************************************
+   *            Default Getter             *
+   *****************************************/
+
+  /**
+   * Get the default identity. 
+   * @param return The name of default identity, or an empty name if there is no default.
+   */
+  virtual Name 
+  getDefaultIdentity();
+
+  /**
+   * Get the default key name for the specified identity.
+   * @param identityName The identity name.
+   * @return The default key name.
+   */
+  virtual Name 
+  getDefaultKeyNameForIdentity(const Name& identityName);
+
+  /**
+   * Get the default certificate name for the specified key.
+   * @param keyName The key name.
+   * @return The default certificate name.
+   */
+  virtual Name 
+  getDefaultCertificateNameForKey(const Name& keyName);
+
+  virtual std::vector<Name>
+  getAllIdentities(bool isDefault);
+
+  virtual std::vector<Name>
+  getAllKeyNames(bool isDefault);
+
+  virtual std::vector<Name>
+  getAllKeyNamesOfIdentity(const Name& identity, bool isDefault);
+    
+  virtual std::vector<Name>
+  getAllCertificateNames(bool isDefault);
+
+  virtual std::vector<Name>
+  getAllCertificateNamesOfKey(const Name& keyName, bool isDefault);
+  
+protected:
+  /**
+   * Set the default identity.  If the identityName does not exist, then clear the default identity
+   * so that getDefaultIdentity() returns an empty name.
+   * @param identityName The default identity name.
+   */
+  virtual void 
+  setDefaultIdentityInternal(const Name& identityName);
+
+  /**
+   * Set the default key name for the specified identity.
+   * @param keyName The key name.
+   * @param identityNameCheck (optional) The identity name to check the keyName.
+   */
+  virtual void
+  setDefaultKeyNameForIdentityInternal(const Name& keyName);
+
+  /**
+   * Set the default key name for the specified identity.
+   * @param keyName The key name.
+   * @param certificateName The certificate name.
+   */
+  virtual void 
+  setDefaultCertificateNameForKeyInternal(const Name& certificateName);  
+  
+private:
+  void
+  updateKeyStatus(const Name& keyName, bool isActive);
+
+  sqlite3 *database_;
+};
+
+void
+SecPublicInfoSqlite3::activatePublicKey(const Name& keyName)
+{
+  updateKeyStatus(keyName, true);
+}
+
+void
+SecPublicInfoSqlite3::deactivatePublicKey(const Name& keyName)
+{
+  updateKeyStatus(keyName, false);
+}
+
+}
+
+#endif // NDN_CPP_HAVE_SQLITE3
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-public-info.hpp b/include/ndn-cpp-dev/security/sec-public-info.hpp
new file mode 100644
index 0000000..7cd7230
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-public-info.hpp
@@ -0,0 +1,380 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_PUBLIC_INFO_HPP
+#define NDN_SEC_PUBLIC_INFO_HPP
+
+#include "../name.hpp"
+#include "security-common.hpp"
+#include "public-key.hpp"
+#include "identity-certificate.hpp"
+
+
+namespace ndn {
+
+/**
+ * SecPublicInfo is a base class for the storage of identity, public keys and certificates. 
+ * Private keys are stored in SecTpm.
+ * This is an abstract base class.  A subclass must implement the methods.
+ */
+class SecPublicInfo {
+public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+  /**
+   * The virtual Destructor.
+   */
+  virtual 
+  ~SecPublicInfo() {}
+
+  /**
+   * Check if the specified identity already exists.
+   * @param identityName The identity name.
+   * @return true if the identity exists, otherwise false.
+   */
+  virtual bool 
+  doesIdentityExist(const Name& identityName) = 0;
+
+  /**
+   * Add a new identity. An exception will be thrown if the identity already exists.
+   * @param identityName The identity name to be added.
+   */
+  virtual void
+  addIdentity(const Name& identityName) = 0;
+
+  /**
+   * Revoke the identity.
+   * @return true if the identity was revoked, false if not.
+   */
+  virtual bool 
+  revokeIdentity() = 0;
+
+  /**
+   * Check if the specified key already exists.
+   * @param keyName The name of the key.
+   * @return true if the key exists, otherwise false.
+   */
+  virtual bool 
+  doesPublicKeyExist(const Name& keyName) = 0;
+
+  /**
+   * Add a public key to the identity storage.
+   * @param keyName The name of the public key to be added.
+   * @param keyType Type of the public key to be added.
+   * @param publicKeyDer A blob of the public key DER to be added.
+   */
+  virtual void 
+  addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer) = 0;
+
+  /**
+   * Get the public key DER blob from the identity storage.
+   * @param keyName The name of the requested public key.
+   * @return The DER Blob.  If not found, return a Blob with a null pointer.
+   */
+  virtual ptr_lib::shared_ptr<PublicKey>
+  getPublicKey(const Name& keyName) = 0;
+
+  /**
+   * Activate a key.  If a key is marked as inactive, its private part will not be used in packet signing.
+   * @param keyName name of the key
+   */
+  virtual void 
+  activatePublicKey(const Name& keyName) = 0;
+
+  /**
+   * Deactivate a key. If a key is marked as inactive, its private part will not be used in packet signing.
+   * @param keyName name of the key
+   */
+  virtual void 
+  deactivatePublicKey(const Name& keyName) = 0;
+
+  /**
+   * Check if the specified certificate already exists.
+   * @param certificateName The name of the certificate.
+   * @return true if the certificate exists, otherwise false.
+   */
+  virtual bool
+  doesCertificateExist(const Name& certificateName) = 0;
+
+  /**
+   * Add a certificate to the identity storage.
+   * @param certificate The certificate to be added.  This makes a copy of the certificate.
+   */
+  virtual void 
+  addCertificate(const IdentityCertificate& certificate) = 0;
+
+  /**
+   * Get a certificate from the identity storage.
+   * @param certificateName The name of the requested certificate.
+   * @param allowAny If false, only a valid certificate will be returned, otherwise validity is disregarded.
+   * @return The requested certificate.  If not found, return a shared_ptr with a null pointer.
+   */
+  virtual ptr_lib::shared_ptr<IdentityCertificate> 
+  getCertificate(const Name &certificateName) = 0;
+
+
+  /*****************************************
+   *            Default Getter             *
+   *****************************************/
+
+  /**
+   * Get the default identity. 
+   * @param return The name of default identity, or an empty name if there is no default.
+   */
+  virtual Name 
+  getDefaultIdentity() = 0;
+
+  /**
+   * Get the default key name for the specified identity.
+   * @param identityName The identity name.
+   * @return The default key name.
+   */
+  virtual Name 
+  getDefaultKeyNameForIdentity(const Name& identityName) = 0;
+
+  /**
+   * Get the default certificate name for the specified key.
+   * @param keyName The key name.
+   * @return The default certificate name.
+   */
+  virtual Name 
+  getDefaultCertificateNameForKey(const Name& keyName) = 0;
+
+  virtual std::vector<Name>
+  getAllIdentities(bool isDefault) = 0;
+
+  virtual std::vector<Name>
+  getAllKeyNames(bool isDefault) = 0;
+
+  virtual std::vector<Name>
+  getAllKeyNamesOfIdentity(const Name& identity, bool isDefault) = 0;
+    
+  virtual std::vector<Name>
+  getAllCertificateNames(bool isDefault) = 0;
+    
+  virtual std::vector<Name>
+  getAllCertificateNamesOfKey(const Name& keyName, bool isDefault) = 0;
+
+protected:
+
+  /*****************************************
+   *            Default Setter             *
+   *****************************************/
+  
+  /**
+   * Set the default identity.  If the identityName does not exist, then clear the default identity
+   * so that getDefaultIdentity() returns an empty name.
+   * @param identityName The default identity name.
+   */
+  virtual void 
+  setDefaultIdentityInternal(const Name& identityName) = 0;
+  
+  /**
+   * Set the default key name for the corresponding identity.
+   * @param keyName The key name.
+   */
+  virtual void
+  setDefaultKeyNameForIdentityInternal(const Name& keyName) = 0;
+
+  /**
+   * Set the default certificate name for the corresponding key.
+   * @param certificateName The certificate name.
+   */
+  virtual void 
+  setDefaultCertificateNameForKeyInternal(const Name& certificateName) = 0; 
+
+public:
+  
+  /*****************************************
+   *            Helper Methods             *
+   *****************************************/
+
+  /**
+   * Set the default identity.  If the identityName does not exist, then clear the default identity
+   * so that getDefaultIdentity() returns an empty name.
+   * @param identityName The default identity name.
+   */
+  inline void 
+  setDefaultIdentity(const Name& identityName);
+
+  /**
+   * Set the default key name for the corresponding identity.
+   * @param keyName The key name.
+   */
+  inline void 
+  setDefaultKeyNameForIdentity(const Name& keyName);
+
+  /**
+   * Set the default certificate name for the corresponding key.
+   * @param certificateName The certificate name.
+   */
+  inline void 
+  setDefaultCertificateNameForKey(const Name& certificateName); 
+
+  /**
+   * Generate a name for a new key belonging to the identity.
+   * @param identityName The identity name.
+   * @param useKsk If true, generate a KSK name, otherwise a DSK name.
+   * @return The generated key name.
+   */
+  inline Name 
+  getNewKeyName(const Name& identityName, bool useKsk);
+
+    /**
+   * Get the default certificate name for the specified identity.
+   * @param identityName The identity name.
+   * @return The default certificate name.
+   */
+  inline Name 
+  getDefaultCertificateNameForIdentity(const Name& identityName);
+
+  /**
+   * Get the default certificate name of the default identity, which will be used when signing is based on identity and 
+   * the identity is not specified.
+   * @return The requested certificate name.
+   */
+  inline Name
+  getDefaultCertificateName();
+
+  /**
+   * Add a certificate and set the certificate as the default of its corresponding key.
+   * @param certificate The certificate to be added.  This makes a copy of the certificate.
+   */
+  inline void
+  addCertificateAsKeyDefault(const IdentityCertificate& certificate);
+
+  /**
+   * Add a certificate into the public key identity storage and set the certificate as the default for its corresponding identity.
+   * @param certificate The certificate to be added.  This makes a copy of the certificate.
+   */
+  inline void
+  addCertificateAsIdentityDefault(const IdentityCertificate& certificate);
+
+  inline void
+  addCertificateAsSystemDefault(const IdentityCertificate& certificate);
+
+  inline ptr_lib::shared_ptr<IdentityCertificate>
+  defaultCertificate();
+  
+  inline void
+  refreshDefaultCertificate();
+
+protected:
+  ptr_lib::shared_ptr<IdentityCertificate> defaultCertificate_;
+
+};
+
+void
+SecPublicInfo::setDefaultIdentity(const Name& identityName)
+{
+  setDefaultIdentityInternal(identityName);
+  refreshDefaultCertificate();
+}
+
+void
+SecPublicInfo::setDefaultKeyNameForIdentity(const Name& keyName)
+{
+  setDefaultKeyNameForIdentityInternal(keyName);
+  refreshDefaultCertificate();
+}
+
+void 
+SecPublicInfo::setDefaultCertificateNameForKey(const Name& certificateName)
+{
+  setDefaultCertificateNameForKeyInternal(certificateName);
+  refreshDefaultCertificate();
+}
+
+Name 
+SecPublicInfo::getDefaultCertificateNameForIdentity(const Name& identityName)
+{
+  return getDefaultCertificateNameForKey(getDefaultKeyNameForIdentity(identityName));
+}
+
+Name
+SecPublicInfo::getNewKeyName (const Name& identityName, bool useKsk)
+{
+  std::ostringstream oss;
+
+  if (useKsk)
+    oss << "ksk-";
+  else
+    oss << "dsk-";
+
+  oss << static_cast<int>(getNow()/1000);  
+
+  Name keyName = Name(identityName).append(oss.str());
+
+  if (doesPublicKeyExist(keyName))
+    throw Error("Key name already exists");
+
+  return keyName;
+}
+
+Name
+SecPublicInfo::getDefaultCertificateName()
+{
+  if(!static_cast<bool>(defaultCertificate_))
+    refreshDefaultCertificate();
+
+  if(!static_cast<bool>(defaultCertificate_))
+    return Name();
+
+  return defaultCertificate_->getName();
+}
+
+void
+SecPublicInfo::addCertificateAsKeyDefault(const IdentityCertificate& certificate)
+{
+  addCertificate(certificate);
+  setDefaultCertificateNameForKeyInternal(certificate.getName());
+  refreshDefaultCertificate();
+}
+
+void
+SecPublicInfo::addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
+{
+  addCertificate(certificate);
+  Name certName = certificate.getName();
+  setDefaultKeyNameForIdentityInternal(IdentityCertificate::certificateNameToPublicKeyName(certName));
+  setDefaultCertificateNameForKeyInternal(certName);
+  refreshDefaultCertificate();
+}
+
+void
+SecPublicInfo::addCertificateAsSystemDefault(const IdentityCertificate& certificate)
+{
+  addCertificate(certificate);
+  Name certName = certificate.getName();
+  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certName);
+  setDefaultIdentityInternal(keyName.getPrefix(-1));
+  setDefaultKeyNameForIdentityInternal(keyName);
+  setDefaultCertificateNameForKeyInternal(certName);
+  refreshDefaultCertificate();
+}
+
+ptr_lib::shared_ptr<IdentityCertificate>
+SecPublicInfo::defaultCertificate()
+{
+  return defaultCertificate_;
+}
+
+void
+SecPublicInfo::refreshDefaultCertificate()
+{
+  Name certName = getDefaultCertificateNameForIdentity(getDefaultIdentity());
+  if(certName.empty())
+    defaultCertificate_.reset();
+  else
+    defaultCertificate_ = getCertificate(certName);
+}
+
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-tpm-memory.hpp b/include/ndn-cpp-dev/security/sec-tpm-memory.hpp
new file mode 100644
index 0000000..8203272
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-tpm-memory.hpp
@@ -0,0 +1,127 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_TPM_MEMORY_HPP
+#define NDN_SEC_TPM_MEMORY_HPP
+
+#include <map>
+#include "sec-tpm.hpp"
+
+struct rsa_st;
+
+namespace ndn {
+
+/**
+ * MemoryPrivateKeyStorage extends PrivateKeyStorage to implement a simple in-memory private key store.  You should
+ * initialize by calling setKeyPairForKeyName.
+ */
+class SecTpmMemory : public SecTpm {
+public:
+  struct Error : public SecTpm::Error { Error(const std::string &what) : SecTpm::Error(what) {} };
+
+  /**
+   * The virtual destructor
+   */    
+  virtual 
+  ~SecTpmMemory();
+
+  /**
+   * Set the public and private key for the keyName.
+   * @param keyName The key name.
+   * @param publicKeyDer The public key DER byte array.
+   * @param publicKeyDerLength The length of publicKeyDer.
+   * @param privateKeyDer The private key DER byte array.
+   * @param privateKeyDerLength The length of privateKeyDer.
+   */
+  void setKeyPairForKeyName(const Name& keyName,
+                            uint8_t *publicKeyDer, size_t publicKeyDerLength,
+                            uint8_t *privateKeyDer, size_t privateKeyDerLength);
+  
+  /**
+   * Generate a pair of asymmetric keys.
+   * @param keyName The name of the key pair.
+   * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
+   * @param keySize The size of the key pair.
+   */
+  virtual void 
+  generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize);
+
+  /**
+   * Get the public key
+   * @param keyName The name of public key.
+   * @return The public key.
+   */
+  virtual ptr_lib::shared_ptr<PublicKey> 
+  getPublicKeyFromTpm(const Name& keyName);
+  
+  /**
+   * Fetch the private key for keyName and sign the data, returning a signature Blob.
+   * @param data Pointer to the input byte array.
+   * @param dataLength The length of data.
+   * @param keyName The name of the signing key.
+   * @param digestAlgorithm the digest algorithm.
+   * @return The signature, or a null pointer if signing fails.
+   */  
+  virtual Block 
+  signInTpm(const uint8_t *data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm);
+
+  virtual void 
+  signInTpm(Data &data, const Name& keyName, DigestAlgorithm digestAlgorithm);
+  
+  /**
+   * Decrypt data.
+   * @param keyName The name of the decrypting key.
+   * @param data The byte to be decrypted.
+   * @param dataLength the length of data.
+   * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric decryption is used.
+   * @return The decrypted data.
+   */
+  virtual ConstBufferPtr 
+  decryptInTpm(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric);
+
+  /**
+   * Encrypt data.
+   * @param keyName The name of the encrypting key.
+   * @param data The byte to be encrypted.
+   * @param dataLength the length of data.
+   * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric decryption is used.
+   * @return The encrypted data.
+   */
+  virtual ConstBufferPtr
+  encryptInTpm(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric);
+
+  /**
+   * @brief Generate a symmetric key.
+   * @param keyName The name of the key.
+   * @param keyType The type of the key, e.g. KEY_TYPE_AES.
+   * @param keySize The size of the key.
+   */
+  virtual void 
+  generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize);
+
+  /**
+   * Check if a particular key exists.
+   * @param keyName The name of the key.
+   * @param keyClass The class of the key, e.g. KEY_CLASS_PUBLIC, KEY_CLASS_PRIVATE, or KEY_CLASS_SYMMETRIC.
+   * @return True if the key exists, otherwise false.
+   */
+  virtual bool
+  doesKeyExistInTpm(const Name& keyName, KeyClass keyClass);  
+  
+private:
+  class RsaPrivateKey;
+
+  typedef std::map<std::string, ptr_lib::shared_ptr<PublicKey> >     PublicKeyStore;
+  typedef std::map<std::string, ptr_lib::shared_ptr<RsaPrivateKey> > PrivateKeyStore;
+  
+  PublicKeyStore  publicKeyStore_;  /**< The map key is the keyName.toUri() */
+  PrivateKeyStore privateKeyStore_; /**< The map key is the keyName.toUri() */
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-tpm-osx.hpp b/include/ndn-cpp-dev/security/sec-tpm-osx.hpp
new file mode 100644
index 0000000..4839e3d
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-tpm-osx.hpp
@@ -0,0 +1,127 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_TPM_OSX_HPP
+#define NDN_SEC_TPM_OSX_HPP
+
+// Only compile if ndn-cpp-config.h defines NDN_CPP_HAVE_OSX_SECURITY 1.
+#include <ndn-cpp-dev/ndn-cpp-config.h>
+#if NDN_CPP_HAVE_OSX_SECURITY
+
+#include "../common.hpp"
+#include "sec-tpm.hpp"
+
+namespace ndn
+{
+  
+class SecTpmOsx : public SecTpm {
+public:
+  struct Error : public SecTpm::Error { Error(const std::string &what) : SecTpm::Error(what) {} };
+
+  /**
+   * constructor of OSXKeyChainTpm
+   * @param keychainName the name of keychain
+   */
+  SecTpmOsx(const std::string & keychainName = "");
+
+  /**
+   * destructor of OSXKeyChainTpm
+   */    
+  virtual 
+  ~SecTpmOsx();
+
+
+  // From TrustedPlatformModule
+  virtual void 
+  generateKeyPairInTpm(const Name& keyName, KeyType keyType = KEY_TYPE_RSA, int keySize = 2048);
+
+  virtual ptr_lib::shared_ptr<PublicKey> 
+  getPublicKeyFromTpm(const Name& keyName);
+  
+  virtual Block
+  signInTpm(const uint8_t *data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm);
+
+  virtual void
+  signInTpm(Data &data, const Name& keyName, DigestAlgorithm digestAlgorithm);
+  
+  /**
+   * Decrypt data.
+   * @param keyName The name of the decrypting key.
+   * @param data The byte to be decrypted.
+   * @param dataLength the length of data.
+   * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric decryption is used.
+   * @return The decrypted data.
+   */
+  virtual ConstBufferPtr 
+  decryptInTpm(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric);
+
+  /**
+   * Encrypt data.
+   * @param keyName The name of the encrypting key.
+   * @param data The byte to be encrypted.
+   * @param dataLength the length of data.
+   * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric decryption is used.
+   * @return The encrypted data.
+   */
+  virtual ConstBufferPtr
+  encryptInTpm(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric);
+
+  /**
+   * Generate a symmetric key.
+   * @param keyName The name of the key.
+   * @param keyType The type of the key, e.g. KEY_TYPE_AES.
+   * @param keySize The size of the key.
+   */
+  virtual void 
+  generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize);
+
+  /**
+   * Check if a particular key exists.
+   * @param keyName The name of the key.
+   * @param keyClass The class of the key, e.g. KEY_CLASS_PUBLIC, KEY_CLASS_PRIVATE, or KEY_CLASS_SYMMETRIC.
+   * @return True if the key exists, otherwise false.
+   */
+  virtual bool
+  doesKeyExistInTpm(const Name& keyName, KeyClass keyClass);  
+
+
+  ////////////////////////////////////////////////////////////////////////////////////
+  // OSX-specifics
+  ////////////////////////////////////////////////////////////////////////////////////
+  
+  /**
+   * configure ACL of a particular key
+   * @param keyName the name of key
+   * @param keyClass the class of key, e.g. Private Key
+   * @param acl the new acl of the key
+   * @param appPath the absolute path to the application
+   * @returns true if setting succeeds
+   */
+  bool 
+  setACL(const Name & keyName, KeyClass keyClass, int acl, const std::string & appPath);
+
+  // /**
+  //  * verify data (test only)
+  //  * @param keyName the name of key
+  //  * @param pData the data to be verified
+  //  * @param pSig the signature associated with the data
+  //  * @param digestAlgo digest algorithm
+  //  * @return true if signature can be verified, otherwise false
+  //  */
+  // bool 
+  // verifyData(const Name & keyName, const Blob & pData, const Blob & pSig, DigestAlgorithm digestAlgo = DIGEST_ALGORITHM_SHA256);
+
+ private:
+  class Impl;
+  std::auto_ptr<Impl> impl_;
+};
+  
+}
+
+#endif // NDN_CPP_HAVE_OSX_SECURITY
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-tpm.hpp b/include/ndn-cpp-dev/security/sec-tpm.hpp
new file mode 100644
index 0000000..c6b5328
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-tpm.hpp
@@ -0,0 +1,104 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_TPM_HPP
+#define NDN_SEC_TPM_HPP
+
+#include <string>
+#include "security-common.hpp"
+#include "../name.hpp"
+#include "../data.hpp"
+#include "public-key.hpp"
+
+namespace ndn {
+
+class SecTpm {
+public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+  /**
+   * The virtual destructor.
+   */    
+  virtual 
+  ~SecTpm() {}
+
+  /**
+   * Generate a pair of asymmetric keys.
+   * @param keyName The name of the key pair.
+   * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
+   * @param keySize The size of the key pair.
+   */
+  virtual void 
+  generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
+
+  /**
+   * Get the public key
+   * @param keyName The name of public key.
+   * @return The public key.
+   */
+  virtual ptr_lib::shared_ptr<PublicKey> 
+  getPublicKeyFromTpm(const Name& keyName) = 0;
+  
+  /**
+   * Fetch the private key for keyName and sign the data, returning a signature Blob.
+   * @param data Pointer to the input byte array.
+   * @param dataLength The length of data.
+   * @param keyName The name of the signing key.
+   * @param digestAlgorithm the digest algorithm.
+   * @return The signature, or a null pointer if signing fails.
+   */  
+  virtual Block
+  signInTpm(const uint8_t *data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm) = 0;
+
+  virtual void
+  signInTpm(Data &data, const Name& keyName, DigestAlgorithm digestAlgorithm) = 0;
+  
+  /**
+   * Decrypt data.
+   * @param keyName The name of the decrypting key.
+   * @param data The byte to be decrypted.
+   * @param dataLength the length of data.
+   * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption is used.
+   * @return The decrypted data.
+   */
+  virtual ConstBufferPtr 
+  decryptInTpm(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric) = 0;
+
+  /**
+   * Encrypt data.
+   * @param keyName The name of the encrypting key.
+   * @param data The byte to be encrypted.
+   * @param dataLength the length of data.
+   * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption is used.
+   * @return The encrypted data.
+   */
+  virtual ConstBufferPtr
+  encryptInTpm(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric) = 0;
+
+  /**
+   * @brief Generate a symmetric key.
+   * @param keyName The name of the key.
+   * @param keyType The type of the key, e.g. KEY_TYPE_AES.
+   * @param keySize The size of the key.
+   */
+  virtual void 
+  generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
+
+  /**
+   * Check if a particular key exists.
+   * @param keyName The name of the key.
+   * @param keyClass The class of the key, e.g. KEY_CLASS_PUBLIC, KEY_CLASS_PRIVATE, or KEY_CLASS_SYMMETRIC.
+   * @return True if the key exists, otherwise false.
+   */
+  virtual bool
+  doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) = 0;  
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/security-common.hpp b/include/ndn-cpp-dev/security/security-common.hpp
new file mode 100644
index 0000000..9ce4599
--- /dev/null
+++ b/include/ndn-cpp-dev/security/security-common.hpp
@@ -0,0 +1,43 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SECURITY_COMMON_HPP
+#define NDN_SECURITY_COMMON_HPP
+
+namespace ndn {
+
+enum KeyType {
+  KEY_TYPE_RSA,
+  // KEY_TYPE_DSA,
+  KEY_TYPE_AES,
+  // KEY_TYPE_DES,
+  // KEY_TYPE_RC4,
+  // KEY_TYPE_RC2
+};
+
+enum KeyClass {
+  KEY_CLASS_PUBLIC,
+  KEY_CLASS_PRIVATE,
+  KEY_CLASS_SYMMETRIC
+};
+  
+enum DigestAlgorithm {
+  // DIGEST_ALGORITHM_MD2,
+  // DIGEST_ALGORITHM_MD5,
+  // DIGEST_ALGORITHM_SHA1,
+  DIGEST_ALGORITHM_SHA256
+};
+
+enum EncryptMode {
+  ENCRYPT_MODE_DEFAULT,
+  ENCRYPT_MODE_CFB_AES,
+  // ENCRYPT_MODE_CBC_AES
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/security-exception.hpp b/include/ndn-cpp-dev/security/security-exception.hpp
new file mode 100644
index 0000000..daf1d61
--- /dev/null
+++ b/include/ndn-cpp-dev/security/security-exception.hpp
@@ -0,0 +1,49 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SECURITY_EXCEPTION_HPP
+#define NDN_SECURITY_EXCEPTION_HPP
+
+#include <exception>
+#include <string>
+
+namespace ndn {
+
+class SecurityException : public std::exception {
+public:
+  SecurityException(const std::string& errorMessage) throw();
+    
+  virtual ~SecurityException() throw();
+    
+  std::string Msg() { return errorMessage_; }
+
+  virtual const char* what() const throw() { return errorMessage_.c_str(); }
+    
+private:
+  const std::string errorMessage_;
+};
+
+class UnrecognizedKeyFormatException : public SecurityException {
+public:
+  UnrecognizedKeyFormatException(const std::string& errorMessage)
+  : SecurityException(errorMessage)
+  {
+  }
+};
+
+class UnrecognizedDigestAlgorithmException : public SecurityException {
+public:
+  UnrecognizedDigestAlgorithmException(const std::string& errorMessage)
+  : SecurityException(errorMessage)
+  {
+  }
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sha256-with-rsa-handler.hpp b/include/ndn-cpp-dev/security/sha256-with-rsa-handler.hpp
new file mode 100644
index 0000000..6627f02
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sha256-with-rsa-handler.hpp
@@ -0,0 +1,38 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SHA256_RSA_HANDLER_HPP
+#define NDN_SHA256_RSA_HANDLER_HPP
+
+#include "../../data.hpp"
+#include "../certificate/public-key.hpp"
+
+namespace ndn{
+
+class Sha256WithRsaHandler {
+public:
+  Sha256WithRsaHandler() {}
+
+  virtual
+  ~Sha256WithRsaHandler() {}
+
+ /**
+  * Verify the signature on the data packet using the given public key. If there is no data.getDefaultWireEncoding(),
+  * this calls data.wireEncode() to set it.
+  * @param data The data packet with the signed portion and the signature to verify. The data packet must have a
+  * Sha256WithRsaSignature.
+  * @param publicKey The public key used to verify the signature.
+  * @return true if the signature verifies, false if not.
+  * @throw SecurityException if data does not have a Sha256WithRsaSignature.
+  */
+  static bool
+  verifySignature(const Data& data, const PublicKey& publicKey);
+
+};
+
+}
+#endif
diff --git a/include/ndn-cpp-dev/security/signature-sha256-with-rsa.hpp b/include/ndn-cpp-dev/security/signature-sha256-with-rsa.hpp
new file mode 100644
index 0000000..b59c765
--- /dev/null
+++ b/include/ndn-cpp-dev/security/signature-sha256-with-rsa.hpp
@@ -0,0 +1,64 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SIGNATURE_SHA256_WITH_RSA_HPP
+#define NDN_SIGNATURE_SHA256_WITH_RSA_HPP
+
+#include "../data.hpp"
+
+namespace ndn {
+
+/**
+ * Representing of SHA256-with-RSA signature in a data packet.
+ */
+class SignatureSha256WithRsa : public Signature {
+public:
+  SignatureSha256WithRsa()
+  {
+    info_ = Block(Tlv::SignatureInfo);
+    
+    type_ = Signature::Sha256WithRsa;
+    info_.push_back(nonNegativeIntegerBlock(Tlv::SignatureType, Tlv::SignatureSha256WithRsa));
+    info_.push_back(keyLocator_.wireEncode());
+  }
+  
+  SignatureSha256WithRsa(const Signature &signature)
+    : Signature(signature)
+  {
+    if (getType() != Signature::Sha256WithRsa)
+      throw Signature::Error("Incorrect signature type");
+
+    info_.parse();
+    Block::element_iterator i = info_.find(Tlv::KeyLocator);
+    if (i != info_.getAll().end())
+      {
+        keyLocator_.wireDecode(*i);
+      }
+  }
+  
+  const KeyLocator& 
+  getKeyLocator() const
+  {
+    return keyLocator_;
+  }
+
+  void 
+  setKeyLocator(const KeyLocator& keyLocator)
+  {
+    keyLocator_ = keyLocator;
+
+    info_.remove(ndn::Tlv::KeyLocator);
+    info_.push_back(keyLocator_.wireEncode());
+  }
+
+private:
+  KeyLocator keyLocator_;
+};
+
+} // namespace ndn
+
+#endif
diff --git a/include/ndn-cpp-dev/security/validation-request.hpp b/include/ndn-cpp-dev/security/validation-request.hpp
new file mode 100644
index 0000000..7471065
--- /dev/null
+++ b/include/ndn-cpp-dev/security/validation-request.hpp
@@ -0,0 +1,48 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_VALIDATION_REQUEST_HPP
+#define NDN_VALIDATION_REQUEST_HPP
+
+#include "../interest.hpp"
+
+namespace ndn {
+
+/**
+ * An OnVerified function object is used to pass a callback to verifyData to report a successful verification.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<Data>& data)> OnVerified;
+
+/**
+ * An OnVerifyFailed function object is used to pass a callback to verifyData to report a failed verification.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<Data>& data)> OnVerifyFailed;
+
+
+class ValidationRequest {
+public:
+  ValidationRequest
+    (const ptr_lib::shared_ptr<Interest> &interest, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed,
+     int retry, int stepCount)
+  : interest_(interest), onVerified_(onVerified), onVerifyFailed_(onVerifyFailed), retry_(retry), stepCount_(stepCount)
+  {
+  }
+    
+  virtual
+  ~ValidationRequest() {}
+
+  ptr_lib::shared_ptr<Interest> interest_; // An interest packet to fetch the requested data.
+  OnVerified onVerified_;                  // A callback function if the requested certificate has been validated.
+  OnVerifyFailed onVerifyFailed_;          // A callback function if the requested certificate cannot be validated.
+  int retry_;                              // The number of retrials when there is an interest timeout.
+  int stepCount_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/verifier.hpp b/include/ndn-cpp-dev/security/verifier.hpp
new file mode 100644
index 0000000..2dbd995
--- /dev/null
+++ b/include/ndn-cpp-dev/security/verifier.hpp
@@ -0,0 +1,102 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_VERIFIER_HPP
+#define NDN_VERIFIER_HPP
+
+#include "../data.hpp"
+#include "../face.hpp"
+#include "sec-policy.hpp"
+#include "validation-request.hpp"
+#include "public-key.hpp"
+#include "signature-sha256-with-rsa.hpp"
+
+namespace ndn {
+  
+/**
+ * Verifier is one of the main classes of the security librar .
+ *
+ * The Verifier class provides the interfaces for packet verification.
+ */
+class Verifier {
+public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+  Verifier(const ptr_lib::shared_ptr<SecPolicy> &policy = DefaultPolicy);
+
+  /**
+   * @brief Set the Face which will be used to fetch required certificates.
+   * @param face A pointer to the Face object.
+   *
+   * Setting face is necessary for verifier operation that involve fetching data.
+   */
+  void
+  setFace(const ptr_lib::shared_ptr<Face> &face) { face_ = face; }
+  
+  /**
+   * @brief Get the policy.
+   * @return The Policy.
+   */
+  inline SecPolicy&
+  policy()
+  {
+    if (!policy_)
+      throw Error("policy is not assigned to the KeyChain");
+
+    return *policy_;
+  }
+
+
+  /**
+   * Check the signature on the Data object and call either onVerify or onVerifyFailed. 
+   * We use callback functions because verify may fetch information to check the signature.
+   * @param data The Data object with the signature to check. It is an error if data does not have a wireEncoding. 
+   * To set the wireEncoding, you can call data.wireDecode.
+   * @param onVerified If the signature is verified, this calls onVerified(data).
+   * @param onVerifyFailed If the signature check fails, this calls onVerifyFailed(data).
+   */
+  void
+  verifyData
+    (const ptr_lib::shared_ptr<Data>& data, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed, int stepCount = 0);
+
+  /*****************************************
+   *      verifySignature method set       *
+   *****************************************/
+    static bool
+  verifySignature(const Data &data, const Signature &sig, const PublicKey &publicKey);
+
+  static bool
+  verifySignature(const Buffer &data, const Signature &sig, const PublicKey &publicKey);
+
+  static bool
+  verifySignature(const Data& data, const SignatureSha256WithRsa& sig, const PublicKey& publicKey);
+
+  static bool
+  verifySignature(const Buffer &data, const SignatureSha256WithRsa &sig, const PublicKey &publicKey);
+
+public:
+  static const ptr_lib::shared_ptr<SecPolicy>     DefaultPolicy;
+    
+private:
+  void
+  onCertificateData
+    (const ptr_lib::shared_ptr<const Interest> &interest, const ptr_lib::shared_ptr<Data> &data, ptr_lib::shared_ptr<ValidationRequest> nextStep);
+  
+  void
+  onCertificateInterestTimeout
+    (const ptr_lib::shared_ptr<const Interest> &interest, int retry, const OnVerifyFailed& onVerifyFailed, 
+     const ptr_lib::shared_ptr<Data> &data, ptr_lib::shared_ptr<ValidationRequest> nextStep);
+
+private:
+  ptr_lib::shared_ptr<SecPolicy>     policy_;
+  ptr_lib::shared_ptr<Face>        face_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/signature.hpp b/include/ndn-cpp-dev/signature.hpp
new file mode 100644
index 0000000..e38ad3e
--- /dev/null
+++ b/include/ndn-cpp-dev/signature.hpp
@@ -0,0 +1,100 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SIGNATURE_HPP
+#define NDN_SIGNATURE_HPP
+
+namespace ndn {
+
+/**
+ * A Signature is storage for the signature-related information (info and value) in a Data packet.
+ */
+class Signature {
+public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+  enum {
+    Sha256 = 0,
+    Sha256WithRsa = 1
+  };
+  
+  Signature()
+    : type_(-1)
+  {
+  }
+  
+  Signature(const Block &info, const Block &value = Block())
+    : value_(value)
+  {
+    setInfo(info);
+  }
+
+  operator bool() const
+  {
+    return type_ != -1;
+  }
+
+  uint32_t
+  getType() const
+  {
+    return type_;
+  }
+  
+  const Block&
+  getInfo() const
+  {
+    info_.encode(); // will do nothing if wire already exists
+    return info_;
+  }
+
+  void
+  setInfo(const Block &info)
+  {
+    info_ = info;
+    if (info_.hasWire() || info_.hasValue())
+      {
+        info_.parse();
+        const Block &signatureType = info_.get(Tlv::SignatureType);
+        type_ = readNonNegativeInteger(signatureType);
+      }
+    else
+      {
+        type_ = -1;
+      }
+  }  
+
+  const Block&
+  getValue() const
+  {
+    value_.encode(); // will do nothing if wire already exists
+    return value_;
+  }
+
+  void
+  setValue(const Block &value)
+  {
+    value_ = value;
+  }
+
+  void
+  reset()
+  {
+    type_ = -1;
+    info_.reset();
+    value_.reset();
+  }
+
+protected:
+  int32_t type_;
+  
+  mutable Block info_;
+  mutable Block value_;
+};
+
+} // namespace ndn
+
+#endif // NDN_SIGNATURE_HPP
diff --git a/include/ndn-cpp-dev/status-response.hpp b/include/ndn-cpp-dev/status-response.hpp
new file mode 100644
index 0000000..a222951
--- /dev/null
+++ b/include/ndn-cpp-dev/status-response.hpp
@@ -0,0 +1,124 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_STATUS_RESPONSE_HPP
+#define NDN_STATUS_RESPONSE_HPP
+
+#include "encoding/block.hpp"
+#include "encoding/tlv-face-management.hpp"
+
+namespace ndn {
+
+class StatusResponse {
+public:
+  StatusResponse()
+    : code_(0)
+  {
+  }
+
+  StatusResponse(uint32_t code, const std::string &info)
+    : code_(code)
+    , info_(info)
+  {
+  }
+  
+  inline uint32_t
+  getCode() const;
+
+  inline void
+  setCode(uint32_t code);
+
+  inline const std::string &
+  getInfo() const;
+
+  inline void
+  setInfo(const std::string &info);
+
+  inline const Block&
+  wireEncode() const;
+
+  inline void
+  wireDecode(const Block &block);
+  
+private:
+  uint32_t code_;
+  std::string info_;
+
+  mutable Block wire_;
+};
+
+inline uint32_t
+StatusResponse::getCode() const
+{
+  return code_;
+}
+
+inline void
+StatusResponse::setCode(uint32_t code)
+{
+  code_ = code;
+  wire_.reset();
+}
+
+inline const std::string &
+StatusResponse::getInfo() const
+{
+  return info_;
+}
+
+inline void
+StatusResponse::setInfo(const std::string &info)
+{
+  info_ = info;
+  wire_.reset();
+}
+
+
+inline const Block&
+StatusResponse::wireEncode() const
+{
+  if (wire_.hasWire())
+    return wire_;
+
+  wire_ = Block(Tlv::FaceManagement::StatusResponse);
+  wire_.push_back
+    (nonNegativeIntegerBlock(Tlv::FaceManagement::StatusCode, code_));
+
+  if (!info_.empty())
+    {
+      wire_.push_back
+        (dataBlock(Tlv::FaceManagement::StatusText, info_.c_str(), info_.size()));
+    }
+  
+  wire_.encode();  
+  return wire_;
+}
+
+inline void
+StatusResponse::wireDecode(const Block &wire)
+{
+  wire_ = wire;
+  wire_.parse();
+
+  code_ = readNonNegativeInteger(wire_.get(Tlv::FaceManagement::StatusCode));
+
+  Block::element_iterator val = wire_.find(Tlv::FaceManagement::StatusText);
+  if (val != wire_.getAll().end())
+    {
+      info_.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
+    }
+}
+
+inline std::ostream&
+operator << (std::ostream &os, const StatusResponse &status)
+{
+  os << status.getCode() << " " << status.getInfo();
+  return os;
+}
+
+}
+
+#endif // NDN_STATUS_RESPONSE_HPP
diff --git a/include/ndn-cpp-dev/transport/transport.hpp b/include/ndn-cpp-dev/transport/transport.hpp
new file mode 100644
index 0000000..ddbff52
--- /dev/null
+++ b/include/ndn-cpp-dev/transport/transport.hpp
@@ -0,0 +1,107 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_TRANSPORT_HPP
+#define NDN_TRANSPORT_HPP
+
+#include <ndn-cpp-dev/common.hpp>
+
+#include <vector>
+#include <boost/asio.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+
+class Transport {
+public:
+  struct Error : public std::runtime_error { inline Error(const boost::system::error_code &code, const std::string &msg); };
+  
+  typedef ptr_lib::function<void (const Block &wire)> ReceiveCallback;
+  typedef ptr_lib::function<void ()> ErrorCallback;
+  
+  inline
+  Transport();
+  
+  inline virtual
+  ~Transport();
+
+  /**
+   * Connect transport
+   *
+   * @throws If connection cannot be established
+   */
+  inline virtual void 
+  connect(boost::asio::io_service &io_service,
+          const ReceiveCallback &receiveCallback);
+  
+  /**
+   * Close the connection.
+   */
+  virtual void 
+  close() = 0;
+
+  /**
+   * Set data to the host
+   * @param data A pointer to the buffer of data to send.
+   * @param dataLength The number of bytes in data.
+   */
+  virtual void 
+  send(const Block &wire) = 0;
+
+  inline bool 
+  isConnected();
+
+protected:
+  inline void
+  receive(const Block &wire);
+  
+protected:
+  boost::asio::io_service *ioService_;
+  bool isConnected_;
+  ReceiveCallback receiveCallback_;
+};
+
+inline
+Transport::Transport()
+  : ioService_(0)
+  , isConnected_(false)
+{
+}
+
+inline Transport::Error::Error(const boost::system::error_code &code, const std::string &msg)
+  : std::runtime_error(msg + (code.value() ? " (" + code.category().message(code.value()) + ")" : ""))
+{
+}
+
+inline
+Transport::~Transport()
+{
+}
+
+inline void 
+Transport::connect(boost::asio::io_service &ioService,
+                   const ReceiveCallback &receiveCallback)
+{
+  ioService_ = &ioService;
+  receiveCallback_ = receiveCallback;
+}
+
+inline bool 
+Transport::isConnected()
+{
+  return isConnected_;
+}
+
+inline void
+Transport::receive(const Block &wire)
+{
+  receiveCallback_(wire);
+}
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/transport/unix-transport.hpp b/include/ndn-cpp-dev/transport/unix-transport.hpp
new file mode 100644
index 0000000..c2ee204
--- /dev/null
+++ b/include/ndn-cpp-dev/transport/unix-transport.hpp
@@ -0,0 +1,42 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_UDPTRANSPORT_HPP
+#define NDN_UDPTRANSPORT_HPP
+
+#include <string>
+#include "transport.hpp"
+
+namespace ndn {
+  
+class UnixTransport : public Transport
+{
+public:
+  UnixTransport(const std::string &unixSocket = "/tmp/.ndnd.sock");
+  ~UnixTransport();
+
+  // from Transport
+  virtual void 
+  connect(boost::asio::io_service &ioService,
+          const ReceiveCallback &receiveCallback);
+  
+  virtual void 
+  close();
+
+  virtual void 
+  send(const Block &wire);
+  
+private:
+  std::string unixSocket_;
+
+  class Impl;
+  ptr_lib::shared_ptr<Impl> impl_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/util/blob.hpp b/include/ndn-cpp-dev/util/blob.hpp
new file mode 100644
index 0000000..4de7a02
--- /dev/null
+++ b/include/ndn-cpp-dev/util/blob.hpp
@@ -0,0 +1,112 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_BLOB_HPP
+#define NDN_BLOB_HPP
+
+#include "../common.hpp"
+
+struct ndn_Blob;
+
+namespace ndn {
+
+/**
+ * A Blob holds a pointer to an immutable byte array implemented as const std::vector<uint8_t>.  
+ * This is like a JavaScript string which is a pointer to an immutable string.  
+ * It is OK to pass a pointer to the string because the new owner can't change the bytes
+ * of the string.  However, like a JavaScript string, it is possible to change the pointer, and so this does allow
+ * the copy constructor and assignment to change the pointer.  Also remember that the pointer can be null.
+ * (Note that we could have made Blob derive directly from vector<uint8_t> and then explicitly use
+ * a pointer to it like Blob, but this does not enforce immutability because we can't declare
+ * Blob as derived from const vector<uint8_t>.)
+ */
+class Blob : public ptr_lib::shared_ptr<const std::vector<uint8_t> > {
+public:
+  /**
+   * Create a new Blob with a null pointer.
+   */
+  Blob()
+  {  
+  }
+  
+  /**
+   * Create a new Blob with an immutable copy of the given array.
+   * @param value A pointer to the byte array which is copied.
+   * @param valueLength The length of value.
+   */
+  Blob(const uint8_t* value, size_t valueLength)
+  : ptr_lib::shared_ptr<const std::vector<uint8_t> >(new std::vector<uint8_t>(value, value + valueLength))
+  {
+  }
+  
+  /**
+   * Create a new Blob with an immutable copy of the array in the given vector.
+   * If you want to transfer the array without copying, the the vector has to start as a 
+   * ptr_lib::shared_ptr<std::vector<uint8_t> > and you can use the Blob constructor with this type.
+   * @param value A reference to a vector which is copied.
+   */
+  Blob(const std::vector<uint8_t> &value)
+  : ptr_lib::shared_ptr<const std::vector<uint8_t> >(new std::vector<uint8_t>(value))
+  {
+  }
+  
+  /**
+   * Create a new Blob with an immutable copy of the array in the given Blob struct.
+   * @param blobStruct The C ndn_Blob struct to receive the pointer.
+   */
+  Blob(const struct ndn_Blob& blobStruct);
+  
+  /**
+   * Create a new Blob to point to an existing byte array.  IMPORTANT: After calling this constructor,
+   * if you keep a pointer to the array then you must treat the array as immutable and promise not to change it.
+   * @param value A pointer to a vector with the byte array.  This takes another reference and does not copy the bytes.
+   */
+  Blob(const ptr_lib::shared_ptr<std::vector<uint8_t> > &value)
+  : ptr_lib::shared_ptr<const std::vector<uint8_t> >((const ptr_lib::shared_ptr<const std::vector<uint8_t> > &)value)
+  {
+  }
+  Blob(const ptr_lib::shared_ptr<const std::vector<uint8_t> > &value)
+  : ptr_lib::shared_ptr<const std::vector<uint8_t> >(value)
+  {
+  }
+  
+  /**
+   * Return the length of the immutable byte array.
+   */
+  size_t 
+  size() const
+  {
+    if (*this)
+      return (*this)->size();
+    else
+      return 0;
+  }
+
+  /**
+   * Return a const pointer to the first byte of the immutable byte array, or 0 if the pointer is null.
+   */
+  const uint8_t* 
+  buf() const
+  {
+    if (*this)
+      return &(*this)->front();
+    else
+      return 0;
+  }
+  
+  /**
+   * Set the blobStruct to point to this Blob's byte array, without copying any memory.
+   * WARNING: The resulting pointer in blobStruct is invalid after a further use of this object which could reallocate memory.
+   * @param blobStruct The C ndn_Blob struct to receive the pointer.
+   */
+  void 
+  get(struct ndn_Blob& blobStruct) const;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/util/signed-blob.hpp b/include/ndn-cpp-dev/util/signed-blob.hpp
new file mode 100644
index 0000000..1ad2d25
--- /dev/null
+++ b/include/ndn-cpp-dev/util/signed-blob.hpp
@@ -0,0 +1,121 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ * @author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SIGNED_BLOB_HPP
+#define NDN_SIGNED_BLOB_HPP
+
+#include "blob.hpp"
+
+namespace ndn {
+
+/**
+ * A SignedBlob extends Blob to keep the offsets of a signed portion (e.g., the bytes of Data packet).
+ */
+class SignedBlob : public Blob {
+public:
+  /**
+   * Create a new SignedBlob with a null pointer.
+   */
+  SignedBlob()
+  : signedPortionBeginOffset_(0), signedPortionEndOffset_(0)
+  {  
+  }
+  
+  /**
+   * Create a new SignedBlob with an immutable copy of the given array.
+   * @param value A pointer to the byte array which is copied.
+   * @param valueLength The length of value.
+   * @param signedPortionBeginOffset The offset in the encoding of the beginning of the signed portion.
+   * @param signedPortionEndOffset The offset in the encoding of the end of the signed portion.
+   */
+  SignedBlob
+    (const uint8_t* value, size_t valueLength, size_t signedPortionBeginOffset, size_t signedPortionEndOffset)
+  : Blob(value, valueLength), signedPortionBeginOffset_(signedPortionBeginOffset), signedPortionEndOffset_(signedPortionEndOffset)
+  {
+  }
+  
+  /**
+   * Create a new SignedBlob with an immutable copy of the array in the given vector.
+   * If you want to transfer the array without copying, the the vector has to start as a 
+   * ptr_lib::shared_ptr<std::vector<uint8_t> > and you can use the SignedBlob constructor with this type.
+   * @param value A reference to a vector which is copied.
+   * @param signedPortionBeginOffset The offset in the encoding of the beginning of the signed portion.
+   * @param signedPortionEndOffset The offset in the encoding of the end of the signed portion.
+   */
+  SignedBlob
+    (const std::vector<uint8_t> &value, size_t signedPortionBeginOffset, size_t signedPortionEndOffset)
+  : Blob(value), signedPortionBeginOffset_(signedPortionBeginOffset), signedPortionEndOffset_(signedPortionEndOffset)
+  {
+  }
+  
+  /**
+   * Create a new SignedBlob to point to an existing byte array.  IMPORTANT: After calling this constructor,
+   * if you keep a pointer to the array then you must treat the array as immutable and promise not to change it.
+   * @param value A pointer to a vector with the byte array.  This takes another reference and does not copy the bytes.
+   * @param signedPortionBeginOffset The offset in the array of the beginning of the signed portion.
+   * @param signedPortionEndOffset The offset in the array of the end of the signed portion.
+   */
+  SignedBlob
+    (const ptr_lib::shared_ptr<std::vector<uint8_t> > &value, 
+     size_t signedPortionBeginOffset, size_t signedPortionEndOffset)
+  : Blob(value), signedPortionBeginOffset_(signedPortionBeginOffset), signedPortionEndOffset_(signedPortionEndOffset)
+  {
+  }
+  SignedBlob
+    (const ptr_lib::shared_ptr<const std::vector<uint8_t> > &value, 
+     size_t signedPortionBeginOffset, size_t signedPortionEndOffset)
+  : Blob(value), signedPortionBeginOffset_(signedPortionBeginOffset), signedPortionEndOffset_(signedPortionEndOffset)
+  {
+  }
+    
+  /**
+   * Return the length of the signed portion of the immutable byte array, or 0 of the pointer to the array is null.
+   */
+  size_t 
+  signedSize() const
+  {
+    if (*this)
+      return signedPortionEndOffset_ - signedPortionBeginOffset_;
+    else
+      return 0;
+  }
+
+  /**
+   * Return a const pointer to the first byte of the signed portion of the immutable byte array, or 0 if the 
+   * pointer to the array is null.
+   */
+  const uint8_t*
+  signedBuf() const
+  {
+    if (*this)
+      return &(*this)->front() + signedPortionBeginOffset_;
+    else
+      return 0;
+  }
+
+  /**
+   * Return the offset in the array of the beginning of the signed portion.
+   */  
+  size_t 
+  getSignedPortionBeginOffset() const { return signedPortionBeginOffset_; }
+
+  /**
+   * Return the offset in the array of the end of the signed portion.
+   */  
+  size_t 
+  getSignedPortionEndOffset() const { return signedPortionEndOffset_; }
+  
+private:
+  size_t signedPortionBeginOffset_;
+  size_t signedPortionEndOffset_;
+};
+
+}
+
+#endif