Debugging and resolving problems with interest serialization/deserialization
diff --git a/bindings/modulegen__gcc_ILP32.py b/bindings/modulegen__gcc_ILP32.py
index 2a28ac4..40dc854 100644
--- a/bindings/modulegen__gcc_ILP32.py
+++ b/bindings/modulegen__gcc_ILP32.py
@@ -1571,6 +1571,16 @@
     cls.add_constructor([])
     ## ccnx-encoding-helper.h (module 'NDNabstraction'): ns3::CcnxEncodingHelper::CcnxEncodingHelper(ns3::CcnxEncodingHelper const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::CcnxEncodingHelper const &', 'arg0')])
+    ## ccnx-encoding-helper.h (module 'NDNabstraction'): static size_t ns3::CcnxEncodingHelper::GetSerializedSize(ns3::CcnxInterestHeader const & interest) [member function]
+    cls.add_method('GetSerializedSize', 
+                   'size_t', 
+                   [param('ns3::CcnxInterestHeader const &', 'interest')], 
+                   is_static=True)
+    ## ccnx-encoding-helper.h (module 'NDNabstraction'): static size_t ns3::CcnxEncodingHelper::GetSerializedSize(ns3::CcnxContentObjectHeader const & contentObject) [member function]
+    cls.add_method('GetSerializedSize', 
+                   'size_t', 
+                   [param('ns3::CcnxContentObjectHeader const &', 'contentObject')], 
+                   is_static=True)
     ## ccnx-encoding-helper.h (module 'NDNabstraction'): static size_t ns3::CcnxEncodingHelper::Serialize(ns3::Buffer::Iterator start, ns3::CcnxInterestHeader const & interest) [member function]
     cls.add_method('Serialize', 
                    'size_t', 
@@ -7852,7 +7862,9 @@
                    [param('ns3::CcnbParser::Visitor &', 'v'), param('boost::any', 'param')], 
                    is_virtual=True)
     ## ccnb-parser-blob.h (module 'NDNabstraction'): ns3::CcnbParser::Blob::m_blob [variable]
-    cls.add_instance_attribute('m_blob', 'ns3::Buffer', is_const=False)
+    cls.add_instance_attribute('m_blob', 'char *', is_const=False)
+    ## ccnb-parser-blob.h (module 'NDNabstraction'): ns3::CcnbParser::Blob::m_blobSize [variable]
+    cls.add_instance_attribute('m_blobSize', 'uint32_t', is_const=False)
     return
 
 def register_Ns3CcnbParserDattr_methods(root_module, cls):
diff --git a/examples/interest-header-example.cc b/examples/interest-header-example.cc
index 8a4a57a..83895ad 100644
--- a/examples/interest-header-example.cc
+++ b/examples/interest-header-example.cc
@@ -12,46 +12,68 @@
 #include "ns3/log.h"
 
 using namespace ns3;
