Correcting everything to the stage that everything compiles
diff --git a/examples/ccnx-grid.cc b/examples/ccnx-grid.cc
index 9d6454a..618bf74 100644
--- a/examples/ccnx-grid.cc
+++ b/examples/ccnx-grid.cc
@@ -47,7 +47,7 @@
 {
   Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("1Mbps"));
   Config::SetDefault ("ns3::PointToPointChannel::Delay", StringValue ("1ms"));
-  Config::SetDefault ("ns3::CcnxConsumer::OffTime", StringValue ("1ms"));
+  Config::SetDefault ("ns3::CcnxConsumer::OffTime", StringValue ("1s"));
     
   Packet::EnableChecking();
   Packet::EnablePrinting();
diff --git a/examples/interest-header-example.cc b/examples/interest-header-example.cc
index 080e5a5..6964440 100644
--- a/examples/interest-header-example.cc
+++ b/examples/interest-header-example.cc
@@ -72,8 +72,7 @@
   uint32_t randomNonce = static_cast<uint32_t> (random.GetValue());
   interestHeader.SetNonce(randomNonce);
     
-  interestHeader.SetNack(true);
-  interestHeader.SetCongested(true);
+  interestHeader.SetNack(CcnxInterestHeader::NACK_CONGESTION);
   NS_LOG_INFO ("Source: \n" << interestHeader);
     
   packet.AddHeader (interestHeader);
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
index 1964ac7..c436923 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
@@ -177,6 +177,7 @@
                boost::any_cast<uint32_t> (
                                           (*n.m_nestedTags.begin())->accept(nonNegativeIntegerVisitor)));
       break;
+    }
 }
 
 } // namespace CcnbParser
diff --git a/helper/ccnx-encoding-helper.cc b/helper/ccnx-encoding-helper.cc
index f486c01..15757fc 100644
--- a/helper/ccnx-encoding-helper.cc
+++ b/helper/ccnx-encoding-helper.cc
@@ -156,16 +156,10 @@
     {
       written += EstimateTaggedBlob (CcnbParser::CCN_DTAG_Nonce, sizeof(uint32_t));
     }
-  if (interest.IsNack () )
+  if (interest.GetNack ()>0)
     {
-        written += EstimateBlockHeader (CcnbParser::NDN_DTAG_Nack);
-        written += EstimateNumber (1);
-        written += 1;
-    }
-  if (interest.IsCongested () )
-    {
-        written += EstimateBlockHeader (CcnbParser::NDN_DTAG_Congested);
-        written += EstimateNumber (1);
+        written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Nack);
+        written += EstimateNumber (interest.GetNack ());
         written += 1;
     }
 
diff --git a/helper/ccnx-stack-helper.cc b/helper/ccnx-stack-helper.cc
index f8f0405..3bc5ce9 100644
--- a/helper/ccnx-stack-helper.cc
+++ b/helper/ccnx-stack-helper.cc
@@ -85,6 +85,10 @@
 #include <map>
 #include <boost/foreach.hpp>
 
+#define NDN_DEFAULT_DATA_SIZE      1024
+#define NDN_INTEREST_RESET_PERIOD  Seconds(0.01)
+
+
 NS_LOG_COMPONENT_DEFINE ("CcnxStackHelper");
 
 namespace ns3 {
@@ -222,19 +226,17 @@
       NS_LOG_INFO("DataRate for this link is " << dataRate.Get());
       pit->maxBucketsPerFace[face->GetId()] = 0.1 * dataRate.Get().GetBitRate () /(NDN_DEFAULT_DATA_SIZE + sizeof(CcnxInterestHeader));
       NS_LOG_INFO("maxBucketsPerFace["<<face->GetId()<<"] = " << pit->maxBucketsPerFace[face->GetId()]); 
-      pit->leakSize[face->GetId()] = 0.97 * NDN_INTEREST_RESET_PERIOD / SECOND * dataRate.Get().GetBitRate () / (NDN_DEFAULT_DATA_SIZE + sizeof(CcnxInterestHeader));
+      pit->leakSize[face->GetId()] = 0.97 * NDN_INTEREST_RESET_PERIOD.ToDouble(Time::S) * dataRate.Get().GetBitRate () / (NDN_DEFAULT_DATA_SIZE + sizeof(CcnxInterestHeader));
       NS_LOG_INFO("pit->leakSize["<<face->GetId()<<"] = " << pit->leakSize[face->GetId()]);
         
-        
-      if(face->IsLocal()==true)
-        NS_LOG_INFO("Face #" << face_id << " is turned on");
+      NS_LOG_INFO("Face #" << face_id << " is turned on");
       face->SetUp ();
       faces->Add (face);
     }
     
   m_forwardingHelper.SetForwarding (ccnx, pit);
 
-  ccnx->ScheduleLeakage ();
+  // ccnx->ScheduleLeakage ();
     
   return faces;
 }
diff --git a/model/ccnx-bestroute-strategy.cc b/model/ccnx-bestroute-strategy.cc
index 625b6d7..4e592c7 100644
--- a/model/ccnx-bestroute-strategy.cc
+++ b/model/ccnx-bestroute-strategy.cc
@@ -19,29 +19,23 @@
  */
 
 #include "ccnx-bestroute-strategy.h"
+#include "ccnx-interest-header.h"
+
 #include "ns3/assert.h"
-
-#include "ccnx-route.h"
-
+#include "ns3/log.h"
 
 NS_LOG_COMPONENT_DEFINE ("CcnxBestRouteStrategy");
-namespace __ccnx_private {
-    
-    struct CcnxFibFaceMetricByFace;
-}
 
 namespace ns3 
 {
     
-using namespace __ccnx_private;
-    
 NS_OBJECT_ENSURE_REGISTERED (CcnxBestRouteStrategy);
   
 TypeId CcnxBestRouteStrategy::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::CcnxBestRouteStrategy")
   .SetGroupName ("Ccnx")
-  .SetParent<Object> ()
+  .SetParent<CcnxForwardingStrategy> ()
   ;
   return tid;
 }
@@ -50,50 +44,42 @@
 {
 }
     
-    
 bool
