diff --git a/include/ndn-cpp/data.hpp b/include/ndn-cpp/data.hpp
index a227c7f..1fb098f 100644
--- a/include/ndn-cpp/data.hpp
+++ b/include/ndn-cpp/data.hpp
@@ -10,51 +10,94 @@
 
 #include "common.hpp"
 #include "name.hpp"
-#include "util/signed-blob.hpp"
-#include "c/data-types.h"
-#include "encoding/wire-format.hpp"
+#include "encoding/block.hpp"
 
-struct ndn_MetaInfo;
-struct ndn_Signature;
-struct ndn_Data;
 
 namespace ndn {
 
 /**
- * A Signature is an abstract base class providing methods to work with the signature information in a Data packet.
- * You must create an object of a subclass, for example Sha256WithRsaSignature.
+ * A Signature is storage for the signature-related information (info and value) in a Data packet.
  */
 class Signature {
 public:
-  /**
-   * Return a pointer to a new Signature which is a copy of this signature.
-   * This is pure virtual, the subclass must implement it.
-   */
-  virtual ptr_lib::shared_ptr<Signature> 
-  clone() const = 0;
+  enum {
+    DigestSha256 = 0,
+    SignatureSha256WithRsa = 1
+  };
   
-  /**
-   * The virtual destructor.
-   */
-  virtual 
-  ~Signature();
+  Signature()
+    : type_(-1)
+  {
+  }
   
-    /**
-   * 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.
-   * This is pure virtual, the subclass must implement it.
-   * @param signatureStruct a C ndn_Signature struct where the name components array is already allocated.
-   */
-  virtual void 
-  get(struct ndn_Signature& signatureStruct) const = 0;
+  Signature(const Block &info, const Block &value)
+    : info_(info)
+    , value_(value)
+  {
+    Buffer::const_iterator i = info_.value_begin();
+    type_ = Tlv::readVarNumber(i, info_.value_end());
+  }
 
-  /**
-   * Clear this signature, and set the values by copying from the ndn_Signature struct.
-   * This is pure virtual, the subclass must implement it.
-   * @param signatureStruct a C ndn_Signature struct
-   */
-  virtual void 
-  set(const struct ndn_Signature& signatureStruct) = 0;
+  operator bool() const
+  {
+    return type_ != -1;
+  }
+
+  uint32_t
+  getType() const
+  {
+    return type_;
+  }
+  
+  const Block&
+  getInfo() const
+  {
+    return info_;
+  }
+
+  void
+  setInfo(const Block &info)
+  {
+    info_ = info;
+    if (info_.hasWire() || info_.hasValue())
+      {
+        info_.parse();
+        const Block &signatureType = info_.get(Tlv::SignatureType);
+        
+        Buffer::const_iterator i = signatureType.value_begin();
+        type_ = Tlv::readVarNumber(i, signatureType.value_end());
+      }
+    else
+      {
+        type_ = -1;
+      }
+  }  
+
+  const Block&
+  getValue() const
+  {
+    return value_;
+  }
+
+  void
+  setValue(const Block &value)
+  {
+    value_ = value;
+  }
+
+  void
+  reset()
+  {
+    type_ = -1;
+    info_.reset();
+    value_.reset();
+  }
+
+private:
+  int32_t type_;
+  
+  Block info_;
+  Block value_;
 };
 
 /**
@@ -62,56 +105,39 @@
  */
 class MetaInfo {
 public:
-  MetaInfo() 
+  enum {
+    TYPE_DEFAULT = 0,
+    TYPE_LINK = 1,
+    TYPE_KEY = 2
+  };
+  
+  MetaInfo()
+    : type_(TYPE_DEFAULT)
+    , freshnessPeriod_(-1)
   {   
-    type_ = ndn_ContentType_DATA;
-    freshnessSeconds_ = -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; }
 
-  /**
-   * Set the metaInfoStruct to point to the values in this meta info object, without copying any memory.
-   * WARNING: The resulting pointers in metaInfoStruct are invalid after a further use of this object which could reallocate memory.
-   * @param metaInfoStruct a C ndn_MetaInfo struct where the name components array is already allocated.
-   */
-  void 
-  get(struct ndn_MetaInfo& metaInfoStruct) const;
-
-  /**
-   * Clear this meta info, and set the values by copying from the ndn_MetaInfo struct.
-   * @param metaInfoStruct a C ndn_MetaInfo struct
-   */
-  void 
-  set(const struct ndn_MetaInfo& metaInfoStruct);
-
-  MillisecondsSince1970 
-  getTimestampMilliseconds() const { return timestampMilliseconds_; }
-  
-  ndn_ContentType 
-  getType() const { return type_; }
-  
-  int 
-  getFreshnessSeconds() const { return freshnessSeconds_; }
-  
-  const Name::Component& 
-  getFinalBlockID() const { return finalBlockID_; }
-  
-  void 
-  setTimestampMilliseconds(MillisecondsSince1970 timestampMilliseconds) { timestampMilliseconds_ = timestampMilliseconds; }
-  
-  void 
-  setType(ndn_ContentType type) { type_ = type; }
-  
-  void 
-  setFreshnessSeconds(int freshnessSeconds) { freshnessSeconds_ = freshnessSeconds; }
-
-  void 
-  setFinalBlockID(const Name::Component& finalBlockID) { finalBlockID_ = finalBlockID; }
-    
 private:
-  MillisecondsSince1970 timestampMilliseconds_; /**< milliseconds since 1/1/1970. -1 for none */
-  ndn_ContentType type_;         /**< default is ndn_ContentType_DATA. -1 for none */
-  int freshnessSeconds_;         /**< -1 for none */
-  Name::Component finalBlockID_; /** size 0 for none */
+  uint32_t type_;
+  Milliseconds freshnessPeriod_;
+
+  Block wire_;
 };
   
 class Data {
@@ -119,31 +145,25 @@
   /**
    * Create a new Data object with default values and where the signature is a blank Sha256WithRsaSignature.
    */
-  Data();
+  Data()
+  {
+  }
 
   /**
    * Create a new Data object with the given name and default values and where the signature is a blank Sha256WithRsaSignature.
    * @param name A reference to the name which is copied.
    */
-  Data(const Name& name);
-  
-  /**
-   * The copy constructor: Create a deep copy of the given data object, including a clone of the signature object.
-   * @param data The data object to copy.
-   */
-  Data(const Data& data);
+  Data(const Name& name)
+    : name_(name)
+  {
+  }
   
   /**
    * The virtual destructor.
    */
-  virtual ~Data();
-  
-  /**
-   * The assignment operator: Copy fields and make a clone of the signature.
-   * @param data The other object to copy from.
-   * @return A reference to this object.
-   */
-  Data& operator=(const Data& data);
+  virtual ~Data()
+  {
+  }
   
   /**
    * Encode this Data for a particular wire format. If wireFormat is the default wire format, also set the defaultWireEncoding 
@@ -152,8 +172,11 @@
    * @param wireFormat A WireFormat object used to encode the input. If omitted, use WireFormat getDefaultWireFormat().
    * @return The encoded byte array.
    */
-  SignedBlob 
-  wireEncode(WireFormat& wireFormat = *WireFormat::getDefaultWireFormat()) const;
+  const Block& 
+  wireEncode() const;
+  
+  void
+  wireDecode(const Block &wire);
   
   /**
    * Decode the input using a particular wire format and update this Data. If wireFormat is the default wire format, also 
@@ -162,155 +185,127 @@
    * @param inputLength The length of input.
    * @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());
-  
-  /**
-   * Decode the input using a particular wire format and update this Data. If wireFormat is the default wire format, also 
-   * set the defaultWireEncoding field to the input.
-   * @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()) 
+  void
+  wireDecode(const uint8_t* input, size_t inputLength);
+
+  const Signature&
+  getSignature() const
   {
-    wireDecode(&input[0], input.size(), wireFormat);
+    return signature_;
   }
   
   /**
-   * Set the dataStruct to point to the values in this interest, without copying any memory.
-   * WARNING: The resulting pointers in dataStruct are invalid after a further use of this object which could reallocate memory.
-   * @param dataStruct a C ndn_Data struct where the name components array is already allocated.
-   */
-  void 
-  get(struct ndn_Data& dataStruct) const;
-
-  /**
-   * Clear this data object, and set the values by copying from the ndn_Data struct.
-   * @param dataStruct a C ndn_Data struct
-   */
-  void 
-  set(const struct ndn_Data& dataStruct);
-
-  const Signature* 
-  getSignature() const { return signature_.get(); }
-  
-  Signature* 
-  getSignature() 
-  { 
-    // TODO: Should add an OnChanged listener instead of always calling onChanged.
-    onChanged();
-    return signature_.get(); 
-  }
-  
-  const Name& 
-  getName() const { return name_; }
-  
-  Name& 
-  getName() 
-  { 
-    // TODO: Should add an OnChanged listener instead of always calling onChanged.
-    onChanged();
-    return name_; 
-  }
-  
-  const MetaInfo& 
-  getMetaInfo() const { return metaInfo_; }
-  
-  MetaInfo& 
-  getMetaInfo() 
-  { 
-    // TODO: Should add an OnChanged listener instead of always calling onChanged.
-    onChanged();
-    return metaInfo_; 
-  }
-  
-  const Blob& 
-  getContent() const { return content_; }
-
-  /**
-   * Return a pointer to the defaultWireEncoding.  It may be null.
-   */
-  const SignedBlob&
-  getDefaultWireEncoding() const { return defaultWireEncoding_; }
-  
-  /**
    * Set the signature to a copy of the given signature.
    * @param signature The signature object which is cloned.
    * @return This Data so that you can chain calls to update values.
    */
   Data& 
   setSignature(const Signature& signature) 
-  { 
-    signature_ = signature.clone(); 
+  {
+    signature_ = signature;
     onChanged();
     return *this;
   }
   
+  const Name& 
+  getName() const
+  {
+    return name_;
+  }
+  
   /**
    * Set name to a copy of the given Name.  This is virtual so that a subclass can override to validate the name.
    * @param name The Name which is copied.
    * @return This Data so that you can chain calls to update values.
    */
-  virtual Data& 
-  setName(const Name& name);
+  void
+  setName(const Name& name)
+  { 
+    name_ = name; 
+    onChanged();
+  }
+  
+  const MetaInfo& 
+  getMetaInfo() const { return metaInfo_; }
   
   /**
    * 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.
    */
-  Data& 
+  void
   setMetaInfo(const MetaInfo& metaInfo) 
   { 
     metaInfo_ = metaInfo; 
     onChanged();
-    return *this;
   }
 
+  const Block& 
+  getContent() const { return content_; }
+
   /**
    * 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.
    */
-  Data& 
+  void
   setContent(const std::vector<uint8_t>& content) 
-  { 
-    content_ = content; 
+  {
+    setContent(&content[0], content.size());
     onChanged();
-    return *this;
   }
   
-  Data& 
+  void
   setContent(const uint8_t* content, size_t contentLength) 
-  { 
-    content_ = Blob(content, contentLength); 
+  {
+    OBufferStream os;
+    Tlv::writeVarNumber(os, Tlv::Content);
+    Tlv::writeVarNumber(os, contentLength);
+    os.write(reinterpret_cast<const char *>(content), contentLength);
+    
+    content_ = Block(os.buf());
     onChanged();
-    return *this;
   }
-      
-  Data& 
-  setContent(const Blob& content) 
+
+  void
+  setContent(const ConstBufferPtr &contentValue)
+  {
+    content_ = Block(Tlv::Content, contentValue); // not real a wire encoding yet
+    onChanged();
+  }
+  
+  void
+  setContent(const Block& content) 
   { 
     content_ = content;
     onChanged();
-    return *this;
   }
 
 private:
   /**
    * Clear the wire encoding.
    */
-  void 
+  inline void 
   onChanged();
-  
-  ptr_lib::shared_ptr<Signature> signature_;
+
+private:
   Name name_;
   MetaInfo metaInfo_;
-  Blob content_;
-  SignedBlob defaultWireEncoding_;
+  Block content_;
+  Signature signature_;
+
+  Block wire_;
 };
-  
+
+
+inline void 
+Data::onChanged()
+{
+  // The values have changed, so the signature and wire format is invalidated
+  signature_.reset();
+  wire_.reset();
 }
 
+} // namespace ndn
+
 #endif