+#include <fstream>
 
 NS_LOG_COMPONENT_DEFINE ("InterestHeaderExample");
 
 int
 main (int argc, char *argv[])
 {
+	LogComponentEnable ("InterestHeaderExample", LOG_ALL);
+	
     NS_LOG_INFO ("Test started");
-    uint32_t randomNonce = UniformVariable().GetInteger(1, std::numeric_limits<uint32_t>::max ());
-    Ptr<CcnxNameComponents> testname = Create<CcnxNameComponents> ();
-    (*testname) ("test") ("test2");
-    
-    Ptr<CcnxNameComponents> exclude = Create<CcnxNameComponents> ();
-    (*testname) ("exclude") ("exclude2");
-    
-    Time lifetime = Seconds(4.0);
-    bool child = true;
-    
-    uint32_t maxSuffixComponents = 40;
-    uint32_t minSuffixComponents = 20;
-    
+
     CcnxInterestHeader interestHeader;
-    interestHeader.SetNonce(randomNonce);
+	
+    Ptr<CcnxNameComponents> testname = Create<CcnxNameComponents> ();
+    (*testname) ("first") ("second");
     interestHeader.SetName(testname);
-    interestHeader.SetInterestLifetime(lifetime);
-    interestHeader.SetChildSelector(child);
-    interestHeader.SetExclude(exclude);
-    interestHeader.SetMaxSuffixComponents(maxSuffixComponents);
+	
+    uint32_t minSuffixComponents = 20;
     interestHeader.SetMinSuffixComponents(minSuffixComponents);
+	
+    uint32_t maxSuffixComponents = 40;
+    interestHeader.SetMaxSuffixComponents(maxSuffixComponents);
+	
+    Time lifetime = Seconds(661777) + MicroSeconds(1234);
+    interestHeader.SetInterestLifetime(lifetime);
+
+    bool child = true;
+    interestHeader.SetChildSelector(child);
+
+    Ptr<CcnxNameComponents> exclude = Create<CcnxNameComponents> ();
+    (*exclude) ("exclude1") ("exclude2");
+    interestHeader.SetExclude(exclude);
+
+	UniformVariable random(1, std::numeric_limits<uint32_t>::max ());
+    uint32_t randomNonce = static_cast<uint32_t> (random.GetValue());
+    interestHeader.SetNonce(randomNonce);
+	NS_LOG_INFO ("Source: \n" <<interestHeader);
     
     uint32_t size = interestHeader.GetSerializedSize();
-    NS_LOG_INFO ("Size = " << size);
+    NS_LOG_INFO ("GetSerializedSize = " << size);
     //uint32_t size = 5;
     //NS_TEST_ASSERT_MSG_EQ (false, true, "GetSize = " << size);
     
-    Buffer buf(size);
+    Buffer buf;
+	buf.AddAtStart (size);
     Buffer::Iterator iter = buf.Begin ();
     //interestHeader.
-    //interestHeader.Serialize(iter);
-    
+    interestHeader.Serialize(iter);
+
+	std::ofstream of( "/tmp/file" );
+	of.write (reinterpret_cast<const char*> (buf.PeekData ()), size);
+	of.close ();
+
+	NS_LOG_INFO ("start = " << buf.GetCurrentStartOffset () << " " <<
+				 "end = " << buf.GetCurrentEndOffset ());	
+	
     iter = buf.Begin ();
     CcnxInterestHeader target;
-    
-}
\ No newline at end of file
+	NS_LOG_INFO ("Trying to deserialize");
+	std::cout << "\n";
+	size = target.Deserialize (iter);
+	buf.RemoveAtEnd (size);
+	NS_LOG_INFO ("Deserialized size = " << size);
+	NS_LOG_INFO ("Target: \n" << target);
+}
diff --git a/helper/ccnb-parser/ccnx-decoding-helper.h b/helper/ccnb-parser/ccnx-decoding-helper.h
deleted file mode 100644
index 375a57a..0000000
--- a/helper/ccnb-parser/ccnx-decoding-helper.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#ifndef _CCNX_DECODING_HELPER_H_
-#define _CCNX_DECODING_HELPER_H_
-
-namespace ns3 {
-
-class CcnxInterestHeader;
-class CcnxContentObjectHeader;
-
-/**
- * \brief Helper class to decode ccnb formatted CCNx message
- */
-class CcnxDecodingHelper
-{
-public:
-  static size_t
-  Deserialize (Buffer::Iterator start, const CcnxInterestHeader &interest);
-
-  static size_t
-  Deserialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject);
-  
-private:
-};
-
-} // namespace ns3
-
-#endif // _CCNX_DECODING_HELPER_H_
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-attr.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-attr.cc
index 397e940..e4baf54 100644
--- a/helper/ccnb-parser/syntax-tree/ccnb-parser-attr.cc
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-attr.cc
@@ -28,10 +28,13 @@
 Attr::Attr (Buffer::Iterator &start, uint32_t length)
 {
   m_attr.reserve (length+2); // extra byte for potential \0 at the end
-  for (uint32_t i = 0; i < (length+1); i++)
+  uint32_t i = 0;
+  for (; !start.IsEnd () && i < (length+1); i++)
     {
       m_attr.push_back (start.ReadU8 ());
     }
+  if (i < (length+1) && start.IsEnd ())
+    throw CcnbDecodingException ();
   m_value = DynamicCast<Udata> (Block::ParseBlock (start));
   if (m_value == 0)
     throw CcnbDecodingException (); // "ATTR must be followed by UDATA field"
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.cc
index 4467891..a0a112c 100644
--- a/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.cc
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.cc
@@ -18,15 +18,30 @@
  * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
 
-#include "ccnb-parser-blob.h"
+#include "ns3/ccnb-parser-blob.h"
 
 namespace ns3 {
 namespace CcnbParser {
 
 Blob::Blob (Buffer::Iterator &start, uint32_t length)
 {
-  m_blob = Buffer (length);
-  start.Read (m_blob.Begin (), length);
+  m_blobSize = length;
+  m_blob = new char[length];
+  if (m_blob == 0 )
+    throw CcnbDecodingException (); // memory problem
+
+  uint32_t i = 0;
+  for (; !start.IsEnd () && i < length; i++)
+    {
+      m_blob[i] = start.ReadU8 ();
+    }
+  if (i < length && start.IsEnd ())
+    throw CcnbDecodingException ();
+}
+
+Blob::~Blob ()
+{
+  delete [] m_blob;
 }
 
 }
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.h
index 4b22d62..f2ede3d 100644
--- a/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.h
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.h
@@ -22,7 +22,6 @@
 #define _CCNB_PARSER_BLOB_H_
 
 #include "ccnb-parser-block.h"
-#include "ns3/buffer.h"
 
 namespace ns3 {
 namespace CcnbParser {
@@ -45,13 +44,15 @@
    * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
    */
   Blob (Buffer::Iterator &start, uint32_t length);
+  ~Blob ();
   
   virtual void accept( VoidNoArguVisitor &v )               { v.visit( *this ); }
   virtual void accept( VoidVisitor &v, boost::any param )   { v.visit( *this, param ); }
   virtual boost::any accept( NoArguVisitor &v )             { return v.visit( *this ); }
   virtual boost::any accept( Visitor &v, boost::any param ) { return v.visit( *this, param ); }
 
-  Buffer m_blob; ///< \brief field holding a parsed BLOB value of the block
+  char* m_blob; ///< \brief field holding a parsed BLOB value of the block
+  uint32_t  m_blobSize;
 };
 
 }
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-block.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-block.cc
index e1e09fd..2af8aef 100644
--- a/helper/ccnb-parser/syntax-tree/ccnb-parser-block.cc
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-block.cc
@@ -42,31 +42,38 @@
 
   // We will have problems if length field is more than 32 bits. Though it's really impossible
   uint8_t byte = 0;
-  while (!(byte & CCN_TT_HBIT))
+  while (!start.IsEnd() && !(byte & CCN_TT_HBIT))
     {
       value <<= 8;
       value += byte;
       byte = start.ReadU8 ();
     }
+  if (start.IsEnd())
+    CcnbDecodingException ();
+  
   value <<= 4;
   value += ( (byte&(~CCN_TT_HBIT)) >> 3);
 
+  /**
+   * Huh. After fighting with NS-3, it became apparent that Create<T>(...) construct
+   * doesn't work with references.  Just simply doesn't work.  wtf?
+   */
   switch (byte & CCN_TT_MASK)
     {
     case CCN_BLOB:
-      return Create<Blob> (start, value);
+      return Ptr<Blob> (new Blob(start, value));
     case CCN_UDATA:
-      return Create<Udata> (start, value);
+      return Ptr<Udata> (new Udata(start, value));
     case CCN_TAG:
-      return Create<Tag> (start, value);
+      return Ptr<Tag> (new Tag(start, value));
     case CCN_ATTR:
-      return Create<Attr> (start, value);
+      return Ptr<Attr> (new Attr(start, value));
     case CCN_DTAG:
-      return Create<Dtag> (start, value);
+      return Ptr<Dtag> (new Dtag(start, value));
     case CCN_DATTR:
-      return Create<Dattr> (start, value);
+      return Ptr<Dattr> (new Dattr(start, value));
     case CCN_EXT:
-      return Create<Ext> (start, value);
+      return Ptr<Ext> (new Ext(start, value));
     default:
       throw CcnbDecodingException ();
     }
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-dtag.cc.~HEAD~ b/helper/ccnb-parser/syntax-tree/ccnb-parser-dtag.cc.~HEAD~
new file mode 100644
index 0000000..8d9ecf7
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-dtag.cc.~HEAD~
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2011 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "ccnb-parser-dtag.h"
+
+#include "ccnb-parser-base-attr.h"
+#include "ccnb-parser-base-tag.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+Dtag::Dtag (Buffer::Iterator &start, uint32_t dtag)
+{
+  m_dtag = dtag;
+
+  /**
+   * Hack
+   *
+   * Stop processing after encountering <Content> dtag.  Actual
+   * content (including virtual payload) will be stored in Packet
+   * buffer
+   */
+  if (dtag == CCN_DTAG_Content)
+    return; // hack #1. Do not process nesting block for <Content>
+  
+  // parse attributes until first nested block reached
+  while (!start.IsEnd () && start.PeekU8 ()!=CCN_CLOSE)
+    {
+      Ptr<Block> block = Block::ParseBlock (start);
+      if (DynamicCast<BaseAttr> (block)!=0)
+		m_attrs.push_back (block);
+	  else
+		{
+		  m_nestedTags.push_back (block);
+		  break;
+		}
+	}
+
+  // parse the rest of nested blocks
+  while (!start.IsEnd () && start.PeekU8 ()!=CCN_CLOSE)
+    {
+      // hack #2. Stop processing nested blocks if last block was <Content>
+      if (m_dtag == CCN_DTAG_ContentObject && // we are in <ContentObject>
+          DynamicCast<Dtag> (m_nestedTags.back())!=0 && // last block is DTAG
+          DynamicCast<Dtag> (m_nestedTags.back())->m_dtag == CCN_DTAG_Content) 
+        {
+          return; 
+        }
+
+      m_nestedTags.push_back (Block::ParseBlock (start));
+    }
+  if (start.IsEnd ())
+      throw CcnbDecodingException ();
+
+  start.ReadU8 (); // read CCN_CLOSE
+}
+
+}
+}
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-tag.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-tag.cc
index c288be9..5862ad4 100644
--- a/helper/ccnb-parser/syntax-tree/ccnb-parser-tag.cc
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-tag.cc
@@ -28,10 +28,13 @@
 Tag::Tag (Buffer::Iterator &start, uint32_t length)
 {
   m_tag.reserve (length+2); // extra byte for potential \0 at the end
-  for (uint32_t i = 0; i < (length+1); i++)
+  uint32_t i = 0;
+  for (; !start.IsEnd () && i < (length+1); i++)
     {
       m_tag.push_back (start.ReadU8 ());
     }
+  if (i < (length+1) && start.IsEnd ())
+    throw CcnbDecodingException ();
   
   // parse attributes until first nested block reached
   while (!start.IsEnd () && start.PeekU8 ()!=CCN_CLOSE)
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-udata.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-udata.cc
index 39217fd..91cba15 100644
--- a/helper/ccnb-parser/syntax-tree/ccnb-parser-udata.cc
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-udata.cc
@@ -32,10 +32,14 @@
 
   m_udata.reserve (length+1); //just in case we will need \0 at the end later
   // this is actually the way Read method is implemented in network/src/buffer.cc
-  for (uint32_t i = 0; i < length; i++)
+  uint32_t i = 0;
+  for (; !start.IsEnd () && i < length; i++)
     {
       m_udata.push_back (start.ReadU8 ());
     }
+
+  if (i < length && start.IsEnd ())
+    throw CcnbDecodingException ();
 }
 
 }
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.cc
index 8548598..d562695 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.cc
@@ -35,13 +35,13 @@
 
 // We don't really care about any other fields
 void
