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/apps/ccnx-consumer.cc b/apps/ccnx-consumer.cc
index 0e6ec9e..71aac13 100644
--- a/apps/ccnx-consumer.cc
+++ b/apps/ccnx-consumer.cc
@@ -19,6 +19,11 @@
  */
 
 #include "ccnx-consumer.h"
+#include "ns3/ptr.h"
+#include "ns3/ccnx-local-face.h"
+#include "ns3/ccnx.h"
+#include "ns3/callback.h"
+#include "ns3/ccnx-content-object-header.h"
 
 NS_LOG_COMPONENT_DEFINE ("CcnxConsumer");
 
@@ -31,49 +36,45 @@
 CcnxConsumer::GetTypeId (void)
 {
     static TypeId tid = TypeId ("ns3::CcnxConsumer")
-    .SetParent<Application> ()
-    .AddConstructor<CcnxConsumer> ()
-    .AddAttribute ("OffTime", "Time interval between packets",
-                    TimeValue (Seconds (0.1)),
-                    MakeTimeAccessor (&CcnxConsumer::m_offTime),
-                    MakeTimeChecker ())
-    .AddAttribute ("Face","Local face to be used",
-                    PointerValue (CreateObject<CcnxLocalFace> ()),
-                    MakePointerAccessor (&CcnxConsumer::m_face),
-                    MakePointerChecker<CcnxLocalFace> ())
-    .AddAttribute ("InterestName","CcnxName of the Interest (use CcnxNameComponents)",
-                    CcnxNameComponentsValue (CcnxNameComponents ()),
-                    MakeCcnxNameComponentsAccessor (&CcnxConsumer::m_interestName),
-                    MakeCcnxNameComponentsChecker ())
-    .AddAttribute ("LifeTime", "LifeTime fo interest packet",
-                    TimeValue (Seconds (4.0)),
-                    MakeTimeAccessor (&CcnxConsumer::m_interestLifeTime),
-                    MakeTimeChecker ())
-    .AddAttribute ("MinSuffixComponents", "MinSuffixComponents",
-                    IntegerValue(-1),
-                    MakeIntegerAccessor(&CcnxConsumer::m_minSuffixComponents),
-                    MakeIntegerChecker<int32_t>())
-    .AddAttribute ("MaxSuffixComponents", "MaxSuffixComponents",
-                    IntegerValue(-1),
-                    MakeIntegerAccessor(&CcnxConsumer::m_maxSuffixComponents),
-                    MakeIntegerChecker<int32_t>())
-    .AddAttribute ("ChildSelector", "ChildSelector",
-                    BooleanValue(false),
-                    MakeBooleanAccessor(&CcnxConsumer::m_childSelector),
-                    MakeBooleanChecker())
-    .AddAttribute ("Exclude", "only simple name matching is supported (use CcnxNameComponents)",
-                   CcnxNameComponentsValue (CcnxNameComponents ()),
-                   MakeCcnxNameComponentsAccessor (&CcnxConsumer::m_exclude),
-                   MakeCcnxNameComponentsChecker ())
-    .AddAttribute ("Initial Nonce", "If 0 then nonce is not used",
-                    UintegerValue(1),
-                    MakeUintegerAccessor(&CcnxConsumer::m_initialNonce),
-                    MakeUintegerChecker<uint32_t>())
-    .AddTraceSource ("InterestTrace", "Interests that were sent",
-                     MakeTraceSourceAccessor (&CcnxConsumer::m_interestsTrace))
-    .AddTraceSource ("ContentObjectTrace", "ContentObjects that were received",
-                     MakeTraceSourceAccessor (&CcnxConsumer::m_contentObjectsTrace))
-    ;
+      .SetParent<Application> ()
+      .AddConstructor<CcnxConsumer> ()
+      .AddAttribute ("OffTime", "Time interval between packets",
+                     TimeValue (Seconds (0.1)),
+                     MakeTimeAccessor (&CcnxConsumer::m_offTime),
+                     MakeTimeChecker ())
+      .AddAttribute ("InterestName","CcnxName of the Interest (use CcnxNameComponents)",
+                     CcnxNameComponentsValue (),
+                     MakeCcnxNameComponentsAccessor (&CcnxConsumer::m_interestName),
+                     MakeCcnxNameComponentsChecker ())
+      .AddAttribute ("LifeTime", "LifeTime fo interest packet",
+                     TimeValue (Seconds (0)),
+                     MakeTimeAccessor (&CcnxConsumer::m_interestLifeTime),
+                     MakeTimeChecker ())
+      .AddAttribute ("MinSuffixComponents", "MinSuffixComponents",
+                     IntegerValue(-1),
+                     MakeIntegerAccessor(&CcnxConsumer::m_minSuffixComponents),
+                     MakeIntegerChecker<int32_t>())
+      .AddAttribute ("MaxSuffixComponents", "MaxSuffixComponents",
+                     IntegerValue(-1),
+                     MakeIntegerAccessor(&CcnxConsumer::m_maxSuffixComponents),
+                     MakeIntegerChecker<int32_t>())
+      .AddAttribute ("ChildSelector", "ChildSelector",
+                     BooleanValue(false),
+                     MakeBooleanAccessor(&CcnxConsumer::m_childSelector),
+                     MakeBooleanChecker())
+      .AddAttribute ("Exclude", "only simple name matching is supported (use CcnxNameComponents)",
+                     CcnxNameComponentsValue (),
+                     MakeCcnxNameComponentsAccessor (&CcnxConsumer::m_exclude),
+                     MakeCcnxNameComponentsChecker ())
+      .AddAttribute ("Initial Nonce", "If 0 then nonce is not used",
+                     UintegerValue(1),
+                     MakeUintegerAccessor(&CcnxConsumer::m_initialNonce),
+                     MakeUintegerChecker<uint32_t>())
+      .AddTraceSource ("InterestTrace", "Interests that were sent",
+                       MakeTraceSourceAccessor (&CcnxConsumer::m_interestsTrace))
+      .AddTraceSource ("ContentObjectTrace", "ContentObjects that were received",
+                       MakeTraceSourceAccessor (&CcnxConsumer::m_contentObjectsTrace))
+      ;
 
     return tid;
 }
