Many corrections to face/local-face/net-device-face/fib/pit.  Now
interest packets actually go down to ccnx stack.  Also, now it is
possible to manually configure FIB entries.

CcnxFib now is an object aggregated to the node
diff --git a/model/ccnx-content-store.cc b/model/ccnx-content-store.cc
index 87a8003..57bb414 100644
--- a/model/ccnx-content-store.cc
+++ b/model/ccnx-content-store.cc
@@ -151,6 +151,7 @@
 Ptr<Packet>
 CcnxContentStore::Lookup (Ptr<const CcnxInterestHeader> interest)
 {
+  NS_LOG_FUNCTION_NOARGS ();
   CcnxContentStoreContainer::type::iterator it = m_contentStore.get<i_prefix> ().find (interest->GetName ());
   if (it != m_contentStore.end ())
     {
@@ -167,6 +168,7 @@
 void 
 CcnxContentStore::Add (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet)
 {
+  NS_LOG_FUNCTION_NOARGS ();
   CcnxContentStoreContainer::type::iterator it = m_contentStore.get<i_prefix> ().find (header->GetName ());
   if (it == m_contentStore.end ())
     { // add entry to the top
diff --git a/model/ccnx-face.cc b/model/ccnx-face.cc
index d672f07..38d76e6 100644
--- a/model/ccnx-face.cc
+++ b/model/ccnx-face.cc
@@ -29,17 +29,17 @@
 
 namespace ns3 {
 
-NS_OBJECT_ENSURE_REGISTERED (CcnxFace);
+// NS_OBJECT_ENSURE_REGISTERED (CcnxFace);
 
-TypeId 
-CcnxFace::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::CcnxFace")
-    .SetGroupName ("Ccnx")
-    .SetParent<Object> ()
-  ;
-  return tid;
-}
+// TypeId 
+// CcnxFace::GetTypeId (void)
+// {
+//   static TypeId tid = TypeId ("ns3::CcnxFace")
+//     .SetGroupName ("Ccnx")
+//     .SetParent<Object> ()
+//   ;
+//   return tid;
+// }
 
 /** 
  * By default, Ccnx face are created in the "down" state
@@ -47,8 +47,8 @@
  * invoke SetUp on them once an Ccnx address and mask have been set.
  */
 CcnxFace::CcnxFace () 
-  : m_metric (1)
-  , m_node (0)
+  // : m_metric (1)
+  : m_node (0)
   , m_ifup (false)
   , m_id ((uint32_t)-1)
 {
@@ -70,13 +70,13 @@
 }
 
   
-void
-CcnxFace::DoDispose (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_node = 0;
-  Object::DoDispose ();
-}
+// void
+// CcnxFace::DoDispose (void)
+// {
+//   NS_LOG_FUNCTION_NOARGS ();
+//   m_node = 0;
+//   Object::DoDispose ();
+// }
 
 void 
 CcnxFace::SetNode (Ptr<Node> node)
@@ -84,19 +84,19 @@
   m_node = node;
 }
 
-void
-CcnxFace::SetMetric (uint16_t metric)
-{
-  NS_LOG_FUNCTION (metric);
-  m_metric = metric;
-}
+// void
+// CcnxFace::SetMetric (uint16_t metric)
+// {
+//   NS_LOG_FUNCTION (metric);
+//   m_metric = metric;
+// }
 
-uint16_t
-CcnxFace::GetMetric (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_metric;
-}
+// uint16_t
+// CcnxFace::GetMetric (void) const
+// {
+//   NS_LOG_FUNCTION_NOARGS ();
+//   return m_metric;
+// }
 
 /**
  * These are face states and may be distinct from 
@@ -147,9 +147,16 @@
   return (m_id < face.m_id);
 }
 
+std::ostream&
+CcnxFace::Print (std::ostream &os) const
+{
+  os << "id=" << GetId ();
+  return os;
+}
+
 std::ostream& operator<< (std::ostream& os, const CcnxFace &face)
 {
-  os << "id=" << face.GetId ();
+  face.Print (os);
   return os;
 }
 
diff --git a/model/ccnx-face.h b/model/ccnx-face.h
index 2650515..07561a0 100644
--- a/model/ccnx-face.h
+++ b/model/ccnx-face.h
@@ -24,7 +24,8 @@
 #include <ostream>
 
 #include "ns3/ptr.h"
-#include "ns3/object.h"
+#include "ns3/simple-ref-count.h"
+#include "ns3/callback.h"
 
 namespace ns3 {
 
@@ -46,7 +47,7 @@
  *
  * \see CcnxLocalFace, CcnxNetDeviceFace, CcnxIpv4Face, CcnxUdpFace
  */
-class CcnxFace  : public Object
+class CcnxFace  : public SimpleRefCount<CcnxFace>
 {
 public:
   /**
@@ -57,12 +58,12 @@
    */
   typedef Callback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>& > ProtocolHandler;
   
-  /**
-   * \brief Interface ID
-   *
-   * \return interface ID
-   */
-  static TypeId GetTypeId (void);
+  // /**
+  //  * \brief Interface ID
+  //  *
+  //  * \return interface ID
+  //  */
+  // static TypeId GetTypeId (void);
 
   /**
    * \brief Default constructor
@@ -95,19 +96,19 @@
    */
   virtual void SetNode (Ptr<Node> node);
 
-  /**
-   * \brief Assign routing/forwarding metric with face
-   *
-   * \param metric configured routing metric (cost) of this face
-   */
-  virtual void SetMetric (uint16_t metric);
+  // /**
+  //  * \Brief Assign routing/forwarding metric with face
+  //  *
+  //  * \param metric configured routing metric (cost) of this face
+  //  */
+  // virtual void SetMetric (uint16_t metric);
 
-  /**
-   * \brief Get routing/forwarding metric assigned to the face
-   *
-   * \returns configured routing/forwarding metric (cost) of this face
-   */
-  virtual uint16_t GetMetric (void) const;
+  // /**
+  //  * \brief Get routing/forwarding metric assigned to the face
+  //  *
+  //  * \returns configured routing/forwarding metric (cost) of this face
+  //  */
+  // virtual uint16_t GetMetric (void) const;
 
   /**
    * These are face states and may be distinct from actual lower-layer
@@ -135,6 +136,9 @@
    */
   virtual bool IsDown () const;
 
+  virtual std::ostream&
+  Print (std::ostream &os) const;
+
   /**
    * \brief Set node Id
    *
@@ -171,15 +175,15 @@
   bool
   operator< (const CcnxFace &face) const;
   
-protected:
-  virtual void DoDispose (void);
+// protected:
+//   virtual void DoDispose (void);
 
 private:
   CcnxFace (const CcnxFace &); ///< \brief Disabled copy constructor
   CcnxFace& operator= (const CcnxFace &); ///< \brief Disabled copy operator
   
 protected:
-  uint16_t m_metric; ///< \brief Routing/forwarding metric
+  // uint16_t m_metric; ///< \brief Routing/forwarding metric
   Ptr<Node> m_node; ///< \brief Smart pointer to Node
   ProtocolHandler m_protocolHandler; ///< Callback via which packets are getting send to CCNx stack
 
diff --git a/model/ccnx-fib.cc b/model/ccnx-fib.cc
index 7e2991c..38f0c65 100644
--- a/model/ccnx-fib.cc
+++ b/model/ccnx-fib.cc
@@ -26,6 +26,7 @@
 
 #include "ns3/node.h"
 #include "ns3/assert.h"
+#include "ns3/names.h"
 
 #define NDN_RTO_ALPHA 0.125
 #define NDN_RTO_BETA 0.25
@@ -60,6 +61,16 @@
   CcnxFibFaceMetric::Status m_status;
 };
 
+struct ChangeMetric
+{
+  ChangeMetric (int32_t metric) : m_metric (metric) { }
+  void operator() (CcnxFibFaceMetric &entry)
+  {
+    entry.m_routingCost = m_metric;
+  }
+private:
+  int32_t m_metric;
+};
 
 // struct SearchByFace {
 //   /**
@@ -121,18 +132,45 @@
 }
 
 void
-CcnxFibEntry::UpdateStatus (Ptr<CcnxFace> face, CcnxFibFaceMetric::Status status)
+CcnxFibEntry::UpdateStatus::operator () (CcnxFibEntry &entry)
 {
-  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");
+  CcnxFibFaceMetricByFace::type::iterator record = entry.m_faces.get<i_face> ().find (m_face);
+  NS_ASSERT_MSG (record != entry.m_faces.get<i_face> ().end (),
+                 "Update status can be performed only on existing faces of CcxnFibEntry");
 
-  m_faces.modify (record, ChangeStatus (status));
+  entry.m_faces.modify (record, ChangeStatus (m_status));
 
   // reordering random access index same way as by metric index
-  m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
+  entry.m_faces.get<i_nth> ().rearrange (entry.m_faces.get<i_metric> ().begin ());
 }
 
+void
+CcnxFibEntry::AddOrUpdateRoutingMetric::operator () (CcnxFibEntry &entry)
+{
+  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 ());
+}
 
+void
+CcnxFibEntry::UpdateFaceRtt::operator() (CcnxFibEntry &entry)
+{
+  CcnxFibFaceMetricContainer::type::iterator metric = entry.m_faces.find (m_face);
+  NS_ASSERT_MSG (metric != entry.m_faces.end (),
+                 "Something wrong. Cannot find entry for the face in FIB");
+
+  entry.m_faces.modify (metric, CcnxFibFaceMetric::UpdateRtt (m_rttSample));
+}
+    
 Ptr<CcnxFace>
 CcnxFibEntry::FindBestCandidate (int skip/* = 0*/)
 {
@@ -145,7 +183,23 @@
 {
 }
 
-std::pair<CcnxFibEntryContainer::type::iterator, bool>
+void
+CcnxFib::NotifyNewAggregate ()
+{
+  if (m_node == 0)
+      m_node = this->GetObject<Node>();
+  Object::NotifyNewAggregate ();
+}
+
+void 
+CcnxFib::DoDispose (void)
+{
+  m_node = 0;
+  Object::DoDispose ();
+}
+
+
+CcnxFibEntryContainer::type::iterator
 CcnxFib::LongestPrefixMatch (const CcnxInterestHeader &interest) const
 {
   const CcnxNameComponents &name = interest.GetName ();
@@ -154,22 +208,38 @@
        componentsCount--)
     {
       CcnxNameComponents subPrefix (name.GetSubComponents (componentsCount));
-      CcnxFibEntryContainer::type::iterator match = m_fib.find (subPrefix);
-      if (match != m_fib.end())
-        return std::pair<CcnxFibEntryContainer::type::iterator, bool> (match,true);
+      CcnxFibEntryContainer::type::iterator match = find (subPrefix);
+      if (match != end())
+        return match;
     }
   
-  return std::pair<CcnxFibEntryContainer::type::iterator, bool> (m_fib.end(),false);
+  return end ();
+}
+
+
+CcnxFibEntryContainer::type::iterator
+CcnxFib::Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric)
+{
+// CcnxFibFaceMetric
+  CcnxFibEntryContainer::type::iterator entry = find (prefix);
+  if (entry == end ())
+    {
+      entry = insert (end (), CcnxFibEntry (prefix));
+      // insert new
+    }
+  modify (entry, CcnxFibEntry::AddOrUpdateRoutingMetric (face, metric));
+
+  return entry;
 }
 
 std::ostream& operator<< (std::ostream& os, const CcnxFib &fib)
 {
-  // os << "Node " << fib.m_node->GetObject<Node> ()->GetId () << "\n";
+  os << "Node " << Names::FindName (fib.m_node) << "\n";
   os << "  Dest prefix      Interfaces(Costs)                  \n";
   os << "+-------------+--------------------------------------+\n";
   
-  for (CcnxFibEntryContainer::type::iterator entry = fib.m_fib.begin ();
-       entry != fib.m_fib.end ();
+  for (CcnxFibEntryContainer::type::iterator entry = fib.begin ();
+       entry != fib.end ();
        entry++)
     {
       os << *entry << "\n";
@@ -179,12 +249,14 @@
 
 std::ostream& operator<< (std::ostream& os, const CcnxFibEntry &entry)
 {
-  os << entry.m_prefix << "\t";
-  for (CcnxFibFaceMetricByFace::type::iterator metric = entry.m_faces.get<i_face> ().begin ();
-       metric != entry.m_faces.get<i_face> ().end ();
+  os << *entry.m_prefix << "\t";
+  
+  for (CcnxFibFaceMetricContainer::type::index<i_nth>::type::iterator metric =
+         entry.m_faces.get<i_nth> ().begin ();
+       metric != entry.m_faces.get<i_nth> ().end ();
        metric++)
     {
-      if (metric != entry.m_faces.get<i_face> ().begin ())
+      if (metric != entry.m_faces.get<i_nth> ().begin ())
         os << ", ";
 
       os << *metric;
@@ -196,7 +268,7 @@
 {
   static const std::string statusString[] = {"","g","y","r"};
 
-  os << metric.m_face << "(" << metric.m_routingCost << ","<< statusString [metric.m_status] << ")";
+  os << *metric.m_face << "(" << metric.m_routingCost << ","<< statusString [metric.m_status] << ")";
   return os;
 }
 
diff --git a/model/ccnx-fib.h b/model/ccnx-fib.h
index 1080d00..ef5d5ad 100644
--- a/model/ccnx-fib.h
+++ b/model/ccnx-fib.h
@@ -26,6 +26,7 @@
 #include "ccnx.h"
 #include "ns3/nstime.h"
 #include "ns3/simple-ref-count.h"
+#include "ns3/node.h"
 
 #include <boost/multi_index_container.hpp>
 #include <boost/multi_index/tag.hpp>
@@ -101,7 +102,7 @@
 						///<		- NDN_FIB_YELLOW
 						///<		- NDN_FIB_RED
   
-  uint32_t m_routingCost; ///< \brief routing protocol cost (interpretation of the value depends on the underlying routing protocol)
+  int32_t m_routingCost; ///< \brief routing protocol cost (interpretation of the value depends on the underlying routing protocol)
 
   Time m_sRtt;         ///< \brief smoothed round-trip time
   Time m_rttVar;       ///< \brief round-trip time variation
@@ -134,7 +135,7 @@
         boost::multi_index::composite_key<
           CcnxFibFaceMetric,
           boost::multi_index::member<CcnxFibFaceMetric,CcnxFibFaceMetric::Status,&CcnxFibFaceMetric::m_status>,
-          boost::multi_index::member<CcnxFibFaceMetric,uint32_t,&CcnxFibFaceMetric::m_routingCost>
+          boost::multi_index::member<CcnxFibFaceMetric,int32_t,&CcnxFibFaceMetric::m_routingCost>
         >
       >,
 
@@ -158,16 +159,52 @@
    * \brief Constructor
    * \param prefix Prefix for the FIB entry
    */
-  CcnxFibEntry (Ptr<CcnxNameComponents> prefix)
-    : m_prefix (prefix)
-    , m_needsProbing (false)
+  CcnxFibEntry (const CcnxNameComponents &prefix)
+  : m_prefix (Create<CcnxNameComponents> (prefix))
+  , m_needsProbing (false)
   { }
 	
   /**
-   * \brief Update status of FIB next hop
+   * \brief Unary function to update status of FIB next hop
    */
-  void
-  UpdateStatus (Ptr<CcnxFace> face, CcnxFibFaceMetric::Status status);
+  struct UpdateStatus
+  {
+    UpdateStatus (Ptr<CcnxFace> face, CcnxFibFaceMetric::Status status)
+      : m_face (face), m_status (status) {}
+    void operator () (CcnxFibEntry &entry);
+  private:
+    Ptr<CcnxFace> m_face;
+    CcnxFibFaceMetric::Status m_status;
+  };
+
+  /**
+   * \brief Unary function to add or update routing metric of FIB next hop
+   *
+   * Initial status of the next hop is set to YELLOW
+   */
+  struct AddOrUpdateRoutingMetric
+  {
+    AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric)
+      : m_face (face), m_metric (metric) {}
+    void operator () (CcnxFibEntry &entry);
+  private:
+    Ptr<CcnxFace> m_face;
+    int32_t m_metric;
+  };
+
+  /**
+   * \brief Unary function to recalculate smoothed RTT and RTT variation
+   * \param rttSample RTT sample
+   */
+  struct UpdateFaceRtt
+  {
+    UpdateFaceRtt (Ptr<CcnxFace> face, const Time &rttSample)
+      : m_face (face), m_rttSample (rttSample) {};
+    void operator() (CcnxFibEntry &entry);
+  private:
+    Ptr<CcnxFace> m_face;
+    const Time &m_rttSample;
+  };
 
   /**
    * \brief Get prefix for the FIB entry
@@ -223,7 +260,7 @@
  * \ingroup ccnx
  * \brief Class implementing FIB functionality
  */
-class CcnxFib : public Object
+class CcnxFib : public Object, public CcnxFibEntryContainer::type
 {
 public:
   /**
@@ -256,23 +293,24 @@
    * \param interest Interest packet header
    * \returns If entry found a pair <valid_iterator, true> will be returned, otherwise <invalid_iterator, false>
    */
-  std::pair<CcnxFibEntryContainer::type::iterator, bool>
+  CcnxFibEntryContainer::type::iterator
   LongestPrefixMatch (const CcnxInterestHeader &interest) const;
   
   /**
-   * Update FIB entry
+   * \brief Add or update FIB entry
+   *
    * If the entry exists, metric will be updated. Otherwise, new entry will be created
    *
    * Entries in FIB never deleted. They can be invalidated with metric==NETWORK_UNREACHABLE
    *
-   * @param name				Prefix
-   * @param interfaceIndex	Forwarding interface
-   * @param metric			Routing metric
-   * @param nextHop			Nexthop node address (IPv4)
-   * @return true if a new entry created, false otherwise
+   * @param name	Prefix
+   * @param face	Forwarding face
+   * @param metric	Routing metric
    */
-  // bool update( const string &name, int interfaceIndex, int metric, NodeAddress nextHop );
-  // bool update( NodeAddress nodeId, int interfaceIndex, int metric, NodeAddress nextHop );
+  CcnxFibEntryContainer::type::iterator
+  Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric);
+  // bool update( const string &name, int interfaceIndex, int metric);
+  // bool update( NodeAddress nodeId, int interfaceIndex, int metric);
   // Bool update( NodeAddress nodeId, int metric, NodeAddress nextHop );
 
   // // Update Fib from OSPF routing table (through a hack in OSPF algorithm)
@@ -288,14 +326,18 @@
   // void dump( const FibIterator &fib );
 
   // void resetProbing();    //reset needsProbing field for every FibEntry
+
+protected:
+  // inherited from Object class
+  virtual void NotifyNewAggregate ();
+  virtual void DoDispose ();
+  
 private:
   friend std::ostream& operator<< (std::ostream& os, const CcnxFib &fib);
   CcnxFib(const CcnxFib&) {} ; ///< \brief copy constructor is disabled
   
 private:
-  // Ptr<Ccnx> m_node;
-
-  CcnxFibEntryContainer::type m_fib;
+  Ptr<Node> m_node;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/model/ccnx-forwarding-strategy.cc b/model/ccnx-forwarding-strategy.cc
index 112a9bf..b2aa342 100644
--- a/model/ccnx-forwarding-strategy.cc
+++ b/model/ccnx-forwarding-strategy.cc
@@ -34,9 +34,9 @@
   return tid;
 }
 
-CcnxForwardingStrategy::CcnxForwardingStrategy ()
+CcnxForwardingStrategy::CcnxForwardingStrategy (Ptr<CcnxFib> fib)
 {
-  m_fib = CreateObject<CcnxFib> ();
+  m_fib = fib;
 }
 
 
diff --git a/model/ccnx-forwarding-strategy.h b/model/ccnx-forwarding-strategy.h
index 7e310b0..0e6134e 100644
--- a/model/ccnx-forwarding-strategy.h
+++ b/model/ccnx-forwarding-strategy.h
@@ -41,7 +41,7 @@
 public:
   static TypeId GetTypeId (void);
 
-  CcnxForwardingStrategy ();
+  CcnxForwardingStrategy (Ptr<CcnxFib> fib);
 
   typedef
   Callback<void, const Ptr<CcnxFace> &, const Ptr<CcnxInterestHeader> &, const Ptr<Packet> &>
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index a79efde..a4241bc 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -60,10 +60,10 @@
     //                  MakeTraceSourceAccessor (&CcnxL3Protocol::m_rxTrace))
     // .AddTraceSource ("Drop", "Drop ccnx packet",
     //                  MakeTraceSourceAccessor (&CcnxL3Protocol::m_dropTrace))
-    .AddAttribute ("InterfaceList", "The set of Ccnx interfaces associated to this Ccnx stack.",
-                   ObjectVectorValue (),
-                   MakeObjectVectorAccessor (&CcnxL3Protocol::m_faces),
-                   MakeObjectVectorChecker<CcnxFace> ())
+    // .AddAttribute ("InterfaceList", "The set of Ccnx interfaces associated to this Ccnx stack.",
+    //                ObjectVectorValue (),
+    //                MakeObjectVectorAccessor (&CcnxL3Protocol::m_faces),
+    //                MakeObjectVectorChecker<CcnxFace> ())
 
     // .AddTraceSource ("SendOutgoing", "A newly-generated packet by this node is about to be queued for transmission",
     //                  MakeTraceSourceAccessor (&CcnxL3Protocol::m_sendOutgoingTrace))
@@ -91,6 +91,10 @@
 CcnxL3Protocol::SetNode (Ptr<Node> node)
 {
   m_node = node;
+  m_fib = m_node->GetObject<CcnxFib> ();
+  NS_ASSERT_MSG (m_fib != 0, "FIB should be created and aggregated to a node before calling Ccnx::SetNode");
+
+  m_pit->SetFib (m_fib);
 }
 
 /*
@@ -158,6 +162,16 @@
   return face->GetId ();
 }
 
+void
+CcnxL3Protocol::RemoveFace (Ptr<CcnxFace> face)
+{
+  // ask face to register in lower-layer stack
+  face->RegisterProtocolHandler (MakeNullCallback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>&> ());
+  CcnxFaceList::iterator face_it = find (m_faces.begin(), m_faces.end(), face);
+  NS_ASSERT_MSG (face_it != m_faces.end (), "Attempt to remove face that doesn't exist");
+  m_faces.erase (face_it);
+}
+
 Ptr<CcnxFace>
 CcnxL3Protocol::GetFace (uint32_t index) const
 {
@@ -197,18 +211,18 @@
 void 
 CcnxL3Protocol::Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p)
 {
-  if (face->IsUp ())
+  if (!face->IsUp ())
     {
       NS_LOG_LOGIC ("Dropping received packet -- interface is down");
       // m_dropTrace (p, INTERFACE_DOWN, m_node->GetObject<Ccnx> ()/*this*/, face);
       return;
     }
-  NS_LOG_LOGIC ("Packet from face " << &face << " received on node " <<  m_node->GetId ());
+  NS_LOG_LOGIC ("Packet from face " << *face << " received on node " <<  m_node->GetId ());
 
   Ptr<Packet> packet = p->Copy (); // give upper layers a rw copy of the packet
   try
     {
-      CcnxHeaderHelper::Type type = CcnxHeaderHelper::CreateCorrectCcnxHeader (p);
+      CcnxHeaderHelper::Type type = CcnxHeaderHelper::GetCcnxHeaderType (p);
       switch (type)
         {
         case CcnxHeaderHelper::INTEREST:
@@ -276,14 +290,14 @@
   CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry.m_incoming.find (incomingFace);
   CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry.m_outgoing.find (incomingFace);
   
-  // suppress interest if 
-  if (pitEntry.m_incoming.size () == 0 || // new PIT entry
-      inFace ==pitEntry.m_incoming.end ()) // existing entry, but interest received via different face
-    {
-      m_droppedInterestsTrace (header, NDN_SUPPRESSED_INTEREST,
-                               m_node->GetObject<Ccnx> ()/*this*/, incomingFace);
-      return;
-    }
+  // // suppress interest if 
+  // if (pitEntry.m_incoming.size () != 0 && // not a new PIT entry and
+  //     inFace != pitEntry.m_incoming.end ()) // existing entry, but interest received via different face
+  //   {
+  //     m_droppedInterestsTrace (header, NDN_SUPPRESSED_INTEREST,
+  //                              m_node->GetObject<Ccnx> ()/*this*/, incomingFace);
+  //     return;
+  //   }
 
   NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
 
@@ -324,9 +338,9 @@
 
       // Note that with MultiIndex we need to modify entries indirectly
   
-      // Update metric status for the incoming interface in the corresponding FIB entry 
-      m_pit->modify (m_pit->iterator_to (pitEntry),
-                    CcnxPitEntry::UpdateFibStatus (incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
+      // Update metric status for the incoming interface in the corresponding FIB entry
+      m_fib->modify (m_fib->iterator_to (pitEntry.m_fibEntry),
+                     CcnxFibEntry::UpdateStatus (incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
   
       // Add or update entry in the content store
       m_contentStore->Add (header, payload);
@@ -337,7 +351,8 @@
       // If we have sent interest for this data via this face, then update stats.
       if (out != pitEntry.m_outgoing.end ())
         {
-          m_pit->modify (m_pit->iterator_to (pitEntry), CcnxPitEntry::EstimateRttAndRemoveFace(out));
+          m_pit->modify (m_pit->iterator_to (pitEntry),
+                         CcnxPitEntry::EstimateRttAndRemoveFace(out, m_fib));
           // face will be removed in the above call
         }
       else
diff --git a/model/ccnx-l3-protocol.h b/model/ccnx-l3-protocol.h
index 4adf03f..f61b7b8 100644
--- a/model/ccnx-l3-protocol.h
+++ b/model/ccnx-l3-protocol.h
@@ -130,10 +130,18 @@
                                   const Ptr<Packet> &packet);
   virtual void Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p);
 
-  virtual uint32_t AddFace (const Ptr<CcnxFace> &face);
-  virtual uint32_t GetNFaces () const;
-  virtual Ptr<CcnxFace> GetFace (uint32_t face) const;
+  virtual uint32_t
+  AddFace (const Ptr<CcnxFace> &face);
+  
+  virtual uint32_t
+  GetNFaces () const;
+  
+  virtual Ptr<CcnxFace>
+  GetFace (uint32_t face) const;
 
+  virtual void
+  RemoveFace (Ptr<CcnxFace> face);
+  
 protected:
   /**
    * \brief Actual processing of incoming CCNx interests. Note, interests do not have payload
@@ -201,6 +209,7 @@
 
   Ptr<CcnxRit> m_rit; ///< \brief RIT (recently interest table)
   Ptr<CcnxPit> m_pit; ///< \brief PIT (pending interest table)
+  Ptr<CcnxFib> m_fib; ///< \brief FIB  
   Ptr<CcnxContentStore> m_contentStore; ///< \brief Content store (for caching purposes only)
   
   TracedCallback<Ptr<const CcnxInterestHeader>,
diff --git a/model/ccnx-local-face.cc b/model/ccnx-local-face.cc
index c047934..aa2c787 100644
--- a/model/ccnx-local-face.cc
+++ b/model/ccnx-local-face.cc
@@ -16,7 +16,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author:  Alexander Afanasyev <alexander.afanasyev@ucla.edu>
-            Ilya Moiseenko <iliamo@cs.ucla.edu>
+ *          Ilya Moiseenko <iliamo@cs.ucla.edu>
  *
  */
 
@@ -26,26 +26,32 @@
 #include "ns3/packet.h"
 #include "ns3/node.h"
 #include "ns3/pointer.h"
-#include "ns3/assert.h" 
+#include "ns3/assert.h"
+
+#include "ns3/ccnx-header-helper.h"
+#include "ccnx-interest-header.h"
+#include "ccnx-content-object-header.h"
 
 NS_LOG_COMPONENT_DEFINE ("CcnxLocalFace");
 
 namespace ns3 
 {
 
-NS_OBJECT_ENSURE_REGISTERED (CcnxLocalFace);
+// NS_OBJECT_ENSURE_REGISTERED (CcnxLocalFace);
 
-TypeId 
-CcnxLocalFace::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::CcnxLocalFace")
-    .SetGroupName ("Ccnx")
-    .SetParent<CcnxFace> ()
-  ;
-  return tid;
-}
+// TypeId 
+// CcnxLocalFace::GetTypeId (void)
+// {
+//   static TypeId tid = TypeId ("ns3::CcnxLocalFace")
+//     .SetGroupName ("Ccnx")
+//     .SetParent<CcnxFace> ()
+//   ;
+//   return tid;
+// }
 
 CcnxLocalFace::CcnxLocalFace () 
+  : m_onInterest (0)
+  , m_onContentObject (0)
 {
   NS_LOG_FUNCTION (this);
 }
@@ -56,19 +62,24 @@
 }
 
 void
-CcnxLocalFace::DoDispose (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  CcnxFace::DoDispose ();
-}
-
-void
 CcnxLocalFace::RegisterProtocolHandler (ProtocolHandler handler)
 {
   m_protocolHandler = handler;
 }
 
 void
+CcnxLocalFace::SetInterestHandler (InterestHandler onInterest)
+{
+  m_onInterest = onInterest;
+}
+
+void
+CcnxLocalFace::SetContentObjectHandler (ContentObjectHandler onContentObject)
+{
+  m_onContentObject = onContentObject;
+}
+
+void
 CcnxLocalFace::Send (Ptr<Packet> p)
 {
   NS_LOG_FUNCTION (*p);
@@ -77,19 +88,47 @@
       return;
     }
 
-  
-}
-    
-void
-CcnxLocalFace::Receive (Ptr<Packet> p)
-{
-    //ypedef Callback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>& > ProtocolHandler;
-    m_protocolHandler ((const Ptr<CcnxFace>)this,(const Ptr<Packet>)p);
+  try
+    {
+      CcnxHeaderHelper::Type type = CcnxHeaderHelper::GetCcnxHeaderType (p);
+      switch (type)
+        {
+        case CcnxHeaderHelper::INTEREST:
+          if (!m_onInterest.IsNull ())
+            {
+              Ptr<CcnxInterestHeader> header = Create<CcnxInterestHeader> ();
+              p->RemoveHeader (*header);
+              m_onInterest (header);
+            }
+          break;
+        case CcnxHeaderHelper::CONTENT_OBJECT:
+          if (!m_onContentObject.IsNull ())
+            {
+              static CcnxContentObjectTail tail;
+              Ptr<CcnxContentObjectHeader> header = Create<CcnxContentObjectHeader> ();
+              p->RemoveHeader (*header);
+              p->RemoveTrailer (tail);
+              m_onContentObject (header, p/*payload*/);
+            }
+          break;
+        }
+    }
+  catch (CcnxUnknownHeaderException)
+    {
+      NS_LOG_ERROR ("Unknown header type");
+    }
 }
 
-std::ostream& operator<< (std::ostream& os, const CcnxLocalFace &localFace)
+// propagate interest down to ccnx stack
+void
+CcnxLocalFace::ReceiveFromApplication (Ptr<Packet> p)
 {
-  os << "dev=local";
+  m_protocolHandler (Ptr<CcnxFace>(this), p);
+}
+
+std::ostream& CcnxLocalFace::Print (std::ostream& os) const
+{
+  os << "dev=local(" << GetId() << ")";
   return os;
 }
 
diff --git a/model/ccnx-local-face.h b/model/ccnx-local-face.h
index 3510eba..24cca9f 100644
--- a/model/ccnx-local-face.h
+++ b/model/ccnx-local-face.h
@@ -27,6 +27,10 @@
 namespace ns3 
 {
 
+class CcnxInterestHeader;
+class CcnxContentObjectHeader;
+class Packet;
+
 /**
  * \ingroup ccnx-face
  * \brief Implementation of application CCNx face
@@ -40,12 +44,9 @@
 class CcnxLocalFace  : public CcnxFace
 {
 public:
-  /**
-   * \brief Interface ID
-   *
-   * \return interface ID
-   */
-  static TypeId GetTypeId (void);
+  typedef Callback<void,const Ptr<const CcnxInterestHeader> &> InterestHandler;
+  typedef Callback<void,const Ptr<const CcnxContentObjectHeader> &,
+                        const Ptr<const Packet> &> ContentObjectHandler;
 
   /**
    * \brief Default constructor
@@ -55,23 +56,49 @@
   
   ////////////////////////////////////////////////////////////////////
   // methods overloaded from CcnxFace
-  
-  virtual void RegisterProtocolHandler (ProtocolHandler handler);
 
-  virtual void Send (Ptr<Packet> p);
+  /**
+   * \brief This method should be called to establish link with lower layers
+   */
+  virtual void
+  RegisterProtocolHandler (ProtocolHandler handler);
 
-  void Receive (Ptr<Packet> p);
+  /**
+   * \brief This method will be called by lower layers to send data to *application*
+   */
+  virtual void
+  Send (Ptr<Packet> p);
 
+  virtual std::ostream&
+  Print (std::ostream &os) const;
   ////////////////////////////////////////////////////////////////////
 
-  /// \todo Need methods to implement application hooks
-  
-protected:
-  virtual void DoDispose (void);
+   /**
+   * \brief This method will be called by higher layers to send data to *ccnx stack*
+   */
+  void ReceiveFromApplication (Ptr<Packet> p);
 
+  /**
+   * \brief Set callback to application
+   *
+   * \param onInterest InterestHandler to be called when interest arrives on the face. Will be disabled if 0
+   */
+  void SetInterestHandler (InterestHandler onInterest);
+
+    /**
+   * \brief Set callback to application
+   *
+   * \param onContentObject ContentObjectHandler to be called when data arrives. Will be disabled if 0
+   */
+  void SetContentObjectHandler (ContentObjectHandler onContentObject);
+ 
 private:
   CcnxLocalFace (const CcnxLocalFace &); ///< \brief Disabled copy constructor
   CcnxLocalFace& operator= (const CcnxLocalFace &); ///< \brief Disabled copy operator
+
+private:
+  InterestHandler m_onInterest;
+  ContentObjectHandler m_onContentObject;
 };
 
 std::ostream& operator<< (std::ostream& os, const CcnxLocalFace &localFace);
diff --git a/model/ccnx-name-components.cc b/model/ccnx-name-components.cc
index 303e987..438e179 100644
--- a/model/ccnx-name-components.cc
+++ b/model/ccnx-name-components.cc
@@ -20,11 +20,14 @@
 
 #include "ccnx-name-components.h"
 #include <boost/foreach.hpp>
+#include "ns3/log.h"
 
 #include <iostream>
 
 using namespace std;
 
+NS_LOG_COMPONENT_DEFINE ("CcnxNameComponents");
+
 namespace ns3 {
 
 ATTRIBUTE_HELPER_CPP (CcnxNameComponents);
@@ -33,10 +36,10 @@
 {
 }
 
-CcnxNameComponents::CcnxNameComponents (const string &s)
-{
-  m_prefix.push_back (s);
-}
+// CcnxNameComponents::CcnxNameComponents (const string &s)
+// {
+//   m_prefix.push_back (s);
+// }
 
 CcnxNameComponents::CcnxNameComponents (const std::list<boost::reference_wrapper<const std::string> > &components)
 {
@@ -106,19 +109,21 @@
 operator >> (std::istream &is, CcnxNameComponents &components)
 {
   istream_iterator<char> eos; // end of stream
-
+  
   std::string component = "";
   for (istream_iterator<char> it (is); it != eos; it++)
     {
       if (*it == '/')
         {
           if (component != "")
-            components.Add (component);
+              components.Add (component);
           component = "";
         }
       else
         component.push_back (*it);
     }
+  if (component != "")
+      components.Add (component);
 
   return is;
 }
diff --git a/model/ccnx-name-components.h b/model/ccnx-name-components.h
index 7e2bb71..ea64635 100644
--- a/model/ccnx-name-components.h
+++ b/model/ccnx-name-components.h
@@ -41,7 +41,7 @@
    * \brief Creates a prefix with zero components (can be looked as root "/")
    */
   CcnxNameComponents ();
-  CcnxNameComponents (const std::string &s);
+  // CcnxNameComponents (const std::string &s);
   CcnxNameComponents (const std::list<boost::reference_wrapper<const std::string> > &components);
   
   inline void
diff --git a/model/ccnx-net-device-face.cc b/model/ccnx-net-device-face.cc
index 9bdcd43..8304711 100644
--- a/model/ccnx-net-device-face.cc
+++ b/model/ccnx-net-device-face.cc
@@ -32,17 +32,17 @@
 
 namespace ns3 {
 
-NS_OBJECT_ENSURE_REGISTERED (CcnxNetDeviceFace);
+// NS_OBJECT_ENSURE_REGISTERED (CcnxNetDeviceFace);
 
-TypeId 
-CcnxNetDeviceFace::GetTypeId ()
-{
-  static TypeId tid = TypeId ("ns3::CcnxNetDeviceFace")
-    .SetGroupName ("Ccnx")
-    .SetParent<CcnxFace> ()
-  ;
-  return tid;
-}
+// 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
@@ -69,15 +69,6 @@
   return *this;
 }
 
-  
-void
-CcnxNetDeviceFace::DoDispose (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_netDevice = 0;
-  Object::DoDispose ();
-}
-
 Ptr<NetDevice>
 CcnxNetDeviceFace::GetNetDevice () const
 {
@@ -126,11 +117,11 @@
 }
 
 
-std::ostream& operator<< (std::ostream& os, const CcnxNetDeviceFace &face)
+std::ostream&
+CcnxNetDeviceFace::Print (std::ostream& os) const
 {
-  return operator<< (os, static_cast<const CcnxFace&> (face)); // just call parent class for now
-  // os << "id=" << face.GetId ();
-  // return os;
+  os << "dev=net(" << GetId () << ")";
+  return os;
 }
 
 }; // namespace ns3
diff --git a/model/ccnx-net-device-face.h b/model/ccnx-net-device-face.h
index baf6a48..6307413 100644
--- a/model/ccnx-net-device-face.h
+++ b/model/ccnx-net-device-face.h
@@ -45,12 +45,12 @@
 class CcnxNetDeviceFace  : public CcnxFace
 {
 public:
-  /**
-   * \brief Interface ID
-   *
-   * \return interface ID
-   */
-  static TypeId GetTypeId (void);
+  // /**
+  //  * \brief Interface ID
+  //  *
+  //  * \return interface ID
+  //  */
+  // static TypeId GetTypeId (void);
 
   /**
    * \brief Constructor
@@ -64,10 +64,14 @@
   ////////////////////////////////////////////////////////////////////
   // methods overloaded from CcnxFace
   
-  virtual void RegisterProtocolHandler (ProtocolHandler handler);
+  virtual void
+  RegisterProtocolHandler (ProtocolHandler handler);
 
-  virtual void Send (Ptr<Packet> p);
+  virtual void
+  Send (Ptr<Packet> p);
 
+  virtual std::ostream&
+  Print (std::ostream &os) const;
   ////////////////////////////////////////////////////////////////////
 
   /**
@@ -76,9 +80,6 @@
    * \returns smart pointer to NetDevice associated with the face
    */
   Ptr<NetDevice> GetNetDevice () const;
-  
-protected:
-  virtual void DoDispose ();
 
 private:
   CcnxNetDeviceFace (const CcnxNetDeviceFace &); ///< \brief Disabled copy constructor
@@ -96,8 +97,6 @@
   Ptr<NetDevice> m_netDevice; ///< \brief Smart pointer to NetDevice
 };
 
-std::ostream& operator<< (std::ostream& os, const CcnxNetDeviceFace &face);
-
 } // namespace ns3
 
 #endif //CCNX_NET_DEVICE_FACE_H
diff --git a/model/ccnx-pit-entry.cc b/model/ccnx-pit-entry.cc
index b9ca8d4..a79f6b7 100644
--- a/model/ccnx-pit-entry.cc
+++ b/model/ccnx-pit-entry.cc
@@ -67,9 +67,9 @@
 // };
 
 
-CcnxPitEntry::CcnxPitEntry (Ptr<CcnxNameComponents> prefix)
+CcnxPitEntry::CcnxPitEntry (Ptr<CcnxNameComponents> prefix, const CcnxFibEntry &fibEntry)
   : m_prefix (prefix)
-  , m_fib (0)
+  , m_fibEntry (fibEntry)
   // , m_expireTime (?)
   , m_timerExpired (false)
   , m_counterExpirations (0)
@@ -82,16 +82,16 @@
   return *m_prefix;
 }
 
-CcnxPitEntry::SetFibEntry::SetFibEntry (Ptr<CcnxFibEntry> fib)
-  : m_fib (fib)
-{
-}
+// CcnxPitEntry::SetFibEntry::SetFibEntry (Ptr<CcnxFibEntry> fib)
+//   : m_fib (fib)
+// {
+// }
 
-void
-CcnxPitEntry::SetFibEntry::operator() (CcnxPitEntry &entry)
-{
-  entry.m_fib = m_fib;
-}
+// void
+// CcnxPitEntry::SetFibEntry::operator() (CcnxPitEntry &entry)
+// {
+//   entry.m_fib = m_fib;
+// }
 
 void
 CcnxPitEntry::AddIncoming::operator() (CcnxPitEntry &entry)
@@ -132,7 +132,8 @@
 void
 CcnxPitEntry::UpdateFibStatus::operator() (CcnxPitEntry &entry)
 {
-  entry.m_fib->UpdateStatus (m_face, m_status);
+  NS_ASSERT_MSG (false, "Broken");
+  // entry.m_fib->UpdateStatus (m_face, m_status);
 }
 
 void
@@ -142,12 +143,9 @@
   if (m_outFace->m_retxNum>0)
     return;
 
-  CcnxFibFaceMetricContainer::type::iterator metric = entry.m_fib->m_faces.find (m_outFace->m_face);
-  NS_ASSERT_MSG (metric != entry.m_fib->m_faces.end (),
-                 "Something wrong. Cannot find entry for the face in FIB");
-
-  Time rtt = Simulator::Now() - m_outFace->m_sendTime;
-  entry.m_fib->m_faces.modify (metric, CcnxFibFaceMetric::UpdateRtt (rtt));
+  m_fib->modify (m_fib->iterator_to (entry.m_fibEntry),
+                CcnxFibEntry::UpdateFaceRtt (m_outFace->m_face,
+                                             Simulator::Now() - m_outFace->m_sendTime));
 
   entry.m_outgoing.erase (m_outFace);
 }
diff --git a/model/ccnx-pit-entry.h b/model/ccnx-pit-entry.h
index 842bd88..ac16c21 100644
--- a/model/ccnx-pit-entry.h
+++ b/model/ccnx-pit-entry.h
@@ -100,24 +100,24 @@
   /**
    * \brief PIT entry constructor
    * \param prefix Prefix of the PIT entry
-   * \param fib A FIB entry associated with the PIT entry
+   * \param fibEntry A FIB entry associated with the PIT entry
    */
-  CcnxPitEntry (Ptr<CcnxNameComponents> prefix);
+  CcnxPitEntry (Ptr<CcnxNameComponents> prefix, const CcnxFibEntry &fibEntry);
   
   // // Get number of outgoing interests that we're expecting data from
   // inline size_t numberOfPromisingInterests( ) const; 
 
-  /**
-   * \brief Unary function to set or update FIB entry with this PIT entry
-   * \param fib smart pointer to FIB entry
-   */
-  struct SetFibEntry
-  {
-    SetFibEntry (Ptr<CcnxFibEntry> fib);
-    void operator() (CcnxPitEntry &entry);
-  private:
-    Ptr<CcnxFibEntry> m_fib;
-  };
+  // /**
+  //  * \brief Unary function to set or update FIB entry with this PIT entry
+  //  * \param fib smart pointer to FIB entry
+  //  */
+  // struct SetFibEntry
+  // {
+  //   SetFibEntry (Ptr<CcnxFibEntry> fib);
+  //   void operator() (CcnxPitEntry &entry);
+  // private:
+  //   Ptr<CcnxFibEntry> m_fib;
+  // };
   
   /**
    * \brief Unary Function to add incoming interest to the PIT entry
@@ -202,11 +202,12 @@
    */
   struct EstimateRttAndRemoveFace
   {
-    EstimateRttAndRemoveFace (CcnxPitEntryOutgoingFaceContainer::type::iterator outFace)
-      : m_outFace (outFace) { };
+    EstimateRttAndRemoveFace (CcnxPitEntryOutgoingFaceContainer::type::iterator outFace, Ptr<CcnxFib> fib)
+      : m_outFace (outFace), m_fib (fib) { };
     void operator() (CcnxPitEntry &entry);
   private:
     CcnxPitEntryOutgoingFaceContainer::type::iterator m_outFace;
+    Ptr<CcnxFib> m_fib;
   };
 
   const CcnxNameComponents &
@@ -220,7 +221,7 @@
   
 public:
   Ptr<CcnxNameComponents> m_prefix; ///< \brief Prefix of the PIT entry
-  Ptr<CcnxFibEntry> m_fib; ///< \brief FIB entry related to this prefix
+  const CcnxFibEntry &m_fibEntry; ///< \brief FIB entry related to this prefix
   
   CcnxPitEntryIncomingFaceContainer::type m_incoming; ///< \brief container for incoming interests
   CcnxPitEntryOutgoingFaceContainer::type m_outgoing; ///< \brief container for outgoing interests
diff --git a/model/ccnx-pit.cc b/model/ccnx-pit.cc
index 614c89c..51c09b4 100644
--- a/model/ccnx-pit.cc
+++ b/model/ccnx-pit.cc
@@ -109,13 +109,22 @@
                                         &CcnxPit::CleanExpired, this); 
 }
 
+void
+CcnxPit::SetFib (Ptr<CcnxFib> fib)
+{
+  m_fib = fib;
+}
+
+
 const CcnxPitEntry&
 CcnxPit::Lookup (const CcnxContentObjectHeader &header) const
 {
+  NS_LOG_FUNCTION_NOARGS ();
+
   CcnxPitEntryContainer::type::iterator entry =
     get<i_prefix> ().find (header.GetName ());
 
-  if (entry != end ())
+  if (entry == end ())
     throw CcnxPitEntryNotFound();
 
   return *entry;
@@ -124,12 +133,23 @@
 const CcnxPitEntry&
 CcnxPit::Lookup (const CcnxInterestHeader &header)
 {
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_ASSERT_MSG (m_fib != 0, "FIB should be set");
+
   CcnxPitEntryContainer::type::iterator entry =
     get<i_prefix> ().find (header.GetName ());
 
-  if (entry != end ())
-    entry = insert (end (), CcnxPitEntry (Create<CcnxNameComponents> (header.GetName ())));
-
+  CcnxFibEntryContainer::type::iterator fibEntry = m_fib->LongestPrefixMatch (header);
+  if (fibEntry == m_fib->end ())
+    {
+      NS_LOG_WARN ("FIB entry wasn't found. Creating an empty record");
+      fibEntry = m_fib->insert (m_fib->end (), CcnxFibEntry (header.GetName ()));
+    }
+  
+  if (entry == end ())
+    entry = insert (end (),
+                    CcnxPitEntry (Create<CcnxNameComponents> (header.GetName ()),
+                                  *fibEntry));
   return *entry;
 }
 
diff --git a/model/ccnx-pit.h b/model/ccnx-pit.h
index 44fb977..cf00604 100644
--- a/model/ccnx-pit.h
+++ b/model/ccnx-pit.h
@@ -164,6 +164,11 @@
    */
   Time GetCleanupTimeout () const;
 
+  /**
+   * \brief Set FIB table
+   */
+  void SetFib (Ptr<CcnxFib> fib);
+
 public:
   // PitBucket				 maxBucketsPerInterface; // maximum number of buckets. Automatically computed based on link capacity
   // // averaging over 1 second (bandwidth * 1second)
@@ -179,6 +184,7 @@
   Time    m_cleanupTimeout; ///< \brief Configurable timeout of how often cleanup events are working
   EventId m_cleanupEvent;   ///< \brief Cleanup event
 
+  Ptr<CcnxFib> m_fib; ///< \brief Link to FIB table
   // PitBucket	m_bucketsPerInterface;	///< \brief pending interface counter per interface
 };
 
diff --git a/model/ccnx-rit.cc b/model/ccnx-rit.cc
index 1eb1a74..c3db1ae 100644
--- a/model/ccnx-rit.cc
+++ b/model/ccnx-rit.cc
@@ -125,6 +125,7 @@
 bool
 CcnxRit::WasRecentlySatisfied (const CcnxInterestHeader &header)
 {
+  NS_LOG_FUNCTION_NOARGS ();
   std::pair<CcnxRitByNonce::type::iterator,CcnxRitByNonce::type::iterator>
     entries = get<nonce> ().equal_range (header.GetNonce ());
   
@@ -145,6 +146,7 @@
 void
 CcnxRit::SetRecentlySatisfied (const CcnxInterestHeader &header)
 {
+  NS_LOG_FUNCTION_NOARGS ();
   NS_ASSERT_MSG (!WasRecentlySatisfied (header), "Duplicate recent interest should not be added to RIT");
   
   get<timestamp> ().push_back (
@@ -157,27 +159,27 @@
 
 void CcnxRit::CleanExpired ()
 {
-  NS_LOG_LOGIC ("Cleaning RIT");
+  // NS_LOG_LOGIC ("Cleaning RIT");
   Time now = Simulator::Now ();
-#ifdef _DEBUG
-  uint32_t count = 0;
-#endif
+// #ifdef _DEBUG
+//   uint32_t count = 0;
+// #endif
   
   while( !empty() )
     {
       if( get<timestamp> ().front ().m_expireTime <= now ) // is the record stale?
         {
          get<timestamp> ().pop_front( );
-#ifdef _DEBUG
-         count++;
-#endif
+// #ifdef _DEBUG
+//          count++;
+// #endif
         }
       else
         break; // nothing else to do. All later records will not be stale
     }
-#ifdef _DEBUG
-  NS_LOG_DEBUG (count << " records cleaned");
-#endif
+// #ifdef _DEBUG
+//   NS_LOG_DEBUG (count << " records cleaned");
+// #endif
   
   // schedule next even
   m_cleanupEvent = Simulator::Schedule (Simulator::Now () + m_cleanupTimeout,
diff --git a/model/ccnx.h b/model/ccnx.h
index 29258ea..a88716a 100644
--- a/model/ccnx.h
+++ b/model/ccnx.h
@@ -168,11 +168,18 @@
   GetNFaces (void) const = 0;
 
   /**
+   * \brief Get face by face index
    * \param face The face number of an Ccnx interface.
    * \returns The CcnxFace associated with the Ccnx face number.
    */
   virtual Ptr<CcnxFace>
   GetFace (uint32_t face) const = 0;
+
+  /**
+   * \brief Remove face from ccnx stack (remove callbacks)
+   */
+  virtual void
+  RemoveFace (Ptr<CcnxFace> face) = 0;
 };
 
 } // namespace ns3