Merge remote-tracking branch 'git.irl/ilya'
diff --git a/apps/ccnx-consumer-cbr.cc b/apps/ccnx-consumer-cbr.cc
new file mode 100644
index 0000000..5a2a759
--- /dev/null
+++ b/apps/ccnx-consumer-cbr.cc
@@ -0,0 +1,126 @@
+/* -*-  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-consumer-cbr.h"
+#include "ns3/ptr.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/double.h"
+
+#include "ns3/ccnx.h"
+#include "../model/ccnx-local-face.h"
+#include "ns3/ccnx-interest-header.h"
+#include "ns3/ccnx-content-object-header.h"
+
+NS_LOG_COMPONENT_DEFINE ("CcnxConsumerCbr");
+
+namespace ns3
+{    
+    
+NS_OBJECT_ENSURE_REGISTERED (CcnxConsumerCbr);
+    
+TypeId
+CcnxConsumerCbr::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::CcnxConsumerCbr")
+    .SetParent<CcnxConsumer> ()
+    .AddConstructor<CcnxConsumerCbr> ()
+
+    .AddAttribute ("MeanRate", "Mean data packet rate (relies on the PayloadSize parameter)",
+                   StringValue ("100Kbps"),
+                   MakeDataRateAccessor (&CcnxConsumerCbr::GetDesiredRate, &CcnxConsumerCbr::SetDesiredRate),
+                   MakeDataRateChecker ())
+    ;
+
+  return tid;
+}
+    
+CcnxConsumerCbr::CcnxConsumerCbr ()
+  : m_desiredRate ("100Kbps")
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  UpdateMean ();
+}
+
+
+void
+CcnxConsumerCbr::UpdateMean ()
+{
+  double mean = 8.0 * m_payloadSize / m_desiredRate.GetBitRate ();
+  m_randExp = ExponentialVariable (mean, 100 * mean); // set upper limit to inter-arrival time
+}
+
+void
+CcnxConsumerCbr::SetPayloadSize (uint32_t payload)
+{
+  CcnxConsumer::SetPayloadSize (payload);
+  UpdateMean ();
+}
+
+void
+CcnxConsumerCbr::SetDesiredRate (DataRate rate)
+{
+  m_desiredRate = rate;
+  UpdateMean ();
+}
+
+DataRate
+CcnxConsumerCbr::GetDesiredRate () const
+{
+  return m_desiredRate;
+}
+
+
+void
+CcnxConsumerCbr::ScheduleNextPacket ()
+{
+  // double mean = 8.0 * m_payloadSize / m_desiredRate.GetBitRate ();
+
+  if (!m_sendEvent.IsRunning ())
+    m_sendEvent = Simulator::Schedule (
+                                       Seconds(m_randExp.GetValue ()),
+                                       // Seconds(mean),
+                                       &CcnxConsumer::SendPacket, this);
+}
+
+///////////////////////////////////////////////////
+//          Process incoming packets             //
+///////////////////////////////////////////////////
+
+// void
+// CcnxConsumer::OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
+//                                const Ptr<const Packet> &payload)
+// {
+//   CcnxConsumer::OnContentObject (contentObject, payload); // tracing inside
+// }
+
+// void
+// CcnxConsumer::OnNack (const Ptr<const CcnxInterestHeader> &interest)
+// {
+//   CcnxConsumer::OnNack (interest); // tracing inside
+// }
+
+} // namespace ns3
diff --git a/apps/ccnx-consumer-cbr.h b/apps/ccnx-consumer-cbr.h
new file mode 100644
index 0000000..59a06d7
--- /dev/null
+++ b/apps/ccnx-consumer-cbr.h
@@ -0,0 +1,83 @@
+/* -*-  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>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef CCNX_CONSUMER_CBR_H
+#define CCNX_CONSUMER_CBR_H
+
+#include "ccnx-consumer.h"
+
+namespace ns3 
+{
+
+/**
+ * @ingroup ccnx
+ * \brief CCNx application for sending out Interest packets at a "constant" rate (Poisson process)
+ */
+class CcnxConsumerCbr: public CcnxConsumer
+{
+public: 
+  static TypeId GetTypeId ();
+        
+  /**
+   * \brief Default constructor 
+   * Sets up randomizer function and packet sequence number
+   */
+  CcnxConsumerCbr ();
+
+  // From CcnxApp
+  // virtual void
+  // OnInterest (const Ptr<const CcnxInterestHeader> &interest);
+
+  // virtual void
+  // OnNack (const Ptr<const CcnxInterestHeader> &interest);
+
+  // virtual void
+  // OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
+  //                  const Ptr<const Packet> &payload);
+
+protected:
+  /**
+   * \brief Constructs the Interest packet and sends it using a callback to the underlying CCNx protocol
+   */
+  virtual void
+  ScheduleNextPacket ();
+  
+private:
+  void
+  UpdateMean ();
+
+  virtual void
+  SetPayloadSize (uint32_t payload);
+
+  void
+  SetDesiredRate (DataRate rate);
+
+  DataRate
+  GetDesiredRate () const;
+  
+protected:
+  ExponentialVariable m_randExp; // packet inter-arrival time generation (Poisson process)
+  DataRate            m_desiredRate;    // Desired data packet rate
+};
+
+} // namespace ns3
+
+#endif
diff --git a/apps/ccnx-consumer-window.cc b/apps/ccnx-consumer-window.cc
new file mode 100644
index 0000000..77f258c
--- /dev/null
+++ b/apps/ccnx-consumer-window.cc
@@ -0,0 +1,132 @@
+/* -*-  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: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "ccnx-consumer-window.h"
+#include "ns3/ptr.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/packet.h"
+#include "ns3/callback.h"
+#include "ns3/string.h"
+#include "ns3/uinteger.h"
+#include "ns3/double.h"
+
+NS_LOG_COMPONENT_DEFINE ("CcnxConsumerWindow");
+
+namespace ns3
+{    
+    
+NS_OBJECT_ENSURE_REGISTERED (CcnxConsumerWindow);
+    
+TypeId
+CcnxConsumerWindow::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::CcnxConsumerWindow")
+    .SetParent<CcnxConsumer> ()
+    .AddConstructor<CcnxConsumerWindow> ()
+
+    .AddAttribute ("Window", "Initial size of the window",
+                   StringValue ("1"),
+                   MakeUintegerAccessor (&CcnxConsumerWindow::GetWindow, &CcnxConsumerWindow::SetWindow),
+                   MakeUintegerChecker<uint32_t> ())
+
+    .AddTraceSource ("WindowTrace",
+                     "Window that controls how many outstanding interests are allowed",
+                     MakeTraceSourceAccessor (&CcnxConsumerWindow::m_window))
+    .AddTraceSource ("InFlight",
+                     "Current number of outstanding interests",
+                     MakeTraceSourceAccessor (&CcnxConsumerWindow::m_window))
+    ;
+
+  return tid;
+}
+
+CcnxConsumerWindow::CcnxConsumerWindow ()
+  : m_inFlight (0)
+{
+}
+
+void
+CcnxConsumerWindow::SetWindow (uint32_t window)
+{
+  m_window = window;
+}
+
+uint32_t
+CcnxConsumerWindow::GetWindow () const
+{
+  return m_window;
+}
+
+void
+CcnxConsumerWindow::ScheduleNextPacket ()
+{
+  if (m_window == static_cast<uint32_t> (0) || m_inFlight >= m_window)
+    {
+      if (!m_sendEvent.IsRunning ())
+        m_sendEvent = Simulator::Schedule (Seconds (m_rtt->RetransmitTimeout ().ToDouble (Time::S) * 0.1), &CcnxConsumer::SendPacket, this);
+      return;
+    }
+  
+  // std::cout << "Window: " << m_window << ", InFlight: " << m_inFlight << "\n";
+  if (!m_sendEvent.IsRunning ())
+    {
+      m_inFlight++;
+      m_sendEvent = Simulator::ScheduleNow (&CcnxConsumer::SendPacket, this);
+    }
+}
+
+///////////////////////////////////////////////////
+//          Process incoming packets             //
+///////////////////////////////////////////////////
+
+void
+CcnxConsumerWindow::OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
+                               const Ptr<const Packet> &payload)
+{
+  CcnxConsumer::OnContentObject (contentObject, payload);
+
+  m_window = m_window + 1;
+
+  if (m_inFlight > static_cast<uint32_t> (0)) m_inFlight--;
+  ScheduleNextPacket ();
+}
+
+void
+CcnxConsumerWindow::OnNack (const Ptr<const CcnxInterestHeader> &interest)
+{
+  CcnxConsumer::OnNack (interest);
+  if (m_inFlight > static_cast<uint32_t> (0)) m_inFlight--;
+
+  if (m_window > static_cast<uint32_t> (0))
+    {
+      // m_window = 0.5 * m_window;//m_window - 1;
+      m_window = m_window - 1;
+    }
+}
+
+void
+CcnxConsumerWindow::OnTimeout (uint32_t sequenceNumber)
+{
+  if (m_inFlight > static_cast<uint32_t> (0)) m_inFlight--;
+  CcnxConsumer::OnTimeout (sequenceNumber);
+}
+
+} // namespace ns3
diff --git a/apps/ccnx-consumer-window.h b/apps/ccnx-consumer-window.h
new file mode 100644
index 0000000..c3b0ddf
--- /dev/null
+++ b/apps/ccnx-consumer-window.h
@@ -0,0 +1,80 @@
+/* -*-  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>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef CCNX_CONSUMER_WINDOW_H
+#define CCNX_CONSUMER_WINDOW_H
+
+#include "ccnx-consumer.h"
+#include "ns3/traced-value.h"
+
+namespace ns3 
+{
+
+/**
+ * @ingroup ccnx
+ * \brief CCNx application for sending out Interest packets (window-based)
+ */
+class CcnxConsumerWindow: public CcnxConsumer
+{
+public: 
+  static TypeId GetTypeId ();
+        
+  /**
+   * \brief Default constructor 
+   */
+  CcnxConsumerWindow ();
+
+  // From CcnxApp
+  // virtual void
+  // OnInterest (const Ptr<const CcnxInterestHeader> &interest);
+
+  virtual void
+  OnNack (const Ptr<const CcnxInterestHeader> &interest);
+
+  virtual void
+  OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
+                   const Ptr<const Packet> &payload);
+
+  virtual void
+  OnTimeout (uint32_t sequenceNumber);
+ 
+protected:
+  /**
+   * \brief Constructs the Interest packet and sends it using a callback to the underlying CCNx protocol
+   */
+  virtual void
+  ScheduleNextPacket ();
+  
+private:
+  virtual void
+  SetWindow (uint32_t window);
+
+  uint32_t
+  GetWindow () const;
+  
+protected:
+  TracedValue<uint32_t> m_window;
+  TracedValue<uint32_t> m_inFlight;
+};
+
+} // namespace ns3
+
+#endif
diff --git a/apps/ccnx-consumer.cc b/apps/ccnx-consumer.cc
index ae56040..b5984e7 100644
--- a/apps/ccnx-consumer.cc
+++ b/apps/ccnx-consumer.cc
@@ -53,27 +53,19 @@
 {
   static TypeId tid = TypeId ("ns3::CcnxConsumer")
     .SetParent<CcnxApp> ()
-    .AddConstructor<CcnxConsumer> ()
     .AddAttribute ("StartSeq", "Initial sequence number",
                    IntegerValue (0),
                    MakeIntegerAccessor(&CcnxConsumer::m_seq),
                    MakeIntegerChecker<int32_t>())
 
-    .AddAttribute ("Size", "Amount of data in megabytes to request (relies on PayloadSize parameter)",
-                   DoubleValue (-1), // don't impose limit by default
-                   MakeDoubleAccessor (&CcnxConsumer::GetMaxSize, &CcnxConsumer::SetMaxSize),
-                   MakeDoubleChecker<double> ())
-
-    ///////
     .AddAttribute ("PayloadSize", "Average size of content object size (to calculate interest generation rate)",
                    UintegerValue (1040),
                    MakeUintegerAccessor (&CcnxConsumer::GetPayloadSize, &CcnxConsumer::SetPayloadSize),
                    MakeUintegerChecker<uint32_t>())
-    .AddAttribute ("MeanRate", "Mean data packet rate (relies on the PayloadSize parameter)",
-                   StringValue ("100Kbps"),
-                   MakeDataRateAccessor (&CcnxConsumer::GetDesiredRate, &CcnxConsumer::SetDesiredRate),
-                   MakeDataRateChecker ())
-    ///////
+    .AddAttribute ("Size", "Amount of data in megabytes to request (relies on PayloadSize parameter)",
+                   DoubleValue (-1), // don't impose limit by default
+                   MakeDoubleAccessor (&CcnxConsumer::GetMaxSize, &CcnxConsumer::SetMaxSize),
+                   MakeDoubleChecker<double> ())
 
     .AddAttribute ("Prefix","CcnxName of the Interest",
                    StringValue ("/"),
@@ -100,11 +92,6 @@
                    MakeCcnxNameComponentsAccessor (&CcnxConsumer::m_exclude),
                    MakeCcnxNameComponentsChecker ())
 
-    .AddAttribute ("RTO",
-                   "Initial retransmission timeout",
-                   StringValue ("1s"),
-                   MakeTimeAccessor (&CcnxConsumer::m_rto),
-                   MakeTimeChecker ())
     .AddAttribute ("RetxTimer",
                    "Timeout defining how frequent retransmission timeouts should be checked",
                    StringValue ("1s"),
@@ -120,13 +107,12 @@
     
 CcnxConsumer::CcnxConsumer ()
   : m_rand (0, std::numeric_limits<uint32_t>::max ())
-  , m_desiredRate ("10Kbps")
   , m_payloadSize (1040)
   , m_seq (0)
 {
   NS_LOG_FUNCTION_NOARGS ();
-
-  UpdateMean (); // not necessary (will be called by ns3 object system anyways), but doesn't hurt
+  
+  m_rtt = CreateObject<RttMeanDeviation> (); 
 }
 
 void
@@ -154,43 +140,25 @@
 
   boost::mutex::scoped_lock (m_seqTimeoutsGuard);
 
+  Time rto = m_rtt->RetransmitTimeout ();
+  
   while (!m_seqTimeouts.empty ())
     {
       SeqTimeoutsContainer::index<i_timestamp>::type::iterator entry =
         m_seqTimeouts.get<i_timestamp> ().begin ();
-      if (entry->time + m_rto <= now) // timeout expired?
+      if (entry->time + rto <= now) // timeout expired?
         {
-          m_retxSeqs.insert (entry->seq);
-          m_seqTimeouts.get<i_timestamp> ().modify (entry,
-                                                    ll::bind(&SeqTimeout::time, ll::_1) = now);
+          m_seqTimeouts.get<i_timestamp> ().erase (entry);
+          OnTimeout (entry->seq);
         }
       else
         break; // nothing else to do. All later packets need not be retransmitted
     }
 
-  if (m_retxSeqs.size () > 0)
-    {
-      ScheduleNextPacket ();
-    }
-  
   m_retxEvent = Simulator::Schedule (m_retxTimer,
                                      &CcnxConsumer::CheckRetxTimeout, this); 
 }
 
-void
-CcnxConsumer::UpdateMean ()
-{
-  double mean = 8.0 * m_payloadSize / m_desiredRate.GetBitRate ();
-  m_randExp = ExponentialVariable (mean, 10000 * mean); // set upper limit to inter-arrival time
-}
-
-void
-CcnxConsumer::SetPayloadSize (uint32_t payload)
-{
-  m_payloadSize = payload;
-  UpdateMean ();
-}
-
 uint32_t
 CcnxConsumer::GetPayloadSize () const
 {
@@ -198,16 +166,9 @@
 }
 
 void
-CcnxConsumer::SetDesiredRate (DataRate rate)
+CcnxConsumer::SetPayloadSize (uint32_t payload)
 {
-  m_desiredRate = rate;
-  UpdateMean ();
-}
-
-DataRate
-CcnxConsumer::GetDesiredRate () const
-{
-  return m_desiredRate;
+  m_payloadSize = payload;
 }
 
 double
@@ -232,16 +193,6 @@
   NS_LOG_DEBUG ("MaxSeqNo: " << m_seqMax);
 }
 