@@ -101,7 +102,24 @@
 CcnxConsumer::StartApplication () // Called at time specified by Start
 {
     NS_LOG_FUNCTION_NOARGS ();
-    ScheduleNextTx();
+
+    NS_ASSERT_MSG (m_face == 0, "Face should not exist");
+    m_face = Create<CcnxLocalFace> ();
+
+    // step 1. Set up forwarding from face to application
+    m_face->SetNode (GetNode ());
+    m_face->SetContentObjectHandler (MakeCallback (&CcnxConsumer::OnContentObject, this));
+
+    // step 2. Set up forwarding to and from ccnx
+    NS_ASSERT_MSG (GetNode ()->GetObject<Ccnx> () !=0,
+                   "Ccnx stack should be installed on the node " << GetNode ());
+    GetNode ()->GetObject<Ccnx> ()->AddFace (m_face);
+
+    // step 3. Enable face
+    m_face->SetUp ();
+
+    // Send first packet immediately
+    m_sendEvent = Simulator::Schedule (Seconds(0.0), &CcnxConsumer::SendPacket, this);
 }
     
 void 
@@ -110,6 +128,17 @@
     NS_LOG_FUNCTION_NOARGS ();
         
     CancelEvents ();
+
+    // step 1. Disable face
+    m_face->SetDown ();
+
+    // step 2. Remove face from ccnx stack
+    GetNode ()->GetObject<Ccnx> ()->RemoveFace (m_face);
+
+    // step 3. Disable callbacks
+    m_face->SetContentObjectHandler (MakeNullCallback<void,
+                                                      const Ptr<const CcnxContentObjectHeader> &,
+                                                      const Ptr<const Packet> &> ());
 }
     
 void 
@@ -120,15 +149,6 @@
     Simulator::Cancel (m_sendEvent);
 }
     
-void 
-CcnxConsumer::ScheduleNextTx ()
-{
-    NS_LOG_FUNCTION_NOARGS ();
-        
-    Time nextTime = Seconds(m_offTime);
-    m_sendEvent = Simulator::Schedule (nextTime, &CcnxConsumer::SendPacket, this);
-}
-    
 void
 CcnxConsumer::SendPacket ()
 {
@@ -145,32 +165,28 @@
     interestHeader.SetMaxSuffixComponents(m_maxSuffixComponents);
     interestHeader.SetMinSuffixComponents(m_minSuffixComponents);
         
+    NS_LOG_INFO ("Interest: \n" << interestHeader);
+
     Ptr<Packet> packet = Create<Packet> ();
     packet->AddHeader (interestHeader);
         
-    m_face->Receive(packet);
-        
-    ScheduleNextTx();
+    m_face->ReceiveFromApplication (packet);
+
+    m_sendEvent = Simulator::Schedule (Seconds(m_offTime), &CcnxConsumer::SendPacket, this);
 }
     
+// void
+// CcnxConsumer::OnInterest (const Ptr<const CcnxInterestHeader> &interest)
+// {
+// }
+
 void
-CcnxConsumer::HandlePacket(const Ptr<CcnxFace> &face, const Ptr<const Packet> &packet)
+CcnxConsumer::OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
+                               const Ptr<const Packet> &payload)
 {
-    uint8_t type[2];
-    uint32_t read = packet->CopyData (type,2);
-    if (read!=2)
-    {
-        NS_LOG_INFO ("Unknown CcnxPacket");
-        return;
-    }
-    
-    if (type[0] == INTEREST_BYTE0 && type[1] == INTEREST_BYTE1)
-    {
-        m_interestsTrace(face,packet);
-    }
-    else if (type[0] == CONTENT_OBJECT_BYTE0 && type[1] == CONTENT_OBJECT_BYTE1)
-    {
-        m_contentObjectsTrace(face,packet);
-    }
+  // do stuff
+  NS_LOG_FUNCTION ("Received contentObject " << contentObject );
 }
+
+
 }
diff --git a/apps/ccnx-consumer.h b/apps/ccnx-consumer.h
index ab12105..1b1971f 100644
--- a/apps/ccnx-consumer.h
+++ b/apps/ccnx-consumer.h
@@ -35,8 +35,6 @@
 #include "ns3/boolean.h"
 #include "ns3/integer.h"
 #include "ns3/uinteger.h"
-#include "ns3/random-variable.h"
-#include <limits> 
 #include "ns3/pointer.h"
 #include "ns3/traced-callback.h"
 #include "ns3/ccnx-header-helper.h"
@@ -50,62 +48,49 @@
 class CcnxConsumer: public Application
 {
 public: 
-    static TypeId GetTypeId (void);
+  static TypeId GetTypeId ();
         
-    CcnxConsumer ();
-        
-    virtual ~CcnxConsumer ();
-    
-    void HandlePacket (const Ptr<CcnxFace> &face, const Ptr<const Packet> &packet);
+  CcnxConsumer ();
+  virtual ~CcnxConsumer ();
+
+  void OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
+                        const Ptr<const Packet> &payload);
         
 protected:
-    virtual void DoDispose (void);
+  virtual void DoDispose (void);
+  
 private:
-    // inherited from Application base class.
-    virtual void StartApplication (void);    // Called at time specified by Start
-    virtual void StopApplication (void);     // Called at time specified by Stop
+  // inherited from Application base class.
+  virtual void StartApplication (void);    // Called at time specified by Start
+  virtual void StopApplication (void);     // Called at time specified by Stop
         
