diff --git a/utils/trie/trie.hpp b/utils/trie/trie.hpp
index 1e37cbd..9afc8d1 100644
--- a/utils/trie/trie.hpp
+++ b/utils/trie/trie.hpp
@@ -40,33 +40,32 @@
 // Allow customization for payload
 //
 template<typename Payload, typename BasePayload = Payload>
-struct pointer_payload_traits
-{
-  typedef Payload         payload_type; // general type of the payload
-  typedef Payload*        storage_type; // how the payload is actually stored
-  typedef Payload*        insert_type;  // what parameter is inserted
+struct pointer_payload_traits {
+  typedef Payload payload_type;  // general type of the payload
+  typedef Payload* storage_type; // how the payload is actually stored
+  typedef Payload* insert_type;  // what parameter is inserted
 
-  typedef Payload*        return_type;  // what is returned on access
-  typedef const Payload*  const_return_type; // what is returned on const access
+  typedef Payload* return_type;             // what is returned on access
+  typedef const Payload* const_return_type; // what is returned on const access
 
-  typedef BasePayload*       base_type;       // base type of the entry (when implementation details need to be hidden)
-  typedef const BasePayload* const_base_type; // const base type of the entry (when implementation details need to be hidden)
+  typedef BasePayload*
+    base_type; // base type of the entry (when implementation details need to be hidden)
+  typedef const BasePayload*
+    const_base_type; // const base type of the entry (when implementation details need to be hidden)
 
   static Payload* empty_payload;
 };
 
 template<typename Payload, typename BasePayload>
-Payload*
-pointer_payload_traits<Payload, BasePayload>::empty_payload = 0;
+Payload* pointer_payload_traits<Payload, BasePayload>::empty_payload = 0;
 
 template<typename Payload, typename BasePayload = Payload>
-struct smart_pointer_payload_traits
-{
-  typedef Payload                 payload_type;
-  typedef ns3::Ptr<Payload>       storage_type;
-  typedef ns3::Ptr<Payload>       insert_type;
+struct smart_pointer_payload_traits {
+  typedef Payload payload_type;
+  typedef ns3::Ptr<Payload> storage_type;
+  typedef ns3::Ptr<Payload> insert_type;
 
-  typedef ns3::Ptr<Payload>       return_type;
+  typedef ns3::Ptr<Payload> return_type;
   typedef ns3::Ptr<const Payload> const_return_type;
 
   typedef ns3::Ptr<BasePayload> base_type;
@@ -76,51 +75,44 @@
 };
 
 template<typename Payload, typename BasePayload>
-ns3::Ptr<Payload>
-smart_pointer_payload_traits<Payload, BasePayload>::empty_payload = 0;
+ns3::Ptr<Payload> smart_pointer_payload_traits<Payload, BasePayload>::empty_payload = 0;
 
 template<typename Payload, typename BasePayload = Payload>
-struct non_pointer_traits
-{
-  typedef Payload         payload_type;
-  typedef Payload         storage_type;
-  typedef const Payload & insert_type; // nothing to insert
+struct non_pointer_traits {
+  typedef Payload payload_type;
+  typedef Payload storage_type;
+  typedef const Payload& insert_type; // nothing to insert
 
-  typedef Payload&        return_type;
-  typedef const Payload & const_return_type;
+  typedef Payload& return_type;
+  typedef const Payload& const_return_type;
 
-  typedef BasePayload&       base_type;
+  typedef BasePayload& base_type;
   typedef const BasePayload& const_base_type;
 
   static Payload empty_payload;
 };
 
 template<typename Payload, typename BasePayload>
-Payload
-non_pointer_traits<Payload, BasePayload>::empty_payload = Payload ();
-
+Payload non_pointer_traits<Payload, BasePayload>::empty_payload = Payload();
 
 ////////////////////////////////////////////////////
 // forward declarations
 //
-template<typename FullKey,
-         typename PayloadTraits,
-         typename PolicyHook >
+template<typename FullKey, typename PayloadTraits, typename PolicyHook>
 class trie;
 
 template<typename FullKey, typename PayloadTraits, typename PolicyHook>
 inline std::ostream&
-operator << (std::ostream &os,
-             const trie<FullKey, PayloadTraits, PolicyHook> &trie_node);
+operator<<(std::ostream& os, const trie<FullKey, PayloadTraits, PolicyHook>& trie_node);
 
 template<typename FullKey, typename PayloadTraits, typename PolicyHook>
 bool
-operator== (const trie<FullKey, PayloadTraits, PolicyHook> &a,
-            const trie<FullKey, PayloadTraits, PolicyHook> &b);
+operator==(const trie<FullKey, PayloadTraits, PolicyHook>& a,
+           const trie<FullKey, PayloadTraits, PolicyHook>& b);
 
-template<typename FullKey, typename PayloadTraits, typename PolicyHook >
+template<typename FullKey, typename PayloadTraits, typename PolicyHook>
 std::size_t
-hash_value (const trie<FullKey, PayloadTraits, PolicyHook> &trie_node);
+hash_value(const trie<FullKey, PayloadTraits, PolicyHook>& trie_node);
 
 ///////////////////////////////////////////////////
 // actual definition
@@ -131,15 +123,12 @@
 template<class T>
 class trie_point_iterator;
 
-template<typename FullKey,
-	 typename PayloadTraits,
-         typename PolicyHook >
-class trie
-{
+template<typename FullKey, typename PayloadTraits, typename PolicyHook>
+class trie {
 public:
   typedef typename FullKey::partial_type Key;
 
-  typedef trie*       iterator;
+  typedef trie* iterator;
   typedef const trie* const_iterator;
 
   typedef trie_iterator<trie, trie> recursive_iterator;
@@ -150,126 +139,119 @@
 
   typedef PayloadTraits payload_traits;
 
-  inline
-  trie (const Key &key, size_t bucketSize = 1, size_t bucketIncrement = 1)
-    : key_ (key)
-    , initialBucketSize_ (bucketSize)
-    , bucketIncrement_ (bucketIncrement)
-    , bucketSize_ (initialBucketSize_)
-    , buckets_ (new bucket_type [bucketSize_]) //cannot use normal pointer, because lifetime of buckets should be larger than lifetime of the container
-    , children_ (bucket_traits (buckets_.get (), bucketSize_))
-    , payload_ (PayloadTraits::empty_payload)
-    , parent_ (0)
+  inline trie(const Key& key, size_t bucketSize = 1, size_t bucketIncrement = 1)
+    : key_(key)
+    , initialBucketSize_(bucketSize)
+    , bucketIncrement_(bucketIncrement)
+    , bucketSize_(initialBucketSize_)
+    , buckets_(new bucket_type[bucketSize_]) // cannot use normal pointer, because lifetime of
+                                             // buckets should be larger than lifetime of the
+                                             // container
+    , children_(bucket_traits(buckets_.get(), bucketSize_))
+    , payload_(PayloadTraits::empty_payload)
+    , parent_(0)
   {
   }
 
-  inline
-  ~trie ()
+  inline ~trie()
   {
     payload_ = PayloadTraits::empty_payload; // necessary for smart pointers...
-    children_.clear_and_dispose (trie_delete_disposer ());
+    children_.clear_and_dispose(trie_delete_disposer());
   }
 
   void
-  clear ()
+  clear()
   {
-    children_.clear_and_dispose (trie_delete_disposer ());
+    children_.clear_and_dispose(trie_delete_disposer());
   }
 
   template<class Predicate>
   void
-  clear_if (Predicate cond)
+  clear_if(Predicate cond)
   {
-    recursive_iterator trieNode (this);
-    recursive_iterator end (0);
+    recursive_iterator trieNode(this);
+    recursive_iterator end(0);
 
-    while (trieNode != end)
-      {
-        if (cond (*trieNode))
-          {
-            trieNode = recursive_iterator (trieNode->erase ());
-          }
-        trieNode ++;
+    while (trieNode != end) {
+      if (cond(*trieNode)) {
+        trieNode = recursive_iterator(trieNode->erase());
       }
+      trieNode++;
+    }
   }
 
   // actual entry
-  friend bool
-  operator== <> (const trie<FullKey, PayloadTraits, PolicyHook> &a,
-                 const trie<FullKey, PayloadTraits, PolicyHook> &b);
+  friend bool operator==<>(const trie<FullKey, PayloadTraits, PolicyHook>& a,
+                           const trie<FullKey, PayloadTraits, PolicyHook>& b);
 
   friend std::size_t
-  hash_value <> (const trie<FullKey, PayloadTraits, PolicyHook> &trie_node);
+  hash_value<>(const trie<FullKey, PayloadTraits, PolicyHook>& trie_node);
 
   inline std::pair<iterator, bool>
-  insert (const FullKey &key,
-          typename PayloadTraits::insert_type payload)
+  insert(const FullKey& key, typename PayloadTraits::insert_type payload)
   {
-    trie *trieNode = this;
+    trie* trieNode = this;
 
-    BOOST_FOREACH (const Key &subkey, key)
-      {
-        typename unordered_set::iterator item = trieNode->children_.find (subkey);
-        if (item == trieNode->children_.end ())
-          {
-            trie *newNode = new trie (subkey, initialBucketSize_, bucketIncrement_);
-            // std::cout << "new " << newNode << "\n";
-            newNode->parent_ = trieNode;
+    BOOST_FOREACH (const Key& subkey, key) {
+      typename unordered_set::iterator item = trieNode->children_.find(subkey);
+      if (item == trieNode->children_.end()) {
+        trie* newNode = new trie(subkey, initialBucketSize_, bucketIncrement_);
+        // std::cout << "new " << newNode << "\n";
+        newNode->parent_ = trieNode;
 
-            if (trieNode->children_.size () >= trieNode->bucketSize_)
-              {
-                trieNode->bucketSize_ += trieNode->bucketIncrement_;
-                trieNode->bucketIncrement_ *= 2; // increase bucketIncrement exponentially
+        if (trieNode->children_.size() >= trieNode->bucketSize_) {
+          trieNode->bucketSize_ += trieNode->bucketIncrement_;
+          trieNode->bucketIncrement_ *= 2; // increase bucketIncrement exponentially
 
-                buckets_array newBuckets (new bucket_type [trieNode->bucketSize_]);
-                trieNode->children_.rehash (bucket_traits (newBuckets.get (), trieNode->bucketSize_));
-                trieNode->buckets_.swap (newBuckets);
-              }
+          buckets_array newBuckets(new bucket_type[trieNode->bucketSize_]);
+          trieNode->children_.rehash(bucket_traits(newBuckets.get(), trieNode->bucketSize_));
+          trieNode->buckets_.swap(newBuckets);
+        }
 
-            std::pair< typename unordered_set::iterator, bool > ret =
-              trieNode->children_.insert (*newNode);
+        std::pair<typename unordered_set::iterator, bool> ret =
+          trieNode->children_.insert(*newNode);
 
-            trieNode = &(*ret.first);
-          }
-        else
-          trieNode = &(*item);
+        trieNode = &(*ret.first);
       }
+      else
+        trieNode = &(*item);
+    }
 
-    if (trieNode->payload_ == PayloadTraits::empty_payload)
-      {
-        trieNode->payload_ = payload;
-        return std::make_pair (trieNode, true);
-      }
+    if (trieNode->payload_ == PayloadTraits::empty_payload) {
+      trieNode->payload_ = payload;
+      return std::make_pair(trieNode, true);
+    }
     else
-      return std::make_pair (trieNode, false);
+      return std::make_pair(trieNode, false);
   }
 
   /**
    * @brief Removes payload (if it exists) and if there are no children, prunes parents trie
    */
   inline iterator
-  erase ()
+  erase()
   {
     payload_ = PayloadTraits::empty_payload;
-    return prune ();
+    return prune();
   }
 
   /**
    * @brief Do exactly as erase, but without erasing the payload
    */
   inline iterator
-  prune ()
+  prune()
   {
-    if (payload_ == PayloadTraits::empty_payload &&
-        children_.size () == 0)
-      {
-        if (parent_ == 0) return this;
+    if (payload_ == PayloadTraits::empty_payload && children_.size() == 0) {
+      if (parent_ == 0)
+        return this;
 
-        trie *parent = parent_;
-        parent->children_.erase_and_dispose (*this, trie_delete_disposer ()); // delete this; basically, committing a suicide
+      trie* parent = parent_;
+      parent->children_
+        .erase_and_dispose(*this,
+                           trie_delete_disposer()); // delete this; basically, committing a suicide
 
-        return parent->prune ();
-      }
+      return parent->prune();
+    }
     return this;
   }
 
@@ -277,16 +259,17 @@
    * @brief Perform prune of the node, but without attempting to parent of the node
    */
   inline void
-  prune_node ()
+  prune_node()
   {
-    if (payload_ == PayloadTraits::empty_payload &&
-        children_.size () == 0)
-      {
-        if (parent_ == 0) return;
+    if (payload_ == PayloadTraits::empty_payload && children_.size() == 0) {
+      if (parent_ == 0)
+        return;
 
-        trie *parent = parent_;
-        parent->children_.erase_and_dispose (*this, trie_delete_disposer ()); // delete this; basically, committing a suicide
-      }
+      trie* parent = parent_;
+      parent->children_
+        .erase_and_dispose(*this,
+                           trie_delete_disposer()); // delete this; basically, committing a suicide
+    }
   }
 
   // inline boost::tuple<const iterator, bool, const iterator>
@@ -302,30 +285,27 @@
    * @return ->second is true if prefix in ->first is longer than key
    */
   inline boost::tuple<iterator, bool, iterator>
-  find (const FullKey &key)
+  find(const FullKey& key)
   {
-    trie *trieNode = this;
+    trie* trieNode = this;
     iterator foundNode = (payload_ != PayloadTraits::empty_payload) ? this : 0;
     bool reachLast = true;
 
-    BOOST_FOREACH (const Key &subkey, key)
-      {
-        typename unordered_set::iterator item = trieNode->children_.find (subkey);
-        if (item == trieNode->children_.end ())
-          {
-            reachLast = false;
-            break;
-          }
-        else
-          {
-            trieNode = &(*item);
-
-            if (trieNode->payload_ != PayloadTraits::empty_payload)
-              foundNode = trieNode;
-          }
+    BOOST_FOREACH (const Key& subkey, key) {
+      typename unordered_set::iterator item = trieNode->children_.find(subkey);
+      if (item == trieNode->children_.end()) {
+        reachLast = false;
+        break;
       }
+      else {
+        trieNode = &(*item);
 
-    return boost::make_tuple (foundNode, reachLast, trieNode);
+        if (trieNode->payload_ != PayloadTraits::empty_payload)
+          foundNode = trieNode;
+      }
+    }
+
+    return boost::make_tuple(foundNode, reachLast, trieNode);
   }
 
   /**
@@ -336,55 +316,50 @@
    */
   template<class Predicate>
   inline boost::tuple<iterator, bool, iterator>
-  find_if (const FullKey &key, Predicate pred)
+  find_if(const FullKey& key, Predicate pred)
   {
-    trie *trieNode = this;
+    trie* trieNode = this;
     iterator foundNode = (payload_ != PayloadTraits::empty_payload) ? this : 0;
     bool reachLast = true;
 
-    BOOST_FOREACH (const Key &subkey, key)
-      {
-        typename unordered_set::iterator item = trieNode->children_.find (subkey);
-        if (item == trieNode->children_.end ())
-          {
-            reachLast = false;
-            break;
-          }
-        else
-          {
-            trieNode = &(*item);
-
-            if (trieNode->payload_ != PayloadTraits::empty_payload &&
-                pred (trieNode->payload_))
-              {
-                foundNode = trieNode;
-              }
-          }
+    BOOST_FOREACH (const Key& subkey, key) {
+      typename unordered_set::iterator item = trieNode->children_.find(subkey);
+      if (item == trieNode->children_.end()) {
+        reachLast = false;
+        break;
       }
+      else {
+        trieNode = &(*item);
 
-    return boost::make_tuple (foundNode, reachLast, trieNode);
+        if (trieNode->payload_ != PayloadTraits::empty_payload && pred(trieNode->payload_)) {
+          foundNode = trieNode;
+        }
+      }
+    }
+
+    return boost::make_tuple(foundNode, reachLast, trieNode);
   }
 
   /**
    * @brief Find next payload of the sub-trie
-   * @returns end() or a valid iterator pointing to the trie leaf (order is not defined, enumeration )
+   * @returns end() or a valid iterator pointing to the trie leaf (order is not defined, enumeration
+   * )
    */
   inline iterator
-  find ()
+  find()
   {
     if (payload_ != PayloadTraits::empty_payload)
       return this;
 
     typedef trie<FullKey, PayloadTraits, PolicyHook> trie;
-    for (typename trie::unordered_set::iterator subnode = children_.begin ();
-         subnode != children_.end ();
-         subnode++ )
-      // BOOST_FOREACH (trie &subnode, children_)
-      {
-        iterator value = subnode->find ();
-        if (value != 0)
-          return value;
-      }
+    for (typename trie::unordered_set::iterator subnode = children_.begin();
+         subnode != children_.end(); subnode++)
+    // BOOST_FOREACH (trie &subnode, children_)
+    {
+      iterator value = subnode->find();
+      if (value != 0)
+        return value;
+    }
 
     return 0;
   }
@@ -392,25 +367,25 @@
   /**
    * @brief Find next payload of the sub-trie satisfying the predicate
    * @param pred predicate
-   * @returns end() or a valid iterator pointing to the trie leaf (order is not defined, enumeration )
+   * @returns end() or a valid iterator pointing to the trie leaf (order is not defined, enumeration
+   * )
    */
   template<class Predicate>
   inline const iterator
-  find_if (Predicate pred)
+  find_if(Predicate pred)
   {
-    if (payload_ != PayloadTraits::empty_payload && pred (payload_))
+    if (payload_ != PayloadTraits::empty_payload && pred(payload_))
       return this;
 
     typedef trie<FullKey, PayloadTraits, PolicyHook> trie;
-    for (typename trie::unordered_set::iterator subnode = children_.begin ();
-         subnode != children_.end ();
-         subnode++ )
-      // BOOST_FOREACH (const trie &subnode, children_)
-      {
-        iterator value = subnode->find_if (pred);
-        if (value != 0)
-          return value;
-      }
+    for (typename trie::unordered_set::iterator subnode = children_.begin();
+         subnode != children_.end(); subnode++)
+    // BOOST_FOREACH (const trie &subnode, children_)
+    {
+      iterator value = subnode->find_if(pred);
+      if (value != 0)
+        return value;
+    }
 
     return 0;
   }
@@ -421,84 +396,83 @@
    *
    * This version check predicate only for the next level children
    *
-   * @returns end() or a valid iterator pointing to the trie leaf (order is not defined, enumeration )
+   * @returns end() or a valid iterator pointing to the trie leaf (order is not defined, enumeration
+   *)
    */
   template<class Predicate>
   inline const iterator
-  find_if_next_level (Predicate pred)
+  find_if_next_level(Predicate pred)
   {
     typedef trie<FullKey, PayloadTraits, PolicyHook> trie;
-    for (typename trie::unordered_set::iterator subnode = children_.begin ();
-         subnode != children_.end ();
-         subnode++ )
-      {
-        if (pred (subnode->key ()))
-          {
-            return subnode->find ();
-          }
+    for (typename trie::unordered_set::iterator subnode = children_.begin();
+         subnode != children_.end(); subnode++) {
+      if (pred(subnode->key())) {
+        return subnode->find();
       }
+    }
 
     return 0;
   }
 
-  iterator end ()
+  iterator
+  end()
   {
     return 0;
   }
 
-  const_iterator end () const
+  const_iterator
+  end() const
   {
     return 0;
   }
 
   typename PayloadTraits::const_return_type
-  payload () const
+  payload() const
   {
     return payload_;
   }
 
   typename PayloadTraits::return_type
-  payload ()
+  payload()
   {
     return payload_;
   }
 
   void
-  set_payload (typename PayloadTraits::insert_type payload)
+  set_payload(typename PayloadTraits::insert_type payload)
   {
     payload_ = payload;
   }
 
-  Key key () const
+  Key
+  key() const
   {
     return key_;
   }
 
   inline void
-  PrintStat (std::ostream &os) const;
+  PrintStat(std::ostream& os) const;
 
 private:
-  //The disposer object function
-  struct trie_delete_disposer
-  {
-    void operator() (trie *delete_this)
+  // The disposer object function
+  struct trie_delete_disposer {
+    void
+    operator()(trie* delete_this)
     {
       delete delete_this;
     }
   };
 
   template<class D>
-  struct array_disposer
-  {
-    void operator() (D *array)
+  struct array_disposer {
+    void
+    operator()(D* array)
     {
-      delete [] array;
+      delete[] array;
     }
   };
 
-  friend
-  std::ostream&
-  operator<< < > (std::ostream &os, const trie &trie_node);
+  friend std::ostream& operator<<<>(std::ostream& os, const trie& trie_node);
 
 public:
   PolicyHook policy_hook_;
@@ -508,12 +482,11 @@
 
   // necessary typedefs
   typedef trie self_type;
-  typedef boost::intrusive::member_hook< trie,
-                                         boost::intrusive::unordered_set_member_hook< >,
-                                         &trie::unordered_set_member_hook_ > member_hook;
+  typedef boost::intrusive::member_hook<trie, boost::intrusive::unordered_set_member_hook<>,
+                                        &trie::unordered_set_member_hook_> member_hook;
 
-  typedef boost::intrusive::unordered_set< trie, member_hook > unordered_set;
-  typedef typename unordered_set::bucket_type   bucket_type;
+  typedef boost::intrusive::unordered_set<trie, member_hook> unordered_set;
+  typedef typename unordered_set::bucket_type bucket_type;
   typedef typename unordered_set::bucket_traits bucket_traits;
 
   template<class T, class NonConstT>
@@ -532,204 +505,267 @@
   size_t bucketIncrement_;
 
   size_t bucketSize_;
-  typedef boost::interprocess::unique_ptr< bucket_type, array_disposer<bucket_type> > buckets_array;
+  typedef boost::interprocess::unique_ptr<bucket_type, array_disposer<bucket_type>> buckets_array;
   buckets_array buckets_;
   unordered_set children_;
 
   typename PayloadTraits::storage_type payload_;
-  trie *parent_; // to make cleaning effective
+  trie* parent_; // to make cleaning effective
 };
 
-
-
-
 template<typename FullKey, typename PayloadTraits, typename PolicyHook>
 inline std::ostream&
-operator << (std::ostream &os, const trie<FullKey, PayloadTraits, PolicyHook> &trie_node)
+operator<<(std::ostream& os, const trie<FullKey, PayloadTraits, PolicyHook>& trie_node)
 {
-  os << "# " << trie_node.key_ << ((trie_node.payload_ != PayloadTraits::empty_payload)?"*":"") << std::endl;
+  os << "# " << trie_node.key_ << ((trie_node.payload_ != PayloadTraits::empty_payload) ? "*" : "")
+     << std::endl;
   typedef trie<FullKey, PayloadTraits, PolicyHook> trie;
 
-  for (typename trie::unordered_set::const_iterator subnode = trie_node.children_.begin ();
-       subnode != trie_node.children_.end ();
-       subnode++ )
+  for (typename trie::unordered_set::const_iterator subnode = trie_node.children_.begin();
+       subnode != trie_node.children_.end(); subnode++)
   // BOOST_FOREACH (const trie &subnode, trie_node.children_)
-    {
-      os << "\"" << &trie_node << "\"" << " [label=\"" << trie_node.key_ << ((trie_node.payload_ != PayloadTraits::empty_payload)?"*":"") << "\"]\n";
-      os << "\"" << &(*subnode) << "\"" << " [label=\"" << subnode->key_ << ((subnode->payload_ != PayloadTraits::empty_payload)?"*":"") << "\"]""\n";
+  {
+    os << "\"" << &trie_node << "\""
+       << " [label=\"" << trie_node.key_
+       << ((trie_node.payload_ != PayloadTraits::empty_payload) ? "*" : "") << "\"]\n";
+    os << "\"" << &(*subnode) << "\""
+       << " [label=\"" << subnode->key_
+       << ((subnode->payload_ != PayloadTraits::empty_payload) ? "*" : "") << "\"]"
+                                                                              "\n";
 
-      os << "\"" << &trie_node << "\"" << " -> " << "\"" << &(*subnode) << "\"" << "\n";
-      os << *subnode;
-    }
+    os << "\"" << &trie_node << "\""
+       << " -> "
+       << "\"" << &(*subnode) << "\""
+       << "\n";
+    os << *subnode;
+  }
 
   return os;
 }
 
 template<typename FullKey, typename PayloadTraits, typename PolicyHook>
 inline void
-trie<FullKey, PayloadTraits, PolicyHook>
-::PrintStat (std::ostream &os) const
+trie<FullKey, PayloadTraits, PolicyHook>::PrintStat(std::ostream& os) const
 {
-  os << "# " << key_ << ((payload_ != PayloadTraits::empty_payload)?"*":"") << ": " << children_.size() << " children" << std::endl;
-  for (size_t bucket = 0, maxbucket = children_.bucket_count ();
-       bucket < maxbucket;
-       bucket++)
-    {
-      os << " " << children_.bucket_size (bucket);
-    }
+  os << "# " << key_ << ((payload_ != PayloadTraits::empty_payload) ? "*" : "") << ": "
+     << children_.size() << " children" << std::endl;
+  for (size_t bucket = 0, maxbucket = children_.bucket_count(); bucket < maxbucket; bucket++) {
+    os << " " << children_.bucket_size(bucket);
+  }
   os << "\n";
 
   typedef trie<FullKey, PayloadTraits, PolicyHook> trie;
-  for (typename trie::unordered_set::const_iterator subnode = children_.begin ();
-       subnode != children_.end ();
-       subnode++ )
+  for (typename trie::unordered_set::const_iterator subnode = children_.begin();
+       subnode != children_.end(); subnode++)
   // BOOST_FOREACH (const trie &subnode, children_)
-    {
-      subnode->PrintStat (os);
-    }
+  {
+    subnode->PrintStat(os);
+  }
 }
 
-
 template<typename FullKey, typename PayloadTraits, typename PolicyHook>
 inline bool
-operator == (const trie<FullKey, PayloadTraits, PolicyHook> &a,
-             const trie<FullKey, PayloadTraits, PolicyHook> &b)
+operator==(const trie<FullKey, PayloadTraits, PolicyHook>& a,
+           const trie<FullKey, PayloadTraits, PolicyHook>& b)
 {
   return a.key_ == b.key_;
 }
 
 template<typename FullKey, typename PayloadTraits, typename PolicyHook>
 inline std::size_t
-hash_value (const trie<FullKey, PayloadTraits, PolicyHook> &trie_node)
+hash_value(const trie<FullKey, PayloadTraits, PolicyHook>& trie_node)
 {
-  return boost::hash_value (trie_node.key_);
+  return boost::hash_value(trie_node.key_);
 }
 
-
-
 template<class Trie, class NonConstTrie> // hack for boost < 1.47
-class trie_iterator
-{
+class trie_iterator {
 public:
-  trie_iterator () : trie_ (0) {}
-  trie_iterator (typename Trie::iterator item) : trie_ (item) {}
-  trie_iterator (Trie &item) : trie_ (&item) {}
-
-  Trie & operator* () { return *trie_; }
-  const Trie & operator* () const { return *trie_; }
-  Trie * operator-> () { return trie_; }
-  const Trie * operator-> () const { return trie_; }
-  bool operator== (trie_iterator<const Trie, NonConstTrie> &other) const { return (trie_ == other.trie_); }
-  bool operator== (trie_iterator<Trie, NonConstTrie> &other) { return (trie_ == other.trie_); }
-  bool operator!= (trie_iterator<const Trie, NonConstTrie> &other) const { return !(*this == other); }
-  bool operator!= (trie_iterator<Trie, NonConstTrie> &other) { return !(*this == other); }
-
-  trie_iterator<Trie,NonConstTrie> &
-  operator++ (int)
+  trie_iterator()
+    : trie_(0)
   {
-    if (trie_->children_.size () > 0)
-      trie_ = &(*trie_->children_.begin ());
+  }
+  trie_iterator(typename Trie::iterator item)
+    : trie_(item)
+  {
+  }
+  trie_iterator(Trie& item)
+    : trie_(&item)
+  {
+  }
+
+  Trie& operator*()
+  {
+    return *trie_;
+  }
+  const Trie& operator*() const
+  {
+    return *trie_;
+  }
+  Trie* operator->()
+  {
+    return trie_;
+  }
+  const Trie* operator->() const
+  {
+    return trie_;
+  }
+  bool
+  operator==(trie_iterator<const Trie, NonConstTrie>& other) const
+  {
+    return (trie_ == other.trie_);
+  }
+  bool
+  operator==(trie_iterator<Trie, NonConstTrie>& other)
+  {
+    return (trie_ == other.trie_);
+  }
+  bool
+  operator!=(trie_iterator<const Trie, NonConstTrie>& other) const
+  {
+    return !(*this == other);
+  }
+  bool
+  operator!=(trie_iterator<Trie, NonConstTrie>& other)
+  {
+    return !(*this == other);
+  }
+
+  trie_iterator<Trie, NonConstTrie>&
+  operator++(int)
+  {
+    if (trie_->children_.size() > 0)
+      trie_ = &(*trie_->children_.begin());
     else
-      trie_ = goUp ();
+      trie_ = goUp();
     return *this;
   }
 
-  trie_iterator<Trie,NonConstTrie> &
-  operator++ ()
+  trie_iterator<Trie, NonConstTrie>&
+  operator++()
   {
     (*this)++;
     return *this;
   }
 
 private:
-  typedef typename boost::mpl::if_< boost::is_same<Trie, NonConstTrie>,
-                                    typename Trie::unordered_set::iterator,
-                                    typename Trie::unordered_set::const_iterator>::type set_iterator;
+  typedef typename boost::mpl::if_<boost::is_same<Trie, NonConstTrie>,
+                                   typename Trie::unordered_set::iterator,
+                                   typename Trie::unordered_set::const_iterator>::type set_iterator;
 
-  Trie* goUp ()
+  Trie*
+  goUp()
   {
-    if (trie_->parent_ != 0)
-      {
-        // typename Trie::unordered_set::iterator item =
-        set_iterator item = const_cast<NonConstTrie*>(trie_)->parent_->children_.iterator_to (const_cast<NonConstTrie&> (*trie_));
-        item++;
-        if (item != trie_->parent_->children_.end ())
-          {
-            return &(*item);
-          }
-        else
-          {
-            trie_ = trie_->parent_;
-            return goUp ();
-          }
+    if (trie_->parent_ != 0) {
+      // typename Trie::unordered_set::iterator item =
+      set_iterator item = const_cast<NonConstTrie*>(trie_)
+                            ->parent_->children_.iterator_to(const_cast<NonConstTrie&>(*trie_));
+      item++;
+      if (item != trie_->parent_->children_.end()) {
+        return &(*item);
       }
+      else {
+        trie_ = trie_->parent_;
+        return goUp();
+      }
+    }
     else
       return 0;
   }
+
 private:
-  Trie *trie_;
+  Trie* trie_;
 };
 
-
 template<class Trie>
-class trie_point_iterator
-{
+class trie_point_iterator {
 private:
-  typedef typename boost::mpl::if_< boost::is_same<Trie, const Trie>,
-                                    typename Trie::unordered_set::const_iterator,
-                                    typename Trie::unordered_set::iterator>::type set_iterator;
+  typedef typename boost::mpl::if_<boost::is_same<Trie, const Trie>,
+                                   typename Trie::unordered_set::const_iterator,
+                                   typename Trie::unordered_set::iterator>::type set_iterator;
 
 public:
-  trie_point_iterator () : trie_ (0) {}
-  trie_point_iterator (typename Trie::iterator item) : trie_ (item) {}
-  trie_point_iterator (Trie &item)
+  trie_point_iterator()
+    : trie_(0)
   {
-    if (item.children_.size () != 0)
-      trie_ = &*item.children_.begin ();
+  }
+  trie_point_iterator(typename Trie::iterator item)
+    : trie_(item)
+  {
+  }
+  trie_point_iterator(Trie& item)
+  {
+    if (item.children_.size() != 0)
+      trie_ = &*item.children_.begin();
     else
       trie_ = 0;
   }
 
-  Trie & operator* () { return *trie_; }
-  const Trie & operator* () const { return *trie_; }
-  Trie * operator-> () { return trie_; }
-  const Trie * operator-> () const { return trie_; }
-  bool operator== (trie_point_iterator<const Trie> &other) const { return (trie_ == other.trie_); }
-  bool operator== (trie_point_iterator<Trie> &other) { return (trie_ == other.trie_); }
-  bool operator!= (trie_point_iterator<const Trie> &other) const { return !(*this == other); }
-  bool operator!= (trie_point_iterator<Trie> &other) { return !(*this == other); }
-
-  trie_point_iterator<Trie> &
-  operator++ (int)
+  Trie& operator*()
   {
-    if (trie_->parent_ != 0)
-      {
-        set_iterator item = trie_->parent_->children_.iterator_to (*trie_);
-        item ++;
-        if (item == trie_->parent_->children_.end ())
-          trie_ = 0;
-        else
-          trie_ = &*item;
-      }
-    else
-      {
+    return *trie_;
+  }
+  const Trie& operator*() const
+  {
+    return *trie_;
+  }
+  Trie* operator->()
+  {
+    return trie_;
+  }
+  const Trie* operator->() const
+  {
+    return trie_;
+  }
+  bool
+  operator==(trie_point_iterator<const Trie>& other) const
+  {
+    return (trie_ == other.trie_);
+  }
+  bool
+  operator==(trie_point_iterator<Trie>& other)
+  {
+    return (trie_ == other.trie_);
+  }
+  bool
+  operator!=(trie_point_iterator<const Trie>& other) const
+  {
+    return !(*this == other);
+  }
+  bool
+  operator!=(trie_point_iterator<Trie>& other)
+  {
+    return !(*this == other);
+  }
+
+  trie_point_iterator<Trie>&
+  operator++(int)
+  {
+    if (trie_->parent_ != 0) {
+      set_iterator item = trie_->parent_->children_.iterator_to(*trie_);
+      item++;
+      if (item == trie_->parent_->children_.end())
         trie_ = 0;
-      }
+      else
+        trie_ = &*item;
+    }
+    else {
+      trie_ = 0;
+    }
     return *this;
   }
 
-  trie_point_iterator<Trie> &
-  operator++ ()
+  trie_point_iterator<Trie>&
+  operator++()
   {
     (*this)++;
     return *this;
   }
 
 private:
-  Trie *trie_;
+  Trie* trie_;
 };
 
-
 } // ndnSIM
 } // ndn
 } // ns3
