Making everything compile. Now everything seems to work, but more
checking is necessary
diff --git a/apps/ccnx-app.cc b/apps/ccnx-app.cc
index a23167e..7b9c2b9 100644
--- a/apps/ccnx-app.cc
+++ b/apps/ccnx-app.cc
@@ -20,9 +20,14 @@
 
 #include "ccnx-app.h"
 #include "ns3/log.h"
+#include "ns3/assert.h"
 #include "ns3/packet.h"
+
 #include "ns3/ccnx-interest-header.h"
 #include "ns3/ccnx-content-object-header.h"
+#include "ns3/ccnx.h"
+#include "ns3/ccnx-fib.h"
+#include "ns3/ccnx-local-face.h"
 
 NS_LOG_COMPONENT_DEFINE ("CcnxApp");
 
@@ -32,7 +37,7 @@
 NS_OBJECT_ENSURE_REGISTERED (CcnxApp);
     
 TypeId
-CcnxConsumer::GetTypeId (void)
+CcnxApp::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::CcnxApp")
     .SetParent<Application> ()
@@ -43,7 +48,7 @@
     
 CcnxApp::CcnxApp ()
   : m_protocolHandler (0)
-  , m_active (true)
+  , m_active (false)
   , m_face (0)
 {
 }
@@ -54,12 +59,12 @@
 }
 
 void
-CcnxProducer::DoDispose (void)
+CcnxApp::DoDispose (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
 
   StopApplication ();
-  CcnxApp::DoDispose ();
+  Application::DoDispose ();
 }
 
 void
@@ -96,16 +101,14 @@
   NS_ASSERT (m_active != true);
   m_active = true;
 
-  NS_ASSERT_MSG (GetObject<Ccnx> () != 0,
+  NS_ASSERT_MSG (GetNode ()->GetObject<Ccnx> () != 0,
                  "Ccnx stack should be installed on the node " << GetNode ());
-  NS_ASSERT_MSG (GetObject<CcnxFib> () != 0);
 
   // step 1. Create a face
   m_face = Create<CcnxLocalFace> (/*Ptr<CcnxApp> (this)*/this);
     
   // step 2. Add face to the CCNx stack
-  GetObject<CcnxFib> ()->Add (m_prefix, m_face, 0);
-  GetObject<Ccnx> ()->AddFace (m_face);
+  GetNode ()->GetObject<Ccnx> ()->AddFace (m_face);
 
   // step 3. Enable face
   m_face->SetUp (true);
@@ -118,8 +121,7 @@
 
   if (!m_active) return; //don't assert here, just return
  
-  NS_ASSERT (GetObject<Ccnx> () != 0);
-  NS_ASSERT (GetObject<CcnxFib> () != 0);
+  NS_ASSERT (GetNode ()->GetObject<Ccnx> () != 0);
 
   m_active = false;
 
@@ -127,14 +129,14 @@
   m_face->SetUp (false);
 
   // step 2. Remove face from CCNx stack
-  GetObject<Ccnx> ()->RemoveFace (m_face);
-  GetObject<CcnxFib> ()->Add (m_prefix, m_face, 0);
+  GetNode ()->GetObject<Ccnx> ()->RemoveFace (m_face);
+  GetNode ()->GetObject<CcnxFib> ()->RemoveFromAll (m_face);
 
   // step 3. Destroy face
   NS_ASSERT_MSG (m_face->GetReferenceCount ()==1,
-                 "At this point, nobody else should have referenced this face");
+                 "At this point, nobody else should have referenced this face, but we have "
+                 << m_face->GetReferenceCount () << " references");
   m_face = 0;
 }
 
-
 }
diff --git a/apps/ccnx-app.h b/apps/ccnx-app.h
index 4f2cb83..f94018f 100644
--- a/apps/ccnx-app.h
+++ b/apps/ccnx-app.h
@@ -31,6 +31,7 @@
 class Packet;
 class CcnxInterestHeader;
 class CcnxContentObjectHeader;
+class CcnxFace;
 
 /**
  * @ingroup ccnx
@@ -41,7 +42,7 @@
 class CcnxApp: public Application
 {
 public:
-  typedef Callback<bool, const Ptr<CcnxFace>&> ProtocolHandler;
+  typedef Callback<bool, const Ptr<const Packet>&> ProtocolHandler;
   
   static TypeId GetTypeId ();
 
@@ -94,8 +95,6 @@
 protected:
   ProtocolHandler m_protocolHandler;
   bool m_active; 
-
-private:
   Ptr<CcnxFace> m_face; // local face that is created 
 };
 
diff --git a/apps/ccnx-consumer.cc b/apps/ccnx-consumer.cc
index 01a5b1d..5d2ce7c 100644
--- a/apps/ccnx-consumer.cc
+++ b/apps/ccnx-consumer.cc
@@ -20,12 +20,21 @@
 
 #include "ccnx-consumer.h"
 #include "ns3/ptr.h"
-#include "ns3/ccnx-local-face.h"
-#include "ns3/ccnx.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/packet.h"
 #include "ns3/callback.h"
 #include "ns3/string.h"
+#include "ns3/boolean.h"
+#include "ns3/uinteger.h"
+
+#include "ns3/ccnx.h"
+#include "ns3/ccnx-local-face.h"
+#include "ns3/ccnx-interest-header.h"
 #include "ns3/ccnx-content-object-header.h"
 
+#include <boost/ref.hpp>
+
 NS_LOG_COMPONENT_DEFINE ("CcnxConsumer");
 
 namespace ns3
@@ -67,14 +76,14 @@
                    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))
+    // .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;
@@ -87,19 +96,6 @@
   NS_LOG_FUNCTION_NOARGS ();
 }
     
-CcnxConsumer::~CcnxConsumer()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-    
-void
-CcnxConsumer::DoDispose (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-        
-  Application::DoDispose ();
-}
-    
 // Application Methods
 void 
 CcnxConsumer::StartApplication () // Called at time specified by Start
@@ -129,11 +125,10 @@
 CcnxConsumer::SendPacket ()
 {
   NS_LOG_FUNCTION_NOARGS ();
-  NS_LOG_INFO ("Sending Interest at " << Simulator::Now ());
     
   //
   Ptr<CcnxNameComponents> nameWithSequence = Create<CcnxNameComponents> (m_interestName);
-  (*name) (m_seq++);
+  (*nameWithSequence) (m_seq++);
   //
 
   CcnxInterestHeader interestHeader;
@@ -145,7 +140,7 @@
   interestHeader.SetMaxSuffixComponents (m_maxSuffixComponents);
   interestHeader.SetMinSuffixComponents (m_minSuffixComponents);
         
-  NS_LOG_INFO ("Interest: \n" << interestHeader);
+  NS_LOG_INFO ("Requesting Interest: \n" << interestHeader);
 
   Ptr<Packet> packet = Create<Packet> ();
   packet->AddHeader (interestHeader);
@@ -161,7 +156,7 @@
 {
   NS_LOG_FUNCTION (this << contentObject << payload);
 
-  NS_LOG_INFO ("Received content object: " << cref(*contentObject));
+  NS_LOG_INFO ("Received content object: " << boost::cref(*contentObject));
 }
 
 } // namespace ns3
diff --git a/apps/ccnx-consumer.h b/apps/ccnx-consumer.h
index b2c115b..792c829 100644
--- a/apps/ccnx-consumer.h
+++ b/apps/ccnx-consumer.h
@@ -22,6 +22,8 @@
 #define CCNX_CONSUMER_H
 
 #include "ccnx-app.h"
+#include "ns3/random-variable.h"
+#include "ns3/ccnx-name-components.h"
 
 namespace ns3 
 {
diff --git a/apps/ccnx-interest-sender.cc b/apps/ccnx-interest-sender.cc
index bcf3d76..d110978 100644
--- a/apps/ccnx-interest-sender.cc
+++ b/apps/ccnx-interest-sender.cc
@@ -1,161 +1,160 @@
-/* -*-  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>
- */
+// /* -*-  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.h"
+// #include "ccnx-interest-sender.h"
 