-    Time m_offTime;
-    CcnxNameComponents m_interestName;
-    Time m_interestLifeTime;
-    int32_t m_minSuffixComponents;
-    int32_t m_maxSuffixComponents;
-    bool m_childSelector;
-    CcnxNameComponents m_exclude;
-    uint32_t m_initialNonce;
-        
-    EventId         m_sendEvent;    // Eventid of pending "send packet" event
-    TypeId          m_tid;
-    Ptr<CcnxLocalFace> m_face;
-        
-    //helpers
-    void CancelEvents ();
-        
-    void Construct (Ptr<Node> n,
-                    std::string tid,
-                    const Time& offtime,
-                    Ptr<CcnxLocalFace> face,
-                    Ptr<CcnxNameComponents> nameComponents,
-                    const Time& lifetime,
-                    const int32_t& minSuffixComponents,
-                    const int32_t& maxSuffixComponents,
-                    const bool childSelector,
-                    Ptr<CcnxNameComponents> exclude,
-                    const uint32_t& initialNonce
-                    );
-        
-    // Event handlers
-    void StartSending ();
-    void StopSending ();
-    void SendPacket ();
-    //typedef Callback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>& > ProtocolHandler;
+  //helpers
+  void CancelEvents ();
+
+  // Event handlers
+  // void StartSending ();
+  // void StopSending ();
+  void SendPacket ();
+  //typedef Callback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>& > ProtocolHandler;
      
 private:
-    void ScheduleNextTx ();
-    //typedef Callback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>& > ProtocolHandler;
-    
-    TracedCallback<const Ptr<CcnxFace>&,const Ptr<const Packet>& > m_interestsTrace;
-    TracedCallback<const Ptr<CcnxFace>&,const Ptr<const Packet>& > m_contentObjectsTrace;
+  TracedCallback<const Ptr<CcnxFace>&,const Ptr<const Packet>& > m_interestsTrace;
+  TracedCallback<const Ptr<CcnxFace>&,const Ptr<const Packet>& > m_contentObjectsTrace;
+
+  Time m_offTime;
+  CcnxNameComponents m_interestName;
+  Time m_interestLifeTime;
+  int32_t m_minSuffixComponents;
+  int32_t m_maxSuffixComponents;
+  bool m_childSelector;
+  CcnxNameComponents m_exclude;
+  uint32_t m_initialNonce;
+        
+  EventId         m_sendEvent;    // Eventid of pending "send packet" event
+  TypeId          m_tid;
+  Ptr<CcnxLocalFace> m_face;
 };
-}
+
+} // namespace ns3
+
 #endif
diff --git a/apps/ccnx-interest-sender.cc b/apps/ccnx-interest-sender.cc
index c3ecc59..bcf3d76 100644
--- a/apps/ccnx-interest-sender.cc
+++ b/apps/ccnx-interest-sender.cc
@@ -37,10 +37,11 @@
                    TimeValue (Seconds (0.1)),
                    MakeTimeAccessor (&CcnxInterestSender::m_offTime),
                    MakeTimeChecker ())