-ContentObjectVisitor::visit (Dtag &n, boost::any param/*should be CcnxContentObjectHeader&*/)
+ContentObjectVisitor::visit (Dtag &n, boost::any param/*should be CcnxContentObjectHeader* */)
 {
   // uint32_t n.m_dtag;
   // std::list<Ptr<Block> > n.m_nestedBlocks;
   static NameComponentsVisitor nameComponentsVisitor;
   
-  CcnxContentObjectHeader &contentObject = boost::any_cast<CcnxContentObjectHeader&> (param);
+  CcnxContentObjectHeader &contentObject = *(boost::any_cast<CcnxContentObjectHeader*> (param));
   
   switch (n.m_dtag)
     {
@@ -59,7 +59,7 @@
         
         BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
           {
-            block->accept (nameComponentsVisitor, *name);
+            block->accept (nameComponentsVisitor, &(*name));
           }
         contentObject.SetName (name);
         break;
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.h
index e15e290..ae6fe9b 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.h
+++ b/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.h
@@ -41,7 +41,7 @@
 class ContentObjectVisitor : public VoidDepthFirstVisitor
 {
 public:
-  virtual void visit (Dtag &n, boost::any param/*should be CcnxContentObjectHeader&*/);
+  virtual void visit (Dtag &n, boost::any param/*should be CcnxContentObjectHeader* */);
 };
 
 }
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
index 052cb8c..0bd0e46 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
@@ -39,7 +39,7 @@
 
 // We don't care about any other fields
 void
-InterestVisitor::visit (Dtag &n, boost::any param/*should be CcnxInterestHeader&*/)
+InterestVisitor::visit (Dtag &n, boost::any param/*should be CcnxInterestHeader* */)
 {
   // uint32_t n.m_dtag;
   // std::list<Ptr<Block> > n.m_nestedBlocks;
@@ -49,7 +49,7 @@
   static TimestampVisitor          timestampVisitor;
   static NonceVisitor              nonceVisitor;
   
-  CcnxInterestHeader &interest = boost::any_cast<CcnxInterestHeader&> (param);
+  CcnxInterestHeader &interest = *(boost::any_cast<CcnxInterestHeader*> (param));
   
   switch (n.m_dtag)
     {
@@ -67,7 +67,7 @@
         
         BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
           {
-            block->accept (nameComponentsVisitor, *name);
+            block->accept (nameComponentsVisitor, &(*name));
           }
         interest.SetName (name);
         break;
@@ -97,7 +97,7 @@
         
         BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
           {
-            block->accept (nameComponentsVisitor, *exclude);
+            block->accept (nameComponentsVisitor, &(*exclude));
           }
         interest.SetExclude (exclude);
         break;
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.h
index 136b173..35a1e13 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.h
+++ b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.h
@@ -41,7 +41,7 @@
 class InterestVisitor : public VoidDepthFirstVisitor
 {
 public:
-  virtual void visit (Dtag &n, boost::any param/*should be CcnxInterestHeader&*/);
+  virtual void visit (Dtag &n, boost::any param/*should be CcnxInterestHeader* */);
 };
 
 }
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.cc
index 08bfe2e..314cb68 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.cc
@@ -28,13 +28,13 @@
 namespace CcnbParser {
 
 void
-NameComponentsVisitor::visit (Dtag &n, boost::any param/*should be CcnxNameComponents&*/)
+NameComponentsVisitor::visit (Dtag &n, boost::any param/*should be CcnxNameComponents* */)
 {
   // uint32_t n.m_dtag;
   // std::list<Ptr<Block> > n.m_nestedBlocks;
   static StringVisitor stringVisitor; 
  
-  CcnxNameComponents &components = boost::any_cast<CcnxNameComponents&> (param);
+  CcnxNameComponents &components = *(boost::any_cast<CcnxNameComponents*> (param));
 
   switch (n.m_dtag)
     {
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.h
index e4b92cf..70257c5 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.h
+++ b/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.h
@@ -33,7 +33,7 @@
 class NameComponentsVisitor : public VoidDepthFirstVisitor
 {
 public:
-  virtual void visit (Dtag &n, boost::any param/*should be CcnxNameComponents&*/);
+  virtual void visit (Dtag &n, boost::any param/*should be CcnxNameComponents* */);
 };
 
 }
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-nonce-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-nonce-visitor.cc
index 7492adf..931f2fa 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-nonce-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-nonce-visitor.cc
@@ -28,10 +28,10 @@
 NonceVisitor::visit (Blob &n) 
 {
   // Buffer n.m_blob;
-  if (n.m_blob.GetSize ()<4)
+  if (n.m_blobSize < 4)
     throw CcnbDecodingException ();
      
-  return boost::any (n.m_blob.Begin ().ReadU32 ());
+  return boost::any (*(reinterpret_cast<uint32_t*> (n.m_blob)));
 }
 
 boost::any
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.cc
index 33c9465..dfc61ed 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.cc
@@ -20,6 +20,7 @@
 
 #include "ccnb-parser-string-visitor.h"
 #include "ns3/ccnb-parser-udata.h"
+#include "ns3/ccnb-parser-blob.h"
 
 namespace ns3 {
 namespace CcnbParser {
@@ -28,7 +29,7 @@
 StringVisitor::visit (Blob &n) 
 {
   // Buffer n.m_blob;
-  throw CcnbDecodingException ();
+  return std::string (n.m_blob, n.m_blobSize);
 }
 
 boost::any
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.h
index b2a2a29..2a1e8ed 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.h
+++ b/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.h
@@ -35,7 +35,7 @@
 class StringVisitor : public NoArguDepthFirstVisitor
 {
 public:
-  virtual boost::any visit (Blob &n); ///< Throws parsing error if BLOB object is encountered
+  virtual boost::any visit (Blob &n);
   virtual boost::any visit (Udata &n);
 };
 
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.cc
index 4724bb4..22965aa 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.cc
@@ -30,26 +30,27 @@
 TimestampVisitor::visit (Blob &n) 
 {
   // Buffer n.m_blob;
-  if (n.m_blob.GetSize ()<2)
+  if (n.m_blobSize < 2)
     throw CcnbDecodingException ();
 
-  Buffer::Iterator start = n.m_blob.Begin ();
+  const char *start = n.m_blob;
   
   intmax_t seconds = 0;
   intmax_t nanoseconds = 0;
 
-  for (uint32_t i=0; i < n.m_blob.GetSize ()-2; i++)
+  for (uint32_t i=0; i < n.m_blobSize-2; i++)
     {
-      seconds = (seconds << 8) | start.ReadU8 ();
+      seconds = (seconds << 8) | (uint8_t)start[i];
     }
-  uint8_t combo = start.ReadU8 (); // 4 most significant bits hold 4 least significant bits of number of seconds
-  seconds = (seconds << 8) | (combo >> 4);
+  uint8_t combo = start[n.m_blobSize-2]; // 4 most significant bits hold 4 least significant bits of number of seconds
+  seconds = (seconds << 4) | (combo >> 4);
+  std::cout << std::hex << (int) start[n.m_blobSize-2] << "\n";
 
   nanoseconds = combo & 0x0F; /*00001111*/ // 4 least significant bits hold 4 most significant bits of number of
-  nanoseconds = (nanoseconds << 8) | start.ReadU8 ();
-  nanoseconds = (intmax_t) ((nanoseconds / 4096.0/*2^12*/) * 1000000000 /*up-convert nanoseconds*/);
+  nanoseconds = (nanoseconds << 8) | start[n.m_blobSize-1];
+  nanoseconds = (intmax_t) ((nanoseconds / 4096.0/*2^12*/) * 1000000 /*up-convert useconds*/);
 
-  return boost::any (Time::FromInteger (seconds, Time::S) + Time::FromInteger (nanoseconds, Time::NS));
+  return boost::any (Time::FromInteger (seconds, Time::S) + Time::FromInteger (nanoseconds, Time::US));
 }
 
 boost::any
diff --git a/helper/ccnx-decoding-helper.cc b/helper/ccnx-decoding-helper.cc
index 1ebb0e8..cb38f98 100644
--- a/helper/ccnx-decoding-helper.cc
+++ b/helper/ccnx-decoding-helper.cc
@@ -30,25 +30,25 @@
 namespace ns3 {
 
 size_t
-CcnxDecodingHelper::Deserialize (Buffer::Iterator start, const CcnxInterestHeader &interest)
+CcnxDecodingHelper::Deserialize (Buffer::Iterator start, CcnxInterestHeader &interest)
 {
   static CcnbParser::InterestVisitor interestVisitor;
 
   Buffer::Iterator i = start;
   Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
-  root->accept (interestVisitor, interest);
+  root->accept (interestVisitor, &interest);
 
   return i.GetDistanceFrom (start);
 }
 
 size_t
-CcnxDecodingHelper::Deserialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject)
+CcnxDecodingHelper::Deserialize (Buffer::Iterator start, CcnxContentObjectHeader &contentObject)
 {
   static CcnbParser::ContentObjectVisitor contentObjectVisitor;
 
   Buffer::Iterator i = start;
   Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
-  root->accept (contentObjectVisitor, contentObject);
+  root->accept (contentObjectVisitor, &contentObject);
 
   return i.GetDistanceFrom (start);
 }
diff --git a/helper/ccnx-decoding-helper.h b/helper/ccnx-decoding-helper.h
index 2e41769..8ebfcc5 100644
--- a/helper/ccnx-decoding-helper.h
+++ b/helper/ccnx-decoding-helper.h
@@ -36,10 +36,10 @@
 {
 public:
   static size_t
-  Deserialize (Buffer::Iterator start, const CcnxInterestHeader &interest);
+  Deserialize (Buffer::Iterator start, CcnxInterestHeader &interest);
 
   static size_t
-  Deserialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject);
+  Deserialize (Buffer::Iterator start, CcnxContentObjectHeader &contentObject);
   
 private:
 };
diff --git a/helper/ccnx-encoding-helper.cc b/helper/ccnx-encoding-helper.cc
index 3dd7ad6..ded1627 100644
--- a/helper/ccnx-encoding-helper.cc
+++ b/helper/ccnx-encoding-helper.cc
@@ -29,107 +29,6 @@
 
 namespace ns3 {
 
-#define CCN_TT_BITS 3
-#define CCN_TT_MASK ((1 << CCN_TT_BITS) - 1)
-#define CCN_MAX_TINY ((1 << (7-CCN_TT_BITS)) - 1)
-#define CCN_TT_HBIT ((unsigned char)(1 << 7))
-
-size_t
-CcnxEncodingHelper::AppendBlockHeader (Buffer::Iterator start, size_t val, CcnbParser::ccn_tt tt)
-{
-  unsigned char buf[1+8*((sizeof(val)+6)/7)];
-  unsigned char *p = &(buf[sizeof(buf)-1]);
-  size_t n = 1;
-  p[0] = (CCN_TT_HBIT & ~CcnbParser::CCN_CLOSE) |
-  ((val & CCN_MAX_TINY) << CCN_TT_BITS) |
-  (CCN_TT_MASK & tt);
-  val >>= (7-CCN_TT_BITS);
-  while (val != 0) {
-    (--p)[0] = (((unsigned char)val) & ~CCN_TT_HBIT) | CcnbParser::CCN_CLOSE;
-    n++;
-    val >>= 7;
-  }
-  start.Write (p,n);
-  return n;
-}
-
-size_t
-CcnxEncodingHelper::AppendNumber (Buffer::Iterator start, uint32_t number)
-{
-  std::ostringstream os;
-  os << number;
-
-  size_t written = 0;
-  written += AppendBlockHeader (start, os.str().size(), CcnbParser::CCN_UDATA);
-  written += os.str().size();
-  start.Write (reinterpret_cast<const unsigned char*>(os.str().c_str()), os.str().size());
-
-  return written;
-}
-
-  
-size_t
-CcnxEncodingHelper::CcnxEncodingHelper::AppendCloser (Buffer::Iterator start)
-{
-  start.WriteU8 (CcnbParser::CCN_CLOSE);
-  return 1;
-}
-
-size_t
-CcnxEncodingHelper::AppendNameComponents (Buffer::Iterator start, const CcnxNameComponents &name)
-{
-  size_t written = 0;
-  BOOST_FOREACH (const std::string &component, name.GetComponents())
-    {
-      written += AppendTaggedBlob (start, CcnbParser::CCN_DTAG_Component,
-                                   reinterpret_cast<const uint8_t*>(component.c_str()), component.size());
-    }
-  return written;
-}
-
-size_t
-CcnxEncodingHelper::AppendTimestampBlob (Buffer::Iterator start, Time time)
-{
-  // the original function implements Markers... thought not sure what are these markers for...
-
-  // Determine miminal number of bytes required to store the timestamp
-  int required_bytes = 2; // 12 bits for fractions of a second, 4 bits left for seconds. Sometimes it is enough
-  intmax_t ts = time.ToInteger (Time::S) >> 4;
-  for (;  required_bytes < 7 && ts != 0; ts >>= 8) // not more than 6 bytes?
-     required_bytes++;
-  
-  size_t len = AppendBlockHeader(start, required_bytes, CcnbParser::CCN_BLOB);
-
-  // write part with seconds
-  ts = time.ToInteger (Time::S) >> 4;
-  for (int i = 0; i < required_bytes - 2; i++)
-    start.WriteU8 ( ts >> (8 * (required_bytes - 3 - i)) );
-
-  /* arithmetic contortions are to avoid overflowing 31 bits */
-  ts = ((time.ToInteger (Time::S) & 15) << 12) + ((time.ToInteger (Time::NS) / 5 * 8 + 195312) / 390625);
-  for (int i = required_bytes - 2; i < required_bytes; i++)
-    start.WriteU8 ( ts >> (8 * (required_bytes - 1 - i)) );
-  
-  return len + required_bytes;
-}
-
-size_t
-CcnxEncodingHelper::AppendTaggedBlob (Buffer::Iterator start, CcnbParser::ccn_dtag dtag,
-                  const uint8_t *data, size_t size)
-{
-  size_t written = AppendBlockHeader (start, dtag, CcnbParser::CCN_DTAG);
-  if (size>0)
-    {
-      written += AppendBlockHeader (start, size, CcnbParser::CCN_BLOB);
-      start.Write (data, size);
-      written += size;
-    }
-  written += AppendCloser (start);
-
-  return written;
-}
-
-
 size_t
 CcnxEncodingHelper::Serialize (Buffer::Iterator start, const CcnxInterestHeader &interest)
 {
@@ -152,7 +51,7 @@
       written += AppendNumber (start, interest.GetMaxSuffixComponents ());
       written += AppendCloser (start);
     }
-  if (interest.GetExclude().size() > 0)
+  if (interest.IsEnabledExclude() && interest.GetExclude().size() > 0)
     {
       written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_Exclude, CcnbParser::CCN_DTAG); // <Exclude>
       written += AppendNameComponents (start, interest.GetExclude());                // <Component>...</Component>...
@@ -195,6 +94,67 @@
 }
 
 size_t
+CcnxEncodingHelper::GetSerializedSize (const CcnxInterestHeader &interest)
+{
+  size_t written = 0;
+  written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Interest); // <Interest>
+  
+  written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Name); // <Name>
+  written += EstimateNameComponents (interest.GetName()); // <Component>...</Component>...
+  written += 1; // </Name>
+
+  if (interest.GetMinSuffixComponents() >= 0)
+    {
+      written += EstimateBlockHeader (CcnbParser::CCN_DTAG_MinSuffixComponents);
+      written += EstimateNumber (interest.GetMinSuffixComponents ());
+      written += 1;
+    }
+  if (interest.GetMaxSuffixComponents() >= 0)
+    {
+      written += EstimateBlockHeader (CcnbParser::CCN_DTAG_MaxSuffixComponents);
+      written += EstimateNumber (interest.GetMaxSuffixComponents ());
+      written += 1;
+    }
+  if (interest.IsEnabledExclude() && interest.GetExclude().size() > 0)
+    {
+      written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Exclude);
+      written += EstimateNameComponents (interest.GetExclude());                // <Component>...</Component>...
+      written += 1;                                  // </Exclude>
+    }
+  if (interest.IsEnabledChildSelector())
+    {
+      written += EstimateBlockHeader (CcnbParser::CCN_DTAG_ChildSelector);
+      written += EstimateNumber (1);
+      written += 1;
+    }
+  if (interest.IsEnabledAnswerOriginKind())
+    {
+      written += EstimateBlockHeader (CcnbParser::CCN_DTAG_AnswerOriginKind);
+      written += EstimateNumber (1);
+      written += 1;
+    }
+  if (interest.GetScope() >= 0)
+    {
+      written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Scope);
+      written += EstimateNumber (interest.GetScope ());
+      written += 1;
+    }
+  if (!interest.GetInterestLifetime().IsZero())
+    {
+      written += EstimateBlockHeader (CcnbParser::CCN_DTAG_InterestLifetime);
+      written += EstimateTimestampBlob (interest.GetInterestLifetime());
+      written += 1;
+    }
+  if (interest.GetNonce()>0)
+    {
+      written += EstimateTaggedBlob (CcnbParser::CCN_DTAG_Nonce, sizeof(uint32_t));
+    }
+  written += 1; // </Interest>
+
+  return written;
+}
+
+size_t
 CcnxEncodingHelper::Serialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject)
 {
   size_t written = 0;
@@ -229,4 +189,197 @@
   return written;
 }
 