-CcnxBestRouteStrategy::PropagateInterest (CcnxPitEntryContainer::type::iterator pitEntry, 
-                                          CcnxFibEntryContainer::type::iterator fibEntry,
+CcnxBestRouteStrategy::PropagateInterest (const CcnxPitEntry  &pitEntry, 
                                           const Ptr<CcnxFace> &incomingFace,
                                           Ptr<CcnxInterestHeader> &header,
                                           const Ptr<const Packet> &packet,
-                                          SendCallback ucb)
+                                          SendCallback sendCallback)
 {
-  //NS_LOG_FUNCTION(this);
-  //NS_LOG_INFO(*fibEntry);
-    
-  Ptr<CcnxFace> bestFace = fibEntry->FindBestCandidate(0);
-   
-  if( bestFace == NULL )
+  NS_LOG_FUNCTION (this);
+  bool forwardedCount = 0;
+
+  try
     {
-      return false;
+      for (uint32_t skip = 0; skip < pitEntry.m_fibEntry.m_faces.size (); skip++)
+        {
+          const CcnxFibFaceMetric bestMetric = pitEntry.m_fibEntry.FindBestCandidate (skip);
+
+          if (bestMetric.m_status == CcnxFibFaceMetric::NDN_FIB_RED) // no point to send there
+            continue;
+
+          if (pitEntry.m_outgoing.find (bestMetric.m_face) != pitEntry.m_outgoing.end ()) // already forwarded before
+            continue;
+
+          bool faceAvailable = m_pit->TryAddOutgoing (pitEntry, bestMetric.m_face);
+          if (!faceAvailable) // huh...
+            continue;
+
+          sendCallback (bestMetric.m_face, header, packet->Copy());
+          forwardedCount++;
+          break; // if we succeeded in sending one packet, stop
+        }
     }
-  else
+  catch (CcnxFibEntry::NoFaces)
     {
-      bool tryResult = GetPit ()->TryAddOutgoing (pitEntry, bestFace);
-      if (tryResult == false)
-      {
-          NS_LOG_INFO("!!!!!!!!!!!!!Trying different face!!!!!!!!!!!!!!!!");
-          for(uint32_t i = 1; i<fibEntry->m_faces.size(); i++ )
-          {
-            bestFace = fibEntry->FindBestCandidate(i);
-            tryResult = GetPit ()->TryAddOutgoing (pitEntry, bestFace);
-            if(tryResult == true)
-              break;
-              NS_LOG_INFO("Trying different face");
-          }
-          
-          if(tryResult == false)
-          {
-              NS_LOG_INFO("FAILURE");
-              return false;
-          }
-      }
-          
-      ucb (bestFace, header, packet->Copy());
     }
-     
-  return true;
+
+  return forwardedCount > 0;
 }
     
 } //namespace ns3
diff --git a/model/ccnx-bestroute-strategy.h b/model/ccnx-bestroute-strategy.h
index d6f9a5a..4e5eb6c 100644
--- a/model/ccnx-bestroute-strategy.h
+++ b/model/ccnx-bestroute-strategy.h
@@ -22,14 +22,7 @@
 #ifndef CCNX_BESTROUTE_STRATEGY_H
 #define CCNX_BESTROUTE_STRATEGY_H
 
-#include "ns3/packet.h"
-#include "ns3/callback.h"
-#include "ns3/object.h"
-#include "ns3/log.h"
-
 #include "ccnx-forwarding-strategy.h"
-#include "ccnx.h"
-#include "ccnx-fib.h"
 
 namespace ns3 
 {
@@ -40,22 +33,26 @@
 /**
  * \ingroup ccnx
  * \brief Best route strategy
+ *
+ * \todo Describe
  */
-    
 class CcnxBestRouteStrategy : public CcnxForwardingStrategy
 {
 public:
   static TypeId GetTypeId (void);
-        
+
+  /**
+   * @brief Default constructor
+   */
   CcnxBestRouteStrategy ();
         
+  // inherited from  CcnxForwardingStrategy
   virtual bool
-  PropagateInterest  (CcnxPitEntryContainer::type::iterator pitEntry,
-                      CcnxFibEntryContainer::type::iterator fibEntry,
-                      const Ptr<CcnxFace> &incomingFace,
-                      Ptr<CcnxInterestHeader> &header,
-                      const Ptr<const Packet> &packet,
-                      SendCallback ucb);
+  PropagateInterest (const CcnxPitEntry  &pitEntry, 
+                     const Ptr<CcnxFace> &incomingFace,
+                     Ptr<CcnxInterestHeader> &header,
+                     const Ptr<const Packet> &packet,
+                     SendCallback sendCallback);
 };
 
 } //namespace ns3
diff --git a/model/ccnx-content-store.cc b/model/ccnx-content-store.cc
index 9232ebc..4875386 100644
--- a/model/ccnx-content-store.cc
+++ b/model/ccnx-content-store.cc
@@ -150,7 +150,7 @@
 }
 
 
-boost::tuple<Ptr<Packet>, Ptr<CcnxContentObjectHeader> >
+boost::tuple<Ptr<Packet>, Ptr<const CcnxContentObjectHeader> >
 CcnxContentStore::Lookup (Ptr<const CcnxInterestHeader> interest)
 {
   NS_LOG_FUNCTION_NOARGS ();
diff --git a/model/ccnx-content-store.h b/model/ccnx-content-store.h
index df92e1c..dd0f884 100644
--- a/model/ccnx-content-store.h
+++ b/model/ccnx-content-store.h
@@ -174,7 +174,7 @@
    * If an entry is found, it is promoted to the top of most recent
    * used entries index, \see m_contentStore
    */
-  boost::tuple<Ptr<Packet>, Ptr<CcnxContentObjectHeader> >
+  boost::tuple<Ptr<Packet>, Ptr<const CcnxContentObjectHeader> >
   Lookup (Ptr<const CcnxInterestHeader> interest);
             
   /**
diff --git a/model/ccnx-fib.cc b/model/ccnx-fib.cc
index 9f23a83..a2d8b4b 100644
--- a/model/ccnx-fib.cc
+++ b/model/ccnx-fib.cc
@@ -38,7 +38,7 @@
 
 #include <boost/lambda/lambda.hpp>
 
-using namespace boost::lambda;
+using namespace boost;
 
 //#define NDN_DUMP_FIB		0
 namespace ns3 {
@@ -100,42 +100,60 @@
 /////////////////////////////////////////////////////////////////////
 
 void
-CcnxFibEntry::UpdateStatus (const CcnxFace &face, CcnxFibFaceMetric::Status status)
+CcnxFibEntry::UpdateFaceRtt (Ptr<CcnxFace> face, const Time &sample)
 {
   CcnxFibFaceMetricByFace::type::iterator record = m_faces.get<i_face> ().find (face);
   NS_ASSERT_MSG (record != m_faces.get<i_face> ().end (),
                  "Update status can be performed only on existing faces of CcxnFibEntry");
 
-  m_faces.modify (record, _1->m_status = status);
+  m_faces.modify (record,
+                  bind (&CcnxFibFaceMetric::UpdateRtt, lambda::_1, sample));
 
   // reordering random access index same way as by metric index
   m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
 }
 
-// void
-// CcnxFibEntry::AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric)
-// {
-//   NS_LOG_FUNCTION(this);
-//   NS_ASSERT_MSG (m_face != NULL, "Trying to Add or Update NULL face");
-
-//   CcnxFibFaceMetricByFace::type::iterator record = entry.m_faces.get<i_face> ().find (m_face);
-//   if (record == entry.m_faces.get<i_face> ().end ())
-//     {
-//       entry.m_faces.insert (CcnxFibFaceMetric (m_face, m_metric));
-//     }
-//   else
-//   {
-//       entry.m_faces.modify (record, ChangeMetric (m_metric));
-//     }
-//   // reordering random access index same way as by metric index
-//   entry.m_faces.get<i_nth> ().rearrange (entry.m_faces.get<i_metric> ().begin ());
-// }
-
-Ptr<CcnxFace>
-CcnxFibEntry::FindBestCandidate (int skip/* = 0*/) const
+void
+CcnxFibEntry::UpdateStatus (Ptr<CcnxFace> face, CcnxFibFaceMetric::Status status)
 {
+  CcnxFibFaceMetricByFace::type::iterator record = m_faces.get<i_face> ().find (face);
+  NS_ASSERT_MSG (record != m_faces.get<i_face> ().end (),
+                 "Update status can be performed only on existing faces of CcxnFibEntry");
+
+  m_faces.modify (record,
+                  (&lambda::_1)->*&CcnxFibFaceMetric::m_status = status);
+
+  // reordering random access index same way as by metric index
+  m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
+}
+
+void
+CcnxFibEntry::AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric)
+{
+  NS_LOG_FUNCTION (this);
+  NS_ASSERT_MSG (face != NULL, "Trying to Add or Update NULL face");
+
+  CcnxFibFaceMetricByFace::type::iterator record = m_faces.get<i_face> ().find (face);
+  if (record == m_faces.get<i_face> ().end ())
+    {
+      m_faces.insert (CcnxFibFaceMetric (face, metric));
+    }
+  else
+  {
+    m_faces.modify (record,
+                    (&lambda::_1)->*&CcnxFibFaceMetric::m_routingCost = metric);
+  }
+  
+  // reordering random access index same way as by metric index
+  m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
+}
+
+const CcnxFibFaceMetric &
+CcnxFibEntry::FindBestCandidate (uint32_t skip/* = 0*/) const
+{
+  if (m_faces.size () == 0) throw CcnxFibEntry::NoFaces ();
   skip = skip % m_faces.size();
-  return m_faces.get<i_nth> () [skip].GetFace ();
+  return m_faces.get<i_nth> () [skip];
 }
 
 