-    .AddAttribute ("Face","Local face to be used",
-                   PointerValue (CreateObject<CcnxLocalFace> ()),
-                   MakePointerAccessor (&CcnxInterestSender::m_face),
-                   MakePointerChecker<CcnxLocalFace> ())
+    // Alex: this is incorrect. SetNode call is not called if face is created using this accessor
+    // .AddAttribute ("Face","Local face to be used",
+    //                PointerValue (CreateObject<CcnxLocalFace> ()),
+    //                MakePointerAccessor (&CcnxInterestSender::m_face),
+    //                MakePointerChecker<CcnxLocalFace> ())
     .AddAttribute ("NameComponents","CcnxName of the Interest (use CcnxNameComponents)",
                    CcnxNameComponentsValue (CcnxNameComponents (/* root */)),
                    MakeCcnxNameComponentsAccessor (&CcnxInterestSender::m_interestName),
diff --git a/apps/ccnx-producer.cc b/apps/ccnx-producer.cc
index 43964b1..7e0757a 100644
--- a/apps/ccnx-producer.cc
+++ b/apps/ccnx-producer.cc
@@ -34,10 +34,11 @@
     static TypeId tid = TypeId ("ns3::CcnxProducer")
     .SetParent<Application> ()
     .AddConstructor<CcnxProducer> ()
-    .AddAttribute ("Face","Local face to be used",
-                    PointerValue (CreateObject<CcnxLocalFace> ()),
-                    MakePointerAccessor (&CcnxProducer::m_face),
-                    MakePointerChecker<CcnxLocalFace> ())
+    // Alex: this is incorrect. SetNode call is not called if face is created using this accessor
+    // .AddAttribute ("Face","Local face to be used",
+    //                 PointerValue (CreateObject<CcnxLocalFace> ()),
+    //                 MakePointerAccessor (&CcnxProducer::m_face),
+    //                 MakePointerChecker<CcnxLocalFace> ())
     .AddAttribute ("Ccnx","Ccnx is needed to access ContentStore",
                    PointerValue (NULL),
                    MakePointerAccessor (&CcnxProducer::m_ccnx),
diff --git a/examples/ccnx-test.cc b/examples/ccnx-test.cc
index 27b120c..49a5c00 100644
--- a/examples/ccnx-test.cc
+++ b/examples/ccnx-test.cc
@@ -12,72 +12,59 @@
 int 
 main (int argc, char *argv[])
 {
-  LogComponentEnable ("CcnxTest", LOG_ALL);
-  LogComponentEnable ("CcnxStackHelper", LOG_ALL);
-  LogComponentEnable ("CcnxRit", LOG_ALL);
+  // LogComponentEnable ("CcnxTest", LOG_ALL);
+  // LogComponentEnable ("CcnxStackHelper", LOG_ALL);
+  // LogComponentEnable ("CcnxRit", LOG_ALL);
   
   // Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
   // Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s"));
 
   Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("10Mbps"));
   Config::SetDefault ("ns3::PointToPointChannel::Delay", StringValue ("1ms"));
-  
+
+  Packet::EnableChecking();
+  Packet::EnablePrinting();
   CommandLine cmd;
   cmd.Parse (argc, argv);
   
   // Here, we will explicitly create seven nodes. 
   NodeContainer c;
   c.Create (3);
+  Names::Add ("1", c.Get (0));
+  Names::Add ("2", c.Get (1));
+  Names::Add ("3", c.Get (2));
   
-  NodeContainer n1 = NodeContainer (c.Get (0), c.Get (1));
-  NodeContainer n2 = NodeContainer (c.Get (1), c.Get (2));
+  // NodeContainer n1 = NodeContainer ("1") ("2");
+  // NodeContainer n2 = NodeContainer ("2") ("3");
   
-  // Ipv4StaticRoutingHelper staticRouting;
-  
-  // Ipv4ListRoutingHelper list;
-  // list.Add (staticRouting, 1);
-
   NS_LOG_INFO ("Create channels.");
   PointToPointHelper p2p;
-  // NetDeviceContainer nd =
-  p2p.Install (n1);
-  p2p.Install (n2);
+  p2p.Install ("1", "2");
+  p2p.Install ("2", "3");
 
   NS_LOG_INFO ("Installing NDN stack");
   CcnxStackHelper ccnx;
   Ptr<CcnxFaceContainer> cf = ccnx.Install (c);
 
-  // // test RIT
-  // NS_LOG_INFO ("Creating RIT");
-  // Ptr<CcnxRit> rit = CreateObject<CcnxRit> ();
-
-  // CcnxInterestHeader header;
-  // Ptr<CcnxNameComponents> testname = Create<CcnxNameComponents> ();
-  // (*testname) ("test") ("test2");
-  // header.SetName (testname);
-  // header.SetNonce (1);
-
-  // rit->SetRecentlySatisfied (header);
-
-  // NS_LOG_INFO (rit->WasRecentlySatisfied (header));
-
-  // (*testname) ("test3"); // should have a side effect of changing name in the packet
-  // rit->SetRecentlySatisfied (header);
-
-  // NS_LOG_INFO (rit->WasRecentlySatisfied (header));
-
-  // header.SetNonce (2);
-  // NS_LOG_INFO (rit->WasRecentlySatisfied (header));
-
-  // rit->SetRecentlySatisfied (header);
-  // ? set up forwarding
+  CcnxConsumerHelper helper ("/3");
+  ApplicationContainer app = helper.Install ("1");
+  app.Start (Seconds (1.0));
+  app.Stop (Seconds (1.05));
   
-  
-  //Add static routing
-  // InternetStackHelper internet;
-  // internet.SetRoutingHelper (list); // has effect on the next Install ()
-  // internet.Install (c);
-  
+  /**
+   * \brief Add forwarding entry in FIB
+   *
+   * \param node Node
+   * \param prefix Routing prefix
+   * \param face Face index
+   * \param metric Routing metric
+   */
+  ccnx.AddRoute ("1", "/3", 0, 1);
+  ccnx.AddRoute ("2", "/3", 1, 1);
+  ccnx.AddRoute ("2", "/3", 0, 10000);
+  NS_LOG_INFO ("FIB dump:\n" << *c.Get(0)->GetObject<CcnxFib> ());
+  NS_LOG_INFO ("FIB dump:\n" << *c.Get(1)->GetObject<CcnxFib> ());
+
   // Create the OnOff application to send UDP datagrams of size
   // 210 bytes at a rate of 448 Kb/s from n0 to n4
   // NS_LOG_INFO ("Create Applications.");
diff --git a/helper/ccnx-consumer-helper.cc b/helper/ccnx-consumer-helper.cc
index b99e0b6..765f6b6 100644
--- a/helper/ccnx-consumer-helper.cc
+++ b/helper/ccnx-consumer-helper.cc
@@ -27,10 +27,13 @@
 namespace ns3 
 {
     
-CcnxConsumerHelper::CcnxConsumerHelper (Ptr<CcnxNameComponents> interestName)
+CcnxConsumerHelper::CcnxConsumerHelper (const std::string &prefix)
 {
     m_factory.SetTypeId ("ns3::CcnxConsumer");
-    m_factory.Set ("InterestName", CcnxNameComponentsValue (*interestName));
+    
+    CcnxNameComponentsValue prefixValue;
+    prefixValue.DeserializeFromString (prefix, MakeCcnxNameComponentsChecker ());
+    m_factory.Set ("InterestName", prefixValue);
 }
     
 void 
@@ -67,17 +70,10 @@
 Ptr<Application>
 CcnxConsumerHelper::InstallPriv (Ptr<Node> node)
 {
-    Ptr<CcnxLocalFace> localFace = CreateObject<CcnxLocalFace> ();
-    localFace->SetNode(node);
-    
-    m_factory.Set ("Face", PointerValue (localFace));
-    Ptr<CcnxConsumer> app = m_factory.Create<CcnxConsumer> ();
-        
-    localFace->RegisterProtocolHandler (MakeCallback (&CcnxConsumer::HandlePacket, app));
-    localFace->SetUp();
-        
+    Ptr<CcnxConsumer> app = m_factory.Create<CcnxConsumer> ();        
     node->AddApplication (app);
         
     return app;
 }
+
 }
diff --git a/helper/ccnx-consumer-helper.h b/helper/ccnx-consumer-helper.h
index e512a8f..d885e2e 100644
--- a/helper/ccnx-consumer-helper.h
+++ b/helper/ccnx-consumer-helper.h
@@ -38,69 +38,70 @@
 namespace ns3 
 {    
 /**
-* \brief A helper to make it easier to instantiate an ns3::CcnxConsumer Application
-* on a set of nodes.
-*/
+ * \brief A helper to make it easier to instantiate an ns3::CcnxConsumer Application
+ * on a set of nodes.
+ */
     
 class CcnxConsumerHelper
 {        
 public:
 
-/**
-* Create an CcnxConsumerHelper to make it easier to work with CcnxConsumer Apps
-*
-*/
-CcnxConsumerHelper (Ptr<CcnxNameComponents> interestName);
+  /**
+   * \brief Create an CcnxConsumerHelper to make it easier to work with CcnxConsumer Apps
+   *
+   * \param prefix Prefix which will be requested by the consumer applications
+   */
+  CcnxConsumerHelper (const std::string &prefix);
         
-/**
-* Helper function used to set the underlying application attributes.
-*
-* \param name the name of the application attribute to set
-* \param value the value of the application attribute to set
-*/
-void SetAttribute (std::string name, const AttributeValue &value);
+  /**
+   * \brief Helper function used to set the underlying application attributes.
+   *
+   * \param name the name of the application attribute to set
+   * \param value the value of the application attribute to set
+   */
+  void SetAttribute (std::string name, const AttributeValue &value);
         
-/**
-* Install an ns3::CcnxConsumer on each node of the input container
-* configured with all the attributes set with SetAttribute.
-*
-* \param c NodeContainer of the set of nodes on which an CcnxConsumer 
-* will be installed.
-* \returns Container of Ptr to the applications installed.
-*/
-ApplicationContainer Install (NodeContainer c);
+  /**
+   * Install an ns3::CcnxConsumer on each node of the input container
+   * configured with all the attributes set with SetAttribute.
+   *
+   * \param c NodeContainer of the set of nodes on which an CcnxConsumer 
+   * will be installed.
+   * \returns Container of Ptr to the applications installed.
+   */
+  ApplicationContainer Install (NodeContainer c);
         
-/**
-* Install an ns3::CcnxConsumer on the node configured with all the 
-* attributes set with SetAttribute.
-*
-* \param node The node on which an CcnxConsumer will be installed.
-* \returns Container of Ptr to the applications installed.
-*/
-ApplicationContainer Install (Ptr<Node> node);
+  /**
+   * Install an ns3::CcnxConsumer on the node configured with all the 
+   * attributes set with SetAttribute.
+   *
+   * \param node The node on which an CcnxConsumer will be installed.
+   * \returns Container of Ptr to the applications installed.
+   */
+  ApplicationContainer Install (Ptr<Node> node);
         
-/**
-* Install an ns3::CcnxConsumer on the node configured with all the 
-* attributes set with SetAttribute.
-*
-* \param nodeName The node on which an CcnxConsumer will be installed.
-* \returns Container of Ptr to the applications installed.
-*/
-ApplicationContainer Install (std::string nodeName);
+  /**
+   * Install an ns3::CcnxConsumer on the node configured with all the 
+   * attributes set with SetAttribute.
+   *
+   * \param nodeName The node on which an CcnxConsumer will be installed.
+   * \returns Container of Ptr to the applications installed.
+   */
+  ApplicationContainer Install (std::string nodeName);
         
 private:
-/**
-* \internal
-* Install an ns3::CcnxConsumer on the node configured with all the 
-* attributes set with SetAttribute.
-*
-* \param node The node on which an CcnxConsumer will be installed.
-* \returns Ptr to the application installed.
-*/
-Ptr<Application> InstallPriv (Ptr<Node> node);
-ObjectFactory m_factory;
+  /**
+   * \internal
+   * Install an ns3::CcnxConsumer on the node configured with all the 
+   * attributes set with SetAttribute.
+   *
+   * \param node The node on which an CcnxConsumer will be installed.
+   * \returns Ptr to the application installed.
+   */
+  Ptr<Application> InstallPriv (Ptr<Node> node);
+  ObjectFactory m_factory;
+};
 
-};    
 }
 
 #endif
diff --git a/helper/ccnx-face-container.cc b/helper/ccnx-face-container.cc
index ce595bb..8a7a9e2 100644
--- a/helper/ccnx-face-container.cc
+++ b/helper/ccnx-face-container.cc
@@ -76,16 +76,16 @@
   return m_faces.size ();
 }
 