-
-void
-CcnxConsumer::ScheduleNextPacket ()
-{
-  if (!m_sendEvent.IsRunning ())
-    m_sendEvent = Simulator::Schedule (
-                                       Seconds(m_randExp.GetValue ()),
-                                       &CcnxConsumer::SendPacket, this);
-}
-
 // Application Methods
 void 
 CcnxConsumer::StartApplication () // Called at time specified by Start
@@ -279,6 +230,12 @@
   
   if (m_retxSeqs.size () != 0)
     {
+      // for (RetxSeqsContainer::const_iterator i=m_retxSeqs.begin (); i!=m_retxSeqs.end (); i++)
+      //   {
+      //     std::cout << *i << " ";
+      //   }
+      // std::cout << "\n";
+      
       seq = *m_retxSeqs.begin ();
       NS_LOG_INFO ("Before: " << m_retxSeqs.size ());
       m_retxSeqs.erase (m_retxSeqs.begin ());
@@ -296,6 +253,8 @@
       
       seq = m_seq++;
     }
+
+  // std::cout << Simulator::Now ().ToDouble (Time::S) << "s -> " << seq << "\n";
   
   //
   Ptr<CcnxNameComponents> nameWithSequence = Create<CcnxNameComponents> (m_interestName);
@@ -324,15 +283,10 @@
 
   NS_LOG_DEBUG ("Trying to add " << seq << " with " << Simulator::Now () << ". already " << m_seqTimeouts.size () << " items");  
   
-  std::pair<SeqTimeoutsContainer::iterator, bool>
-    res = m_seqTimeouts.insert (SeqTimeout (seq, Simulator::Now ()));
-  
-  if (!res.second)
-    m_seqTimeouts.modify (res.first,
-                          ll::bind(&SeqTimeout::time, ll::_1) = Simulator::Now ());
-  
+  m_seqTimeouts.insert (SeqTimeout (seq, Simulator::Now ()));
   m_transmittedInterests (&interestHeader, this, m_face);
 
+  m_rtt->SentSeq (SequenceNumber32 (seq), 1);
   ScheduleNextPacket ();
 }
 
@@ -368,6 +322,8 @@
 
   m_seqTimeouts.erase (seq);
   m_retxSeqs.erase (seq);
+
+  m_rtt->AckSeq (SequenceNumber32 (seq));
 }
 
 void
@@ -385,6 +341,7 @@
   // NS_LOG_INFO ("Received NACK: " << boost::cref(*interest));
   uint32_t seq = boost::lexical_cast<uint32_t> (interest->GetName ().GetComponents ().back ());
   NS_LOG_INFO ("< NACK for " << seq);
+  // std::cout << Simulator::Now ().ToDouble (Time::S) << "s -> " << "NACK for " << seq << "\n"; 
 
   // put in the queue of interests to be retransmitted
   NS_LOG_INFO ("Before: " << m_retxSeqs.size ());
@@ -394,4 +351,13 @@
   ScheduleNextPacket ();
 }
 
+void
+CcnxConsumer::OnTimeout (uint32_t sequenceNumber)
+{
+  // std::cout << "TO: " << sequenceNumber << "\n";
+  // m_retxSeqs.insert (sequenceNumber);
+  // std::cout << "Current RTO: " << m_rtt->RetransmitTimeout ().ToDouble (Time::S) << "s\n";
+  ScheduleNextPacket (); 
+}
+
 } // namespace ns3
diff --git a/apps/ccnx-consumer.h b/apps/ccnx-consumer.h
index 9b28a2c..4bffbaf 100644
--- a/apps/ccnx-consumer.h
+++ b/apps/ccnx-consumer.h
@@ -27,6 +27,7 @@
 #include "ns3/ccnx-name-components.h"
 #include "ns3/nstime.h"
 #include "ns3/data-rate.h"
+#include "ns3/rtt-estimator.h"
 
 #include <set>
 
@@ -66,6 +67,13 @@
   OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
                    const Ptr<const Packet> &payload);
 
+  virtual void
+  OnTimeout (uint32_t sequenceNumber);
+
+  // Simulator::Schedule doesn't work with protected members???
+  void
+  SendPacket ();
+  
 protected:
   // from CcnxApp
   virtual void
@@ -74,31 +82,12 @@
   virtual void
   StopApplication ();
   
-private:
   /**
    * \brief Constructs the Interest packet and sends it using a callback to the underlying CCNx protocol
    */
-  void
-  ScheduleNextPacket ();
-
-  void
-  UpdateMean ();
-
-  void
-  SetPayloadSize (uint32_t payload);
-
-  uint32_t
-  GetPayloadSize () const;
-
-  void
-  SetDesiredRate (DataRate rate);
-
-  DataRate
-  GetDesiredRate () const;
+  virtual void
+  ScheduleNextPacket () = 0;
   