+size_t
+CcnxEncodingHelper::GetSerializedSize (const CcnxContentObjectHeader &contentObject)
+{
+  size_t written = 0;
+  written += EstimateBlockHeader (CcnbParser::CCN_DTAG_ContentObject); // <ContentObject>
+
+  // fake signature
+  written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Signature); // <Signature>
+  // Signature ::= DigestAlgorithm? 
+  //               Witness?         
+  //               SignatureBits   
+  written += EstimateTaggedBlob (CcnbParser::CCN_DTAG_SignatureBits, 0);      // <SignatureBits />
+  written += 1;                                    // </Signature>  
+
+  written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Name);    // <Name>
+  written += EstimateNameComponents (contentObject.GetName()); //   <Component>...</Component>...
+  written += 1;                                  // </Name>  
+
+  // fake signature
+  written += EstimateBlockHeader (CcnbParser::CCN_DTAG_SignedInfo); // <SignedInfo>
+  // SignedInfo ::= PublisherPublicKeyDigest
+  //                Timestamp
+  //                Type?
+  //                FreshnessSeconds?
+  //                FinalBlockID?
+  //                KeyLocator?
+  written += EstimateTaggedBlob (CcnbParser::CCN_DTAG_PublisherPublicKeyDigest, 0); // <PublisherPublicKeyDigest />
+  written += 1;                                     // </SignedInfo>
+
+  written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Content); // <Content>
+
+  // there is no closing tag !!!
+  return written;
+}
+
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+
+#define CCN_TT_BITS 3
+#define CCN_TT_MASK ((1 << CCN_TT_BITS) - 1)
+#define CCN_MAX_TINY ((1 << (7-CCN_TT_BITS)) - 1)
+#define CCN_TT_HBIT ((unsigned char)(1 << 7))
+
+size_t
+CcnxEncodingHelper::AppendBlockHeader (Buffer::Iterator &start, size_t val, CcnbParser::ccn_tt tt)
+{
+  unsigned char buf[1+8*((sizeof(val)+6)/7)];
+  unsigned char *p = &(buf[sizeof(buf)-1]);
+  size_t n = 1;
+  p[0] = (CCN_TT_HBIT & ~CcnbParser::CCN_CLOSE) |
+  ((val & CCN_MAX_TINY) << CCN_TT_BITS) |
+  (CCN_TT_MASK & tt);
+  val >>= (7-CCN_TT_BITS);
+  while (val != 0) {
+    (--p)[0] = (((unsigned char)val) & ~CCN_TT_HBIT) | CcnbParser::CCN_CLOSE;
+    n++;
+    val >>= 7;
+  }
+  start.Write (p,n);
+  return n;
+}
+
+size_t
+CcnxEncodingHelper::EstimateBlockHeader (size_t value)
+{
+  value >>= (7-CCN_TT_BITS);
+  size_t n = 1;
+  while (value>0)
+    {
+      value >>= 7;
+      n++;
+    }
+  return n;
+}
+
+size_t
+CcnxEncodingHelper::AppendNumber (Buffer::Iterator &start, uint32_t number)
+{
+  std::ostringstream os;
+  os << number;
+
+  size_t written = 0;
+  written += AppendBlockHeader (start, os.str().size(), CcnbParser::CCN_UDATA);
+  written += os.str().size();
+  start.Write (reinterpret_cast<const unsigned char*>(os.str().c_str()), os.str().size());
+
+  return written;
+}
+
+size_t
+CcnxEncodingHelper::EstimateNumber (uint32_t number)
+{
+  std::ostringstream os;
+  os << number;
+  return EstimateBlockHeader (os.str ().size ()) + os.str ().size ();
+}
+  
+size_t
+CcnxEncodingHelper::AppendCloser (Buffer::Iterator &start)
+{
+  start.WriteU8 (CcnbParser::CCN_CLOSE);
+  return 1;
+}
+
+size_t
+CcnxEncodingHelper::AppendNameComponents (Buffer::Iterator &start, const CcnxNameComponents &name)
+{
+  size_t written = 0;
+  BOOST_FOREACH (const std::string &component, name.GetComponents())
+    {
+      written += AppendTaggedBlob (start, CcnbParser::CCN_DTAG_Component,
+                                   reinterpret_cast<const uint8_t*>(component.c_str()), component.size());
+    }
+  return written;
+}
+
+size_t
+CcnxEncodingHelper::EstimateNameComponents (const CcnxNameComponents &name)
+{
+  size_t written = 0;
+  BOOST_FOREACH (const std::string &component, name.GetComponents())
+    {
+      written += EstimateTaggedBlob (CcnbParser::CCN_DTAG_Component, component.size());
+    }
+  return written;
+}
+
+size_t
+CcnxEncodingHelper::AppendTimestampBlob (Buffer::Iterator &start, const Time &time)
+{
+  // the original function implements Markers... thought not sure what are these markers for...
+
+  // Determine miminal number of bytes required to store the timestamp
+  int required_bytes = 2; // 12 bits for fractions of a second, 4 bits left for seconds. Sometimes it is enough
+  intmax_t ts = time.ToInteger (Time::S) >> 4;
+  for (;  required_bytes < 7 && ts != 0; ts >>= 8) // not more than 6 bytes?
+     required_bytes++;
+  
+  size_t len = AppendBlockHeader(start, required_bytes, CcnbParser::CCN_BLOB);
+
+  // write part with seconds
+  ts = time.ToInteger (Time::S) >> 4;
+  for (int i = 0; i < required_bytes - 2; i++)
+    start.WriteU8 ( ts >> (8 * (required_bytes - 3 - i)) );
+
+  /* arithmetic contortions are to avoid overflowing 31 bits */
+  ts = ((time.ToInteger (Time::S) & 15) << 12) +
+       (((time.ToInteger (Time::NS) % 1000000000) / 5 * 8 + 195312) / 390625);
+  for (int i = required_bytes - 2; i < required_bytes; i++)
+    start.WriteU8 ( ts >> (8 * (required_bytes - 1 - i)) );
+  
+  return len + required_bytes;
+}
+
+size_t
+CcnxEncodingHelper::EstimateTimestampBlob (const Time &time)
+{
+  int required_bytes = 2; // 12 bits for fractions of a second, 4 bits left for seconds. Sometimes it is enough
+  intmax_t ts = time.ToInteger (Time::S) >> 4;
+  for (;  required_bytes < 7 && ts != 0; ts >>= 8) // not more than 6 bytes?
+     required_bytes++;
+
+  return EstimateBlockHeader (required_bytes) + required_bytes;
+}
+
+size_t
+CcnxEncodingHelper::AppendTaggedBlob (Buffer::Iterator &start, CcnbParser::ccn_dtag dtag,
+                  const uint8_t *data, size_t size)
+{
+  size_t written = AppendBlockHeader (start, dtag, CcnbParser::CCN_DTAG);
+  /* 2 */
+  if (size>0)
+    {
+      written += AppendBlockHeader (start, size, CcnbParser::CCN_BLOB);
+      start.Write (data, size);
+      written += size;
+      /* size */
+    }
+  written += AppendCloser (start);
+  /* 1 */
+
+  return written;
+}
+
+size_t
+CcnxEncodingHelper::EstimateTaggedBlob (CcnbParser::ccn_dtag dtag, size_t size)
+{
+  return EstimateBlockHeader (dtag) + EstimateBlockHeader (size) + size + 1;
+}
+
+
+
 } // namespace ns3
