Now everything at least compiles, though doing nothing
diff --git a/model/sync-ccnx-name-info.cc b/model/sync-ccnx-name-info.cc
index f0a5473..2f97b12 100644
--- a/model/sync-ccnx-name-info.cc
+++ b/model/sync-ccnx-name-info.cc
@@ -24,26 +24,52 @@
 #include "ns3/ccnx-name-components.h"
 
 #include <boost/lexical_cast.hpp>
+#include <utility>
+
+using namespace std;
+using namespace boost;
 
 namespace ns3 {
 namespace Sync {
 
+NameInfoConstPtr
+CcnxNameInfo::FindOrCreate (Ptr<const CcnxNameComponents> name)
+{
+  string key = lexical_cast<string> (*name);
+
+  NameInfoPtr value = NameInfoPtr (new CcnxNameInfo (name));
+  pair<NameMap::iterator,bool> item =
+    m_names.insert (make_pair (key, value));
+
+  return item.first->second;
+}
 
 CcnxNameInfo::CcnxNameInfo (Ptr<const CcnxNameComponents> name)
   : m_name (name)
 {
+  m_id = m_ids ++; // set ID for a newly inserted element
 }
 
-CcnxNameInfo::~CcnxNameInfo ()
-{
-}
-
-std::string
+string
 CcnxNameInfo::toString () const
 {
-  return boost::lexical_cast<std::string> (*m_name);
+  return lexical_cast<std::string> (*m_name);
 }
 
+bool
+CcnxNameInfo::operator == (const NameInfo &info) const
+{
+  try
+    {
+      return *m_name == *dynamic_cast<const CcnxNameInfo&> (info).m_name;
+    }
+  catch (...)
+    {
+      return false;
+    }
+}
+
+
 
 } // Sync
 } // ns3
diff --git a/model/sync-ccnx-name-info.h b/model/sync-ccnx-name-info.h
index 89ea006..d26183a 100644
--- a/model/sync-ccnx-name-info.h
+++ b/model/sync-ccnx-name-info.h
@@ -36,18 +36,35 @@
 {
 public:
   /**
-   * @brief Constructor
-   * @param name full (routable) name for the participant
+   * @brief Lookup existing or create new NameInfo object
+   * @param name routable prefix
    */
-  CcnxNameInfo (Ptr<const CcnxNameComponents> name);
-  virtual ~CcnxNameInfo ();
+  static NameInfoConstPtr
+  FindOrCreate (Ptr<const CcnxNameComponents> name);
+
+  virtual ~CcnxNameInfo () { };
   
   // from NameInfo
+  virtual bool
+  operator == (const NameInfo &info) const;
+
   virtual std::string
   toString () const;
-  
+
 private:
-  Ptr<const CcnxNameCompnents> m_name;
+  // implementing a singleton pattern. 
+  /**
+   * @brief Disabled default constructor. NameInfo object should be created through FindOrCreate static call.
+   */
+
+  /**
+   * @brief Disabled default
+   */
+  CcnxNameInfo () {}
+  CcnxNameInfo& operator = (const CcnxNameInfo &info) { return *this; }
+  CcnxNameInfo (Ptr<const CcnxNameComponents> name);
+  
+  Ptr<const CcnxNameComponents> m_name;
 };
 
 } // Sync
diff --git a/model/sync-diff-leaf.h b/model/sync-diff-leaf.h
index d857690..d6ef532 100644
--- a/model/sync-diff-leaf.h
+++ b/model/sync-diff-leaf.h
@@ -52,7 +52,7 @@
    */
   DiffLeaf (boost::shared_ptr<const NameInfo> info, const SeqNo &seq)
     : Leaf (info, seq)
-    , m_op (Operation::UPDATE)
+    , m_op (UPDATE)
   {
   }
 
@@ -65,7 +65,7 @@
    */
   DiffLeaf (boost::shared_ptr<const NameInfo> info)
     : Leaf (info, SeqNo (0,0))
-    , m_op (Operation::REMOVE)
+    , m_op (REMOVE)
   {
   }
 
@@ -83,6 +83,8 @@
   Operation m_op;
 };
 
+typedef boost::shared_ptr<DiffLeaf> DiffLeafPtr;
+
 } // Sync
 } // ns3
 
