Added support for ContentObject
diff --git a/Makefile.am b/Makefile.am
index 0ddbb32..d9a11e7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -11,33 +11,44 @@
 
 lib_LIBRARIES = libndn-c.a libndn-cpp.a
 
-bin_PROGRAMS = bin/test-encode-decode-interest
+bin_PROGRAMS = bin/test-encode-decode-Interest bin/test-encode-decode-ContentObject
 
 libndn_c_a_SOURCES = \
   config.h \
+  ndn-cpp/c/ContentObject.h \
   ndn-cpp/c/Interest.h \
+  ndn-cpp/c/Key.h \
   ndn-cpp/c/Name.h \
+  ndn-cpp/c/PublisherPublicKeyDigest.h \
   ndn-cpp/c/errors.c ndn-cpp/c/errors.h \
   ndn-cpp/c/encoding/BinaryXML.h \
+  ndn-cpp/c/encoding/BinaryXMLContentObject.c ndn-cpp/c/encoding/BinaryXMLContentObject.h \
   ndn-cpp/c/encoding/BinaryXMLDecoder.c ndn-cpp/c/encoding/BinaryXMLDecoder.h \
   ndn-cpp/c/encoding/BinaryXMLEncoder.c ndn-cpp/c/encoding/BinaryXMLEncoder.h \
   ndn-cpp/c/encoding/BinaryXMLInterest.c ndn-cpp/c/encoding/BinaryXMLInterest.h \
   ndn-cpp/c/encoding/BinaryXMLName.c ndn-cpp/c/encoding/BinaryXMLName.h \
+  ndn-cpp/c/encoding/BinaryXMLPublisherPublicKeyDigest.c ndn-cpp/c/encoding/BinaryXMLPublisherPublicKeyDigest.h \
   ndn-cpp/c/encoding/BinaryXMLStructureDecoder.c ndn-cpp/c/encoding/BinaryXMLStructureDecoder.h \
   ndn-cpp/c/util/DynamicUCharArray.c ndn-cpp/c/util/DynamicUCharArray.h \
   ndn-cpp/c/util/ndn_memory.c ndn-cpp/c/util/ndn_memory.h
 
 libndn_cpp_a_SOURCES = \
-  config.h ndn-cpp/common.h \
+  config.h ndn-cpp/common.hpp \
+  ndn-cpp/ContentObject.cpp ndn-cpp/c/ContentObject.h ndn-cpp/ContentObject.hpp \
   ndn-cpp/Interest.cpp ndn-cpp/c/Interest.h ndn-cpp/Interest.hpp \
+  ndn-cpp/Key.cpp ndn-cpp/c/Key.h ndn-cpp/Key.hpp \
   ndn-cpp/Name.cpp ndn-cpp/c/Name.h ndn-cpp/Name.hpp \
+  ndn-cpp/PublisherPublicKeyDigest.hpp \
   ndn-cpp/c/encoding/BinaryXML.h \
   ndn-cpp/c/encoding/BinaryXMLEncoder.h ndn-cpp/encoding/BinaryXMLEncoder.hpp ndn-cpp/c/util/DynamicUCharArray.h \
   ndn-cpp/c/encoding/BinaryXMLStructureDecoder.h ndn-cpp/encoding/BinaryXMLStructureDecoder.hpp \
   ndn-cpp/encoding/BinaryXMLWireFormat.cpp ndn-cpp/c/encoding/BinaryXMLName.h ndn-cpp/encoding/BinaryXMLWireFormat.hpp \
   ndn-cpp/encoding/WireFormat.cpp ndn-cpp/encoding/WireFormat.hpp
 
-bin_test_encode_decode_interest_SOURCES = test/test-encode-decode-interest.cpp
-bin_test_encode_decode_interest_LDADD = libndn-c.a libndn-cpp.a
+bin_test_encode_decode_Interest_SOURCES = tests/test-encode-decode-Interest.cpp
+bin_test_encode_decode_Interest_LDADD = libndn-c.a libndn-cpp.a
+
+bin_test_encode_decode_ContentObject_SOURCES = tests/test-encode-decode-ContentObject.cpp
+bin_test_encode_decode_ContentObject_LDADD = libndn-c.a libndn-cpp.a
 
 dist_noinst_SCRIPTS = autogen.sh
diff --git a/Makefile.in b/Makefile.in
index 176d86f..d614e11 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -85,7 +85,8 @@
 	$(am__configure_deps) $(srcdir)/config.h.in \
 	$(dist_noinst_SCRIPTS) depcomp COPYING ar-lib compile \
 	config.guess config.sub install-sh missing ltmain.sh
-bin_PROGRAMS = bin/test-encode-decode-interest$(EXEEXT)
+bin_PROGRAMS = bin/test-encode-decode-Interest$(EXEEXT) \
+	bin/test-encode-decode-ContentObject$(EXEEXT)
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
@@ -134,27 +135,37 @@
 libndn_c_a_AR = $(AR) $(ARFLAGS)
 libndn_c_a_LIBADD =
 am__dirstamp = $(am__leading_dot)dirstamp
-am_libndn_c_a_OBJECTS = ndn-cpp/c/encoding/BinaryXMLDecoder.$(OBJEXT) \
+am_libndn_c_a_OBJECTS = ndn-cpp/c/errors.$(OBJEXT) \
+	ndn-cpp/c/encoding/BinaryXMLContentObject.$(OBJEXT) \
+	ndn-cpp/c/encoding/BinaryXMLDecoder.$(OBJEXT) \
 	ndn-cpp/c/encoding/BinaryXMLEncoder.$(OBJEXT) \
 	ndn-cpp/c/encoding/BinaryXMLInterest.$(OBJEXT) \
 	ndn-cpp/c/encoding/BinaryXMLName.$(OBJEXT) \
+	ndn-cpp/c/encoding/BinaryXMLPublisherPublicKeyDigest.$(OBJEXT) \
 	ndn-cpp/c/encoding/BinaryXMLStructureDecoder.$(OBJEXT) \
 	ndn-cpp/c/util/DynamicUCharArray.$(OBJEXT) \
 	ndn-cpp/c/util/ndn_memory.$(OBJEXT)
 libndn_c_a_OBJECTS = $(am_libndn_c_a_OBJECTS)
 libndn_cpp_a_AR = $(AR) $(ARFLAGS)
 libndn_cpp_a_LIBADD =