-  void
-  SendPacket ();
-
   /**
    * \brief Checks if the packet need to be retransmitted becuase of retransmission timer expiration
    */
@@ -119,6 +108,12 @@
   Time
   GetRetxTimer () const;
   
+  virtual void
+  SetPayloadSize (uint32_t payload);
+
+  uint32_t
+  GetPayloadSize () const;
+
   double
   GetMaxSize () const;
 
@@ -127,20 +122,15 @@
   
 protected:
   UniformVariable m_rand; // nonce generator
-
-  ExponentialVariable m_randExp; // packet inter-arrival time generation (Poisson process)
-  DataRate            m_desiredRate;    // Desired data packet rate
   uint32_t            m_payloadSize; // expected payload size
-  
+
   uint32_t        m_seq;
   uint32_t        m_seqMax;    // maximum number of sequence number
   EventId         m_sendEvent; // Eventid of pending "send packet" event
   Time            m_retxTimer;
   EventId         m_retxEvent; // Event to check whether or not retransmission should be performed
 
-  Time            m_rto;        ///< \brief Retransmission timeout
-  Time            m_rttVar;     ///< \brief RTT variance
-  Time            m_sRtt;       ///< \brief smoothed RTT
+  Ptr<RttEstimator> m_rtt;
   
   Time               m_offTime;             ///< \brief Time interval between packets
   CcnxNameComponents m_interestName;        ///< \brief CcnxName of the Interest (use CcnxNameComponents)
diff --git a/examples/abilene-topology-backup.txt b/examples/abilene-topology-backup.txt
deleted file mode 100644
index f4f1d43..0000000
--- a/examples/abilene-topology-backup.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-12  30
-1   2   9920000 1   1   100 100
-2   1   9920000 1   1   100 100
-2   5   9920000 1176    1   100 100
-2   6   2480000 587 1   100 100
-2   12  9920000 846 1   100 100
-3   6   9920000 260 1   100 100
-3   9   9920000 700 1   100 100
-4   7   9920000 639 1   100 100
-4   10  9920000 1295 1   100 100
-4   11  9920000 2095    1   100 100
-5   2   9920000 1176    1   100 100
-5   7   9920000 902 1   100 100
-5   8   9920000 1893 1   100 100
-6   2   9920000 587 1   100 100
-6   3   2480000 260 1   100 100
-6   7   9920000 548 1   100 100
-7   4   9920000 639 1   100 100
-7   5   9920000 902 1   100 100
-7   6   9920000 548 1   100 100
-8   5   9920000 1893 1   100 100
-8   10  9920000 366 1   100 100
-9   3   9920000 700 1   100 100
-9   12  9920000 233 1   100 100
-10  4   9920000 1295 1   100 100
-10  8   9920000 366 1   100 100
-10  11  9920000 861 1   100 100
-11  4   9920000 2095 1   100 100
-11  10  9920000 861 1   100 100
-12  2   9920000 846 1   100 100
-12  9   9920000 233 1   100 100
diff --git a/examples/abilene-topology.cc b/examples/abilene-topology.cc
index 48ad6db..ff7f52d 100644
--- a/examples/abilene-topology.cc
+++ b/examples/abilene-topology.cc
@@ -117,7 +117,7 @@
   ccnxHelper.InstallAll ();
     
   NS_LOG_INFO ("Installing Applications");
-  CcnxAppHelper consumerHelper ("ns3::CcnxConsumer");
+  CcnxAppHelper consumerHelper ("ns3::CcnxConsumerCbr");
   consumerHelper.SetPrefix ("/Data");
   consumerHelper.SetAttribute ("MeanRate", StringValue ("1Mbps"));
   ApplicationContainer consumers = consumerHelper.Install (Names::Find<Node> ("/abilene", "SNVAng"));
@@ -146,7 +146,7 @@
     }
 
   CcnxTraceHelper traceHelper;
-  traceHelper.EnableAggregateAppAll ("ns3::CcnxConsumer");
+  traceHelper.EnableAggregateAppAll ("ns3::CcnxConsumerCbr");
   traceHelper.EnableAggregateAppAll ("ns3::CcnxProducer");
   traceHelper.EnableAggregateL3All ();
   traceHelper.SetL3TraceFile ("trace-l3.log");
diff --git a/examples/annotated-topology-read-example.cc b/examples/annotated-topology-read-example.cc
index 450d8d1..d000d57 100644
--- a/examples/annotated-topology-read-example.cc
+++ b/examples/annotated-topology-read-example.cc
@@ -93,7 +93,7 @@
   Ptr<CcnxFaceContainer> cf = ccnx.Install (nodes);
      
   NS_LOG_INFO ("Installing Applications");
-  CcnxAppHelper helper ("ns3::CcnxConsumer");
+  CcnxAppHelper helper ("ns3::CcnxConsumerCbr");
   helper.SetPrefix ("/3");
   ApplicationContainer app = helper.Install ("1");
   app.Start (Seconds (1.0));
diff --git a/examples/blackhole-abilene.cc b/examples/blackhole-abilene.cc
deleted file mode 100644
index 8e71033..0000000
--- a/examples/blackhole-abilene.cc
+++ /dev/null
@@ -1 +0,0 @@
-//we don't need it?
diff --git a/examples/ccnx-grid.cc b/examples/ccnx-grid.cc
index a4255be..15898aa 100644
--- a/examples/ccnx-grid.cc
+++ b/examples/ccnx-grid.cc
@@ -115,7 +115,7 @@
   std::ostringstream prefix;
   prefix << "/" << producer->GetId ();
   
-  CcnxAppHelper consumerHelper ("ns3::CcnxConsumer");
+  CcnxAppHelper consumerHelper ("ns3::CcnxConsumerCbr");
   consumerHelper.SetPrefix (prefix.str ());
   consumerHelper.SetAttribute ("MeanRate", StringValue ("1Mbps"));
   ApplicationContainer consumers = consumerHelper.Install (consumerNodes);