-NS_LOG_COMPONENT_DEFINE ("CcnxInterestSender");
+// NS_LOG_COMPONENT_DEFINE ("CcnxInterestSender");
 
-namespace ns3
-{    
+// namespace ns3
+// {    
 
-NS_OBJECT_ENSURE_REGISTERED (CcnxInterestSender);
+// NS_OBJECT_ENSURE_REGISTERED (CcnxInterestSender);
 
-TypeId
-CcnxInterestSender::GetTypeId (void)
-{
-    static TypeId tid = TypeId ("ns3::CcnxInterestSender")
-    .SetParent<Application> ()
-    .AddConstructor<CcnxInterestSender> ()
-    .AddAttribute ("OffTime", "Time interval between packets",
-                   TimeValue (Seconds (0.1)),
-                   MakeTimeAccessor (&CcnxInterestSender::m_offTime),
-                   MakeTimeChecker ())
-    // 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),
-                   MakeCcnxNameComponentsChecker ())
-    .AddAttribute ("LifeTime", "LifeTime fo interest packet",
-                   TimeValue (Seconds (4.0)),
-                   MakeTimeAccessor (&CcnxInterestSender::m_interestLifeTime),
-                   MakeTimeChecker ())
-    .AddAttribute ("MinSuffixComponents", "MinSuffixComponents",
-                   IntegerValue(-1),
-                   MakeIntegerAccessor(&CcnxInterestSender::m_minSuffixComponents),
-                   MakeIntegerChecker<int32_t>())
-    .AddAttribute ("MaxSuffixComponents", "MaxSuffixComponents",
-                   IntegerValue(-1),
-                   MakeIntegerAccessor(&CcnxInterestSender::m_maxSuffixComponents),
-                   MakeIntegerChecker<int32_t>())
-    .AddAttribute ("ChildSelector", "ChildSelector",
-                   BooleanValue(false),
-                   MakeBooleanAccessor(&CcnxInterestSender::m_childSelector),
-                   MakeBooleanChecker())
-    .AddAttribute ("Exclude","only simple name matching is supported (use CcnxNameComponents)",
-                   CcnxNameComponentsValue (CcnxNameComponents(/* root */)),
-                   MakeCcnxNameComponentsAccessor (&CcnxInterestSender::m_exclude),
-                   MakeCcnxNameComponentsChecker ())
-    .AddAttribute ("Initial Nonce", "If 0 then nonce is not used",
-                   UintegerValue(1),
-                   MakeUintegerAccessor(&CcnxInterestSender::m_initialNonce),
-                   MakeUintegerChecker<uint32_t>())
-    ;
-    /*
-    .AddAttribute ("NoiseModel",
-                   "A pointer to the model of the channel ambient noise.",
-                   PointerValue (CreateObject<UanNoiseModelDefault> ()),
-                   MakePointerAccessor (&UanChannel::m_noise),
-                   MakePointerChecker<UanNoiseModel> ())*/
-    return tid;
-}
+// TypeId
+// CcnxInterestSender::GetTypeId (void)
+// {
+//   static TypeId tid = TypeId ("ns3::CcnxInterestSender")
+//     .SetParent<Application> ()
+//     .AddConstructor<CcnxInterestSender> ()
+//     .AddAttribute ("OffTime", "Time interval between packets",
+//                    TimeValue (Seconds (0.1)),
+//                    MakeTimeAccessor (&CcnxInterestSender::m_offTime),
+//                    MakeTimeChecker ())
+//     // 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),
+//                    MakeCcnxNameComponentsChecker ())
+//     .AddAttribute ("LifeTime", "LifeTime fo interest packet",
+//                    TimeValue (Seconds (4.0)),
+//                    MakeTimeAccessor (&CcnxInterestSender::m_interestLifeTime),
+//                    MakeTimeChecker ())
+//     .AddAttribute ("MinSuffixComponents", "MinSuffixComponents",
+//                    IntegerValue(-1),
+//                    MakeIntegerAccessor(&CcnxInterestSender::m_minSuffixComponents),
+//                    MakeIntegerChecker<int32_t>())
+//     .AddAttribute ("MaxSuffixComponents", "MaxSuffixComponents",
+//                    IntegerValue(-1),
+//                    MakeIntegerAccessor(&CcnxInterestSender::m_maxSuffixComponents),
+//                    MakeIntegerChecker<int32_t>())
+//     .AddAttribute ("ChildSelector", "ChildSelector",
+//                    BooleanValue(false),
+//                    MakeBooleanAccessor(&CcnxInterestSender::m_childSelector),
+//                    MakeBooleanChecker())
+//     .AddAttribute ("Exclude","only simple name matching is supported (use CcnxNameComponents)",
+//                    CcnxNameComponentsValue (CcnxNameComponents(/* root */)),
+//                    MakeCcnxNameComponentsAccessor (&CcnxInterestSender::m_exclude),
+//                    MakeCcnxNameComponentsChecker ())
+//     .AddAttribute ("Initial Nonce", "If 0 then nonce is not used",
+//                    UintegerValue(1),
+//                    MakeUintegerAccessor(&CcnxInterestSender::m_initialNonce),
+//                    MakeUintegerChecker<uint32_t>())
+//     ;
+//   /*
+//     .AddAttribute ("NoiseModel",
+//     "A pointer to the model of the channel ambient noise.",
+//     PointerValue (CreateObject<UanNoiseModelDefault> ()),
+//     MakePointerAccessor (&UanChannel::m_noise),
+//     MakePointerChecker<UanNoiseModel> ())*/
+//   return tid;
+// }
     
-CcnxInterestSender::CcnxInterestSender ()
-{
-    NS_LOG_FUNCTION_NOARGS ();
-}
+// CcnxInterestSender::CcnxInterestSender ()
+// {
+//   NS_LOG_FUNCTION_NOARGS ();
+// }
     
-CcnxInterestSender::~CcnxInterestSender()
-{
-    NS_LOG_FUNCTION_NOARGS ();
-}
+// CcnxInterestSender::~CcnxInterestSender()
+// {
+//   NS_LOG_FUNCTION_NOARGS ();
+// }
     
-void
-CcnxInterestSender::DoDispose (void)
-{
-    NS_LOG_FUNCTION_NOARGS ();
+// void
+// CcnxInterestSender::DoDispose (void)
+// {
+//   NS_LOG_FUNCTION_NOARGS ();
         
-    Application::DoDispose ();
-}
+//   Application::DoDispose ();
+// }
     
-// Application Methods
-void 
-CcnxInterestSender::StartApplication () // Called at time specified by Start
-{
-    NS_LOG_FUNCTION_NOARGS ();
-    ScheduleNextTx();
-}
+// // Application Methods
+// void 
+// CcnxInterestSender::StartApplication () // Called at time specified by Start
+// {
+//   NS_LOG_FUNCTION_NOARGS ();
+//   ScheduleNextTx();
+// }
     
-void 
-CcnxInterestSender::StopApplication () // Called at time specified by Stop
-{
-    NS_LOG_FUNCTION_NOARGS ();
+// void 
+// CcnxInterestSender::StopApplication () // Called at time specified by Stop
+// {
+//   NS_LOG_FUNCTION_NOARGS ();
     
-    CancelEvents ();
-}
+//   CancelEvents ();
+// }
     
