Adding digest recalculation logic to Sync::FullState
diff --git a/model/sync-diff-state.h b/model/sync-diff-state.h
index 14202c4..4a46969 100644
--- a/model/sync-diff-state.h
+++ b/model/sync-diff-state.h
@@ -54,11 +54,18 @@
     m_next = next;
   }
 
-  // void
-  // setDigest (Hash digest);
+  /**
+   * @brief Set digest for the diff state (obtained from a corresponding full state)
+   * @param digest A read only smart pointer to a digest object (that should be unmodified anywhere else)
+   */
+  void
+  setDigest (DigestConstPtr digest) { m_digest = digest; }
 
-  // Hash
-  // getDigest () const;
+  /**
+   * @brief Get digest for the diff state
+   */
+  DigestConstPtr
+  getDigest () const { return m_digest; }
 
   /**
    * @brief Accumulate differences from `this' state to the most current state
@@ -86,7 +93,7 @@
   
 private:
   DiffStatePtr m_next;
-  // Hash m_digest;
+  DigestConstPtr m_digest;
 };
 
 } // Sync
diff --git a/model/sync-digest.cc b/model/sync-digest.cc
index 4004614..f6ad110 100644
--- a/model/sync-digest.cc
+++ b/model/sync-digest.cc
@@ -23,7 +23,7 @@
 #include "sync-digest.h"
 #include <string.h>
 
-#include "ns3/assert.h"
+#include <boost/assert.hpp>
 #include <boost/exception/errinfo_at_line.hpp>
 
 using namespace boost;
@@ -81,7 +81,7 @@
   if (m_buffer == 0)
     finalize ();
 
-  NS_ASSERT (sizeof (std::size_t) <= m_hashLength);
+  BOOST_ASSERT (sizeof (std::size_t) <= m_hashLength);
   
   // just getting first sizeof(std::size_t) bytes
   // not ideal, but should work pretty well
@@ -97,7 +97,7 @@
   if (digest.m_buffer == 0)
     digest.finalize ();
   
-  NS_ASSERT (m_hashLength == digest.m_hashLength);
+  BOOST_ASSERT (m_hashLength == digest.m_hashLength);
 
   return memcmp (m_buffer, digest.m_buffer, m_hashLength) == 0;
 }
diff --git a/model/sync-digest.h b/model/sync-digest.h
index d0c76f5..adf4d96 100644
--- a/model/sync-digest.h
+++ b/model/sync-digest.h
@@ -124,6 +124,8 @@
 
 struct DigestCalculationError : virtual boost::exception { };
 
+typedef boost::shared_ptr<Digest> DigestPtr;
+typedef boost::shared_ptr<const Digest> DigestConstPtr;
 
 Digest &
 Digest::operator << (const std::string &str)
diff --git a/model/sync-full-leaf.h b/model/sync-full-leaf.h
index 2851c84..5e2c49b 100644
--- a/model/sync-full-leaf.h
+++ b/model/sync-full-leaf.h
@@ -64,6 +64,7 @@
 };
 
 typedef boost::shared_ptr<FullLeaf> FullLeafPtr;
+typedef boost::shared_ptr<const FullLeaf> FullLeafConstPtr;
 
 } // Sync
 
diff --git a/model/sync-full-state.cc b/model/sync-full-state.cc
index b7e948f..1ec8249 100644
--- a/model/sync-full-state.cc
+++ b/model/sync-full-state.cc
@@ -27,6 +27,10 @@
 #include <boost/make_shared.hpp>
 #include <boost/lambda/lambda.hpp>
 #include <boost/lambda/bind.hpp>
+#include <boost/foreach.hpp>
+#include <boost/assert.hpp>
+
+#include "sync-full-leaf.h"
 
 using namespace boost;
 namespace ll = boost::lambda;
@@ -48,12 +52,30 @@
 {
   return ns3::Simulator::Now () - m_lastUpdated;
 }
-  
+
+DigestConstPtr
+FullState::getDigest ()
+{
+  if (m_digest == 0)
+    {
+      m_digest = make_shared<Digest> ();
+      BOOST_FOREACH (LeafConstPtr leaf, m_leaves)
+        {
+          FullLeafConstPtr fullLeaf = dynamic_pointer_cast<const FullLeaf> (leaf);
+          BOOST_ASSERT (fullLeaf != 0);
+          *m_digest << fullLeaf->getDigest ();
+        }
+    }
+
+  return m_digest;
+}
+
 // from State
 void
 FullState::update (NameInfoConstPtr info, const SeqNo &seq)
 {
   m_lastUpdated = ns3::Simulator::Now ();
+  m_digest.reset ();
 
   LeafContainer::iterator item = m_leaves.find (*info);
   if (item == m_leaves.end ())
@@ -70,6 +92,7 @@
 FullState::remove (NameInfoConstPtr info)
 {
   m_lastUpdated = ns3::Simulator::Now ();
+  m_digest.reset ();
 
   m_leaves.erase (*info);
 }
diff --git a/model/sync-full-state.h b/model/sync-full-state.h
index 75b6b1b..479647a 100644
--- a/model/sync-full-state.h
+++ b/model/sync-full-state.h
@@ -48,6 +48,14 @@
    */
   ns3::Time
   getTimeFromLastUpdate () const;
+
+  /**
+   * @brief Obtain a read-only copy of the digest
+   *
+   * If m_digest is 0, then it is automatically created.  On every update and removal, m_digest is reset to 0
+   */
+  DigestConstPtr
+  getDigest ();
   
   // from State
   virtual void
@@ -58,6 +66,7 @@
   
 private:
   ns3::Time m_lastUpdated; ///< @brief Time when state was updated last time
+  DigestPtr m_digest;
 };
 
 
diff --git a/model/sync-leaf.h b/model/sync-leaf.h
index a4c64cf..c4da60c 100644
--- a/model/sync-leaf.h
+++ b/model/sync-leaf.h
@@ -70,6 +70,7 @@
 };
 
 typedef boost::shared_ptr<Leaf> LeafPtr;
+typedef boost::shared_ptr<const Leaf> LeafConstPtr;
 
 } // Sync