-am_libndn_cpp_a_OBJECTS = ndn-cpp/Interest.$(OBJEXT) \
+am_libndn_cpp_a_OBJECTS = ndn-cpp/ContentObject.$(OBJEXT) \
+	ndn-cpp/Interest.$(OBJEXT) ndn-cpp/Key.$(OBJEXT) \
 	ndn-cpp/Name.$(OBJEXT) \
 	ndn-cpp/encoding/BinaryXMLWireFormat.$(OBJEXT) \
 	ndn-cpp/encoding/WireFormat.$(OBJEXT)
 libndn_cpp_a_OBJECTS = $(am_libndn_cpp_a_OBJECTS)
 PROGRAMS = $(bin_PROGRAMS)
-am_bin_test_encode_decode_interest_OBJECTS =  \
-	test/test-encode-decode-interest.$(OBJEXT)
-bin_test_encode_decode_interest_OBJECTS =  \
-	$(am_bin_test_encode_decode_interest_OBJECTS)
-bin_test_encode_decode_interest_DEPENDENCIES = libndn-c.a libndn-cpp.a
+am_bin_test_encode_decode_ContentObject_OBJECTS =  \
+	tests/test-encode-decode-ContentObject.$(OBJEXT)
+bin_test_encode_decode_ContentObject_OBJECTS =  \
+	$(am_bin_test_encode_decode_ContentObject_OBJECTS)
+bin_test_encode_decode_ContentObject_DEPENDENCIES = libndn-c.a \
+	libndn-cpp.a
+am_bin_test_encode_decode_Interest_OBJECTS =  \
+	tests/test-encode-decode-Interest.$(OBJEXT)
+bin_test_encode_decode_Interest_OBJECTS =  \
+	$(am_bin_test_encode_decode_Interest_OBJECTS)
+bin_test_encode_decode_Interest_DEPENDENCIES = libndn-c.a libndn-cpp.a
 SCRIPTS = $(dist_noinst_SCRIPTS)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -198,9 +209,11 @@
 am__v_CXXLD_0 = @echo "  CXXLD   " $@;
 am__v_CXXLD_1 = 
 SOURCES = $(libndn_c_a_SOURCES) $(libndn_cpp_a_SOURCES) \
-	$(bin_test_encode_decode_interest_SOURCES)
+	$(bin_test_encode_decode_ContentObject_SOURCES) \
+	$(bin_test_encode_decode_Interest_SOURCES)
 DIST_SOURCES = $(libndn_c_a_SOURCES) $(libndn_cpp_a_SOURCES) \
-	$(bin_test_encode_decode_interest_SOURCES)
+	$(bin_test_encode_decode_ContentObject_SOURCES) \
+	$(bin_test_encode_decode_Interest_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -390,29 +403,40 @@
 lib_LIBRARIES = libndn-c.a libndn-cpp.a
 libndn_c_a_SOURCES = \
   config.h \
+  ndn-cpp/c/ContentObject.h \
   ndn-cpp/c/Interest.h \
+  ndn-cpp/c/Key.h \
   ndn-cpp/c/Name.h \
+  ndn-cpp/c/PublisherPublicKeyDigest.h \
+  ndn-cpp/c/errors.c ndn-cpp/c/errors.h \
   ndn-cpp/c/encoding/BinaryXML.h \
+  ndn-cpp/c/encoding/BinaryXMLContentObject.c ndn-cpp/c/encoding/BinaryXMLContentObject.h \
   ndn-cpp/c/encoding/BinaryXMLDecoder.c ndn-cpp/c/encoding/BinaryXMLDecoder.h \
   ndn-cpp/c/encoding/BinaryXMLEncoder.c ndn-cpp/c/encoding/BinaryXMLEncoder.h \
   ndn-cpp/c/encoding/BinaryXMLInterest.c ndn-cpp/c/encoding/BinaryXMLInterest.h \
   ndn-cpp/c/encoding/BinaryXMLName.c ndn-cpp/c/encoding/BinaryXMLName.h \
+  ndn-cpp/c/encoding/BinaryXMLPublisherPublicKeyDigest.c ndn-cpp/c/encoding/BinaryXMLPublisherPublicKeyDigest.h \
   ndn-cpp/c/encoding/BinaryXMLStructureDecoder.c ndn-cpp/c/encoding/BinaryXMLStructureDecoder.h \
   ndn-cpp/c/util/DynamicUCharArray.c ndn-cpp/c/util/DynamicUCharArray.h \
   ndn-cpp/c/util/ndn_memory.c ndn-cpp/c/util/ndn_memory.h
 
 libndn_cpp_a_SOURCES = \
-  config.h ndn-cpp/common.h \
+  config.h ndn-cpp/common.hpp \
+  ndn-cpp/ContentObject.cpp ndn-cpp/c/ContentObject.h ndn-cpp/ContentObject.hpp \
   ndn-cpp/Interest.cpp ndn-cpp/c/Interest.h ndn-cpp/Interest.hpp \
+  ndn-cpp/Key.cpp ndn-cpp/c/Key.h ndn-cpp/Key.hpp \
   ndn-cpp/Name.cpp ndn-cpp/c/Name.h ndn-cpp/Name.hpp \
+  ndn-cpp/PublisherPublicKeyDigest.hpp \
   ndn-cpp/c/encoding/BinaryXML.h \
   ndn-cpp/c/encoding/BinaryXMLEncoder.h ndn-cpp/encoding/BinaryXMLEncoder.hpp ndn-cpp/c/util/DynamicUCharArray.h \
   ndn-cpp/c/encoding/BinaryXMLStructureDecoder.h ndn-cpp/encoding/BinaryXMLStructureDecoder.hpp \
   ndn-cpp/encoding/BinaryXMLWireFormat.cpp ndn-cpp/c/encoding/BinaryXMLName.h ndn-cpp/encoding/BinaryXMLWireFormat.hpp \
   ndn-cpp/encoding/WireFormat.cpp ndn-cpp/encoding/WireFormat.hpp
 
-bin_test_encode_decode_interest_SOURCES = test/test-encode-decode-interest.cpp
-bin_test_encode_decode_interest_LDADD = libndn-c.a libndn-cpp.a
+bin_test_encode_decode_Interest_SOURCES = tests/test-encode-decode-Interest.cpp
+bin_test_encode_decode_Interest_LDADD = libndn-c.a libndn-cpp.a
+bin_test_encode_decode_ContentObject_SOURCES = tests/test-encode-decode-ContentObject.cpp
+bin_test_encode_decode_ContentObject_LDADD = libndn-c.a libndn-cpp.a
 dist_noinst_SCRIPTS = autogen.sh
 all: config.h
 	$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -500,12 +524,23 @@
 
 clean-libLIBRARIES:
 	-test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
+ndn-cpp/c/$(am__dirstamp):
+	@$(MKDIR_P) ndn-cpp/c
+	@: > ndn-cpp/c/$(am__dirstamp)
+ndn-cpp/c/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) ndn-cpp/c/$(DEPDIR)
+	@: > ndn-cpp/c/$(DEPDIR)/$(am__dirstamp)
+ndn-cpp/c/errors.$(OBJEXT): ndn-cpp/c/$(am__dirstamp) \
+	ndn-cpp/c/$(DEPDIR)/$(am__dirstamp)
 ndn-cpp/c/encoding/$(am__dirstamp):
 	@$(MKDIR_P) ndn-cpp/c/encoding
 	@: > ndn-cpp/c/encoding/$(am__dirstamp)
 ndn-cpp/c/encoding/$(DEPDIR)/$(am__dirstamp):
 	@$(MKDIR_P) ndn-cpp/c/encoding/$(DEPDIR)
 	@: > ndn-cpp/c/encoding/$(DEPDIR)/$(am__dirstamp)