@@ -192,7 +210,8 @@
     }
 
   NS_ASSERT_MSG (face != NULL, "Trying to modify NULL face");
-  modify (entry, CcnxFibEntry::AddOrUpdateRoutingMetric (face, metric));
+  modify (entry,
+          bind (&CcnxFibEntry::AddOrUpdateRoutingMetric, lambda::_1, face, metric));
     
   return entry;
 }
diff --git a/model/ccnx-fib.h b/model/ccnx-fib.h
index 4410b59..2bd131c 100644
--- a/model/ccnx-fib.h
+++ b/model/ccnx-fib.h
@@ -150,6 +150,8 @@
 class CcnxFibEntry : public SimpleRefCount<CcnxFibEntry>
 {
 public:
+  class NoFaces {};
+  
   /**
    * \brief Constructor
    * \param prefix Prefix for the FIB entry
@@ -163,16 +165,22 @@
    * \brief Update status of FIB next hop
    * \param status Status to set on the FIB entry
    */
-  void UpdateStatus (const CcnxFace &face, CcnxFibFaceMetric::Status status);
+  void UpdateStatus (Ptr<CcnxFace> face, CcnxFibFaceMetric::Status status);
 
-  // /**
-  //  * \brief Add or update routing metric of FIB next hop
-  //  *
-  //  * Initial status of the next hop is set to YELLOW
-  //  */
-  // void AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric);
+  /**
+   * \brief Add or update routing metric of FIB next hop
+   *
+   * Initial status of the next hop is set to YELLOW
+   */
+  void AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric);
 
   /**
+   * @brief Update RTT averages for the face
+   */
+  void
+  UpdateFaceRtt (Ptr<CcnxFace> face, const Time &sample);
+  
+  /**
    * \brief Get prefix for the FIB entry
    */
   const CcnxNameComponents&
@@ -180,9 +188,11 @@
 
   /**
    * \brief Find "best route" candidate, skipping `skip' first candidates (modulo # of faces)
+   *
+   * throws CcnxFibEntry::NoFaces if m_faces.size()==0
    */
-  Ptr<CcnxFace>
-    FindBestCandidate (int skip = 0) const;
+  const CcnxFibFaceMetric &
+  FindBestCandidate (uint32_t skip = 0) const;
 	
 private:
   friend std::ostream& operator<< (std::ostream& os, const CcnxFibEntry &entry);
diff --git a/model/ccnx-flooding-strategy.cc b/model/ccnx-flooding-strategy.cc
index 83ddd7e..d7f6827 100644
--- a/model/ccnx-flooding-strategy.cc
+++ b/model/ccnx-flooding-strategy.cc
@@ -20,8 +20,10 @@
 
 #include "ccnx-flooding-strategy.h"
 #include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ccnx-interest-header.h"
 
-#include "ccnx-route.h"
+#include <boost/foreach.hpp>
 
 NS_LOG_COMPONENT_DEFINE ("CcnxFloodingStrategy");
 
@@ -32,116 +34,47 @@
     
 TypeId CcnxFloodingStrategy::GetTypeId (void)
 {
-    static TypeId tid = TypeId ("ns3::CcnxFloodingStrategy")
+  static TypeId tid = TypeId ("ns3::CcnxFloodingStrategy")
     .SetGroupName ("Ccnx")
-    .SetParent<Object> ()
+    .SetParent<CcnxForwardingStrategy> ()
     ;
-    return tid;
+  return tid;
 }
     
 CcnxFloodingStrategy::CcnxFloodingStrategy ()
 {
 }
-    
-    
+
 bool
-CcnxFloodingStrategy::PropagateInterest  (CcnxPitEntryContainer::type::iterator pitEntry, 
-                                          CcnxFibEntryContainer::type::iterator fibEntry,
-                                          const Ptr<CcnxFace> &incomingFace,
-                                          Ptr<CcnxInterestHeader> &header,
-                                          const Ptr<const Packet> &packet,
-                                          SendCallback ucb)
+CcnxFloodingStrategy::PropagateInterest (const CcnxPitEntry  &pitEntry, 
+                                         const Ptr<CcnxFace> &incomingFace,
+                                         Ptr<CcnxInterestHeader> &header,
+                                         const Ptr<const Packet> &packet,
+                                         SendCallback sendCallback)
 {
-    //CcnxFibEntryContainer::type::iterator fibEntryArray = GetFib()->LongestPrefixMatch(*header);
-    NS_LOG_FUNCTION(this);
+  NS_LOG_FUNCTION (this);
     
-    //CcnxFibEntryContainer::type::iterator fibEntryArray = GetCcnx()->GetObject<CcnxFib>()->LongestPrefixMatch(*header);
-    NS_LOG_INFO(*fibEntry);
-    
-    int count = 0;
-    for(CcnxFibFaceMetricContainer::type::iterator face = fibEntry->m_faces.begin ();
-        face != fibEntry->m_faces.end ();
-        face++)
+  int propagatedCount = 0;
+  BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry.m_fibEntry.m_faces)
     {
-        if(face->m_face == incomingFace)
-            continue;
-        NS_LOG_INFO ("JUST before try add outgoing");
-        //Add new outgoing interest to pit entry
-		// If PIT entry cannot be created (limit reached or interest already sent), nothing will be forwarded
-		//if( _pit.add(VALUE(info.pe), PitOutgoingInterest( *iface, getSimTime(_node), pkt->nonce )) )
-		//{
-        //GetPit()->Add(*header,fibEntry,face->m_face);
-        //GetPit()->modify (GetPit()->end (), CcnxPitEntry::AddOutgoing(face->m_face));
-        bool tryResult = GetPit ()->TryAddOutgoing (pitEntry, face->m_face);
-        if ( tryResult == false )
-        {NS_LOG_INFO("false");
-            continue;
-        }
-        else
-            NS_LOG_INFO("true");
+      if (metricFace.m_status == CcnxFibFaceMetric::NDN_FIB_RED) // all non-read faces are in front
+        break;
+      
+      if (metricFace.m_face == incomingFace) // same face as incoming, don't forward
+        continue;
+
+      if (pitEntry.m_outgoing.find (metricFace.m_face) != pitEntry.m_outgoing.end ()) // already forwarded before
+        continue;
+
+      bool faceAvailable = m_pit->TryAddOutgoing (pitEntry, metricFace.m_face);
+      if (!faceAvailable) // huh...
+          continue;
         
-        NS_LOG_INFO("count="<<count);
-        ucb (face->m_face, header, packet->Copy());
-        count++;
+      sendCallback (metricFace.m_face, header, packet->Copy());
+      propagatedCount++;
     }