diff --git a/examples/ccnx-test.cc b/examples/ccnx-test.cc
deleted file mode 100644
index cae2815..0000000
--- a/examples/ccnx-test.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-
-#include "ns3/core-module.h"
-#include "ns3/network-module.h"
-#include "ns3/point-to-point-module.h"
-#include "ns3/NDNabstraction-module.h"
-
-using namespace ns3;
-
-NS_LOG_COMPONENT_DEFINE ("CcnxTest");
-
-int 
-main (int argc, char *argv[])
-{
-  // 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 ("1") ("2");
-  // NodeContainer n2 = NodeContainer ("2") ("3");
-  
-  NS_LOG_INFO ("Create channels.");
-  PointToPointHelper p2p;
-  p2p.Install ("1", "2");
-  p2p.Install ("2", "3");
-
-  NS_LOG_INFO ("Installing NDN stack");
-  CcnxStackHelper ccnx;
-  Ptr<CcnxFaceContainer> cf = ccnx.Install (c);
-
-  CcnxAppHelper helper ("ns3::CcnxConsumer");
-  helper.SetPrefix ("/3");
-  ApplicationContainer app = helper.Install ("1");
-  app.Start (Seconds (1.0));
-  app.Stop (Seconds (10.05));
-
-  CcnxAppHelper helper2 ("ns3::CcnxProducer");
-  helper2.SetPrefix ("/3");
-  helper2.SetAttribute ("PayloadSize", StringValue("1024"));
-  ApplicationContainer app2 = helper2.Install("3");
-  
-  app2.Start(Seconds(0.0));
-  app2.Stop(Seconds(15.0));
-  
-  /**
-   * \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.");
-  
-  // std::string sendsizeattr = "SendSize";
-  // //flow2 7-->2
-  // BulkSendHelper bulksend0 ("ns3::CcnxLocalFaceFactory", InetSocketAddress (i23.GetAddress (0), port));
-  // //bulksend0.SetAttribute(sendsizeattr, AttributeValue(ConstantVariable(2560)));
-  // bulksend0.SetAttribute("MaxBytes", UintegerValue(2560));
-  // ApplicationContainer apps = bulksend0.Install(c.Get(6));
-  // apps.Start(Seconds (1.0));
-  // apps.Stop(Seconds (10.0));
-
-  // AsciiTraceHelper ascii;
-  // p2p.EnableAsciiAll (ascii.CreateFileStream ("ccnx-test.tr"));
-  // p2p.EnablePcapAll ("ccnx-test");
-  
-  Simulator::Stop (Seconds (20));
-  
-  NS_LOG_INFO ("Run Simulation.");
-  Simulator::Run ();
-  Simulator::Destroy ();
-  NS_LOG_INFO ("Done.");
-  
-  return 0;
-}
diff --git a/examples/congestion-pop.cc b/examples/congestion-pop.cc
index 51a5fa0..fcfcc99 100644
--- a/examples/congestion-pop.cc
+++ b/examples/congestion-pop.cc
@@ -28,6 +28,7 @@
 #include "ns3/random-variable.h"
 #include "ns3/internet-module.h"
 #include "ns3/applications-module.h"
+#include "ns3/config-store.h"
 
 #include <iostream>
 #include <sstream>
@@ -45,108 +46,133 @@
 
 NS_LOG_COMPONENT_DEFINE ("Scenario");
 
-void PrintTime ()
-{
-  cout << "Progress: " << Simulator::Now ().ToDouble (Time::S) << "s" << endl;
+// void PrintTime ()
+// {
+//   cout << "Progress: " << Simulator::Now ().ToDouble (Time::S) << "s" << endl;
 
-  Simulator::Schedule (Seconds (1.0), PrintTime);
-}
+//   Simulator::Schedule (Seconds (1.0), PrintTime);
+// }
 
 class Experiment
 {
 public:
   Experiment ()
     : m_rand (0,52)
-    , reader ("/sprint")
+    , reader (0)
   { }
-  
+
+  ~Experiment ()
+  {
+    if (reader != 0) delete reader;
+  }
+    
   void
-  ConfigureCcnxTopology ()
+  ConfigureTopology ()
   {
     Names::Clear ();
+    cout << "Configure Topology\n";
+    if (reader != 0) delete reader;
+    reader = new RocketfuelWeightsReader ("/sprint");
     
     string weights   ("./src/NDNabstraction/examples/sprint-pops.weights");
     string latencies ("./src/NDNabstraction/examples/sprint-pops.latencies");
     string positions ("./src/NDNabstraction/examples/sprint-pops.positions");
   
-    RocketfuelWeightsReader reader ("/sprint");
-
-    reader.SetFileName (positions);
-    reader.SetFileType (RocketfuelWeightsReader::POSITIONS);
-    reader.Read ();
+    reader->SetFileName (positions);
+    reader->SetFileType (RocketfuelWeightsReader::POSITIONS);
+    reader->Read ();
   
-    reader.SetFileName (weights);
-    reader.SetFileType (RocketfuelWeightsReader::WEIGHTS);    
-    reader.Read ();
+    reader->SetFileName (weights);
+    reader->SetFileType (RocketfuelWeightsReader::WEIGHTS);    
+    reader->Read ();
 
-    reader.SetFileName (latencies);
-    reader.SetFileType (RocketfuelWeightsReader::LATENCIES);    
-    reader.Read ();
+    reader->SetFileName (latencies);
+    reader->SetFileType (RocketfuelWeightsReader::LATENCIES);    
+    reader->Read ();
     
-    reader.Commit ();
-    NS_ASSERT_MSG (reader.LinksSize () != 0, "Problems reading the topology file. Failing.");
-    
-    NS_LOG_INFO("Nodes = " << reader.GetNodes ().GetN());
-    NS_LOG_INFO("Links = " << reader.LinksSize ());
-  
-    // ------------------------------------------------------------
-    // -- Read topology data.
-    // --------------------------------------------
-        
+    reader->Commit ();
+  }
+
+  void InstallCcnxStack ()
+  {
     InternetStackHelper stack;
     Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingOrderedNexthops");
     stack.SetRoutingHelper (ipv4RoutingHelper);
-    stack.Install (reader.GetNodes ());
+    stack.Install (reader->GetNodes ());
 
-    reader.AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
+    reader->AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
     
     // Install CCNx stack
-    NS_LOG_INFO ("Installing CCNx stack");
+    cout << "Installing CCNx stack\n";
     CcnxStackHelper ccnxHelper;
     ccnxHelper.SetForwardingStrategy ("ns3::CcnxBestRouteStrategy");
     ccnxHelper.EnableLimits (true, Seconds(0.1));
     ccnxHelper.SetDefaultRoutes (false);
     ccnxHelper.InstallAll ();
-  }
 
-  void
-  ConfigureRouting ()
-  {
-    CcnxStackHelper ccnxHelper;
     // // Populate FIB based on IPv4 global routing controller
     ccnxHelper.InstallFakeGlobalRoutes ();
     ccnxHelper.InstallRoutesToAll ();
   }
   
-  ApplicationContainer
-  AddCcnxRandomApplications (uint16_t numStreams)
+  void InstallIpStack ()
   {
-    map<uint32_t, set<uint32_t> > streams;
-    ApplicationContainer apps;
+    InternetStackHelper stack;
+    stack.Install (reader->GetNodes ());
+    reader->AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
+
+    Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+  }
+
+  void
+  GenerateRandomPairs (uint16_t numStreams)
+  {
+    m_pairs.clear ();
+    // map<uint32_t, set<uint32_t> > streams;
+    set<uint32_t> usedNodes;
     
     uint16_t createdStreams = 0;
     uint16_t guard = 0;
     while (createdStreams < numStreams && guard < (numeric_limits<uint16_t>::max ()-1))
       {
         guard ++;
-        
+
         uint32_t node1_num = m_rand.GetValue ();
         uint32_t node2_num = m_rand.GetValue ();
 
         if (node1_num == node2_num)
           continue;
 
-        if (streams[node1_num].count (node2_num) > 0) // don't create duplicate streams
-          continue;
-        
-        streams[node1_num].insert (node2_num);
+        if (usedNodes.count (node1_num) > 0 ||
+            usedNodes.count (node2_num) > 0 )
+          {
+            continue; // don't reuse nodes
+          }
+
+        usedNodes.insert (node1_num);
+        usedNodes.insert (node2_num);
+
+        m_pairs.push_back (make_tuple (node1_num, node2_num));
+        createdStreams ++;
+      }
+  }
+  
+  ApplicationContainer
+  AddCcnxApplications ()
+  {
+    ApplicationContainer apps;
+
+    for (list<tuple<uint32_t,uint32_t> >::iterator i = m_pairs.begin (); i != m_pairs.end (); i++)
+      {
+        uint32_t node1_num = i->get<0> ();
+        uint32_t node2_num = i->get<1> ();
 
         Ptr<Node> node1 = Names::Find<Node> ("/sprint", lexical_cast<string> (node1_num));
         Ptr<Node> node2 = Names::Find<Node> ("/sprint", lexical_cast<string> (node2_num));
 
-        CcnxAppHelper consumerHelper ("ns3::CcnxConsumer");
+        CcnxAppHelper consumerHelper ("ns3::CcnxConsumerWindow");
         consumerHelper.SetPrefix ("/" + lexical_cast<string> (node2->GetId ()));
-        consumerHelper.SetAttribute ("MeanRate", StringValue ("2Mbps"));
+        // consumerHelper.SetAttribute ("MeanRate", StringValue ("2Mbps"));
         consumerHelper.SetAttribute ("Size", StringValue ("1.983642578125")); //to make sure max seq # is 2000
 
         CcnxAppHelper producerHelper ("ns3::CcnxProducer");
@@ -157,13 +183,51 @@
 
         apps.Add
           (producerHelper.Install (node2));
-
-        createdStreams ++;
       }
 
     return apps;
   }
 
+  ApplicationContainer
+  AddTcpApplications ()
+  {
+    ApplicationContainer apps;
+
+    uint32_t streamId = 0;
+    const static uint32_t base_port = 10;
+    for (list<tuple<uint32_t,uint32_t> >::iterator i = m_pairs.begin (); i != m_pairs.end (); i++)
+      {
+        uint32_t node1_num = i->get<0> ();
+        uint32_t node2_num = i->get<1> ();
+
+        Ptr<Node> node1 = Names::Find<Node> ("/sprint", lexical_cast<string> (node2_num));
+        Ptr<Node> node2 = Names::Find<Node> ("/sprint", lexical_cast<string> (node1_num));
+
+        Ptr<Ipv4> ipv4 = node1->GetObject<Ipv4> ();
+        // ipv4->GetAddress (0, 0);
+
+        // to make sure we don't reuse the same port numbers for different flows, just make all port numbers unique
+        PacketSinkHelper consumerHelper ("ns3::TcpSocketFactory",
+                                         InetSocketAddress (Ipv4Address::GetAny (), base_port + streamId));
+
+        BulkSendHelper producerHelper ("ns3::TcpSocketFactory",
+                                       InetSocketAddress (ipv4->GetAddress (1, 0).GetLocal (), base_port + streamId));
+        // cout << "SendTo: " <<  ipv4->GetAddress (1, 0).GetLocal () << endl;
+        producerHelper.SetAttribute ("MaxBytes", UintegerValue (2081040)); // equal to 2001 ccnx packets
+        
+        apps.Add
+          (consumerHelper.Install (node1));
+
+        apps.Add
+          (producerHelper.Install (node2));
+
+        streamId++;
+      }
+
+    return apps;
+  }
+
+
   void
   Run (const Time &finishTime)
   {
@@ -176,7 +240,9 @@
   }
 
   UniformVariable m_rand;
-  RocketfuelWeightsReader reader;
+  RocketfuelWeightsReader *reader;
+
+  list<tuple<uint32_t,uint32_t> > m_pairs;
 };
 
 
@@ -186,8 +252,15 @@
   cout << "Begin congestion-pop scenario\n";
   
   Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("1Mbps"));
-  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("20"));
+  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("60"));
+  Config::SetDefault ("ns3::TcpSocket::SegmentSize", StringValue ("1040"));
+  
+  Config::SetDefault ("ns3::BulkSendApplication::SendSize", StringValue ("1040"));
 
+  Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("attributes.xml"));
+  Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save"));
+  Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("Xml"));
+  
   uint32_t maxRuns = 1;
   uint32_t startRun = 0;
   CommandLine cmd;
@@ -195,6 +268,9 @@
   cmd.AddValue ("runs", "Number of runs", maxRuns);
   cmd.Parse (argc, argv);
 
+  // ConfigStore config;
+  // config.ConfigureDefaults ();
+  
   for (uint32_t run = startRun; run < startRun + maxRuns; run++)
     {
       Config::SetGlobal ("RngRun", IntegerValue (run));
@@ -202,27 +278,69 @@
 
       Experiment experiment;
       cout << "Run " << run << endl;
-      
-      experiment.ConfigureCcnxTopology ();
-      ApplicationContainer apps = experiment.AddCcnxRandomApplications (20);
-      experiment.ConfigureRouting ();
-  
       string prefix = "run-" + lexical_cast<string> (run) + "-";
 
+      experiment.GenerateRandomPairs (20);
       ofstream of_nodes ((prefix + "apps.log").c_str ());
-      for (uint32_t i = 0; i < apps.GetN () / 2; i++) 
+      for (list<tuple<uint32_t,uint32_t> >::iterator i = experiment.m_pairs.begin (); i != experiment.m_pairs.end (); i++)
         {
-          of_nodes << "From " << apps.Get (i*2)->GetNode ()->GetId ()
-                   << " to "  << apps.Get (i*2 + 1)->GetNode ()->GetId ();
+          of_nodes << "From " << i->get<0> ()
+                   << " to "  << i->get<1> ();
           of_nodes << "\n";
         }
       of_nodes.close ();
 
-      CcnxTraceHelper traceHelper;
-      traceHelper.EnableRateL3All (prefix + "rate-trace.log");
-      traceHelper.EnableSeqsAppAll ("ns3::CcnxConsumer", prefix + "consumers-seqs.log");
+      cout << "NDN experiment\n";
+      // NDN
+      {
+        experiment.ConfigureTopology ();
+        experiment.InstallCcnxStack ();
+        ApplicationContainer apps = experiment.AddCcnxApplications ();
 
-      experiment.Run (Seconds (200.0));
+        for (uint32_t i = 0; i < apps.GetN () / 2; i++) 
+          {
+            apps.Get (i*2)->SetStartTime (Seconds (1+i));
+            apps.Get (i*2 + 1)->SetStartTime (Seconds (1+i));
+          }
+
+        CcnxTraceHelper traceHelper;
+        // traceHelper.EnableRateL3All (prefix + "rate-trace.log");
+        // traceHelper.EnableSeqsAppAll ("ns3::CcnxConsumerCbr", prefix + "consumers-seqs.log");
+        traceHelper.EnableSeqsAppAll ("ns3::CcnxConsumerWindow", prefix + "consumers-seqs.log");
+        traceHelper.EnableWindowsAll (prefix + "windows.log");
+
+        // config.ConfigureAttributes ();
+        experiment.Run (Seconds (200.0));
+      }
+
+      cout << "TCP experiment\n";
+      // TCP
+      {
+        experiment.ConfigureTopology ();
+        experiment.InstallIpStack ();
+        ApplicationContainer apps = experiment.AddTcpApplications ();
+
+        CcnxTraceHelper traceHelper;
+        traceHelper.EnableIpv4SeqsAppAll (prefix + "tcp-consumers-seqs.log");
+        traceHelper.EnableWindowsTcpAll (prefix + "tcp-windows.log");
+
+        for (uint32_t i = 0; i < apps.GetN () / 2; i++) 
+          {
+            apps.Get (i*2)->SetStartTime (Seconds (1+i));
+
+            apps.Get (i*2 + 1)->SetStartTime (Seconds (1+i));
+
+            // cout << "Node: " << apps.Get (i*2 + 1)->GetNode ()->GetId () << "\n";
+            // care only about BulkSender
+            Simulator::Schedule (Seconds (1+i+0.01),
+                                 &CcnxTraceHelper::TcpConnect, &traceHelper, apps.Get (i*2)->GetNode ());
+
+            Simulator::Schedule (Seconds (1+i+0.01),
+                                 &CcnxTraceHelper::TcpConnect, &traceHelper, apps.Get (i*2 + 1)->GetNode ());
+          }
+
+        experiment.Run (Seconds (200.0));
+      }
     }
 
   // cout << "Finish congestion-pop scenario\n";
diff --git a/examples/congestion-tcp-pop.cc b/examples/congestion-tcp-pop.cc
deleted file mode 100644
index c1ac443..0000000
--- a/examples/congestion-tcp-pop.cc
+++ /dev/null
@@ -1,231 +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 "ns3/core-module.h"
-#include "ns3/network-module.h"
-#include "ns3/point-to-point-module.h"
-#include "ns3/NDNabstraction-module.h"
-#include "ns3/point-to-point-grid.h"
-#include "ns3/ipv4-global-routing-helper.h"
-#include "ns3/random-variable.h"
-#include "ns3/internet-module.h"
-#include "ns3/applications-module.h"
-#include "ns3/config-store.h"
-
-#include <iostream>
-#include <sstream>
-#include <map>
-#include <list>
-#include <set>
-#include "ns3/rocketfuel-topology-reader.h"
-
-#include "../helper/tracers/ipv4-seqs-app-tracer.h"
-
-#include <boost/lexical_cast.hpp>
-#include <boost/foreach.hpp>
-
-using namespace ns3;
-using namespace std;
-using namespace boost;
-
-NS_LOG_COMPONENT_DEFINE ("Scenario");
-
-void PrintTime ()
-{
-  cout << "Progress: " << Simulator::Now ().ToDouble (Time::S) << "s" << endl;
-
-  Simulator::Schedule (Seconds (1.0), PrintTime);
-}
-
-class Experiment
-{
-public:
-  Experiment ()
-    : m_rand (0,52)
-    , reader ("/sprint")
-  { }
-
-  void
-  ConfigureIpv4Topology ()
-  {
-    Names::Clear ();
-    
-    string weights   ("./src/NDNabstraction/examples/sprint-pops.weights");
-    string latencies ("./src/NDNabstraction/examples/sprint-pops.latencies");
-    string positions ("./src/NDNabstraction/examples/sprint-pops.positions");
-  
-    reader.SetFileName (positions);
-    reader.SetFileType (RocketfuelWeightsReader::POSITIONS);
-    reader.Read ();
-  
-    reader.SetFileName (weights);
-    reader.SetFileType (RocketfuelWeightsReader::WEIGHTS);    
-    reader.Read ();
-
-    reader.SetFileName (latencies);
-    reader.SetFileType (RocketfuelWeightsReader::LATENCIES);    
-    reader.Read ();
-    
-    reader.Commit ();
-    NS_ASSERT_MSG (reader.LinksSize () != 0, "Problems reading the topology file. Failing.");
-    
-    NS_LOG_INFO("Nodes = " << reader.GetNodes ().GetN());
-    NS_LOG_INFO("Links = " << reader.LinksSize ());
-
-    InternetStackHelper stack;
-    stack.Install (reader.GetNodes ());
-    reader.AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
-  }
-
-  void
-  ConfigureRouting ()
-  {
-    Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
-
-    // m_rand = UniformVariable (0, reader.GetNodes ().GetN());
-  }
-  
-  ApplicationContainer
-  AddTcpRandomApplications (uint16_t numStreams)
-  {
-    map<uint32_t, set<uint32_t> > streams;
-    ApplicationContainer apps;
-
-    const static uint32_t base_port = 10;
-    uint16_t createdStreams = 0;
-    uint16_t guard = 0;
-    while (createdStreams < numStreams && guard < (numeric_limits<uint16_t>::max ()-1))
-      {
-        guard ++;
-        
-        uint32_t node1_num = m_rand.GetValue ();
-        uint32_t node2_num = m_rand.GetValue ();
-
-        if (node1_num == node2_num)
-          continue;
-
-        if (streams[node1_num].count (node2_num) > 0) // don't create duplicate streams
-          continue;
-        
-        streams[node1_num].insert (node2_num);
-
-        Ptr<Node> node1 = Names::Find<Node> ("/sprint", lexical_cast<string> (node1_num));
-        Ptr<Node> node2 = Names::Find<Node> ("/sprint", lexical_cast<string> (node2_num));
-
-        Ptr<Ipv4> ipv4 = node1->GetObject<Ipv4> ();
-        // ipv4->GetAddress (0, 0);
-
-        // to make sure we don't reuse the same port numbers for different flows, just make all port numbers unique
-        PacketSinkHelper consumerHelper ("ns3::TcpSocketFactory",
-                                         InetSocketAddress (Ipv4Address::GetAny (), base_port + createdStreams));
-
-        BulkSendHelper producerHelper ("ns3::TcpSocketFactory",
-                                       InetSocketAddress (ipv4->GetAddress (1, 0).GetLocal (), base_port + createdStreams));
-        // cout << "SendTo: " <<  ipv4->GetAddress (1, 0).GetLocal () << endl;
-        producerHelper.SetAttribute ("MaxBytes", UintegerValue (2081040)); // equal to 2001 ccnx packets
-        
-        apps.Add
-          (consumerHelper.Install (node1));
-
-        apps.Add
-          (producerHelper.Install (node2));
-
-        createdStreams ++;
-      }
-
-    return apps;
-  }
-
-  void
-  Run (const Time &finishTime)
-  {
-    cout << "Run Simulation.\n";
-    Simulator::Stop (finishTime);
-    // Simulator::Schedule (Seconds (1.0), PrintTime);
-    Simulator::Run ();
-    Simulator::Destroy ();
-    cout << "Done.\n";
-  }
-
-  UniformVariable m_rand;
-  RocketfuelWeightsReader reader;
-};
-
-int 
-main (int argc, char *argv[])
-{
-  cout << "Begin congestion-pop scenario\n";
-  Packet::EnableChecking();
-  Packet::EnablePrinting();
-  
-  Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("1Mbps"));
-  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("20"));
-  Config::SetDefault ("ns3::TcpSocket::SegmentSize", StringValue ("1040"));
-  
-  Config::SetDefault ("ns3::BulkSendApplication::SendSize", StringValue ("1040"));
-
-  // Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("attributes.xml"));
-  // Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save"));
-  // Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("Xml"));
-  
-  uint32_t maxRuns = 1;
-  uint32_t startRun = 0;
-  CommandLine cmd;
-  cmd.AddValue ("start", "Initial run number", startRun);
-  cmd.AddValue ("runs", "Number of runs", maxRuns);
-  cmd.Parse (argc, argv);
-
-  // ConfigStore config;
-  // config.ConfigureDefaults ();
-
-  for (uint32_t run = startRun; run < startRun + maxRuns; run++)
-    {
-      Config::SetGlobal ("RngRun", IntegerValue (run));
-      cout << "seed = " << SeedManager::GetSeed () << ", run = " << SeedManager::GetRun () << endl;
-      
-      Experiment experiment;
-      cout << "Run " << run << endl;
-      
-      experiment.ConfigureIpv4Topology ();
-      ApplicationContainer apps = experiment.AddTcpRandomApplications (20);
-      experiment.ConfigureRouting ();
-
-      string prefix = "run-tcp-" + lexical_cast<string> (run) + "-";      
-
-      ofstream of_nodes ((prefix + "apps.log").c_str ());
-      for (uint32_t i = 0; i < apps.GetN () / 2; i++) 
-        {
-          of_nodes << "From " << apps.Get (i*2)->GetNode ()->GetId ()
-                   << " to "  << apps.Get (i*2 + 1)->GetNode ()->GetId ();
-          of_nodes << "\n";
-        }
-
-      CcnxTraceHelper traceHelper;
-      traceHelper.EnableIpv4SeqsAppAll (prefix + "consumers-seqs.log");
-
-      // config.ConfigureAttributes ();  
-
-      experiment.Run (Seconds (200.0));
-    }
-
-  // cout << "Finish congestion-pop scenario\n";
-  return 0;
-}
diff --git a/examples/link-failure-abilene.cc b/examples/link-failure-abilene.cc
deleted file mode 100644
index 4a94585..0000000
--- a/examples/link-failure-abilene.cc
+++ /dev/null
@@ -1,202 +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 "ns3/core-module.h"
-#include "ns3/network-module.h"
-#include "ns3/point-to-point-module.h"
-#include "ns3/NDNabstraction-module.h"
-#include "ns3/point-to-point-grid.h"
-#include "ns3/ipv4-global-routing-helper.h"
-#include "ns3/random-variable.h"
-
-#include <iostream>
-#include <sstream>
-#include <map>
-#include <list>
-#include <set>
-#include "ns3/rocketfuel-topology-reader.h"
-
-#include <boost/lexical_cast.hpp>
-#include <boost/foreach.hpp>
-
-using namespace ns3;
-using namespace std;
-using namespace boost;
-
-NS_LOG_COMPONENT_DEFINE ("LinkFailureSprint");
-
-void PrintTime ()
-{
-  cout << "Progress: " << Simulator::Now ().ToDouble (Time::S) << "s" << endl;
-
-  Simulator::Schedule (Seconds (1.0), PrintTime);
-}
-
-
-class Experiment
-{
-public:
-  Experiment ()
-  : m_reader ("/abilene", 2.0) { }
-
-  void
-  ConfigureTopology ()
-  {
-    string input ("./src/NDNabstraction/examples/abilene-topology.txt");
-    string strategy ("ns3::CcnxBestRouteStrategy");
-    // string strategy ("ns3::CcnxFloodingStrategy");
-  
-   
-    m_reader.SetFileName (input);
-    
-    NodeContainer nodes = m_reader.Read ();
-    
-    if (m_reader.LinksSize () == 0)
-    {
-      NS_LOG_ERROR ("Problems reading the topology file. Failing.");
-      return;
-    }
-
-    NS_ASSERT_MSG (m_reader.LinksSize () != 0, "Problems reading the topology file. Failing.");    
-    NS_LOG_INFO("Nodes = " << m_reader.GetNodes ().GetN());
-    NS_LOG_INFO("Links = " << m_reader.LinksSize ());
-  
-    // ------------------------------------------------------------
-    // -- Read topology data.
-    // --------------------------------------------
-        
-    InternetStackHelper stack;
-    Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingOrderedNexthops");
-    stack.SetRoutingHelper (ipv4RoutingHelper);
-    stack.Install (m_reader.GetNodes ());
-
-    m_reader.AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
-
-    // Install CCNx stack
-    NS_LOG_INFO ("Installing CCNx stack");
-    CcnxStackHelper ccnxHelper;
-    ccnxHelper.SetForwardingStrategy (strategy);
-    ccnxHelper.EnableLimits (true, Seconds(0.1));
-    ccnxHelper.SetDefaultRoutes (false);
-    ccnxHelper.InstallAll ();
-
-    // // Populate FIB based on IPv4 global routing controller
-    ccnxHelper.InstallFakeGlobalRoutes ();
-    ccnxHelper.InstallRoutesToAll ();
-
-    m_rand = UniformVariable (0, m_reader.GetNodes ().GetN());
-    m_linkRand = UniformVariable(0, m_reader.LinksSize());
-  }
-
-public:  
-  void
-  Run (const Time &finishTime)
-  {
-    cout << "Run Simulation.\n";
-    Simulator::Stop (finishTime);
-    Simulator::Schedule (Seconds (1.0), PrintTime);
-    Simulator::Run ();
-    Simulator::Destroy ();
-    cout << "Done.\n";
-  }
-
-  //We are creating "everybody-to-everybody" usage pattern
-  ApplicationContainer
-  AddApplications()
-  {
-    ApplicationContainer apps;
-    for(uint32_t i =0; i<m_reader.GetNodes().GetN(); i++)
-    {
-      Ptr<Node> node1 = Names::Find<Node> ("/abilene", lexical_cast<string> (i));
-      CcnxAppHelper producerHelper ("ns3::CcnxProducer");
-      producerHelper.SetPrefix ("/" + lexical_cast<string> (i));
-        
-      apps.Add(producerHelper.Install (node1));
-          
-      for(uint32_t j = 0; j<m_reader.GetNodes().GetN();j++)
-      {
-        if(i==j)
-          continue;
-        
-        Ptr<Node> node2 = Names::Find<Node> ("/abilene", lexical_cast<string> (j));
-        
-        CcnxAppHelper consumerHelper ("ns3::CcnxConsumer");
-        consumerHelper.SetPrefix ("/" + lexical_cast<string> (i));
-        consumerHelper.SetAttribute ("MeanRate", StringValue ("1Mbps"));
-        consumerHelper.SetAttribute ("Size", StringValue ("2"));  
-        
-        apps.Add(consumerHelper.Install (node2));
-      }
-    }
-    return apps;
-  }
-  
-  UniformVariable m_rand;
-  UniformVariable m_linkRand;
-  
-private:
-  AnnotatedTopologyReader m_reader;
-};
-
-int 
-main (int argc, char *argv[])
-{
-  cout << "Begin link failure scenario\n";
-  
-  Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("2Mbps"));
-  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("100"));
-
-  Time finishTime = Seconds (20.0);
-
-  CommandLine cmd;
-  cmd.AddValue ("finish", "Finish time", finishTime);
-  cmd.Parse (argc, argv);
-
-  Experiment experiment;
-
-  for (uint32_t i = 0; i < 100; i++)
-    {
-  
-      experiment.ConfigureTopology ();
-      ApplicationContainer apps = experiment.AddApplications ();
-
-      for (uint32_t i = 0; i < apps.GetN () / 2; i++) 
-        {
-          cout << "From " << apps.Get (i*2)->GetNode ()->GetId ()
-               << " to "  << apps.Get (i*2 + 1)->GetNode ()->GetId ();
-          cout << "\n";
-        }
-  
-      CcnxTraceHelper traceHelper;
-      // traceHelper.EnableAggregateAppAll ("ns3::CcnxConsumer");
-      // traceHelper.EnableAggregateAppAll ("ns3::CcnxProducer");
-      // traceHelper.EnableAggregateL3All ();
-      // traceHelper.SetL3TraceFile ("trace-l3.log");
-      // traceHelper.SetAppTraceFile ("trace-app.log");
-      // traceHelper.EnableRateL3All ("rate-trace.log");
-      traceHelper.EnableSeqsAppAll ("ns3::CcnxConsumer", "consumers-seqs.log");
-
-      experiment.Run (finishTime);
-    }
-
-  cout << "Finish link failure scenario\n";
-  return 0;
-}
diff --git a/examples/syntactic-topology-ndnabstraction.cc b/examples/syntactic-topology-ndnabstraction.cc
deleted file mode 100644
index 3fc04a1..0000000
--- a/examples/syntactic-topology-ndnabstraction.cc
+++ /dev/null
@@ -1,226 +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 "ns3/core-module.h"
-#include "ns3/network-module.h"
-#include "ns3/point-to-point-module.h"
-#include "ns3/NDNabstraction-module.h"
-#include <ns3/point-to-point-grid.h>
-#include "ns3/ipv4-global-routing-helper.h"
-
-#include <iostream>
-#include <sstream>
-
-#include "ns3/ccnx.h"
-
-
-using namespace ns3;
-
-NS_LOG_COMPONENT_DEFINE ("SyncTopologyNDNabstraction");
-
-int 
-main (int argc, char *argv[])
-{
-  // Set up some default values for the simulation.  Use the 
-  
-  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
-  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s"));
-  
-  Packet::EnableChecking();
-  Packet::EnablePrinting();
-
-  // Allow the user to override any of the defaults and the above
-  // DefaultValue::Bind ()s at run-time, via command-line arguments
-  CommandLine cmd;
-  cmd.Parse (argc, argv);
-  
-  // Here, we will explicitly create seven nodes. 
-  NS_LOG_INFO ("Create nodes.");
-  NodeContainer c;
-  c.Create (7);
-  Names::Add ("1", c.Get (0));
-  Names::Add ("2", c.Get (1));
-  Names::Add ("3", c.Get (2));
-  Names::Add ("4", c.Get (3));
-  Names::Add ("5", c.Get (4));
-  Names::Add ("6", c.Get (5));
-  Names::Add ("7", c.Get (6));
-    
-    
-  NodeContainer n13 = NodeContainer (c.Get (0), c.Get (2));
-  NodeContainer n23 = NodeContainer (c.Get (1), c.Get (2));
-  NodeContainer n35 = NodeContainer (c.Get (2), c.Get (4));
-  NodeContainer n34 = NodeContainer (c.Get (2), c.Get (3));
-  NodeContainer n45 = NodeContainer (c.Get (3), c.Get (4));
-  NodeContainer n56 = NodeContainer (c.Get (4), c.Get (5));
-  NodeContainer n57 = NodeContainer (c.Get (4), c.Get (6));
-  
-  //Ipv4StaticRoutingHelper staticRouting;
-  
-  //Ipv4ListRoutingHelper list;
-  //list.Add (staticRouting, 1);
-  
-  //Add static routing
-  //InternetStackHelper internet;
-  //internet.SetRoutingHelper (list); // has effect on the next Install ()
-  //internet.Install (c);
-  
-  // We create the channels first without any IP addressing information
-  NS_LOG_INFO ("Create channels.");
-  PointToPointHelper p2p;
-  p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
-  p2p.SetChannelAttribute ("Delay", StringValue ("1ms"));
-  NetDeviceContainer nd13 = p2p.Install (n13);
-  NetDeviceContainer nd23 = p2p.Install (n23);
-  NetDeviceContainer nd56 = p2p.Install (n56);
-  
-  p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
-  p2p.SetChannelAttribute ("Delay", StringValue ("50ms"));
-  NetDeviceContainer nd57 = p2p.Install (n57);
-  
-  p2p.SetDeviceAttribute ("DataRate", StringValue ("1Mbps"));
-  p2p.SetChannelAttribute ("Delay", StringValue ("1ms"));
-  NetDeviceContainer nd34 = p2p.Install (n34);
-  NetDeviceContainer nd45 = p2p.Install (n45);
-  
-  p2p.SetDeviceAttribute ("DataRate", StringValue ("1Mbps"));
-  p2p.SetChannelAttribute ("Delay", StringValue ("50ms"));
-  NetDeviceContainer nd35 = p2p.Install (n35);
-  
-  InternetStackHelper stack;
-  Ipv4GlobalRoutingHelper ipv4RoutingHelper;
-  // Ptr<Ipv4RoutingHelper> ipv4RoutingHelper = stack.GetRoutingHelper ();
-  stack.SetRoutingHelper (ipv4RoutingHelper);
-  stack.Install(c);
-  // // Create router nodes, initialize routing database and set up the routing
-  // // tables in the nodes.
-  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
-    
-  // Later, we add IP addresses.
-  NS_LOG_INFO ("Assign IP Addresses.");
-  Ipv4AddressHelper ipv4;
-  ipv4.SetBase ("192.168.1.0", "255.255.255.0");
-  Ipv4InterfaceContainer i13 = ipv4.Assign (nd13);
-  Ipv4InterfaceContainer i23 = ipv4.Assign (nd23);
-  Ipv4InterfaceContainer i35 = ipv4.Assign (nd35);
-  Ipv4InterfaceContainer i34 = ipv4.Assign (nd34);
-  Ipv4InterfaceContainer i45 = ipv4.Assign (nd45);
-  Ipv4InterfaceContainer i56 = ipv4.Assign (nd56);
-  Ipv4InterfaceContainer i57 = ipv4.Assign (nd57);
-  
-    
-    
-    
-  CcnxStackHelper ccnx;
-  ccnx.SetForwardingStrategy ("ns3::CcnxFloodingStrategy");
-  ccnx.EnableLimits (false);
-  Ptr<CcnxFaceContainer> cf = ccnx.Install (c);
-    
-  NS_LOG_INFO ("Installing Applications");
-  CcnxConsumerHelper helper ("/3");
-  ApplicationContainer app = helper.Install (c.Get(1));
-  app.Start (Seconds (1.0));
-  app.Stop (Seconds (1000.05));
-    
-  /*CcnxConsumerHelper helper2 ("/4");
-    ApplicationContainer app2 = helper2.Install(c.Get(5));
-    app2.Start (Seconds (1.0));
-    app2.Stop (Seconds (1000.05));
-  */
-  CcnxProducerHelper helper3 ("/3",120);
-  ApplicationContainer app3 = helper3.Install(c.Get(6));
-  app3.Start(Seconds(0.0));
-  app3.Stop(Seconds(1500.0));
-  /*
-    CcnxProducerHelper helper4 ("/4",150);
-    ApplicationContainer app4 = helper4.Install(c.Get(0));
-    app4.Start(Seconds(0.0));
-    app4.Stop(Seconds(1500.0));
-  */
-    
-  ccnx.AddRoute("1","/3",0,1);
-  ccnx.AddRoute("3","/3",2,1);
-  ccnx.AddRoute("3","/3",3,1);
-  ccnx.AddRoute("4","/3",1,1);
-  ccnx.AddRoute("5","/3",2,1);
-    
-  /*ccnx.AddRoute ("1", "/3", 0, 1);
-    ccnx.AddRoute ("1", "/3", 1, 1);
-    
-    ccnx.AddRoute ("2", "/3", 1, 1);
-    
-    ccnx.AddRoute ("3", "/3", 1, 1);
-    
-    ccnx.AddRoute ("4", "/3", 2, 1);
-    
-    ccnx.AddRoute ("6", "/3", 2, 1);
-    
-    ccnx.AddRoute ("7", "/3", 1, 1);
-    
-    ccnx.AddRoute ("8", "/3", 1, 1);
-  */
-    
-  // 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.");
-    uint16_t port = 9;   // Discard port (RFC 863)
-  
-    std::string sendsizeattr = "SendSize";
-    //flow2 7-->2
-    BulkSendHelper bulksend0 ("ns3::UdpSocketFactory", InetSocketAddress (i23.GetAddress (0), port));
-    //bulksend0.SetAttribute(sendsizeattr, AttributeValue(ConstantVariable(2560)));
-    bulksend0.SetAttribute("MaxBytes", UintegerValue(2560));
-    ApplicationContainer apps = bulksend0.Install(c.Get(6));
-    apps.Start(Seconds (1.0));
-    apps.Stop(Seconds (10.0));
-  
-    // Create a packet sink to receive these packets
-    PacketSinkHelper sink0 ("ns3::UdpSocketFactory", InetSocketAddress(Ipv4Address::GetAny (), port));
-    apps = sink0.Install(c.Get(1));
-    apps.Start(Seconds(0.0));
-    apps.Stop(Seconds(20.0));
-  
-    //flow1 1-->6
-    BulkSendHelper bulksend ("ns3::UdpSocketFactory", InetSocketAddress (i56.GetAddress (1), port));
-    //bulksend.SetAttribute(sendsizeattr, AttributeValue( ConstantVariable(2560)));
-    bulksend0.SetAttribute("MaxBytes", UintegerValue(2560));
-    apps = bulksend.Install (c.Get (0));
-    apps.Start (Seconds (6.0));
-    apps.Stop (Seconds (20.0));
-  
-    // Create a packet sink to receive these packets
-    PacketSinkHelper sink ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), port));
-    apps = sink.Install (c.Get (5));
-    apps.Start(Seconds(0.0));
-    apps.Stop(Seconds(20.0));
-  
-    AsciiTraceHelper ascii;
-    p2p.EnableAsciiAll (ascii.CreateFileStream ("sync-topology-ndnabstraction.tr"));
-    p2p.EnablePcapAll ("sync-topology-ndnabstraction");*/
-  
-  Simulator::Stop (Seconds (2000));
-  
-  NS_LOG_INFO ("Run Simulation.");
-  Simulator::Run ();
-  Simulator::Destroy ();
-  NS_LOG_INFO ("Done.");
-  
-  return 0;
-}
diff --git a/examples/synthetic-topology.cc b/examples/synthetic-topology.cc
index 971bbe1..250a936 100644
--- a/examples/synthetic-topology.cc
+++ b/examples/synthetic-topology.cc
@@ -89,7 +89,7 @@
   ccnxHelper.InstallAll ();
     
   NS_LOG_INFO ("Installing Applications");