+ndn-cpp/c/encoding/BinaryXMLContentObject.$(OBJEXT):  \
+	ndn-cpp/c/encoding/$(am__dirstamp) \
+	ndn-cpp/c/encoding/$(DEPDIR)/$(am__dirstamp)
 ndn-cpp/c/encoding/BinaryXMLDecoder.$(OBJEXT):  \
 	ndn-cpp/c/encoding/$(am__dirstamp) \
 	ndn-cpp/c/encoding/$(DEPDIR)/$(am__dirstamp)
@@ -518,6 +553,9 @@
 ndn-cpp/c/encoding/BinaryXMLName.$(OBJEXT):  \
 	ndn-cpp/c/encoding/$(am__dirstamp) \
 	ndn-cpp/c/encoding/$(DEPDIR)/$(am__dirstamp)
+ndn-cpp/c/encoding/BinaryXMLPublisherPublicKeyDigest.$(OBJEXT):  \
+	ndn-cpp/c/encoding/$(am__dirstamp) \
+	ndn-cpp/c/encoding/$(DEPDIR)/$(am__dirstamp)
 ndn-cpp/c/encoding/BinaryXMLStructureDecoder.$(OBJEXT):  \
 	ndn-cpp/c/encoding/$(am__dirstamp) \
 	ndn-cpp/c/encoding/$(DEPDIR)/$(am__dirstamp)
@@ -543,8 +581,12 @@
 ndn-cpp/$(DEPDIR)/$(am__dirstamp):
 	@$(MKDIR_P) ndn-cpp/$(DEPDIR)
 	@: > ndn-cpp/$(DEPDIR)/$(am__dirstamp)
+ndn-cpp/ContentObject.$(OBJEXT): ndn-cpp/$(am__dirstamp) \
+	ndn-cpp/$(DEPDIR)/$(am__dirstamp)
 ndn-cpp/Interest.$(OBJEXT): ndn-cpp/$(am__dirstamp) \
 	ndn-cpp/$(DEPDIR)/$(am__dirstamp)
+ndn-cpp/Key.$(OBJEXT): ndn-cpp/$(am__dirstamp) \
+	ndn-cpp/$(DEPDIR)/$(am__dirstamp)
 ndn-cpp/Name.$(OBJEXT): ndn-cpp/$(am__dirstamp) \
 	ndn-cpp/$(DEPDIR)/$(am__dirstamp)
 ndn-cpp/encoding/$(am__dirstamp):
@@ -606,45 +648,58 @@
 
 clean-binPROGRAMS:
 	-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
-test/$(am__dirstamp):
-	@$(MKDIR_P) test
-	@: > test/$(am__dirstamp)
-test/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) test/$(DEPDIR)
-	@: > test/$(DEPDIR)/$(am__dirstamp)
-test/test-encode-decode-interest.$(OBJEXT): test/$(am__dirstamp) \
-	test/$(DEPDIR)/$(am__dirstamp)
+tests/$(am__dirstamp):
+	@$(MKDIR_P) tests
+	@: > tests/$(am__dirstamp)
+tests/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) tests/$(DEPDIR)
+	@: > tests/$(DEPDIR)/$(am__dirstamp)
+tests/test-encode-decode-ContentObject.$(OBJEXT):  \
+	tests/$(am__dirstamp) tests/$(DEPDIR)/$(am__dirstamp)
 bin/$(am__dirstamp):
 	@$(MKDIR_P) bin
 	@: > bin/$(am__dirstamp)
 
