Implementing face clean up callback in forwarding strategy

Necessary for FwStats strategy that uses CcnxFace object as a key to
several statistics parameters.
diff --git a/apps/ccnx-app.cc b/apps/ccnx-app.cc
index 8cdddac..59da17c 100644
--- a/apps/ccnx-app.cc
+++ b/apps/ccnx-app.cc
@@ -28,6 +28,7 @@
 #include "ns3/ccnx.h"
 #include "ns3/ccnx-fib.h"
 #include "ns3/ccnx-app-face.h"
+#include "ns3/ccnx-forwarding-strategy.h"
 
 NS_LOG_COMPONENT_DEFINE ("CcnxApp");
 
@@ -151,6 +152,7 @@
   // step 2. Remove face from CCNx stack
   GetNode ()->GetObject<Ccnx> ()->RemoveFace (m_face);
   GetNode ()->GetObject<CcnxFib> ()->RemoveFromAll (m_face);
+  GetNode ()->GetObject<CcnxForwardingStrategy> ()->RemoveFace (m_face); // notify that face is removed
 
   // step 3. Destroy face
   NS_ASSERT_MSG (m_face->GetReferenceCount ()==1,
diff --git a/model/forwarding-strategy/ccnx-forwarding-strategy.cc b/model/forwarding-strategy/ccnx-forwarding-strategy.cc
index 88451e6..ddc4e51 100644
--- a/model/forwarding-strategy/ccnx-forwarding-strategy.cc
+++ b/model/forwarding-strategy/ccnx-forwarding-strategy.cc
@@ -473,4 +473,11 @@
   // do nothing for now. may be need to do some logging
 }
 
+
+void
+CcnxForwardingStrategy::RemoveFace (Ptr<CcnxFace> face)
+{
+  // do nothing here
+}
+
 } //namespace ns3
diff --git a/model/forwarding-strategy/ccnx-forwarding-strategy.h b/model/forwarding-strategy/ccnx-forwarding-strategy.h
index 20ef1b5..ff0dcef 100644
--- a/model/forwarding-strategy/ccnx-forwarding-strategy.h
+++ b/model/forwarding-strategy/ccnx-forwarding-strategy.h
@@ -83,6 +83,9 @@
 
   virtual void
   WillErasePendingInterest (Ptr<CcnxPitEntry> pitEntry);
+
+  virtual void
+  RemoveFace (Ptr<CcnxFace> face);
   
 protected:
   // events
diff --git a/model/forwarding-strategy/fw-stats.cc b/model/forwarding-strategy/fw-stats.cc
index 9d15152..cd3b744 100644
--- a/model/forwarding-strategy/fw-stats.cc
+++ b/model/forwarding-strategy/fw-stats.cc
@@ -193,6 +193,13 @@
     }
 }
 
+void
+FwStats::RemoveFace (Ptr<CcnxFace> face)
+{
+  m_stats.RemoveFace (face);
+
+  super::RemoveFace (face);
+}
 
 
 } // namespace ndnSIM
diff --git a/model/forwarding-strategy/fw-stats.h b/model/forwarding-strategy/fw-stats.h
index 1849fb2..67f2763 100644
--- a/model/forwarding-strategy/fw-stats.h
+++ b/model/forwarding-strategy/fw-stats.h
@@ -56,7 +56,10 @@
           Ptr<CcnxContentObjectHeader> &header,
           Ptr<Packet> &payload,
           const Ptr<const Packet> &packet);
-  
+
+  virtual void
+  RemoveFace (Ptr<CcnxFace> face);
+
 protected:
   virtual void
   DidCreatePitEntry (const Ptr<CcnxFace> &incomingFace,
diff --git a/utils/load-stats-node.cc b/utils/load-stats-node.cc
index e64bb9d..04ac660 100644
--- a/utils/load-stats-node.cc
+++ b/utils/load-stats-node.cc
@@ -170,6 +170,15 @@
   return zero;  
 }
 
+
+void
+LoadStatsNode::RemoveFace (ns3::Ptr<ns3::CcnxFace> face)
+{
+  NS_LOG_FUNCTION (this);
+  m_incoming.erase (face);
+  m_outgoing.erase (face);
+}
+
 bool
 LoadStatsNode::operator == (const LoadStatsNode &other) const
 {
diff --git a/utils/load-stats-node.h b/utils/load-stats-node.h
index 9bdf5be..a4d6d87 100644
--- a/utils/load-stats-node.h
+++ b/utils/load-stats-node.h
@@ -118,6 +118,9 @@
     // don't do any copying at all
     return *this;
   }
+
+  void
+  RemoveFace (ns3::Ptr<ns3::CcnxFace> face);
   
 private:
   LoadStatsFace   m_pit;
diff --git a/utils/stats-tree.cc b/utils/stats-tree.cc
index e987043..d83b881 100644
--- a/utils/stats-tree.cc
+++ b/utils/stats-tree.cc
@@ -137,6 +137,16 @@
   return node->payload ();
 }
 
+void
+StatsTree::RemoveFace (ns3::Ptr<ns3::CcnxFace> face)
+{
+  tree_type::recursive_iterator item (&m_tree), end;
+  for (; item != end; item ++)
+    {
+      item->payload ().RemoveFace (face);
+    }
+}
+
 std::ostream &
 operator << (std::ostream &os, const StatsTree &tree)
 {
diff --git a/utils/stats-tree.h b/utils/stats-tree.h
index 9702675..1bb128b 100644
--- a/utils/stats-tree.h
+++ b/utils/stats-tree.h
@@ -65,10 +65,14 @@
   // Get (const ns3::CcnxNameComponents &key) const;
   const LoadStatsNode &
   operator [] (const ns3::CcnxNameComponents &key) const;
+
+  void
+  RemoveFace (ns3::Ptr<ns3::CcnxFace> face);
   
 private:
   const LoadStatsNode &
   WalkLeftRightRoot (tree_type *node);
+
   
 private:
   tree_type m_tree;