-    
-    /*const CcnxFibEntryContainer& s,
-    
-    for (CcnxFibEntryContainer::type::iterator entry = fibEntryArray.begin ();
-         entry != fibEntryArray.end ();
-         entry++)
-    {
-    
-        const typename boost::multi_index::index<CcnxFibEntryContainer, Tag>::type& i = get<Tag>(s);
-        
-        typedef typename CcnxFibEntryContainer::value_type value_type;
-        
-        for(const CcnxFibEntryContainer& c = i.begin(); c != i.end (); c++)
-        {
-                c->
-        }
-        
-        for(nth_index<CcnxFibEntryContainer,1>::type::iterator it1=get<i_prefix>(entry).begin();
-            it1!=get<i_prefix>(entry).end();++it1)
-        {
-            //std::cout<<it1->name()<<std::endl;
-            
-           CcnxFibFaceMetricContainer faceContainer = it1->m_faces;
-            
-            const typename boost::multi_index::index<CcnxFibFaceMetricContainer, __ccnx_private::i_face>::type& i = get<__ccnx_private::i_face>(faceContainer);
-             
-             //typedef typename CcnxFibEntryContainer::value_type value_type;
-             
-             for(const CcnxFibFaceMetricContainer& c = i.begin(); c != i.end (); c++)
-             {
-                 Ptr<CcnxFace> face = c->m_face;
-                 
-                 typedef
-                 Callback<void, const Ptr<CcnxFace> &, const Ptr<CcnxInterestHeader> &, const Ptr<Packet> &>
-                 SendCallback;
-                 
-                 ucb (face, header, packet);
-             }
-            
-        }
-        
-        
-        // obtain a reference to the index tagged by Tag
-        
-        const typename boost::multi_index::index<MultiIndexContainer,Tag>::type& i=
-        get<Tag>(s);
-        
-        typedef typename MultiIndexContainer::value_type value_type;
-        
-        // dump the elements of the index to cout 
-        
-        std::copy(i.begin(),i.end(),std::ostream_iterator<value_type>(std::cout));
-        */
-    
-    if(count == 0)
-        return false;
-    else
-        return true;
+
+  return propagatedCount > 0;
 }
     
 } //namespace ns3
diff --git a/model/ccnx-flooding-strategy.h b/model/ccnx-flooding-strategy.h
index b6c309d..0d43b6a 100644
--- a/model/ccnx-flooding-strategy.h
+++ b/model/ccnx-flooding-strategy.h
@@ -21,14 +21,7 @@
 #ifndef CCNX_FLOODING_STRATEGY_H
 #define CCNX_FLOODING_STRATEGY_H
 
-#include "ns3/packet.h"
-#include "ns3/callback.h"
-#include "ns3/object.h"
-#include "ns3/log.h"
-
 #include "ccnx-forwarding-strategy.h"
-#include "ccnx.h"
-#include "ccnx-fib.h"
 
 namespace ns3 
 {
@@ -39,22 +32,26 @@
 /**
  * \ingroup ccnx
  * \brief Flooding strategy
+ *
+ * \todo Describe
  */
-
 class CcnxFloodingStrategy : public CcnxForwardingStrategy
 {
 public:
   static TypeId GetTypeId (void);
-        
+
+  /**
+   * @brief Default constructor
+   */
   CcnxFloodingStrategy ();
 
+  // inherited from  CcnxForwardingStrategy
   virtual bool
-  PropagateInterest (CcnxPitEntryContainer::type::iterator pitEntry,
-                     CcnxFibEntryContainer::type::iterator fibEntry,
+  PropagateInterest (const CcnxPitEntry  &pitEntry, 
                      const Ptr<CcnxFace> &incomingFace,
                      Ptr<CcnxInterestHeader> &header,
                      const Ptr<const Packet> &packet,
-                     SendCallback ucb);
+                     SendCallback sendCallback);
 };
     
 } //namespace ns3
diff --git a/model/ccnx-forwarding-strategy.cc b/model/ccnx-forwarding-strategy.cc
index 64fef94..40b9e47 100644
--- a/model/ccnx-forwarding-strategy.cc
+++ b/model/ccnx-forwarding-strategy.cc
@@ -33,7 +33,7 @@
   static TypeId tid = TypeId ("ns3::CcnxForwardingStrategy")
     .SetGroupName ("Ccnx")
     .SetParent<Object> ()
-  ;
+    ;
   return tid;
 }
 
@@ -46,15 +46,15 @@
 }
 
 void
-CcnxForwardingStrategy::SetPit(Ptr<CcnxPit> pit)
+CcnxForwardingStrategy::SetPit (Ptr<CcnxPit> pit)
 {
-    m_pit = pit;
+  m_pit = pit;
 }
     
-Ptr<CcnxPit>
-CcnxForwardingStrategy::GetPit()
-{
-    return m_pit;
-}
+// Ptr<CcnxPit>
+// CcnxForwardingStrategy::GetPit ()
+// {
+//   return m_pit;
+// }
     
 } //namespace ns3
