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
