Making policy container more flexible
diff --git a/utils/fifo-policy.h b/utils/fifo-policy.h
index db6bd9f..afb0919 100644
--- a/utils/fifo-policy.h
+++ b/utils/fifo-policy.h
@@ -21,73 +21,84 @@
 #ifndef FIFO_POLICY_H_
 #define FIFO_POLICY_H_
 
-template<typename FullKey,
-	 typename Payload,
-         typename PayloadTraits
-         >
 struct fifo_policy_traits
 {
   typedef bi::list_member_hook<> policy_hook_type;
-  typedef trie< FullKey, Payload, PayloadTraits, policy_hook_type> parent_trie;
-  typedef typename bi::list< parent_trie,
-                             bi::member_hook< parent_trie,
-                                              policy_hook_type,
-                                              &parent_trie::policy_hook_ > > policy_container;
 
-  
-  class policy : public policy_container
+  template<class Container>
+  struct container_hook
   {
-  public:
-    policy ()
-      : max_size_ (100)
-    {
-    }
+    // could be class/struct implementation
+    typedef bi::member_hook< Container,
+                             policy_hook_type,
+                             &Container::policy_hook_ > type;
+  };
 
-    inline void
-    update (typename parent_trie::iterator item)
+  template<class Base,
+           class Container,
+           class Hook>
+  struct policy 
+  {
+    typedef typename bi::list< Container, Hook > policy_container;
+    
+    // could be just typedef
+    class type : public policy_container
     {
-      // do nothing
-    }
+    public:
+      typedef Container parent_trie;
+
+      type (Base &base)
+        : base_ (base)
+        , max_size_ (100)
+      {
+      }
+
+      inline void
+      update (typename parent_trie::iterator item)
+      {
+        // do nothing
+      }
   
-    inline void
-    insert (typename parent_trie::iterator item)
-    {
-      if (policy_container::size () >= max_size_)
-        {
-          typename parent_trie::iterator oldItem = &(*policy_container::begin ());
-          policy_container::pop_front ();
-          oldItem->erase ();
-        }
+      inline bool
+      insert (typename parent_trie::iterator item)
+      {
+        if (policy_container::size () >= max_size_)
+          {
+            base_.erase (&(*policy_container::begin ()));
+          }
       
-      policy_container::push_back (*item);
-    }
+        policy_container::push_back (*item);
+        return true;
+      }
   
-    inline void
-    lookup (typename parent_trie::iterator item)
-    {
-      // do nothing
-    }
+      inline void
+      lookup (typename parent_trie::iterator item)
+      {
+        // do nothing
+      }
   
-    inline void
-    erase (typename parent_trie::iterator item)
-    {
-      policy_container::erase (policy_container::s_iterator_to (*item));
-    }
+      inline void
+      erase (typename parent_trie::iterator item)
+      {
+        policy_container::erase (policy_container::s_iterator_to (*item));
+      }
 
-    inline void
-    set_max_size (size_t max_size)
-    {
-      max_size_ = max_size;
-    }
+      inline void
+      set_max_size (size_t max_size)
+      {
+        max_size_ = max_size;
+      }
 
-    inline size_t
-    get_max_size () const
-    {
-      return max_size_;
-    }
+      inline size_t
+      get_max_size () const
+      {
+        return max_size_;
+      }
 
-  private:
-    size_t max_size_;
+    private:
+      Base &base_;
+      size_t max_size_;
+    };
   };
 };
 
diff --git a/utils/lru-policy.h b/utils/lru-policy.h
index 2a9187d..14e49f7 100644
--- a/utils/lru-policy.h
+++ b/utils/lru-policy.h
@@ -21,79 +21,90 @@
 #ifndef LRU_POLICY_H_
 #define LRU_POLICY_H_
 