diff --git a/helper/ccnx-encoding-helper.h b/helper/ccnx-encoding-helper.h
index 6e3c1c4..bea5087 100644
--- a/helper/ccnx-encoding-helper.h
+++ b/helper/ccnx-encoding-helper.h
@@ -46,20 +46,35 @@
   Serialize (Buffer::Iterator start, const CcnxInterestHeader &interest);
 
   static size_t
+  GetSerializedSize (const CcnxInterestHeader &interest);
+
+  static size_t
   Serialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject);
 
+  static size_t
+  GetSerializedSize (const CcnxContentObjectHeader &contentObject);
+  
 private:
   static size_t
-  AppendBlockHeader (Buffer::Iterator start, size_t value, CcnbParser::ccn_tt block_type);
+  AppendBlockHeader (Buffer::Iterator &start, size_t value, CcnbParser::ccn_tt block_type);
 
   static size_t
-  AppendNumber (Buffer::Iterator start, uint32_t number);
+  EstimateBlockHeader (size_t value);
 
   static size_t
-  AppendCloser (Buffer::Iterator start);
+  AppendNumber (Buffer::Iterator &start, uint32_t number);
 
   static size_t
-  AppendNameComponents (Buffer::Iterator start, const CcnxNameComponents &name);
+  EstimateNumber (uint32_t number);
+
+  static size_t
+  AppendCloser (Buffer::Iterator &start);
+
+  static size_t
+  AppendNameComponents (Buffer::Iterator &start, const CcnxNameComponents &name);
+
+  static size_t
+  EstimateNameComponents (const CcnxNameComponents &name);
 
   /**
    * Append a binary timestamp as a BLOB using the ccn binary
@@ -71,7 +86,10 @@
    * @returns written length
    */
   static size_t
