Implement Interest Exclude
diff --git a/ndn-cpp/Interest.cpp b/ndn-cpp/Interest.cpp
index d081620..382db2e 100644
--- a/ndn-cpp/Interest.cpp
+++ b/ndn-cpp/Interest.cpp
@@ -3,12 +3,38 @@
  * See COPYING for copyright and distribution information.
  */
 
+#include <stdexcept>
 #include "Interest.hpp"
 
 using namespace std;
 
 namespace ndn {
   
+void Exclude::get(struct ndn_Exclude &excludeStruct) const
+{
+  if (excludeStruct.maxEntries < entries_.size())
+    throw runtime_error("excludeStruct.maxEntries must be >= this exclude getEntryCount()");
+  
+  excludeStruct.nEntries = entries_.size();
+  for (unsigned int i = 0; i < excludeStruct.nEntries; ++i)
+    entries_[i].get(excludeStruct.entries[i]);  
+}
+
+void Exclude::set(struct ndn_Exclude &excludeStruct)
+{
+  entries_.clear();
+  for (unsigned int i = 0; i < excludeStruct.nEntries; ++i) {
+    ndn_ExcludeEntry *entry = &excludeStruct.entries[i];
+    
+    if (entry->type == ndn_Exclude_COMPONENT)
+      addComponent(entry->component, entry->componentLength);
+    else if (entry->type == ndn_Exclude_ANY)
+      addAny();
+    else
+      throw runtime_error("unrecognized ndn_ExcludeType");
+  }
+}
+
 void Interest::set(struct ndn_Interest &interestStruct) 
 {
   name_.set(interestStruct.name);
@@ -19,7 +45,8 @@
   if (interestStruct.publisherPublicKeyDigest)
     publisherPublicKeyDigest_.insert
       (publisherPublicKeyDigest_.begin(), interestStruct.publisherPublicKeyDigest, interestStruct.publisherPublicKeyDigest + interestStruct.publisherPublicKeyDigestLength);
-	// TODO: implement exclude
+  
+  exclude_.set(interestStruct.exclude);
 	childSelector_ = interestStruct.childSelector;
 	answerOriginKind_ = interestStruct.answerOriginKind;
 	scope_ = interestStruct.scope;
@@ -42,8 +69,7 @@
   else
     interestStruct.publisherPublicKeyDigest = 0;
   
-  // TODO: implement exclude.
-  
+  exclude_.get(interestStruct.exclude);
   interestStruct.childSelector = childSelector_;
   interestStruct.answerOriginKind = answerOriginKind_;
   interestStruct.scope = scope_;
diff --git a/ndn-cpp/Interest.hpp b/ndn-cpp/Interest.hpp
index ab94f99..2a3def0 100644
--- a/ndn-cpp/Interest.hpp
+++ b/ndn-cpp/Interest.hpp
@@ -11,6 +11,101 @@
 #include "c/Interest.h"
 
 namespace ndn {
+  
+class ExcludeEntry {
+public:
+  /**
+   * Create an ExcludeEntry of type ndn_Exclude_ANY
+   */
+  ExcludeEntry()
+  : type_(ndn_Exclude_ANY)
+  {    
+  }
+  
+  /**
+   * Create an ExcludeEntry of type ndn_Exclude_COMPONENT
+   */
+  ExcludeEntry(unsigned char *component, unsigned int componentLen) 
+  : type_(ndn_Exclude_COMPONENT), component_(component, component + componentLen)
+  {
+  }
+  
+  /**
+   * Set the type in the excludeEntryStruct and to point to this component, 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_NameComponent struct to receive the pointer.
+   */
+  void get(struct ndn_ExcludeEntry &excludeEntryStruct) const 
+  {
+    excludeEntryStruct.type = type_;
+    if (type_ == ndn_Exclude_COMPONENT) {
+      excludeEntryStruct.componentLength = component_.size();
+      excludeEntryStruct.component = (unsigned char *)&component_[0];
+    }
+  }
+  
+  ndn_ExcludeType getType() const { return type_; }
+  
+  const std::vector<unsigned char> &getComponent() const { return component_; }
+  
+private:
+  ndn_ExcludeType type_;
+  std::vector<unsigned char> component_; /**< only used if type_ is ndn_Exclude_COMPONENT */
+}; 
+  
+class Exclude {
+public:
+  /**
+   * Create a new Exclude with no entries.
+   */
+  Exclude() {
+  }
+  
+  unsigned int getEntryCount() const {
+    return entries_.size();
+  }
+  
+  const ExcludeEntry &getEntry(unsigned int 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(struct ndn_Exclude &excludeStruct);
+
+  /**
+   * Add a new entry of type ndn_Exclude_ANY
+   */
+  void addAny()
+  {    
+    entries_.push_back(ExcludeEntry());
+  }
+  
+  /**
+   * Add a new entry of type ndn_Exclude_COMPONENT, copying from component of length compnentLength
+   */
+  void addComponent(unsigned char *component, unsigned int componentLen) 
+  {
+    entries_.push_back(ExcludeEntry(component, componentLen));
+  }
+  
+  /**
+   * Clear all the entries.
+   */
+  void clear() {
+    entries_.clear();
+  }
+  
+private:
+	std::vector<ExcludeEntry> entries_;
+};
 
 class Interest {
 public:    
@@ -54,7 +149,7 @@
   
   const std::vector<unsigned char> getPublisherPublicKeyDigest() const { return publisherPublicKeyDigest_; }
 
-  // TODO: Implement getExclude().)
+  const Exclude &getExclude() const { return exclude_; }
   
   int getChildSelector() const { return childSelector_; }
 
@@ -78,7 +173,7 @@
 	int minSuffixComponents_;
 	int maxSuffixComponents_;	
 	std::vector<unsigned char> publisherPublicKeyDigest_;
-	// TODO: implement exclude
+  Exclude exclude_;
 	int childSelector_;
 	int answerOriginKind_;
 	int scope_;
diff --git a/test/test-encode-decode-interest.cpp b/test/test-encode-decode-interest.cpp
index e8c82c5..a6a3325 100644
--- a/test/test-encode-decode-interest.cpp
+++ b/test/test-encode-decode-interest.cpp
@@ -20,9 +20,7 @@
     0x02, 0x85, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 
                 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 
   0x00,
-#if 0
   0x02, 0xda, 0xfa, 0x9d, 0x61, 0x62, 0x63, 0x00, 0xea, 0x00, 0x00, 
-#endif
   0x05, 0xaa, 0x8e, 0x31, 0x00, 
   0x02, 0xfa, 0x8e, 0x34, 0x00, 
   0x02, 0xd2, 0x8e, 0x32, 0x00, 
@@ -42,6 +40,7 @@
     interest.decode(Interest1, sizeof(Interest1));
     cout << "Interest name " << interest.getName().to_uri() << endl;
     cout << "Interest minSuffixComponents " << interest.getMinSuffixComponents() << endl;
+    cout << "Interest excludeEntryCount " << interest.getExclude().getEntryCount() << endl;
     cout << "InterestLifetime " << interest.getInterestLifetime() << endl;
     
     vector<unsigned char> encoding;
@@ -52,6 +51,7 @@
     reDecodedInterest.decode(encoding);
     cout << "Re-decoded Interest name " << reDecodedInterest.getName().to_uri() << endl;
     cout << "Re-decoded Interest minSuffixComponents " << reDecodedInterest.getMinSuffixComponents() << endl;
+    cout << "Re-decoded Interest excludeEntryCount " << reDecodedInterest.getExclude().getEntryCount() << endl;
     cout << "Re-decoded InterestLifetime " << reDecodedInterest.getInterestLifetime() << endl;
   } catch (exception &e) {
     cout << "exception: " << e.what() << endl;