When giving up PIT entry, remove all outgoing interests. Otherwise,
everything can stuck (was happening...)

Modified experiment with synthetic topology
diff --git a/apps/ccnx-consumer.cc b/apps/ccnx-consumer.cc
index 4bd4d4c..cc3276f 100644
--- a/apps/ccnx-consumer.cc
+++ b/apps/ccnx-consumer.cc
@@ -192,7 +192,9 @@
   if (m_retxSeqs.size () != 0)
     {
       seq = *m_retxSeqs.begin ();
+      NS_LOG_INFO ("Before: " << m_retxSeqs.size ());
       m_retxSeqs.erase (m_retxSeqs.begin ());
+      NS_LOG_INFO ("After: " << m_retxSeqs.size ());
     }
   else
     seq = m_seq++;
@@ -265,6 +267,9 @@
 {
   CcnxApp::OnNack (interest); // tracing inside
   
+  NS_LOG_DEBUG ("Nack type: " << interest->GetNack ());
+  boost::mutex::scoped_lock (m_seqTimeoutsGuard);
+
   NS_LOG_FUNCTION (this << interest);
 
   // NS_LOG_INFO ("Received NACK: " << boost::cref(*interest));
@@ -272,7 +277,9 @@
   NS_LOG_INFO ("< NACK for " << seq);
 
   // put in the queue of interests to be retransmitted
+  NS_LOG_INFO ("Before: " << m_retxSeqs.size ());
   m_retxSeqs.insert (seq);
+  NS_LOG_INFO ("After: " << m_retxSeqs.size ());
 }
 
 } // namespace ns3
diff --git a/examples/synthetic-topology.cc b/examples/synthetic-topology.cc
index b19b375..f03c22e 100644
--- a/examples/synthetic-topology.cc
+++ b/examples/synthetic-topology.cc
@@ -44,7 +44,7 @@
   Simulator::Schedule (Seconds (10.0), PrintTime);
 }
 