-  CcnxAppHelper consumerHelper ("ns3::CcnxConsumer");
+  CcnxAppHelper consumerHelper ("ns3::CcnxConsumerCbr");
 
   consumerHelper.SetPrefix ("/6");
   consumerHelper.SetAttribute ("MeanRate", StringValue ("2Mbps"));
@@ -142,13 +142,13 @@
   Simulator::Stop (finishTime);
 
   CcnxTraceHelper traceHelper;
-  // traceHelper.EnableAggregateAppAll ("ns3::CcnxConsumer");
+  // traceHelper.EnableAggregateAppAll ("ns3::CcnxConsumerCbr");
   // traceHelper.EnableAggregateAppAll ("ns3::CcnxProducer");
   // traceHelper.EnableAggregateL3All ();
   // traceHelper.SetL3TraceFile ("trace-l3.log");
   // traceHelper.SetAppTraceFile ("trace-app.log");
   // traceHelper.EnableRateL3All ("rate-trace.log");
-  traceHelper.EnableSeqsAppAll ("ns3::CcnxConsumer", "consumers-seqs.log");
+  traceHelper.EnableSeqsAppAll ("ns3::CcnxConsumerCbr", "consumers-seqs.log");
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
diff --git a/helper/ccnx-stack-helper.cc b/helper/ccnx-stack-helper.cc
index ff73cae..62c5f82 100644
--- a/helper/ccnx-stack-helper.cc
+++ b/helper/ccnx-stack-helper.cc
@@ -155,7 +155,10 @@
 }
 
 void
