diff --git a/include/ndn-cpp/interest.hpp b/include/ndn-cpp/interest.hpp
index d5d8e49..5694394 100644
--- a/include/ndn-cpp/interest.hpp
+++ b/include/ndn-cpp/interest.hpp
@@ -9,187 +9,12 @@
 #define NDN_INTEREST_HPP
 
 #include "name.hpp"
-#include "publisher-public-key-digest.hpp"
-#include "c/interest-types.h"
-#include "encoding/wire-format.hpp"
-
-struct ndn_ExcludeEntry;
-struct ndn_Exclude;
-struct ndn_Interest;
+#include "exclude.hpp"
+#include "encoding/block.hpp"
 
 namespace ndn {
   
 /**
- * An Exclude holds a vector of Exclude::Entry.
- */
-class Exclude {
-public:
-  /**
-   * Create a new Exclude with no entries.
-   */
-  Exclude() 
-  {
-  }
-
-  /**
-   * An Exclude::Entry holds an ndn_ExcludeType, and if it is a COMPONENT, it holds the component value.
-   */
-  class Entry {
-  public:
-    /**
-     * Create an Exclude::Entry of type ndn_Exclude_ANY
-     */
-    Entry()
-    : type_(ndn_Exclude_ANY)
-    {    
-    }
-
-    /**
-     * Create an Exclude::Entry of type ndn_Exclude_COMPONENT.
-     */
-    Entry(uint8_t *component, size_t componentLen) 
-    : type_(ndn_Exclude_COMPONENT), component_(component, componentLen)
-    {
-    }
-
-    /**
-     * Create an Exclude::Entry of type ndn_Exclude_COMPONENT.
-     */
-    Entry(const Blob& component) 
-    : type_(ndn_Exclude_COMPONENT), component_(component)
-    {
-    }
-
-    /**
-     * Set the type in the excludeEntryStruct and to point to this entry, without copying any memory.
-     * WARNING: The resulting pointer in excludeEntryStruct is invalid after a further use of this object which could reallocate memory.
-     * @param excludeEntryStruct the C ndn_ExcludeEntry struct to receive the pointer
-     */
-    void 
-    get(struct ndn_ExcludeEntry& excludeEntryStruct) const;
-
-    ndn_ExcludeType 
-    getType() const { return type_; }
-
-    const Name::Component& 
-    getComponent() const { return component_; }
-
-  private:
-    ndn_ExcludeType type_;
-    Name::Component component_; /**< only used if type_ is ndn_Exclude_COMPONENT */
-  }; 
-
-  /**
-   * Get the number of entries.
-   * @return The number of entries.
-   */
-  size_t 
-  size() const { return entries_.size(); }
-  
-  /**
-   * Get the entry at the given index.
-   * @param i The index of the entry, starting from 0.
-   * @return The entry at the index.
-   */
-  const Exclude::Entry& 
-  get(size_t i) const { return entries_[i]; }
-
-  /**
-   * @deprecated Use size().
-   */  
-  size_t 
-  getEntryCount() const { return entries_.size(); }
-  
-  /**
-   * @deprecated Use get(i).
-   */  
-  const Exclude::Entry& 
-  getEntry(size_t i) const { return entries_[i]; }
-  
-  /**
-   * Set the excludeStruct to point to the entries in this Exclude, without copying any memory.
-   * WARNING: The resulting pointers in excludeStruct are invalid after a further use of this object which could reallocate memory.
-   * @param excludeStruct a C ndn_Exclude struct where the entries array is already allocated
-   */
-  void 
-  get(struct ndn_Exclude& excludeStruct) const;
-  
-  /**
-   * Clear this Exclude, and set the entries by copying from the ndn_Exclude struct.
-   * @param excludeStruct a C ndn_Exclude struct
-   */
-  void 
-  set(const struct ndn_Exclude& excludeStruct);
-
-  /**
-   * Append a new entry of type ndn_Exclude_ANY.
-   * @return This Exclude so that you can chain calls to append.
-   */
-  Exclude& 
-  appendAny()
-  {    
-    entries_.push_back(Entry());
-    return *this;
-  }
-  
-  /**
-   * Append a new entry of type ndn_Exclude_COMPONENT, copying from component of length componentLength.
-   * @param component A pointer to the component byte array.
-   * @param componentLength The length of component.
-   * @return This Exclude so that you can chain calls to append.
-   */
-  Exclude& 
-  appendComponent(uint8_t *component, size_t componentLength) 
-  {
-    entries_.push_back(Entry(component, componentLength));
-    return *this;
-  }
-
-  /**
-   * Append a new entry of type ndn_Exclude_COMPONENT, taking another pointer to the Blob value.
-   * @param component A blob with a pointer to an immutable array.  The pointer is copied.
-   * @return This Exclude so that you can chain calls to append.
-   */
-  Exclude& 
-  appendComponent(const Blob &component) 
-  {
-    entries_.push_back(Entry(component));
-    return *this;
-  }
-
-  /**
-   * @deprecated Use appendAny.
-   */
-  Exclude& 
-  addAny() { return appendAny(); }
-
-  /**
-   * @deprecated Use appendComponent.
-   */
-  Exclude& 
-  addComponent(uint8_t *component, size_t componentLength) { return appendComponent(component, componentLength); }
-  
-  /**
-   * Clear all the entries.
-   */
-  void 
-  clear() 
-  {
-    entries_.clear();
-  }
-  
-  /**
-   * Encode this Exclude with elements separated by "," and ndn_Exclude_ANY shown as "*".
-   * @return the URI string
-   */
-  std::string 
-  toUri() const;
-  
-private:
-  std::vector<Entry> entries_;
-};
-
-/**
  * An Interest holds a Name and other fields for an interest.
  */
 class Interest {
@@ -199,42 +24,29 @@
    * @param name
    * @param minSuffixComponents
    * @param maxSuffixComponents
-   * @param publisherPublicKeyDigest
    * @param exclude
    * @param childSelector
-   * @param answerOriginKind
+   * @param mustBeFresh
    * @param scope
-   * @param interestLifetimeMilliseconds
+   * @param interestLifetime
    * @param nonce
    */
-  Interest(const Name& name, int minSuffixComponents, int maxSuffixComponents, 
-    const PublisherPublicKeyDigest& publisherPublicKeyDigest, const Exclude& exclude, int childSelector, int answerOriginKind, 
-    int scope, Milliseconds interestLifetimeMilliseconds, const Blob& nonce) 
-  : name_(name), minSuffixComponents_(minSuffixComponents), maxSuffixComponents_(maxSuffixComponents),
-  publisherPublicKeyDigest_(publisherPublicKeyDigest), exclude_(exclude), childSelector_(childSelector), 
-  answerOriginKind_(answerOriginKind), scope_(scope), interestLifetimeMilliseconds_(interestLifetimeMilliseconds),
-  nonce_(nonce)
-  {
-  }
-
-  /**
-   * Create a new Interest with the given name and values, and "none" for the nonce.
-   * @param name
-   * @param minSuffixComponents
-   * @param maxSuffixComponents
-   * @param publisherPublicKeyDigest
-   * @param exclude
-   * @param childSelector
-   * @param answerOriginKind
-   * @param scope
-   * @param interestLifetimeMilliseconds
-   */
-  Interest(const Name& name, int minSuffixComponents, int maxSuffixComponents, 
-    const PublisherPublicKeyDigest& publisherPublicKeyDigest, const Exclude& exclude, int childSelector, int answerOriginKind, 
-    int scope, Milliseconds interestLifetimeMilliseconds) 
-  : name_(name), minSuffixComponents_(minSuffixComponents), maxSuffixComponents_(maxSuffixComponents),
-  publisherPublicKeyDigest_(publisherPublicKeyDigest), exclude_(exclude), childSelector_(childSelector), 
-  answerOriginKind_(answerOriginKind), scope_(scope), interestLifetimeMilliseconds_(interestLifetimeMilliseconds)
+  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)
   {
   }
 
@@ -243,11 +55,11 @@
    * @param name The name for the interest.
    * @param interestLifetimeMilliseconds The interest lifetime in milliseconds, or -1 for none.
    */
-  Interest(const Name& name, Milliseconds interestLifetimeMilliseconds) 
+  Interest(const Name& name, Milliseconds interestLifetime) 
   : name_(name)
   {
     construct();
-    interestLifetimeMilliseconds_ = interestLifetimeMilliseconds;
+    interestLifetime_ = interestLifetime;
   }
 
   /**
@@ -273,10 +85,10 @@
    * @param wireFormat A WireFormat object used to decode the input. If omitted, use WireFormat::getDefaultWireFormat().
    * @return The encoded byte array.
    */
-  Blob 
-  wireEncode(WireFormat& wireFormat = *WireFormat::getDefaultWireFormat()) const 
+  const Block&
+  wireEncode() const 
   {
-    return wireFormat.encodeInterest(*this);
+    return wire_;
   }
   
   /**
@@ -286,9 +98,9 @@
    * @param wireFormat A WireFormat object used to decode the input. If omitted, use WireFormat::getDefaultWireFormat().
    */
   void 
-  wireDecode(const uint8_t *input, size_t inputLength, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat()) 
+  wireDecode(const Block &wire) 
   {
-    wireFormat.decodeInterest(*this, input, inputLength);
+    // wireFormat.decodeInterest(*this, input, inputLength);
   }
   
   /**
@@ -296,27 +108,19 @@
    * @param input The input byte array to be decoded.
    * @param wireFormat A WireFormat object used to decode the input. If omitted, use WireFormat::getDefaultWireFormat().
    */
-  void 
-  wireDecode(const std::vector<uint8_t>& input, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat()) 
-  {
-    wireDecode(&input[0], input.size(), wireFormat);
-  }
+  // void 
+  // wireDecode(const std::vector<uint8_t>& input, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat()) 
+  // {
+  //   wireDecode(&input[0], input.size(), wireFormat);
+  // }
   
   /**
    * 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.
    */
-  std::string
+  inline std::string
   toUri() const;
-  
-  /**
-   * Set the interestStruct to point to the components in this interest, without copying any memory.
-   * WARNING: The resulting pointers in interestStruct are invalid after a further use of this object which could reallocate memory.
-   * @param interestStruct a C ndn_Interest struct where the name components array is already allocated.
-   */
-  void 
-  get(struct ndn_Interest& interestStruct) const;
 
   Name& 
   getName() { return name_; }
@@ -329,12 +133,6 @@
   
   int 
   getMaxSuffixComponents() const { return maxSuffixComponents_; }
-  
-  PublisherPublicKeyDigest& 
-  getPublisherPublicKeyDigest() { return publisherPublicKeyDigest_; }
-  
-  const PublisherPublicKeyDigest& 
-  getPublisherPublicKeyDigest() const { return publisherPublicKeyDigest_; }
 
   Exclude& 
   getExclude() { return exclude_; }
@@ -346,24 +144,17 @@
   getChildSelector() const { return childSelector_; }
 
   int 
-  getAnswerOriginKind() const { return answerOriginKind_; }
+  getMustBeFresh() const { return mustBeFresh_; }
 
   int 
   getScope() const { return scope_; }
 
   Milliseconds 
-  getInterestLifetimeMilliseconds() const { return interestLifetimeMilliseconds_; }
+  getInterestLifetime() const { return interestLifetime_; }
 
-  const Blob& 
+  uint32_t
   getNonce() const { return nonce_; }
-  
-  /**
-   * Clear this interest, and set the values by copying from the interest struct.
-   * @param interestStruct a C ndn_Interest struct
-   */
-  void 
-  set(const struct ndn_Interest& interestStruct);
-  
+    
   void
   setName(const Name& name) { name_ = name; }
   
@@ -377,16 +168,32 @@
   setChildSelector(int childSelector) { childSelector_ = childSelector; }
 
   void 
-  setAnswerOriginKind(int answerOriginKind) { answerOriginKind_ = answerOriginKind; }
+  setMustBeFresh(bool mustBeFresh) { mustBeFresh_ = mustBeFresh; }
 
   void 
   setScope(int scope) { scope_ = scope; }
 
   void 
-  setInterestLifetimeMilliseconds(Milliseconds interestLifetimeMilliseconds) { interestLifetimeMilliseconds_ = interestLifetimeMilliseconds; }
+  setInterestLifetime(Milliseconds interestLifetime) { interestLifetime_ = interestLifetime; }
 
   void 
-  setNonce(const Blob& nonce) { nonce_ = nonce; }
+  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 
@@ -395,23 +202,55 @@
     minSuffixComponents_ = -1;
     maxSuffixComponents_ = -1;  
     childSelector_ = -1;
-    answerOriginKind_ = -1;
+    mustBeFresh_ = false; // default
     scope_ = -1;
-    interestLifetimeMilliseconds_ = -1.0;
+    interestLifetime_ = -1.0;
+    nonce_ = 0;
   }
   
   Name name_;
   int minSuffixComponents_;
   int maxSuffixComponents_;  