-void 
-CcnxInterestSender::CancelEvents ()
-{
-    NS_LOG_FUNCTION_NOARGS ();
+// void 
+// CcnxInterestSender::CancelEvents ()
+// {
+//   NS_LOG_FUNCTION_NOARGS ();
         
-    Simulator::Cancel (m_sendEvent);
-}
+//   Simulator::Cancel (m_sendEvent);
+// }
 
-void 
-CcnxInterestSender::ScheduleNextTx ()
-{
-    NS_LOG_FUNCTION_NOARGS ();
+// void 
+// CcnxInterestSender::ScheduleNextTx ()
+// {
+//   NS_LOG_FUNCTION_NOARGS ();
         
-    Time nextTime = Seconds(m_offTime);
-    m_sendEvent = Simulator::Schedule (nextTime, &CcnxInterestSender::SendPacket, this);
-}
+//   Time nextTime = Seconds(m_offTime);
+//   m_sendEvent = Simulator::Schedule (nextTime, &CcnxInterestSender::SendPacket, this);
+// }
     
-void
-CcnxInterestSender::SendPacket ()
-{
-    NS_LOG_FUNCTION_NOARGS ();
-    // NS_LOG_INFO ("Sending Interest at " << Simulator::Now ());
+// void
+// CcnxInterestSender::SendPacket ()
+// {
+//   NS_LOG_FUNCTION_NOARGS ();
+//   // NS_LOG_INFO ("Sending Interest at " << Simulator::Now ());
     
-    uint32_t randomNonce = UniformVariable().GetInteger(1, std::numeric_limits<uint32_t>::max ());
-    CcnxInterestHeader interestHeader;
-    interestHeader.SetNonce(randomNonce);
-    //const Ptr<CcnxNameComponents> name = Create<CcnxNameComponents>(m_interestName);
-    interestHeader.SetName(Create<CcnxNameComponents> (m_interestName)); //making a copy of name
-    interestHeader.SetInterestLifetime(m_interestLifeTime);
-    interestHeader.SetChildSelector(m_childSelector);
-    //const Ptr<CcnxNameComponents> exclude = Create<CcnxNameComponents>(m_exclude);
-    interestHeader.SetExclude(Create<CcnxNameComponents> (m_exclude));
-    interestHeader.SetMaxSuffixComponents(m_maxSuffixComponents);
-    interestHeader.SetMinSuffixComponents(m_minSuffixComponents);
+//   uint32_t randomNonce = UniformVariable().GetInteger(1, std::numeric_limits<uint32_t>::max ());
+//   CcnxInterestHeader interestHeader;
+//   interestHeader.SetNonce(randomNonce);
+//   //const Ptr<CcnxNameComponents> name = Create<CcnxNameComponents>(m_interestName);
+//   interestHeader.SetName(Create<CcnxNameComponents> (m_interestName)); //making a copy of name
+//   interestHeader.SetInterestLifetime(m_interestLifeTime);
+//   interestHeader.SetChildSelector(m_childSelector);
+//   //const Ptr<CcnxNameComponents> exclude = Create<CcnxNameComponents>(m_exclude);
+//   interestHeader.SetExclude(Create<CcnxNameComponents> (m_exclude));
+//   interestHeader.SetMaxSuffixComponents(m_maxSuffixComponents);
+//   interestHeader.SetMinSuffixComponents(m_minSuffixComponents);
     
-    Ptr<Packet> packet = Create<Packet> ();
-    packet->AddHeader (interestHeader);
+//   Ptr<Packet> packet = Create<Packet> ();
+//   packet->AddHeader (interestHeader);
     
-    m_face->Send(packet);
+//   m_face->Send(packet);
     
-    ScheduleNextTx();
-}
-
+//   ScheduleNextTx();
+// }
     
-}
+// }
diff --git a/apps/ccnx-interest-sender.h b/apps/ccnx-interest-sender.h
index ad8de28..cbb54ad 100644
--- a/apps/ccnx-interest-sender.h
+++ b/apps/ccnx-interest-sender.h
@@ -1,106 +1,106 @@
-/* -*-  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>
- */
+// /* -*-  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 "ns3/application.h"
-#include "ns3/log.h"
-#include "ns3/random-variable.h"
-#include "ns3/nstime.h"
-#include "ns3/event-id.h"
-#include "ns3/ptr.h"
-#include "ns3/simulator.h"
-#include "ns3/ccnx-interest-header.h"
-#include "ns3/ccnx-local-face.h"
-#include "ns3/ccnx-name-components.h"
-#include "ns3/packet.h"
-#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/application.h"
+// #include "ns3/log.h"
+// #include "ns3/random-variable.h"
+// #include "ns3/nstime.h"
+// #include "ns3/event-id.h"
+// #include "ns3/ptr.h"
+// #include "ns3/simulator.h"
+// #include "ns3/ccnx-interest-header.h"
+// #include "ns3/ccnx-local-face.h"
+// #include "ns3/ccnx-name-components.h"
+// #include "ns3/packet.h"
+// #include "ns3/boolean.h"
+// #include "ns3/integer.h"
+// #include "ns3/uinteger.h"
+// #include "ns3/random-variable.h"
+// #include <limits> 
+// #include "ns3/pointer.h"
 
-namespace ns3 
-{
+// namespace ns3 
+// {
     
-class Socket;
+// class Socket;
     
-class CcnxInterestSender: public Application
-{
-public: 
-  static TypeId GetTypeId (void);
+// class CcnxInterestSender: public Application
+// {
+// public: 
+//   static TypeId GetTypeId (void);
         
-  CcnxInterestSender ();
+//   CcnxInterestSender ();
         
-  virtual ~CcnxInterestSender ();
+//   virtual ~CcnxInterestSender ();
         
-protected:
-  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
+// protected:
+//   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
         
-  //Time m_onTime;
-  Time m_offTime;
-  CcnxNameComponents m_interestName;
+//   //Time m_onTime;
+//   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;
+//   Time m_interestLifeTime;
+//   int32_t m_minSuffixComponents;
+//   int32_t m_maxSuffixComponents;
+//   bool m_childSelector;
+//   CcnxNameComponents m_exclude;
+//   uint32_t m_initialNonce;
     
-  //EventId         m_startStopEvent;     // Event id for next start or stop event
-  EventId         m_sendEvent;    // Eventid of pending "send packet" event
-  TypeId          m_tid;
-  Ptr<CcnxLocalFace> m_face;
+//   //EventId         m_startStopEvent;     // Event id for next start or stop event
+//   EventId         m_sendEvent;    // Eventid of pending "send packet" event
+//   TypeId          m_tid;
+//   Ptr<CcnxLocalFace> m_face;
         
-  //helpers
-  void CancelEvents ();
+//   //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
-                  );
+//   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 ();
+//   // Event handlers
+//   void StartSending ();
+//   void StopSending ();
+//   void SendPacket ();
         
-private:
-  void ScheduleNextTx ();
-  //void ScheduleStartEvent ();
-  //void ScheduleStopEvent ();
-  void ConnectionSucceeded (Ptr<Socket>);
-  void ConnectionFailed (Ptr<Socket>);
-  void Ignore (Ptr<Socket>);
+// private:
+//   void ScheduleNextTx ();
+//   //void ScheduleStartEvent ();
+//   //void ScheduleStopEvent ();
+//   void ConnectionSucceeded (Ptr<Socket>);
+//   void ConnectionFailed (Ptr<Socket>);
+//   void Ignore (Ptr<Socket>);
         
-};
-}
+// };
+// }
diff --git a/apps/ccnx-producer.cc b/apps/ccnx-producer.cc
index 1cec691..0a82d0c 100644
--- a/apps/ccnx-producer.cc
+++ b/apps/ccnx-producer.cc
@@ -20,11 +20,17 @@
  */
 
 #include "ccnx-producer.h"