-CcnxStackHelper::EnableLimits (bool enable/* = true*/, Time avgRtt/*=Seconds(0.1)*/, uint32_t avgContentObject/*=1100*/, uint32_t avgInterest/*=40*/)
+CcnxStackHelper::EnableLimits (bool enable/* = true*/,
+                               Time avgRtt/*=Seconds(0.1)*/,
+                               uint32_t avgContentObject/*=1100*/,
+                               uint32_t avgInterest/*=40*/)
 {
   NS_LOG_INFO ("EnableLimits: " << enable);
   m_limitsEnabled = enable;
@@ -237,7 +240,7 @@
           
           NS_LOG_INFO("DataRate for this link is " << dataRate.Get());
 
-          double maxInterestPackets = 1.0  * dataRate.Get ().GetBitRate () / 8.0 / m_avgContentObjectSize;
+          double maxInterestPackets = 1.0  * dataRate.Get ().GetBitRate () / 8.0 / (m_avgContentObjectSize + m_avgInterestSize);
           NS_LOG_INFO ("Max packets per second: " << maxInterestPackets);
           NS_LOG_INFO ("Max burst: " << m_avgRtt.ToDouble (Time::S) * maxInterestPackets);
 
diff --git a/helper/ccnx-trace-helper.cc b/helper/ccnx-trace-helper.cc
index 1742462..a7f8014 100644
--- a/helper/ccnx-trace-helper.cc
+++ b/helper/ccnx-trace-helper.cc
@@ -31,6 +31,7 @@
 #include "ns3/object-vector.h"
 #include "ns3/simulator.h"
 #include "ns3/names.h"
+#include "ns3/tcp-l4-protocol.h"
 
 #include <boost/ref.hpp>
 #include <boost/lexical_cast.hpp>
@@ -40,6 +41,7 @@
 #include "tracers/ccnx-rate-l3-tracer.h"
 #include "tracers/ccnx-seqs-app-tracer.h"
 #include "tracers/ipv4-seqs-app-tracer.h"
+#include "tracers/ccnx-consumer-window-tracer.h"
 
 #include "ns3/ccnx-interest-header.h"
 #include "ns3/ccnx-content-object-header.h"
@@ -57,6 +59,8 @@
   : m_l3RateTrace (0)
   , m_appSeqsTrace (0)
   , m_ipv4AppSeqsTrace (0)
+  , m_windowsTrace (0)
+  , m_windowsTcpTrace (0)
 {
 }
 
@@ -66,6 +70,8 @@
   if (m_l3RateTrace != 0) delete m_l3RateTrace;
   if (m_appSeqsTrace != 0) delete m_appSeqsTrace;
   if (m_ipv4AppSeqsTrace != 0) delete m_ipv4AppSeqsTrace;
+  if (m_windowsTrace != 0) delete m_windowsTrace;
+  if (m_windowsTcpTrace != 0) delete m_windowsTcpTrace;
   
   if (m_apps.size () > 0)
     {
@@ -286,5 +292,72 @@
     }
 }
 