-void 
-CcnxFaceContainer::SetMetricToAll (uint16_t metric)
-{
-  for (FaceContainer::iterator it=m_faces.begin ();
-       it != m_faces.end ();
-       it++)
-    {
-      (*it)->SetMetric (metric);
-    }
-}
+// void 
+// CcnxFaceContainer::SetMetricToAll (uint16_t metric)
+// {
+//   for (FaceContainer::iterator it=m_faces.begin ();
+//        it != m_faces.end ();
+//        it++)
+//     {
+//       (*it)->SetMetric (metric);
+//     }
+// }
 
 void 
 CcnxFaceContainer::Add (const Ptr<CcnxFace> &face)
diff --git a/helper/ccnx-face-container.h b/helper/ccnx-face-container.h
index ecb29d9..39391f8 100644
--- a/helper/ccnx-face-container.h
+++ b/helper/ccnx-face-container.h
@@ -26,11 +26,10 @@
 
 #include "ns3/ptr.h"
 #include "ns3/simple-ref-count.h"
+#include "ns3/ccnx-face.h"
 
 namespace ns3 {
 
-class CcnxFace;
-
 /**
  * \ingroup ccnx-helpers
  * \brief A pool for CCNx faces
@@ -105,12 +104,12 @@
    */
   uint32_t GetN () const;
 
-  /**
-   * \brief Set a metric for all faces in the container
-   *
-   * \param metric value of metric to assign to all faces in the container
-   */
-  void SetMetricToAll (uint16_t metric);
+  // /**
+  //  * \brief Set a metric for all faces in the container
+  //  *
+  //  * \param metric value of metric to assign to all faces in the container
+  //  */
+  // void SetMetricToAll (uint16_t metric);
 
   /**
    * Add an entry to the container
diff --git a/helper/ccnx-header-helper.cc b/helper/ccnx-header-helper.cc
index 85c88f1..1c7a806 100644
--- a/helper/ccnx-header-helper.cc
+++ b/helper/ccnx-header-helper.cc
@@ -27,6 +27,7 @@
 
 #include "ns3/ccnx-interest-header.h"
 #include "ns3/ccnx-content-object-header.h"
+#include <iomanip>
 
 NS_LOG_COMPONENT_DEFINE ("CcnxHeaderHelper");
 
@@ -35,12 +36,12 @@
 {
 
 CcnxHeaderHelper::Type
-CcnxHeaderHelper::CreateCorrectCcnxHeader (Ptr<const Packet> packet)
+CcnxHeaderHelper::GetCcnxHeaderType (Ptr<const Packet> packet)
 {
   uint8_t type[2];
   uint32_t read=packet->CopyData (type,2);
   if (read!=2) throw CcnxUnknownHeaderException();
-  
+
   if (type[0] == INTEREST_BYTE0 && type[1] == INTEREST_BYTE1)
     {
       return CcnxHeaderHelper::INTEREST;
diff --git a/helper/ccnx-header-helper.h b/helper/ccnx-header-helper.h
index 996b874..f4096db 100644
--- a/helper/ccnx-header-helper.h
+++ b/helper/ccnx-header-helper.h
@@ -74,7 +74,7 @@
    */
   
   static Type
-  CreateCorrectCcnxHeader (Ptr<const Packet> packet);
+  GetCcnxHeaderType (Ptr<const Packet> packet);
 };
 
   /**
diff --git a/helper/ccnx-interest-sender-helper.cc b/helper/ccnx-interest-sender-helper.cc
deleted file mode 100644
index addd9de..0000000
--- a/helper/ccnx-interest-sender-helper.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include "ccnx-interest-sender-helper.h"
-#include "ns3/inet-socket-address.h"
-#include "ns3/packet-socket-address.h"
-#include "ns3/string.h"
-#include "ns3/names.h"
-
-namespace ns3 
-{
-    
-CcnxInterestSenderHelper::CcnxInterestSenderHelper (Ptr<CcnxNameComponents> interestName)
-{
-    m_factory.SetTypeId ("ns3::CcnxConsumer");
-    m_factory.Set ("InterestName", CcnxNameComponentsValue (*interestName));
-}
-    
-void 
-CcnxInterestSenderHelper::SetAttribute (std::string name, const AttributeValue &value)
-{
-    m_factory.Set (name, value);
-}
-    
-ApplicationContainer
-CcnxInterestSenderHelper::Install (Ptr<Node> node)
-{
-    return ApplicationContainer (InstallPriv (node));
-}
-    
-ApplicationContainer
-CcnxInterestSenderHelper::Install (std::string nodeName)
-{
-    Ptr<Node> node = Names::Find<Node> (nodeName);
-    return ApplicationContainer (InstallPriv (node));
-}
-    
-ApplicationContainer
-CcnxInterestSenderHelper::Install (NodeContainer c)
-{
-    ApplicationContainer apps;
-    for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
-    {
-        apps.Add (InstallPriv (*i));
-    }
-        
-    return apps;
-}
-    
-Ptr<Application>
-CcnxInterestSenderHelper::InstallPriv (Ptr<Node> node)
-{
-    Ptr<CcnxLocalFace> localFace = Create<CcnxLocalFace> ();
-    localFace->SetNode(node);
-    localFace->SetUp();
-    m_factory.Set ("Face", PointerValue (localFace));
-    
-    Ptr<Application> app = m_factory.Create<Application> ();
-    node->AddApplication (app);
-        
-    return app;
-}
-}
\ No newline at end of file
diff --git a/helper/ccnx-interest-sender-helper.h b/helper/ccnx-interest-sender-helper.h
deleted file mode 100644
index b58b41f..0000000
--- a/helper/ccnx-interest-sender-helper.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#ifndef CCNX_INTEREST_SENDER_HELPER_H
-#define CCNX_INTEREST_SENDER_HELPER_H
-
-#include <stdint.h>
-#include <string>
-#include "ns3/object-factory.h"
-#include "ns3/address.h"
-#include "ns3/attribute.h"
-#include "ns3/net-device.h"
-#include "ns3/node-container.h"
-#include "ns3/application-container.h"
-#include "ns3/ccnx-name-components.h"
-#include "ns3/pointer.h"
-#include "ns3/ccnx-local-face.h"
-
-namespace ns3 
-{    
-/**
- * \brief A helper to make it easier to instantiate an ns3::CcnxInterestSenderApplication
- * on a set of nodes.
- */
-
-class CcnxInterestSenderHelper
-{
-
-public:
-    /**
-     * Create an CcnxInterestSenderHelper to make it easier to work with CcnxInterestSenderApps
-     *
-     */
-    CcnxInterestSenderHelper (Ptr<CcnxNameComponents> interestName);
-        
-    /**
-     * Helper function used to set the underlying application attributes.
-     *
-     * \param name the name of the application attribute to set
-     * \param value the value of the application attribute to set
-     */
-    void SetAttribute (std::string name, const AttributeValue &value);
-        
-    /**
-     * Install an ns3::CcnxInterestSender on each node of the input container
-     * configured with all the attributes set with SetAttribute.
-     *
-     * \param c NodeContainer of the set of nodes on which an CcnxInterestSender 
-     * will be installed.
-     * \returns Container of Ptr to the applications installed.
-     */
-    ApplicationContainer Install (NodeContainer c);
-        
-    /**
-     * Install an ns3::CcnxInterestSender on the node configured with all the 
-     * attributes set with SetAttribute.
-     *
-     * \param node The node on which an CcnxInterestSender will be installed.
-     * \returns Container of Ptr to the applications installed.
-     */
-    ApplicationContainer Install (Ptr<Node> node);
-        
-    /**
-     * Install an ns3::CcnxInterestSender on the node configured with all the 
-     * attributes set with SetAttribute.
-     *
-     * \param nodeName The node on which an CcnxInterestSender will be installed.
-     * \returns Container of Ptr to the applications installed.
-     */
-    ApplicationContainer Install (std::string nodeName);
-        
-private:
-    /**
-     * \internal
-     * Install an ns3::CcnxInterestSender on the node configured with all the 
-     * attributes set with SetAttribute.
-     *
-     * \param node The node on which an CcnxInterestSender will be installed.
-     * \returns Ptr to the application installed.
-    */
-    Ptr<Application> InstallPriv (Ptr<Node> node);
-    ObjectFactory m_factory;
-};    
-}
-
-#endif
-
diff --git a/helper/ccnx-producer-helper.cc b/helper/ccnx-producer-helper.cc
index 71a7c32..433a15a 100644
--- a/helper/ccnx-producer-helper.cc
+++ b/helper/ccnx-producer-helper.cc
@@ -72,11 +72,9 @@
 Ptr<Application>
 CcnxProducerHelper::InstallPriv (Ptr<Node> node)
 {
-    Ptr<CcnxLocalFace> localFace = CreateObject<CcnxLocalFace> ();
+    Ptr<CcnxLocalFace> localFace = Create<CcnxLocalFace> ();
     localFace->SetNode(node);
-    
-    
-    
+        
     //CreateAndAggregateObjectFromTypeId (node, "ns3::CcnxL3Protocol");
     ObjectFactory factory;
     factory.SetTypeId("ns3::CcnxL3Protocol");
@@ -92,7 +90,7 @@
         return 0;
     }
 