-bin/test-encode-decode-interest$(EXEEXT): $(bin_test_encode_decode_interest_OBJECTS) $(bin_test_encode_decode_interest_DEPENDENCIES) $(EXTRA_bin_test_encode_decode_interest_DEPENDENCIES) bin/$(am__dirstamp)
-	@rm -f bin/test-encode-decode-interest$(EXEEXT)
-	$(AM_V_CXXLD)$(CXXLINK) $(bin_test_encode_decode_interest_OBJECTS) $(bin_test_encode_decode_interest_LDADD) $(LIBS)
+bin/test-encode-decode-ContentObject$(EXEEXT): $(bin_test_encode_decode_ContentObject_OBJECTS) $(bin_test_encode_decode_ContentObject_DEPENDENCIES) $(EXTRA_bin_test_encode_decode_ContentObject_DEPENDENCIES) bin/$(am__dirstamp)
+	@rm -f bin/test-encode-decode-ContentObject$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(bin_test_encode_decode_ContentObject_OBJECTS) $(bin_test_encode_decode_ContentObject_LDADD) $(LIBS)
+tests/test-encode-decode-Interest.$(OBJEXT): tests/$(am__dirstamp) \
+	tests/$(DEPDIR)/$(am__dirstamp)
+
+bin/test-encode-decode-Interest$(EXEEXT): $(bin_test_encode_decode_Interest_OBJECTS) $(bin_test_encode_decode_Interest_DEPENDENCIES) $(EXTRA_bin_test_encode_decode_Interest_DEPENDENCIES) bin/$(am__dirstamp)
+	@rm -f bin/test-encode-decode-Interest$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(bin_test_encode_decode_Interest_OBJECTS) $(bin_test_encode_decode_Interest_LDADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
 	-rm -f ndn-cpp/*.$(OBJEXT)
+	-rm -f ndn-cpp/c/*.$(OBJEXT)
 	-rm -f ndn-cpp/c/encoding/*.$(OBJEXT)
 	-rm -f ndn-cpp/c/util/*.$(OBJEXT)
 	-rm -f ndn-cpp/encoding/*.$(OBJEXT)
-	-rm -f test/*.$(OBJEXT)
+	-rm -f tests/*.$(OBJEXT)
 
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/$(DEPDIR)/ContentObject.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/$(DEPDIR)/Interest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/$(DEPDIR)/Key.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/$(DEPDIR)/Name.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/c/$(DEPDIR)/errors.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/c/encoding/$(DEPDIR)/BinaryXMLContentObject.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/c/encoding/$(DEPDIR)/BinaryXMLDecoder.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/c/encoding/$(DEPDIR)/BinaryXMLEncoder.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/c/encoding/$(DEPDIR)/BinaryXMLInterest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/c/encoding/$(DEPDIR)/BinaryXMLName.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/c/encoding/$(DEPDIR)/BinaryXMLPublisherPublicKeyDigest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/c/encoding/$(DEPDIR)/BinaryXMLStructureDecoder.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/c/util/$(DEPDIR)/DynamicUCharArray.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/c/util/$(DEPDIR)/ndn_memory.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/encoding/$(DEPDIR)/BinaryXMLWireFormat.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ndn-cpp/encoding/$(DEPDIR)/WireFormat.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test-encode-decode-interest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test-encode-decode-ContentObject.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test-encode-decode-Interest.Po@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -929,14 +984,16 @@
 	-rm -f bin/$(am__dirstamp)
 	-rm -f ndn-cpp/$(DEPDIR)/$(am__dirstamp)
 	-rm -f ndn-cpp/$(am__dirstamp)
+	-rm -f ndn-cpp/c/$(DEPDIR)/$(am__dirstamp)
+	-rm -f ndn-cpp/c/$(am__dirstamp)
 	-rm -f ndn-cpp/c/encoding/$(DEPDIR)/$(am__dirstamp)
 	-rm -f ndn-cpp/c/encoding/$(am__dirstamp)
 	-rm -f ndn-cpp/c/util/$(DEPDIR)/$(am__dirstamp)
 	-rm -f ndn-cpp/c/util/$(am__dirstamp)
 	-rm -f ndn-cpp/encoding/$(DEPDIR)/$(am__dirstamp)
 	-rm -f ndn-cpp/encoding/$(am__dirstamp)
-	-rm -f test/$(DEPDIR)/$(am__dirstamp)
-	-rm -f test/$(am__dirstamp)
+	-rm -f tests/$(DEPDIR)/$(am__dirstamp)
+	-rm -f tests/$(am__dirstamp)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
@@ -948,7 +1005,7 @@
 
 distclean: distclean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-	-rm -rf ndn-cpp/$(DEPDIR) ndn-cpp/c/encoding/$(DEPDIR) ndn-cpp/c/util/$(DEPDIR) ndn-cpp/encoding/$(DEPDIR) test/$(DEPDIR)
+	-rm -rf ndn-cpp/$(DEPDIR) ndn-cpp/c/$(DEPDIR) ndn-cpp/c/encoding/$(DEPDIR) ndn-cpp/c/util/$(DEPDIR) ndn-cpp/encoding/$(DEPDIR) tests/$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-hdr distclean-tags
@@ -996,7 +1053,7 @@
 maintainer-clean: maintainer-clean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
 	-rm -rf $(top_srcdir)/autom4te.cache
-	-rm -rf ndn-cpp/$(DEPDIR) ndn-cpp/c/encoding/$(DEPDIR) ndn-cpp/c/util/$(DEPDIR) ndn-cpp/encoding/$(DEPDIR) test/$(DEPDIR)
+	-rm -rf ndn-cpp/$(DEPDIR) ndn-cpp/c/$(DEPDIR) ndn-cpp/c/encoding/$(DEPDIR) ndn-cpp/c/util/$(DEPDIR) ndn-cpp/encoding/$(DEPDIR) tests/$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
diff --git a/ndn-cpp/ContentObject.cpp b/ndn-cpp/ContentObject.cpp
new file mode 100644
index 0000000..e675e5a
--- /dev/null
+++ b/ndn-cpp/ContentObject.cpp
@@ -0,0 +1,88 @@
+/**
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "common.hpp"
+#include "ContentObject.hpp"
+
+using namespace std;
+
+namespace ndn {
+
+void Signature::get(struct ndn_Signature &signatureStruct) const 
+{
+  signatureStruct.digestAlgorithmLength = digestAlgorithm_.size();
+  if (digestAlgorithm_.size() > 0)
+    signatureStruct.digestAlgorithm = (unsigned char *)&digestAlgorithm_[0];
+  else
+    signatureStruct.digestAlgorithm = 0;
+
+  signatureStruct.witnessLength = witness_.size();
+  if (witness_.size() > 0)
+    signatureStruct.witness = (unsigned char *)&witness_[0];
+  else
+    signatureStruct.witness = 0;
+
+  signatureStruct.signatureLength = signature_.size();
+  if (signature_.size() > 0)
+    signatureStruct.signature = (unsigned char *)&signature_[0];
+  else
+    signatureStruct.signature = 0;
+}
+
+void Signature::set(const struct ndn_Signature &signatureStruct)
+{
+  setVector(digestAlgorithm_, signatureStruct.digestAlgorithm, signatureStruct.digestAlgorithmLength);
+  setVector(witness_, signatureStruct.witness, signatureStruct.witnessLength);
+  setVector(signature_, signatureStruct.signature, signatureStruct.signatureLength);
+}
+
+void SignedInfo::get(struct ndn_SignedInfo &signedInfoStruct) const 
+{
+  publisherPublicKeyDigest_.get(signedInfoStruct.publisherPublicKeyDigest);
+  // TODO: Implement timestamp
+  signedInfoStruct.type = type_;
+  signedInfoStruct.freshnessSeconds = freshnessSeconds_;
+  
+  signedInfoStruct.finalBlockIDLength = finalBlockID_.size();
+  if (finalBlockID_.size() > 0)
+    signedInfoStruct.finalBlockID = (unsigned char *)&finalBlockID_[0];
+  else
+    signedInfoStruct.finalBlockID = 0;
+
+  keyLocator_.get(signedInfoStruct.keyLocator);
+}
+
+void SignedInfo::set(const struct ndn_SignedInfo &signedInfoStruct)
+{
+  publisherPublicKeyDigest_.set(signedInfoStruct.publisherPublicKeyDigest);
+  // TODO: Implement timestamp
+  type_ = signedInfoStruct.type;
+  freshnessSeconds_ = signedInfoStruct.freshnessSeconds;
+  setVector(finalBlockID_, signedInfoStruct.finalBlockID, signedInfoStruct.finalBlockIDLength);
+  keyLocator_.set(signedInfoStruct.keyLocator);
+}
+
+void ContentObject::get(struct ndn_ContentObject &contentObjectStruct) const 
+{
+  signature_.get(contentObjectStruct.signature);
+  name_.get(contentObjectStruct.name);
+  signedInfo_.get(contentObjectStruct.signedInfo);
+  
+  contentObjectStruct.contentLength = content_.size();
+  if (content_.size() > 0)
+    contentObjectStruct.content = (unsigned char *)&content_[0];
+  else
+    contentObjectStruct.content = 0;
+}
+
+void ContentObject::set(const struct ndn_ContentObject &contentObjectStruct)
+{
+  signature_.set(contentObjectStruct.signature);
+  name_.set(contentObjectStruct.name);
+  signedInfo_.set(contentObjectStruct.signedInfo);
+  setVector(content_, contentObjectStruct.content, contentObjectStruct.contentLength);
+}
+
+}
diff --git a/ndn-cpp/ContentObject.hpp b/ndn-cpp/ContentObject.hpp
new file mode 100644
index 0000000..9cf1c3d
--- /dev/null
+++ b/ndn-cpp/ContentObject.hpp
@@ -0,0 +1,142 @@
+/**
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_CONTENTOBJECT_HPP
+#define	NDN_CONTENTOBJECT_HPP
+
+#include "Name.hpp"
+#include "PublisherPublicKeyDigest.hpp"
+#include "Key.hpp"
+#include "c/ContentObject.h"
+
+namespace ndn {
+
+class Signature {
+public:
+  /**
+   * Set the signatureStruct to point to the values in this signature object, without copying any memory.
+   * WARNING: The resulting pointers in signatureStruct are invalid after a further use of this object which could reallocate memory.
+   * @param signatureStruct a C ndn_Signature struct where the name components array is already allocated.
+   */
+  void get(struct ndn_Signature &signatureStruct) const;
+
+  /**
+   * Clear this signature, and set the values by copying from the ndn_Signature struct.
+   * @param signatureStruct a C ndn_Signature struct
+   */
+  void set(const struct ndn_Signature &signatureStruct);
+
+  const std::vector<unsigned char> getDigestAlgorithm() const { return digestAlgorithm_; }
+
+  const std::vector<unsigned char> getWitness() const { return witness_; }
+
+  const std::vector<unsigned char> getSignature() const { return signature_; }
+  
+private:
+  std::vector<unsigned char> digestAlgorithm_; /**< if empty, the default is 2.16.840.1.101.3.4.2.1 (sha-256) */
+  std::vector<unsigned char> witness_;
+  std::vector<unsigned char> signature_;
+};
+
+class SignedInfo {
+public:
+  SignedInfo() 
+  {   
+    type_ = ndn_ContentType_DATA;
+    freshnessSeconds_ = -1;
+  }
+
+  /**
+   * Set the signedInfoStruct to point to the values in this signed info object, without copying any memory.
+   * WARNING: The resulting pointers in signedInfoStruct are invalid after a further use of this object which could reallocate memory.
+   * @param signedInfoStruct a C ndn_SignedInfo struct where the name components array is already allocated.
+   */
+  void get(struct ndn_SignedInfo &signedInfoStruct) const;
+
+  /**
+   * Clear this signed info, and set the values by copying from the ndn_SignedInfo struct.
+   * @param signedInfoStruct a C ndn_SignedInfo struct
+   */
+  void set(const struct ndn_SignedInfo &signedInfoStruct);
+
+  const PublisherPublicKeyDigest &getPublisherPublicKeyDigest() const { return publisherPublicKeyDigest_; }
+  
+  // TODO: Implement timestamp
+  
+  int getType() const { return type_; }
+  
+  int getFreshnessSeconds() const { return freshnessSeconds_; }
+  
+  const std::vector<unsigned char> getFinalBlockID() const { return finalBlockID_; }
+  
+  const KeyLocator &getKeyLocator() const { return keyLocator_; }
+  
+private:
+  PublisherPublicKeyDigest publisherPublicKeyDigest_;
+  // TODO: Implement timestamp
+  int type_;
+  int freshnessSeconds_;
+  std::vector<unsigned char> finalBlockID_;
+  KeyLocator keyLocator_;
+};
+  
+class ContentObject {
+public:
+  void encode(std::vector<unsigned char> &output, WireFormat &wireFormat) const 
+  {
+    wireFormat.encodeContentObject(*this, output);
+  }
+  void encode(std::vector<unsigned char> &output) const 
+  {
+    encode(output, BinaryXMLWireFormat::instance());
+  }
+  void decode(const unsigned char *input, unsigned int inputLength, WireFormat &wireFormat) 
+  {
+    wireFormat.decodeContentObject(*this, input, inputLength);
+  }
+  void decode(const unsigned char *input, unsigned int inputLength) 
+  {
+    decode(input, inputLength, BinaryXMLWireFormat::instance());
+  }
+  void decode(const std::vector<unsigned char> &input, WireFormat &wireFormat) 
+  {
+    decode(&input[0], input.size(), wireFormat);
+  }
+  void decode(const std::vector<unsigned char> &input) 
+  {
+    decode(&input[0], input.size());
+  }
+  
+  /**
+   * Set the contentObjectStruct to point to the values in this interest, without copying any memory.
+   * WARNING: The resulting pointers in contentObjectStruct are invalid after a further use of this object which could reallocate memory.
+   * @param contentObjectStruct a C ndn_ContentObject struct where the name components array is already allocated.
+   */
+  void get(struct ndn_ContentObject &contentObjectStruct) const;
+
+  /**
+   * Clear this content object, and set the values by copying from the ndn_ContentObject struct.
+   * @param contentObjectStruct a C ndn_ContentObject struct
+   */
+  void set(const struct ndn_ContentObject &contentObjectStruct);
+
+  const Signature &getSignature() const { return signature_; }
+  
+  const Name &getName() const { return name_; }
+  
+  const SignedInfo &getSignedInfo() const { return signedInfo_; }
+  
+  const std::vector<unsigned char> getContent() const { return content_; }
+  
+private:
+  Signature signature_;
+  Name name_;
+  SignedInfo signedInfo_;
+  std::vector<unsigned char> content_;
+};
+  
+}
+
+#endif
diff --git a/ndn-cpp/Key.cpp b/ndn-cpp/Key.cpp
new file mode 100644
index 0000000..45425f2
--- /dev/null
+++ b/ndn-cpp/Key.cpp
@@ -0,0 +1,34 @@
+/**
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "common.hpp"
+#include "Key.hpp"
+
+using namespace std;
+
+namespace ndn {
+
+void KeyLocator::get(struct ndn_KeyLocator &keyLocatorStruct) const 
+{
+  keyLocatorStruct.type = type_;
+  
+  keyLocatorStruct.keyOrCertificateLength = keyOrCertificate_.size();
+  if (keyOrCertificate_.size() > 0)
+    keyLocatorStruct.keyOrCertificate = (unsigned char *)&keyOrCertificate_[0];
+  else
+    keyLocatorStruct.keyOrCertificate = 0;
+
+  // TODO: Implement keyName.
+}
+
+void KeyLocator::set(const struct ndn_KeyLocator &keyLocatorStruct)
+{
+  type_ = keyLocatorStruct.type;
+  setVector(keyOrCertificate_, keyLocatorStruct.keyOrCertificate, keyLocatorStruct.keyOrCertificateLength);
+  // TODO: Implement keyName.
+}
+
+}
+
diff --git a/ndn-cpp/Key.hpp b/ndn-cpp/Key.hpp
new file mode 100644
index 0000000..aa2f01b
--- /dev/null
+++ b/ndn-cpp/Key.hpp
@@ -0,0 +1,48 @@
+/**
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_KEY_HPP
+#define	NDN_KEY_HPP
+
+#include <vector>
+#include "c/Key.h"
+
+namespace ndn {
+  
+class KeyLocator {
+public:
+  KeyLocator()
+  {
+    type_ = (ndn_KeyLocatorType)-1;
+  }
+  
+  /**
+   * Set the keyLocatorStruct to point to the values in this key locator, without copying any memory.
+   * WARNING: The resulting pointers in keyLocatorStruct are invalid after a further use of this object which could reallocate memory.
+   * @param keyLocatorStruct a C ndn_KeyLocator struct where the name components array is already allocated.
+   */
+  void get(struct ndn_KeyLocator &keyLocatorStruct) const;
+  
+  /**
+   * Clear this key locator, and set the values by copying from the ndn_KeyLocator struct.
+   * @param keyLocatorStruct a C ndn_KeyLocator struct
+   */
+  void set(const struct ndn_KeyLocator &keyLocatorStruct);
+
+  ndn_KeyLocatorType getType() const { return type_; }
+  
+  const std::vector<unsigned char> getKeyOrCertificate() const { return keyOrCertificate_; }
+
+  // TODO: Implement keyName.
+
+private:
+  ndn_KeyLocatorType type_;
+  std::vector<unsigned char> keyOrCertificate_; /**< used if type_ is ndn_KeyLocatorType_KEY or ndn_KeyLocatorType_CERTIFICATE */
+  // TODO: Implement keyName.
+};
+  
+}
+
+#endif
diff --git a/ndn-cpp/c/ContentObject.h b/ndn-cpp/c/ContentObject.h
new file mode 100644
index 0000000..4d46e53
--- /dev/null
+++ b/ndn-cpp/c/ContentObject.h
@@ -0,0 +1,96 @@
+/**
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_CONTENTOBJECT_H
+#define	NDN_CONTENTOBJECT_H
+
+#include "Name.h"
+#include "PublisherPublicKeyDigest.h"
+#include "Key.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct ndn_Signature {
+  unsigned char *digestAlgorithm;      /**< pointer to pre-allocated buffer.  0 for none.
+                                        *   If none, default is 2.16.840.1.101.3.4.2.1 (sha-256). */
+  unsigned int digestAlgorithmLength; /**< length of digestAlgorithm.  0 for none */
+  unsigned char *witness;              /**< pointer to pre-allocated buffer.  0 for none. */
+  unsigned int witnessLength;          /**< length of witness.  0 for none */
+  unsigned char *signature;
+  unsigned int signatureLength;
+};
+
+static inline void ndn_Signature_init(struct ndn_Signature *self) {
+  self->digestAlgorithm = 0;
+  self->digestAlgorithmLength = 0;
+  self->witness = 0;
+  self->witnessLength = 0;
+  self->signature = 0;
+  self->signatureLength = 0;
+}
+
+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
+};
+
+struct ndn_SignedInfo {
+  struct ndn_PublisherPublicKeyDigest publisherPublicKeyDigest;
+  // TODO: Implement timestamp
+  int type;              /**< default is ndn_ContentType_DATA. -1 for none */
+  int freshnessSeconds;  /**< -1 for none */
+	unsigned char *finalBlockID;	    /**< pointer to pre-allocated buffer.  0 for none */
+  unsigned int finalBlockIDLength;  /**< length of finalBlockID.  0 for none */
+  struct ndn_KeyLocator keyLocator;
+};
+
+/**
+ * Initialize the ndn_SignedInfo struct with values for none and the type to the default ndn_ContentType_DATA.
+ * @param self pointer to the ndn_SignedInfo struct.
+ */
+static inline void ndn_SignedInfo_init(struct ndn_SignedInfo *self) {
+  ndn_PublisherPublicKeyDigest_init(&self->publisherPublicKeyDigest);
+  self->type = ndn_ContentType_DATA;
+  self->freshnessSeconds = -1;
+  self->finalBlockID = 0;
+  self->finalBlockIDLength = 0;
+  ndn_KeyLocator_init(&self->keyLocator);
+}
+
+struct ndn_ContentObject {
+  struct ndn_Signature signature;
+  struct ndn_Name name;
+  struct ndn_SignedInfo signedInfo;
+  unsigned char *content;     /**< pointer to the content */
+  unsigned int contentLength; /**< length of content */
+};
+
+/**
+ * Initialize an ndn_ContentObject struct with the pre-allocated nameComponents,
+ * and defaults for all the values.
+ * @param self pointer to the ndn_ContentObject struct
+ * @param nameComponents the pre-allocated array of ndn_NameComponent
+ * @param maxNameComponents the number of elements in the allocated nameComponents array
+ */
+static inline void ndn_ContentObject_init(struct ndn_ContentObject *self, struct ndn_NameComponent *nameComponents, unsigned int maxNameComponents) 
+{
+  ndn_Signature_init(&self->signature);
+  ndn_Name_init(&self->name, nameComponents, maxNameComponents);
+  ndn_SignedInfo_init(&self->signedInfo);
+  self->content = 0;
+  self->contentLength = 0;
+}
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
diff --git a/ndn-cpp/c/Key.h b/ndn-cpp/c/Key.h
new file mode 100644
index 0000000..1545a74
--- /dev/null
+++ b/ndn-cpp/c/Key.h
@@ -0,0 +1,38 @@
+/**
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_KEY_H
+#define	NDN_KEY_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+  ndn_KeyLocatorType_KEY = 1,
+  ndn_KeyLocatorType_CERTIFICATE = 2,
+  ndn_KeyLocatorType_KEYNAME = 3
+} ndn_KeyLocatorType;
+  
+struct ndn_KeyLocator {
+  ndn_KeyLocatorType type;
+  unsigned char *keyOrCertificate; /**< if type is ndn_KeyLocatorType_KEY, pointer to the pre-allocated buffer for the key value.
+                                        if type is ndn_KeyLocatorType_CERTIFICATE, pointer to the pre-allocated buffer for the cetrificate value. */
+  unsigned int keyOrCertificateLength;
+  // TODO: Implement keyName.
+};
+
+static inline void ndn_KeyLocator_init(struct ndn_KeyLocator *self) {
+  self->type = (ndn_KeyLocatorType)-1;
+  self->keyOrCertificate = 0;
+  self->keyOrCertificateLength = 0;
+  // TODO: Implement keyName.
+}
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
diff --git a/ndn-cpp/c/encoding/BinaryXMLContentObject.h b/ndn-cpp/c/encoding/BinaryXMLContentObject.h
new file mode 100644
index 0000000..b6444bb
--- /dev/null
+++ b/ndn-cpp/c/encoding/BinaryXMLContentObject.h
@@ -0,0 +1,26 @@
+/**
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_BINARYXMLCONTENTOBJECT_H
+#define	NDN_BINARYXMLCONTENTOBJECT_H
+
+#include "../errors.h"
+#include "../ContentObject.h"
+#include "BinaryXMLEncoder.h"
+#include "BinaryXMLDecoder.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+ndn_Error ndn_encodeBinaryXMLContentObject(struct ndn_ContentObject *contentObject, struct ndn_BinaryXMLEncoder *encoder);
+
+ndn_Error ndn_decodeBinaryXMLContentObject(struct ndn_ContentObject *contentObject, struct ndn_BinaryXMLDecoder *decoder);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
diff --git a/ndn-cpp/encoding/BinaryXMLWireFormat.cpp b/ndn-cpp/encoding/BinaryXMLWireFormat.cpp
index f3af9c8..83261de 100644
--- a/ndn-cpp/encoding/BinaryXMLWireFormat.cpp
+++ b/ndn-cpp/encoding/BinaryXMLWireFormat.cpp
@@ -6,7 +6,9 @@
 #include <stdexcept>
 #include "../c/encoding/BinaryXMLName.h"
 #include "../c/encoding/BinaryXMLInterest.h"
+#include "../c/encoding/BinaryXMLContentObject.h"
 #include "../Interest.hpp"
+#include "../ContentObject.hpp"
 #include "BinaryXMLEncoder.hpp"
 #include "../c/encoding/BinaryXMLDecoder.h"
 #include "BinaryXMLWireFormat.hpp"
@@ -81,4 +83,35 @@
   interest.set(interestStruct);
 }
 
+void BinaryXMLWireFormat::encodeContentObject(const ContentObject &contentObject, vector<unsigned char> &output) 
+{
+  struct ndn_NameComponent nameComponents[100];
+  struct ndn_ContentObject contentObjectStruct;
+  ndn_ContentObject_init
+    (&contentObjectStruct, nameComponents, sizeof(nameComponents) / sizeof(nameComponents[0]));
+  contentObject.get(contentObjectStruct);
+
+  BinaryXMLEncoder encoder;
+  ndn_encodeBinaryXMLContentObject(&contentObjectStruct, encoder.getEncoder());
+     
+  encoder.appendTo(output);
+}
+
+void BinaryXMLWireFormat::decodeContentObject(ContentObject &contentObject, const unsigned char *input, unsigned int inputLength)
+{
+  struct ndn_NameComponent nameComponents[100];
+  struct ndn_ContentObject contentObjectStruct;
+  ndn_ContentObject_init
+    (&contentObjectStruct, nameComponents, sizeof(nameComponents) / sizeof(nameComponents[0]));
+    
+  struct ndn_BinaryXMLDecoder decoder;
+  ndn_BinaryXMLDecoder_init(&decoder, (unsigned char *)input, inputLength);
+  
+  ndn_Error error;
+  if (error = ndn_decodeBinaryXMLContentObject(&contentObjectStruct, &decoder))
+    throw std::runtime_error(ndn_getErrorString(error));
+
+  contentObject.set(contentObjectStruct);
+}
+
 }
diff --git a/ndn-cpp/encoding/BinaryXMLWireFormat.hpp b/ndn-cpp/encoding/BinaryXMLWireFormat.hpp
index ad3a88c..a1a5e6a 100644
--- a/ndn-cpp/encoding/BinaryXMLWireFormat.hpp
+++ b/ndn-cpp/encoding/BinaryXMLWireFormat.hpp
@@ -17,6 +17,9 @@
 
   virtual void encodeInterest(const Interest &interest, std::vector<unsigned char> &output);
   virtual void decodeInterest(Interest &interest, const unsigned char *input, unsigned int inputLength);
+
+  virtual void encodeContentObject(const ContentObject &contentObject, std::vector<unsigned char> &output);
+  virtual void decodeContentObject(ContentObject &contentObject, const unsigned char *input, unsigned int inputLength);
   
   static BinaryXMLWireFormat &instance() { return instance_; }
   
diff --git a/ndn-cpp/encoding/WireFormat.cpp b/ndn-cpp/encoding/WireFormat.cpp
index 3217fe1..7e784a3 100644
--- a/ndn-cpp/encoding/WireFormat.cpp
+++ b/ndn-cpp/encoding/WireFormat.cpp
@@ -28,4 +28,13 @@
   throw logic_error("unimplemented");
 }
 
+void WireFormat::encodeContentObject(const ContentObject &contentObject, vector<unsigned char> &output) 
+{
+  throw logic_error("unimplemented");
+}
+void WireFormat::decodeContentObject(ContentObject &contentObject, const unsigned char *input, unsigned int inputLength) 
+{
+  throw logic_error("unimplemented");
+}
+
 }
diff --git a/ndn-cpp/encoding/WireFormat.hpp b/ndn-cpp/encoding/WireFormat.hpp
index f09ae22..8458f94 100644
--- a/ndn-cpp/encoding/WireFormat.hpp
+++ b/ndn-cpp/encoding/WireFormat.hpp
@@ -12,6 +12,7 @@
   
 class Name;
 class Interest;
+class ContentObject;
   
 class WireFormat {
 public:
@@ -21,7 +22,8 @@
   virtual void encodeInterest(const Interest &interest, std::vector<unsigned char> &output);
   virtual void decodeInterest(Interest &interest, const unsigned char *input, unsigned int inputLength);
 
-  // etc. for each type of object.
+  virtual void encodeContentObject(const ContentObject &contentObject, std::vector<unsigned char> &output);
+  virtual void decodeContentObject(ContentObject &contentObject, const unsigned char *input, unsigned int inputLength);
 };
 
 }
diff --git a/tests/test-encode-decode-ContentObject.cpp b/tests/test-encode-decode-ContentObject.cpp
new file mode 100644
index 0000000..fcb7905
--- /dev/null
+++ b/tests/test-encode-decode-ContentObject.cpp
@@ -0,0 +1,83 @@
+/**
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ */
+
+#include <cstdlib>
+#include <sstream>
+#include <iostream>
+#include <ndn-cpp/ContentObject.hpp>
+
+using namespace std;
+using namespace ndn;
+
+unsigned char ContentObject1[] = {
+0x04, 0x82, // ContentObject
+  0x02, 0xaa, // Signature
+    0x03, 0xb2, // SignatureBits
+      0x08, 0x85, 0x20, 0xea, 0xb5, 0xb0, 0x63, 0xda, 0x94, 0xe9, 0x68, 0x7a,
+      0x8e, 0x65, 0x60, 0xe0, 0xc6, 0x43, 0x96, 0xd9, 0x69, 0xb4, 0x40, 0x72, 0x52, 0x00, 0x2c, 0x8e, 0x2a, 0xf5,
+      0x47, 0x12, 0x59, 0x93, 0xda, 0xed, 0x82, 0xd0, 0xf8, 0xe6, 0x65, 0x09, 0x87, 0x84, 0x54, 0xc7, 0xce, 0x9a,
+      0x93, 0x0d, 0x47, 0xf1, 0xf9, 0x3b, 0x98, 0x78, 0x2c, 0x22, 0x21, 0xd9, 0x2b, 0xda, 0x03, 0x30, 0x84, 0xf3,
+      0xc5, 0x52, 0x64, 0x2b, 0x1d, 0xde, 0x50, 0xe0, 0xee, 0xca, 0xa2, 0x73, 0x7a, 0x93, 0x30, 0xa8, 0x47, 0x7f,
+      0x6f, 0x41, 0xb0, 0xc8, 0x6e, 0x89, 0x1c, 0xcc, 0xf9, 0x01, 0x44, 0xc3, 0x08, 0xcf, 0x77, 0x47, 0xfc, 0xed,
+      0x48, 0xf0, 0x4c, 0xe9, 0xc2, 0x3b, 0x7d, 0xef, 0x6e, 0xa4, 0x80, 0x40, 0x9e, 0x43, 0xb6, 0x77, 0x7a, 0x1d,
+      0x51, 0xed, 0x98, 0x33, 0x93, 0xdd, 0x88, 0x01, 0x0e, 0xd3, 
+    0x00, 
+  0x00, 
+  0xf2, 0xfa, 0x9d, 0x6e, 0x64, 0x6e, 0x00, 0xfa, 0x9d, 0x61, 0x62, 0x63, 0x00, 0x00,  // Name
+  0x01, 0xa2, // SignedInfo
+    0x03, 0xe2, // PublisherPublicKeyDigest
+      0x02, 0x85, 0xb5, 0x50, 0x6b, 0x1a,
+      0xba, 0x3d, 0xa7, 0x76, 0x1b, 0x0f, 0x8d, 0x61, 0xa4, 0xaa, 0x7e, 0x3b, 0x6d, 0x15, 0xb4, 0x26, 0xfe, 0xb5,
+      0xbd, 0xa8, 0x23, 0x89, 0xac, 0xa7, 0x65, 0xa3, 0xb8, 0x1c, 
+    0x00, 
+#if 0
+    0x02, 0xba, // Timestamp
+      0xb5, 0x05, 0x1d, 0xde, 0xe9, 0x5b, 0xdb, 
+    0x00, 
+#endif
+    0x01, 0xe2, // KeyLocator
+      0x01, 0xda, // Key
+        0x0a, 0x95, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+        0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81,
+        0x81, 0x00, 0xe1, 0x7d, 0x30, 0xa7, 0xd8, 0x28, 0xab, 0x1b, 0x84, 0x0b, 0x17, 0x54, 0x2d, 0xca, 0xf6, 0x20,
+        0x7a, 0xfd, 0x22, 0x1e, 0x08, 0x6b, 0x2a, 0x60, 0xd1, 0x6c, 0xb7, 0xf5, 0x44, 0x48, 0xba, 0x9f, 0x3f, 0x08,
+        0xbc, 0xd0, 0x99, 0xdb, 0x21, 0xdd, 0x16, 0x2a, 0x77, 0x9e, 0x61, 0xaa, 0x89, 0xee, 0xe5, 0x54, 0xd3, 0xa4,
+        0x7d, 0xe2, 0x30, 0xbc, 0x7a, 0xc5, 0x90, 0xd5, 0x24, 0x06, 0x7c, 0x38, 0x98, 0xbb, 0xa6, 0xf5, 0xdc, 0x43,
+        0x60, 0xb8, 0x45, 0xed, 0xa4, 0x8c, 0xbd, 0x9c, 0xf1, 0x26, 0xa7, 0x23, 0x44, 0x5f, 0x0e, 0x19, 0x52, 0xd7,
+        0x32, 0x5a, 0x75, 0xfa, 0xf5, 0x56, 0x14, 0x4f, 0x9a, 0x98, 0xaf, 0x71, 0x86, 0xb0, 0x27, 0x86, 0x85, 0xb8,
+        0xe2, 0xc0, 0x8b, 0xea, 0x87, 0x17, 0x1b, 0x4d, 0xee, 0x58, 0x5c, 0x18, 0x28, 0x29, 0x5b, 0x53, 0x95, 0xeb,
+        0x4a, 0x17, 0x77, 0x9f, 0x02, 0x03, 0x01, 0x00, 0x01, 
+      0x00, 
+    0x00, 
+  0x00, 
+  0x01, 0x9a, // Content
+    0xc5, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x21, 
+  0x00, 
+0x00,
+1
+};
+
+/*
+ * 
+ */
+int main(int argc, char** argv)
+{
+  try {
+    ContentObject contentObject;
+    contentObject.decode(ContentObject1, sizeof(ContentObject1));
+    cout << "Interest name " << contentObject.getName().to_uri() << endl;
+    
+    vector<unsigned char> encoding;
+    contentObject.encode(encoding);
+    cout << "ContentObject encoding length " << encoding.size() << " vs. sizeof(ContentObject1) " << sizeof(ContentObject1) << endl;
+    
+    ContentObject reDecodedContentObject;
+    reDecodedContentObject.decode(encoding);
+    cout << "Re-decoded Interest name " << reDecodedContentObject.getName().to_uri() << endl;
+  } catch (exception &e) {
+    cout << "exception: " << e.what() << endl;
+  }
+  return 0;
+}