diff --git a/utils/trie.h b/utils/trie.h
index 86ca01f..1b2056e 100644
--- a/utils/trie.h
+++ b/utils/trie.h
@@ -30,6 +30,7 @@
 #include <boost/interprocess/smart_ptr/unique_ptr.hpp>
 #include <boost/tuple/tuple.hpp>
 #include <boost/foreach.hpp>
+#include <boost/mpl/if.hpp>
 
 namespace ndnSIM
 {
@@ -92,7 +93,8 @@
 ///////////////////////////////////////////////////
 // actual definition
 //
-
+template<class T>
+class trie_iterator;
 
 template<typename FullKey,
 	 typename Payload, typename PayloadTraits,
@@ -104,18 +106,52 @@
 
   typedef trie*       iterator;
   typedef const trie* const_iterator;
+
+  typedef trie_iterator<trie> recursive_iterator;
+  typedef trie_iterator<const trie> const_recursive_iterator;
   
   inline
-  trie (const Key &key, size_t bucketSize = 10, size_t bucketIncrement = 10);
+  trie (const Key &key, size_t bucketSize = 10, size_t bucketIncrement = 10)
+    : 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 ();
+  ~trie ()
+  {
+    payload_ = PayloadTraits::empty_payload; // necessary for smart pointers...
+    children_.clear_and_dispose (trie_delete_disposer ());
+  }
 
   void
   clear ()
   {
     children_.clear_and_dispose (trie_delete_disposer ());
   }
+
+  template<class Predicate>
+  void
+  clear_if (Predicate cond)
+  {
+    recursive_iterator trieNode (this);
+    recursive_iterator end (0);
+
+    while (trieNode != end)
+      {
+        if (cond (*trieNode))
+          {
+            trieNode = recursive_iterator (trieNode->erase ());
+          }
+        trieNode ++;
+      }
+  }
   
   // actual entry
   friend bool
@@ -127,19 +163,73 @@
 
   inline std::pair<iterator, bool>
   insert (const FullKey &key,
-          typename PayloadTraits::pointer_type payload);
+          typename PayloadTraits::pointer_type payload)
+  {
+    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;
+
+            if (trieNode->children_.size () >= trieNode->bucketSize_)
+              {
+                trieNode->bucketSize_ += trieNode->bucketIncrement_;
+                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);
+	  
+            trieNode = &(*ret.first);
+          }
+        else
+          trieNode = &(*item);
+      }
+
+    if (trieNode->payload_ == PayloadTraits::empty_payload)
+      {
+        trieNode->payload_ = payload;
+        return std::make_pair (trieNode, true);
+      }
+    else
+      return std::make_pair (trieNode, false);
+  }
 
   /**
    * @brief Removes payload (if it exists) and if there are no children, prunes parents trie
    */
-  inline void
-  erase ();
+  inline iterator
+  erase ()
+  {
+    payload_ = PayloadTraits::empty_payload;
+    return prune ();
+  }
 
   /**
    * @brief Do exactly as erase, but without erasing the payload
    */
-  inline void
-  prune ();
+  inline iterator
+  prune ()
+  {
+    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
+
+        return parent->prune ();
+      }
+    return this;
+  }
 
   inline boost::tuple<const iterator, bool, const iterator>
   find (const FullKey &key) const
@@ -154,14 +244,55 @@
    * @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;
+    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;
+          }
+      }
+
+    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 )
    */
   inline iterator
-  find ();
+  find ()
+  {
+    if (payload_ != PayloadTraits::empty_payload)
+      return this;
+
+    typedef trie<FullKey, Payload, 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;
+      }
+  
+    return 0;
+  }
 
   /**
    * @brief Find next payload of the sub-trie satisfying the predicate
@@ -170,7 +301,24 @@
    */
   template<class Predicate>
   inline iterator
-  find_if (Predicate pred);
+  find_if (Predicate pred)
+  {
+    if (payload_ != PayloadTraits::empty_payload && pred (payload_))
+      return this;
+
+    typedef trie<FullKey, Payload, 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 (value != 0)
+          return value;
+      }
+  
+    return 0;
+  }
 
   iterator end ()
   {
@@ -209,7 +357,6 @@
   {
     void operator() (trie *delete_this)
     {
-      // std::cout << "Deleting " << delete_this << "\n";
       delete delete_this;
     }
   };
@@ -238,10 +385,14 @@
   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 typename unordered_set::bucket_traits bucket_traits;
 
+  template<class T>
+  friend class trie_iterator;
+  
   ////////////////////////////////////////////////
   // Actual data
   ////////////////////////////////////////////////
@@ -260,173 +411,8 @@
   trie *parent_; // to make cleaning effective
 };
 