-template<typename FullKey,
-	 typename Payload,
-         typename PayloadTraits
-         >
 struct lru_policy_traits
 {
   typedef bi::list_member_hook<> policy_hook_type;
-  typedef trie< FullKey, Payload, PayloadTraits, policy_hook_type> parent_trie;
-  typedef typename bi::list< parent_trie,
-                             bi::member_hook< parent_trie,
-                                              policy_hook_type,
-                                              &parent_trie::policy_hook_ > > policy_container;
 
-  
-  class policy : public policy_container
+  template<class Container>
+  struct container_hook
   {
-  public:
-    policy ()
-      : max_size_ (100)
-    {
-    }
+    // could be class/struct implementation
+    typedef bi::member_hook< Container,
+                             policy_hook_type,
+                             &Container::policy_hook_ > type;
+  };
 
-    inline void
-    update (typename parent_trie::iterator item)
+  template<class Base,
+           class Container,
+           class Hook>
+  struct policy 
+  {
+    typedef typename bi::list< Container, Hook > policy_container;
+    
+    // could be just typedef
+    class type : public policy_container
     {
-      // do relocation
-      policy_container::splice (policy_container::end (),
-                                *this,
-                                policy_container::s_iterator_to (*item));
-    }
+    public:
+      typedef Container parent_trie;
+    
+      type (Base &base)
+        : base_ (base)
+        , max_size_ (100)
+      {
+      }
+
+      inline void
+      update (typename parent_trie::iterator item)
+      {
+        // do relocation
+        policy_container::splice (policy_container::end (),
+                                  *this,
+                                  policy_container::s_iterator_to (*item));
+      }
   
-    inline void
-    insert (typename parent_trie::iterator item)
-    {
-      if (policy_container::size () >= max_size_)
-        {
-          typename parent_trie::iterator oldItem = &(*policy_container::begin ());
-          policy_container::pop_front ();
-          oldItem->erase ();
-        }
+      inline bool
+      insert (typename parent_trie::iterator item)
+      {
+        if (policy_container::size () >= max_size_)
+          {
+            base_.erase (&(*policy_container::begin ()));
+          }
       
-      policy_container::push_back (*item);
-    }
+        policy_container::push_back (*item);
+        return true;
+      }
   
-    inline void
-    lookup (typename parent_trie::iterator item)
-    {
-      // do relocation
-      policy_container::splice (policy_container::end (),
-                                *this,
-                                policy_container::s_iterator_to (*item));
-    }
+      inline void
+      lookup (typename parent_trie::iterator item)
+      {
+        // do relocation
+        policy_container::splice (policy_container::end (),
+                                  *this,
+                                  policy_container::s_iterator_to (*item));
+      }
   
-    inline void
-    erase (typename parent_trie::iterator item)
-    {
-      policy_container::erase (policy_container::s_iterator_to (*item));
-    }
+      inline void
+      erase (typename parent_trie::iterator item)
+      {
+        policy_container::erase (policy_container::s_iterator_to (*item));
+      }
 
-    inline void
-    set_max_size (size_t max_size)
-    {
-      max_size_ = max_size;
-    }
+      inline void
+      set_max_size (size_t max_size)
+      {
+        max_size_ = max_size;
+      }
 
-    inline size_t
-    get_max_size () const
-    {
-      return max_size_;
-    }
+      inline size_t
+      get_max_size () const
+      {
+        return max_size_;
+      }
 
-  private:
-    size_t max_size_;
+    private:
+      Base &base_;
+      size_t max_size_;
+    };
   };
 };
 
diff --git a/utils/random-policy.h b/utils/random-policy.h
index 1f47f00..28a9800 100644
--- a/utils/random-policy.h
+++ b/utils/random-policy.h
@@ -23,89 +23,121 @@
 
 #include "ns3/random-variable.h"
 