-    m_factory.Set ("Face", PointerValue (localFace));
+    // m_factory.Set ("Face", PointerValue (localFace));
     m_factory.Set ("Ccnx", PointerValue (ccnx));
     Ptr<CcnxProducer> app = m_factory.Create<CcnxProducer> ();
 
@@ -104,4 +102,4 @@
         
     return app;
 }
-}
\ No newline at end of file
+}
diff --git a/helper/ccnx-stack-helper.cc b/helper/ccnx-stack-helper.cc
index d59827e..428ddef 100644
--- a/helper/ccnx-stack-helper.cc
+++ b/helper/ccnx-stack-helper.cc
@@ -69,6 +69,7 @@
 #include "ns3/ccnx-forwarding-strategy.h"
 #include "ns3/ccnx-net-device-face.h"
 #include "ns3/ccnx-l3-protocol.h"
+#include "ns3/ccnx-fib.h"
 
 #include "ccnx-face-container.h"
 #include "ccnx-stack-helper.h"
@@ -112,37 +113,15 @@
 static FaceStreamMapCcnx g_faceStreamMapCcnx; /**< A mapping of Ccnx/face pairs to ascii streams */
 
 CcnxStackHelper::CcnxStackHelper ()
-  : m_forwarding (0)
-  , m_ccnxEnabled (true)
 {
-  Initialize ();
-}
-
-// private method called by both constructor and Reset ()
-void
-CcnxStackHelper::Initialize ()
-{
-  // CcnxStaticForwardingHelper staticForwarding;
-  // CcnxGlobalForwardingHelper globalForwarding;
-  // CcnxListForwardingHelper listForwarding;
-  // listForwarding.Add (staticForwarding, 0);
-  // listForwarding.Add (globalForwarding, -10);
-  // SetForwardingHelper (listForwarding);
 }
 
 CcnxStackHelper::~CcnxStackHelper ()
 {
-  if (m_forwarding)
-    {
-      delete m_forwarding;
-      m_forwarding = 0;
-    }
 }
 
 CcnxStackHelper::CcnxStackHelper (const CcnxStackHelper &o)
 {
-  m_forwarding = o.m_forwarding->Copy ();
-  m_ccnxEnabled = o.m_ccnxEnabled;
 }
 
 CcnxStackHelper &