+void
+CcnxTraceHelper::EnableWindowsAll (const std::string &windowTrace)
+{
+  NS_LOG_FUNCTION (this);
+  m_windowsTrace = new ofstream (windowTrace.c_str (), ios::trunc);
+
+  for (NodeList::Iterator node = NodeList::Begin ();
+       node != NodeList::End ();
+       node++)
+    {
+      ObjectVectorValue apps;
+      (*node)->GetAttribute ("ApplicationList", apps);
+
+      NS_LOG_DEBUG ("Node: " << lexical_cast<string> ((*node)->GetId ()));
+      
+      uint32_t appId = 0;
+      for (ObjectVectorValue::Iterator app = apps.Begin ();
+           app != apps.End ();
+           app++, appId++)
+        {
+          if ((*app)->GetInstanceTypeId ().GetName () == "ns3::CcnxConsumerWindow")
+            {
+              Ptr<CcnxConsumerWindowTracer> trace = Create<CcnxConsumerWindowTracer> (boost::ref(*m_windowsTrace),
+                                                                                      *node,
+                                                                                      lexical_cast<string> (appId));
+              m_windows.push_back (trace);
+            }
+        }
+      
+    }
+
+  if (m_windows.size () > 0)
+    {
+      m_windows.front ()->PrintHeader (*m_windowsTrace);
+      *m_windowsTrace << "\n";
+    }
+}
+
+void
+CcnxTraceHelper::TcpConnect (Ptr<Node> node)
+{
+  ObjectVectorValue sockets;
+  node->GetObject<TcpL4Protocol> ()->GetAttribute ("SocketList", sockets);
+  
+  uint32_t sockId = 0;      
+  for (ObjectVectorValue::Iterator socket = sockets.Begin ();
+       socket != sockets.End ();
+       socket++, sockId++)
+    {
+      // std::cout << "Node: " << node->GetId () << ", Socket " << sockId << "\n";
+          
+      Ptr<TcpCongestionWindowTracer> trace = Create<TcpCongestionWindowTracer> (boost::ref(*m_windowsTcpTrace),
+                                                                                node,
+                                                                                lexical_cast<string> (sockId));
+      m_windowsTcp.push_back (trace);
+    }
+}
+
+void
+CcnxTraceHelper::EnableWindowsTcpAll (const std::string &windowTrace)
+{
+  NS_LOG_FUNCTION (this);
+  m_windowsTcpTrace = new ofstream (windowTrace.c_str (), ios::trunc);
+
+  WindowTracer::PrintHeader (*m_windowsTcpTrace);
+  *m_windowsTcpTrace << "\n";
+}
 
 } // namespace ns3