diff --git a/model/sync-diff-state.cc b/model/sync-diff-state.cc
index b26a756..b5bb7cf 100644
--- a/model/sync-diff-state.cc
+++ b/model/sync-diff-state.cc
@@ -21,6 +21,7 @@
  */
 
 #include "sync-diff-state.h"
+#include "sync-diff-leaf.h"
 
 #include <boost/make_shared.hpp>
 
@@ -30,7 +31,6 @@
 namespace Sync {
 
 DiffState::DiffState ()
-  : m_next (0)
 {
 }
 
@@ -43,7 +43,7 @@
 {
   DiffStatePtr ret = make_shared<DiffState> ();
 
-  DiffState *state = m_next;
+  DiffStatePtr state = m_next;
   while (state != 0)
     {
       *ret += *state;
@@ -60,24 +60,22 @@
 }
   
 // from State
-virtual void
+void
 DiffState::update (NameInfoConstPtr info, const SeqNo &seq)
 {
-  LeafContainer::iterator item = m_leafs.find (info);
-  if (item != m_leafs.end ())
-    m_leafs.remove (item);
-  
-  m_leafs.insert (make_shared<DiffLeaf> (info, cref (seq)));
+  m_leaves.erase (*info);
+
+  DiffLeafPtr leaf = make_shared<DiffLeaf> (info, cref (seq));
+  m_leaves.insert (leaf);
 }
 
-virtual void
+void
 DiffState::remove (NameInfoConstPtr info)
 {
-  LeafContainer::iterator item = m_leafs.find (info);
-  if (item != m_leafs.end ())
-    m_leafs.remove (item);
+  m_leaves.erase (*info);
 
-  m_leafs.insert (make_shared<DiffLeaf> (info));
+  DiffLeafPtr leaf = make_shared<DiffLeaf> (info);
+  m_leaves.insert (leaf);
 }
 
 
diff --git a/model/sync-full-state.cc b/model/sync-full-state.cc
index 696ac3c..ffd3120 100644
--- a/model/sync-full-state.cc
+++ b/model/sync-full-state.cc
@@ -56,14 +56,14 @@
 {
   m_lastUpdated = Simulator::Now ();
 
-  LeafContainer::iterator item = m_leafs.find (*info);
-  if (item == m_leafs.end ())
+  LeafContainer::iterator item = m_leaves.find (*info);
+  if (item == m_leaves.end ())
     {
-      m_leafs.insert (make_shared<Leaf> (info, cref (seq)));
+      m_leaves.insert (make_shared<Leaf> (info, cref (seq)));
     }
   else
     {
-      m_leafs.modify (item, ll::bind (&Leaf::setSeq, ll::_1, cref (seq)));
+      m_leaves.modify (item, ll::bind (&Leaf::setSeq, *ll::_1, seq));
     }
 }
 
@@ -72,7 +72,7 @@
 {
   m_lastUpdated = Simulator::Now ();
 
-  m_leafs.remove (info);
+  m_leaves.erase (*info);
 }
 
 
diff --git a/model/sync-full-state.h b/model/sync-full-state.h
index 56d7f0d..2803497 100644
--- a/model/sync-full-state.h
+++ b/model/sync-full-state.h
@@ -23,6 +23,7 @@
 #ifndef SYNC_FULL_STATE_H
 #define SYNC_FULL_STATE_H
 
+#include "ns3/nstime.h"
 #include "sync-state.h"
 
 namespace ns3 {
diff --git a/model/sync-leaf.h b/model/sync-leaf.h
index 151f2c6..a7f2ce5 100644
--- a/model/sync-leaf.h
+++ b/model/sync-leaf.h
@@ -24,13 +24,11 @@
 #define SYNC_LEAF_H
 
 #include "sync-seq-no.h"
-#include <boost/shared_ptr.hpp>
+#include "sync-name-info.h"
 
 namespace ns3 {
 namespace Sync {
 
-class NameInfo;
-
 /**
  * \ingroup sync
  * @brief Sync tree leaf
diff --git a/model/sync-name-info.cc b/model/sync-name-info.cc
index 2680859..07f57ae 100644
--- a/model/sync-name-info.cc
+++ b/model/sync-name-info.cc
@@ -19,3 +19,24 @@
  *         卞超轶 Chaoyi Bian <bcy@pku.edu.cn>
  *	   Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
+
+#include "sync-name-info.h"
+#include "ns3/ccnx-name-components.h"
+
+#include <boost/lexical_cast.hpp>
+
+namespace ns3 {
+namespace Sync {
+
+NameInfo::NameMap NameInfo::m_names;
+size_t  NameInfo::m_ids = 0;
+
+/**
+ * @brief Calculates digest of the name
+ */
+// tempalte<>
+// Digest
+// NameInfo::getDigest<PrefixInfo> () const;
+
+} // Sync
+} // ns3
diff --git a/model/sync-name-info.h b/model/sync-name-info.h
index d0ec575..c332e4d 100644
--- a/model/sync-name-info.h
+++ b/model/sync-name-info.h
@@ -23,29 +23,61 @@
 #ifndef SYNC_NAME_INFO_H
 #define SYNC_NAME_INFO_H
 
+#include <boost/shared_ptr.hpp>
+#include <map>
+#include <string>
+
 namespace ns3 {
 namespace Sync {
 
 /**
- * @brief Abstraction of the leaf name
+ * @ingroup sync
+ * @brief Templated class for the leaf name
  */
 class NameInfo
 {
+private:
+  typedef boost::shared_ptr<const NameInfo> const_ptr;
+  
 public:
-  virtual ~NameInfo () = 0;
+  virtual ~NameInfo () { };
+
+  /**
+   * @brief Get ID of the record (should be locally-unique, but not really necessary---this is be used for hashing purposes)
+   */
+  size_t
+  getHashId () const { return m_id; }
+  
+  virtual bool
+  operator == (const NameInfo &info) const = 0;
+
   /**
    * @brief Calculates digest of the name
    */
   // Digest
   // getDigest () const;
 
+  /**
+   * @brief Convert prefix to string
+   * @returns string representation of prefix
+   */
   virtual std::string
   toString () const = 0;
+
+protected:
+  // actual stuff
+  size_t m_id; ///< @brief Identifies NameInfo throughout the library (for hash container, doesn't need to be strictly unique)
+
+  // static stuff
+  typedef std::map<std::string, const_ptr> NameMap;
+  static size_t  m_ids;
+  static NameMap m_names;
 };
 
 typedef boost::shared_ptr<NameInfo> NameInfoPtr;
 typedef boost::shared_ptr<const NameInfo> NameInfoConstPtr;
 
+
 } // Sync
 } // ns3
 
diff --git a/model/sync-seq-no.h b/model/sync-seq-no.h
index 1461acb..3923d37 100644
--- a/model/sync-seq-no.h
+++ b/model/sync-seq-no.h
@@ -23,6 +23,8 @@
 #ifndef SYNC_SEQ_NO_H
 #define SYNC_SEQ_NO_H
 
+#include <boost/cstdint.hpp>
+
 namespace ns3
 {
 
diff --git a/model/sync-state-leaf-container.h b/model/sync-state-leaf-container.h
index f66c966..c674fc1 100644
--- a/model/sync-state-leaf-container.h
+++ b/model/sync-state-leaf-container.h
@@ -23,6 +23,8 @@
 #ifndef SYNC_STATE_LEAF_CONTAINER
 #define SYNC_STATE_LEAF_CONTAINER
 
+#include "sync-leaf.h"
+
 #include <boost/multi_index_container.hpp>
 // #include <boost/multi_index/tag.hpp>
 // #include <boost/multi_index/ordered_index.hpp>
@@ -37,6 +39,17 @@
 namespace ns3 {
 namespace Sync {
 
+struct NameInfoHash : public std::unary_function<NameInfo, std::size_t>
+{
+  std::size_t
+  operator() (const NameInfo &prefix) const
+  {
+    return prefix.getHashId ();
+  }
+};
+
+struct hashed { };
+
 /**
  * \ingroup sync
  * @brief Container for SYNC leaves
@@ -46,9 +59,9 @@
     mi::indexed_by<
       // For fast access to elements using NameInfo
       mi::hashed_unique<
+        mi::tag<hashed>,
         mi::const_mem_fun<Leaf, const NameInfo&, &Leaf::getInfo>,
-        LeafHash (),
-        LeafEqual () 
+        NameInfoHash
       >
     >
    >
diff --git a/model/sync-state.h b/model/sync-state.h
index c6511e5..84abea6 100644
--- a/model/sync-state.h
+++ b/model/sync-state.h
@@ -41,7 +41,7 @@
 class State
 {
 public:
-  virtual ~State () = 0;
+  virtual ~State () { };
   
   /**
    * @brief Add or update leaf to the state tree