-  AppendTimestampBlob (Buffer::Iterator start, Time time);
+  AppendTimestampBlob (Buffer::Iterator &start, const Time &time);
+
+  static size_t
+  EstimateTimestampBlob (const Time &time);
 
   /**
    * Append a tagged BLOB
@@ -86,9 +104,11 @@
    * @returns written length
    */
   static size_t
-  AppendTaggedBlob (Buffer::Iterator start, CcnbParser::ccn_dtag dtag,
+  AppendTaggedBlob (Buffer::Iterator &start, CcnbParser::ccn_dtag dtag,
                     const uint8_t *data, size_t size);
   
+  static size_t
+  EstimateTaggedBlob (CcnbParser::ccn_dtag dtag, size_t size);
 };
 
 } // namespace ns3
diff --git a/helper/ndn_stupidinterestgenerator_helper.cc b/helper/ndn_stupidinterestgenerator_helper.cc
deleted file mode 100644
index 8fde311..0000000
--- a/helper/ndn_stupidinterestgenerator_helper.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-//
-//  ndn_stupidinterestgenerator_helper.cpp
-//  Abstraction
-//
-//  Created by Ilya Moiseenko on 05.08.11.
-//  Copyright 2011 UCLA. All rights reserved.
-//w
-
-#include "ndn_stupidinterestgenerator_helper.h"
-#include "ns3/inet-socket-address.h"
-#include "ns3/packet-socket-address.h"
-#include "ns3/string.h"
-#include "ns3/names.h"
-
-
-namespace ns3 {
-    
-StupidInterestGeneratorHelper::StupidInterestGeneratorHelper (std::string protocol, Address address)
-{
-	m_factory.SetTypeId ("ns3::StupidInterestGenerator");
-	m_factory.Set ("Protocol", StringValue (protocol));
-	m_factory.Set ("Remote", AddressValue (address));
-}
-    
-void 
-StupidInterestGeneratorHelper::SetAttribute (std::string name, const AttributeValue &value)
-{
-	m_factory.Set (name, value);
-}
-    
-ApplicationContainer
-StupidInterestGeneratorHelper::Install (Ptr<Node> node) const
-{
-	return ApplicationContainer (InstallPriv (node));
-}
-    
-ApplicationContainer
-StupidInterestGeneratorHelper::Install (std::string nodeName) const
-{
-	Ptr<Node> node = Names::Find<Node> (nodeName);
-	return ApplicationContainer (InstallPriv (node));
-}
-    
-ApplicationContainer
-StupidInterestGeneratorHelper::Install (NodeContainer c) const
-{
-	ApplicationContainer apps;
-	for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
-	{
-		apps.Add (InstallPriv (*i));
-	}
-        
-	return apps;
-}
-    
-Ptr<Application>
-StupidInterestGeneratorHelper::InstallPriv (Ptr<Node> node) const
-{
-	Ptr<Application> app = m_factory.Create<Application> ();
-	node->AddApplication (app);
-        
-	return app;
-}
-    
-} // namespace ns3
diff --git a/helper/ndn_stupidinterestgenerator_helper.h b/helper/ndn_stupidinterestgenerator_helper.h
deleted file mode 100644
index b8a39ca..0000000
--- a/helper/ndn_stupidinterestgenerator_helper.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; c-set-offset 'innamespace 0; -*- */
-//
-//  ndn_stupidinterestgenerator_helper.h
-//  Abstraction
-//
-//  Created by Ilya Moiseenko on 05.08.11.
-//  Copyright 2011 UCLA. All rights reserved.
-//
-
-#include "ns3/object-factory.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/node-container.h"
-#include "ns3/application-container.h"
-
-namespace ns3 {
-    
-    /**
-     * \brief A helper to make it easier to instantiate an ns3::OnOffApplication 
-     * on a set of nodes.
-     */
-    class StupidInterestGeneratorHelper
-    {
-    public:
-        /**
-         * Create an OnOffHelper to make it easier to work with OnOffApplications
-         *
-         * \param protocol the name of the protocol to use to send traffic
-         *        by the applications. This string identifies the socket
-         *        factory type used to create sockets for the applications.
-         *        A typical value would be ns3::UdpSocketFactory.
-         * \param address the address of the remote node to send traffic
-         *        to.
-         */
-        StupidInterestGeneratorHelper (std::string protocol, Address address);
-        
-        /**
-         * Helper function used to set the underlying application attributes.
-         *
-         * \param name the name of the application attribute to set
-         * \param value the value of the application attribute to set
-         */
-        void SetAttribute (std::string name, const AttributeValue &value);
-        
-        /**
-         * Install an ns3::OnOffApplication on each node of the input container
-         * configured with all the attributes set with SetAttribute.
-         *
-         * \param c NodeContainer of the set of nodes on which an OnOffApplication 
-         * will be installed.
-         * \returns Container of Ptr to the applications installed.
-         */
-        ApplicationContainer Install (NodeContainer c) const;
-        
-        /**
-         * Install an ns3::OnOffApplication on the node configured with all the 
-         * attributes set with SetAttribute.
-         *
-         * \param node The node on which an OnOffApplication will be installed.
-         * \returns Container of Ptr to the applications installed.
-         */
-        ApplicationContainer Install (Ptr<Node> node) const;
-        
-        /**
-         * Install an ns3::OnOffApplication on the node configured with all the 
-         * attributes set with SetAttribute.
-         *
-         * \param nodeName The node on which an OnOffApplication will be installed.
-         * \returns Container of Ptr to the applications installed.
-         */
-        ApplicationContainer Install (std::string nodeName) const;
-        
-    private:
-        /**
-         * \internal
-         * Install an ns3::OnOffApplication on the node configured with all the 
-         * attributes set with SetAttribute.
-         *
-         * \param node The node on which an OnOffApplication will be installed.
-         * \returns Ptr to the application installed.
-         */
-        Ptr<Application> InstallPriv (Ptr<Node> node) const;
-        std::string m_protocol;
-        Address m_remote;
-        ObjectFactory m_factory;
-    };
-    
-} // namespace ns3
diff --git a/model/ccnx-content-object-header.cc b/model/ccnx-content-object-header.cc
index 581c6c4..2a248e1 100644
--- a/model/ccnx-content-object-header.cc
+++ b/model/ccnx-content-object-header.cc
@@ -63,11 +63,8 @@
 uint32_t
 CcnxContentObjectHeader::GetSerializedSize (void) const
 {
-  // Unfortunately, two serializations are required, unless we can pre-calculate header length... which is not trivial
-  /// \todo This is totally wrong. Need to do some simple packet buffer estimation
-  Buffer tmp(2048);
-  
-  return CcnxEncodingHelper::Serialize (tmp.Begin(), *this);
+  // unfortunately, we don't know exact header size in advance
+  return CcnxEncodingHelper::GetSerializedSize (*this);
 }
     
 void