-struct bla : public bi::set_member_hook<>
-{
-  uint32_t randomOrder;
-};
-
-template<class Key>
-struct MemberHookLess
-{
-  bool operator () (const Key &a, const Key &b) const
-  {
-    return a.policy_hook_.randomOrder < b.policy_hook_.randomOrder;
-  }
-};
-
-template<typename FullKey,
-	 typename Payload, typename PayloadTraits
-         >
 struct random_policy_traits
 {
-  typedef bla policy_hook_type;
-  typedef trie< FullKey, Payload, PayloadTraits, policy_hook_type > parent_trie;
-  typedef typename bi::set< parent_trie,
-                            bi::compare< MemberHookLess< parent_trie > >,
-                            bi::member_hook< parent_trie,
-                                             policy_hook_type,
-                                             &parent_trie::policy_hook_ > > policy_container;
+  struct policy_hook_type : public bi::set_member_hook<> { uint32_t randomOrder; };
 
-  class policy : public policy_container
+  template<class Container>
+  struct container_hook
   {
-  public:
-    policy ()
-      : u_rand (0, std::numeric_limits<uint32_t>::max ())
-      , max_size_ (100)
+    struct type
     {
-    }
+      typedef bi::member_hook< Container,
+                               policy_hook_type,
+                               &Container::policy_hook_ > hook_type;
 
-    inline void
-    update (typename parent_trie::iterator item)
+      static uint32_t& get_order (typename Container::iterator item)
+      {
+        return item->policy_hook_.randomOrder;
+      }
+      
+      static const uint32_t& get_order (typename Container::const_iterator item)
+      {
+        return item->policy_hook_.randomOrder;
+      }
+    };
+  };
+
+  template<class Base,
+           class Container,
+           class Hook>
+  struct policy 
+  {
+    template<class Key>
+    struct MemberHookLess
     {
-      // do nothing. it's random policy
-    }
+      bool operator () (const Key &a, const Key &b) const
+      {
+        return Hook::get_order (&a) < Hook::get_order (&b);
+      }
+    };
+
+    typedef bi::set< Container,
+                     bi::compare< MemberHookLess< Container > >,
+                     typename Hook::hook_type > policy_container;
+    
+    // could be just typedef
+    class type : public policy_container
+    {
+    public:
+      typedef Container parent_trie;
+
+      type (Base &base)
+        : base_ (base)
+        , u_rand (0, std::numeric_limits<uint32_t>::max ())
+        , max_size_ (100)
+      {
+      }
+
+      inline void
+      update (typename parent_trie::iterator item)
+      {
+        // do nothing. it's random policy
+      }
   
-    inline void
-    insert (typename parent_trie::iterator item)
-    {
-      item->policy_hook_.randomOrder = u_rand.GetValue ();
-      if (policy_container::size () >= max_size_)
-        {
-          typename parent_trie::iterator oldItem = &(*policy_container::begin ());
-          policy_container::erase (policy_container::begin ());
-          oldItem->erase ();
-        }
+      inline bool
+      insert (typename parent_trie::iterator item)
+      {
+        Hook::get_order (item) = u_rand.GetValue ();
 
-      policy_container::insert (*item);
-    }
+        if (policy_container::size () >= max_size_)
+          {
+            if (MemberHookLess<Container>() (*item, *policy_container::begin ()))
+              {
+                std::cout << "Cannot add. Signaling fail\n";
+                // just return false. Indicating that insert "failed"
+                return false;
+              }
+            else
+              {
+                // removing some random element
+                base_.erase (&(*policy_container::begin ()));
+              }
+          }
+
+        policy_container::insert (*item);
+        return true;
+      }
   
-    inline void
-    lookup (typename parent_trie::iterator item)
-    {
-      // do nothing. it's random policy
-    }
+      inline void
+      lookup (typename parent_trie::iterator item)
+      {
+        // do nothing. it's random policy
+      }
   
-    inline void
-    erase (typename parent_trie::iterator item)
-    {
-      policy_container::erase (policy_container::s_iterator_to (*item));
-    }
+      inline void
+      erase (typename parent_trie::iterator item)
+      {
+        policy_container::erase (policy_container::s_iterator_to (*item));
+      }
 
-    inline void
-    set_max_size (size_t max_size)
-    {
-      max_size_ = max_size;
-    }
+      inline void
+      set_max_size (size_t max_size)
+      {
+        max_size_ = max_size;
+      }
 
-    inline size_t
-    get_max_size () const
-    {
-      return max_size_;
-    }
+      inline size_t
+      get_max_size () const
+      {
+        return max_size_;
+      }
 
-  private:
-    ns3::UniformVariable u_rand;
-    size_t max_size_;
+    private:
+      Base &base_;
+      ns3::UniformVariable u_rand;
+      size_t max_size_;
+    };
   };
 };
 
diff --git a/utils/trie-with-policy.h b/utils/trie-with-policy.h
index a977285..46fbe69 100644
--- a/utils/trie-with-policy.h
+++ b/utils/trie-with-policy.h
@@ -22,22 +22,30 @@
 #define TRIE_WITH_POLICY_H_
 
 #include "trie.h"
-#include "lru-policy.h"
 
 template<typename FullKey,