diff --git a/helper/ccnx-trace-helper.h b/helper/ccnx-trace-helper.h
index 4079f9c..cfff107 100644
--- a/helper/ccnx-trace-helper.h
+++ b/helper/ccnx-trace-helper.h
@@ -28,9 +28,11 @@
 
 namespace ns3 {
 
+class Node;
 class CcnxAppTracer;
 class CcnxL3Tracer;
 class Ipv4AppTracer;
+class WindowTracer;
 
 class CcnxTraceHelper
 {
@@ -93,7 +95,21 @@
    */
   void
   EnableIpv4SeqsAppAll (const std::string &appSeqsTrace = "app-seqs.log");
-  
+
+  /**
+   * @brief Enable tracing of window changes in CcnxConsumerWindow
+   */
+  void
+  EnableWindowsAll (const std::string &windowTrace = "windows.log");
+
+  /**
+   * @brief Enable tracing of congestion window changes in TcpNewReno
+   */
+  void
+  EnableWindowsTcpAll (const std::string &windowTrace);
+
+  void TcpConnect (Ptr<Node> node);
+
 private:
   std::string m_appTrace;
   std::list<Ptr<CcnxAppTracer> > m_apps;
@@ -109,6 +125,12 @@
 
   std::list<Ptr<Ipv4AppTracer> > m_ipv4AppSeqs;
   std::ostream *m_ipv4AppSeqsTrace;
+
+  std::list<Ptr<WindowTracer> > m_windows;
+  std::ostream *m_windowsTrace;
+
+  std::list<Ptr<WindowTracer> > m_windowsTcp;
+  std::ostream *m_windowsTcpTrace;
 };
 
 
diff --git a/helper/tracers/ccnx-consumer-window-tracer.cc b/helper/tracers/ccnx-consumer-window-tracer.cc
new file mode 100644
index 0000000..eea664a
--- /dev/null
+++ b/helper/tracers/ccnx-consumer-window-tracer.cc
@@ -0,0 +1,88 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2011 UCLA
+ *
+ * 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:  Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "ccnx-consumer-window-tracer.h"
+#include "ns3/node.h"
+#include "ns3/packet.h"
+#include "ns3/config.h"
+#include "ns3/callback.h"
+#include "ns3/names.h"
+#include "ns3/simulator.h"
+
+#include <boost/lexical_cast.hpp>
+
+using namespace std;
+using namespace boost;
+
+namespace ns3 {
+
+void
+CcnxConsumerWindowTracer::Connect ()
+{
+  Config::Connect ("/NodeList/"+m_node+"/ApplicationList/"+m_appId+"/$ns3::CcnxConsumerWindow/WindowTrace",
+                   MakeCallback (&WindowTracer::OnWindowChange, this));
+}
+
+void
+TcpCongestionWindowTracer::Connect ()
+{
+  Config::Connect ("/NodeList/"+m_node+"/$ns3::TcpL4Protocol/SocketList/*/CongestionWindow",
+                   MakeCallback (&WindowTracer::OnWindowChange, this));
+}
+
+
+WindowTracer::WindowTracer (std::ostream &os, Ptr<Node> node, const std::string &appId)
+  : m_appId (appId)
+  , m_nodePtr (node)
+  , m_os (os)
+{
+  m_node = boost::lexical_cast<string> (m_nodePtr->GetId ());
+
+  string name = Names::FindName (node);
+  if (!name.empty ())
+    {
+      m_nodeName = name;
+    }
+  else
+    m_nodeName = m_node;
+}
+
+
+void
+WindowTracer::PrintHeader (std::ostream &os)
+{
+  os << "Time\t"
+     << "Node\t"
+     << "AppId\t"
+     << "Window";
+}
+
+void
+WindowTracer::OnWindowChange (std::string context,
+                              uint32_t oldValue, uint32_t newValue)
+{
+  m_os                                                             
+    << Simulator::Now ().ToDouble (Time::S) << "\t"                   
+    << m_nodeName << "\t"                                                 
+    << m_appId << "\t"
+    << newValue << endl;
+}
+
+} // namespace ns3
diff --git a/helper/tracers/ccnx-consumer-window-tracer.h b/helper/tracers/ccnx-consumer-window-tracer.h
new file mode 100644
index 0000000..c538931
--- /dev/null
+++ b/helper/tracers/ccnx-consumer-window-tracer.h
@@ -0,0 +1,77 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012 UCLA
+ *
+ * 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:  Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef CCNX_CONSUMER_WINDOW_TRACER_H
+#define CCNX_CONSUMER_WINDOW_TRACER_H
+
+#include "ns3/ptr.h"
+#include "ns3/simple-ref-count.h"
+
+namespace ns3 {
+
+class Node;
+
+class WindowTracer : public SimpleRefCount<WindowTracer>
+{
+public:
+  WindowTracer (std::ostream &os, Ptr<Node> node, const std::string &appId = "*");
+  virtual ~WindowTracer () { };
+                
+  static void
+  PrintHeader (std::ostream &os);
+  
+  virtual void
+  OnWindowChange (std::string context,
+                  uint32_t oldValue, uint32_t newValue);
+
+protected:
+  std::string m_appId;
+  std::string m_node;
+  std::string m_nodeName;
+  Ptr<Node> m_nodePtr;
+  std::ostream& m_os;
+};
+
+class CcnxConsumerWindowTracer : public WindowTracer
+{
+public:
+  CcnxConsumerWindowTracer (std::ostream &os, Ptr<Node> node, const std::string &appId = "*")
+    : WindowTracer (os, node, appId)
+  { Connect (); }
+
+  void
+  Connect ();
+};
+
+class TcpCongestionWindowTracer : public WindowTracer
+{
+public:
+  TcpCongestionWindowTracer (std::ostream &os, Ptr<Node> node, const std::string &appId = "*")
+    : WindowTracer (os, node, appId)
+  { Connect (); }
+
+  void
+  Connect ();
+};
+
+
+} // namespace ns3
+
+#endif // CCNX_CONSUMER_WINDOW_TRACER_H
diff --git a/examples/content-object-example.cc b/test/content-object-example.cc
similarity index 100%
rename from examples/content-object-example.cc
rename to test/content-object-example.cc
diff --git a/examples/interest-header-example.cc b/test/interest-header-example.cc
similarity index 100%
rename from examples/interest-header-example.cc
rename to test/interest-header-example.cc
diff --git a/examples/packet-sizes.cc b/test/packet-sizes.cc
similarity index 100%
rename from examples/packet-sizes.cc
rename to test/packet-sizes.cc
diff --git a/wscript b/wscript
index 8e7a186..e33af19 100644
--- a/wscript
+++ b/wscript
@@ -61,6 +61,7 @@
         "helper/tracers/ipv4-app-tracer.h",
         "helper/tracers/ccnx-app-tracer.h",
         "helper/tracers/ccnx-l3-tracer.h",
+        "helper/tracers/ccnx-consumer-window-tracer.h",
         "helper/ccnx-face-container.h",
 
         "apps/ccnx-app.h",
@@ -84,24 +85,15 @@
     tests.source = bld.path.ant_glob('test/*.cc');
 
     if True or bld.env['ENABLE_EXAMPLES']:
-        obj = bld.create_ns3_program('ccnx-test', ['NDNabstraction', 'internet'])
-        obj.source = 'examples/ccnx-test.cc'
-        
-        obj = bld.create_ns3_program('ccnx-routing-simple', ['NDNabstraction', 'point-to-point-layout'])
+        obj = bld.create_ns3_program('ccnx-routing-simple', ['NDNabstraction'])
         obj.source = 'examples/ccnx-routing-simple.cc'
         
-        obj = bld.create_ns3_program('ccnx-grid', ['NDNabstraction', 'point-to-point-layout'])
+        obj = bld.create_ns3_program('ccnx-grid', ['NDNabstraction'])
         obj.source = 'examples/ccnx-grid.cc'
 
-        obj = bld.create_ns3_program('annotated-topology', ['NDNabstraction', 'point-to-point-layout'])
+        obj = bld.create_ns3_program('annotated-topology', ['NDNabstraction'])
         obj.source = 'examples/annotated-topology-read-example.cc'
 
-        obj = bld.create_ns3_program('interest-header-example', ['NDNabstraction'])
-        obj.source = 'examples/interest-header-example.cc'
-
-        obj = bld.create_ns3_program('packet-sizes', ['NDNabstraction'])
-        obj.source = 'examples/packet-sizes.cc'
-
         obj = bld.create_ns3_program('ccnx-sprint-topology', ['NDNabstraction'])
         obj.source = 'examples/sprint-topology.cc'
 
@@ -114,22 +106,10 @@
         obj = bld.create_ns3_program('congestion-pop', ['NDNabstraction'])
         obj.source = 'examples/congestion-pop.cc'
 
-        obj = bld.create_ns3_program('congestion-tcp-pop', ['NDNabstraction'])
-        obj.source = 'examples/congestion-tcp-pop.cc'
-
-        #obj = bld.create_ns3_program('congestion-pop', ['NDNabstraction'])
-        #obj.source = 'examples/congestion-pop.cc'
-        
-        obj = bld.create_ns3_program('link-failure-sprint', ['NDNabstraction'])
-        obj.source = 'examples/link-failure-sprint.cc'
-        
-        #obj = bld.create_ns3_program('link-failure-abilene', ['NDNabstraction'])
-        #obj.source = 'examples/link-failure-abilene.cc'
+        #obj = bld.create_ns3_program('link-failure-sprint', ['NDNabstraction'])
+        #obj.source = 'examples/link-failure-sprint.cc'
 
         obj = bld.create_ns3_program('blackhole-sprint', ['NDNabstraction'])
         obj.source = 'examples/blackhole-sprint.cc'
 
-        #obj = bld.create_ns3_program('blackhole-abilene', ['NDNabstraction'])
-        #obj.source = 'examples/blackhole-abilene.cc'
-
     bld.ns3_python_bindings()