diff --git a/model/ccnx-forwarding-strategy.h b/model/ccnx-forwarding-strategy.h
index cdf9576..b8bbc5b 100644
--- a/model/ccnx-forwarding-strategy.h
+++ b/model/ccnx-forwarding-strategy.h
@@ -37,33 +37,50 @@
 
 /**
  * \ingroup ccnx
- * \brief Abstract base class for Ccnx forwarding protocols
+ * \brief Abstract base class for CCNx forwarding strategies
  */
 class CcnxForwardingStrategy : public Object
 {
 public:
-  static TypeId GetTypeId (void);
-
-  CcnxForwardingStrategy ();
-  virtual ~CcnxForwardingStrategy ();
-    
-  void
-  SetPit (Ptr<CcnxPit> pit);
-    
   typedef
-  Callback<void, const Ptr<CcnxFace> &, const Ptr<CcnxInterestHeader> &, const Ptr<Packet> &>
+  Callback<void, const Ptr<CcnxFace> &, const Ptr<const CcnxInterestHeader> &, const Ptr<Packet> &>
   SendCallback;
 
+  static TypeId GetTypeId (void);
+
+  /**
+   * @brief Default constructor
+   */
+  CcnxForwardingStrategy ();
+  virtual ~CcnxForwardingStrategy ();
+
+  /**
+   * @brief Interface method to propagate the insterest according to the forwarding strategy
+   *
+   * @param pitEntry      Reference to PIT entry (reference to corresponding FIB entry inside)
+   * @param incomingFace  Incoming face
+   * @param header        CcnxInterestHeader
+   * @param packet        Original Interest packet
+   * @param sendCallback  Send callback
+   *
+   * @return true if interest was successfully propagated, false if all options have failed
+   */
   virtual bool
-  PropagateInterest (CcnxPitEntryContainer::type::iterator pitEntry, 
-                     CcnxFibEntryContainer::type::iterator fibEntry,
+  PropagateInterest (const CcnxPitEntry  &pitEntry, 
                      const Ptr<CcnxFace> &incomingFace,
                      Ptr<CcnxInterestHeader> &header,
                      const Ptr<const Packet> &packet,
-                     SendCallback ucb) = 0;
-  Ptr<CcnxPit> GetPit();
+                     SendCallback sendCallback) = 0;
     
-private:  
+  /**
+   * @brief Set link to PIT for the forwarding strategy
+   *
+   * @param pit pointer to PIT
+   */
+  void
+  SetPit (Ptr<CcnxPit> pit);
+
+protected:  
   Ptr<CcnxPit> m_pit;
 };
 
diff --git a/model/ccnx-interest-header.cc b/model/ccnx-interest-header.cc
index cc21412..6539ff8 100644
--- a/model/ccnx-interest-header.cc
+++ b/model/ccnx-interest-header.cc
@@ -183,9 +183,9 @@
 }
 
 uint32_t
-CcnxInterestHeader::IsNack () const
+CcnxInterestHeader::GetNack () const
 {
-  return m_nack;
+  return m_nackType;
 }
 
 uint32_t
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index a479390..b719e99 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -33,7 +33,6 @@
 #include "ns3/ccnx-header-helper.h"
 
 #include "ccnx-face.h"
-#include "ccnx-route.h"
 #include "ccnx-forwarding-strategy.h"
 #include "ccnx-interest-header.h"
 #include "ccnx-content-object-header.h"
@@ -42,9 +41,10 @@
 
 #include <boost/foreach.hpp>
 #include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
 
 using namespace boost::tuples;
-using namespace boost::lambda;
+namespace ll = boost::lambda;
 
 NS_LOG_COMPONENT_DEFINE ("CcnxL3Protocol");
 
@@ -84,7 +84,6 @@
 {
   NS_LOG_FUNCTION (this);
   
-  m_rit = CreateObject<CcnxRit> ();
   m_pit = CreateObject<CcnxPit> ();
   m_contentStore = CreateObject<CcnxContentStore> ();
 }
@@ -138,7 +137,6 @@
 
   // Force delete on objects
   m_forwardingStrategy = 0; // there is a reference to PIT stored in here
-  m_rit = 0;
   m_pit = 0;
   m_contentStore = 0;
   m_fib = 0;
@@ -358,10 +356,10 @@
   // m_receivedInterestsTrace (header, m_node->GetObject<Ccnx> (), incomingFace);
 
   // Lookup of Pit (and associated Fib) entry for this Interest 
-  const CcnxPitEntry &pitEntry;
-  bool isNew;
-  bool isDuplicated;
-  tie (pitEntry, isNew, isDuplicated) = m_pit->Lookup (*header);
+  tuple<const CcnxPitEntry&,bool,bool> ret = m_pit->Lookup (*header);
+  CcnxPitEntry const& pitEntry = ret.get<0> ();
+  // bool isNew = ret.get<1> ();
+  bool isDuplicated = ret.get<2> ();
 
   if (isDuplicated) 
     {
@@ -378,7 +376,7 @@
       Ptr<Packet> packet = Create<Packet> ();
       packet->AddHeader (*header);
 
-      SendInterest (m_incomingFace, header, packet);
+      SendInterest (incomingFace, header, packet);
       
       // //Trace duplicate interest  
       // m_droppedInterestsTrace (header, NDN_DUPLICATE_INTEREST, m_node->GetObject<Ccnx> (), incomingFace);
@@ -386,12 +384,12 @@
     }
 
   Ptr<Packet> contentObject;