-	 typename Payload,
          typename PayloadTraits,
          typename PolicyTraits
          >
 class trie_with_policy
 {
 public:
-  typedef trie< FullKey, Payload, PayloadTraits, typename PolicyTraits::policy_hook_type > parent_trie;
-  typedef typename parent_trie::iterator          iterator;
+  typedef trie< FullKey,
+                typename PayloadTraits::payload_type,
+                PayloadTraits,
+                typename PolicyTraits::policy_hook_type > parent_trie;
+
+  typedef typename parent_trie::iterator iterator;
+
+  typedef typename PolicyTraits::template policy<
+    trie_with_policy<FullKey, PayloadTraits, PolicyTraits>,
+    parent_trie,
+    typename PolicyTraits::template container_hook<parent_trie>::type >::type policy_container;
 
   inline
   trie_with_policy (size_t bucketSize = 10, size_t bucketIncrement = 10)
     : trie_ ("", bucketSize, bucketIncrement)
+    , policy_ (*this)
   {
   }
 
@@ -49,7 +57,12 @@
 
     if (item.second) // real insert
       {
-        policy_.insert (s_iterator_to (item.first));
+        bool ok = policy_.insert (s_iterator_to (item.first));
+        if (!ok)
+          {
+            item.first->erase (); // cannot insert
+            return std::make_pair (end (), false);
+          }
       }
     else
       {
@@ -142,60 +155,6 @@
         return trie_.end ();
       }
   }
-  
-  // /**
-  //  * @brief Perform the longest prefix match
-  //  * @param key the key for which to perform the longest prefix match
-  //  *
-  //  * @return ->second is true if prefix in ->first is longer than key
-  //  *         ->third is always last node searched
-  //  */
-  // inline boost::tuple< iterator, bool, iterator >
-  // find (const FullKey &key)
-  // {
-  //   boost::tuple< iterator, bool, iterator > item = trie_.find (key);
-  //   if (item.template get<0> () != trie_.end ())
-  //     {
-  //       policy_.lookup (s_iterator_to (item.template get<0> ()));
-  //     }
-  //   return boost::make_tuple (s_iterator_to (item.template get<0> ()),
-  //                             item.template get<1> (),
-  //                             s_iterator_to (item.template get<2> ()));
-  // }
-
-  // /**
-  //  * @brief Find next payload of the sub-trie
-  //  * @param start Start for the search (root for the sub-trie)
-  //  * @returns end() or a valid iterator pointing to the trie leaf (order is not defined, enumeration )
-  //  */
-  // inline iterator
-  // find (iterator start)
-  // {
-  //   iterator item = start->find ();
-  //   if (item != trie_.end ())
-  //     {
-  //       policy_.lookup (s_iterator_to (item));
-  //     }
-  //   return item;
-  // }
-
-  // /**
-  //  * @brief Find next payload of the sub-trie satisfying the predicate
-  //  * @param start Start for the search (root for the sub-trie)
-  //  * @param pred predicate
-  //  * @returns end() or a valid iterator pointing to the trie leaf (order is not defined, enumeration )
-  //  */
-  // template<class Predicate>
-  // inline iterator
-  // find_if (iterator start, Predicate pred)
-  // {
-  //   iterator item = start->find (pred);
-  //   if (item != trie_.end ())
-  //     {
-  //       policy_.lookup (s_iterator_to (item));
-  //     }
-  //   return item;
-  // }
 
   iterator end ()
   {
@@ -205,10 +164,10 @@
   const parent_trie &
   getTrie () const { return trie_; }
 
-  const typename PolicyTraits::policy &
+  const policy_container &
   getPolicy () const { return policy_; }
 
-  typename PolicyTraits::policy &
+  policy_container &
   getPolicy () { return policy_; }
 
   static inline iterator
@@ -222,7 +181,7 @@
   
 private:
   parent_trie      trie_;
-  typename PolicyTraits::policy policy_;
+  policy_container policy_;
 };
 
 
diff --git a/utils/trie.h b/utils/trie.h
index 5d440d2..ebaa921 100644
--- a/utils/trie.h
+++ b/utils/trie.h
@@ -38,6 +38,7 @@
 template<typename Payload>
 struct pointer_payload_traits
 {
+  typedef Payload         payload_type;
   typedef Payload*        pointer_type;
   typedef const Payload*  const_pointer_type;
 
@@ -51,6 +52,7 @@
 template<typename Payload>
 struct smart_pointer_payload_traits
 {
+  typedef Payload                 payload_type;
   typedef ns3::Ptr<Payload>       pointer_type;
   typedef ns3::Ptr<const Payload> const_pointer_type;