-template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
-trie<FullKey, Payload, PayloadTraits, PolicyHook>
-::trie (const trie::Key &key, size_t bucketSize, size_t bucketIncrement)
-  : 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)
-{
-}
-
-template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
-trie<FullKey, Payload, PayloadTraits, PolicyHook>
-::~trie ()
-{
-  payload_ = PayloadTraits::empty_payload; // necessary for smart pointers...
-  children_.clear_and_dispose (trie_delete_disposer ());
-}
-
-template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
-inline
-std::pair<typename trie<FullKey, Payload, PayloadTraits, PolicyHook>::iterator, bool>
-trie<FullKey, Payload, PayloadTraits, PolicyHook>
-::insert (const FullKey &key, typename PayloadTraits::pointer_type payload)
-{
-  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;
-
-	  if (trieNode->children_.size () >= trieNode->bucketSize_)
-	    {
-	      trieNode->bucketSize_ += trieNode->bucketIncrement_;
-              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);
-	  
-	  trieNode = &(*ret.first);
-	}
-      else
-	trieNode = &(*item);
-    }
-
-  if (trieNode->payload_ == 0)
-    {
-      trieNode->payload_ = payload;
-      return std::make_pair (trieNode, true);
-    }
-  else
-    return std::make_pair (trieNode, false);
-}
-
-template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
-inline
-boost::tuple<typename trie<FullKey, Payload, PayloadTraits, PolicyHook>::iterator,
-	     bool,
-	     typename trie<FullKey, Payload, PayloadTraits, PolicyHook>::iterator>
-trie<FullKey, Payload, PayloadTraits, PolicyHook>
-::find (const FullKey &key)
-{
-  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;
-	}
-    }
-
-  return boost::make_tuple (foundNode, reachLast, trieNode);  
-}
-
-template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
-inline typename trie<FullKey, Payload, PayloadTraits, PolicyHook>::iterator
-trie<FullKey, Payload, PayloadTraits, PolicyHook>
-::find ()
-{
-  if (payload_ != PayloadTraits::empty_payload)
-    return this;
-
-  typedef trie<FullKey, Payload, 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;
-    }
-  
-  return 0;
-}
-
-template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
-template<class Predicate>
-inline typename trie<FullKey, Payload, PayloadTraits, PolicyHook>::iterator
-trie<FullKey, Payload, PayloadTraits, PolicyHook>
-::find_if (Predicate pred)
-{
-  if (payload_ != PayloadTraits::empty_payload && pred (payload_))
-    return this;
-
-  typedef trie<FullKey, Payload, 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 (value != 0)
-        return value;
-    }
-  
-  return 0;
-}
 
 
-template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
-inline void
-trie<FullKey, Payload, PayloadTraits, PolicyHook>
-::erase ()
-{
-  payload_ = PayloadTraits::empty_payload;
-  prune ();
-}
-
-template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
-inline void
-trie<FullKey, Payload, PayloadTraits, PolicyHook>
-::prune ()
-{
-  if (payload_ == 0 && 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
-
-      parent->prune ();
-    }
-}
 
 template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
 inline std::ostream&
@@ -490,6 +476,72 @@
   return boost::hash_value (trie_node.key_);
 }
 
+
+
+template<class Trie>
+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> &other) const { return (trie_ == other.trie_); }
+  bool operator== (trie_iterator<Trie> &other) { return (trie_ == other.trie_); }
+  bool operator!= (trie_iterator<const Trie> &other) const { return !(*this == other); }
+  bool operator!= (trie_iterator<Trie> &other) { return !(*this == other); }
+  
+  trie_iterator<Trie> &
+  operator++ (int)
+  {
+    if (trie_->children_.size () > 0)
+      trie_ = &(*trie_->children_.begin ());
+    else
+      trie_ = goUp ();
+    return *this;
+  }
+
+  trie_iterator<Trie> &
+  operator++ ()
+  {
+    (*this)++;
+    return *this;
+  }  
+
+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;
+  
+  Trie* goUp ()
+  {
+    if (trie_->parent_ != 0)
+      {
+        // typename Trie::unordered_set::iterator item =
+        set_iterator item = trie_->parent_->children_.iterator_to (*trie_);
+        item++;
+        if (item != trie_->parent_->children_.end ())
+          {
+            return &(*item);
+          }
+        else
+          {
+            trie_ = trie_->parent_;
+            return goUp ();
+          }
+      }
+    else
+      return 0;
+  }
+private:
+  Trie *trie_;
+};
+
+
 } // ndnSIM
 
 #endif // TRIE_H_