+#include "ns3/log.h"
 #include "ns3/ccnx-interest-header.h"
+#include "ns3/ccnx-content-object-header.h"
 #include "ns3/string.h"
-#include "ns3/integer.h"
+#include "ns3/uinteger.h"
+#include "ns3/packet.h"
 
 #include "ns3/ccnx-local-face.h"
+#include "ns3/ccnx-fib.h"
+
+#include <boost/ref.hpp>
 
 NS_LOG_COMPONENT_DEFINE ("CcnxProducer");
 
@@ -60,7 +66,29 @@
 {
   // NS_LOG_FUNCTION_NOARGS ();
 }
-       
+
+// inherited from Application base class.
+void
+CcnxProducer::StartApplication ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_ASSERT (GetNode ()->GetObject<CcnxFib> () != 0);
+
+  CcnxApp::StartApplication ();
+
+  GetNode ()->GetObject<CcnxFib> ()->Add (m_prefix, m_face, 0);
+}
+
+void
+CcnxProducer::StopApplication ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_ASSERT (GetNode ()->GetObject<CcnxFib> () != 0);
+
+  CcnxApp::StopApplication ();
+}
+
+
 void
 CcnxProducer::OnInterest (const Ptr<const CcnxInterestHeader> &interest)
 {
@@ -71,12 +99,14 @@
   static CcnxContentObjectTail tail;
   Ptr<CcnxContentObjectHeader> header = Create<CcnxContentObjectHeader> ();
   header->SetName (Create<CcnxNameComponents> (interest->GetName ()));
+
+  NS_LOG_INFO ("Respodning with ContentObject:\n" << boost::cref(*header));
   
   Ptr<Packet> packet = Create<Packet> (m_virtualPayloadSize);
-  outgoingPacket->AddHeader (*header);
-  outgoingPacket->AddTrailer (tail);
+  packet->AddHeader (*header);
+  packet->AddTrailer (tail);
 
-  m_protocolHandler (outgoingPacket);
+  m_protocolHandler (packet);
 }
 
 } // namespace ns3
diff --git a/apps/ccnx-producer.h b/apps/ccnx-producer.h
index 289c22e..ac9a492 100644
--- a/apps/ccnx-producer.h
+++ b/apps/ccnx-producer.h
@@ -41,6 +41,14 @@
   // inherited from CcnxApp
   void OnInterest (const Ptr<const CcnxInterestHeader> &interest);
 
+protected:
+  // inherited from Application base class.
+  virtual void
+  StartApplication ();    // Called at time specified by Start
+
+  virtual void
+  StopApplication ();     // Called at time specified by Stop
+
 private:
   CcnxNameComponents m_prefix;
   uint32_t m_virtualPayloadSize;
diff --git a/examples/ccnx-grid.cc b/examples/ccnx-grid.cc
index 618bf74..5c02746 100644
--- a/examples/ccnx-grid.cc
+++ b/examples/ccnx-grid.cc
@@ -94,14 +94,14 @@
   CcnxConsumerHelper consumerHelper (prefix.str ());
   ApplicationContainer consumers = consumerHelper.Install (consumerNodes);
   
-  consumers.Start (Seconds (0.0));
-  consumers.Stop (finishTime);
+  // consumers.Start (Seconds (0.0));
+  // consumers.Stop (finishTime);
     
   CcnxProducerHelper producerHelper (prefix.str (),120);
   ApplicationContainer producers = producerHelper.Install (producer);
   
-  producers.Start(Seconds(0.0));
-  producers.Stop(finishTime);
+  // producers.Start(Seconds(0.0));
+  // producers.Stop(finishTime);
 
   NS_LOG_INFO ("Outputing FIBs into [fibs.log]");
   Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("fibs.log", std::ios::out);
diff --git a/helper/ccnx-forwarding-helper.cc b/helper/ccnx-forwarding-helper.cc
index 6a8d3fb..31ffecb 100644
--- a/helper/ccnx-forwarding-helper.cc
+++ b/helper/ccnx-forwarding-helper.cc
@@ -32,37 +32,28 @@
     m_strategy = Ccnx::NDN_FLOODING;
 }
     
-CcnxForwardingHelper::CcnxForwardingHelper(Ccnx::ForwardingStrategy strategy)
+CcnxForwardingHelper::CcnxForwardingHelper (Ccnx::ForwardingStrategy strategy)
 {
     m_strategy = strategy;
 }
 
-CcnxForwardingHelper::~CcnxForwardingHelper ()
-{
-   
-}
-
 void 
-CcnxForwardingHelper::SetForwarding(Ptr<Ccnx> ccnx, Ptr<CcnxPit> pit) const
+CcnxForwardingHelper::SetForwarding (Ptr<Ccnx> ccnx) const
 {
     if(m_strategy == Ccnx::NDN_FLOODING)
     {
         Ptr<CcnxFloodingStrategy> ccnxForwarding = CreateObject<CcnxFloodingStrategy> ();
-        //ccnxForwarding->SetCcnx(ccnx);
-        ccnxForwarding->SetPit(pit);
         ccnx->SetForwardingStrategy (ccnxForwarding);
     }
     else if(m_strategy == Ccnx::NDN_BESTROUTE)
     {
         Ptr<CcnxBestRouteStrategy> ccnxForwarding = CreateObject<CcnxBestRouteStrategy> ();
-        //ccnxForwarding->SetCcnx(ccnx);
-        ccnxForwarding->SetPit(pit);
         ccnx->SetForwardingStrategy (ccnxForwarding);
     }
     else if (m_strategy == Ccnx::NDN_RANKING)
     {}
 }
-    
+
 // void
 // CcnxForwardingHelper::PrintForwardingTableAllAt (Time printTime, Ptr<OutputStreamWrapper> stream) const
 // {