-  Ptr<CcnxContentObjectHeader> contentObjectHeader;
+  Ptr<const CcnxContentObjectHeader> contentObjectHeader;
   tie (contentObject, contentObjectHeader) = m_contentStore->Lookup (header);
   if (contentObject != 0)
     {
-      NS_ASSERT_MSG (pitEntry.m_incoming.size () == 0,
-                     "Something strange. Data is cached, but size of incoming interests is not zero...");
+      // NS_ASSERT_MSG (pitEntry.m_incoming.size () == 0,
+      //                "Something strange. Data is cached, but size of incoming interests is not zero...");
       NS_ASSERT (contentObjectHeader != 0);
       
       NS_LOG_LOGIC("Found in cache");
@@ -402,8 +400,8 @@
 
       // Set pruning timout on PIT entry (instead of deleting the record)
       m_pit->modify (m_pit->iterator_to (pitEntry),
-                     boost::bind (&CcnxPitEntry::SetExpireTime, _1,
-                                  Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
+                     bind (&CcnxPitEntry::SetExpireTime, ll::_1,
+                           Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
       return;
     }
 
@@ -421,8 +419,8 @@
     }
   else
     {
-      m_pit->modify (m_pit->iterator_to (m_pitpitEntry),
-                    iface = _1->m_incoming.insert (CcnxPitEntryIncoming (incomingFace, Simulator::Now ())));
+      m_pit->modify (m_pit->iterator_to (pitEntry),
+                     ll::var(inFace) = ll::bind (&CcnxPitEntry::AddIncoming, ll::_1, incomingFace));
     }
 
   if (outFace != pitEntry.m_outgoing.end ())
@@ -436,12 +434,12 @@
       // ?? not sure if we need to do that ?? ...
       
       m_fib->modify(m_fib->iterator_to (pitEntry.m_fibEntry),
-                    boost::bind (&CcnxFibEntry::UpdateStatus,
-                                 _1, incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
+                    ll::bind (&CcnxFibEntry::UpdateStatus,
+                              ll::_1, incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
 
       // suppress?
     }
-  else if (pitEntry->m_outgoing.size() > 0) // Suppress this interest if we're still expecting data from some other face
+  else if (pitEntry.m_outgoing.size() > 0) // Suppress this interest if we're still expecting data from some other face
 
     {
       // We are already expecting data later in future. Suppress the interest
@@ -456,7 +454,7 @@
   NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
   
   bool propagated = m_forwardingStrategy->
-    PropagateInterest (pitEntry, fibEntry,incomingFace, header, packet,
+    PropagateInterest (pitEntry, incomingFace, header, packet,
                        MakeCallback (&CcnxL3Protocol::SendInterest, this)
                        );
 
@@ -467,22 +465,23 @@
     {
       Ptr<Packet> packet = Create<Packet> ();
       header->SetNack (CcnxInterestHeader::NACK_CONGESTION);
-      packet.AddHeader (*header);
+      packet->AddHeader (*header);
 
-      while (pitEntry.m_incoming.size () > 0)
+      BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry.m_incoming)
         {
-          SendInterest (pitEntry.m_incoming.front ().m_face, header, packet->Copy ());
-
-          pitEntry.m_incoming.pop_front ();
+          SendInterest (incoming.m_face, header, packet->Copy ());
 
           // m_droppedInterestsTrace (header, DROP_CONGESTION,
           //                          m_node->GetObject<Ccnx> (), incomingFace);
         }
+      // All incoming interests cannot be satisfied. Remove them
+      m_pit->modify (m_pit->iterator_to (pitEntry),
+                     ll::bind (&CcnxPitEntry::ClearIncoming, ll::_1));
 
       // Set pruning timout on PIT entry (instead of deleting the record)
       m_pit->modify (m_pit->iterator_to (pitEntry),
-                     boost::bind (&CcnxPitEntry::SetExpireTime, _1,
-                                  Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
+                     ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
+                           Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
     }
 }
 
@@ -493,7 +492,7 @@
                              const Ptr<const Packet> &packet)
 {
     
-  NS_LOG_FUNCTION (incomingFace << header, payload, packet);
+  NS_LOG_FUNCTION (incomingFace << header << payload << packet);
   // m_receivedDataTrace (header, payload, m_node->GetObject<Ccnx> ()/*this*/, incomingFace);
 
   // 1. Lookup PIT entry
@@ -505,7 +504,8 @@
   
       // Update metric status for the incoming interface in the corresponding FIB entry
       m_fib->modify (m_fib->iterator_to (pitEntry.m_fibEntry),
-                     boost::bind (CcnxFibEntry::UpdateStatus, _1, incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
+                     ll::bind (&CcnxFibEntry::UpdateStatus, ll::_1,
+                           incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
   
       // Add or update entry in the content store
       m_contentStore->Add (header, payload);
@@ -516,9 +516,10 @@
       if (out != pitEntry.m_outgoing.end ())
         {
           m_fib->modify (m_fib->iterator_to (pitEntry.m_fibEntry),
-                         boost::bind (&CcnxFibEntry::UpdateRtt,
-                                      _1,
-                                      Simulator::Now () - out->m_sendTime));
+                         ll::bind (&CcnxFibEntry::UpdateFaceRtt,
+                               ll::_1,
+                               incomingFace,
+                               Simulator::Now () - out->m_sendTime));
         }
       else
         {
@@ -533,19 +534,20 @@
         }
 
       //satisfy all pending incoming Interests
-      while (pitEntry.m_incoming.size () > 0)
+      BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry.m_incoming)
         {
-          if (pitEntry.m_incoming.front ().m_face != incomingFace)
-            SendInterest (pitEntry.m_incoming.front ().m_face, header, packet->Copy ());
+          if (incoming.m_face != incomingFace)
+            SendContentObject (incoming.m_face, header, packet->Copy ());
 
-          pitEntry.m_incoming.pop_front ();
-
-          // m_transmittedDataTrace (header, payload, FORWARDED, m_node->GetObject<Ccnx> (), interest.m_face);
+          // successfull forwarded data trace
         }
-
+      // All incoming interests are satisfied. Remove them
+      m_pit->modify (m_pit->iterator_to (pitEntry),
+                     ll::bind (&CcnxPitEntry::ClearIncoming, ll::_1));
+      
       // Set pruning timout on PIT entry (instead of deleting the record)
       m_pit->modify (m_pit->iterator_to (pitEntry),
-                     boost::bind (&CcnxPitEntry::SetExpireTime, _1,
+                     ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
                                   Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
     }
   catch (CcnxPitEntryNotFound)
@@ -561,7 +563,7 @@
 
 void
 CcnxL3Protocol::SendInterest (const Ptr<CcnxFace> &face,
-                              const Ptr<CcnxInterestHeader> &header,
+                              const Ptr<const CcnxInterestHeader> &header,
                               const Ptr<Packet> &packet)
 {
   NS_LOG_FUNCTION (this << "packet: " << &packet << ", face: "<< &face);
@@ -582,7 +584,7 @@
 
 void
 CcnxL3Protocol::SendContentObject (const Ptr<CcnxFace> &face,
-                                   const Ptr<CcnxContentObjectHeader> &header,
+                                   const Ptr<const CcnxContentObjectHeader> &header,
                                    const Ptr<Packet> &packet)
 {
   NS_LOG_FUNCTION (this << "packet: " << &packet << ", face: "<< &face);
diff --git a/model/ccnx-l3-protocol.h b/model/ccnx-l3-protocol.h
index 3605da4..c470959 100644
--- a/model/ccnx-l3-protocol.h
+++ b/model/ccnx-l3-protocol.h
@@ -128,10 +128,10 @@
   Ptr<CcnxForwardingStrategy> GetForwardingStrategy () const;
 
   virtual void SendInterest (const Ptr<CcnxFace> &face,
-                             const Ptr<CcnxInterestHeader> &header,
+                             const Ptr<const CcnxInterestHeader> &header,
                              const Ptr<Packet> &packet);
   virtual void SendContentObject (const Ptr<CcnxFace> &face,
-                                  const Ptr<CcnxContentObjectHeader> &header,
+                                  const Ptr<const CcnxContentObjectHeader> &header,
                                   const Ptr<Packet> &packet);
   virtual void Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p);
 
diff --git a/model/ccnx-local-face.cc b/model/ccnx-local-face.cc
index 5020877..fc4dd11 100644
--- a/model/ccnx-local-face.cc
+++ b/model/ccnx-local-face.cc
@@ -54,7 +54,6 @@
   , m_onContentObject (0)
 {
   NS_LOG_FUNCTION (this);
-  m_isLocal = true;
 }
 
 CcnxLocalFace::~CcnxLocalFace ()
@@ -83,7 +82,7 @@
 void
 CcnxLocalFace::Send (Ptr<Packet> p)
 {
-    NS_LOG_FUNCTION("Local face send");
+  NS_LOG_FUNCTION("Local face send");
   NS_LOG_FUNCTION (*p);
   if (!IsUp ())
     {
diff --git a/model/ccnx-net-device-face.cc b/model/ccnx-net-device-face.cc
index e06a741..12cb272 100644
--- a/model/ccnx-net-device-face.cc
+++ b/model/ccnx-net-device-face.cc
@@ -32,18 +32,6 @@
 
 namespace ns3 {
 
-// NS_OBJECT_ENSURE_REGISTERED (CcnxNetDeviceFace);
-
-// TypeId 
-// CcnxNetDeviceFace::GetTypeId ()
-// {
-//   static TypeId tid = TypeId ("ns3::CcnxNetDeviceFace")
-//     .SetGroupName ("Ccnx")
-//     .SetParent<CcnxFace> ()
-//   ;
-//   return tid;
-// }
-
 /** 
  * By default, Ccnx face are created in the "down" state.  Before
  * becoming useable, the user must invoke SetUp on the face
@@ -53,7 +41,6 @@
   NS_LOG_FUNCTION (this);
 
   m_netDevice = netDevice;
-  m_isLocal = false;
 }
 
 CcnxNetDeviceFace::~CcnxNetDeviceFace ()
@@ -63,7 +50,6 @@
 
 CcnxNetDeviceFace::CcnxNetDeviceFace (const CcnxNetDeviceFace &)
 {
-    m_isLocal = false;
 }
 
 CcnxNetDeviceFace& CcnxNetDeviceFace::operator= (const CcnxNetDeviceFace &)
@@ -94,8 +80,8 @@
 {
   NS_ASSERT_MSG (packet->GetSize () <= m_netDevice->GetMtu (), 
                  "Packet size " << packet->GetSize () << " exceeds device MTU "
-                                << m_netDevice->GetMtu ()
-                                << " for Ccnx; fragmentation not supported");
+                 << m_netDevice->GetMtu ()
+                 << " for Ccnx; fragmentation not supported");
 
   NS_LOG_FUNCTION (*packet);
   if (!IsUp ())
@@ -104,7 +90,7 @@
     }
 
   m_netDevice->Send (packet, m_netDevice->GetBroadcast (), 
-                  CcnxL3Protocol::ETHERNET_FRAME_TYPE);
+                     CcnxL3Protocol::ETHERNET_FRAME_TYPE);
 }
 
 // callback
diff --git a/model/ccnx-pit-entry-incoming-face.h b/model/ccnx-pit-entry-incoming-face.h
index 9a3859f..80f7e09 100644
--- a/model/ccnx-pit-entry-incoming-face.h
+++ b/model/ccnx-pit-entry-incoming-face.h
@@ -44,7 +44,7 @@
    * \param face face of the incoming interest
    * \param lifetime lifetime of the incoming interest
    */
-  CcnxPitEntryIncomingFace (Ptr<CcnxFace> face, Time arrivalTime);
+  CcnxPitEntryIncomingFace (Ptr<CcnxFace> face);
 
   bool operator== (const CcnxPitEntryIncomingFace &dst) { return *m_face==*(dst.m_face); }
   bool operator== (Ptr<CcnxFace> face) { return *m_face==*face; }
diff --git a/model/ccnx-pit-entry.cc b/model/ccnx-pit-entry.cc
index 5dab9ae..7b8f489 100644
--- a/model/ccnx-pit-entry.cc
+++ b/model/ccnx-pit-entry.cc
@@ -44,21 +44,28 @@
   return *m_prefix;
 }
 
-// void
-// CcnxPitEntry::AddIncoming (Ptr<CcnxFace> face)
-// {
-//   m_incoming.insert (CcnxPitEntryIncomingFace (face,     )
-// }
+CcnxPitEntryIncomingFaceContainer::type::iterator
+CcnxPitEntry::AddIncoming (Ptr<CcnxFace> face)
+{
+  std::pair<CcnxPitEntryIncomingFaceContainer::type::iterator,bool> ret = 
+    m_incoming.insert (CcnxPitEntryIncomingFace (face));
 
+  NS_ASSERT_MSG (ret.second, "Something is wrong");
 
-// CcnxPitEntry::UpdateFibStatus::UpdateFibStatus (Ptr<CcnxFace> face,
-//                                                 CcnxFibFaceMetric::Status status,
-//                                                 Ptr<CcnxFib> fib)
-//   : m_face (face)
-//   , m_status (status)
-//   , m_fib (fib)
-// {
-// }
+  return ret.first;
+}
+
+CcnxPitEntryOutgoingFaceContainer::type::iterator
+CcnxPitEntry::AddOutgoing (Ptr<CcnxFace> face)
+{
+  std::pair<CcnxPitEntryOutgoingFaceContainer::type::iterator,bool> ret =
+    m_outgoing.insert (CcnxPitEntryOutgoingFace (face));
+
+  NS_ASSERT_MSG (ret.second, "Something is wrong");
+
+  return ret.first;
+}
+
 
 // void
 // CcnxPitEntry::UpdateFibStatus::operator() (CcnxPitEntry &entry)
diff --git a/model/ccnx-pit-entry.h b/model/ccnx-pit-entry.h
index 59f2a3e..ac1b277 100644
--- a/model/ccnx-pit-entry.h
+++ b/model/ccnx-pit-entry.h
@@ -129,8 +129,15 @@
   AddSeenNonce (uint32_t nonce)
   { m_seenNonces.insert (nonce); }
 
+  CcnxPitEntryIncomingFaceContainer::type::iterator
+  AddIncoming (Ptr<CcnxFace> face);
+
   void
-  AddIncoming (const CcnxFace &face);
+  ClearIncoming ()
+  { m_incoming.clear (); }
+
+  CcnxPitEntryOutgoingFaceContainer::type::iterator
+  AddOutgoing (Ptr<CcnxFace> face);
   
 private:
   friend std::ostream& operator<< (std::ostream& os, const CcnxPitEntry &entry);
diff --git a/model/ccnx-pit.cc b/model/ccnx-pit.cc
index 3017857..85b4ecb 100644
--- a/model/ccnx-pit.cc
+++ b/model/ccnx-pit.cc
@@ -20,13 +20,18 @@
 
 #include "ccnx-pit.h"
 #include "ns3/log.h"
+#include "ns3/string.h"
 #include "ns3/simulator.h"
 #include "ccnx-interest-header.h"
 #include "ccnx-content-object-header.h"
 
+#include <boost/bind.hpp>
+#include <boost/lambda/lambda.hpp>
+
 NS_LOG_COMPONENT_DEFINE ("CcnxPit");
 
 using namespace boost::tuples;
+using namespace boost;
 
 namespace ns3 {
 
@@ -51,6 +56,11 @@
                    StringValue ("100ms"),
                    MakeTimeAccessor (&CcnxPit::m_PitEntryPruningTimout),
                    MakeTimeChecker ())
+    .AddAttribute ("PitEntryDefaultLifetime",
+                   "Default lifetime of PIT entry (aka default Interest lifetime)",
+                   StringValue("4s"),
+                   MakeTimeAccessor (&CcnxPit::m_PitEntryDefaultLifetime),
+                   MakeTimeChecker ())
     ;
 
   return tid;
@@ -130,40 +140,23 @@
   m_fib = fib;
 }
 
-/*CcnxPitEntryContainer::type::iterator
-  CcnxPit::Add (const CcnxInterestHeader &header, CcnxFibEntryContainer::type::iterator fibEntry, Ptr<CcnxFace> face)
-  {
-  if( m_bucketsPerFace[face->GetId()]+1.0 >= maxBucketsPerFace[face->GetId()] )
-  {
-  //		printf( "DEBUG: bucket overflow. Should not forward anything to interface %d\n", interest.interfaceIndex );
-  return end();
-  }
-    
-  CcnxPitEntryContainer::type::iterator entry = insert (end (),
-  CcnxPitEntry (Create<CcnxNameComponents> (header.GetName ()),
-  *fibEntry));
-  return entry;
-  }*/
-
 bool
-CcnxPit::TryAddOutgoing (CcnxPitEntryContainer::type::iterator pitEntry, Ptr<CcnxFace> face)
+CcnxPit::TryAddOutgoing (const CcnxPitEntry &pitEntry, Ptr<CcnxFace> face)
 {
-  NS_LOG_INFO ("Face has " << m_bucketsPerFace[face->GetId()] << " packets with max allowance " << maxBucketsPerFace[face->GetId()]); 
+  NS_LOG_FUNCTION ("Face has " << m_bucketsPerFace[face->GetId()] <<
+               " packets with max allowance " << maxBucketsPerFace[face->GetId()]); 
     
-  if((face->IsLocal() == false) 
-     && (m_bucketsPerFace[face->GetId()]+1.0 >= maxBucketsPerFace[face->GetId()] ))
+  if (m_bucketsPerFace[face->GetId()]+1.0 >= maxBucketsPerFace[face->GetId()])
     {
-      NS_LOG_INFO("********LIMIT**************");
+      NS_LOG_INFO("************ LIMIT **************");
       return false;
     }
     
   m_bucketsPerFace[face->GetId()] = m_bucketsPerFace[face->GetId()] + 1.0;
-	
-  NS_LOG_INFO(this->size());
-  NS_LOG_INFO("before modify");
-  NS_LOG_INFO(pitEntry->GetPrefix());
-  modify (pitEntry, CcnxPitEntry::AddOutgoing(face));
-  NS_LOG_INFO("after modify");
+
+  modify (iterator_to (pitEntry),
+          bind(&CcnxPitEntry::AddOutgoing, lambda::_1, face));
+          
   return true;
 }
 
@@ -181,7 +174,7 @@
   return *entry;
 }
 
-std::pair<CcnxPitEntryContainer::type::iterator,std::pair<bool, bool> >
+boost::tuple<const CcnxPitEntry&, bool, bool>
 CcnxPit::Lookup (const CcnxInterestHeader &header)
 {
   NS_LOG_FUNCTION_NOARGS ();
@@ -202,8 +195,8 @@
       entry = insert (end (),
                       CcnxPitEntry (Create<CcnxNameComponents> (header.GetName ()),
                                     Simulator::Now () +
-                                    (header.GetInterestLifetime ().IsZero ()?DEFAULT_INTEREST_LIFETIME:
-                                                                             header.GetInterestLifetime ())
+                                    (header.GetInterestLifetime ().IsZero ()?m_PitEntryDefaultLifetime
+                                     :                                       header.GetInterestLifetime ()),
                                     *fibEntry));
 
       // isDuplicate = false; // redundant
@@ -212,12 +205,13 @@
   else
     {
       isNew = false;
-      isDuplicate = entry->IsNonceSeen (header->GetNonce ());
+      isDuplicate = entry->IsNonceSeen (header.GetNonce ());
     }
 
   if (!isDuplicate)
     {
-      modify (entry, boost::bind(&CcnxPitEntry::AddSeenNonce, boost::lambda::_1, header->GetNonce ()));
+      modify (entry,
+              boost::bind(&CcnxPitEntry::AddSeenNonce, boost::lambda::_1, header.GetNonce ()));
     }
 
   return make_tuple (cref(*entry), isNew, isDuplicate);
diff --git a/model/ccnx-pit.h b/model/ccnx-pit.h
index 538e127..7c8785c 100644
--- a/model/ccnx-pit.h
+++ b/model/ccnx-pit.h
@@ -123,11 +123,16 @@
    */
   virtual ~CcnxPit ();
 
-  /*CcnxPitEntryContainer::type::iterator
-  Add (const CcnxInterestHeader &header, CcnxFibEntryContainer::type::iterator fibEntry, Ptr<CcnxFace> face);*/
-  
+  /**
+   * @brief Try to add outgoing entry to PIT entry.
+   * Will fail if there were too much (other) interests forwarded to this face
+   *
+   * @param pitEntry PIT entry
+   * @param face     face
+   * @returns false if rate limit is imposed and no outgoing entry was created. True otherwise
+   */
   bool
-  TryAddOutgoing(CcnxPitEntryContainer::type::iterator pitEntry, Ptr<CcnxFace> face);
+  TryAddOutgoing(const CcnxPitEntry &pitEntry, Ptr<CcnxFace> face);
   
   /**
    * \brief Find corresponding PIT entry for the given content name
@@ -211,6 +216,7 @@
   Time    m_cleanupTimeout; ///< \brief Configurable timeout of how often cleanup events are working
   EventId m_cleanupEvent;   ///< \brief Cleanup event
   Time    m_PitEntryPruningTimout;
+  Time    m_PitEntryDefaultLifetime; 
 
   Ptr<CcnxFib> m_fib; ///< \brief Link to FIB table
   PitBucket    m_bucketsPerFace; ///< \brief pending interface counter per face
diff --git a/model/ccnx.h b/model/ccnx.h
index 32e2f57..4d6f636 100644
--- a/model/ccnx.h
+++ b/model/ccnx.h
@@ -49,11 +49,10 @@
 class i_mru {};
 }
 
-#define MILLI_SECOND 1
-#define SECOND 1000
 // default data size
-#define NDN_DEFAULT_DATA_SIZE   1024
-#define NDN_INTEREST_RESET_PERIOD	(10*MILLI_SECOND)
+// #define NDN_DEFAULT_DATA_SIZE   1024
+// #define NDN_INTEREST_RESET_PERIOD	(10*MILLI_SECOND)
+
 /**
  * \defgroup ccnx NDN abstraction
  *
@@ -108,7 +107,7 @@
    */
   virtual void
   SendInterest (const Ptr<CcnxFace> &face,
-                const Ptr<CcnxInterestHeader> &header,
+                const Ptr<const CcnxInterestHeader> &header,
                 const Ptr<Packet> &packet) = 0;
 
   /**
@@ -123,7 +122,7 @@
    */
   virtual void
   SendContentObject (const Ptr<CcnxFace> &face,
-                     const Ptr<CcnxContentObjectHeader> &header,
+                     const Ptr<const CcnxContentObjectHeader> &header,
                      const Ptr<Packet> &packet) = 0;
 
   /**