-int 
+int
 main (int argc, char *argv[])
 {
   string input ("./src/NDNabstraction/examples/synthetic-topology.txt");
@@ -64,18 +64,18 @@
   // --------------------------------------------
     
   AnnotatedTopologyReader reader ("/synthetic");
-  reader.SetMobilityModel ("ns3::SpringMobilityModel");
+  // reader.SetMobilityModel ("ns3::SpringMobilityModel");
   reader.SetFileName (input);
   NodeContainer nodes = reader.Read ();
-  SpringMobilityHelper::InstallSprings (reader.LinksBegin (), reader.LinksEnd ());
+  // SpringMobilityHelper::InstallSprings (reader.LinksBegin (), reader.LinksEnd ());
     
   InternetStackHelper stack;
   Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingOrderedNexthops");
   stack.SetRoutingHelper (ipv4RoutingHelper);
   stack.Install (nodes);
-  /*
-    reader.AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
-  */
+
+  reader.AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
+
   NS_LOG_INFO("Nodes = " << nodes.GetN());
   NS_LOG_INFO("Links = " << reader.LinksSize ());
     
@@ -84,31 +84,50 @@
   CcnxStackHelper ccnxHelper;
   ccnxHelper.SetForwardingStrategy (strategy);
   ccnxHelper.EnableLimits (true, Seconds(0.1));
-  ccnxHelper.SetDefaultRoutes (true);
+  ccnxHelper.SetDefaultRoutes (false);
   ccnxHelper.InstallAll ();
     
   NS_LOG_INFO ("Installing Applications");
-  CcnxConsumerHelper consumerHelper ("/1");
-  ApplicationContainer consumers = consumerHelper.Install (Names::Find<Node> ("/synthetic", "NODE1"));
-    
-  CcnxConsumerHelper consumerHelper2("/2");
-  ApplicationContainer consumers2 = consumerHelper2.Install(Names::Find<Node> ("/synthetic", "NODE2"));
-    
-  CcnxProducerHelper producerHelper ("/1",1024);
-  ApplicationContainer producers = producerHelper.Install (Names::Find<Node> ("/synthetic", "NODE6"));
-        
-  CcnxProducerHelper producerHelper2 ("/2",1024);
-  ApplicationContainer producers2 = producerHelper2.Install (Names::Find<Node> ("/synthetic", "NODE7"));
+  CcnxConsumerHelper consumerHelper ("/6");
+  ApplicationContainer consumers = consumerHelper.Install (Names::Find<Node> ("/synthetic", "c1"));
 
+  consumerHelper.SetPrefix ("/7");
+  ApplicationContainer consumers2 = consumerHelper.Install(Names::Find<Node> ("/synthetic", "c2"));
+
+  consumerHelper.SetPrefix ("/8");
+  ApplicationContainer consumers3 = consumerHelper.Install(Names::Find<Node> ("/synthetic", "c3"));
+  
+  consumerHelper.SetPrefix ("/10");
+  ApplicationContainer consumers4 = consumerHelper.Install(Names::Find<Node> ("/synthetic", "c4"));
+
+  consumers.Start (Seconds (2.121212123));
+  consumers2.Start (Seconds (0.166666));
+  consumers3.Start (Seconds (4.1235432));
+  consumers4.Start (Seconds (3.00005421));
+  
+  CcnxProducerHelper producerHelper ("/6",1024);
+  ApplicationContainer producers = producerHelper.Install (Names::Find<Node> ("/synthetic", "p1"));
+        
+  CcnxProducerHelper producerHelper2 ("/7",1024);
+  ApplicationContainer producers2 = producerHelper2.Install (Names::Find<Node> ("/synthetic", "p2"));
+
+  CcnxProducerHelper producerHelper3 ("/8",1024);
+  ApplicationContainer producers3 = producerHelper3.Install (Names::Find<Node> ("/synthetic", "p3"));
+  
+  CcnxProducerHelper producerHelper4 ("/10",1024);
+  ApplicationContainer producers4 = producerHelper4.Install (Names::Find<Node> ("/synthetic", "p4"));
+  
   Simulator::Schedule (Seconds (10.0), PrintTime);
 
   // Populate FIB based on IPv4 global routing controller
-  //ccnxHelper.InstallFakeGlobalRoutes ();
-  //ccnxHelper.InstallRouteTo (Names::Find<Node> ("/synthetic", "NODE1"));
-  //ccnxHelper.InstallRouteTo (Names::Find<Node> ("/synthetic", "NODE7"));
-    
+  ccnxHelper.InstallFakeGlobalRoutes ();
+  ccnxHelper.InstallRouteTo (Names::Find<Node> ("/synthetic", "p1"));
+  ccnxHelper.InstallRouteTo (Names::Find<Node> ("/synthetic", "p2"));
+  ccnxHelper.InstallRouteTo (Names::Find<Node> ("/synthetic", "p3"));
+  ccnxHelper.InstallRouteTo (Names::Find<Node> ("/synthetic", "p4"));
+
   Simulator::Stop (finishTime);
-    
+
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
   Simulator::Destroy ();
diff --git a/examples/synthetic-topology.txt b/examples/synthetic-topology.txt
index 2c080d9..0d175b0 100644
--- a/examples/synthetic-topology.txt
+++ b/examples/synthetic-topology.txt
@@ -1,20 +1,29 @@
 router
 #name	city	latitude	longitude
-NODE1	NODE1	60		20
-NODE2	NODE2	20		20
-NODE3	NODE3	40		40
-NODE4	NODE4	20		60
-NODE5	NODE5	40		80
-NODE6	NODE6	60  		100
-NODE7	NODE7	20		100
+c1	NODE1	50		30
+c2	NODE2	30		30
+c3	x	10		30
+n1	NODE3	40		40
+n12	NODE4	30		60
+n2	NODE5	40		80
+p1	NODE6	50  		90
+p2	NODE7	30		90
+p3	x	10		90
+c4	x	10		40
+p4	x	10		80
 link
 #capacity on 4/10/2003 (see page 20 of http://www.internet2.edu/presentations/spring03/20030410-Abilene-Corbato.pdf)
 #OSPF weight on 04/10/2003 (see http://www.abilene.iu.edu/images/Ab-IGP-topo.jpg)
-#x	y	capacity(kbps)	OSPF    Delay   QueueSize1	QueueSize2
-NODE1	NODE3	10Mbps 		1 	1  	150  	    	150
-NODE2	NODE3	10Mbps 		1 	1   	150 	    	150
-NODE3	NODE4	1Mbps 		1176   	1   	15  		15
-NODE3	NODE5	1Mbps 		587    	1   	15  		15
-NODE4	NODE5	1Mbps 		846    	1   	15  		15
-NODE5	NODE6	10Mbps 		260   	1   	150		150
-NODE5	NODE7	10Mbps 		700   	50  	150		150
+#x	y	capacity(kbps)	OSPF    Delay		MaxPackets
+c1	n1	10Mbps 		1 	1ms  		200
+c2	n1	10Mbps 		1 	1ms   		200
+c3	n1	10Mbps		1	1ms		200
+n1	n2	1Mbps 		1176   	1ms   		20 
+n1	n12	1Mbps 		587    	1ms   		20
+n12	n2	1Mbps 		846    	1ms   		20
+n2	p1	10Mbps 		260   	50ms   		200
+n2	p2	10Mbps 		700   	1ms  		200
+n2	p3	10Mbps		1	1ms		200
+c4	n1	10Mbps		1	1ms		200
+n2	p4	10Mbps		1	1ms		200
+
diff --git a/helper/ccnx-consumer-helper.cc b/helper/ccnx-consumer-helper.cc
index f6fcb7c..dc29d9a 100644
--- a/helper/ccnx-consumer-helper.cc
+++ b/helper/ccnx-consumer-helper.cc
@@ -32,12 +32,18 @@
 CcnxConsumerHelper::CcnxConsumerHelper (const std::string &prefix)
 {
     m_factory.SetTypeId ("ns3::CcnxConsumer");
-    
+
+    SetPrefix (prefix);
+}
+
+void
+CcnxConsumerHelper::SetPrefix (const std::string &prefix)
+{
     CcnxNameComponentsValue prefixValue;
     prefixValue.DeserializeFromString (prefix, MakeCcnxNameComponentsChecker ());
     m_factory.Set ("InterestName", prefixValue);
 }
-    
+
 void 
 CcnxConsumerHelper::SetAttribute (std::string name, const AttributeValue &value)
 {
diff --git a/helper/ccnx-consumer-helper.h b/helper/ccnx-consumer-helper.h
index 158ede7..aa7c8c9 100644
--- a/helper/ccnx-consumer-helper.h
+++ b/helper/ccnx-consumer-helper.h
@@ -44,7 +44,13 @@
    * \param prefix Prefix which will be requested by the consumer applications
    */
   CcnxConsumerHelper (const std::string &prefix);
-        
+
+  /**
+   * @brief Set the prefix consumer will be requesting
+   */
+  void
+  SetPrefix (const std::string &prefix);
+  
   /**
    * \brief Helper function used to set the underlying application attributes.
    *
diff --git a/model/annotated-topology-reader.cc b/model/annotated-topology-reader.cc
index 8caceb1..edcff58 100644
--- a/model/annotated-topology-reader.cc
+++ b/model/annotated-topology-reader.cc
@@ -137,7 +137,7 @@
       double latitude, longitude;
 
       lineBuffer >> name >> city >> latitude >> longitude;
-      Ptr<Node> node = CreateNode (name, 2*longitude, -2*latitude);
+      Ptr<Node> node = CreateNode (name, longitude, -latitude);
       nodes.Add (node);
     }
 
@@ -154,9 +154,9 @@
       // NS_LOG_DEBUG ("Input: [" << line << "]");
       
       istringstream lineBuffer (line);
-      string from, to, capacity, metric, delay, queueSizeNode1, queueSizeNode2;
+      string from, to, capacity, metric, delay, maxPackets;
 
-      lineBuffer >> from >> to >> capacity >> metric >> delay >> queueSizeNode1 >> queueSizeNode2;
+      lineBuffer >> from >> to >> capacity >> metric >> delay >> maxPackets;
 
       if (processedLinks[to].size () != 0 &&
           processedLinks[to].find (from) != processedLinks[to].end ())
@@ -177,13 +177,11 @@
 
       if (!delay.empty ())
           link.SetAttribute ("Delay", delay);
-      if (!queueSizeNode1.empty ())
-        link.SetAttribute ("QueueSizeNode1", queueSizeNode1);
-      if (!queueSizeNode2.empty ())
-        link.SetAttribute ("QueueSizeNode2", queueSizeNode2);
+      if (!maxPackets.empty ())
+        link.SetAttribute ("MaxPackets", maxPackets);
 
       AddLink (link);
-      NS_LOG_DEBUG ("New link " << from << " <==> " << to << " / " << capacity << "Kbps with " << metric << " metric");
+      NS_LOG_DEBUG ("New link " << from << " <==> " << to << " / " << capacity << " with " << metric << " metric (" << delay << ", " << maxPackets << ")");
     }
         
   NS_LOG_INFO ("Annotated topology created with " << nodes.GetN () << " nodes and " << LinksSize () << " links");
@@ -253,37 +251,33 @@
       if (link.GetAttributeFailSafe ("DataRate", tmp))
         {
           NS_LOG_INFO ("DataRate = " + link.GetAttribute("DataRate"));
-          p2p.SetDeviceAttribute ("DataRate", StringValue(link.GetAttribute("DataRate")));
+          p2p.SetDeviceAttribute ("DataRate", StringValue (link.GetAttribute ("DataRate")));
         }
 
-      if (link.GetAttributeFailSafe("Delay", tmp))
+      if (link.GetAttributeFailSafe ("Delay", tmp))
         {
           NS_LOG_INFO ("Delay = " + link.GetAttribute("Delay"));
-          p2p.SetChannelAttribute ("Delay", StringValue(link.GetAttribute("Delay")));
+          p2p.SetChannelAttribute ("Delay", StringValue (link.GetAttribute ("Delay")));
         }
-        
+
       NetDeviceContainer nd = p2p.Install(link.GetFromNode (), link.GetToNode ());
       link.SetNetDevices (nd.Get (0), nd.Get (1));
 
-      if (link.GetAttributeFailSafe("QueueSizeNode1", tmp))
+      if (link.GetAttributeFailSafe ("MaxPackets", tmp))
         {
-          PointerValue txQueueFrom;
-          link.GetFromNetDevice ()->GetAttribute ("TxQueue", txQueueFrom);
-          NS_ASSERT (txQueueFrom.Get<DropTailQueue> () != 0);
+          NS_LOG_INFO ("MaxPackets = " + link.GetAttribute ("MaxPackets"));
 
-          NS_LOG_INFO ("QueueFrom: " << link.GetAttribute("QueueSizeNode1"));
-          txQueueFrom.Get<DropTailQueue> ()->SetAttribute ("MaxPackets", StringValue (link.GetAttribute("QueueSizeNode1")));
+          PointerValue txQueue;
+
+          link.GetToNetDevice ()->GetAttribute ("TxQueue", txQueue);
+          NS_ASSERT (txQueue.Get<DropTailQueue> () != 0);       
+          txQueue.Get<DropTailQueue> ()->SetAttribute ("MaxPackets", StringValue (link.GetAttribute ("MaxPackets")));
+
+          link.GetFromNetDevice ()->GetAttribute ("TxQueue", txQueue);
+          NS_ASSERT (txQueue.Get<DropTailQueue> () != 0);
+          txQueue.Get<DropTailQueue> ()->SetAttribute ("MaxPackets", StringValue (link.GetAttribute ("MaxPackets")));
         }
-      
-      if (link.GetAttributeFailSafe("QueueSizeNode2", tmp))
-        {
-          PointerValue txQueueTo;
-          link.GetToNetDevice ()->GetAttribute ("TxQueue", txQueueTo);
-          NS_ASSERT (txQueueTo.Get<DropTailQueue> () != 0);
         
-          NS_LOG_INFO ("QueueTo: " << link.GetAttribute("QueueSizeNode2"));
-          txQueueTo.Get<DropTailQueue> ()->SetAttribute ("MaxPackets", StringValue (link.GetAttribute("QueueSizeNode2")));
-        }
     }
 }
 
diff --git a/model/ccnx-bestroute-strategy.cc b/model/ccnx-bestroute-strategy.cc
index 776315f..2bbe287 100644
--- a/model/ccnx-bestroute-strategy.cc
+++ b/model/ccnx-bestroute-strategy.cc
@@ -86,6 +86,7 @@
       if (outgoing != pitEntry.m_outgoing.end () &&
           outgoing->m_retxCount >= pitEntry.m_maxRetxCount)
         {
+          NS_LOG_ERROR (outgoing->m_retxCount << " >= " << pitEntry.m_maxRetxCount);
           continue; // already forwarded before during this retransmission cycle
         }
 
diff --git a/model/ccnx-face.cc b/model/ccnx-face.cc
index 3e39384..18b2015 100644
--- a/model/ccnx-face.cc
+++ b/model/ccnx-face.cc
@@ -112,7 +112,7 @@
   
   if (m_bucketMax > 0)
     {
-      //NS_LOG_DEBUG ("Limits enabled: " << m_bucketMax << ", current: " << m_bucket);
+      NS_LOG_DEBUG ("Limits enabled: " << m_bucketMax << ", current: " << m_bucket);
       if (m_bucket+1.0 > m_bucketMax)
         {
           //NS_LOG_DEBUG ("Returning false");
diff --git a/model/ccnx-forwarding-strategy.cc b/model/ccnx-forwarding-strategy.cc
index d09d916..fbd4613 100644
--- a/model/ccnx-forwarding-strategy.cc
+++ b/model/ccnx-forwarding-strategy.cc
@@ -78,7 +78,7 @@
                                                    Ptr<CcnxInterestHeader> &header,
                                                    const Ptr<const Packet> &packet)
 {
-  // NS_LOG_FUNCTION (this);
+  NS_LOG_FUNCTION (this);
 
   int propagatedCount = 0;
   
@@ -97,6 +97,7 @@
       if (outgoing != pitEntry.m_outgoing.end () &&
           outgoing->m_retxCount >= pitEntry.m_maxRetxCount)
         {
+          NS_LOG_DEBUG ("retxCount: " << outgoing->m_retxCount << ", maxRetxCount: " << pitEntry.m_maxRetxCount);
           continue;
         }
       
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index 4e3e460..5b55906 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -76,7 +76,7 @@
     
     .AddAttribute ("BucketLeakInterval",
                    "Interval to leak buckets",
-                   StringValue ("10ms"),
+                   StringValue ("100ms"),
                    MakeTimeAccessor (&CcnxL3Protocol::GetBucketLeakInterval,
                                      &CcnxL3Protocol::SetBucketLeakInterval),
                    MakeTimeChecker ())
@@ -398,9 +398,11 @@
   // Lookup of Pit (and associated Fib) entry for this Interest 
   tuple<const CcnxPitEntry&,bool,bool> ret = m_pit->Lookup (*header);
   CcnxPitEntry const& pitEntry = ret.get<0> ();
-  // bool isNew = ret.get<1> ();
+  bool isNew = ret.get<1> ();
   bool isDuplicated = ret.get<2> ();
 
+  NS_LOG_DEBUG ("isNew: " << isNew << ", isDup: " << isDuplicated);
+  
   if (isDuplicated) 
     {
       m_dropInterests (header, DUPLICATED, incomingFace);
@@ -463,6 +465,8 @@
                      ll::var(inFace) = ll::bind (&CcnxPitEntry::AddIncoming, ll::_1, incomingFace));
     }
 
+  NS_LOG_DEBUG ("IsRetx: " << isRetransmitted);
+
   // update PIT entry lifetime
   m_pit->modify (m_pit->iterator_to (pitEntry),
                  ll::bind (&CcnxPitEntry::UpdateLifetime, ll::_1,
@@ -516,6 +520,7 @@
   // ForwardingStrategy failed to find it. 
   if (!propagated)
     {
+      NS_LOG_DEBUG ("Not propagated");
       m_dropInterests (header, NO_FACES, incomingFace);
       GiveUpInterest (pitEntry, header);
     }
@@ -620,6 +625,10 @@
   m_pit->modify (m_pit->iterator_to (pitEntry),
                  ll::bind (&CcnxPitEntry::ClearIncoming, ll::_1));
 
+  // Remove also outgoing
+  m_pit->modify (m_pit->iterator_to (pitEntry),
+                 ll::bind (&CcnxPitEntry::ClearOutgoing, ll::_1));
+  
   // Set pruning timout on PIT entry (instead of deleting the record)
   m_pit->modify (m_pit->iterator_to (pitEntry),
                  ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
diff --git a/model/ccnx-pit-entry.cc b/model/ccnx-pit-entry.cc
index 76c7997..0cc6509 100644
--- a/model/ccnx-pit-entry.cc
+++ b/model/ccnx-pit-entry.cc
@@ -140,6 +140,7 @@
 void
 CcnxPitEntry::IncreaseAllowedRetxCount ()
 {
+  NS_LOG_ERROR (this);
   m_maxRetxCount++;
 }
 
diff --git a/model/ccnx-pit-entry.h b/model/ccnx-pit-entry.h
index c07eeda..12ffa91 100644
--- a/model/ccnx-pit-entry.h
+++ b/model/ccnx-pit-entry.h
@@ -195,6 +195,13 @@
   AddOutgoing (Ptr<CcnxFace> face);
 
   /**
+   * @brief Clear all incoming faces either after all of them were satisfied or NACKed
+   */
+  void
+  ClearOutgoing ()
+  { m_outgoing.clear (); }  
+  
+  /**
    * @brief Remove all references to face.
    * 
    * This method should be called before face is completely removed from the stack.