diff --git a/helper/ccnx-forwarding-helper.h b/helper/ccnx-forwarding-helper.h
index fe9f9d4..d75a35a 100644
--- a/helper/ccnx-forwarding-helper.h
+++ b/helper/ccnx-forwarding-helper.h
@@ -42,7 +42,6 @@
 class CcnxForwardingHelper
 {
 public:
-    
   /*
    * \brief Default constructor, which sets NDN_FLOODING forwarding strategy
    */
@@ -52,16 +51,11 @@
    * \brief This constructor sets a specified forwarding strategy 
    */
   CcnxForwardingHelper(Ccnx::ForwardingStrategy strategy);
-  
-  /*
-   * Destroy an instance of an CcnxForwardingHelper
-   */
-  ~CcnxForwardingHelper ();
 
   /*
-   * \brief creates a specified ForwardingStrategy object and binds it to Pit
+   * \brief creates a specified ForwardingStrategy object
    */
-  void SetForwarding(Ptr<Ccnx> ccnx, Ptr<CcnxPit> pit) const;
+  void SetForwarding(Ptr<Ccnx> ccnx) const;
     
   /**
    * \brief prints the forwarding tables of all nodes at a particular time.
diff --git a/helper/ccnx-stack-helper.cc b/helper/ccnx-stack-helper.cc
index 3bc5ce9..f965fc7 100644
--- a/helper/ccnx-stack-helper.cc
+++ b/helper/ccnx-stack-helper.cc
@@ -204,8 +204,7 @@
   Ptr<CcnxL3Protocol> ccnx = CreateObject<CcnxL3Protocol> ();
   node->AggregateObject (ccnx);
 
-  Ptr<CcnxPit> pit = ccnx->GetPit();
-  NS_LOG_INFO("NODE->GetNDevices()="<<node->GetNDevices());
+  NS_LOG_INFO("NODE->GetNDevices()=" << node->GetNDevices());
     
   for (uint32_t index=0; index < node->GetNDevices (); index++)
     {
@@ -213,28 +212,28 @@
       if(device == 0)
         continue;
         
-      Ptr<CcnxNetDeviceFace> face = Create<CcnxNetDeviceFace> (node->GetDevice (index));
-      face->SetNode (node);
+      Ptr<CcnxNetDeviceFace> face = Create<CcnxNetDeviceFace> (node, node->GetDevice (index));
+
       uint32_t __attribute__ ((unused)) face_id = ccnx->AddFace (face);
       NS_LOG_LOGIC ("Node " << node->GetId () << ": added CcnxNetDeviceFace as face #" << face_id);
       // Setup bucket filtering
       // Assume that we know average data packet size, and this size is equal default size
       // Set maximum buckets (averaging over 1 second)
       
-      DataRateValue dataRate;
-      device->GetAttribute ("DataRate", dataRate);
-      NS_LOG_INFO("DataRate for this link is " << dataRate.Get());
-      pit->maxBucketsPerFace[face->GetId()] = 0.1 * dataRate.Get().GetBitRate () /(NDN_DEFAULT_DATA_SIZE + sizeof(CcnxInterestHeader));
-      NS_LOG_INFO("maxBucketsPerFace["<<face->GetId()<<"] = " << pit->maxBucketsPerFace[face->GetId()]); 
-      pit->leakSize[face->GetId()] = 0.97 * NDN_INTEREST_RESET_PERIOD.ToDouble(Time::S) * dataRate.Get().GetBitRate () / (NDN_DEFAULT_DATA_SIZE + sizeof(CcnxInterestHeader));
-      NS_LOG_INFO("pit->leakSize["<<face->GetId()<<"] = " << pit->leakSize[face->GetId()]);
+      // DataRateValue dataRate;
+      // device->GetAttribute ("DataRate", dataRate);
+      // NS_LOG_INFO("DataRate for this link is " << dataRate.Get());
+      // pit->maxBucketsPerFace[face->GetId()] = 0.1 * dataRate.Get().GetBitRate () /(NDN_DEFAULT_DATA_SIZE + sizeof(CcnxInterestHeader));
+      // NS_LOG_INFO("maxBucketsPerFace["<<face->GetId()<<"] = " << pit->maxBucketsPerFace[face->GetId()]); 
+      // pit->leakSize[face->GetId()] = 0.97 * NDN_INTEREST_RESET_PERIOD.ToDouble(Time::S) * dataRate.Get().GetBitRate () / (NDN_DEFAULT_DATA_SIZE + sizeof(CcnxInterestHeader));
+      // NS_LOG_INFO("pit->leakSize["<<face->GetId()<<"] = " << pit->leakSize[face->GetId()]);
         
       NS_LOG_INFO("Face #" << face_id << " is turned on");
       face->SetUp ();
       faces->Add (face);
     }
     
-  m_forwardingHelper.SetForwarding (ccnx, pit);
+  m_forwardingHelper.SetForwarding (ccnx);
 
   // ccnx->ScheduleLeakage ();
     
diff --git a/model/ccnx-bestroute-strategy.cc b/model/ccnx-bestroute-strategy.cc
index cad2d67..a7a9801 100644
--- a/model/ccnx-bestroute-strategy.cc
+++ b/model/ccnx-bestroute-strategy.cc
@@ -24,6 +24,10 @@
 #include "ns3/assert.h"
 #include "ns3/log.h"
 
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+namespace ll = boost::lambda;
+
 NS_LOG_COMPONENT_DEFINE ("CcnxBestRouteStrategy");
 
 namespace ns3 
@@ -65,12 +69,16 @@
           if (pitEntry.m_outgoing.find (bestMetric.m_face) != pitEntry.m_outgoing.end ()) // already forwarded before
             continue;
 
-          bool faceAvailable = bestMetric.m_face->SendWithLimit (packet->Copy ());
+          bool faceAvailable = bestMetric.m_face->IsBelowLimit ();
           if (!faceAvailable) // huh...
             continue;
 
           m_pit->modify (m_pit->iterator_to (pitEntry),
-                         bind(&CcnxPitEntry::AddOutgoing, lambda::_1, bestMetric.m_face));
+                         ll::bind(&CcnxPitEntry::AddOutgoing, ll::_1, bestMetric.m_face));
+
+          // NS_LOG_DEBUG ("new outgoing entry for " << boost::cref (*metricFace.m_face));
+
+          bestMetric.m_face->Send (packet->Copy ());
 
           forwardedCount++;
           break; // if we succeeded in sending one packet, stop
diff --git a/model/ccnx-face.cc b/model/ccnx-face.cc
index 1bb55ab..e6aa03f 100644
--- a/model/ccnx-face.cc
+++ b/model/ccnx-face.cc
@@ -21,6 +21,7 @@
 
 #include "ccnx-face.h"
 
+#include "ns3/packet.h"
 #include "ns3/log.h"
 #include "ns3/node.h"
 #include "ns3/assert.h"
@@ -35,7 +36,7 @@
  * invoke SetUp on them once an Ccnx address and mask have been set.
  */
 CcnxFace::CcnxFace (Ptr<Node> node) 
-  : m_node (Ptr<Node> node)
+  : m_node (node)
   , m_bucket (0.0)
   , m_bucketMax (-1.0)
   , m_bucketLeak (0.0)
@@ -44,6 +45,8 @@
   , m_id ((uint32_t)-1)
 {
   NS_LOG_FUNCTION (this);
+
+  NS_ASSERT_MSG (node != 0, "node cannot be NULL. Check the code");
 }
 
 CcnxFace::~CcnxFace ()
@@ -63,17 +66,20 @@
 void
 CcnxFace::RegisterProtocolHandler (ProtocolHandler handler)
 {
+  NS_LOG_FUNCTION_NOARGS ();
+
   m_protocolHandler = handler;
 }
 
 bool
-CcnxFace::SendWithLimit (Ptr<Packet> packet)
+CcnxFace::IsBelowLimit ()
 {
+  NS_LOG_FUNCTION_NOARGS ();
+
   /// \todo Implement tracing, if requested
-  
   if (!IsUp ())
     return false;
-
+  
   if (m_bucketMax > 0)
     {
       if (m_bucket+1.0 > m_bucketMax)
@@ -82,13 +88,14 @@
       m_bucket += 1.0;
     }
 
-  SendImpl (packet);
   return true;
 }
 
 bool
-CcnxFace::SendWithoutLimits (Ptr<Packet> packet)
+CcnxFace::Send (Ptr<Packet> packet)
 {
+  NS_LOG_FUNCTION_NOARGS ();
+
   /// \todo Implement tracing, if requested
 
   if (!IsUp ())
@@ -99,14 +106,18 @@
 }
 
 bool
-CcnxFace::Receive (Ptr<const Packet> packet)
+CcnxFace::Receive (const Ptr<const Packet> &packet)
 {
+  NS_LOG_FUNCTION_NOARGS ();
+
   /// \todo Implement tracing, if requested
 
   if (!IsUp ())
     return false;
 
   m_protocolHandler (this, packet);
+  
+  return true;
 }
 
 // void
diff --git a/model/ccnx-face.h b/model/ccnx-face.h
index bc6769e..132ef36 100644
--- a/model/ccnx-face.h
+++ b/model/ccnx-face.h
@@ -22,9 +22,11 @@
 #define CCNX_FACE_H
 
 #include <ostream>
+#include <algorithm>
 
 #include "ns3/ptr.h"
 #include "ns3/ccnx.h"
+#include "ns3/nstime.h"
 
 namespace ns3 {
 
@@ -71,40 +73,36 @@
    */
   virtual void
   RegisterProtocolHandler (ProtocolHandler handler);
-  
-  /**
-   * \brief Send packet on a face with regard Interest limits
-   *
-   * This method will be called by lower layers to send data to device or application
-   *
-   * \param p smart pointer to a packet to send
-   *
-   * @return false if either limit is reached or face is down
-   */ 
-  bool
-  SendWithLimit (Ptr<Packet> p);
 
   /**
-   * \brief Send content packet on a face without regard to limits
+   * @brief Check if Interest limit is reached
+   *
+   * Side effect: if limit is not yet reached, the number of outstanding packets will be increased
+   *
+   * @returns true if Interest limit is not yet reached
+   */
+  bool
+  IsBelowLimit ();
+  
+  /**
+   * \brief Send packet on a face
    *
    * This method will be called by lower layers to send data to device or application
    *
-   * !!! The only difference between this call and SendInterest is that the former check Interest limit !!!
-   *
    * \param p smart pointer to a packet to send
    *
-   * @return false if face is down
+   * @return false if either limit is reached
    */ 
   bool
-  SendWithoutLimits (Ptr<Packet> p);
+  Send (Ptr<Packet> p);
 
   /**
    * \brief Receive packet from application or another node and forward it to the CCNx stack
    *
    * \todo The only reason for this call is to handle tracing, if requested
    */
-  void
-  Receive (Ptr<const Packet> p);
+  bool
+  Receive (const Ptr<const Packet> &p);
   ////////////////////////////////////////////////////////////////////
 
   // /**
@@ -251,7 +249,7 @@
 CcnxFace::LeakBucket (const Time &interval)
 {
   const double leak = m_bucketLeak * 1.0 / interval.ToDouble (Time::S);
-  m_bucket -= std::max (0, m_bucket-leak); 
+  m_bucket -= std::max (0.0, m_bucket-leak); 
 }
 
 
diff --git a/model/ccnx-fib.cc b/model/ccnx-fib.cc
index bd3cd67..e4e36d5 100644
--- a/model/ccnx-fib.cc
+++ b/model/ccnx-fib.cc
@@ -33,14 +33,10 @@
 #define NDN_RTO_BETA 0.25
 #define NDN_RTO_K 4
 
-//#define NDN_DEBUG_OSPF	0
-//#define NDN_DEBUG_OSPF_NODES 0
-
 #include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+namespace ll = boost::lambda;
 
-using namespace boost;
-
-//#define NDN_DUMP_FIB		0
 namespace ns3 {
 
 
@@ -107,7 +103,7 @@
                  "Update status can be performed only on existing faces of CcxnFibEntry");
 
   m_faces.modify (record,
-                  bind (&CcnxFibFaceMetric::UpdateRtt, lambda::_1, sample));
+                  ll::bind (&CcnxFibFaceMetric::UpdateRtt, ll::_1, sample));
 
   // reordering random access index same way as by metric index
   m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
@@ -121,7 +117,7 @@
                  "Update status can be performed only on existing faces of CcxnFibEntry");
 
   m_faces.modify (record,
-                  (&lambda::_1)->*&CcnxFibFaceMetric::m_status = status);
+                  (&ll::_1)->*&CcnxFibFaceMetric::m_status = status);
 
   // reordering random access index same way as by metric index
   m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