@@ -152,30 +131,14 @@
     {
       return *this;
     }
-  m_forwarding = o.m_forwarding->Copy ();
   return *this;
 }
 
-void
-CcnxStackHelper::Reset (void)
-{
-  delete m_forwarding;
-  m_forwarding = 0;
-  m_ccnxEnabled = true;
-  Initialize ();
-}
-
 void 
 CcnxStackHelper::SetForwardingHelper (const CcnxForwardingHelper &forwarding)
 {
-  delete m_forwarding;
-  m_forwarding = forwarding.Copy ();
-}
-
-void
-CcnxStackHelper::SetCcnxStackInstall (bool enable)
-{
-  m_ccnxEnabled = enable;
+  // delete m_forwarding;
+  // m_forwarding = forwarding.Copy ();
 }
 
 Ptr<CcnxFaceContainer>
@@ -195,14 +158,14 @@
   return Install (NodeContainer::GetGlobal ());
 }
 
-void
-CcnxStackHelper::CreateAndAggregateObjectFromTypeId (Ptr<Node> node, const std::string typeId)
-{
-  ObjectFactory factory;
-  factory.SetTypeId (typeId);
-  Ptr<Object> protocol = factory.Create <Object> ();
-  node->AggregateObject (protocol);
-}
+// void
+// CcnxStackHelper::CreateAndAggregateObjectFromTypeId (Ptr<Node> node, const std::string typeId)
+// {
+//   ObjectFactory factory;
+//   factory.SetTypeId (typeId);
+//   Ptr<Object> protocol = factory.Create <Object> ();
+//   node->AggregateObject (protocol);
+// }
 
 Ptr<CcnxFaceContainer>
 CcnxStackHelper::Install (Ptr<Node> node) const
@@ -210,30 +173,31 @@
   // NS_ASSERT_MSG (m_forwarding, "SetForwardingHelper() should be set prior calling Install() method");
   Ptr<CcnxFaceContainer> faces = Create<CcnxFaceContainer> ();
   
