For duplicate interests keep incoming face !!! Need more thinking
diff --git a/helper/ccnx-stack-helper.cc b/helper/ccnx-stack-helper.cc
index 4fdb8a5..9fc02f4 100644
--- a/helper/ccnx-stack-helper.cc
+++ b/helper/ccnx-stack-helper.cc
@@ -146,7 +146,7 @@
       if (m_needSetDefaultRoutes)
         {
           // default route with lowest priority possible
-          AddRoute (node, "/", face, std::numeric_limits<int32_t>::max ()); 
+          AddRoute (node, "/bcast", face, std::numeric_limits<int32_t>::max ()); 
         }
       
       if (m_limitsEnabled)
diff --git a/model/ccnx-content-object-header.cc b/model/ccnx-content-object-header.cc
index ca013e8..d858e04 100644
--- a/model/ccnx-content-object-header.cc
+++ b/model/ccnx-content-object-header.cc
@@ -114,7 +114,8 @@
 void
 CcnxContentObjectHeader::Print (std::ostream &os) const
 {
-  os << "<ContentObject><Name>" << GetName () << "</Name><Content>";
+  os << "D: " << GetName ();
+  // os << "<ContentObject><Name>" << GetName () << "</Name><Content>";
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/model/ccnx-face.h b/model/ccnx-face.h
index e2100c6..16a31fd 100644
--- a/model/ccnx-face.h
+++ b/model/ccnx-face.h
@@ -27,6 +27,7 @@
 #include "ns3/ptr.h"
 #include "ns3/ccnx.h"
 #include "ns3/nstime.h"
+#include "ns3/type-id.h"
 
 namespace ns3 {
 
diff --git a/model/ccnx-interest-header.cc b/model/ccnx-interest-header.cc
index 941fc02..06777e3 100644
--- a/model/ccnx-interest-header.cc
+++ b/model/ccnx-interest-header.cc
@@ -218,6 +218,9 @@
 void
 CcnxInterestHeader::Print (std::ostream &os) const
 {
+  os << "I: " << GetName ();
+  
+  return;
   os << "<Interest>\n  <Name>" << GetName () << "</Name>\n";
   if (GetNack ()>0)
     {
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index c06e0cf..d216b4f 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -172,6 +172,13 @@
   return m_forwardingStrategy;
 }
 
+Ptr<CcnxPit>
+CcnxL3Protocol::GetPit () const
+{
+  return m_pit;
+}
+
+
 uint32_t 
 CcnxL3Protocol::AddFace (const Ptr<CcnxFace> &face)
 {
@@ -397,7 +404,6 @@
                                  Ptr<CcnxInterestHeader> &header,
                                  const Ptr<const Packet> &packet)
 {
-  NS_LOG_FUNCTION (incomingFace << header << packet << header->GetName ());
   m_inInterests (header, incomingFace);
   // NS_LOG_DEBUG (*m_pit);
 
@@ -409,8 +415,43 @@
 
   // NS_LOG_DEBUG ("isNew: " << isNew << ", isDup: " << isDuplicated);
   
+  NS_LOG_FUNCTION (header->GetName () << header->GetNonce () << boost::cref (*incomingFace) << isDuplicated);
+
+  /////////////////////////////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////////////////////////////
+  //                                                                                     //
+  // !!!! IMPORTANT CHANGE !!!! Duplicate interests will create incoming face entry !!!! //
+  //                                                                                     //
+  /////////////////////////////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////////////////////////////
+  
+  // Data is not in cache
+  CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry.m_incoming.find (incomingFace);
+  CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry.m_outgoing.find (incomingFace);
+
+  bool isRetransmitted = false;
+  
+  if (inFace != pitEntry.m_incoming.end ())
+    {
+      // CcnxPitEntryIncomingFace.m_arrivalTime keeps track arrival time of the first packet... why?
+
+      isRetransmitted = true;
+      // this is almost definitely a retransmission. But should we trust the user on that?
+    }
+  else
+    {
+      m_pit->modify (m_pit->iterator_to (pitEntry),
+                     ll::var(inFace) = ll::bind (&CcnxPitEntry::AddIncoming, ll::_1, incomingFace));
+    }
+  //////////////////////////////////////////////////////////////////////////////////
+  //////////////////////////////////////////////////////////////////////////////////
+  //////////////////////////////////////////////////////////////////////////////////
+  
   if (isDuplicated) 
     {
+      NS_LOG_DEBUG ("Received duplicatie interest on " << *incomingFace);
       m_dropInterests (header, DUPLICATED, incomingFace);
 
       /**
@@ -439,45 +480,13 @@
   tie (contentObject, contentObjectHeader, payload) = m_contentStore->Lookup (header);
   if (contentObject != 0)
     {
-      NS_ASSERT (contentObjectHeader != 0);
-      
+      NS_ASSERT (contentObjectHeader != 0);      
       NS_LOG_LOGIC("Found in cache");
-        
-      incomingFace->Send (contentObject);
-      m_outData (contentObjectHeader, payload, true, incomingFace);
 
-      // Set pruning timout on PIT entry (instead of deleting the record)
-      m_pit->modify (m_pit->iterator_to (pitEntry),
-                     bind (&CcnxPitEntry::SetExpireTime, ll::_1,
-                           Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
-        
+      OnDataDelayed (contentObjectHeader, contentObject, payload);
       return;
     }
 
-  // \todo Detect retransmissions. Not yet sure how...
-  
-  // Data is not in cache
-  CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry.m_incoming.find (incomingFace);
-  CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry.m_outgoing.find (incomingFace);
-
-  bool isRetransmitted = false;
-  
-  if (inFace != pitEntry.m_incoming.end ())
-    {
-      // CcnxPitEntryIncomingFace.m_arrivalTime keeps track arrival time of the first packet... why?
-
-      isRetransmitted = true;
-      // this is almost definitely a retransmission. But should we trust the user on that?
-    }
-  else
-    {
-      m_pit->modify (m_pit->iterator_to (pitEntry),
-                     ll::var(inFace) = ll::bind (&CcnxPitEntry::AddIncoming, ll::_1, incomingFace));
-    }
-
-  // NS_LOG_DEBUG ("IsRetx: " << isRetransmitted);
-  // NS_LOG_DEBUG (*m_pit);
-
   // update PIT entry lifetime
   m_pit->modify (m_pit->iterator_to (pitEntry),
                  ll::bind (&CcnxPitEntry::UpdateLifetime, ll::_1,
@@ -539,8 +548,8 @@
 }
 
 void
-CcnxL3Protocol::OnDataDelayed (Ptr<CcnxContentObjectHeader> header,
-                               Ptr<Packet> payload,
+CcnxL3Protocol::OnDataDelayed (Ptr<const CcnxContentObjectHeader> header,
+                               Ptr<const Packet> payload,
                                const Ptr<const Packet> &packet)
 {
   if (m_delayingDataProcessing)
diff --git a/model/ccnx-l3-protocol.h b/model/ccnx-l3-protocol.h
index a9c4f8a..c790c8e 100644
--- a/model/ccnx-l3-protocol.h
+++ b/model/ccnx-l3-protocol.h
@@ -118,7 +118,8 @@
   virtual Ptr<CcnxFace>
   GetFaceByNetDevice (Ptr<NetDevice> netDevice) const;
   
-  Ptr<CcnxPit> GetPit();
+  virtual Ptr<CcnxPit>
+  GetPit () const;
   
   // void ScheduleLeakage();
 private:
@@ -196,8 +197,8 @@
                   Ptr<CcnxInterestHeader> header);
 
   void
-  OnDataDelayed (Ptr<CcnxContentObjectHeader> header,
-                 Ptr<Packet> payload,
+  OnDataDelayed (Ptr<const CcnxContentObjectHeader> header,
+                 Ptr<const Packet> payload,
                  const Ptr<const Packet> &packet);
   
 private:
diff --git a/model/ccnx-net-device-face.cc b/model/ccnx-net-device-face.cc
index d14e136..2fe1840 100644
--- a/model/ccnx-net-device-face.cc
+++ b/model/ccnx-net-device-face.cc
@@ -28,6 +28,9 @@
 #include "ns3/node.h"
 #include "ns3/pointer.h"
 
+#include "ns3/point-to-point-net-device.h"
+#include "ns3/channel.h"
+
 NS_LOG_COMPONENT_DEFINE ("CcnxNetDeviceFace");
 
 namespace ns3 {
@@ -115,7 +118,11 @@
 std::ostream&
 CcnxNetDeviceFace::Print (std::ostream& os) const
 {
-  os << "dev[" << GetNode ()->GetId () << "]=net(" << GetId () << ")";
+  os << "dev[" << GetNode ()->GetId () << "]=net(" << GetId () << ",";
+  os << DynamicCast<PointToPointNetDevice> (m_netDevice)->GetChannel ()->GetDevice (0)->GetNode ()->GetId ();
+  os << "-";
+  os << DynamicCast<PointToPointNetDevice> (m_netDevice)->GetChannel ()->GetDevice (1)->GetNode ()->GetId ();
+  os << ")";
   return os;
 }
 
diff --git a/model/ccnx-pit-entry.cc b/model/ccnx-pit-entry.cc
index d0615b0..bcd384d 100644
--- a/model/ccnx-pit-entry.cc
+++ b/model/ccnx-pit-entry.cc
@@ -153,7 +153,13 @@
 CcnxPitEntry::IncreaseAllowedRetxCount ()
 {
   NS_LOG_ERROR (this);
-  m_maxRetxCount++;
+  // if (Simulator::Now () - m_lastRetransmission >= MilliSeconds (10))
+    {
+      // cheat:
+      // don't allow retransmission faster than every 10ms
+      m_maxRetxCount++;
+      // m_lastRetransmission = Simulator::Now ();
+    }
 }
 
 std::ostream& operator<< (std::ostream& os, const CcnxPitEntry &entry)
@@ -182,6 +188,17 @@
       
       os << *face.m_face;
     }
+  os << "\nNonces: ";
+  first = true;
+  BOOST_FOREACH (uint32_t nonce, entry.m_seenNonces)
+    {
+      if (!first)
+        os << ",";
+      else
+        first = false;
+      
+      os << nonce;
+    }
 
   return os;
 }
diff --git a/model/ccnx-pit-entry.h b/model/ccnx-pit-entry.h
index ad865ba..40f33d1 100644
--- a/model/ccnx-pit-entry.h
+++ b/model/ccnx-pit-entry.h
@@ -253,6 +253,7 @@
 
   Time m_expireTime;         ///< \brief Time when PIT entry will be removed
 
+  Time m_lastRetransmission; ///< @brief Last time when number of retransmissions were increased
   uint32_t m_maxRetxCount;   ///< @brief Maximum allowed number of retransmissions via outgoing faces
 };
 
diff --git a/model/ccnx-pit.cc b/model/ccnx-pit.cc
index a68c4a7..6e63550 100644
--- a/model/ccnx-pit.cc
+++ b/model/ccnx-pit.cc
@@ -219,6 +219,9 @@
 {
   BOOST_FOREACH (const CcnxPitEntry &entry, pit)
     {
+      if (entry.m_incoming.size () == 0 && entry.m_outgoing.size () == 0)
+        continue; // these are stale to-be-removed records, so there is no need to print them out
+      
       os << entry << std::endl;
     }
 
diff --git a/model/ccnx.h b/model/ccnx.h
index 8d565c1..1008753 100644
--- a/model/ccnx.h
+++ b/model/ccnx.h
@@ -34,6 +34,7 @@
 class CcnxFace;
 class CcnxContentObjectHeader;
 class CcnxInterestHeader;
+class CcnxPit;
 
 /**
  * \internal
@@ -145,11 +146,16 @@
   RemoveFace (Ptr<CcnxFace> face) = 0;
 
   /**
-   * Get face for NetDevice
+   * \brief Get face for NetDevice
    */
   virtual Ptr<CcnxFace>
   GetFaceByNetDevice (Ptr<NetDevice> netDevice) const = 0;
 
+  /**
+   * \brief Get PIT associated with Node 
+   */
+  virtual Ptr<CcnxPit>
+  GetPit() const = 0;
 
   /**
    * \enum DropReason
diff --git a/wscript b/wscript
index 06ee05c..9203c61 100644
--- a/wscript
+++ b/wscript
@@ -70,6 +70,10 @@
         "apps/ccnx-app.h",
 
         "model/ccnx.h",
+        "model/ccnx-pit.h",
+        "model/ccnx-pit-entry.h",
+        "model/ccnx-pit-entry-incoming-face.h",
+        "model/ccnx-pit-entry-outgoing-face.h",
         "model/ccnx-fib.h",
         "model/ccnx-face.h",
         "model/ccnx-interest-header.h",