@@ -141,7 +137,7 @@
   else
   {
     m_faces.modify (record,
-                    (&lambda::_1)->*&CcnxFibFaceMetric::m_routingCost = metric);
+                    (&ll::_1)->*&CcnxFibFaceMetric::m_routingCost = metric);
   }
   
   // reordering random access index same way as by metric index
@@ -211,33 +207,37 @@
 
   NS_ASSERT_MSG (face != NULL, "Trying to modify NULL face");
   modify (entry,
-          bind (&CcnxFibEntry::AddOrUpdateRoutingMetric, lambda::_1, face, metric));
+          ll::bind (&CcnxFibEntry::AddOrUpdateRoutingMetric, ll::_1, face, metric));
     
   return entry;
 }
     
 void
-CcnxFib::Delete (const CcnxNameComponents &prefix, Ptr<CcnxFace> face)
+CcnxFib::Remove (const CcnxFibEntry &entry, Ptr<CcnxFace> face)
 {
-  NS_LOG_FUNCTION (this << prefix << face);
+  NS_LOG_FUNCTION (this);
 
-  CcnxFibEntryContainer::type::iterator entry = find (prefix);
-  if (entry == end ())
-    return;
-
-  modify (entry,
-          bind (&CcnxFibEntry::RemoveFace, _1, face));
-  if (entry->m_faces.size () == 0)
+  modify (iterator_to (entry),
+          ll::bind (&CcnxFibEntry::RemoveFace, ll::_1, face));
+  if (entry.m_faces.size () == 0)
     {
-      erase (entry);
+      erase (iterator_to (entry));
     }
 }
 
 void
-CcnxFib::DeleteFromAll (Ptr<CcnxFace> face)
+CcnxFib::RemoveFromAll (Ptr<CcnxFace> face)
 {
+  NS_LOG_FUNCTION (this);
+
+  for_each (begin (), end (), ll::bind (&CcnxFib::Remove, this, ll::_1, face));
+  // BOOST_FOREACH (const CcnxFibEntry &entry, *this)
+  //   {
+  //     Remove (entry, face);
+  //   }
 }
 
+
 std::ostream& operator<< (std::ostream& os, const CcnxFib &fib)
 {
   os << "Node " << Names::FindName (fib.m_node) << "\n";
diff --git a/model/ccnx-fib.h b/model/ccnx-fib.h
index 84d618d..3e7807b 100644
--- a/model/ccnx-fib.h
+++ b/model/ccnx-fib.h
@@ -193,6 +193,15 @@
    */
   const CcnxFibFaceMetric &
   FindBestCandidate (uint32_t skip = 0) const;
+
+  /**
+   * @brief Remove record associated with `face`
+   */
+  void
+  RemoveFace (const Ptr<CcnxFace> &face)
+  {
+    m_faces.erase (face);
+  }
 	
 private:
   friend std::ostream& operator<< (std::ostream& os, const CcnxFibEntry &entry);
@@ -278,18 +287,18 @@
   Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric);
 
   /**
-   * @brief Remove reference to a face from the entry for `prefix`. If entry had only this face, the whole
+   * @brief Remove reference to a face from the entry. If entry had only this face, the whole
    * entry will be removed
    */
   void
-  Delete (const CcnxNameComponents &prefix, Ptr<CcnxFace> face);
+  Remove (const CcnxFibEntry &entry, Ptr<CcnxFace> face);
 
   /**
    * @brief Remove all references to a face from FIB.  If for some enty that face was the only element,
    * this FIB entry will be removed.
    */
   void
-  DeleteFromAll (Ptr<CcnxFace> face);
+  RemoveFromAll (Ptr<CcnxFace> face);
 
 protected:
   // inherited from Object class
diff --git a/model/ccnx-flooding-strategy.cc b/model/ccnx-flooding-strategy.cc
index 1fa7a93..52231b4 100644
--- a/model/ccnx-flooding-strategy.cc
+++ b/model/ccnx-flooding-strategy.cc
@@ -23,7 +23,11 @@
 #include "ns3/log.h"
 #include "ccnx-interest-header.h"
 
+#include <boost/ref.hpp>
 #include <boost/foreach.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+namespace ll = boost::lambda;
 
 NS_LOG_COMPONENT_DEFINE ("CcnxFloodingStrategy");
 