diff --git a/model/ccnx-interest-header.cc b/model/ccnx-interest-header.cc
index ee9f63b..323c5fc 100644
--- a/model/ccnx-interest-header.cc
+++ b/model/ccnx-interest-header.cc
@@ -54,7 +54,7 @@
   , m_childSelector (false)
   , m_answerOriginKind (false)
   , m_scope (-1)
-  , m_interestLifetime (-1)
+  , m_interestLifetime (Seconds (0))
   , m_nonce (0)
 {
 }
@@ -68,6 +68,7 @@
 const CcnxNameComponents&
 CcnxInterestHeader::GetName () const
 {
+  if (m_name==0) throw CcnxInterestHeaderException();
   return *m_name;
 }
 
@@ -101,9 +102,16 @@
   m_exclude = exclude;
 }
 
+bool
+CcnxInterestHeader::IsEnabledExclude () const
+{
+  return m_exclude!=0;
+}
+
 const CcnxNameComponents&
 CcnxInterestHeader::GetExclude () const
 {
+  if (m_exclude==0) throw CcnxInterestHeaderException();
   return *m_exclude;
 }
 
@@ -170,17 +178,16 @@
 uint32_t
 CcnxInterestHeader::GetSerializedSize (void) const
 {
-  // unfortunately, 2 serialization required...
-  /// \todo This is totally wrong. Need to do some simple packet buffer estimation
-  Buffer tmp(2048);
-  
-  return CcnxEncodingHelper::Serialize (tmp.Begin(), *this);
+  // unfortunately, we don't know exact header size in advance
+  return CcnxEncodingHelper::GetSerializedSize (*this);
 }
     
 void
 CcnxInterestHeader::Serialize (Buffer::Iterator start) const
 {
-  CcnxEncodingHelper::Serialize (start, *this);
+  size_t size = CcnxEncodingHelper::Serialize (start, *this);
+  
+  NS_LOG_INFO ("Serialize size = " << size);
 }
 
 uint32_t