-  PublisherPublicKeyDigest publisherPublicKeyDigest_;
   Exclude exclude_;
   int childSelector_;
-  int answerOriginKind_;
+  bool mustBeFresh_;
   int scope_;
-  Milliseconds interestLifetimeMilliseconds_;
-  Blob nonce_;
+  Milliseconds interestLifetime_;
+  uint32_t nonce_;
+
+  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/src/interest.cpp b/src/interest.cpp
index fe8faf3..2caffb1 100644
--- a/src/interest.cpp
+++ b/src/interest.cpp
@@ -8,139 +8,76 @@
 #include <stdexcept>
 #include <ndn-cpp/common.hpp>
 #include <ndn-cpp/interest.hpp>
-#include "c/interest.h"
 
 using namespace std;
 
 namespace ndn {
-  
-void 
-Exclude::Entry::get(struct ndn_ExcludeEntry& excludeEntryStruct) const 
+
+bool
+Interest::matchesName(const Name &name) const
 {
-  excludeEntryStruct.type = type_;
-  if (type_ == ndn_Exclude_COMPONENT)
-    component_.get(excludeEntryStruct.component);
+  if (!name_.isPrefixOf(name))
+    return false;
+  
+  if (minSuffixComponents_ >= 0 &&
+    // Add 1 for the implicit digest.
+      !(name.size() + 1 - name_.size() >= minSuffixComponents_))
+    return false;
+
+  if (maxSuffixComponents_ >= 0 &&
+    // Add 1 for the implicit digest.
+    !(name.size() + 1 - name_.size() <= maxSuffixComponents_))
+    return false;
+
+  if (!exclude_.empty() && name.size() > name_.size() &&
+      exclude_.isExcluded(name[name_.size()]))
+    return false;
+
+  return true;
 }
 
-void 
-Exclude::get(struct ndn_Exclude& excludeStruct) const
+std::ostream &
+operator << (std::ostream &os, const Interest &interest)
 {
-  if (excludeStruct.maxEntries < entries_.size())
-    throw runtime_error("excludeStruct.maxEntries must be >= this exclude getEntryCount()");
-  
-  excludeStruct.nEntries = entries_.size();
-  for (size_t i = 0; i < excludeStruct.nEntries; ++i)
-    entries_[i].get(excludeStruct.entries[i]);  
-}
+  os << interest.getName();
 
-void 
-Exclude::set(const struct ndn_Exclude& excludeStruct)
-{
-  entries_.clear();
-  for (size_t i = 0; i < excludeStruct.nEntries; ++i) {
-    ndn_ExcludeEntry *entry = &excludeStruct.entries[i];
-    
-    if (entry->type == ndn_Exclude_COMPONENT)
-      appendComponent(entry->component.value.value, entry->component.value.length);
-    else if (entry->type == ndn_Exclude_ANY)
-      appendAny();
-    else
-      throw runtime_error("unrecognized ndn_ExcludeType");
+  char delim = '?';
+
+  if (interest.getMinSuffixComponents() >= 0) {
+    os << delim << "ndn.MinSuffixComponents=" << interest.getMinSuffixComponents();
+    delim = '&';
   }
-}
-
-string 
-Exclude::toUri() const
-{
-  if (entries_.size() == 0)
-    return "";
-
-  ostringstream result;
-  for (unsigned i = 0; i < entries_.size(); ++i) {
-    if (i > 0)
-      result << ",";
-        
-    if (entries_[i].getType() == ndn_Exclude_ANY)
-      result << "*";
-    else
-      Name::toEscapedString(*entries_[i].getComponent().getValue(), result);
+  if (interest.getMaxSuffixComponents() >= 0) {
+    os << delim << "ndn.MaxSuffixComponents=" << interest.getMaxSuffixComponents();
+    delim = '&';
   }
-  
-  return result.str();  
-}
-
-void 
-Interest::set(const struct ndn_Interest& interestStruct) 
-{
-  name_.set(interestStruct.name);
-  minSuffixComponents_ = interestStruct.minSuffixComponents;
-  maxSuffixComponents_ = interestStruct.maxSuffixComponents;
-  
-  publisherPublicKeyDigest_.set(interestStruct.publisherPublicKeyDigest);
-  
-  exclude_.set(interestStruct.exclude);
-  childSelector_ = interestStruct.childSelector;
-  answerOriginKind_ = interestStruct.answerOriginKind;
-  scope_ = interestStruct.scope;
-  interestLifetimeMilliseconds_ = interestStruct.interestLifetimeMilliseconds;
-  nonce_ = Blob(interestStruct.nonce);
-}
-
-void 
-Interest::get(struct ndn_Interest& interestStruct) const 
-{
-  name_.get(interestStruct.name);
-  interestStruct.minSuffixComponents = minSuffixComponents_;
-  interestStruct.maxSuffixComponents = maxSuffixComponents_;
-  publisherPublicKeyDigest_.get(interestStruct.publisherPublicKeyDigest);
-  exclude_.get(interestStruct.exclude);
-  interestStruct.childSelector = childSelector_;
-  interestStruct.answerOriginKind = answerOriginKind_;
-  interestStruct.scope = scope_;
-  interestStruct.interestLifetimeMilliseconds = interestLifetimeMilliseconds_;
-  nonce_.get(interestStruct.nonce);
-}
-
-string 
-Interest::toUri() const
-{
-  ostringstream selectors;
-
-  if (minSuffixComponents_ >= 0)
-    selectors << "&ndn.MinSuffixComponents=" << minSuffixComponents_;
-  if (maxSuffixComponents_ >= 0)
-    selectors << "&ndn.MaxSuffixComponents=" << maxSuffixComponents_;
-  if (childSelector_ >= 0)
-    selectors << "&ndn.ChildSelector=" << childSelector_;
-  if (answerOriginKind_ >= 0)
-    selectors << "&ndn.AnswerOriginKind=" << answerOriginKind_;
-  if (scope_ >= 0)
-    selectors << "&ndn.Scope=" << scope_;
-  if (interestLifetimeMilliseconds_ >= 0)
-    selectors << "&ndn.InterestLifetime=" << interestLifetimeMilliseconds_;
-  if (publisherPublicKeyDigest_.getPublisherPublicKeyDigest().size() > 0) {
-    selectors << "&ndn.PublisherPublicKeyDigest=";
-    Name::toEscapedString(*publisherPublicKeyDigest_.getPublisherPublicKeyDigest(), selectors);
+  if (interest.getChildSelector() >= 0) {
+    os << delim << "ndn.ChildSelector=" << interest.getChildSelector();
+    delim = '&';
   }
-  if (nonce_.size() > 0) {
-    selectors << "&ndn.Nonce=";
-    Name::toEscapedString(*nonce_, selectors);
+  if (interest.getMustBeFresh()) {
+    os << delim << "ndn.MustBeFresh=" << interest.getMustBeFresh();
+    delim = '&';
   }
-  if (exclude_.size() > 0)
-    selectors << "&ndn.Exclude=" << exclude_.toUri();
-
-  ostringstream result;
-
-  result << name_.toUri();
-  string selectorsString(selectors.str());
-  if (selectorsString.size() > 0) {
-    // Replace the first & with ?.
-    result << "?";
-    result.write(&selectorsString[1], selectorsString.size() - 1);
+  if (interest.getScope() >= 0) {
+    os << delim << "ndn.Scope=" << interest.getScope();
+    delim = '&';
   }
-  
-  return result.str();  
+  if (interest.getInterestLifetime() >= 0) {
+    os << delim << "ndn.InterestLifetime=" << interest.getInterestLifetime();
+    delim = '&';
+  }
+
+  if (interest.getNonce() > 0) {
+    os << delim << "ndn.Nonce=" << interest.getNonce();
+    delim = '&';
+  }
+  if (!interest.getExclude().empty()) {
+    os << delim << "ndn.Exclude=" << interest.getExclude();
+    delim = '&';
+  }
+
+  return os;
 }
 
 }
-