@@ -65,16 +69,21 @@
       if (pitEntry.m_outgoing.find (metricFace.m_face) != pitEntry.m_outgoing.end ()) // already forwarded before
         continue;
 
-      bool faceAvailable = metricFace.m_face->SendWithLimit (packet->Copy ());
+      bool faceAvailable = metricFace.m_face->IsBelowLimit ();
       if (!faceAvailable) // huh...
         continue;
 
       m_pit->modify (m_pit->iterator_to (pitEntry),
-                     bind(&CcnxPitEntry::AddOutgoing, lambda::_1, metricFace.m_face));
-        
+                     ll::bind(&CcnxPitEntry::AddOutgoing, ll::_1, metricFace.m_face));
+
+      // NS_LOG_DEBUG ("new outgoing entry for " << boost::cref (*metricFace.m_face));
+
+      metricFace.m_face->Send (packet->Copy ());
+      
       propagatedCount++;
     }
 
+  NS_LOG_INFO ("Propagated to " << propagatedCount << " faces");
   return propagatedCount > 0;
 }
     
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index 1d4c548..e0e12c2 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -64,7 +64,8 @@
     .AddAttribute ("BucketLeakInterval",
                    "Interval to leak buckets",
                    StringValue ("10ms"),
-                   MakeTimeAccessor (&CcnxPit::GetBucketLeakInterval, &CcnxPit::SetBucketLeakInterval),
+                   MakeTimeAccessor (&CcnxL3Protocol::GetBucketLeakInterval,
+                                     &CcnxL3Protocol::SetBucketLeakInterval),
                    MakeTimeChecker ())
   ;
   return tid;
@@ -144,7 +145,7 @@
 {
   NS_LOG_FUNCTION (this);
   m_forwardingStrategy = forwardingStrategy;
-  // m_forwardingStrategy->SetCcnx (this);
+  m_forwardingStrategy->SetPit (m_pit);
 }
 
 Ptr<CcnxForwardingStrategy>