@@ -198,23 +205,24 @@
 void
 CcnxInterestHeader::Print (std::ostream &os) const
 {
-  os << "<Interest><Name>" << *m_name << "</Name>";
-  if (m_minSuffixComponents>=0)
-    os << "<MinSuffixComponents>" << m_minSuffixComponents << "</MinSuffixComponents>";
-  if (m_maxSuffixComponents>=0)
-    os << "<MaxSuffixComponents>" << m_maxSuffixComponents << "</MaxSuffixComponents>";
-  if (m_exclude->size()>0)
-    os << "<Exclude>" << *m_exclude << "</Exclude>";
-  if (m_childSelector)
-    os << "<ChildSelector />";
-  if (m_answerOriginKind)
-    os << "<AnswerOriginKind />";
-  if (m_scope>=0)
-    os << "<Scope>" << m_scope << "</Scope>";
-  if (!m_interestLifetime.IsZero())
-    os << "<InterestLifetime>" << m_interestLifetime << "</InterestLifetime>";
-  if (m_nonce>0)
-    os << "<Nonce>" << m_nonce << "</Nonce>";
+  os << "<Interest>\n  <Name>" << GetName () << "</Name>\n";
+  if (GetMinSuffixComponents () >= 0)
+    os << "  <MinSuffixComponents>" << GetMinSuffixComponents () << "</MinSuffixComponents>\n";
+  if (GetMaxSuffixComponents () >= 0)
+    os << "  <MaxSuffixComponents>" << m_maxSuffixComponents << "</MaxSuffixComponents>\n";
+  if (IsEnabledExclude () && GetExclude ().size()>0)
+    os << "  <Exclude>" << GetExclude () << "</Exclude>\n";
+  if (IsEnabledChildSelector ())
+    os << "  <ChildSelector />\n";
+  if (IsEnabledAnswerOriginKind ())
+    os << "  <AnswerOriginKind />\n";
+  if (GetScope () >= 0)
+    os << "  <Scope>" << GetScope () << "</Scope>\n";
+  if ( !GetInterestLifetime ().IsZero() )
+    os << "  <InterestLifetime>" << GetInterestLifetime () << "</InterestLifetime>\n";
+  if (GetNonce ()>0)
+    os << "  <Nonce>" << GetNonce () << "</Nonce>\n";
+  os << "</Interest>";
 }
 
 }
diff --git a/model/ccnx-interest-header.h b/model/ccnx-interest-header.h
index e8436fb..061c26b 100644
--- a/model/ccnx-interest-header.h
+++ b/model/ccnx-interest-header.h
@@ -166,6 +166,9 @@
   void
   SetExclude (const Ptr<CcnxNameComponents> &exclude);
 
+  bool
+  IsEnabledExclude () const;
+  
   const CcnxNameComponents&
   GetExclude () const;
 
@@ -220,6 +223,8 @@
   uint32_t m_nonce; ///< Nonce. not used if zero
 };
 
+class CcnxInterestHeaderException {};
+
 } // namespace ns3
 
 #endif // _CCNX_INTEREST_HEADER_H_