-  if (m_ccnxEnabled)
+  if (node->GetObject<Ccnx> () != 0)
     {
-      if (node->GetObject<Ccnx> () != 0)
-        {
-          NS_FATAL_ERROR ("CcnxStackHelper::Install (): Installing " 
-                          "a CcnxStack to a node with an existing Ccnx object");
-          return 0;
-        }
-
-      CreateAndAggregateObjectFromTypeId (node, "ns3::CcnxL3Protocol");
-      // Set forwarding
-      Ptr<Ccnx> ccnx = node->GetObject<Ccnx> ();
-      for (uint32_t index=0; index < node->GetNDevices (); index++)
-        {
-          Ptr<CcnxNetDeviceFace> face = Create<CcnxNetDeviceFace> (node->GetDevice (index));
-          uint32_t __attribute__ ((unused)) face_id = ccnx->AddFace (face);
-          NS_LOG_LOGIC ("Node " << node->GetId () << ": added CcxnNetDeviceFace as face #" << face_id);
-
-          faces->Add (face);
-        }
-      // Ptr<CcnxForwardingStrategy> ccnxForwarding = m_forwarding->Create (node);
-      // ccnx->SetForwardingStrategy (ccnxForwarding);
+      NS_FATAL_ERROR ("CcnxStackHelper::Install (): Installing " 
+                      "a CcnxStack to a node with an existing Ccnx object");
+      return 0;
     }
 
+  Ptr<CcnxFib> fib = CreateObject<CcnxFib> ();
+  node->AggregateObject (fib);
+
+  Ptr<Ccnx> ccnx = CreateObject<CcnxL3Protocol> ();
+  node->AggregateObject (ccnx);
+
+  for (uint32_t index=0; index < node->GetNDevices (); index++)
+    {
+      Ptr<CcnxNetDeviceFace> face = Create<CcnxNetDeviceFace> (node->GetDevice (index));
+      face->SetNode (node);
+      uint32_t __attribute__ ((unused)) face_id = ccnx->AddFace (face);
+      NS_LOG_LOGIC ("Node " << node->GetId () << ": added CcxnNetDeviceFace as face #" << face_id);
+
+      faces->Add (face);
+    }
+  // Ptr<CcnxForwardingStrategy> ccnxForwarding = m_forwarding->Create (node);
+  // ccnx->SetForwardingStrategy (ccnxForwarding);
+
   return faces;
 }
 
@@ -244,6 +208,26 @@
   return Install (node);
 }
 
+
+void
+CcnxStackHelper::AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric)
+{
+  NS_LOG_LOGIC ("[" << nodeName << "]$ route add " << prefix << " via " << faceId << " metric " << metric);
+  
+  Ptr<Node> node = Names::Find<Node> (nodeName);
+  NS_ASSERT_MSG (node != 0, "Node [" << nodeName << "] does not exist");
+  
+  Ptr<Ccnx>     ccnx = node->GetObject<Ccnx> ();
+  Ptr<CcnxFib>  fib  = node->GetObject<CcnxFib> ();
+  Ptr<CcnxFace> face = ccnx->GetFace (faceId);
+  NS_ASSERT_MSG (node != 0, "Face with ID [" << faceId << "] does not exist on node [" << nodeName << "]");
+
+  CcnxNameComponentsValue prefixValue;
+  prefixValue.DeserializeFromString (prefix, MakeCcnxNameComponentsChecker ());
+  fib->Add (prefixValue.Get (), face, metric);
+}
+
+
 static void
 CcnxL3ProtocolRxTxSink (Ptr<const Packet> p, Ptr<Ccnx> ccnx, uint32_t face)
 {
@@ -286,12 +270,6 @@
 {
   NS_LOG_FUNCTION (prefix << ccnx << face);
 
-  if (!m_ccnxEnabled)
-    {
-      NS_LOG_INFO ("Call to enable Ccnx pcap tracing but Ccnx not enabled");
-      return;
-    }
-
   //
   // We have to create a file and a mapping from protocol/face to file 
   // irrespective of how many times we want to trace a particular protocol.
@@ -412,12 +390,6 @@
   uint32_t face,
   bool explicitFilename)
 {
-  if (!m_ccnxEnabled)
-    {
-      NS_LOG_INFO ("Call to enable Ccnx ascii tracing but Ccnx not enabled");
-      return;
-    }
-
   //
   // Our trace sinks are going to use packet printing, so we have to 
   // make sure that is turned on.
diff --git a/helper/ccnx-stack-helper.h b/helper/ccnx-stack-helper.h
index 060b0a7..1e587e3 100644
--- a/helper/ccnx-stack-helper.h
+++ b/helper/ccnx-stack-helper.h
@@ -72,11 +72,6 @@
   CcnxStackHelper &operator = (const CcnxStackHelper &o);
 
   /**
-   * \brief Return helper internal state to that of a newly constructed one
-   */
-  void Reset ();
-
-  /**
    * Set forwarding strategy helper
    *
    * \param forwarding a new forwarding helper
@@ -142,12 +137,15 @@
   InstallAll () const;
 
   /**
-   * \brief Enable/disable ccnx stack install.
+   * \brief Add forwarding entry in FIB
    *
-   * \param enable enable state
+   * \param nodeName Node name
+   * \param prefix Routing prefix
+   * \param faceId Face index
+   * \param metric Routing metric
    */
   void
-  SetCcnxStackInstall (bool enable);
+  AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric);
 
 private:
   /**
@@ -179,14 +177,10 @@
                                         uint32_t interface,
                                         bool explicitFilename);
 
-  void Initialize (void);
-  ObjectFactory m_tcpFactory;
-  const CcnxForwardingHelper *m_forwarding;
-
-  /**
-   * \internal
-   */
-  static void CreateAndAggregateObjectFromTypeId (Ptr<Node> node, const std::string typeId);
+  // /**
+  //  * \internal
+  //  */
+  // static void CreateAndAggregateObjectFromTypeId (Ptr<Node> node, const std::string typeId);
 
   /**
    * \internal
@@ -202,11 +196,6 @@
    * \internal
    */
   bool AsciiHooked (Ptr<Ccnx> ccnx);
-
-  /**
-   * \brief Ccnx install state (enabled/disabled) ?
-   */
-  bool m_ccnxEnabled;
 };
 
 } // namespace ns3
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