@@ -158,7 +159,6 @@
 {
   NS_LOG_FUNCTION (this << &face);
 
-  face->SetNode (m_node);
   face->SetId (m_faceCounter); // sets a unique ID of the face. This ID serves only informational purposes
 
   // ask face to register in lower-layer stack
@@ -176,16 +176,16 @@
   face->RegisterProtocolHandler (MakeNullCallback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>&> ());
 
   // just to be on a safe side. Do the process in two steps
-  list<CcnxPitEntryContainer::type::iterator> entriesToRemoves; 
+  std::list<CcnxPitEntryContainer::type::iterator> entriesToRemoves; 
   BOOST_FOREACH (const CcnxPitEntry &pitEntry, *m_pit)
     {
       m_pit->modify (m_pit->iterator_to (pitEntry),
-                     ll::bind (CcnxPitEntry::RemoveAllReferencesToFace, ll::_1, face));
+                     ll::bind (&CcnxPitEntry::RemoveAllReferencesToFace, ll::_1, face));
 
       // If this face is the only for the associated FIB entry, then FIB entry will be removed soon.
       // Thus, we have to remove the whole PIT entry
-      if (m_pit->m_fibEntry.size () == 1 &&
-          m_pit->m_fibEntry.m_faces.begin ()->m_face == face)
+      if (pitEntry.m_fibEntry.m_faces.size () == 1 &&
+          pitEntry.m_fibEntry.m_faces.begin ()->m_face == face)
         {
           entriesToRemoves.push_back (m_pit->iterator_to (pitEntry));
         }
@@ -330,7 +330,7 @@
   //               {
   //                 header->SetNonce(it->m_nonce);
   //                 header->SetNack(true);
-  //                 face.m_face->SendWithoutLimit (packet->Copy());
+  //                 face.m_face->Send (packet->Copy());
   //               }
   //           }
   //       }
@@ -373,7 +373,7 @@
       Ptr<Packet> packet = Create<Packet> ();
       packet->AddHeader (*header);
 
-      incomingFace->SendWithoutLimit (packet);
+      incomingFace->Send (packet);
       
       // //Trace duplicate interest  
       // m_droppedInterestsTrace (header, NDN_DUPLICATE_INTEREST, m_node->GetObject<Ccnx> (), incomingFace);
@@ -391,7 +391,7 @@
         
       // TransmittedDataTrace (contentObject, CACHED,
       //                       m_node->GetObject<Ccnx> (), incomingFace);
-      incomingFace->SendWithoutLimit (contentObject);
+      incomingFace->Send (contentObject);
 
       // Set pruning timout on PIT entry (instead of deleting the record)
       m_pit->modify (m_pit->iterator_to (pitEntry),
@@ -462,7 +462,7 @@
 
       BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry.m_incoming)
         {
-          incoming.m_face->SendWithoutLimit (packet->Copy ());
+          incoming.m_face->Send (packet->Copy ());
 
           // m_droppedInterestsTrace (header, DROP_CONGESTION,
           //                          m_node->GetObject<Ccnx> (), incomingFace);
@@ -479,10 +479,11 @@
 }
 
 // Processing ContentObjects
-void CcnxL3Protocol::OnData (const Ptr<CcnxFace> &incomingFace,
-                             Ptr<CcnxContentObjectHeader> &header,
-                             Ptr<Packet> &payload,
-                             const Ptr<const Packet> &packet)
+void
+CcnxL3Protocol::OnData (const Ptr<CcnxFace> &incomingFace,
+                        Ptr<CcnxContentObjectHeader> &header,
+                        Ptr<Packet> &payload,
+                        const Ptr<const Packet> &packet)
 {
     
   NS_LOG_FUNCTION (incomingFace << header << payload << packet);
@@ -494,14 +495,6 @@
       const CcnxPitEntry &pitEntry = m_pit->Lookup (*header);
 
       // Note that with MultiIndex we need to modify entries indirectly
-  
-      // Update metric status for the incoming interface in the corresponding FIB entry
-      m_fib->modify (m_fib->iterator_to (pitEntry.m_fibEntry),
-                     ll::bind (&CcnxFibEntry::UpdateStatus, ll::_1,
-                           incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
-  
-      // Add or update entry in the content store
-      m_contentStore->Add (header, payload);
 
       CcnxPitEntryOutgoingFaceContainer::type::iterator out = pitEntry.m_outgoing.find (incomingFace);
   
@@ -510,9 +503,9 @@
         {
           m_fib->modify (m_fib->iterator_to (pitEntry.m_fibEntry),
                          ll::bind (&CcnxFibEntry::UpdateFaceRtt,
-                               ll::_1,
-                               incomingFace,
-                               Simulator::Now () - out->m_sendTime));
+                                   ll::_1,
+                                   incomingFace,
+                                   Simulator::Now () - out->m_sendTime));
         }
       else
         {
@@ -521,16 +514,25 @@
           
           NS_LOG_ERROR ("Node "<< m_node->GetId() <<
                        ". PIT entry for "<< header->GetName ()<<" is valid, "
-                       "but outgoing entry for interface "<< incomingFace <<" doesn't exist\n");
+                        "but outgoing entry for interface "<< boost::cref(*incomingFace) <<" doesn't exist\n");
 
-          NS_ASSERT (false); // temporary put false here
+          // ignore unsolicited data
+          return;
         }
 
+      // Update metric status for the incoming interface in the corresponding FIB entry
+      m_fib->modify (m_fib->iterator_to (pitEntry.m_fibEntry),
+                     ll::bind (&CcnxFibEntry::UpdateStatus, ll::_1,
+                               incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
+  
+      // Add or update entry in the content store
+      m_contentStore->Add (header, payload);
+
       //satisfy all pending incoming Interests
       BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry.m_incoming)
         {
           if (incoming.m_face != incomingFace)
-            incoming.m_face->SendWithoutLimit (packet->Copy ());
+            incoming.m_face->Send (packet->Copy ());
 
           // successfull forwarded data trace
         }
@@ -573,7 +575,7 @@
 }
 
 void 
-CcnxPit::LeakBuckets ()
+CcnxL3Protocol::LeakBuckets ()
 {
   BOOST_FOREACH (const Ptr<CcnxFace> &face, m_faces)
     {
diff --git a/model/ccnx-local-face.cc b/model/ccnx-local-face.cc
index 4a7c777..0f8ef27 100644
--- a/model/ccnx-local-face.cc
+++ b/model/ccnx-local-face.cc
@@ -28,6 +28,8 @@
 #include "ns3/assert.h"
 
 #include "ns3/ccnx-header-helper.h"
+#include "ns3/ccnx-app.h"
+
 #include "ccnx-interest-header.h"
 #include "ccnx-content-object-header.h"
 
@@ -37,12 +39,12 @@
 {
 
 CcnxLocalFace::CcnxLocalFace (Ptr<CcnxApp> app)
-  : CcnxFace (app->GetObject<Node> ())
+  : CcnxFace (app->GetNode ())
   , m_app (app)
 {
   NS_LOG_FUNCTION (this << app);
   
-  NS_ASSERT (app != 0);
+  NS_ASSERT (m_app != 0);
 }
 
 CcnxLocalFace::~CcnxLocalFace ()
@@ -53,11 +55,11 @@
 void
 CcnxLocalFace::RegisterProtocolHandler (ProtocolHandler handler)
 {
-  NS_LOG_FUNCTION (this << handler);
+  NS_LOG_FUNCTION (this);
 
   CcnxFace::RegisterProtocolHandler (handler);
 
-  app->RegisterProtocolHandler (MakeCallback (&CcnxFace::Receive, this));
+  m_app->RegisterProtocolHandler (MakeCallback (&CcnxFace::Receive, this));
 }
     
 void
@@ -71,23 +73,27 @@
       switch (type)
         {
         case CcnxHeaderHelper::INTEREST:
-          if (!m_onInterest.IsNull ())
-            {
-              Ptr<CcnxInterestHeader> header = Create<CcnxInterestHeader> ();
-              p->RemoveHeader (*header);
-              app->OnInterest (header);
-            }
-          break;
+          {
+            Ptr<CcnxInterestHeader> header = Create<CcnxInterestHeader> ();
+            p->RemoveHeader (*header);
+
+            if (header->GetNack () > 0)
+              m_app->OnNack (header);
+            else
+              m_app->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);
-              app->OnContentObject (header, p/*payload*/);
-            }
-          break;
+          {
+            static CcnxContentObjectTail tail;
+            Ptr<CcnxContentObjectHeader> header = Create<CcnxContentObjectHeader> ();
+            p->RemoveHeader (*header);
+            p->RemoveTrailer (tail);
+            m_app->OnContentObject (header, p/*payload*/);
+          
+            break;
+          }
         }
     }
   catch (CcnxUnknownHeaderException)
diff --git a/model/ccnx-local-face.h b/model/ccnx-local-face.h
index a7705ed..c8c4515 100644
--- a/model/ccnx-local-face.h
+++ b/model/ccnx-local-face.h
@@ -30,6 +30,7 @@
 class CcnxInterestHeader;
 class CcnxContentObjectHeader;
 class Packet;
+class CcnxApp;
 
 /**
  * \ingroup ccnx-face
@@ -69,7 +70,7 @@
   CcnxLocalFace& operator= (const CcnxLocalFace &); ///< \brief Disabled copy operator
 
 private:
-  Ptr<CcnxApp> m_application;
+  Ptr<CcnxApp> m_app;
 };
 
 std::ostream& operator<< (std::ostream& os, const CcnxLocalFace &localFace);
diff --git a/model/ccnx-name-components.h b/model/ccnx-name-components.h
index 5dafcfc..fdffe91 100644
--- a/model/ccnx-name-components.h
+++ b/model/ccnx-name-components.h
@@ -119,6 +119,13 @@
   return *this;
 }
 
+// template<>
+// void
+// CcnxNameComponents::Add (const std::string &string)
+// {
+//   m_prefix.push_back (string);
+// }
+
 template<class T>
 void
 CcnxNameComponents::Add (const T &value)
@@ -128,13 +135,6 @@
   m_prefix.push_back (os.str ());
 }
 
-template<class T=std::string>
-void
-CcnxNameComponents::Add (const T &string)
-{
-  m_prefix.push_back (string);
-}
-
 bool
 CcnxNameComponents::operator== (const CcnxNameComponents &prefix) const
 {
diff --git a/model/ccnx-net-device-face.cc b/model/ccnx-net-device-face.cc
index 72aa14a..dff7694 100644
--- a/model/ccnx-net-device-face.cc
+++ b/model/ccnx-net-device-face.cc
@@ -50,10 +50,6 @@
   NS_LOG_FUNCTION_NOARGS ();
 }
 
-CcnxNetDeviceFace::CcnxNetDeviceFace (const CcnxNetDeviceFace &)
-{
-}
-
 CcnxNetDeviceFace& CcnxNetDeviceFace::operator= (const CcnxNetDeviceFace &)
 {
   return *this;
@@ -68,7 +64,7 @@
 void
 CcnxNetDeviceFace::RegisterProtocolHandler (ProtocolHandler handler)
 {
-  NS_LOG_FUNCTION (this << handler);
+  NS_LOG_FUNCTION (this);
 
   CcnxFace::RegisterProtocolHandler (handler);
   
@@ -77,7 +73,7 @@
 }
 
 void
-CcnxNetDeviceFace::Send (Ptr<Packet> packet)
+CcnxNetDeviceFace::SendImpl (Ptr<Packet> packet)
 {
   NS_LOG_FUNCTION (this << packet);
   
diff --git a/model/ccnx-pit-entry.cc b/model/ccnx-pit-entry.cc
index cd6d854..a4db50a 100644
--- a/model/ccnx-pit-entry.cc
+++ b/model/ccnx-pit-entry.cc
@@ -38,12 +38,6 @@
 {
 }
 
-const CcnxNameComponents &
-CcnxPitEntry::GetPrefix () const
-{
-  return *m_prefix;
-}
-
 CcnxPitEntryIncomingFaceContainer::type::iterator
 CcnxPitEntry::AddIncoming (Ptr<CcnxFace> face)
 {
diff --git a/model/ccnx-pit-entry.h b/model/ccnx-pit-entry.h
index 52e7921..9f05e1e 100644
--- a/model/ccnx-pit-entry.h
+++ b/model/ccnx-pit-entry.h
@@ -108,8 +108,11 @@
   // // Get number of outgoing interests that we're expecting data from
   // inline size_t numberOfPromisingInterests( ) const; 
 
-  // const CcnxNameComponents &
-  // GetPrefix () const;
+  const CcnxNameComponents &
+  GetPrefix () const
+  {
+    return *m_prefix;
+  }
 
   /**
    * @brief Get current expiration time of the record
diff --git a/model/ccnx-pit.cc b/model/ccnx-pit.cc
index 63e1db8..9770bd0 100644
--- a/model/ccnx-pit.cc
+++ b/model/ccnx-pit.cc
@@ -86,9 +86,6 @@
   if (m_cleanupEvent.IsRunning ())
     m_cleanupEvent.Cancel ();
 
-  if (m_PitBucketLeakEvent.IsRunning ())
-    m_PitBucketLeakEvent.Cancel ();
-
   clear ();
 }