merge with ns-3-dev
authorPavel Boyko <boyko@iitp.ru>
Mon, 16 Nov 2009 13:35:38 +0300
changeset 5738 4adee3d945ba
parent 5737 9e23a1e1533f (current diff)
parent 5534 3bc5cbc9431d (diff)
child 5739 ad55c9c7c793
merge with ns-3-dev
doc/howtos/howtos-application.h
doc/howtos/howtos-callbacks.h
doc/howtos/howtos-net-device.h
doc/howtos/howtos-packet-header.h
doc/howtos/howtos.h
src/contrib/wscript
src/core/test.h
src/internet-stack/ipv4-l3-protocol.cc
src/internet-stack/ipv4-l3-protocol.h
--- a/AUTHORS	Mon Nov 16 13:32:56 2009 +0300
+++ b/AUTHORS	Mon Nov 16 13:35:38 2009 +0300
@@ -12,23 +12,33 @@
 Craig Dowell (craigdo@ee.washington.edu)
 David Gross (gdavid.devel@gmail.com)
 Tom Henderson (tomhend@u.washington.edu)
-Andrey Mazo (mazo@iitp.ru)
 Sam Jansen (sam.jansen@gmail.com)
 Liu Jian (liujatp@gmail.com)
 Joe Kopena (tjkopena@cs.drexel.edu)
 Aleksey Kovalenko (kovalenko@iitp.ru)
 Mathieu Lacage (mathieu.lacage@sophia.inria.fr)
 Emmanuelle Laprise (emmmanuelle.laprise@bluekazoo.ca)
+Keith Ma (keith.nwsuaf@gmail.com)
 Federico Maguolo (maguolof@dei.unipd.it)
+Antti Makela (zarhan@cc.hut.fi)
 Francesco Malandrino (francesco.malandrino@gmail.com)
+Fabian Mauchle (f1mauchl@hsr.ch)
+Andrey Mazo (mazo@iitp.ru)
 Faker Moatamri (faker.moatamri@sophia.inria.fr)
 Duy Nguyen (duy@soe.ucsc.edu)
+Tommaso Pecorella (tommaso.pecorella@unifi.it)
+Yana Podkosova (yanapdk@rambler.ru)
 Guangyu Pei (guangyu.pei@boeing.com)
 George F. Riley (riley@ece.gatech.edu)
 Providence Salumu Munga (Providence.Salumu@gmail.com, Providence.Salumu_Munga@it-sudparis.eu)
+Guillaume Seguin (guillaume.seguin@sophia.inria.fr)
 Kulin Shah (m.kulin@gmail.com)
+Ewgenij Starostin (estar@cs.tu-berlin.de)
+Adrian S. W. Tam (adrian.sw.tam@gmail.com)
+Wilson Thong (wilsonwk@ee.cityu.edu.hk)
 Mauro Tortonesi (mauro.tortonesi@unife.it)
 Sebastien Vincent (vincent@clarinet.u-strasbg.fr)
 Guillaume Vu-Brugier (gvubrugier@gmail.com)
+Tom Wambold (tom5760@gmail.com)
 Florian Westphal (fw@strlen.de)
 Josh Pelkey (jpelkey@gatech.edu)
--- a/CHANGES.html	Mon Nov 16 13:32:56 2009 +0300
+++ b/CHANGES.html	Mon Nov 16 13:35:38 2009 +0300
@@ -44,6 +44,100 @@
 us a note on ns-developers mailing list.  </p>
 
 <hr>
+<h1>Changes from ns-3.6 to ns-3.7</h1>
+
+
+<h2>Changes to build system:</h2>
+
+<h2>New API:</h2>
+
+<ul>
+<li><b>Simulator event contexts</b>: The Simulator API now keeps track of a per-event
+'context' (a 32bit integer which, by convention identifies a node by its id). Simulator::GetContext
+returns the context of the currently-executing event while Simulator::ScheduleWithContext creates an
+event with a context different from the execution context of the caller. This API is used
+by the ns-3 logging system to report the execution context of each log line.
+<li><b>Object::DoStart</b>: Users who need to complete their object setup at the start of a simulation
+can override this virtual method, perform their adhoc setup, and then, must chain up to their parent.
+</ul>
+
+<h2>Changes to existing API:</h2>
+<ul>
+<li><b>Application::Start</b> and <b>Application::Stop</b> have been renamed to
+<b>Application::SetStartTime</b> and <b>Application::SetStopTime</b>.
+<li><b>Channel::Send</b>: this method does not really exist but each subclass of the Channel
+base class must implement a similar method which sends a packet from a node to another node.
+Users must now use Simulator::ScheduleWithContext instead of Simulator::Schedule to schedule
+the reception event on a remote node.<br>
+For example, before:
+<pre>
+void
+SimpleChannel::Send (Ptr&lt;Packet&gt; p, uint16_t protocol, 
+		     Mac48Address to, Mac48Address from,
+		     Ptr&lt;SimpleNetDevice&gt; sender)
+{
+  for (std::vector&lt;Ptr&lt;SimpleNetDevice&gt; &gt;::const_iterator i = m_devices.begin (); i != m_devices.end (); ++i)
+    {
+      Ptr&lt;SimpleNetDevice&gt; tmp = *i;
+      if (tmp == sender)
+	{
+	  continue;
+	}
+      Simulator::ScheduleNow (&SimpleNetDevice::Receive, tmp, p->Copy (), protocol, to, from);
+    }
+}
+</pre>
+After:
+<pre>
+void
+SimpleChannel::Send (Ptr&lt;Packet&gt; p, uint16_t protocol, 
+		     Mac48Address to, Mac48Address from,
+		     Ptr&lt;SimpleNetDevice&gt; sender)
+{
+  for (std::vector&lt;Ptr&lt;SimpleNetDevice&gt; &gt;::const_iterator i = m_devices.begin (); i != m_devices.end (); ++i)
+    {
+      Ptr&lt;SimpleNetDevice&gt; tmp = *i;
+      if (tmp == sender)
+	{
+	  continue;
+	}
+      Simulator::ScheduleWithContext (tmp->GetNode ()->GetId (), Seconds (0),
+                                      &SimpleNetDevice::Receive, tmp, p->Copy (), protocol, to, from);
+    }
+}
+</pre>
+
+<li><b>Simulator::SetScheduler</b>: this method now takes an ObjectFactory
+instead of an object pointer directly. Existing callers can trivially be
+updated to use this new method.<br>
+Before:
+<pre>
+Ptr&lt;Scheduler&gt; sched = CreateObject&lt;ListScheduler&gt; ();
+Simulator::SetScheduler (sched);
+</pre>
+After:
+<pre>
+ObjectFactory sched;
+sched.SetTypeId ("ns3::ListScheduler");
+Simulator::SetScheduler (sched);
+</pre>
+
+</ul>
+
+<h2>Changed behavior:</h2>
+<ul>
+<li> Changed default value of YansWifiPhy::EnergyDetectionThreshold from
+-140.0 dBm to -96.0 dBm.  Changed default value of 
+YansWifiPhy::CcaModelThreshold from -140.0 dBm to -99.0 dBm.  Rationale
+can be found <a href="http://www.nsnam.org/bugzilla/show_bug.cgi?id=689"> 
+here</a>.
+</ul>
+<ul>
+<li> Default TTL of IPv4 broadcast datagrams changed from 1 to 64.
+</ul> 
+
+
+<hr>
 <h1>Changes from ns-3.5 to ns-3.6</h1>
 
 <h2>Changes to build system:</h2>
--- a/RELEASE_NOTES	Mon Nov 16 13:32:56 2009 +0300
+++ b/RELEASE_NOTES	Mon Nov 16 13:35:38 2009 +0300
@@ -1,11 +1,51 @@
 
 		ns-3 RELEASE NOTES
 
-This file contains ns-3 release notes (most recent releases first).
+This file contains ns-3 release notes (most recent releases first).  
 
 All of the ns-3 documentation is accessible from the ns-3 website: 
 http://www.nsnam.org including tutorials: http://www.nsnam.org/tutorials.html
 
+Consult the file CHANGES.html for more detailed information about changed
+API and behavior across ns-3 releases.
+
+Release 3.7
+===========
+
+Availability
+------------
+This release is not yet available
+
+Supported platforms
+-------------------
+ns-3.7 has been tested on the following platforms:
+  - linux x86 gcc 4.4.1, 4.2, 4.1, and, 3.4.6.
+  - linux x86_64 gcc 4.4.0, 4.3.2, 4.2.3, 4.2.1, 4.1.3, 3.4.6
+  - MacOS X ppc and x86 (gcc 4.0.x and 4.2.x)
+  - cygwin gcc 3.4.4 (debug only), gcc 4.3.2 (debug and optimized)
+
+Not all ns-3 options are available on all platforms; consult the
+wiki for more information:
+http://www.nsnam.org/wiki/index.php/Installation
+
+New user-visible features
+-------------------------
+
+  * The ns-3 logging macros (NS_LOG_*) now report automatically the node id
+    of the event which called the macro.
+
+API changes from ns-3.5
+-----------------------
+API changes for this release are documented in the file CHANGES.html. 
+
+Known issues
+------------
+ns-3.6 build is known to fail on the following platforms:
+  - gcc 3.3 and earlier
+  - optimized builds on gcc 3.4.4 and 3.4.5
+  - optimized builds on linux x86 gcc 4.0.x
+
+
 Release 3.6
 ===========
 
@@ -21,7 +61,6 @@
   - linux x86_64 gcc 4.4.0, 4.3.2, 4.2.3, 4.2.1, 4.1.3, 3.4.6
   - MacOS X ppc and x86 (gcc 4.0.x and 4.2.x)
   - cygwin gcc 3.4.4 (debug only), gcc 4.3.2 (debug and optimized)
-  - mingw gcc 3.4.5 (debug only)
 
 Not all ns-3 options are available on all platforms; consult the
 wiki for more information:
@@ -78,7 +117,7 @@
 
 Known issues
 ------------
-ns-3 build is known to fail on the following platforms:
+ns-3.6 build is known to fail on the following platforms:
   - gcc 3.3 and earlier
   - optimized builds on gcc 3.4.4 and 3.4.5
   - optimized builds on linux x86 gcc 4.0.x
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_common.py	Mon Nov 16 13:32:56 2009 +0300
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_common.py	Mon Nov 16 13:35:38 2009 +0300
@@ -903,6 +903,11 @@
     cls.add_method('Close', 
                    'void', 
                    [])
+    ## pcap-file.h: static bool ns3::PcapFile::Diff(std::string const & f1, std::string const & f2, uint32_t & sec, uint32_t & usec, uint32_t snapLen=ns3::PcapFile::SNAPLEN_DEFAULT) [member function]
+    cls.add_method('Diff', 
+                   'bool', 
+                   [param('std::string const &', 'f1'), param('std::string const &', 'f2'), param('uint32_t &', 'sec'), param('uint32_t &', 'usec'), param('uint32_t', 'snapLen', default_value='ns3::PcapFile::SNAPLEN_DEFAULT')], 
+                   is_static=True)
     ## pcap-file.h: uint32_t ns3::PcapFile::GetDataLinkType() [member function]
     cls.add_method('GetDataLinkType', 
                    'uint32_t', 
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_core.py	Mon Nov 16 13:32:56 2009 +0300
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_core.py	Mon Nov 16 13:35:38 2009 +0300
@@ -51,6 +51,8 @@
     module.add_class('ObjectBase', allow_subclassing=True)
     ## object-factory.h: ns3::ObjectFactory [class]
     module.add_class('ObjectFactory')
+    ## object-ref-count.h: ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase> [class]
+    module.add_class('ObjectRefCount', template_parameters=['ns3::Object', 'ns3::ObjectBase'], parent=root_module['ns3::ObjectBase'])
     ## random-variable.h: ns3::RandomVariable [class]
     module.add_class('RandomVariable')
     ## ref-count-base.h: ns3::RefCountBase [class]
@@ -144,7 +146,7 @@
     ## random-variable.h: ns3::NormalVariable [class]
     module.add_class('NormalVariable', parent=root_module['ns3::RandomVariable'])
     ## object.h: ns3::Object [class]
-    module.add_class('Object', automatic_type_narrowing=True, parent=root_module['ns3::ObjectBase'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
+    module.add_class('Object', automatic_type_narrowing=True, parent=root_module['ns3::ObjectRefCount< ns3::Object, ns3::ObjectBase >'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
     ## object.h: ns3::Object::AggregateIterator [class]
     module.add_class('AggregateIterator', outer_class=root_module['ns3::Object'])
     ## object-factory.h: ns3::ObjectFactoryChecker [class]
@@ -304,6 +306,7 @@
     register_Ns3Names_methods(root_module, root_module['ns3::Names'])
     register_Ns3ObjectBase_methods(root_module, root_module['ns3::ObjectBase'])
     register_Ns3ObjectFactory_methods(root_module, root_module['ns3::ObjectFactory'])
+    register_Ns3ObjectRefCount__Ns3Object_Ns3ObjectBase_methods(root_module, root_module['ns3::ObjectRefCount< ns3::Object, ns3::ObjectBase >'])
     register_Ns3RandomVariable_methods(root_module, root_module['ns3::RandomVariable'])
     register_Ns3RefCountBase_methods(root_module, root_module['ns3::RefCountBase'])
     register_Ns3RngStream_methods(root_module, root_module['ns3::RngStream'])
@@ -721,6 +724,43 @@
                    [param('std::string', 'tid')])
     return
 
+def register_Ns3ObjectRefCount__Ns3Object_Ns3ObjectBase_methods(root_module, cls):
+    ## object-ref-count.h: ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::ObjectRefCount() [constructor]
+    cls.add_constructor([])
+    ## object-ref-count.h: ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::ObjectRefCount(ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase> const & o) [copy constructor]
+    cls.add_constructor([param('ns3::ObjectRefCount< ns3::Object, ns3::ObjectBase > const &', 'o')])
+    ## object-ref-count.h: int ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::GetReferenceCount() const [member function]
+    cls.add_method('GetReferenceCount', 
+                   'int', 
+                   [], 
+                   is_const=True)
+    ## object-ref-count.h: void ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::Ref() const [member function]
+    cls.add_method('Ref', 
+                   'void', 
+                   [], 
+                   is_const=True)
+    ## object-ref-count.h: void ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::Unref() const [member function]
+    cls.add_method('Unref', 
+                   'void', 
+                   [], 
+                   is_const=True)
+    ## object-ref-count.h: int * ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::PeekCountPtr() const [member function]
+    cls.add_method('PeekCountPtr', 
+                   'int *', 
+                   [], 
+                   is_const=True, visibility='protected')
+    ## object-ref-count.h: void ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::ShareCount(ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase> * other) [member function]
+    cls.add_method('ShareCount', 
+                   'void', 
+                   [param('ns3::ObjectRefCount< ns3::Object, ns3::ObjectBase > *', 'other')], 
+                   visibility='protected')
+    ## object-ref-count.h: void ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::DoDelete() [member function]
+    cls.add_method('DoDelete', 
+                   'void', 
+                   [], 
+                   is_pure_virtual=True, visibility='private', is_virtual=True)
+    return
+
 def register_Ns3RandomVariable_methods(root_module, cls):
     cls.add_output_stream_operator()
     ## random-variable.h: ns3::RandomVariable::RandomVariable() [constructor]
@@ -962,10 +1002,25 @@
     cls.add_constructor([param('ns3::SystemWallClockMs const &', 'arg0')])
     ## system-wall-clock-ms.h: ns3::SystemWallClockMs::SystemWallClockMs() [constructor]
     cls.add_constructor([])
-    ## system-wall-clock-ms.h: long long unsigned int ns3::SystemWallClockMs::End() [member function]
+    ## system-wall-clock-ms.h: int64_t ns3::SystemWallClockMs::End() [member function]
     cls.add_method('End', 
-                   'long long unsigned int', 
+                   'int64_t', 
                    [])
+    ## system-wall-clock-ms.h: int64_t ns3::SystemWallClockMs::GetElapsedReal() const [member function]
+    cls.add_method('GetElapsedReal', 
+                   'int64_t', 
+                   [], 
+                   is_const=True)
+    ## system-wall-clock-ms.h: int64_t ns3::SystemWallClockMs::GetElapsedSystem() const [member function]
+    cls.add_method('GetElapsedSystem', 
+                   'int64_t', 
+                   [], 
+                   is_const=True)
+    ## system-wall-clock-ms.h: int64_t ns3::SystemWallClockMs::GetElapsedUser() const [member function]
+    cls.add_method('GetElapsedUser', 
+                   'int64_t', 
+                   [], 
+                   is_const=True)
     ## system-wall-clock-ms.h: void ns3::SystemWallClockMs::Start() [member function]
     cls.add_method('Start', 
                    'void', 
@@ -1003,6 +1058,14 @@
     cls.add_method('GetBaseDir', 
                    'std::string', 
                    [])
+    ## test.h: void ns3::TestCase::SetTempDir(std::string dir) [member function]
+    cls.add_method('SetTempDir', 
+                   'void', 
+                   [param('std::string', 'dir')])
+    ## test.h: std::string ns3::TestCase::GetTempDir() [member function]
+    cls.add_method('GetTempDir', 
+                   'std::string', 
+                   [])
     ## test.h: std::string ns3::TestCase::GetSourceDir(std::string file) [member function]
     cls.add_method('GetSourceDir', 
                    'std::string', 
@@ -1162,6 +1225,14 @@
     cls.add_method('GetBaseDir', 
                    'std::string', 
                    [])
+    ## test.h: void ns3::TestSuite::SetTempDir(std::string dir) [member function]
+    cls.add_method('SetTempDir', 
+                   'void', 
+                   [param('std::string', 'dir')])
+    ## test.h: std::string ns3::TestSuite::GetTempDir() [member function]
+    cls.add_method('GetTempDir', 
+                   'std::string', 
+                   [])
     ## test.h: void ns3::TestSuite::SetStream(std::ofstream * ofs) [member function]
     cls.add_method('SetStream', 
                    'void', 
@@ -2046,6 +2117,11 @@
                    'void', 
                    [], 
                    visibility='protected', is_virtual=True)
+    ## object.h: void ns3::Object::DoDelete() [member function]
+    cls.add_method('DoDelete', 
+                   'void', 
+                   [], 
+                   visibility='private', is_virtual=True)
     return
 
 def register_Ns3ObjectAggregateIterator_methods(root_module, cls):
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_mobility.py	Mon Nov 16 13:32:56 2009 +0300
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_mobility.py	Mon Nov 16 13:35:38 2009 +0300
@@ -9,6 +9,8 @@
     module.add_class('Rectangle')
     ## rectangle.h: ns3::Rectangle::Side [enumeration]
     module.add_enum('Side', ['RIGHT', 'LEFT', 'TOP', 'BOTTOM'], outer_class=root_module['ns3::Rectangle'])
+    ## waypoint.h: ns3::Waypoint [class]
+    module.add_class('Waypoint')
     ## position-allocator.h: ns3::PositionAllocator [class]
     module.add_class('PositionAllocator', parent=root_module['ns3::Object'])
     ## position-allocator.h: ns3::RandomDiscPositionAllocator [class]
@@ -19,6 +21,10 @@
     module.add_class('RectangleChecker', parent=root_module['ns3::AttributeChecker'])
     ## rectangle.h: ns3::RectangleValue [class]
     module.add_class('RectangleValue', parent=root_module['ns3::AttributeValue'])
+    ## waypoint.h: ns3::WaypointChecker [class]
+    module.add_class('WaypointChecker', parent=root_module['ns3::AttributeChecker'])
+    ## waypoint.h: ns3::WaypointValue [class]
+    module.add_class('WaypointValue', parent=root_module['ns3::AttributeValue'])
     ## position-allocator.h: ns3::GridPositionAllocator [class]
     module.add_class('GridPositionAllocator', parent=root_module['ns3::PositionAllocator'])
     ## position-allocator.h: ns3::GridPositionAllocator::LayoutType [enumeration]
@@ -35,6 +41,8 @@
     module.add_enum('Mode', ['MODE_DISTANCE', 'MODE_TIME'], outer_class=root_module['ns3::RandomWalk2dMobilityModel'])
     ## random-waypoint-mobility-model.h: ns3::RandomWaypointMobilityModel [class]
     module.add_class('RandomWaypointMobilityModel', parent=root_module['ns3::MobilityModel'])
+    ## waypoint-mobility-model.h: ns3::WaypointMobilityModel [class]
+    module.add_class('WaypointMobilityModel', parent=root_module['ns3::MobilityModel'])
     ## constant-acceleration-mobility-model.h: ns3::ConstantAccelerationMobilityModel [class]
     module.add_class('ConstantAccelerationMobilityModel', parent=root_module['ns3::MobilityModel'])
     ## constant-position-mobility-model.h: ns3::ConstantPositionMobilityModel [class]
@@ -117,17 +125,21 @@
 def register_methods(root_module):
     register_Ns3ConstantVelocityHelper_methods(root_module, root_module['ns3::ConstantVelocityHelper'])
     register_Ns3Rectangle_methods(root_module, root_module['ns3::Rectangle'])
+    register_Ns3Waypoint_methods(root_module, root_module['ns3::Waypoint'])
     register_Ns3PositionAllocator_methods(root_module, root_module['ns3::PositionAllocator'])
     register_Ns3RandomDiscPositionAllocator_methods(root_module, root_module['ns3::RandomDiscPositionAllocator'])
     register_Ns3RandomRectanglePositionAllocator_methods(root_module, root_module['ns3::RandomRectanglePositionAllocator'])
     register_Ns3RectangleChecker_methods(root_module, root_module['ns3::RectangleChecker'])
     register_Ns3RectangleValue_methods(root_module, root_module['ns3::RectangleValue'])
+    register_Ns3WaypointChecker_methods(root_module, root_module['ns3::WaypointChecker'])
+    register_Ns3WaypointValue_methods(root_module, root_module['ns3::WaypointValue'])
     register_Ns3GridPositionAllocator_methods(root_module, root_module['ns3::GridPositionAllocator'])
     register_Ns3ListPositionAllocator_methods(root_module, root_module['ns3::ListPositionAllocator'])
     register_Ns3MobilityModel_methods(root_module, root_module['ns3::MobilityModel'])
     register_Ns3RandomDirection2dMobilityModel_methods(root_module, root_module['ns3::RandomDirection2dMobilityModel'])
     register_Ns3RandomWalk2dMobilityModel_methods(root_module, root_module['ns3::RandomWalk2dMobilityModel'])
     register_Ns3RandomWaypointMobilityModel_methods(root_module, root_module['ns3::RandomWaypointMobilityModel'])
+    register_Ns3WaypointMobilityModel_methods(root_module, root_module['ns3::WaypointMobilityModel'])
     register_Ns3ConstantAccelerationMobilityModel_methods(root_module, root_module['ns3::ConstantAccelerationMobilityModel'])
     register_Ns3ConstantPositionMobilityModel_methods(root_module, root_module['ns3::ConstantPositionMobilityModel'])
     register_Ns3ConstantVelocityMobilityModel_methods(root_module, root_module['ns3::ConstantVelocityMobilityModel'])
@@ -214,6 +226,20 @@
     cls.add_instance_attribute('yMin', 'double', is_const=False)
     return
 
+def register_Ns3Waypoint_methods(root_module, cls):
+    cls.add_output_stream_operator()
+    ## waypoint.h: ns3::Waypoint::Waypoint(ns3::Waypoint const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Waypoint const &', 'arg0')])
+    ## waypoint.h: ns3::Waypoint::Waypoint(ns3::Time const & waypointTime, ns3::Vector const & waypointPosition) [constructor]
+    cls.add_constructor([param('ns3::Time const &', 'waypointTime'), param('ns3::Vector const &', 'waypointPosition')])
+    ## waypoint.h: ns3::Waypoint::Waypoint() [constructor]
+    cls.add_constructor([])
+    ## waypoint.h: ns3::Waypoint::position [variable]
+    cls.add_instance_attribute('position', 'ns3::Vector', is_const=False)
+    ## waypoint.h: ns3::Waypoint::time [variable]
+    cls.add_instance_attribute('time', 'ns3::Time', is_const=False)
+    return
+
 def register_Ns3PositionAllocator_methods(root_module, cls):
     ## position-allocator.h: ns3::PositionAllocator::PositionAllocator(ns3::PositionAllocator const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::PositionAllocator const &', 'arg0')])
@@ -329,6 +355,46 @@
                    [param('ns3::Rectangle const &', 'value')])
     return
 
+def register_Ns3WaypointChecker_methods(root_module, cls):
+    ## waypoint.h: ns3::WaypointChecker::WaypointChecker() [constructor]
+    cls.add_constructor([])
+    ## waypoint.h: ns3::WaypointChecker::WaypointChecker(ns3::WaypointChecker const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::WaypointChecker const &', 'arg0')])
+    return
+
+def register_Ns3WaypointValue_methods(root_module, cls):
+    ## waypoint.h: ns3::WaypointValue::WaypointValue() [constructor]
+    cls.add_constructor([])
+    ## waypoint.h: ns3::WaypointValue::WaypointValue(ns3::WaypointValue const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::WaypointValue const &', 'arg0')])
+    ## waypoint.h: ns3::WaypointValue::WaypointValue(ns3::Waypoint const & value) [constructor]
+    cls.add_constructor([param('ns3::Waypoint const &', 'value')])
+    ## waypoint.h: ns3::Ptr<ns3::AttributeValue> ns3::WaypointValue::Copy() const [member function]
+    cls.add_method('Copy', 
+                   'ns3::Ptr< ns3::AttributeValue >', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## waypoint.h: bool ns3::WaypointValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+    cls.add_method('DeserializeFromString', 
+                   'bool', 
+                   [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_virtual=True)
+    ## waypoint.h: ns3::Waypoint ns3::WaypointValue::Get() const [member function]
+    cls.add_method('Get', 
+                   'ns3::Waypoint', 
+                   [], 
+                   is_const=True)
+    ## waypoint.h: std::string ns3::WaypointValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+    cls.add_method('SerializeToString', 
+                   'std::string', 
+                   [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_const=True, is_virtual=True)
+    ## waypoint.h: void ns3::WaypointValue::Set(ns3::Waypoint const & value) [member function]
+    cls.add_method('Set', 
+                   'void', 
+                   [param('ns3::Waypoint const &', 'value')])
+    return
+
 def register_Ns3GridPositionAllocator_methods(root_module, cls):
     ## position-allocator.h: ns3::GridPositionAllocator::GridPositionAllocator(ns3::GridPositionAllocator const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::GridPositionAllocator const &', 'arg0')])
@@ -563,6 +629,56 @@
                    visibility='private', is_virtual=True)
     return
 
+def register_Ns3WaypointMobilityModel_methods(root_module, cls):
+    ## waypoint-mobility-model.h: ns3::WaypointMobilityModel::WaypointMobilityModel(ns3::WaypointMobilityModel const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::WaypointMobilityModel const &', 'arg0')])
+    ## waypoint-mobility-model.h: ns3::WaypointMobilityModel::WaypointMobilityModel() [constructor]
+    cls.add_constructor([])
+    ## waypoint-mobility-model.h: void ns3::WaypointMobilityModel::AddWaypoint(ns3::Waypoint const & waypoint) [member function]
+    cls.add_method('AddWaypoint', 
+                   'void', 
+                   [param('ns3::Waypoint const &', 'waypoint')])
+    ## waypoint-mobility-model.h: void ns3::WaypointMobilityModel::EndMobility() [member function]
+    cls.add_method('EndMobility', 
+                   'void', 
+                   [])
+    ## waypoint-mobility-model.h: ns3::Waypoint ns3::WaypointMobilityModel::GetNextWaypoint() const [member function]
+    cls.add_method('GetNextWaypoint', 
+                   'ns3::Waypoint', 
+                   [], 
+                   is_const=True)
+    ## waypoint-mobility-model.h: static ns3::TypeId ns3::WaypointMobilityModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## waypoint-mobility-model.h: uint32_t ns3::WaypointMobilityModel::WaypointsLeft() const [member function]
+    cls.add_method('WaypointsLeft', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True)
+    ## waypoint-mobility-model.h: void ns3::WaypointMobilityModel::DoDispose() [member function]
+    cls.add_method('DoDispose', 
+                   'void', 
+                   [], 
+                   visibility='private', is_virtual=True)
+    ## waypoint-mobility-model.h: ns3::Vector ns3::WaypointMobilityModel::DoGetPosition() const [member function]
+    cls.add_method('DoGetPosition', 
+                   'ns3::Vector', 
+                   [], 
+                   is_const=True, visibility='private', is_virtual=True)
+    ## waypoint-mobility-model.h: ns3::Vector ns3::WaypointMobilityModel::DoGetVelocity() const [member function]
+    cls.add_method('DoGetVelocity', 
+                   'ns3::Vector', 
+                   [], 
+                   is_const=True, visibility='private', is_virtual=True)
+    ## waypoint-mobility-model.h: void ns3::WaypointMobilityModel::DoSetPosition(ns3::Vector const & position) [member function]
+    cls.add_method('DoSetPosition', 
+                   'void', 
+                   [param('ns3::Vector const &', 'position')], 
+                   visibility='private', is_virtual=True)
+    return
+
 def register_Ns3ConstantAccelerationMobilityModel_methods(root_module, cls):
     ## constant-acceleration-mobility-model.h: ns3::ConstantAccelerationMobilityModel::ConstantAccelerationMobilityModel(ns3::ConstantAccelerationMobilityModel const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::ConstantAccelerationMobilityModel const &', 'arg0')])
@@ -703,6 +819,10 @@
     module.add_function('MakeRectangleChecker', 
                         'ns3::Ptr< ns3::AttributeChecker const >', 
                         [])
+    ## waypoint.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeWaypointChecker() [free function]
+    module.add_function('MakeWaypointChecker', 
+                        'ns3::Ptr< ns3::AttributeChecker const >', 
+                        [])
     register_functions_ns3_Config(module.get_submodule('Config'), root_module)
     register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
     register_functions_ns3_addressUtils(module.get_submodule('addressUtils'), root_module)
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_point_to_point.py	Mon Nov 16 13:32:56 2009 +0300
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_point_to_point.py	Mon Nov 16 13:35:38 2009 +0300
@@ -101,6 +101,10 @@
                    'ns3::TypeId', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## ppp-header.h: uint16_t ns3::PppHeader::GetProtocol() [member function]
+    cls.add_method('GetProtocol', 
+                   'uint16_t', 
+                   [])
     ## ppp-header.h: uint32_t ns3::PppHeader::GetSerializedSize() const [member function]
     cls.add_method('GetSerializedSize', 
                    'uint32_t', 
@@ -121,6 +125,10 @@
                    'void', 
                    [param('ns3::Buffer::Iterator', 'start')], 
                    is_const=True, is_virtual=True)
+    ## ppp-header.h: void ns3::PppHeader::SetProtocol(uint16_t protocol) [member function]
+    cls.add_method('SetProtocol', 
+                   'void', 
+                   [param('uint16_t', 'protocol')])
     return
 
 def register_Ns3PointToPointChannel_methods(root_module, cls):
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_stats.py	Mon Nov 16 13:32:56 2009 +0300
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_stats.py	Mon Nov 16 13:35:38 2009 +0300
@@ -5,18 +5,16 @@
     
     ## data-output-interface.h: ns3::DataOutputCallback [class]
     module.add_class('DataOutputCallback', allow_subclassing=True)
+    ## data-calculator.h: ns3::StatisticalSummary [class]
+    module.add_class('StatisticalSummary', allow_subclassing=True)
     ## data-calculator.h: ns3::DataCalculator [class]
     module.add_class('DataCalculator', parent=root_module['ns3::Object'])
     ## data-collector.h: ns3::DataCollector [class]
     module.add_class('DataCollector', parent=root_module['ns3::Object'])
     ## data-output-interface.h: ns3::DataOutputInterface [class]
     module.add_class('DataOutputInterface', parent=root_module['ns3::Object'])
-    ## basic-data-calculators.h: ns3::MinMaxAvgTotalCalculator<unsigned int> [class]
-    module.add_class('MinMaxAvgTotalCalculator', template_parameters=['unsigned int'], parent=root_module['ns3::DataCalculator'])
     ## omnet-data-output.h: ns3::OmnetDataOutput [class]
     module.add_class('OmnetDataOutput', parent=root_module['ns3::DataOutputInterface'])
-    ## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator [class]
-    module.add_class('PacketSizeMinMaxAvgTotalCalculator', parent=root_module['ns3::MinMaxAvgTotalCalculator< unsigned int >'])
     ## sqlite-data-output.h: ns3::SqliteDataOutput [class]
     module.add_class('SqliteDataOutput', parent=root_module['ns3::DataOutputInterface'])
     ## time-data-calculators.h: ns3::TimeMinMaxAvgTotalCalculator [class]
@@ -104,12 +102,11 @@
 
 def register_methods(root_module):
     register_Ns3DataOutputCallback_methods(root_module, root_module['ns3::DataOutputCallback'])
+    register_Ns3StatisticalSummary_methods(root_module, root_module['ns3::StatisticalSummary'])
     register_Ns3DataCalculator_methods(root_module, root_module['ns3::DataCalculator'])
     register_Ns3DataCollector_methods(root_module, root_module['ns3::DataCollector'])
     register_Ns3DataOutputInterface_methods(root_module, root_module['ns3::DataOutputInterface'])
-    register_Ns3MinMaxAvgTotalCalculator__Unsigned_int_methods(root_module, root_module['ns3::MinMaxAvgTotalCalculator< unsigned int >'])
     register_Ns3OmnetDataOutput_methods(root_module, root_module['ns3::OmnetDataOutput'])
-    register_Ns3PacketSizeMinMaxAvgTotalCalculator_methods(root_module, root_module['ns3::PacketSizeMinMaxAvgTotalCalculator'])
     register_Ns3SqliteDataOutput_methods(root_module, root_module['ns3::SqliteDataOutput'])
     register_Ns3TimeMinMaxAvgTotalCalculator_methods(root_module, root_module['ns3::TimeMinMaxAvgTotalCalculator'])
     register_Ns3CounterCalculator__Unsigned_int_methods(root_module, root_module['ns3::CounterCalculator< unsigned int >'])
@@ -146,6 +143,58 @@
                    'void', 
                    [param('std::string', 'key'), param('std::string', 'variable'), param('ns3::Time', 'val')], 
                    is_pure_virtual=True, is_virtual=True)
+    ## data-output-interface.h: void ns3::DataOutputCallback::OutputStatistic(std::string key, std::string variable, ns3::StatisticalSummary const * statSum) [member function]
+    cls.add_method('OutputStatistic', 
+                   'void', 
+                   [param('std::string', 'key'), param('std::string', 'variable'), param('ns3::StatisticalSummary const *', 'statSum')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
+def register_Ns3StatisticalSummary_methods(root_module, cls):
+    ## data-calculator.h: ns3::StatisticalSummary::StatisticalSummary() [constructor]
+    cls.add_constructor([])
+    ## data-calculator.h: ns3::StatisticalSummary::StatisticalSummary(ns3::StatisticalSummary const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::StatisticalSummary const &', 'arg0')])
+    ## data-calculator.h: long int ns3::StatisticalSummary::getCount() const [member function]
+    cls.add_method('getCount', 
+                   'long int', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: double ns3::StatisticalSummary::getMax() const [member function]
+    cls.add_method('getMax', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: double ns3::StatisticalSummary::getMean() const [member function]
+    cls.add_method('getMean', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: double ns3::StatisticalSummary::getMin() const [member function]
+    cls.add_method('getMin', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: double ns3::StatisticalSummary::getSqrSum() const [member function]
+    cls.add_method('getSqrSum', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: double ns3::StatisticalSummary::getStddev() const [member function]
+    cls.add_method('getStddev', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: double ns3::StatisticalSummary::getSum() const [member function]
+    cls.add_method('getSum', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: double ns3::StatisticalSummary::getVariance() const [member function]
+    cls.add_method('getVariance', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
     return
 
 def register_Ns3DataCalculator_methods(root_module, cls):
@@ -161,6 +210,11 @@
     cls.add_method('Enable', 
                    'void', 
                    [])
+    ## data-calculator.h: std::string ns3::DataCalculator::GetContext() const [member function]
+    cls.add_method('GetContext', 
+                   'std::string', 
+                   [], 
+                   is_const=True)
     ## data-calculator.h: bool ns3::DataCalculator::GetEnabled() const [member function]
     cls.add_method('GetEnabled', 
                    'bool', 
@@ -176,6 +230,10 @@
                    'void', 
                    [param('ns3::DataOutputCallback &', 'callback')], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: void ns3::DataCalculator::SetContext(std::string const context) [member function]
+    cls.add_method('SetContext', 
+                   'void', 
+                   [param('std::string const', 'context')])
     ## data-calculator.h: void ns3::DataCalculator::SetKey(std::string const key) [member function]
     cls.add_method('SetKey', 
                    'void', 
@@ -296,27 +354,6 @@
                    visibility='protected', is_virtual=True)
     return
 
-def register_Ns3MinMaxAvgTotalCalculator__Unsigned_int_methods(root_module, cls):
-    ## basic-data-calculators.h: ns3::MinMaxAvgTotalCalculator<unsigned int>::MinMaxAvgTotalCalculator(ns3::MinMaxAvgTotalCalculator<unsigned int> const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::MinMaxAvgTotalCalculator< unsigned int > const &', 'arg0')])
-    ## basic-data-calculators.h: ns3::MinMaxAvgTotalCalculator<unsigned int>::MinMaxAvgTotalCalculator() [constructor]
-    cls.add_constructor([])
-    ## basic-data-calculators.h: void ns3::MinMaxAvgTotalCalculator<unsigned int>::Output(ns3::DataOutputCallback & callback) const [member function]
-    cls.add_method('Output', 
-                   'void', 
-                   [param('ns3::DataOutputCallback &', 'callback')], 
-                   is_const=True, is_virtual=True)
-    ## basic-data-calculators.h: void ns3::MinMaxAvgTotalCalculator<unsigned int>::Update(unsigned int const i) [member function]
-    cls.add_method('Update', 
-                   'void', 
-                   [param('unsigned int const', 'i')])
-    ## basic-data-calculators.h: void ns3::MinMaxAvgTotalCalculator<unsigned int>::DoDispose() [member function]
-    cls.add_method('DoDispose', 
-                   'void', 
-                   [], 
-                   visibility='protected', is_virtual=True)
-    return
-
 def register_Ns3OmnetDataOutput_methods(root_module, cls):
     ## omnet-data-output.h: ns3::OmnetDataOutput::OmnetDataOutput(ns3::OmnetDataOutput const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::OmnetDataOutput const &', 'arg0')])
@@ -334,26 +371,6 @@
                    visibility='protected', is_virtual=True)
     return
 
-def register_Ns3PacketSizeMinMaxAvgTotalCalculator_methods(root_module, cls):
-    ## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator::PacketSizeMinMaxAvgTotalCalculator(ns3::PacketSizeMinMaxAvgTotalCalculator const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::PacketSizeMinMaxAvgTotalCalculator const &', 'arg0')])
-    ## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator::PacketSizeMinMaxAvgTotalCalculator() [constructor]
-    cls.add_constructor([])
-    ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::FrameUpdate(std::string path, ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address realto) [member function]
-    cls.add_method('FrameUpdate', 
-                   'void', 
-                   [param('std::string', 'path'), param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'realto')])
-    ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::PacketUpdate(std::string path, ns3::Ptr<ns3::Packet const> packet) [member function]
-    cls.add_method('PacketUpdate', 
-                   'void', 
-                   [param('std::string', 'path'), param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::DoDispose() [member function]
-    cls.add_method('DoDispose', 
-                   'void', 
-                   [], 
-                   visibility='protected', is_virtual=True)
-    return
-
 def register_Ns3SqliteDataOutput_methods(root_module, cls):
     ## sqlite-data-output.h: ns3::SqliteDataOutput::SqliteDataOutput(ns3::SqliteDataOutput const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::SqliteDataOutput const &', 'arg0')])
@@ -444,6 +461,10 @@
 
 def register_functions(root_module):
     module = root_module
+    ## data-calculator.h: bool ns3::isNaN(double x) [free function]
+    module.add_function('isNaN', 
+                        'bool', 
+                        [param('double', 'x')])
     register_functions_ns3_Config(module.get_submodule('Config'), root_module)
     register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
     register_functions_ns3_addressUtils(module.get_submodule('addressUtils'), root_module)
--- a/bindings/python/apidefs/gcc-ILP32/ns3modulegen_generated.py	Mon Nov 16 13:32:56 2009 +0300
+++ b/bindings/python/apidefs/gcc-ILP32/ns3modulegen_generated.py	Mon Nov 16 13:35:38 2009 +0300
@@ -17,29 +17,29 @@
 import ns3_module_test
 import ns3_module_mobility
 import ns3_module_common
+import ns3_module_contrib
 import ns3_module_node
-import ns3_module_contrib
+import ns3_module_tap_bridge
+import ns3_module_v4ping
+import ns3_module_static_routing
+import ns3_module_packet_sink
+import ns3_module_stats
+import ns3_module_onoff
 import ns3_module_point_to_point
 import ns3_module_internet_stack
-import ns3_module_tap_bridge
 import ns3_module_csma
+import ns3_module_list_routing
+import ns3_module_virtual_net_device
 import ns3_module_wifi
-import ns3_module_static_routing
-import ns3_module_v4ping
-import ns3_module_virtual_net_device
-import ns3_module_packet_sink
-import ns3_module_global_routing
-import ns3_module_stats
-import ns3_module_list_routing
 import ns3_module_emu
 import ns3_module_bridge
-import ns3_module_onoff
+import ns3_module_global_routing
 import ns3_module_udp_echo
-import ns3_module_ping6
 import ns3_module_nix_vector_routing
 import ns3_module_olsr
+import ns3_module_radvd
+import ns3_module_ping6
 import ns3_module_flow_monitor
-import ns3_module_radvd
 import ns3_module_mesh
 import ns3_module_helper
 import ns3_module_dot11s
@@ -107,6 +107,17 @@
         ns3_module_common__local.register_types(module)
     
     root_module.end_section('ns3_module_common')
+    root_module.begin_section('ns3_module_contrib')
+    ns3_module_contrib.register_types(module)
+    
+    try:
+        import ns3_module_contrib__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_contrib__local.register_types(module)
+    
+    root_module.end_section('ns3_module_contrib')
     root_module.begin_section('ns3_module_node')
     ns3_module_node.register_types(module)
     
@@ -118,17 +129,72 @@
         ns3_module_node__local.register_types(module)
     
     root_module.end_section('ns3_module_node')
-    root_module.begin_section('ns3_module_contrib')
-    ns3_module_contrib.register_types(module)
+    root_module.begin_section('ns3_module_tap_bridge')
+    ns3_module_tap_bridge.register_types(module)
     
     try:
-        import ns3_module_contrib__local
+        import ns3_module_tap_bridge__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_tap_bridge__local.register_types(module)
+    
+    root_module.end_section('ns3_module_tap_bridge')
+    root_module.begin_section('ns3_module_v4ping')
+    ns3_module_v4ping.register_types(module)
+    
+    try:
+        import ns3_module_v4ping__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_v4ping__local.register_types(module)
+    
+    root_module.end_section('ns3_module_v4ping')
+    root_module.begin_section('ns3_module_static_routing')
+    ns3_module_static_routing.register_types(module)
+    
+    try:
+        import ns3_module_static_routing__local
     except ImportError:
         pass
     else:
-        ns3_module_contrib__local.register_types(module)
+        ns3_module_static_routing__local.register_types(module)
+    
+    root_module.end_section('ns3_module_static_routing')
+    root_module.begin_section('ns3_module_packet_sink')
+    ns3_module_packet_sink.register_types(module)
+    
+    try:
+        import ns3_module_packet_sink__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_packet_sink__local.register_types(module)
+    
+    root_module.end_section('ns3_module_packet_sink')
+    root_module.begin_section('ns3_module_stats')
+    ns3_module_stats.register_types(module)
     
-    root_module.end_section('ns3_module_contrib')
+    try:
+        import ns3_module_stats__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_stats__local.register_types(module)
+    
+    root_module.end_section('ns3_module_stats')
+    root_module.begin_section('ns3_module_onoff')
+    ns3_module_onoff.register_types(module)
+    
+    try:
+        import ns3_module_onoff__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_onoff__local.register_types(module)
+    
+    root_module.end_section('ns3_module_onoff')
     root_module.begin_section('ns3_module_point_to_point')
     ns3_module_point_to_point.register_types(module)
     
@@ -151,17 +217,6 @@
         ns3_module_internet_stack__local.register_types(module)
     
     root_module.end_section('ns3_module_internet_stack')
-    root_module.begin_section('ns3_module_tap_bridge')
-    ns3_module_tap_bridge.register_types(module)
-    
-    try:
-        import ns3_module_tap_bridge__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_tap_bridge__local.register_types(module)
-    
-    root_module.end_section('ns3_module_tap_bridge')
     root_module.begin_section('ns3_module_csma')
     ns3_module_csma.register_types(module)
     
@@ -173,6 +228,28 @@
         ns3_module_csma__local.register_types(module)
     
     root_module.end_section('ns3_module_csma')
+    root_module.begin_section('ns3_module_list_routing')
+    ns3_module_list_routing.register_types(module)
+    
+    try:
+        import ns3_module_list_routing__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_list_routing__local.register_types(module)
+    
+    root_module.end_section('ns3_module_list_routing')
+    root_module.begin_section('ns3_module_virtual_net_device')
+    ns3_module_virtual_net_device.register_types(module)
+    
+    try:
+        import ns3_module_virtual_net_device__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_virtual_net_device__local.register_types(module)
+    
+    root_module.end_section('ns3_module_virtual_net_device')
     root_module.begin_section('ns3_module_wifi')
     ns3_module_wifi.register_types(module)
     
@@ -184,83 +261,6 @@
         ns3_module_wifi__local.register_types(module)
     
     root_module.end_section('ns3_module_wifi')
-    root_module.begin_section('ns3_module_static_routing')
-    ns3_module_static_routing.register_types(module)
-    
-    try:
-        import ns3_module_static_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_static_routing__local.register_types(module)
-    
-    root_module.end_section('ns3_module_static_routing')
-    root_module.begin_section('ns3_module_v4ping')
-    ns3_module_v4ping.register_types(module)
-    
-    try:
-        import ns3_module_v4ping__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_v4ping__local.register_types(module)
-    
-    root_module.end_section('ns3_module_v4ping')
-    root_module.begin_section('ns3_module_virtual_net_device')
-    ns3_module_virtual_net_device.register_types(module)
-    
-    try:
-        import ns3_module_virtual_net_device__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_virtual_net_device__local.register_types(module)
-    
-    root_module.end_section('ns3_module_virtual_net_device')
-    root_module.begin_section('ns3_module_packet_sink')
-    ns3_module_packet_sink.register_types(module)
-    
-    try:
-        import ns3_module_packet_sink__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_packet_sink__local.register_types(module)
-    
-    root_module.end_section('ns3_module_packet_sink')
-    root_module.begin_section('ns3_module_global_routing')
-    ns3_module_global_routing.register_types(module)
-    
-    try:
-        import ns3_module_global_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_global_routing__local.register_types(module)
-    
-    root_module.end_section('ns3_module_global_routing')
-    root_module.begin_section('ns3_module_stats')
-    ns3_module_stats.register_types(module)
-    
-    try:
-        import ns3_module_stats__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_stats__local.register_types(module)
-    
-    root_module.end_section('ns3_module_stats')
-    root_module.begin_section('ns3_module_list_routing')
-    ns3_module_list_routing.register_types(module)
-    
-    try:
-        import ns3_module_list_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_list_routing__local.register_types(module)
-    
-    root_module.end_section('ns3_module_list_routing')
     root_module.begin_section('ns3_module_emu')
     ns3_module_emu.register_types(module)
     
@@ -283,17 +283,17 @@
         ns3_module_bridge__local.register_types(module)
     
     root_module.end_section('ns3_module_bridge')
-    root_module.begin_section('ns3_module_onoff')
-    ns3_module_onoff.register_types(module)
+    root_module.begin_section('ns3_module_global_routing')
+    ns3_module_global_routing.register_types(module)
     
     try:
-        import ns3_module_onoff__local
+        import ns3_module_global_routing__local
     except ImportError:
         pass
     else:
-        ns3_module_onoff__local.register_types(module)
+        ns3_module_global_routing__local.register_types(module)
     
-    root_module.end_section('ns3_module_onoff')
+    root_module.end_section('ns3_module_global_routing')
     root_module.begin_section('ns3_module_udp_echo')
     ns3_module_udp_echo.register_types(module)
     
@@ -305,17 +305,6 @@
         ns3_module_udp_echo__local.register_types(module)
     
     root_module.end_section('ns3_module_udp_echo')
-    root_module.begin_section('ns3_module_ping6')
-    ns3_module_ping6.register_types(module)
-    
-    try:
-        import ns3_module_ping6__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_ping6__local.register_types(module)
-    
-    root_module.end_section('ns3_module_ping6')
     root_module.begin_section('ns3_module_nix_vector_routing')
     ns3_module_nix_vector_routing.register_types(module)
     
@@ -338,6 +327,28 @@
         ns3_module_olsr__local.register_types(module)
     
     root_module.end_section('ns3_module_olsr')
+    root_module.begin_section('ns3_module_radvd')
+    ns3_module_radvd.register_types(module)
+    
+    try:
+        import ns3_module_radvd__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_radvd__local.register_types(module)
+    
+    root_module.end_section('ns3_module_radvd')
+    root_module.begin_section('ns3_module_ping6')
+    ns3_module_ping6.register_types(module)
+    
+    try:
+        import ns3_module_ping6__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_ping6__local.register_types(module)
+    
+    root_module.end_section('ns3_module_ping6')
     root_module.begin_section('ns3_module_flow_monitor')
     ns3_module_flow_monitor.register_types(module)
     
@@ -349,17 +360,6 @@
         ns3_module_flow_monitor__local.register_types(module)
     
     root_module.end_section('ns3_module_flow_monitor')
-    root_module.begin_section('ns3_module_radvd')
-    ns3_module_radvd.register_types(module)
-    
-    try:
-        import ns3_module_radvd__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_radvd__local.register_types(module)
-    
-    root_module.end_section('ns3_module_radvd')
     root_module.begin_section('ns3_module_mesh')
     ns3_module_mesh.register_types(module)
     
@@ -549,6 +549,17 @@
         ns3_module_common__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_common')
+    root_module.begin_section('ns3_module_contrib')
+    ns3_module_contrib.register_methods(root_module)
+    
+    try:
+        import ns3_module_contrib__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_contrib__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_contrib')
     root_module.begin_section('ns3_module_node')
     ns3_module_node.register_methods(root_module)
     
@@ -560,17 +571,72 @@
         ns3_module_node__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_node')
-    root_module.begin_section('ns3_module_contrib')
-    ns3_module_contrib.register_methods(root_module)
+    root_module.begin_section('ns3_module_tap_bridge')
+    ns3_module_tap_bridge.register_methods(root_module)
     
     try:
-        import ns3_module_contrib__local
+        import ns3_module_tap_bridge__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_tap_bridge__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_tap_bridge')
+    root_module.begin_section('ns3_module_v4ping')
+    ns3_module_v4ping.register_methods(root_module)
+    
+    try:
+        import ns3_module_v4ping__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_v4ping__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_v4ping')
+    root_module.begin_section('ns3_module_static_routing')
+    ns3_module_static_routing.register_methods(root_module)
+    
+    try:
+        import ns3_module_static_routing__local
     except ImportError:
         pass
     else:
-        ns3_module_contrib__local.register_methods(root_module)
+        ns3_module_static_routing__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_static_routing')
+    root_module.begin_section('ns3_module_packet_sink')
+    ns3_module_packet_sink.register_methods(root_module)
+    
+    try:
+        import ns3_module_packet_sink__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_packet_sink__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_packet_sink')
+    root_module.begin_section('ns3_module_stats')
+    ns3_module_stats.register_methods(root_module)
     
-    root_module.end_section('ns3_module_contrib')
+    try:
+        import ns3_module_stats__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_stats__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_stats')
+    root_module.begin_section('ns3_module_onoff')
+    ns3_module_onoff.register_methods(root_module)
+    
+    try:
+        import ns3_module_onoff__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_onoff__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_onoff')
     root_module.begin_section('ns3_module_point_to_point')
     ns3_module_point_to_point.register_methods(root_module)
     
@@ -593,17 +659,6 @@
         ns3_module_internet_stack__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_internet_stack')
-    root_module.begin_section('ns3_module_tap_bridge')
-    ns3_module_tap_bridge.register_methods(root_module)
-    
-    try:
-        import ns3_module_tap_bridge__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_tap_bridge__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_tap_bridge')
     root_module.begin_section('ns3_module_csma')
     ns3_module_csma.register_methods(root_module)
     
@@ -615,6 +670,28 @@
         ns3_module_csma__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_csma')
+    root_module.begin_section('ns3_module_list_routing')
+    ns3_module_list_routing.register_methods(root_module)
+    
+    try:
+        import ns3_module_list_routing__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_list_routing__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_list_routing')
+    root_module.begin_section('ns3_module_virtual_net_device')
+    ns3_module_virtual_net_device.register_methods(root_module)
+    
+    try:
+        import ns3_module_virtual_net_device__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_virtual_net_device__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_virtual_net_device')
     root_module.begin_section('ns3_module_wifi')
     ns3_module_wifi.register_methods(root_module)
     
@@ -626,83 +703,6 @@
         ns3_module_wifi__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_wifi')
-    root_module.begin_section('ns3_module_static_routing')
-    ns3_module_static_routing.register_methods(root_module)
-    
-    try:
-        import ns3_module_static_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_static_routing__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_static_routing')
-    root_module.begin_section('ns3_module_v4ping')
-    ns3_module_v4ping.register_methods(root_module)
-    
-    try:
-        import ns3_module_v4ping__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_v4ping__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_v4ping')
-    root_module.begin_section('ns3_module_virtual_net_device')
-    ns3_module_virtual_net_device.register_methods(root_module)
-    
-    try:
-        import ns3_module_virtual_net_device__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_virtual_net_device__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_virtual_net_device')
-    root_module.begin_section('ns3_module_packet_sink')
-    ns3_module_packet_sink.register_methods(root_module)
-    
-    try:
-        import ns3_module_packet_sink__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_packet_sink__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_packet_sink')
-    root_module.begin_section('ns3_module_global_routing')
-    ns3_module_global_routing.register_methods(root_module)
-    
-    try:
-        import ns3_module_global_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_global_routing__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_global_routing')
-    root_module.begin_section('ns3_module_stats')
-    ns3_module_stats.register_methods(root_module)
-    
-    try:
-        import ns3_module_stats__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_stats__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_stats')
-    root_module.begin_section('ns3_module_list_routing')
-    ns3_module_list_routing.register_methods(root_module)
-    
-    try:
-        import ns3_module_list_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_list_routing__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_list_routing')
     root_module.begin_section('ns3_module_emu')
     ns3_module_emu.register_methods(root_module)
     
@@ -725,17 +725,17 @@
         ns3_module_bridge__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_bridge')
-    root_module.begin_section('ns3_module_onoff')
-    ns3_module_onoff.register_methods(root_module)
+    root_module.begin_section('ns3_module_global_routing')
+    ns3_module_global_routing.register_methods(root_module)
     
     try:
-        import ns3_module_onoff__local
+        import ns3_module_global_routing__local
     except ImportError:
         pass
     else:
-        ns3_module_onoff__local.register_methods(root_module)
+        ns3_module_global_routing__local.register_methods(root_module)
     
-    root_module.end_section('ns3_module_onoff')
+    root_module.end_section('ns3_module_global_routing')
     root_module.begin_section('ns3_module_udp_echo')
     ns3_module_udp_echo.register_methods(root_module)
     
@@ -747,17 +747,6 @@
         ns3_module_udp_echo__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_udp_echo')
-    root_module.begin_section('ns3_module_ping6')
-    ns3_module_ping6.register_methods(root_module)
-    
-    try:
-        import ns3_module_ping6__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_ping6__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_ping6')
     root_module.begin_section('ns3_module_nix_vector_routing')
     ns3_module_nix_vector_routing.register_methods(root_module)
     
@@ -780,6 +769,28 @@
         ns3_module_olsr__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_olsr')
+    root_module.begin_section('ns3_module_radvd')
+    ns3_module_radvd.register_methods(root_module)
+    
+    try:
+        import ns3_module_radvd__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_radvd__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_radvd')
+    root_module.begin_section('ns3_module_ping6')
+    ns3_module_ping6.register_methods(root_module)
+    
+    try:
+        import ns3_module_ping6__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_ping6__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_ping6')
     root_module.begin_section('ns3_module_flow_monitor')
     ns3_module_flow_monitor.register_methods(root_module)
     
@@ -791,17 +802,6 @@
         ns3_module_flow_monitor__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_flow_monitor')
-    root_module.begin_section('ns3_module_radvd')
-    ns3_module_radvd.register_methods(root_module)
-    
-    try:
-        import ns3_module_radvd__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_radvd__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_radvd')
     root_module.begin_section('ns3_module_mesh')
     ns3_module_mesh.register_methods(root_module)
     
@@ -1039,6 +1039,17 @@
         ns3_module_common__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_common')
+    root_module.begin_section('ns3_module_contrib')
+    ns3_module_contrib.register_functions(root_module)
+    
+    try:
+        import ns3_module_contrib__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_contrib__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_contrib')
     root_module.begin_section('ns3_module_node')
     ns3_module_node.register_functions(root_module)
     
@@ -1050,17 +1061,72 @@
         ns3_module_node__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_node')
-    root_module.begin_section('ns3_module_contrib')
-    ns3_module_contrib.register_functions(root_module)
+    root_module.begin_section('ns3_module_tap_bridge')
+    ns3_module_tap_bridge.register_functions(root_module)
     
     try:
-        import ns3_module_contrib__local
+        import ns3_module_tap_bridge__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_tap_bridge__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_tap_bridge')
+    root_module.begin_section('ns3_module_v4ping')
+    ns3_module_v4ping.register_functions(root_module)
+    
+    try:
+        import ns3_module_v4ping__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_v4ping__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_v4ping')
+    root_module.begin_section('ns3_module_static_routing')
+    ns3_module_static_routing.register_functions(root_module)
+    
+    try:
+        import ns3_module_static_routing__local
     except ImportError:
         pass
     else:
-        ns3_module_contrib__local.register_functions(root_module)
+        ns3_module_static_routing__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_static_routing')
+    root_module.begin_section('ns3_module_packet_sink')
+    ns3_module_packet_sink.register_functions(root_module)
+    
+    try:
+        import ns3_module_packet_sink__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_packet_sink__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_packet_sink')
+    root_module.begin_section('ns3_module_stats')
+    ns3_module_stats.register_functions(root_module)
     
-    root_module.end_section('ns3_module_contrib')
+    try:
+        import ns3_module_stats__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_stats__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_stats')
+    root_module.begin_section('ns3_module_onoff')
+    ns3_module_onoff.register_functions(root_module)
+    
+    try:
+        import ns3_module_onoff__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_onoff__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_onoff')
     root_module.begin_section('ns3_module_point_to_point')
     ns3_module_point_to_point.register_functions(root_module)
     
@@ -1083,17 +1149,6 @@
         ns3_module_internet_stack__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_internet_stack')
-    root_module.begin_section('ns3_module_tap_bridge')
-    ns3_module_tap_bridge.register_functions(root_module)
-    
-    try:
-        import ns3_module_tap_bridge__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_tap_bridge__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_tap_bridge')
     root_module.begin_section('ns3_module_csma')
     ns3_module_csma.register_functions(root_module)
     
@@ -1105,6 +1160,28 @@
         ns3_module_csma__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_csma')
+    root_module.begin_section('ns3_module_list_routing')
+    ns3_module_list_routing.register_functions(root_module)
+    
+    try:
+        import ns3_module_list_routing__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_list_routing__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_list_routing')
+    root_module.begin_section('ns3_module_virtual_net_device')
+    ns3_module_virtual_net_device.register_functions(root_module)
+    
+    try:
+        import ns3_module_virtual_net_device__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_virtual_net_device__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_virtual_net_device')
     root_module.begin_section('ns3_module_wifi')
     ns3_module_wifi.register_functions(root_module)
     
@@ -1116,83 +1193,6 @@
         ns3_module_wifi__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_wifi')
-    root_module.begin_section('ns3_module_static_routing')
-    ns3_module_static_routing.register_functions(root_module)
-    
-    try:
-        import ns3_module_static_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_static_routing__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_static_routing')
-    root_module.begin_section('ns3_module_v4ping')
-    ns3_module_v4ping.register_functions(root_module)
-    
-    try:
-        import ns3_module_v4ping__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_v4ping__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_v4ping')
-    root_module.begin_section('ns3_module_virtual_net_device')
-    ns3_module_virtual_net_device.register_functions(root_module)
-    
-    try:
-        import ns3_module_virtual_net_device__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_virtual_net_device__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_virtual_net_device')
-    root_module.begin_section('ns3_module_packet_sink')
-    ns3_module_packet_sink.register_functions(root_module)
-    
-    try:
-        import ns3_module_packet_sink__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_packet_sink__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_packet_sink')
-    root_module.begin_section('ns3_module_global_routing')
-    ns3_module_global_routing.register_functions(root_module)
-    
-    try:
-        import ns3_module_global_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_global_routing__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_global_routing')
-    root_module.begin_section('ns3_module_stats')
-    ns3_module_stats.register_functions(root_module)
-    
-    try:
-        import ns3_module_stats__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_stats__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_stats')
-    root_module.begin_section('ns3_module_list_routing')
-    ns3_module_list_routing.register_functions(root_module)
-    
-    try:
-        import ns3_module_list_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_list_routing__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_list_routing')
     root_module.begin_section('ns3_module_emu')
     ns3_module_emu.register_functions(root_module)
     
@@ -1215,17 +1215,17 @@
         ns3_module_bridge__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_bridge')
-    root_module.begin_section('ns3_module_onoff')
-    ns3_module_onoff.register_functions(root_module)
+    root_module.begin_section('ns3_module_global_routing')
+    ns3_module_global_routing.register_functions(root_module)
     
     try:
-        import ns3_module_onoff__local
+        import ns3_module_global_routing__local
     except ImportError:
         pass
     else:
-        ns3_module_onoff__local.register_functions(root_module)
+        ns3_module_global_routing__local.register_functions(root_module)
     
-    root_module.end_section('ns3_module_onoff')
+    root_module.end_section('ns3_module_global_routing')
     root_module.begin_section('ns3_module_udp_echo')
     ns3_module_udp_echo.register_functions(root_module)
     
@@ -1237,17 +1237,6 @@
         ns3_module_udp_echo__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_udp_echo')
-    root_module.begin_section('ns3_module_ping6')
-    ns3_module_ping6.register_functions(root_module)
-    
-    try:
-        import ns3_module_ping6__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_ping6__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_ping6')
     root_module.begin_section('ns3_module_nix_vector_routing')
     ns3_module_nix_vector_routing.register_functions(root_module)
     
@@ -1270,6 +1259,28 @@
         ns3_module_olsr__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_olsr')
+    root_module.begin_section('ns3_module_radvd')
+    ns3_module_radvd.register_functions(root_module)
+    
+    try:
+        import ns3_module_radvd__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_radvd__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_radvd')
+    root_module.begin_section('ns3_module_ping6')
+    ns3_module_ping6.register_functions(root_module)
+    
+    try:
+        import ns3_module_ping6__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_ping6__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_ping6')
     root_module.begin_section('ns3_module_flow_monitor')
     ns3_module_flow_monitor.register_functions(root_module)
     
@@ -1281,17 +1292,6 @@
         ns3_module_flow_monitor__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_flow_monitor')
-    root_module.begin_section('ns3_module_radvd')
-    ns3_module_radvd.register_functions(root_module)
-    
-    try:
-        import ns3_module_radvd__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_radvd__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_radvd')
     root_module.begin_section('ns3_module_mesh')
     ns3_module_mesh.register_functions(root_module)
     
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_common.py	Mon Nov 16 13:32:56 2009 +0300
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_common.py	Mon Nov 16 13:35:38 2009 +0300
@@ -903,6 +903,11 @@
     cls.add_method('Close', 
                    'void', 
                    [])
+    ## pcap-file.h: static bool ns3::PcapFile::Diff(std::string const & f1, std::string const & f2, uint32_t & sec, uint32_t & usec, uint32_t snapLen=ns3::PcapFile::SNAPLEN_DEFAULT) [member function]
+    cls.add_method('Diff', 
+                   'bool', 
+                   [param('std::string const &', 'f1'), param('std::string const &', 'f2'), param('uint32_t &', 'sec'), param('uint32_t &', 'usec'), param('uint32_t', 'snapLen', default_value='ns3::PcapFile::SNAPLEN_DEFAULT')], 
+                   is_static=True)
     ## pcap-file.h: uint32_t ns3::PcapFile::GetDataLinkType() [member function]
     cls.add_method('GetDataLinkType', 
                    'uint32_t', 
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_core.py	Mon Nov 16 13:32:56 2009 +0300
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_core.py	Mon Nov 16 13:35:38 2009 +0300
@@ -51,6 +51,8 @@
     module.add_class('ObjectBase', allow_subclassing=True)
     ## object-factory.h: ns3::ObjectFactory [class]
     module.add_class('ObjectFactory')
+    ## object-ref-count.h: ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase> [class]
+    module.add_class('ObjectRefCount', template_parameters=['ns3::Object', 'ns3::ObjectBase'], parent=root_module['ns3::ObjectBase'])
     ## random-variable.h: ns3::RandomVariable [class]
     module.add_class('RandomVariable')
     ## ref-count-base.h: ns3::RefCountBase [class]
@@ -144,7 +146,7 @@
     ## random-variable.h: ns3::NormalVariable [class]
     module.add_class('NormalVariable', parent=root_module['ns3::RandomVariable'])
     ## object.h: ns3::Object [class]
-    module.add_class('Object', automatic_type_narrowing=True, parent=root_module['ns3::ObjectBase'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
+    module.add_class('Object', automatic_type_narrowing=True, parent=root_module['ns3::ObjectRefCount< ns3::Object, ns3::ObjectBase >'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
     ## object.h: ns3::Object::AggregateIterator [class]
     module.add_class('AggregateIterator', outer_class=root_module['ns3::Object'])
     ## object-factory.h: ns3::ObjectFactoryChecker [class]
@@ -304,6 +306,7 @@
     register_Ns3Names_methods(root_module, root_module['ns3::Names'])
     register_Ns3ObjectBase_methods(root_module, root_module['ns3::ObjectBase'])
     register_Ns3ObjectFactory_methods(root_module, root_module['ns3::ObjectFactory'])
+    register_Ns3ObjectRefCount__Ns3Object_Ns3ObjectBase_methods(root_module, root_module['ns3::ObjectRefCount< ns3::Object, ns3::ObjectBase >'])
     register_Ns3RandomVariable_methods(root_module, root_module['ns3::RandomVariable'])
     register_Ns3RefCountBase_methods(root_module, root_module['ns3::RefCountBase'])
     register_Ns3RngStream_methods(root_module, root_module['ns3::RngStream'])
@@ -721,6 +724,43 @@
                    [param('std::string', 'tid')])
     return
 
+def register_Ns3ObjectRefCount__Ns3Object_Ns3ObjectBase_methods(root_module, cls):
+    ## object-ref-count.h: ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::ObjectRefCount() [constructor]
+    cls.add_constructor([])
+    ## object-ref-count.h: ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::ObjectRefCount(ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase> const & o) [copy constructor]
+    cls.add_constructor([param('ns3::ObjectRefCount< ns3::Object, ns3::ObjectBase > const &', 'o')])
+    ## object-ref-count.h: int ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::GetReferenceCount() const [member function]
+    cls.add_method('GetReferenceCount', 
+                   'int', 
+                   [], 
+                   is_const=True)
+    ## object-ref-count.h: void ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::Ref() const [member function]
+    cls.add_method('Ref', 
+                   'void', 
+                   [], 
+                   is_const=True)
+    ## object-ref-count.h: void ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::Unref() const [member function]
+    cls.add_method('Unref', 
+                   'void', 
+                   [], 
+                   is_const=True)
+    ## object-ref-count.h: int * ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::PeekCountPtr() const [member function]
+    cls.add_method('PeekCountPtr', 
+                   'int *', 
+                   [], 
+                   is_const=True, visibility='protected')
+    ## object-ref-count.h: void ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::ShareCount(ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase> * other) [member function]
+    cls.add_method('ShareCount', 
+                   'void', 
+                   [param('ns3::ObjectRefCount< ns3::Object, ns3::ObjectBase > *', 'other')], 
+                   visibility='protected')
+    ## object-ref-count.h: void ns3::ObjectRefCount<ns3::Object, ns3::ObjectBase>::DoDelete() [member function]
+    cls.add_method('DoDelete', 
+                   'void', 
+                   [], 
+                   is_pure_virtual=True, visibility='private', is_virtual=True)
+    return
+
 def register_Ns3RandomVariable_methods(root_module, cls):
     cls.add_output_stream_operator()
     ## random-variable.h: ns3::RandomVariable::RandomVariable() [constructor]
@@ -962,10 +1002,25 @@
     cls.add_constructor([param('ns3::SystemWallClockMs const &', 'arg0')])
     ## system-wall-clock-ms.h: ns3::SystemWallClockMs::SystemWallClockMs() [constructor]
     cls.add_constructor([])
-    ## system-wall-clock-ms.h: long long unsigned int ns3::SystemWallClockMs::End() [member function]
+    ## system-wall-clock-ms.h: int64_t ns3::SystemWallClockMs::End() [member function]
     cls.add_method('End', 
-                   'long long unsigned int', 
+                   'int64_t', 
                    [])
+    ## system-wall-clock-ms.h: int64_t ns3::SystemWallClockMs::GetElapsedReal() const [member function]
+    cls.add_method('GetElapsedReal', 
+                   'int64_t', 
+                   [], 
+                   is_const=True)
+    ## system-wall-clock-ms.h: int64_t ns3::SystemWallClockMs::GetElapsedSystem() const [member function]
+    cls.add_method('GetElapsedSystem', 
+                   'int64_t', 
+                   [], 
+                   is_const=True)
+    ## system-wall-clock-ms.h: int64_t ns3::SystemWallClockMs::GetElapsedUser() const [member function]
+    cls.add_method('GetElapsedUser', 
+                   'int64_t', 
+                   [], 
+                   is_const=True)
     ## system-wall-clock-ms.h: void ns3::SystemWallClockMs::Start() [member function]
     cls.add_method('Start', 
                    'void', 
@@ -1003,6 +1058,14 @@
     cls.add_method('GetBaseDir', 
                    'std::string', 
                    [])
+    ## test.h: void ns3::TestCase::SetTempDir(std::string dir) [member function]
+    cls.add_method('SetTempDir', 
+                   'void', 
+                   [param('std::string', 'dir')])
+    ## test.h: std::string ns3::TestCase::GetTempDir() [member function]
+    cls.add_method('GetTempDir', 
+                   'std::string', 
+                   [])
     ## test.h: std::string ns3::TestCase::GetSourceDir(std::string file) [member function]
     cls.add_method('GetSourceDir', 
                    'std::string', 
@@ -1162,6 +1225,14 @@
     cls.add_method('GetBaseDir', 
                    'std::string', 
                    [])
+    ## test.h: void ns3::TestSuite::SetTempDir(std::string dir) [member function]
+    cls.add_method('SetTempDir', 
+                   'void', 
+                   [param('std::string', 'dir')])
+    ## test.h: std::string ns3::TestSuite::GetTempDir() [member function]
+    cls.add_method('GetTempDir', 
+                   'std::string', 
+                   [])
     ## test.h: void ns3::TestSuite::SetStream(std::ofstream * ofs) [member function]
     cls.add_method('SetStream', 
                    'void', 
@@ -2046,6 +2117,11 @@
                    'void', 
                    [], 
                    visibility='protected', is_virtual=True)
+    ## object.h: void ns3::Object::DoDelete() [member function]
+    cls.add_method('DoDelete', 
+                   'void', 
+                   [], 
+                   visibility='private', is_virtual=True)
     return
 
 def register_Ns3ObjectAggregateIterator_methods(root_module, cls):
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_mobility.py	Mon Nov 16 13:32:56 2009 +0300
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_mobility.py	Mon Nov 16 13:35:38 2009 +0300
@@ -9,6 +9,8 @@
     module.add_class('Rectangle')
     ## rectangle.h: ns3::Rectangle::Side [enumeration]
     module.add_enum('Side', ['RIGHT', 'LEFT', 'TOP', 'BOTTOM'], outer_class=root_module['ns3::Rectangle'])
+    ## waypoint.h: ns3::Waypoint [class]
+    module.add_class('Waypoint')
     ## position-allocator.h: ns3::PositionAllocator [class]
     module.add_class('PositionAllocator', parent=root_module['ns3::Object'])
     ## position-allocator.h: ns3::RandomDiscPositionAllocator [class]
@@ -19,6 +21,10 @@
     module.add_class('RectangleChecker', parent=root_module['ns3::AttributeChecker'])
     ## rectangle.h: ns3::RectangleValue [class]
     module.add_class('RectangleValue', parent=root_module['ns3::AttributeValue'])
+    ## waypoint.h: ns3::WaypointChecker [class]
+    module.add_class('WaypointChecker', parent=root_module['ns3::AttributeChecker'])
+    ## waypoint.h: ns3::WaypointValue [class]
+    module.add_class('WaypointValue', parent=root_module['ns3::AttributeValue'])
     ## position-allocator.h: ns3::GridPositionAllocator [class]
     module.add_class('GridPositionAllocator', parent=root_module['ns3::PositionAllocator'])
     ## position-allocator.h: ns3::GridPositionAllocator::LayoutType [enumeration]
@@ -35,6 +41,8 @@
     module.add_enum('Mode', ['MODE_DISTANCE', 'MODE_TIME'], outer_class=root_module['ns3::RandomWalk2dMobilityModel'])
     ## random-waypoint-mobility-model.h: ns3::RandomWaypointMobilityModel [class]
     module.add_class('RandomWaypointMobilityModel', parent=root_module['ns3::MobilityModel'])
+    ## waypoint-mobility-model.h: ns3::WaypointMobilityModel [class]
+    module.add_class('WaypointMobilityModel', parent=root_module['ns3::MobilityModel'])
     ## constant-acceleration-mobility-model.h: ns3::ConstantAccelerationMobilityModel [class]
     module.add_class('ConstantAccelerationMobilityModel', parent=root_module['ns3::MobilityModel'])
     ## constant-position-mobility-model.h: ns3::ConstantPositionMobilityModel [class]
@@ -117,17 +125,21 @@
 def register_methods(root_module):
     register_Ns3ConstantVelocityHelper_methods(root_module, root_module['ns3::ConstantVelocityHelper'])
     register_Ns3Rectangle_methods(root_module, root_module['ns3::Rectangle'])
+    register_Ns3Waypoint_methods(root_module, root_module['ns3::Waypoint'])
     register_Ns3PositionAllocator_methods(root_module, root_module['ns3::PositionAllocator'])
     register_Ns3RandomDiscPositionAllocator_methods(root_module, root_module['ns3::RandomDiscPositionAllocator'])
     register_Ns3RandomRectanglePositionAllocator_methods(root_module, root_module['ns3::RandomRectanglePositionAllocator'])
     register_Ns3RectangleChecker_methods(root_module, root_module['ns3::RectangleChecker'])
     register_Ns3RectangleValue_methods(root_module, root_module['ns3::RectangleValue'])
+    register_Ns3WaypointChecker_methods(root_module, root_module['ns3::WaypointChecker'])
+    register_Ns3WaypointValue_methods(root_module, root_module['ns3::WaypointValue'])
     register_Ns3GridPositionAllocator_methods(root_module, root_module['ns3::GridPositionAllocator'])
     register_Ns3ListPositionAllocator_methods(root_module, root_module['ns3::ListPositionAllocator'])
     register_Ns3MobilityModel_methods(root_module, root_module['ns3::MobilityModel'])
     register_Ns3RandomDirection2dMobilityModel_methods(root_module, root_module['ns3::RandomDirection2dMobilityModel'])
     register_Ns3RandomWalk2dMobilityModel_methods(root_module, root_module['ns3::RandomWalk2dMobilityModel'])
     register_Ns3RandomWaypointMobilityModel_methods(root_module, root_module['ns3::RandomWaypointMobilityModel'])
+    register_Ns3WaypointMobilityModel_methods(root_module, root_module['ns3::WaypointMobilityModel'])
     register_Ns3ConstantAccelerationMobilityModel_methods(root_module, root_module['ns3::ConstantAccelerationMobilityModel'])
     register_Ns3ConstantPositionMobilityModel_methods(root_module, root_module['ns3::ConstantPositionMobilityModel'])
     register_Ns3ConstantVelocityMobilityModel_methods(root_module, root_module['ns3::ConstantVelocityMobilityModel'])
@@ -214,6 +226,20 @@
     cls.add_instance_attribute('yMin', 'double', is_const=False)
     return
 
+def register_Ns3Waypoint_methods(root_module, cls):
+    cls.add_output_stream_operator()
+    ## waypoint.h: ns3::Waypoint::Waypoint(ns3::Waypoint const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Waypoint const &', 'arg0')])
+    ## waypoint.h: ns3::Waypoint::Waypoint(ns3::Time const & waypointTime, ns3::Vector const & waypointPosition) [constructor]
+    cls.add_constructor([param('ns3::Time const &', 'waypointTime'), param('ns3::Vector const &', 'waypointPosition')])
+    ## waypoint.h: ns3::Waypoint::Waypoint() [constructor]
+    cls.add_constructor([])
+    ## waypoint.h: ns3::Waypoint::position [variable]
+    cls.add_instance_attribute('position', 'ns3::Vector', is_const=False)
+    ## waypoint.h: ns3::Waypoint::time [variable]
+    cls.add_instance_attribute('time', 'ns3::Time', is_const=False)
+    return
+
 def register_Ns3PositionAllocator_methods(root_module, cls):
     ## position-allocator.h: ns3::PositionAllocator::PositionAllocator(ns3::PositionAllocator const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::PositionAllocator const &', 'arg0')])
@@ -329,6 +355,46 @@
                    [param('ns3::Rectangle const &', 'value')])
     return
 
+def register_Ns3WaypointChecker_methods(root_module, cls):
+    ## waypoint.h: ns3::WaypointChecker::WaypointChecker() [constructor]
+    cls.add_constructor([])
+    ## waypoint.h: ns3::WaypointChecker::WaypointChecker(ns3::WaypointChecker const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::WaypointChecker const &', 'arg0')])
+    return
+
+def register_Ns3WaypointValue_methods(root_module, cls):
+    ## waypoint.h: ns3::WaypointValue::WaypointValue() [constructor]
+    cls.add_constructor([])
+    ## waypoint.h: ns3::WaypointValue::WaypointValue(ns3::WaypointValue const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::WaypointValue const &', 'arg0')])
+    ## waypoint.h: ns3::WaypointValue::WaypointValue(ns3::Waypoint const & value) [constructor]
+    cls.add_constructor([param('ns3::Waypoint const &', 'value')])
+    ## waypoint.h: ns3::Ptr<ns3::AttributeValue> ns3::WaypointValue::Copy() const [member function]
+    cls.add_method('Copy', 
+                   'ns3::Ptr< ns3::AttributeValue >', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## waypoint.h: bool ns3::WaypointValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+    cls.add_method('DeserializeFromString', 
+                   'bool', 
+                   [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_virtual=True)
+    ## waypoint.h: ns3::Waypoint ns3::WaypointValue::Get() const [member function]
+    cls.add_method('Get', 
+                   'ns3::Waypoint', 
+                   [], 
+                   is_const=True)
+    ## waypoint.h: std::string ns3::WaypointValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+    cls.add_method('SerializeToString', 
+                   'std::string', 
+                   [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_const=True, is_virtual=True)
+    ## waypoint.h: void ns3::WaypointValue::Set(ns3::Waypoint const & value) [member function]
+    cls.add_method('Set', 
+                   'void', 
+                   [param('ns3::Waypoint const &', 'value')])
+    return
+
 def register_Ns3GridPositionAllocator_methods(root_module, cls):
     ## position-allocator.h: ns3::GridPositionAllocator::GridPositionAllocator(ns3::GridPositionAllocator const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::GridPositionAllocator const &', 'arg0')])
@@ -563,6 +629,56 @@
                    visibility='private', is_virtual=True)
     return
 
+def register_Ns3WaypointMobilityModel_methods(root_module, cls):
+    ## waypoint-mobility-model.h: ns3::WaypointMobilityModel::WaypointMobilityModel(ns3::WaypointMobilityModel const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::WaypointMobilityModel const &', 'arg0')])
+    ## waypoint-mobility-model.h: ns3::WaypointMobilityModel::WaypointMobilityModel() [constructor]
+    cls.add_constructor([])
+    ## waypoint-mobility-model.h: void ns3::WaypointMobilityModel::AddWaypoint(ns3::Waypoint const & waypoint) [member function]
+    cls.add_method('AddWaypoint', 
+                   'void', 
+                   [param('ns3::Waypoint const &', 'waypoint')])
+    ## waypoint-mobility-model.h: void ns3::WaypointMobilityModel::EndMobility() [member function]
+    cls.add_method('EndMobility', 
+                   'void', 
+                   [])
+    ## waypoint-mobility-model.h: ns3::Waypoint ns3::WaypointMobilityModel::GetNextWaypoint() const [member function]
+    cls.add_method('GetNextWaypoint', 
+                   'ns3::Waypoint', 
+                   [], 
+                   is_const=True)
+    ## waypoint-mobility-model.h: static ns3::TypeId ns3::WaypointMobilityModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## waypoint-mobility-model.h: uint32_t ns3::WaypointMobilityModel::WaypointsLeft() const [member function]
+    cls.add_method('WaypointsLeft', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True)
+    ## waypoint-mobility-model.h: void ns3::WaypointMobilityModel::DoDispose() [member function]
+    cls.add_method('DoDispose', 
+                   'void', 
+                   [], 
+                   visibility='private', is_virtual=True)
+    ## waypoint-mobility-model.h: ns3::Vector ns3::WaypointMobilityModel::DoGetPosition() const [member function]
+    cls.add_method('DoGetPosition', 
+                   'ns3::Vector', 
+                   [], 
+                   is_const=True, visibility='private', is_virtual=True)
+    ## waypoint-mobility-model.h: ns3::Vector ns3::WaypointMobilityModel::DoGetVelocity() const [member function]
+    cls.add_method('DoGetVelocity', 
+                   'ns3::Vector', 
+                   [], 
+                   is_const=True, visibility='private', is_virtual=True)
+    ## waypoint-mobility-model.h: void ns3::WaypointMobilityModel::DoSetPosition(ns3::Vector const & position) [member function]
+    cls.add_method('DoSetPosition', 
+                   'void', 
+                   [param('ns3::Vector const &', 'position')], 
+                   visibility='private', is_virtual=True)
+    return
+
 def register_Ns3ConstantAccelerationMobilityModel_methods(root_module, cls):
     ## constant-acceleration-mobility-model.h: ns3::ConstantAccelerationMobilityModel::ConstantAccelerationMobilityModel(ns3::ConstantAccelerationMobilityModel const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::ConstantAccelerationMobilityModel const &', 'arg0')])
@@ -703,6 +819,10 @@
     module.add_function('MakeRectangleChecker', 
                         'ns3::Ptr< ns3::AttributeChecker const >', 
                         [])
+    ## waypoint.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeWaypointChecker() [free function]
+    module.add_function('MakeWaypointChecker', 
+                        'ns3::Ptr< ns3::AttributeChecker const >', 
+                        [])
     register_functions_ns3_Config(module.get_submodule('Config'), root_module)
     register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
     register_functions_ns3_addressUtils(module.get_submodule('addressUtils'), root_module)
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_point_to_point.py	Mon Nov 16 13:32:56 2009 +0300
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_point_to_point.py	Mon Nov 16 13:35:38 2009 +0300
@@ -101,6 +101,10 @@
                    'ns3::TypeId', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## ppp-header.h: uint16_t ns3::PppHeader::GetProtocol() [member function]
+    cls.add_method('GetProtocol', 
+                   'uint16_t', 
+                   [])
     ## ppp-header.h: uint32_t ns3::PppHeader::GetSerializedSize() const [member function]
     cls.add_method('GetSerializedSize', 
                    'uint32_t', 
@@ -121,6 +125,10 @@
                    'void', 
                    [param('ns3::Buffer::Iterator', 'start')], 
                    is_const=True, is_virtual=True)
+    ## ppp-header.h: void ns3::PppHeader::SetProtocol(uint16_t protocol) [member function]
+    cls.add_method('SetProtocol', 
+                   'void', 
+                   [param('uint16_t', 'protocol')])
     return
 
 def register_Ns3PointToPointChannel_methods(root_module, cls):
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_stats.py	Mon Nov 16 13:32:56 2009 +0300
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_stats.py	Mon Nov 16 13:35:38 2009 +0300
@@ -5,18 +5,16 @@
     
     ## data-output-interface.h: ns3::DataOutputCallback [class]
     module.add_class('DataOutputCallback', allow_subclassing=True)
+    ## data-calculator.h: ns3::StatisticalSummary [class]
+    module.add_class('StatisticalSummary', allow_subclassing=True)
     ## data-calculator.h: ns3::DataCalculator [class]
     module.add_class('DataCalculator', parent=root_module['ns3::Object'])
     ## data-collector.h: ns3::DataCollector [class]
     module.add_class('DataCollector', parent=root_module['ns3::Object'])
     ## data-output-interface.h: ns3::DataOutputInterface [class]
     module.add_class('DataOutputInterface', parent=root_module['ns3::Object'])
-    ## basic-data-calculators.h: ns3::MinMaxAvgTotalCalculator<unsigned int> [class]
-    module.add_class('MinMaxAvgTotalCalculator', template_parameters=['unsigned int'], parent=root_module['ns3::DataCalculator'])
     ## omnet-data-output.h: ns3::OmnetDataOutput [class]
     module.add_class('OmnetDataOutput', parent=root_module['ns3::DataOutputInterface'])
-    ## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator [class]
-    module.add_class('PacketSizeMinMaxAvgTotalCalculator', parent=root_module['ns3::MinMaxAvgTotalCalculator< unsigned int >'])
     ## sqlite-data-output.h: ns3::SqliteDataOutput [class]
     module.add_class('SqliteDataOutput', parent=root_module['ns3::DataOutputInterface'])
     ## time-data-calculators.h: ns3::TimeMinMaxAvgTotalCalculator [class]
@@ -104,12 +102,11 @@
 
 def register_methods(root_module):
     register_Ns3DataOutputCallback_methods(root_module, root_module['ns3::DataOutputCallback'])
+    register_Ns3StatisticalSummary_methods(root_module, root_module['ns3::StatisticalSummary'])
     register_Ns3DataCalculator_methods(root_module, root_module['ns3::DataCalculator'])
     register_Ns3DataCollector_methods(root_module, root_module['ns3::DataCollector'])
     register_Ns3DataOutputInterface_methods(root_module, root_module['ns3::DataOutputInterface'])
-    register_Ns3MinMaxAvgTotalCalculator__Unsigned_int_methods(root_module, root_module['ns3::MinMaxAvgTotalCalculator< unsigned int >'])
     register_Ns3OmnetDataOutput_methods(root_module, root_module['ns3::OmnetDataOutput'])
-    register_Ns3PacketSizeMinMaxAvgTotalCalculator_methods(root_module, root_module['ns3::PacketSizeMinMaxAvgTotalCalculator'])
     register_Ns3SqliteDataOutput_methods(root_module, root_module['ns3::SqliteDataOutput'])
     register_Ns3TimeMinMaxAvgTotalCalculator_methods(root_module, root_module['ns3::TimeMinMaxAvgTotalCalculator'])
     register_Ns3CounterCalculator__Unsigned_int_methods(root_module, root_module['ns3::CounterCalculator< unsigned int >'])
@@ -146,6 +143,58 @@
                    'void', 
                    [param('std::string', 'key'), param('std::string', 'variable'), param('ns3::Time', 'val')], 
                    is_pure_virtual=True, is_virtual=True)
+    ## data-output-interface.h: void ns3::DataOutputCallback::OutputStatistic(std::string key, std::string variable, ns3::StatisticalSummary const * statSum) [member function]
+    cls.add_method('OutputStatistic', 
+                   'void', 
+                   [param('std::string', 'key'), param('std::string', 'variable'), param('ns3::StatisticalSummary const *', 'statSum')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
+def register_Ns3StatisticalSummary_methods(root_module, cls):
+    ## data-calculator.h: ns3::StatisticalSummary::StatisticalSummary() [constructor]
+    cls.add_constructor([])
+    ## data-calculator.h: ns3::StatisticalSummary::StatisticalSummary(ns3::StatisticalSummary const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::StatisticalSummary const &', 'arg0')])
+    ## data-calculator.h: long int ns3::StatisticalSummary::getCount() const [member function]
+    cls.add_method('getCount', 
+                   'long int', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: double ns3::StatisticalSummary::getMax() const [member function]
+    cls.add_method('getMax', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: double ns3::StatisticalSummary::getMean() const [member function]
+    cls.add_method('getMean', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: double ns3::StatisticalSummary::getMin() const [member function]
+    cls.add_method('getMin', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: double ns3::StatisticalSummary::getSqrSum() const [member function]
+    cls.add_method('getSqrSum', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: double ns3::StatisticalSummary::getStddev() const [member function]
+    cls.add_method('getStddev', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: double ns3::StatisticalSummary::getSum() const [member function]
+    cls.add_method('getSum', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: double ns3::StatisticalSummary::getVariance() const [member function]
+    cls.add_method('getVariance', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
     return
 
 def register_Ns3DataCalculator_methods(root_module, cls):
@@ -161,6 +210,11 @@
     cls.add_method('Enable', 
                    'void', 
                    [])
+    ## data-calculator.h: std::string ns3::DataCalculator::GetContext() const [member function]
+    cls.add_method('GetContext', 
+                   'std::string', 
+                   [], 
+                   is_const=True)
     ## data-calculator.h: bool ns3::DataCalculator::GetEnabled() const [member function]
     cls.add_method('GetEnabled', 
                    'bool', 
@@ -176,6 +230,10 @@
                    'void', 
                    [param('ns3::DataOutputCallback &', 'callback')], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## data-calculator.h: void ns3::DataCalculator::SetContext(std::string const context) [member function]
+    cls.add_method('SetContext', 
+                   'void', 
+                   [param('std::string const', 'context')])
     ## data-calculator.h: void ns3::DataCalculator::SetKey(std::string const key) [member function]
     cls.add_method('SetKey', 
                    'void', 
@@ -296,27 +354,6 @@
                    visibility='protected', is_virtual=True)
     return
 
-def register_Ns3MinMaxAvgTotalCalculator__Unsigned_int_methods(root_module, cls):
-    ## basic-data-calculators.h: ns3::MinMaxAvgTotalCalculator<unsigned int>::MinMaxAvgTotalCalculator(ns3::MinMaxAvgTotalCalculator<unsigned int> const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::MinMaxAvgTotalCalculator< unsigned int > const &', 'arg0')])
-    ## basic-data-calculators.h: ns3::MinMaxAvgTotalCalculator<unsigned int>::MinMaxAvgTotalCalculator() [constructor]
-    cls.add_constructor([])
-    ## basic-data-calculators.h: void ns3::MinMaxAvgTotalCalculator<unsigned int>::Output(ns3::DataOutputCallback & callback) const [member function]
-    cls.add_method('Output', 
-                   'void', 
-                   [param('ns3::DataOutputCallback &', 'callback')], 
-                   is_const=True, is_virtual=True)
-    ## basic-data-calculators.h: void ns3::MinMaxAvgTotalCalculator<unsigned int>::Update(unsigned int const i) [member function]
-    cls.add_method('Update', 
-                   'void', 
-                   [param('unsigned int const', 'i')])
-    ## basic-data-calculators.h: void ns3::MinMaxAvgTotalCalculator<unsigned int>::DoDispose() [member function]
-    cls.add_method('DoDispose', 
-                   'void', 
-                   [], 
-                   visibility='protected', is_virtual=True)
-    return
-
 def register_Ns3OmnetDataOutput_methods(root_module, cls):
     ## omnet-data-output.h: ns3::OmnetDataOutput::OmnetDataOutput(ns3::OmnetDataOutput const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::OmnetDataOutput const &', 'arg0')])
@@ -334,26 +371,6 @@
                    visibility='protected', is_virtual=True)
     return
 
-def register_Ns3PacketSizeMinMaxAvgTotalCalculator_methods(root_module, cls):
-    ## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator::PacketSizeMinMaxAvgTotalCalculator(ns3::PacketSizeMinMaxAvgTotalCalculator const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::PacketSizeMinMaxAvgTotalCalculator const &', 'arg0')])
-    ## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator::PacketSizeMinMaxAvgTotalCalculator() [constructor]
-    cls.add_constructor([])
-    ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::FrameUpdate(std::string path, ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address realto) [member function]
-    cls.add_method('FrameUpdate', 
-                   'void', 
-                   [param('std::string', 'path'), param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'realto')])
-    ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::PacketUpdate(std::string path, ns3::Ptr<ns3::Packet const> packet) [member function]
-    cls.add_method('PacketUpdate', 
-                   'void', 
-                   [param('std::string', 'path'), param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::DoDispose() [member function]
-    cls.add_method('DoDispose', 
-                   'void', 
-                   [], 
-                   visibility='protected', is_virtual=True)
-    return
-
 def register_Ns3SqliteDataOutput_methods(root_module, cls):
     ## sqlite-data-output.h: ns3::SqliteDataOutput::SqliteDataOutput(ns3::SqliteDataOutput const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::SqliteDataOutput const &', 'arg0')])
@@ -444,6 +461,10 @@
 
 def register_functions(root_module):
     module = root_module
+    ## data-calculator.h: bool ns3::isNaN(double x) [free function]
+    module.add_function('isNaN', 
+                        'bool', 
+                        [param('double', 'x')])
     register_functions_ns3_Config(module.get_submodule('Config'), root_module)
     register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
     register_functions_ns3_addressUtils(module.get_submodule('addressUtils'), root_module)
--- a/bindings/python/apidefs/gcc-LP64/ns3modulegen_generated.py	Mon Nov 16 13:32:56 2009 +0300
+++ b/bindings/python/apidefs/gcc-LP64/ns3modulegen_generated.py	Mon Nov 16 13:35:38 2009 +0300
@@ -17,29 +17,29 @@
 import ns3_module_test
 import ns3_module_mobility
 import ns3_module_common
+import ns3_module_contrib
 import ns3_module_node
-import ns3_module_contrib
+import ns3_module_tap_bridge
+import ns3_module_v4ping
+import ns3_module_static_routing
+import ns3_module_packet_sink
+import ns3_module_stats
+import ns3_module_onoff
 import ns3_module_point_to_point
 import ns3_module_internet_stack
-import ns3_module_tap_bridge
 import ns3_module_csma
+import ns3_module_list_routing
+import ns3_module_virtual_net_device
 import ns3_module_wifi
-import ns3_module_static_routing
-import ns3_module_v4ping
-import ns3_module_virtual_net_device
-import ns3_module_packet_sink
-import ns3_module_global_routing
-import ns3_module_stats
-import ns3_module_list_routing
 import ns3_module_emu
 import ns3_module_bridge
-import ns3_module_onoff
+import ns3_module_global_routing
 import ns3_module_udp_echo
-import ns3_module_ping6
 import ns3_module_nix_vector_routing
 import ns3_module_olsr
+import ns3_module_radvd
+import ns3_module_ping6
 import ns3_module_flow_monitor
-import ns3_module_radvd
 import ns3_module_mesh
 import ns3_module_helper
 import ns3_module_dot11s
@@ -107,6 +107,17 @@
         ns3_module_common__local.register_types(module)
     
     root_module.end_section('ns3_module_common')
+    root_module.begin_section('ns3_module_contrib')
+    ns3_module_contrib.register_types(module)
+    
+    try:
+        import ns3_module_contrib__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_contrib__local.register_types(module)
+    
+    root_module.end_section('ns3_module_contrib')
     root_module.begin_section('ns3_module_node')
     ns3_module_node.register_types(module)
     
@@ -118,17 +129,72 @@
         ns3_module_node__local.register_types(module)
     
     root_module.end_section('ns3_module_node')
-    root_module.begin_section('ns3_module_contrib')
-    ns3_module_contrib.register_types(module)
+    root_module.begin_section('ns3_module_tap_bridge')
+    ns3_module_tap_bridge.register_types(module)
     
     try:
-        import ns3_module_contrib__local
+        import ns3_module_tap_bridge__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_tap_bridge__local.register_types(module)
+    
+    root_module.end_section('ns3_module_tap_bridge')
+    root_module.begin_section('ns3_module_v4ping')
+    ns3_module_v4ping.register_types(module)
+    
+    try:
+        import ns3_module_v4ping__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_v4ping__local.register_types(module)
+    
+    root_module.end_section('ns3_module_v4ping')
+    root_module.begin_section('ns3_module_static_routing')
+    ns3_module_static_routing.register_types(module)
+    
+    try:
+        import ns3_module_static_routing__local
     except ImportError:
         pass
     else:
-        ns3_module_contrib__local.register_types(module)
+        ns3_module_static_routing__local.register_types(module)
+    
+    root_module.end_section('ns3_module_static_routing')
+    root_module.begin_section('ns3_module_packet_sink')
+    ns3_module_packet_sink.register_types(module)
+    
+    try:
+        import ns3_module_packet_sink__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_packet_sink__local.register_types(module)
+    
+    root_module.end_section('ns3_module_packet_sink')
+    root_module.begin_section('ns3_module_stats')
+    ns3_module_stats.register_types(module)
     
-    root_module.end_section('ns3_module_contrib')
+    try:
+        import ns3_module_stats__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_stats__local.register_types(module)
+    
+    root_module.end_section('ns3_module_stats')
+    root_module.begin_section('ns3_module_onoff')
+    ns3_module_onoff.register_types(module)
+    
+    try:
+        import ns3_module_onoff__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_onoff__local.register_types(module)
+    
+    root_module.end_section('ns3_module_onoff')
     root_module.begin_section('ns3_module_point_to_point')
     ns3_module_point_to_point.register_types(module)
     
@@ -151,17 +217,6 @@
         ns3_module_internet_stack__local.register_types(module)
     
     root_module.end_section('ns3_module_internet_stack')
-    root_module.begin_section('ns3_module_tap_bridge')
-    ns3_module_tap_bridge.register_types(module)
-    
-    try:
-        import ns3_module_tap_bridge__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_tap_bridge__local.register_types(module)
-    
-    root_module.end_section('ns3_module_tap_bridge')
     root_module.begin_section('ns3_module_csma')
     ns3_module_csma.register_types(module)
     
@@ -173,6 +228,28 @@
         ns3_module_csma__local.register_types(module)
     
     root_module.end_section('ns3_module_csma')
+    root_module.begin_section('ns3_module_list_routing')
+    ns3_module_list_routing.register_types(module)
+    
+    try:
+        import ns3_module_list_routing__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_list_routing__local.register_types(module)
+    
+    root_module.end_section('ns3_module_list_routing')
+    root_module.begin_section('ns3_module_virtual_net_device')
+    ns3_module_virtual_net_device.register_types(module)
+    
+    try:
+        import ns3_module_virtual_net_device__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_virtual_net_device__local.register_types(module)
+    
+    root_module.end_section('ns3_module_virtual_net_device')
     root_module.begin_section('ns3_module_wifi')
     ns3_module_wifi.register_types(module)
     
@@ -184,83 +261,6 @@
         ns3_module_wifi__local.register_types(module)
     
     root_module.end_section('ns3_module_wifi')
-    root_module.begin_section('ns3_module_static_routing')
-    ns3_module_static_routing.register_types(module)
-    
-    try:
-        import ns3_module_static_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_static_routing__local.register_types(module)
-    
-    root_module.end_section('ns3_module_static_routing')
-    root_module.begin_section('ns3_module_v4ping')
-    ns3_module_v4ping.register_types(module)
-    
-    try:
-        import ns3_module_v4ping__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_v4ping__local.register_types(module)
-    
-    root_module.end_section('ns3_module_v4ping')
-    root_module.begin_section('ns3_module_virtual_net_device')
-    ns3_module_virtual_net_device.register_types(module)
-    
-    try:
-        import ns3_module_virtual_net_device__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_virtual_net_device__local.register_types(module)
-    
-    root_module.end_section('ns3_module_virtual_net_device')
-    root_module.begin_section('ns3_module_packet_sink')
-    ns3_module_packet_sink.register_types(module)
-    
-    try:
-        import ns3_module_packet_sink__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_packet_sink__local.register_types(module)
-    
-    root_module.end_section('ns3_module_packet_sink')
-    root_module.begin_section('ns3_module_global_routing')
-    ns3_module_global_routing.register_types(module)
-    
-    try:
-        import ns3_module_global_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_global_routing__local.register_types(module)
-    
-    root_module.end_section('ns3_module_global_routing')
-    root_module.begin_section('ns3_module_stats')
-    ns3_module_stats.register_types(module)
-    
-    try:
-        import ns3_module_stats__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_stats__local.register_types(module)
-    
-    root_module.end_section('ns3_module_stats')
-    root_module.begin_section('ns3_module_list_routing')
-    ns3_module_list_routing.register_types(module)
-    
-    try:
-        import ns3_module_list_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_list_routing__local.register_types(module)
-    
-    root_module.end_section('ns3_module_list_routing')
     root_module.begin_section('ns3_module_emu')
     ns3_module_emu.register_types(module)
     
@@ -283,17 +283,17 @@
         ns3_module_bridge__local.register_types(module)
     
     root_module.end_section('ns3_module_bridge')
-    root_module.begin_section('ns3_module_onoff')
-    ns3_module_onoff.register_types(module)
+    root_module.begin_section('ns3_module_global_routing')
+    ns3_module_global_routing.register_types(module)
     
     try:
-        import ns3_module_onoff__local
+        import ns3_module_global_routing__local
     except ImportError:
         pass
     else:
-        ns3_module_onoff__local.register_types(module)
+        ns3_module_global_routing__local.register_types(module)
     
-    root_module.end_section('ns3_module_onoff')
+    root_module.end_section('ns3_module_global_routing')
     root_module.begin_section('ns3_module_udp_echo')
     ns3_module_udp_echo.register_types(module)
     
@@ -305,17 +305,6 @@
         ns3_module_udp_echo__local.register_types(module)
     
     root_module.end_section('ns3_module_udp_echo')
-    root_module.begin_section('ns3_module_ping6')
-    ns3_module_ping6.register_types(module)
-    
-    try:
-        import ns3_module_ping6__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_ping6__local.register_types(module)
-    
-    root_module.end_section('ns3_module_ping6')
     root_module.begin_section('ns3_module_nix_vector_routing')
     ns3_module_nix_vector_routing.register_types(module)
     
@@ -338,6 +327,28 @@
         ns3_module_olsr__local.register_types(module)
     
     root_module.end_section('ns3_module_olsr')
+    root_module.begin_section('ns3_module_radvd')
+    ns3_module_radvd.register_types(module)
+    
+    try:
+        import ns3_module_radvd__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_radvd__local.register_types(module)
+    
+    root_module.end_section('ns3_module_radvd')
+    root_module.begin_section('ns3_module_ping6')
+    ns3_module_ping6.register_types(module)
+    
+    try:
+        import ns3_module_ping6__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_ping6__local.register_types(module)
+    
+    root_module.end_section('ns3_module_ping6')
     root_module.begin_section('ns3_module_flow_monitor')
     ns3_module_flow_monitor.register_types(module)
     
@@ -349,17 +360,6 @@
         ns3_module_flow_monitor__local.register_types(module)
     
     root_module.end_section('ns3_module_flow_monitor')
-    root_module.begin_section('ns3_module_radvd')
-    ns3_module_radvd.register_types(module)
-    
-    try:
-        import ns3_module_radvd__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_radvd__local.register_types(module)
-    
-    root_module.end_section('ns3_module_radvd')
     root_module.begin_section('ns3_module_mesh')
     ns3_module_mesh.register_types(module)
     
@@ -549,6 +549,17 @@
         ns3_module_common__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_common')
+    root_module.begin_section('ns3_module_contrib')
+    ns3_module_contrib.register_methods(root_module)
+    
+    try:
+        import ns3_module_contrib__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_contrib__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_contrib')
     root_module.begin_section('ns3_module_node')
     ns3_module_node.register_methods(root_module)
     
@@ -560,17 +571,72 @@
         ns3_module_node__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_node')
-    root_module.begin_section('ns3_module_contrib')
-    ns3_module_contrib.register_methods(root_module)
+    root_module.begin_section('ns3_module_tap_bridge')
+    ns3_module_tap_bridge.register_methods(root_module)
     
     try:
-        import ns3_module_contrib__local
+        import ns3_module_tap_bridge__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_tap_bridge__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_tap_bridge')
+    root_module.begin_section('ns3_module_v4ping')
+    ns3_module_v4ping.register_methods(root_module)
+    
+    try:
+        import ns3_module_v4ping__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_v4ping__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_v4ping')
+    root_module.begin_section('ns3_module_static_routing')
+    ns3_module_static_routing.register_methods(root_module)
+    
+    try:
+        import ns3_module_static_routing__local
     except ImportError:
         pass
     else:
-        ns3_module_contrib__local.register_methods(root_module)
+        ns3_module_static_routing__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_static_routing')
+    root_module.begin_section('ns3_module_packet_sink')
+    ns3_module_packet_sink.register_methods(root_module)
+    
+    try:
+        import ns3_module_packet_sink__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_packet_sink__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_packet_sink')
+    root_module.begin_section('ns3_module_stats')
+    ns3_module_stats.register_methods(root_module)
     
-    root_module.end_section('ns3_module_contrib')
+    try:
+        import ns3_module_stats__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_stats__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_stats')
+    root_module.begin_section('ns3_module_onoff')
+    ns3_module_onoff.register_methods(root_module)
+    
+    try:
+        import ns3_module_onoff__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_onoff__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_onoff')
     root_module.begin_section('ns3_module_point_to_point')
     ns3_module_point_to_point.register_methods(root_module)
     
@@ -593,17 +659,6 @@
         ns3_module_internet_stack__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_internet_stack')
-    root_module.begin_section('ns3_module_tap_bridge')
-    ns3_module_tap_bridge.register_methods(root_module)
-    
-    try:
-        import ns3_module_tap_bridge__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_tap_bridge__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_tap_bridge')
     root_module.begin_section('ns3_module_csma')
     ns3_module_csma.register_methods(root_module)
     
@@ -615,6 +670,28 @@
         ns3_module_csma__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_csma')
+    root_module.begin_section('ns3_module_list_routing')
+    ns3_module_list_routing.register_methods(root_module)
+    
+    try:
+        import ns3_module_list_routing__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_list_routing__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_list_routing')
+    root_module.begin_section('ns3_module_virtual_net_device')
+    ns3_module_virtual_net_device.register_methods(root_module)
+    
+    try:
+        import ns3_module_virtual_net_device__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_virtual_net_device__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_virtual_net_device')
     root_module.begin_section('ns3_module_wifi')
     ns3_module_wifi.register_methods(root_module)
     
@@ -626,83 +703,6 @@
         ns3_module_wifi__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_wifi')
-    root_module.begin_section('ns3_module_static_routing')
-    ns3_module_static_routing.register_methods(root_module)
-    
-    try:
-        import ns3_module_static_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_static_routing__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_static_routing')
-    root_module.begin_section('ns3_module_v4ping')
-    ns3_module_v4ping.register_methods(root_module)
-    
-    try:
-        import ns3_module_v4ping__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_v4ping__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_v4ping')
-    root_module.begin_section('ns3_module_virtual_net_device')
-    ns3_module_virtual_net_device.register_methods(root_module)
-    
-    try:
-        import ns3_module_virtual_net_device__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_virtual_net_device__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_virtual_net_device')
-    root_module.begin_section('ns3_module_packet_sink')
-    ns3_module_packet_sink.register_methods(root_module)
-    
-    try:
-        import ns3_module_packet_sink__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_packet_sink__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_packet_sink')
-    root_module.begin_section('ns3_module_global_routing')
-    ns3_module_global_routing.register_methods(root_module)
-    
-    try:
-        import ns3_module_global_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_global_routing__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_global_routing')
-    root_module.begin_section('ns3_module_stats')
-    ns3_module_stats.register_methods(root_module)
-    
-    try:
-        import ns3_module_stats__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_stats__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_stats')
-    root_module.begin_section('ns3_module_list_routing')
-    ns3_module_list_routing.register_methods(root_module)
-    
-    try:
-        import ns3_module_list_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_list_routing__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_list_routing')
     root_module.begin_section('ns3_module_emu')
     ns3_module_emu.register_methods(root_module)
     
@@ -725,17 +725,17 @@
         ns3_module_bridge__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_bridge')
-    root_module.begin_section('ns3_module_onoff')
-    ns3_module_onoff.register_methods(root_module)
+    root_module.begin_section('ns3_module_global_routing')
+    ns3_module_global_routing.register_methods(root_module)
     
     try:
-        import ns3_module_onoff__local
+        import ns3_module_global_routing__local
     except ImportError:
         pass
     else:
-        ns3_module_onoff__local.register_methods(root_module)
+        ns3_module_global_routing__local.register_methods(root_module)
     
-    root_module.end_section('ns3_module_onoff')
+    root_module.end_section('ns3_module_global_routing')
     root_module.begin_section('ns3_module_udp_echo')
     ns3_module_udp_echo.register_methods(root_module)
     
@@ -747,17 +747,6 @@
         ns3_module_udp_echo__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_udp_echo')
-    root_module.begin_section('ns3_module_ping6')
-    ns3_module_ping6.register_methods(root_module)
-    
-    try:
-        import ns3_module_ping6__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_ping6__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_ping6')
     root_module.begin_section('ns3_module_nix_vector_routing')
     ns3_module_nix_vector_routing.register_methods(root_module)
     
@@ -780,6 +769,28 @@
         ns3_module_olsr__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_olsr')
+    root_module.begin_section('ns3_module_radvd')
+    ns3_module_radvd.register_methods(root_module)
+    
+    try:
+        import ns3_module_radvd__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_radvd__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_radvd')
+    root_module.begin_section('ns3_module_ping6')
+    ns3_module_ping6.register_methods(root_module)
+    
+    try:
+        import ns3_module_ping6__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_ping6__local.register_methods(root_module)
+    
+    root_module.end_section('ns3_module_ping6')
     root_module.begin_section('ns3_module_flow_monitor')
     ns3_module_flow_monitor.register_methods(root_module)
     
@@ -791,17 +802,6 @@
         ns3_module_flow_monitor__local.register_methods(root_module)
     
     root_module.end_section('ns3_module_flow_monitor')
-    root_module.begin_section('ns3_module_radvd')
-    ns3_module_radvd.register_methods(root_module)
-    
-    try:
-        import ns3_module_radvd__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_radvd__local.register_methods(root_module)
-    
-    root_module.end_section('ns3_module_radvd')
     root_module.begin_section('ns3_module_mesh')
     ns3_module_mesh.register_methods(root_module)
     
@@ -1039,6 +1039,17 @@
         ns3_module_common__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_common')
+    root_module.begin_section('ns3_module_contrib')
+    ns3_module_contrib.register_functions(root_module)
+    
+    try:
+        import ns3_module_contrib__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_contrib__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_contrib')
     root_module.begin_section('ns3_module_node')
     ns3_module_node.register_functions(root_module)
     
@@ -1050,17 +1061,72 @@
         ns3_module_node__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_node')
-    root_module.begin_section('ns3_module_contrib')
-    ns3_module_contrib.register_functions(root_module)
+    root_module.begin_section('ns3_module_tap_bridge')
+    ns3_module_tap_bridge.register_functions(root_module)
     
     try:
-        import ns3_module_contrib__local
+        import ns3_module_tap_bridge__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_tap_bridge__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_tap_bridge')
+    root_module.begin_section('ns3_module_v4ping')
+    ns3_module_v4ping.register_functions(root_module)
+    
+    try:
+        import ns3_module_v4ping__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_v4ping__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_v4ping')
+    root_module.begin_section('ns3_module_static_routing')
+    ns3_module_static_routing.register_functions(root_module)
+    
+    try:
+        import ns3_module_static_routing__local
     except ImportError:
         pass
     else:
-        ns3_module_contrib__local.register_functions(root_module)
+        ns3_module_static_routing__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_static_routing')
+    root_module.begin_section('ns3_module_packet_sink')
+    ns3_module_packet_sink.register_functions(root_module)
+    
+    try:
+        import ns3_module_packet_sink__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_packet_sink__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_packet_sink')
+    root_module.begin_section('ns3_module_stats')
+    ns3_module_stats.register_functions(root_module)
     
-    root_module.end_section('ns3_module_contrib')
+    try:
+        import ns3_module_stats__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_stats__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_stats')
+    root_module.begin_section('ns3_module_onoff')
+    ns3_module_onoff.register_functions(root_module)
+    
+    try:
+        import ns3_module_onoff__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_onoff__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_onoff')
     root_module.begin_section('ns3_module_point_to_point')
     ns3_module_point_to_point.register_functions(root_module)
     
@@ -1083,17 +1149,6 @@
         ns3_module_internet_stack__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_internet_stack')
-    root_module.begin_section('ns3_module_tap_bridge')
-    ns3_module_tap_bridge.register_functions(root_module)
-    
-    try:
-        import ns3_module_tap_bridge__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_tap_bridge__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_tap_bridge')
     root_module.begin_section('ns3_module_csma')
     ns3_module_csma.register_functions(root_module)
     
@@ -1105,6 +1160,28 @@
         ns3_module_csma__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_csma')
+    root_module.begin_section('ns3_module_list_routing')
+    ns3_module_list_routing.register_functions(root_module)
+    
+    try:
+        import ns3_module_list_routing__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_list_routing__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_list_routing')
+    root_module.begin_section('ns3_module_virtual_net_device')
+    ns3_module_virtual_net_device.register_functions(root_module)
+    
+    try:
+        import ns3_module_virtual_net_device__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_virtual_net_device__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_virtual_net_device')
     root_module.begin_section('ns3_module_wifi')
     ns3_module_wifi.register_functions(root_module)
     
@@ -1116,83 +1193,6 @@
         ns3_module_wifi__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_wifi')
-    root_module.begin_section('ns3_module_static_routing')
-    ns3_module_static_routing.register_functions(root_module)
-    
-    try:
-        import ns3_module_static_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_static_routing__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_static_routing')
-    root_module.begin_section('ns3_module_v4ping')
-    ns3_module_v4ping.register_functions(root_module)
-    
-    try:
-        import ns3_module_v4ping__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_v4ping__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_v4ping')
-    root_module.begin_section('ns3_module_virtual_net_device')
-    ns3_module_virtual_net_device.register_functions(root_module)
-    
-    try:
-        import ns3_module_virtual_net_device__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_virtual_net_device__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_virtual_net_device')
-    root_module.begin_section('ns3_module_packet_sink')
-    ns3_module_packet_sink.register_functions(root_module)
-    
-    try:
-        import ns3_module_packet_sink__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_packet_sink__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_packet_sink')
-    root_module.begin_section('ns3_module_global_routing')
-    ns3_module_global_routing.register_functions(root_module)
-    
-    try:
-        import ns3_module_global_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_global_routing__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_global_routing')
-    root_module.begin_section('ns3_module_stats')
-    ns3_module_stats.register_functions(root_module)
-    
-    try:
-        import ns3_module_stats__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_stats__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_stats')
-    root_module.begin_section('ns3_module_list_routing')
-    ns3_module_list_routing.register_functions(root_module)
-    
-    try:
-        import ns3_module_list_routing__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_list_routing__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_list_routing')
     root_module.begin_section('ns3_module_emu')
     ns3_module_emu.register_functions(root_module)
     
@@ -1215,17 +1215,17 @@
         ns3_module_bridge__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_bridge')
-    root_module.begin_section('ns3_module_onoff')
-    ns3_module_onoff.register_functions(root_module)
+    root_module.begin_section('ns3_module_global_routing')
+    ns3_module_global_routing.register_functions(root_module)
     
     try:
-        import ns3_module_onoff__local
+        import ns3_module_global_routing__local
     except ImportError:
         pass
     else:
-        ns3_module_onoff__local.register_functions(root_module)
+        ns3_module_global_routing__local.register_functions(root_module)
     
-    root_module.end_section('ns3_module_onoff')
+    root_module.end_section('ns3_module_global_routing')
     root_module.begin_section('ns3_module_udp_echo')
     ns3_module_udp_echo.register_functions(root_module)
     
@@ -1237,17 +1237,6 @@
         ns3_module_udp_echo__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_udp_echo')
-    root_module.begin_section('ns3_module_ping6')
-    ns3_module_ping6.register_functions(root_module)
-    
-    try:
-        import ns3_module_ping6__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_ping6__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_ping6')
     root_module.begin_section('ns3_module_nix_vector_routing')
     ns3_module_nix_vector_routing.register_functions(root_module)
     
@@ -1270,6 +1259,28 @@
         ns3_module_olsr__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_olsr')
+    root_module.begin_section('ns3_module_radvd')
+    ns3_module_radvd.register_functions(root_module)
+    
+    try:
+        import ns3_module_radvd__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_radvd__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_radvd')
+    root_module.begin_section('ns3_module_ping6')
+    ns3_module_ping6.register_functions(root_module)
+    
+    try:
+        import ns3_module_ping6__local
+    except ImportError:
+        pass
+    else:
+        ns3_module_ping6__local.register_functions(root_module)
+    
+    root_module.end_section('ns3_module_ping6')
     root_module.begin_section('ns3_module_flow_monitor')
     ns3_module_flow_monitor.register_functions(root_module)
     
@@ -1281,17 +1292,6 @@
         ns3_module_flow_monitor__local.register_functions(root_module)
     
     root_module.end_section('ns3_module_flow_monitor')
-    root_module.begin_section('ns3_module_radvd')
-    ns3_module_radvd.register_functions(root_module)
-    
-    try:
-        import ns3_module_radvd__local
-    except ImportError:
-        pass
-    else:
-        ns3_module_radvd__local.register_functions(root_module)
-    
-    root_module.end_section('ns3_module_radvd')
     root_module.begin_section('ns3_module_mesh')
     ns3_module_mesh.register_functions(root_module)
     
--- a/doc/howtos/howtos-application.h	Mon Nov 16 13:32:56 2009 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*!
-  \page application How to create a traffic generator ?
-  \anchor howtos-application
-
-  <b>Question:</b> How do I create a new traffic generator ?
-
-  <b>Answer:</b> It is possible to instanciate \ref ns3::Packet "Packet"
-  objects, schedule events, and call functions from any piece of code
-  in ns-3 so, technically, there is no single answer to the question of
-  how we can write a new traffic generator. However, the 
-  \ref ns3::Socket "Socket" API was really designed to be the single 
-  point of entry for traffic generators or traffic analysers and the
-  \ref ns3::Application "Application" class was designed to hold
-  together any number of sockets.
-
-  Implementing a new traffic generator thus boils down to:
-- implementing a new subclass of the \ref ns3::Application "Application"
-  base class
-- instanciate one or many sockets within that application
-- start scheduling events when \ref ns3::Application::StartApplication "StartApplication"
-  is called
-- stop scheduling events when \ref ns3::Application::StopApplication "StopApplication" 
-  is called
-- create packets and send them over one or many sockets in each event
-
-The following "random" generator generates packets separated by a random
-delay and with a random size.
-
-\code
-class RandomGenerator : public Application
-{
-public:
-  RandomGenerator ();
-  void SetDelay (RandomVariable delay);
-  void SetSize (RandomVariable size);
-  void SetRemote (std::string socketType, 
-                  Address remote);
-private:
-  virtual void StartApplication (void);
-  virtual void StopApplication (void);
-  void DoGenerate (void);
-
-  RandomVariable m_delay;
-  RandomVariable m_size;
-  Ptr<Socket> m_socket;
-};
-\endcode
-
-The socket is created in the SetRemote method:
-\code
-void 
-RandomGenerator::SetRemote (std::string socketType, 
-                            Address remote)
-{
-  TypeId tid = TypeId::LookupByName (socketType);
-  m_socket = Socket::CreateSocket (GetNode (), tid);
-  m_socket->Bind ();
-  m_socket->ShutdownRecv ();
-  m_socket->Connect (remote);
-}
-\endcode
-While the the crux of the logic is located in the DoGenerate method
-which is called from within StartApplication:
-\code
-void
-RandomGenerator::DoGenerate (void)
-{
-  m_next = Simulator::Schedule (Seconds (m_delay.GetValue ()), 
-				&RandomGenerator::DoGenerate, this);
-  Ptr<Packet> p = Create<Packet> (m_size.GetIntValue ());
-  m_socket->Send (p);
-}
-\endcode
-
-To make that application more integrated in ns-3, it needs an associated 
-helper class:
-\code
-class RandomAppHelper
-{
-public:
-  RandomAppHelper (std::string protocol, Address remote);
-  void SetPacketSize (RandomVariable packetSize);
-  void SetDelay (RandomVariable delay);
-  ApplicationContainer Install (NodeContainer nodes);
-private:
-  std::string m_protocol;
-  Address m_remote;
-  RandomVariable m_packetSize;
-  RandomVariable m_delay;
-};
-\endcode
-
-which could be trivially implemented as:
-\code
-ApplicationContainer 
-RandomAppHelper::Install (NodeContainer nodes)
-{
-  ApplicationContainer applications;
-  for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i)
-    {
-      Ptr<RandomAppHelper> app = CreateObject<RandomAppHelper> ();
-      app->SetSize (m_packetSize);
-      app->SetDelay (m_delay);
-      app->SetRemote (m_protocol, m_remote);
-      (*i)->AddApplication (app);
-      applications.Add (app);
-    }
-  return applications;
-}
-\endcode
-
-Despite being functional, this API is not very consistant with the style of 
-the other helper classes, all of which allow you to control the parameters
-of the underlying class through attributes and not explicit setters. The
-following API thus replaces the pair SetPacketSize/SetDelay with a single
-method SetAttribute:
-\code
-class RandomAppHelper
-{
-public:
-  RandomAppHelper (std::string protocol, Address remote);
-  void SetAttribute (std::string name, const AttributeValue &value);
-  ApplicationContainer Install (NodeContainer c);
-private:
-  std::string m_protocol;
-  Address m_remote;
-  ObjectFactory m_factory;
-};
-\endcode
-
-And which can be used as follows:
-\code
-RandomAppHelper app = RandomAppHelper ("ns3::TcpSocketFactory", 
-				       InetSocketAddress (Ipv4Address ("192.168.1.10"), 10));
-app.SetAttribute ("Delay", StringValue ("Constant:2.5"));
-app.SetAttribute ("Size", StringValue ("Constant:2100"));
-app.Install (nodes);
-\endcode
-
-The implementation, in this case, is not necessarily longer but its 
-simplicity hides a lot of behind-the-scenes complexity:
-
-\code
-void 
-RandomAppHelper::SetAttribute (std::string name, const AttributeValue &value)
-{
-  m_factory.Set (name, value);
-}
-ApplicationContainer 
-RandomAppHelper::Install (NodeContainer nodes)
-{
-  ApplicationContainer applications;
-  for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i)
-    {
-      Ptr<RandomAppHelper> app = m_factory.Create<RandomAppHelper> ();
-      app->SetRemote (m_socketType, m_remote);
-      (*i)->AddApplication (app);
-      applications.Add (app);
-    }
-  return applications;
-}
-\endcode
-
-The key difference between this implementation and the previous one
-is that this helper does not handle explicitely the attributes
-delay and packet size. Instead, it stores them in an 
-\ref ns3::ObjectFactory "ObjectFactory" object. This, of course,
-does not work magically, and requires extra support from the
-underlying RandomGenerator class. Specifically, it requires
-that the underlying RandomGenerator defines its attributes
-in its \ref ns3::TypeId "TypeId" in a new public static method:
-
-\code
-class RandomGenerator
-{
-public:
-  static TypeId GetTypeId (void);
-};
-\endcode
-
-The corresponding implementation is shown below:
-
-\code
-TypeId
-RandomGenerator::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("RandomGenerator")
-    .SetParent<Application> ()
-    .AddConstructor<RandomGenerator> ()
-    .AddAttribute ("Delay", "The delay between two packets (s)",
-		   RandomVariableValue (ConstantVariable (1.0)),
-		   MakeRandomVariableAccessor (&RandomGenerator::m_delay),
-		   MakeRandomVariableChecker ())
-    .AddAttribute ("PacketSize", "The size of each packet (bytes)",
-		   RandomVariableValue (ConstantVariable (2000)),
-		   MakeRandomVariableAccessor (&RandomGenerator::m_size),
-		   MakeRandomVariableChecker ())
-    ;
-  return tid;
-}   
-\endcode
-
-*/
--- a/doc/howtos/howtos-callbacks.h	Mon Nov 16 13:32:56 2009 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*!
-\page callbacks Using ns-3 callbacks
-\anchor howtos-callbacks
-
-\section null_callbacks Null Callbacks
-
-<b>Question:</b> The API I am using calls for using a callback (in the 
-function signature), but I do not
-want to provide one.  Is there a way to provide a null callback?
-
-<b>Answer:</b> Use the ns3::MakeNullCallback construct:
-\code
-template<typename R>
-Callback< R, T1, T2, T3, T4, T5, T6 > ns3::MakeNullCallback (void)
-\endcode
-
-Example usage:  The ns3::Socket class uses callbacks to indicate completion
-of events such as a successful TCP connect().  These callbacks are set
-in the following function:
-\code
-  void Socket::SetConnectCallback (Callback<void, Ptr<Socket> > connectionSucceeded,
-                        Callback<void, Ptr<Socket> > connectionFailed,
-                        Callback<void, Ptr<Socket> > halfClose);
-
-\endcode
-But suppose you do not care about registering a callback for the 
-halfClose event (but you want to register one for the 
-connectionSucceeded and connectionFailed cases).  In that case, you
-can pass a null callback as the third argument.  You just need to
-pass a callback with the matching signature, as follows:
-\code
-  localSocket->SetConnectCallback (
-  MakeCallback (&ConnectionSucceededCallback),
-  MakeCallback (&ConnectionFailedCallback),
-  MakeNullCallback<void, Ptr<Socket> > () );
-\endcode
-
-*/
--- a/doc/howtos/howtos-net-device.h	Mon Nov 16 13:32:56 2009 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/*!
-  \page net-device How to create a new OSI layer 1 + 2 implementation ?
-  \anchor howtos-net-device
-
-  <b>Question:</b> How do I integrate a new OSI layer 1 + 2 implementation ?
-
-  <b>Answer:</b> The OSI layers 1 and 2 are represented by the ns3::NetDevice
-  and ns3::Channel classes. To plug transparently in ns-3, a new layer 1+2 model
-  thus simply needs to provide two new subclasses of these two base classes.
-
-  To make that subclassing process easy, two skeleton classes are provided in
-  the src/node directory: simple-net-device.h (ns3::SimpleNetDevice) and 
-  simple-channel.h (ns3::SimpleChannel) implement a broadcast passthru medium 
-  using 48bit MAC addresses without any kind of MAC access algorithm or PHY 
-  layer modeling.
-
-  The ns3::SimpleChannel class is really very simple: it provides
-  an implementation for the ns3::Channel::GetNDevices and ns3::Channel::GetDevice
-  methods defined in the Channel base class and, then defines the channel-specific
-  send and add methods:
-- The Add method is used by SimpleNetDevice::SetChannel to register a new 
-  SimpleNetDevice with its associated channel.
-- The Send method is used by SimpleNetDevice::Send to send a packet over the
-  broadcast medium and ensure that it gets delivered to all associated devices
-  (except the sender).
-
-\code
-class SimpleChannel : public Channel
-{
-public:
-  static TypeId GetTypeId (void);
-  SimpleChannel ();
-
-  void Send (Ptr<Packet> p, uint16_t protocol, Mac48Address to, Mac48Address from,
-	     Ptr<SimpleNetDevice> sender);
-
-  void Add (Ptr<SimpleNetDevice> device);
-
-  // inherited from ns3::Channel
-  virtual uint32_t GetNDevices (void) const;
-  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
-
-private:
-  std::vector<Ptr<SimpleNetDevice> > m_devices;
-};
-\endcode
-
-The SimpleNetDevice class is also trivial since it implements no special
-MAC-layer processing:
-\code
-class SimpleNetDevice : public NetDevice
-{
-public:
-  static TypeId GetTypeId (void);
-  SimpleNetDevice ();
-
-  void Receive (Ptr<Packet> packet, uint16_t protocol, Mac48Address to, Mac48Address from);
-  void SetChannel (Ptr<SimpleChannel> channel);
-  void SetAddress (Mac48Address address);
-
-  // inherited from NetDevice base class.
-  virtual void SetName(const std::string name);
-  ...
-};
-\endcode
-
-The code below illustrates how the three model-specific methods defined above are
-implemented:
-
-\code
-void 
-SimpleNetDevice::Receive (Ptr<Packet> packet, uint16_t protocol, 
-			  Mac48Address to, Mac48Address from)
-{
-  if (to == m_address || to == Mac48Address::GetBroadcast ())
-    {
-      m_rxCallback (this, packet, protocol, from);
-    }
-}
-void 
-SimpleNetDevice::SetChannel (Ptr<SimpleChannel> channel)
-{
-  m_channel = channel;
-  m_channel->Add (this);
-}
-void 
-SimpleNetDevice::SetAddress (Mac48Address address)
-{
-  m_address = address;
-}
-\endcode
-
-Building a topology with such a device is then a matter of
-instanciating a set of SimpleNetDevice objects connected on a shared
-SimpleChannel:
-\code
-NodeContainer nodes;
-nodes.Create (10);
-Ptr<SimpleChannel> channel = CreateObject<SimpleChannel> ();
-for (uint32_t i = 0; i < nodes.GetN (); ++i)
-  {
-    CreateSimpleDevice (nodes.Get (i), channel);
-  }
-\endcode
-
-With the following CreateSimpleDevice function:
-\code
-static Ptr<SimpleNetDevice>
-CreateSimpleDevice (Ptr<Node> node, Ptr<SimpleChannel> channel)
-{
-  Ptr<SimpleNetDevice> device = CreateObject<SimpleNetDevice> ();
-  device->SetAddress (Mac48Address:Allocate ());
-  device->SetChannel (channel);
-  node->AddDevice (device);
-  return device;
-}
-\endcode
-
-Of course, ultimately, you need to provide a helper class for this new device and channel
-to save each user from having to re-implement their own CreateSimpleDevice helper 
-function:
-
-\code
-class SimpleHelper
-{
-public:
-  NetDeviceContainer Install (NodeContainer nodes, Ptr<SimpleChannel> channel);
-  NetDeviceContainer Install (NodeContainer nodes);
-};
-\endcode
-
-with the following straightforward implementation, inspired by the CreateSimpleDevice 
-function defined above:
-
-\code
-NetDeviceContainer
-SimpleHelper::Install (NodeContainer nodes, Ptr<SimpleChannel> channel)
-{
-  NetDeviceContainer devices;
-  for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i)
-    {
-      Ptr<SimpleNetDevice> dev = CreateObject<SimpleNetDevice> ();
-      dev->SetAddress (Mac48Address::Allocate ());
-      dev->SetChannel (channel);
-      (*i)->AddDevice (dev);
-      devices.Add (dev);
-    }
-  return devices;
-}
-NetDeviceContainer
-SimpleHelper::Install (NodeContainer nodes)
-{
-  return Install (nodes, CreateObject<SimpleChannel> ());
-}
-\endcode
-
-Of course, at some point, this device helper class should also contain a couple of 
-ascii and pcap tracing helper functions but, since the default SimpleNetDevice
-class we used as an example here does not report any trace event, it would
-be of little use.
-
-*/
--- a/doc/howtos/howtos-packet-header.h	Mon Nov 16 13:32:56 2009 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*!
-\page packet-header-trailer How to create a new type of protocol header or trailer
-\anchor howtos-packet-header-trailer
-
-<b>Question:</b> I want to implement a new protocol X which uses a new
-type of header Y. How do I implement and use this new header Y in ns-3 ?
-
-<b>Answer:</b> The key is to implement a new subclass of the ns3::Header
-base class to represent your protocol header:
-\code
-class YHeader : public Header
-{
-public:
-  // must be implemented to become a valid new header.
-  static TypeId GetTypeId (void);
-  virtual TypeId GetInstanceTypeId (void) const;
-  virtual uint32_t GetSerializedSize (void) const;
-  virtual void Serialize (Buffer::Iterator start) const;
-  virtual uint32_t Deserialize (Buffer::Iterator start);
-  virtual void Print (std::ostream &os) const;
-
-  // allow protocol-specific access to the header data.
-  void SetData (uint32_t data);
-  uint32_t GetData (void) const;
-private:
-  uint32_t m_data;
-};
-\endcode
-
-Once this class is implemented, you can easily store your protocol
-header into a packet:
-\code
-Ptr<Packet> p = ...;
-YHeader yHeader;
-yHeader.SetData (0xdeadbeaf);
-// copy the header into the packet
-p->AddHeader (yHeader);
-\endcode
-and get it out of a packet:
-\code
-Ptr<Packet> p = ...;
-YHeader yHeader;
-// copy the header from the packet
-p->RemoveHeader (yHeader);
-uint32_t data = yHeader.GetData ();
-\endcode
-
-The implementation of the new header is very simple. First, you need
-to give a TypeId to your YHeader class:
-\code
-TypeId
-YHeader::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("YHeader")
-    .SetParent<Header> ()
-    .AddConstructor<YHeader> ()
-  ;
-  return tid;
-}
-TypeId
-YHeader::GetInstanceTypeId (void)
-{
-  return GetTypeId ();
-}
-\endcode
-
-Then, you need to allow your header to serialize and deserialize itself
-to a byte buffer in its network representation. Here, our new protocol
-header contains first a 2-byte constant, and, then, the data field so,
-the total size of the header is 2+4=6 bytes.
-\code
-uint32_t 
-YHeader::GetSerializedSize (void) const
-{
-  return 6;
-}
-void 
-YHeader::Serialize (Buffer::Iterator start) const
-{
-  // The 2 byte-constant
-  start.WriteU8 (0xfe);
-  start.WriteU8 (0xef);
-  // The data.
-  start.WriteHtonU32 (m_data);
-}
-uint32_t 
-YHeader::Deserialize (Buffer::Iterator start)
-{
-  uint8_t tmp;
-  tmp = start.ReadU8 ();
-  NS_ASSERT (tmp == 0xfe);
-  tmp = start.ReadU8 ();
-  NS_ASSERT (tmp == 0xef);
-  m_data = start.ReadNtohU32 ();
-  return 6; // the number of bytes consumed.
-}
-\endcode
-
-Finally, to make sure that Packet::Print also prints the content
-of your header, just as it prints the content of the other
-headers of the system, you need to provide a Print method:
-\code
-void 
-YHeader::Print (std::ostream &os) const
-{
-  os << "data=" << m_data;
-}
-\endcode
-
-The code will look the same if you want to implement a trailer,
-that is, a protocol data structure which will be appended to the
-end of the packet, not its start: you need to make sure that
-you derive from the ns3::Trailer base class and that you call
-Packet::AddTrailer and Packet::RemoveTrailer. Another important
-detail is that you must make sure to rewind the iterator in your
-Serialize and Deserialize methods writing to or reading from 
-the underlying buffer.
-
-*/
--- a/doc/howtos/howtos.h	Mon Nov 16 13:32:56 2009 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-/*!
-\page howtos ns-3 HOWTOs
-\anchor howtos-anchor
-
-This is an organized set of frequently asked questions (FAQ) and HOWTOs
-for ns-3.  This complements the following wiki pages:
-
-- <a href="http://www.nsnam.org/wiki/index.php/User_FAQ">User FAQ</a>
-- <a href="http://www.nsnam.org/wiki/index.php/Developer_FAQ">Developer FAQ</a>
-
-Please consider contributing tips to either the wiki (yourself) or
-by submitting a patch to this maintained documentation.
-
-- \subpage callbacks
-- \subpage packet-header-trailer
-- \subpage net-device
-- \subpage application
-
-*/
-
--- a/doc/main.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/doc/main.h	Mon Nov 16 13:35:38 2009 +0300
@@ -6,29 +6,29 @@
  * <a href="http://www.doxygen.org">Doxygen</a>.
  * Doxygen is typically used for 
  * API documentation, and organizes such documentation across different
- * modules.   This project uses Doxygen both for building the manual around 
- * the API documentation,  and a separate GNU texinfo document is used for 
- * the manual.
+ * modules.   This project uses Doxygen for building the definitive
+ * maintained API documentation,  Separate GNU texinfo documents are used for 
+ * a tutorial, reference manual, and testing and validation manual.
  *
  * The ns-3 project documentation is organized as follows:
  *     - <b><a href="modules.html">modules</a></b>:  The "Modules" tab (above) 
  *       organizes  all of the public API and supporting manual text 
- *       along the  source code directory structure.   This forms the 
- *       "ns-3 manual", and it is available in HTML and PDF forms.
- *     - \ref howtos-anchor "HOWTOs": A set of HOWTOs and FAQs is
- *       maintained on another Doxygen "Related Page" 
- *     - <a href="http://www.nsnam.org/docs/tutorial/tutorial.html">tutorial</a>:  The ns-3 tutorial is a separate document maintained in <a href="http://www.gnu.org/software/texinfo/"> GNU Texinfo</a>. 
+ *       along the  source code directory structure.   
+ *     - <a href="http://www.nsnam.org/tutorials.html">tutorial</a>:  The ns-3 tutorial is a separate document maintained in <a href="http://www.gnu.org/software/texinfo/"> GNU Texinfo</a>. 
+ *     - <a href="http://www.nsnam.org/tutorials.html">Reference manual</a>:  The ns-3 reference manual is a separate document maintained in <a href="http://www.gnu.org/software/texinfo/"> GNU Texinfo</a>. 
+ *     - <a href="http://www.nsnam.org/tutorials.html">Testing and validation manual</a>:  The ns-3 testing and validation manual is a separate document maintained in <a href="http://www.gnu.org/software/texinfo/"> GNU Texinfo</a>. 
  *     - The <b><a href="http://www.nsnam.org/wiki/index.php/Main_Page">ns-3 wiki</a></b> 
  *       contains additional user-contributed material.  Some wiki-contributed
- *       material may migrate to and overlap with the Doxygen information.
+ *       material may migrate to and overlap with the Doxygen and manual information.
  *
  * \section install-sec Building the Documentation
  * 
  * ns-3 requires Doxygen version 1.5.4 or greater to fully build all items,
  * although earlier versions of Doxygen will mostly work.
  * 
- * Type "./waf doxygen" to build the documentation.  The doc/ directory contains
- * configuration for Doxygen (doxygen.conf and main.txt).  The Doxygen 
+ * Type "./waf --doxygen" or "./waf --doxygen-no-build" to build the 
+ *  documentation.  The doc/ directory contains
+ * configuration for Doxygen (doxygen.conf) and main.h.  The Doxygen 
  * build process puts html files into the doc/html/ directory, and latex 
  * filex into the doc/latex/ directory.
  * 
@@ -44,8 +44,14 @@
  *       to network simulations but shared by pretty much every model
  *       of a network component.
  *     - node: located in src/node. Defines the abstract interfaces which 
- *       must be implemented by every node and more specifically, by ipv4 nodes.       
+ *       must be implemented by every node and more specifically, by 
+ *       IPv4 and IPv6 nodes.       
  *     - devices: located in src/devices. Contains a set of MAC-level models
+ *     - InternetStack: located in src/internet-stack. Contains TCP/IP models.
+ *     - Applications: located in src/applications
+ *     - Routing:  located in src/routing; routing protocols.
+ *     - Mobility:  located in src/mobility; Mobility models for nodes
+ *     - Helper:  located in src/helper; Helper API for the simulator
  *
  * More detail can be found in the <b><a href="modules.html">Modules</a></b>
  * tab.
--- a/doc/manual/Makefile	Mon Nov 16 13:32:56 2009 +0300
+++ b/doc/manual/Makefile	Mon Nov 16 13:35:38 2009 +0300
@@ -32,10 +32,22 @@
 
 CHAPTERS = \
 	manual.texi \
+	animation.texi \
 	attributes.texi \
+	bridge.texi \
 	callbacks.texi \
 	csma.texi \
 	emulation.texi \
+	emu.texi \
+	flow-monitor.texi \
+	helpers.texi \
+	internet.texi \
+	ipv4.texi \
+	ipv6.texi \
+	log.texi \
+	manual.texi \
+	mesh.texi \
+	names.texi \
 	new-models.texi \
 	node.texi \
 	objects.texi \
@@ -43,11 +55,16 @@
 	output.texi \
 	packets.texi \
 	point-to-point.texi \
+	python.texi \
 	random.texi \
 	realtime.texi \
 	routing.texi \
+	simple.texi \
 	sockets.texi \
 	statistics.texi \
+	tap.texi \
+	tcp.texi \
+	tracing.texi \
 	troubleshoot.texi \
 	wifi.texi
 
@@ -64,7 +81,7 @@
 	$(TEXI2HTML) ${CSS} manual.texi
 
 manual/manual.html: version $(IMAGES) $(CHAPTERS)
-	$(TEXI2HTML) ${CSS} ${SPLIT} manual.texi
+	$(TEXI2HTML) ${CSS} ${SPLIT} --output manual manual.texi
 
 figures-clean:
 	rm -rf $(IMAGES)
--- a/doc/testing/Makefile	Mon Nov 16 13:32:56 2009 +0300
+++ b/doc/testing/Makefile	Mon Nov 16 13:35:38 2009 +0300
@@ -19,7 +19,13 @@
 CHAPTERS = \
 	testing.texi \
 	overview.texi \
+	background.texi \
+	testing-framework.texi \
+	how-to-write-tests.texi \
+	validation.texi \
+	random-variables.texi \
 	propagation-loss.texi \
+	references.texi \
 
 %.eps : %.dia; $(DIA) -t eps $< -e $@
 %.png : %.dia; $(DIA) -t png $< -e $@
@@ -34,7 +40,7 @@
 	$(TEXI2HTML) ${CSS} testing.texi
 
 testing/testing.html: version $(IMAGES) $(CHAPTERS)
-	$(TEXI2HTML) ${CSS} ${SPLIT} testing.texi
+	$(TEXI2HTML) ${CSS} ${SPLIT} --output testing testing.texi
 
 figures-clean:
 	rm -rf $(IMAGES)
--- a/doc/tutorial/Makefile	Mon Nov 16 13:32:56 2009 +0300
+++ b/doc/tutorial/Makefile	Mon Nov 16 13:35:38 2009 +0300
@@ -27,7 +27,7 @@
 	$(TEXI2HTML) ${CSS} tutorial.texi
 
 split-html: 
-	$(TEXI2HTML) ${CSS} ${SPLIT} tutorial.texi
+	$(TEXI2HTML) ${CSS} ${SPLIT} --output tutorial tutorial.texi
 
 pdf:
 	$(TEXI2PDF) tutorial.texi
--- a/doc/tutorial/tutorial.texi	Mon Nov 16 13:32:56 2009 +0300
+++ b/doc/tutorial/tutorial.texi	Mon Nov 16 13:35:38 2009 +0300
@@ -64,7 +64,9 @@
 @end titlepage
 
 @c So the toc is printed at the start.
+@ifnottex
 @anchor{Full Table of Contents}
+@end ifnottex
 @contents
 
 @ifnottex
--- a/examples/emulation/emu-ping.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/examples/emulation/emu-ping.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -186,8 +186,8 @@
   Ptr<V4Ping> app = CreateObject<V4Ping> ();
   app->SetAttribute ("Remote", Ipv4AddressValue (remoteIp));
   node->AddApplication (app);
-  app->Start (Seconds (1.0));
-  app->Stop (Seconds (5.0));
+  app->SetStartTime (Seconds (1.0));
+  app->SetStopTime (Seconds (5.0));
 
   //
   // Give the application a name.  This makes life much easier when constructing
--- a/examples/ipv6/radvd-two-prefix.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/examples/ipv6/radvd-two-prefix.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -183,8 +183,8 @@
   radvd->AddConfiguration (routerInterface2);
 
   r->AddApplication (radvd);
-  radvd->Start (Seconds (1.0));
-  radvd->Stop (Seconds (2.0));
+  radvd->SetStartTime (Seconds (1.0));
+  radvd->SetStopTime (Seconds (2.0));
 
   /* Create a Ping6 application to send ICMPv6 echo request from n0 to n1 via R */
   uint32_t packetSize = 1024;
--- a/examples/ipv6/radvd.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/examples/ipv6/radvd.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -123,8 +123,8 @@
   radvd->AddConfiguration (routerInterface2);
 
   r->AddApplication (radvd);
-  radvd->Start (Seconds (1.0));
-  radvd->Stop (Seconds (10.0));
+  radvd->SetStartTime (Seconds (1.0));
+  radvd->SetStopTime (Seconds (10.0));
 
   /* Create a Ping6 application to send ICMPv6 echo request from n0 to n1 via R */
   uint32_t packetSize = 1024;
--- a/examples/stats/README	Mon Nov 16 13:32:56 2009 +0300
+++ b/examples/stats/README	Mon Nov 16 13:35:38 2009 +0300
@@ -14,3 +14,23 @@
 available online on the ns-3 wiki at:
 
 http://www.nsnam.org/wiki/index.php/Statistical_Framework_for_Network_Simulation
+
+*** Using ns-3 with the OMNeT++ analysis tool ***
+
+The stat framework can write out the result in a format that is compatible with the
+output format of OMNeT++ 4 Discrete Event Simulator Framework.
+Use the wifi-example-omnet.sh script to generate the results in OMNeT++ format.
+
+If you want to analyse the results with OMNeT++'s result analyser tool:
+a) Download OMNeT++ 4 and install it. Start the IDE. (www.omnetpp.org)
+b) If you do not want to install the whole simulator framework, there is a seperate 
+   package which contains only the analysis tool from the OMNeT++ package.
+   You can download it from http://omnetpp.org/download/release/omnetpp-scave.tgz
+
+Once you are running the OMNeT++ IDE or the separate analysis tool (SCAVE)
+- Choose File|Import...|Existing Projects into Workspace, then click [Next]
+- Select root directory. (choose the examples/stats directory) and click [Finish]
+
+Double click the wifi-example-omnet.anf in the opened project and select 
+the Chart page to see the created chart. Experiment with the analysis tool and read its
+documentation: http://omnetpp.org/doc/omnetpp40/userguide/ch09.html
--- a/examples/stats/wifi-example-sim.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/examples/stats/wifi-example-sim.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -32,6 +32,8 @@
 
 // #define NS3_LOG_ENABLE // Now defined by Makefile
 
+#include <ctime>
+
 #include <sstream>
 
 #include "ns3/core-module.h"
@@ -165,12 +167,12 @@
   Ptr<Node> appSource = NodeList::GetNode(0);  
   Ptr<Sender> sender = CreateObject<Sender>();
   appSource->AddApplication(sender);
-  sender->Start(Seconds(1));
+  sender->SetStartTime(Seconds(1));
 
   Ptr<Node> appSink = NodeList::GetNode(1);  
   Ptr<Receiver> receiver = CreateObject<Receiver>();
   appSink->AddApplication(receiver);
-  receiver->Start(Seconds(0));
+  receiver->SetStartTime(Seconds(0));
 
   //  Config::Set("/NodeList/*/ApplicationList/*/$Sender/Destination",
   //              Ipv4AddressValue("192.168.0.2"));
@@ -200,6 +202,7 @@
   Ptr<CounterCalculator<uint32_t> > totalTx =
     CreateObject<CounterCalculator<uint32_t> >();
   totalTx->SetKey("wifi-tx-frames");
+  totalTx->SetContext("node[0]");
   Config::Connect("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
                   MakeBoundCallback(&TxCallback, totalTx));
   data.AddDataCalculator(totalTx);
@@ -211,6 +214,7 @@
   Ptr<PacketCounterCalculator> totalRx =
     CreateObject<PacketCounterCalculator>();
   totalRx->SetKey("wifi-rx-frames");
+  totalRx->SetContext("node[1]");
   Config::Connect("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
                   MakeCallback(&PacketCounterCalculator::PacketUpdate,
                                totalRx));
@@ -225,6 +229,7 @@
   Ptr<PacketCounterCalculator> appTx =
     CreateObject<PacketCounterCalculator>();
   appTx->SetKey("sender-tx-packets");
+  appTx->SetContext("node[0]");
   Config::Connect("/NodeList/0/ApplicationList/*/$Sender/Tx",
                   MakeCallback(&PacketCounterCalculator::PacketUpdate,
                                     appTx));
@@ -237,6 +242,7 @@
   Ptr<CounterCalculator<> > appRx =
     CreateObject<CounterCalculator<> >();
   appRx->SetKey("receiver-rx-packets");
+  appRx->SetContext("node[1]");
   receiver->SetCounter(appRx);
   data.AddDataCalculator(appRx);
 
@@ -263,6 +269,7 @@
   Ptr<PacketSizeMinMaxAvgTotalCalculator> appTxPkts =
     CreateObject<PacketSizeMinMaxAvgTotalCalculator>();
   appTxPkts->SetKey("tx-pkt-size");
+  appTxPkts->SetContext("node[0]");
   Config::Connect("/NodeList/0/ApplicationList/*/$Sender/Tx",
                   MakeCallback
                     (&PacketSizeMinMaxAvgTotalCalculator::PacketUpdate,
@@ -277,6 +284,7 @@
   Ptr<TimeMinMaxAvgTotalCalculator> delayStat =
     CreateObject<TimeMinMaxAvgTotalCalculator>();
   delayStat->SetKey("delay");
+  delayStat->SetContext(".");
   receiver->SetDelayTracker(delayStat);
   data.AddDataCalculator(delayStat);
 
--- a/examples/tutorial/fifth.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/examples/tutorial/fifth.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -210,8 +210,8 @@
   Ptr<MyApp> app = CreateObject<MyApp> ();
   app->Setup (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("1Mbps"));
   nodes.Get (0)->AddApplication (app);
-  app->Start (Seconds (1.));
-  app->Stop (Seconds (20.));
+  app->SetStartTime (Seconds (1.));
+  app->SetStopTime (Seconds (20.));
 
   devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeCallback (&RxDrop));
 
--- a/examples/wireless/wifi-simple-adhoc.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/examples/wireless/wifi-simple-adhoc.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -80,7 +80,7 @@
     {
       socket->Send (Create<Packet> (pktSize));
       Simulator::Schedule (pktInterval, &GenerateTraffic, 
-                           socket, pktSize,pktCount-1, pktInterval);
+                                      socket, pktSize,pktCount-1, pktInterval);
     }
   else
     {
@@ -187,8 +187,9 @@
   // Output what we are doing
   NS_LOG_UNCOND ("Testing " << numPackets  << " packets sent with receiver rss " << rss );
 
-  Simulator::Schedule (Seconds (1.0), &GenerateTraffic, 
-                       source, packetSize, numPackets, interPacketInterval);
+  Simulator::ScheduleWithContext (source->GetNode ()->GetId (),
+                                  Seconds (1.0), &GenerateTraffic, 
+                                  source, packetSize, numPackets, interPacketInterval);
 
   Simulator::Run ();
   Simulator::Destroy ();
--- a/examples/wireless/wifi-simple-infra.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/examples/wireless/wifi-simple-infra.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -200,8 +200,9 @@
   // Output what we are doing
   NS_LOG_UNCOND ("Testing " << numPackets  << " packets sent with receiver rss " << rss );
 
-  Simulator::Schedule (Seconds (1.0), &GenerateTraffic, 
-                       source, packetSize, numPackets, interPacketInterval);
+  Simulator::ScheduleWithContext (source->GetNode ()->GetId (),
+                                  Seconds (1.0), &GenerateTraffic, 
+                                  source, packetSize, numPackets, interPacketInterval);
 
   Simulator::Stop (Seconds (30.0));
   Simulator::Run ();
--- a/examples/wireless/wifi-simple-interference.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/examples/wireless/wifi-simple-interference.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -245,11 +245,13 @@
   // Output what we are doing
   NS_LOG_UNCOND ("Primary packet RSS=" << Prss << " dBm and interferer RSS=" << Irss << " dBm at time offset=" << delta << " ms");
 
-  Simulator::Schedule (Seconds (startTime), &GenerateTraffic, 
-                       source, PpacketSize, numPackets, interPacketInterval);
+  Simulator::ScheduleWithContext (source->GetNode ()->GetId (),
+                                  Seconds (startTime), &GenerateTraffic, 
+                                  source, PpacketSize, numPackets, interPacketInterval);
 
-  Simulator::Schedule (Seconds (startTime + delta/1000000.0), &GenerateTraffic, 
-                       interferer, IpacketSize, numPackets, interPacketInterval);
+  Simulator::ScheduleWithContext (interferer->GetNode ()->GetId (),
+                                  Seconds (startTime + delta/1000000.0), &GenerateTraffic, 
+                                  interferer, IpacketSize, numPackets, interPacketInterval);
 
   Simulator::Run ();
   Simulator::Destroy ();
--- a/src/applications/radvd/radvd-interface.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/applications/radvd/radvd-interface.h	Mon Nov 16 13:35:38 2009 +0300
@@ -22,7 +22,7 @@
 #define RADVD_INTERFACE_H
 
 #include <list>
-
+#include "ns3/simple-ref-count.h"
 #include "radvd-prefix.h"
 
 namespace ns3
@@ -33,7 +33,7 @@
  * \class RadvdInterface
  * \brief Radvd interface configuration.
  */
-class RadvdInterface : public RefCountBase
+class RadvdInterface : public SimpleRefCount<RadvdInterface>
 {
   public:
     /**
--- a/src/applications/radvd/radvd-prefix.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/applications/radvd/radvd-prefix.h	Mon Nov 16 13:35:38 2009 +0300
@@ -24,6 +24,7 @@
 #include <stdint.h>
 
 #include "ns3/ipv6-address.h"
+#include "ns3/simple-ref-count.h"
 
 namespace ns3
 {
@@ -33,7 +34,7 @@
  * \class RadvdPrefix
  * \brief Router prefix for radvd application.
  */
-class RadvdPrefix : public RefCountBase
+class RadvdPrefix : public SimpleRefCount<RadvdPrefix>
 {
   public:
     /**
--- a/src/common/ascii-writer.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/common/ascii-writer.h	Mon Nov 16 13:35:38 2009 +0300
@@ -23,7 +23,7 @@
 
 #include <stdint.h>
 #include <ostream>
-#include "ns3/ref-count-base.h"
+#include "ns3/simple-ref-count.h"
 #include "ns3/ptr.h"
 
 namespace ns3 {
@@ -35,7 +35,7 @@
  *
  * \brief Ascii output
  */
-class AsciiWriter : public RefCountBase
+class AsciiWriter : public SimpleRefCount<AsciiWriter>
 {
 public:
   static Ptr<AsciiWriter> Get (std::ostream &os);
--- a/src/common/packet.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/common/packet.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -112,21 +112,6 @@
 }
 
 
-void 
-Packet::Ref (void) const
-{
-  m_refCount++;
-}
-void 
-Packet::Unref (void) const
-{
-  m_refCount--;
-  if (m_refCount == 0)
-    {
-      delete this;
-    }
-}
-
 Ptr<Packet> 
 Packet::Copy (void) const
 {
@@ -141,8 +126,7 @@
     m_byteTagList (),
     m_packetTagList (),
     m_metadata (m_globalUid, 0),
-    m_nixVector (0),
-    m_refCount (1)
+    m_nixVector (0)
 {
   m_globalUid++;
 }
@@ -151,8 +135,7 @@
   : m_buffer (o.m_buffer),
     m_byteTagList (o.m_byteTagList),
     m_packetTagList (o.m_packetTagList),
-    m_metadata (o.m_metadata),
-    m_refCount (1)
+    m_metadata (o.m_metadata)
 {
   o.m_nixVector ? m_nixVector = o.m_nixVector->Copy () 
                 : m_nixVector = 0;
@@ -179,8 +162,7 @@
     m_byteTagList (),
     m_packetTagList (),
     m_metadata (m_globalUid, size),
-    m_nixVector (0),
-    m_refCount (1)
+    m_nixVector (0)
 {
   m_globalUid++;
 }
@@ -189,8 +171,7 @@
     m_byteTagList (),
     m_packetTagList (),
     m_metadata (m_globalUid, size),
-    m_nixVector (0),
-    m_refCount (1)
+    m_nixVector (0)
 {
   m_globalUid++;
   m_buffer.AddAtStart (size);
@@ -204,8 +185,7 @@
     m_byteTagList (byteTagList),
     m_packetTagList (packetTagList),
     m_metadata (metadata),
-    m_nixVector (0),
-    m_refCount (1)
+    m_nixVector (0)
 {}
 
 Ptr<Packet>
--- a/src/common/packet.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/common/packet.h	Mon Nov 16 13:35:38 2009 +0300
@@ -32,7 +32,6 @@
 #include "ns3/callback.h"
 #include "ns3/assert.h"
 #include "ns3/ptr.h"
-#include "ns3/deprecated.h"
 
 namespace ns3 {
 
@@ -199,12 +198,9 @@
  * The performance aspects of the Packet API are discussed in 
  * \ref packetperf
  */
-class Packet 
+class Packet : public SimpleRefCount<Packet>
 {
 public:
-  void Ref (void) const;
-  void Unref (void) const;
-
   Ptr<Packet> Copy (void) const;
 
   /**
@@ -541,7 +537,6 @@
   /* Please see comments above about nix-vector */
   Ptr<NixVector> m_nixVector;
 
-  mutable uint32_t m_refCount;
   static uint32_t m_globalUid;
 };
 
--- a/src/common/pcap-file-test-suite.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/common/pcap-file-test-suite.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -107,7 +107,7 @@
   std::stringstream filename;
   uint32_t n = rand ();
   filename << n;
-  m_testFilename = "/tmp/" + filename.str () + ".pcap";
+  m_testFilename = GetTempDir () + filename.str () + ".pcap";
 }
 
 void
@@ -218,7 +218,7 @@
   std::stringstream filename;
   uint32_t n = rand ();
   filename << n;
-  m_testFilename = "/tmp/" + filename.str () + ".pcap";
+  m_testFilename = GetTempDir () + filename.str () + ".pcap";
 }
 
 void
@@ -317,7 +317,7 @@
   std::stringstream filename;
   uint32_t n = rand ();
   filename << n;
-  m_testFilename = "/tmp/" + filename.str () + ".pcap";
+  m_testFilename = GetTempDir () + filename.str () + ".pcap";
 }
 
 void
@@ -416,7 +416,7 @@
   std::stringstream filename;
   uint32_t n = rand ();
   filename << n;
-  m_testFilename = "/tmp/" + filename.str () + ".pcap";
+  m_testFilename = GetTempDir () + filename.str () + ".pcap";
 }
 
 void
@@ -607,7 +607,7 @@
   std::stringstream filename;
   uint32_t n = rand ();
   filename << n;
-  m_testFilename = "/tmp/" + filename.str () + ".pcap";
+  m_testFilename = GetTempDir () + filename.str () + ".pcap";
 }
 
 void
--- a/src/contrib/flow-monitor/flow-classifier.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/flow-monitor/flow-classifier.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -28,6 +28,8 @@
 {
 }
 
+FlowClassifier::~FlowClassifier ()
+{}
 
 FlowId
 FlowClassifier::GetNewFlowId ()
--- a/src/contrib/flow-monitor/flow-classifier.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/flow-monitor/flow-classifier.h	Mon Nov 16 13:35:38 2009 +0300
@@ -21,7 +21,7 @@
 #ifndef __FLOW_CLASSIFIER_H__
 #define __FLOW_CLASSIFIER_H__
 
-#include "ns3/ref-count-base.h"
+#include "ns3/simple-ref-count.h"
 #include <ostream>
 
 namespace ns3 {
@@ -39,13 +39,14 @@
 /// statistics reference only those abstract identifiers in order to
 /// keep the core architecture generic and not tied down to any
 /// particular flow capture method or classification system.
-class FlowClassifier : public RefCountBase
+class FlowClassifier : public SimpleRefCount<FlowClassifier>
 {
   FlowId m_lastNewFlowId;
 
 public:
 
   FlowClassifier ();
+  virtual ~FlowClassifier ();
 
   virtual void SerializeToXmlStream (std::ostream &os, int indent) const = 0;
 
--- a/src/contrib/flow-monitor/flow-probe.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/flow-monitor/flow-probe.h	Mon Nov 16 13:35:38 2009 +0300
@@ -24,7 +24,7 @@
 #include <map>
 #include <vector>
 
-#include "ns3/ref-count-base.h"
+#include "ns3/simple-ref-count.h"
 #include "ns3/flow-classifier.h"
 #include "ns3/nstime.h"
 
@@ -36,14 +36,14 @@
 /// in a specific point of the simulated space, report those events to
 /// the global FlowMonitor, and collect its own flow statistics
 /// regarding only the packets that pass through that probe.
-class FlowProbe : public RefCountBase
+class FlowProbe : public SimpleRefCount<FlowProbe>
 {
 protected:
   
   FlowProbe (Ptr<FlowMonitor> flowMonitor);
   
 public:
-  ~FlowProbe ();
+  virtual ~FlowProbe ();
 
   struct FlowStats
   {
--- a/src/contrib/flow-monitor/ipv4-flow-probe.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/flow-monitor/ipv4-flow-probe.h	Mon Nov 16 13:35:38 2009 +0300
@@ -41,7 +41,7 @@
   
 public:
   Ipv4FlowProbe (Ptr<FlowMonitor> monitor, Ptr<Ipv4FlowClassifier> classifier, Ptr<Node> node);
-  ~Ipv4FlowProbe ();
+  virtual ~Ipv4FlowProbe ();
 
   /// \brief enumeration of possible reasons why a packet may be dropped
   enum DropReason 
--- a/src/contrib/net-anim/animation-interface.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/net-anim/animation-interface.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -21,9 +21,15 @@
 #include <stdio.h>
 #include <sstream>
 
+#include "ns3/net-anim-config.h"
+
 // Socket related includes
-#include <sys/socket.h>
-#include <netinet/in.h>
+#if defined(HAVE_SYS_SOCKET_H) && defined(HAVE_NETINET_IN_H)
+# include <sys/socket.h>
+# include <netinet/in.h>
+#else
+#include <fcntl.h>
+#endif
 
 // ns3 includes
 #include "ns3/animation-interface.h"
@@ -58,6 +64,7 @@
 
 bool AnimationInterface::SetServerPort (uint16_t port)
 {
+#if defined(HAVE_SYS_SOCKET_H) && defined(HAVE_NETINET_IN_H)
   int s = socket (AF_INET, SOCK_STREAM, 0);
   struct sockaddr_in addr;
   addr.sin_family = AF_INET;
@@ -77,6 +84,8 @@
   int t = 1;
   setsockopt (s, SOL_SOCKET, SO_LINGER, &t, sizeof(t));
   return true;
+#endif
+  return false;//never reached unless the above is disabled
 }
 
 bool AnimationInterface::SetInternalAnimation ()
--- a/src/contrib/net-anim/point-to-point-dumbbell-helper.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/net-anim/point-to-point-dumbbell-helper.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -21,10 +21,6 @@
 #include <iostream>
 #include <sstream>
 
-// Socket related includes
-#include <sys/socket.h>
-#include <netinet/in.h>
-
 // ns3 includes
 #include "ns3/animation-interface.h"
 #include "ns3/point-to-point-dumbbell-helper.h"
--- a/src/contrib/net-anim/wscript	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/net-anim/wscript	Mon Nov 16 13:35:38 2009 +0300
@@ -1,5 +1,11 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
+def configure(conf):
+    conf.check(header_name='sys/socket.h', define_name='HAVE_SYS_SOCKET_H')
+    conf.check(header_name='netinet/in.h', define_name='HAVE_NETINET_IN_H')
+    conf.write_config_header('ns3/net-anim-config.h', top=True)
+
+
 def build(bld):
     obj = bld.create_ns3_module('net-anim')
     obj.source = [
--- a/src/contrib/stats/basic-data-calculators.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/stats/basic-data-calculators.h	Mon Nov 16 13:35:38 2009 +0300
@@ -29,7 +29,8 @@
   //------------------------------------------------------------
   //--------------------------------------------
   template <typename T  = uint32_t>
-  class MinMaxAvgTotalCalculator : public DataCalculator {
+  class MinMaxAvgTotalCalculator : public DataCalculator,
+                                   public StatisticalSummary {
   public:
     MinMaxAvgTotalCalculator();
     virtual ~MinMaxAvgTotalCalculator();
@@ -38,6 +39,15 @@
 
     virtual void Output(DataOutputCallback &callback) const;
 
+    long getCount() const { return m_count; }
+    double getSum() const { return m_total; }
+    double getMin() const { return m_min; }
+    double getMax() const { return m_max; }
+    double getMean() const { return m_total / (double)m_count; }
+    double getStddev() const { return NaN; } // unsupported
+    double getVariance() const { return NaN; } // unsupported
+    double getSqrSum() const { return NaN; } // unsupported
+
   protected:
     virtual void DoDispose(void);
 
@@ -86,23 +96,15 @@
     }
     // end MinMaxAvgTotalCalculator::Update
   }
+
   template <typename T>
   void
   MinMaxAvgTotalCalculator<T>::Output(DataOutputCallback &callback) const
   {
-    callback.OutputSingleton(m_key, "count", m_count);
-    if (m_count > 0) {
-      callback.OutputSingleton(m_key, "total", m_total);
-      callback.OutputSingleton(m_key, "average", m_total/m_count);
-      callback.OutputSingleton(m_key, "max", m_max);
-      callback.OutputSingleton(m_key, "min", m_min);
-    }
-    // end MinMaxAvgTotalCalculator::Output
+      callback.OutputStatistic(m_context, m_key, this);
   }
 
 
-
-
   //------------------------------------------------------------
   //--------------------------------------------
   template <typename T  = uint32_t>
@@ -178,7 +180,7 @@
   void
   CounterCalculator<T>::Output(DataOutputCallback &callback) const
   {
-    callback.OutputSingleton(m_key, "count", m_count);
+    callback.OutputSingleton(m_context, m_key, m_count);
     // end CounterCalculator::Output
   }
 
--- a/src/contrib/stats/data-calculator.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/stats/data-calculator.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -27,6 +27,8 @@
 
 NS_LOG_COMPONENT_DEFINE("DataCalculator");
 
+static double zero = 0;
+const double ns3::NaN = zero / zero;
 
 //--------------------------------------------------------------
 //----------------------------------------------
@@ -70,6 +72,20 @@
 
 //----------------------------------------------
 void
+DataCalculator::SetContext(const std::string context)
+{
+  m_context = context;
+  // end DataCalculator::SetContext
+}
+
+std::string
+DataCalculator::GetContext() const
+{
+  return m_context;
+  // end DataCalculator::GetContext
+}
+//----------------------------------------------
+void
 DataCalculator::Enable()
 {
   m_enabled = true;
--- a/src/contrib/stats/data-calculator.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/stats/data-calculator.h	Mon Nov 16 13:35:38 2009 +0300
@@ -26,9 +26,62 @@
 #include "ns3/simulator.h"
 
 namespace ns3 {
+  extern const double NaN;
+  inline bool isNaN(double x) { return x != x; }
 
   class DataOutputCallback;
 
+  class StatisticalSummary {
+	  public:
+	    /**
+	     * Destructor
+	     */
+	    virtual ~StatisticalSummary () 
+	    {
+	    }
+	    /**
+	     * Returns the number of the observations.
+	     */
+	    virtual long getCount() const = 0;
+
+	    /**
+	     * Returns the sum of the values.
+	     * @see getWeightedSum()
+	     */
+	    virtual double getSum() const = 0;
+
+	    /**
+	     * Returns the sum of the squared values.
+	     * @see getWeightedSqrSum()
+	     */
+	    virtual double getSqrSum() const = 0;
+
+	    /**
+	     * Returns the minimum of the values.
+	     */
+	    virtual double getMin() const = 0;
+
+	    /**
+	     * Returns the maximum of the values.
+	     */
+	    virtual double getMax() const = 0;
+
+	    /**
+	     * Returns the mean of the (weighted) observations.
+	     */
+	    virtual double getMean() const = 0;
+
+	    /**
+	     * Returns the standard deviation of the (weighted) observations.
+	     */
+	    virtual double getStddev() const = 0;
+
+	    /**
+	     * Returns the variance of the (weighted) observations.
+	     */
+	    virtual double getVariance() const = 0;
+  };
+
   //------------------------------------------------------------
   //--------------------------------------------
   class DataCalculator : public Object {
@@ -43,6 +96,9 @@
     void SetKey(const std::string key);
     std::string GetKey() const;
 
+    void SetContext(const std::string context);
+    std::string GetContext() const;
+
     virtual void Start(const Time& startTime);
     virtual void Stop(const Time& stopTime);
 
@@ -52,6 +108,7 @@
     bool m_enabled;  // Descendant classes *must* check & respect m_enabled!
 
     std::string m_key;
+    std::string m_context;
 
     virtual void DoDispose(void);
 
--- a/src/contrib/stats/data-output-interface.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/stats/data-output-interface.h	Mon Nov 16 13:35:38 2009 +0300
@@ -23,6 +23,7 @@
 
 #include "ns3/object.h"
 #include "ns3/nstime.h"
+#include "ns3/data-calculator.h"
 
 namespace ns3 {
 
@@ -52,6 +53,10 @@
   public:
     virtual ~DataOutputCallback() {}
 
+    virtual void OutputStatistic(std::string key,
+                                 std::string variable,
+                                 const StatisticalSummary *statSum) = 0;
+
     virtual void OutputSingleton(std::string key,
                                  std::string variable,
                                  int val) = 0;
--- a/src/contrib/stats/omnet-data-output.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/stats/omnet-data-output.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -19,6 +19,7 @@
  */
 
 #include <fstream>
+#include <cstdlib>
 
 #include "ns3/log.h"
 #include "ns3/nstime.h"
@@ -54,26 +55,31 @@
 }
 
 //----------------------------------------------
+
+inline bool isNumeric(const std::string& s) {
+  char *endp;
+  strtod(s.c_str(), &endp);
+  return endp == s.c_str() + s.size();
+}
+
 void
 OmnetDataOutput::Output(DataCollector &dc)
 {
 
   std::ofstream scalarFile;
-  std::string fn = m_filePrefix + ".sca";
-  scalarFile.open(fn.c_str(), std::ios_base::app);
+  std::string fn = m_filePrefix +"-"+dc.GetRunLabel()+ ".sca";
+  scalarFile.open(fn.c_str(), std::ios_base::out);
 
-  scalarFile << std::endl;
+  // TODO add timestamp to the runlevel
   scalarFile << "run " << dc.GetRunLabel() << std::endl;
-  scalarFile << std::endl;
   scalarFile << "attr experiment \"" << dc.GetExperimentLabel()
             << "\"" << std::endl;
   scalarFile << "attr strategy \"" << dc.GetStrategyLabel()
             << "\"" << std::endl;
-  scalarFile << "attr input \"" << dc.GetInputLabel()
+  scalarFile << "attr measurement \"" << dc.GetInputLabel()
             << "\"" << std::endl;
   scalarFile << "attr description \"" << dc.GetDescription()
             << "\"" << std::endl;
-  scalarFile << std::endl;
 
   for (MetadataList::iterator i = dc.MetadataBegin();
        i != dc.MetadataEnd(); i++) {
@@ -83,7 +89,18 @@
   }
 
   scalarFile << std::endl;
-
+  if (isNumeric(dc.GetInputLabel())) {
+     scalarFile << "scalar . measurement \"" << dc.GetInputLabel()
+            << "\"" << std::endl;
+  }
+  for (MetadataList::iterator i = dc.MetadataBegin();
+       i != dc.MetadataEnd(); i++) {
+    std::pair<std::string, std::string> blob = (*i);
+    if (isNumeric(blob.second)) {
+       scalarFile << "scalar . \"" << blob.first << "\" \"" << blob.second << "\""
+               << std::endl;
+    }
+  }
   OmnetOutputCallback callback(&scalarFile);
 
   for (DataCalculatorList::iterator i = dc.DataCalculatorBegin();
@@ -97,6 +114,7 @@
   // end OmnetDataOutput::Output
 }
 
+
 OmnetDataOutput::OmnetOutputCallback::OmnetOutputCallback
   (std::ostream *scalar) :
   m_scalar(scalar)
@@ -104,42 +122,92 @@
 }
 
 void
-OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string key,
-                                                      std::string variable,
+OmnetDataOutput::OmnetOutputCallback::OutputStatistic(std::string context,
+                                                      std::string name,
+                                                      const StatisticalSummary *statSum)
+{
+	if (context == "")
+		context = ".";
+	if (name == "")
+		name = "\"\"";
+	(*m_scalar) << "statistic " << context << " " << name << std::endl;
+	if (!isNaN(statSum->getCount()))
+		(*m_scalar) << "field count " << statSum->getCount() << std::endl;
+	if (!isNaN(statSum->getSum()))
+		(*m_scalar) << "field sum " << statSum->getSum() << std::endl;
+	if (!isNaN(statSum->getMean()))
+		(*m_scalar) << "field mean " << statSum->getMean() << std::endl;
+	if (!isNaN(statSum->getMin()))
+		(*m_scalar) << "field min " << statSum->getMin() << std::endl;
+	if (!isNaN(statSum->getMax()))
+		(*m_scalar) << "field max " << statSum->getMax() << std::endl;
+	if (!isNaN(statSum->getSqrSum()))
+		(*m_scalar) << "field sqrsum " << statSum->getSqrSum() << std::endl;
+	if (!isNaN(statSum->getStddev()))
+		(*m_scalar) << "field stddev " << statSum->getStddev() << std::endl;
+}
+
+void
+OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string context,
+                                                      std::string name,
                                                       int val)
 {
-  (*m_scalar) << "scalar " << key << " " << variable << " " << val << std::endl;
+	if (context == "")
+		context = ".";
+	if (name == "")
+		name = "\"\"";
+  (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
   // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
 }
+
 void
-OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string key,
-                                                      std::string variable,
+OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string context,
+                                                      std::string name,
                                                       uint32_t val)
 {
-  (*m_scalar) << "scalar " << key << " " << variable << " " << val << std::endl;
+	if (context == "")
+		context = ".";
+	if (name == "")
+		name = "\"\"";
+  (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
   // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
 }
+
 void
-OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string key,
-                                                      std::string variable,
+OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string context,
+                                                      std::string name,
                                                       double val)
 {
-  (*m_scalar) << "scalar " << key << " " << variable << " " << val << std::endl;
+	if (context == "")
+		context = ".";
+	if (name == "")
+		name = "\"\"";
+    (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
   // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
 }
+
 void
-OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string key,
-                                                      std::string variable,
+OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string context,
+                                                      std::string name,
                                                       std::string val)
 {
-  (*m_scalar) << "scalar " << key << " " << variable << " " << val << std::endl;
+	if (context == "")
+		context = ".";
+	if (name == "")
+		name = "\"\"";
+    (*m_scalar) << "scalar " << context << " " << name << " " << val << std::endl;
   // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
 }
+
 void
-OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string key,
-                                                      std::string variable,
+OmnetDataOutput::OmnetOutputCallback::OutputSingleton(std::string context,
+                                                      std::string name,
                                                       Time val)
 {
-  (*m_scalar) << "scalar " << key << " " << variable << " " << val << std::endl;
+	if (context == "")
+		context = ".";
+	if (name == "")
+		name = "\"\"";
+    (*m_scalar) << "scalar " << context << " " << name << " " << val.GetTimeStep() << std::endl;
   // end OmnetDataOutput::OmnetOutputCallback::OutputSingleton
 }
--- a/src/contrib/stats/omnet-data-output.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/stats/omnet-data-output.h	Mon Nov 16 13:35:38 2009 +0300
@@ -45,24 +45,28 @@
     public:
       OmnetOutputCallback(std::ostream *scalar);
 
-      void OutputSingleton(std::string key,
-                           std::string variable,
+      void OutputStatistic(std::string context,
+                           std::string name,
+                           const StatisticalSummary *statSum);
+
+      void OutputSingleton(std::string context,
+                           std::string name,
                            int val);
 
-      void OutputSingleton(std::string key,
-                           std::string variable,
+      void OutputSingleton(std::string context,
+                           std::string name,
                            uint32_t val);
 
-      void OutputSingleton(std::string key,
-                           std::string variable,
+      void OutputSingleton(std::string context,
+                           std::string name,
                            double val);
 
-      void OutputSingleton(std::string key,
-                           std::string variable,
+      void OutputSingleton(std::string context,
+                           std::string name,
                            std::string val);
 
-      void OutputSingleton(std::string key,
-                           std::string variable,
+      void OutputSingleton(std::string context,
+                           std::string name,
                            Time val);
 
     private:
--- a/src/contrib/stats/sqlite-data-output.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/stats/sqlite-data-output.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -154,6 +154,25 @@
 }
 
 void
+SqliteDataOutput::SqliteOutputCallback::OutputStatistic(std::string key,
+                       std::string variable,
+                       const StatisticalSummary *statSum)
+{
+	OutputSingleton(key,variable+"-count", (double)statSum->getCount());
+	if (!isNaN(statSum->getSum()))
+		OutputSingleton(key,variable+"-total", statSum->getSum());
+	if (!isNaN(statSum->getMax()))
+		OutputSingleton(key,variable+"-max", statSum->getMax());
+	if (!isNaN(statSum->getMin()))
+		OutputSingleton(key,variable+"-min", statSum->getMin());
+	if (!isNaN(statSum->getSqrSum()))
+		OutputSingleton(key,variable+"-sqrsum", statSum->getSqrSum());
+	if (!isNaN(statSum->getStddev()))
+		OutputSingleton(key,variable+"-stddev", statSum->getStddev());
+}
+
+
+void
 SqliteDataOutput::SqliteOutputCallback::OutputSingleton(std::string key,
                                                         std::string variable,
                                                         int val)
--- a/src/contrib/stats/sqlite-data-output.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/stats/sqlite-data-output.h	Mon Nov 16 13:35:38 2009 +0300
@@ -48,6 +48,10 @@
     public:
       SqliteOutputCallback(Ptr<SqliteDataOutput> owner, std::string run);
 
+      void OutputStatistic(std::string key,
+                           std::string variable,
+                           const StatisticalSummary *statSum);
+
       void OutputSingleton(std::string key,
                            std::string variable,
                            int val);
--- a/src/contrib/stats/time-data-calculators.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/stats/time-data-calculators.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -70,12 +70,12 @@
 void
 TimeMinMaxAvgTotalCalculator::Output(DataOutputCallback &callback) const
 {
-  callback.OutputSingleton(m_key, "count", m_count);
+  callback.OutputSingleton(m_context, m_key + "-count", m_count);
   if (m_count > 0) {
-    callback.OutputSingleton(m_key, "total", m_total);
-    callback.OutputSingleton(m_key, "average", m_total/Scalar(m_count));
-    callback.OutputSingleton(m_key, "max", m_max);
-    callback.OutputSingleton(m_key, "min", m_min);
+    callback.OutputSingleton(m_context, m_key + "-total", m_total);
+    callback.OutputSingleton(m_context, m_key + "-average", m_total/Scalar(m_count));
+    callback.OutputSingleton(m_context, m_key + "-max", m_max);
+    callback.OutputSingleton(m_context, m_key + "-min", m_min);
   }
   // end TimeMinMaxAvgTotalCalculator::Output
 }
--- a/src/contrib/wscript	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/contrib/wscript	Mon Nov 16 13:35:38 2009 +0300
@@ -14,9 +14,11 @@
     conf.report_optional_feature("XmlIo", "XmlIo",
                                  conf.env['ENABLE_LIBXML2'],
                                  "library 'libxml-2.0 >= 2.7' not found")
-    conf.sub_config('stats')
+    conf.write_config_header('ns3/contrib-config.h', top=True)
 
-    conf.write_config_header('ns3/contrib-config.h', top=True)
+    conf.sub_config('stats')
+    conf.sub_config('net-anim')
+
 
 def build(bld):
     module = bld.create_ns3_module('contrib', ['simulator', 'common'])
--- a/src/core/attribute.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/core/attribute.h	Mon Nov 16 13:35:38 2009 +0300
@@ -23,7 +23,7 @@
 #include <string>
 #include <stdint.h>
 #include "ptr.h"
-#include "ref-count-base.h"
+#include "simple-ref-count.h"
 
 namespace ns3 {
 
@@ -48,7 +48,7 @@
  * Most subclasses of this base class are implemented by the 
  * ATTRIBUTE_HELPER_* macros.
  */
-class AttributeValue : public RefCountBase
+class AttributeValue : public SimpleRefCount<AttributeValue>
 {
 public:
   AttributeValue ();
@@ -94,7 +94,7 @@
  * of this base class are usually provided through the MakeAccessorHelper
  * template functions, hidden behind an ATTRIBUTE_HELPER_* macro.
  */
-class AttributeAccessor : public RefCountBase
+class AttributeAccessor : public SimpleRefCount<AttributeAccessor>
 {
 public:
   AttributeAccessor ();
@@ -146,7 +146,7 @@
  * Most subclasses of this base class are implemented by the 
  * ATTRIBUTE_HELPER_HEADER and ATTRIBUTE_HELPER_CPP macros.
  */
-class AttributeChecker : public RefCountBase
+class AttributeChecker : public SimpleRefCount<AttributeChecker>
 {
 public:
   AttributeChecker ();
--- a/src/core/callback.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/core/callback.h	Mon Nov 16 13:35:38 2009 +0300
@@ -27,6 +27,7 @@
 #include "type-traits.h"
 #include "attribute.h"
 #include "attribute-helper.h"
+#include "simple-ref-count.h"
 #include <typeinfo>
 
 namespace ns3 {
@@ -72,25 +73,11 @@
   }
 };
 
-class CallbackImplBase
+class CallbackImplBase : public SimpleRefCount<CallbackImplBase>
 {
 public:
-  CallbackImplBase ()
-    : m_count (1) {}
   virtual ~CallbackImplBase () {}
-  void Ref (void) const {
-    m_count++;
-  }
-  void Unref (void) const {
-    m_count--;
-    if (m_count == 0) {
-      delete this;
-    }
-  }
-  uint32_t GetReferenceCount (void) const { return m_count; }
   virtual bool IsEqual (Ptr<const CallbackImplBase> other) const = 0;
-private:
-  mutable uint32_t m_count;
 };
 
 // declare the CallbackImpl class
--- a/src/core/log.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/core/log.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -35,6 +35,7 @@
 namespace ns3 {
 
 LogTimePrinter g_logTimePrinter = 0;
+LogNodePrinter g_logNodePrinter = 0;
 
 typedef std::list<std::pair <std::string, LogComponent *> > ComponentList;
 typedef std::list<std::pair <std::string, LogComponent *> >::iterator ComponentListI;
@@ -124,7 +125,7 @@
           component = tmp;
           if (component == myName || component == "*")
             {
-              int level = LOG_ALL | LOG_PREFIX_TIME | LOG_PREFIX_FUNC;
+              int level = LOG_ALL | LOG_PREFIX_TIME | LOG_PREFIX_FUNC | LOG_PREFIX_NODE;
               Enable ((enum LogLevel)level);
               return;
             }
@@ -178,6 +179,10 @@
                     {
                       level |= LOG_PREFIX_TIME;
                     }
+                  else if (lev == "prefix_node")
+                    {
+                      level |= LOG_PREFIX_NODE;
+                    }
                   else if (lev == "level_error")
                     {
                       level |= LOG_LEVEL_ERROR;
@@ -360,6 +365,15 @@
   return g_logTimePrinter;
 }
 
+void LogSetNodePrinter (LogNodePrinter printer)
+{
+  g_logNodePrinter = printer;
+}
+LogNodePrinter LogGetNodePrinter(void)
+{
+  return g_logNodePrinter;
+}
+
 
 ParameterLogger::ParameterLogger (std::ostream &os)
   : m_itemNumber (0),
--- a/src/core/log.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/core/log.h	Mon Nov 16 13:35:38 2009 +0300
@@ -48,11 +48,12 @@
   LOG_LOGIC          = 0x00000020, // control flow tracing within functions
   LOG_LEVEL_LOGIC    = 0x0000003f,
 
-  LOG_ALL            = 0x3fffffff, // print everything
+  LOG_ALL            = 0x1fffffff, // print everything
   LOG_LEVEL_ALL      = LOG_ALL,
 
   LOG_PREFIX_FUNC    = 0x80000000, // prefix all trace prints with function
-  LOG_PREFIX_TIME    = 0x40000000  // prefix all trace prints with simulation time
+  LOG_PREFIX_TIME    = 0x40000000, // prefix all trace prints with simulation time
+  LOG_PREFIX_NODE    = 0x20000000  // prefix all trace prints with simulation node
 };
 
 /**
@@ -160,6 +161,17 @@
         }                                                       \
     }
 
+#define NS_LOG_APPEND_NODE_PREFIX                               \
+  if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE))                   \
+    {                                                           \
+      ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();  \
+      if (printer != 0)                                         \
+        {                                                       \
+          (*printer) (std::clog);                               \
+          std::clog << " ";                                     \
+        }                                                       \
+    }
+
 #define NS_LOG_APPEND_FUNC_PREFIX                               \
   if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC))                   \
     {                                                           \
@@ -192,6 +204,7 @@
       if (g_log.IsEnabled (level))                              \
         {                                                       \
           NS_LOG_APPEND_TIME_PREFIX;                            \
+          NS_LOG_APPEND_NODE_PREFIX;                            \
           NS_LOG_APPEND_CONTEXT;                                \
           NS_LOG_APPEND_FUNC_PREFIX;                            \
           std::clog << msg << std::endl;                        \
@@ -246,6 +259,7 @@
       if (g_log.IsEnabled (ns3::LOG_FUNCTION))                  \
         {                                                       \
           NS_LOG_APPEND_TIME_PREFIX;                            \
+          NS_LOG_APPEND_NODE_PREFIX;                            \
           NS_LOG_APPEND_CONTEXT;                                \
           std::clog << g_log.Name () << ":"                     \
                     << __FUNCTION__ << "()" << std::endl;       \
@@ -276,6 +290,7 @@
       if (g_log.IsEnabled (ns3::LOG_FUNCTION))                  \
         {                                                       \
           NS_LOG_APPEND_TIME_PREFIX;                            \
+          NS_LOG_APPEND_NODE_PREFIX;                            \
           NS_LOG_APPEND_CONTEXT;                                \
           std::clog << g_log.Name () << ":"                     \
                     << __FUNCTION__ << "(";                     \
@@ -321,10 +336,14 @@
 void LogComponentPrintList (void);
 
 typedef void (*LogTimePrinter) (std::ostream &os);
+typedef void (*LogNodePrinter) (std::ostream &os);
 
 void LogSetTimePrinter (LogTimePrinter);
 LogTimePrinter LogGetTimePrinter(void);
 
+void LogSetNodePrinter (LogNodePrinter);
+LogNodePrinter LogGetNodePrinter(void);
+
 
 class LogComponent {
 public:
@@ -384,6 +403,8 @@
 
 #define LogSetTimePrinter(printer)
 #define LogGetTimePrinter
+#define LogSetNodePrinter(printer)
+#define LogGetNodePrinter
 
 #endif /* LOG_ENABLE */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/object-ref-count.h	Mon Nov 16 13:35:38 2009 +0300
@@ -0,0 +1,120 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Mathieu Lacage
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@gmail.com>
+ */
+#ifndef OBJECT_REF_COUNT_H
+#define OBJECT_REF_COUNT_H
+
+#include "empty.h"
+
+namespace ns3 {
+
+/**
+ * This templated class provides the refcounting implementation
+ * for the ns3::Object class.
+ *
+ * The tricky aspect of the implementation of this class is that
+ * instead of storing a count directly, it keeps track of a pointer
+ * to a count to allow multiple instances of the class to share the
+ * same pointer/count. This is mainly used by the aggregation support
+ * of the ns3::Object class
+ */
+template <typename T, typename PARENT = empty>
+class ObjectRefCount : public PARENT
+{
+public:
+  ObjectRefCount ()
+    : m_count (new int (1))
+  {}
+  ObjectRefCount (const ObjectRefCount &o)
+    : m_count (new int (1))
+  {}
+  ObjectRefCount & operator = (const ObjectRefCount &o)
+  {
+    return *this;
+  }
+  ~ObjectRefCount () 
+  {
+    m_count = 0;
+  }
+
+  /**
+   * Get the reference count of the object.  Normally not needed; for language bindings.
+   */
+  int GetReferenceCount (void) const {
+    return *m_count;
+  }
+  /**
+   * Increment the reference count. This method should not be called
+   * by user code. Object instances are expected to be used in conjunction
+   * of the Ptr template which would make calling Ref unecessary and 
+   * dangerous.
+   */
+  inline void Ref (void) const
+    {
+      (*m_count)++;
+    }
+  /**
+   * Decrement the reference count. This method should not be called
+   * by user code. Object instances are expected to be used in conjunction
+   * of the Ptr template which would make calling Ref unecessary and 
+   * dangerous.
+   */
+  inline void Unref (void) const
+    {
+      (*m_count)--;
+      if ((*m_count) == 0)
+        {
+	  const_cast<ObjectRefCount<T,PARENT>*>(this)->DoDelete ();
+        }
+    }
+protected:
+  /**
+   * \param other another object
+   *
+   * This method makes this object and the input other object
+   * share the same reference count.
+   */
+  void ShareCount (ObjectRefCount *other)
+    {
+      (*m_count) += (*other->m_count);
+      delete other->m_count;
+      other->m_count = m_count;
+    }
+  /**
+   * Called just before deleting this object: when two
+   * objects share the same reference count, the user
+   * who is deleting them must be careful to delete the
+   * associated count only once and this is done by calling 
+   * this method to get a reference to the count and, then,
+   * calling delete on the count.
+   *
+   * \sa ns3::Object::DoDelete
+   */
+  int *PeekCountPtr (void) const
+    {
+      return m_count;
+    }
+private:
+  virtual void DoDelete (void) = 0;
+  mutable int *m_count;
+};
+
+} // namespace ns3
+
+#endif /* OBJECT_REF_COUNT_H */
--- a/src/core/object.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/core/object.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -28,6 +28,8 @@
 #include "string.h"
 #include <vector>
 #include <sstream>
+#include <stdlib.h>
+#include <string.h>
 
 NS_LOG_COMPONENT_DEFINE ("Object");
 
@@ -40,28 +42,23 @@
 NS_OBJECT_ENSURE_REGISTERED (Object);
 
 Object::AggregateIterator::AggregateIterator ()
-  : m_first (0),
+  : m_object (0),
     m_current (0)
 {}
 
 bool 
 Object::AggregateIterator::HasNext (void) const
 {
-  if (m_current != 0 && m_current->m_next != PeekPointer (m_first))
-    {
-      return true;
-    }
-  return false;
+  return m_current < m_object->m_aggregates->n;
 }
 Ptr<const Object> 
 Object::AggregateIterator::Next (void)
 {
-  m_current = m_current->m_next;
-  return m_current;
+  return m_object->m_aggregates->buffer[m_current];
 }
-Object::AggregateIterator::AggregateIterator (Ptr<const Object> first)
-  : m_first (first),
-    m_current (first)
+Object::AggregateIterator::AggregateIterator (Ptr<const Object> object)
+  : m_object (object),
+    m_current (0)
 {}
 
 
@@ -82,25 +79,47 @@
 
 
 Object::Object ()
-  : m_count (1),
-    m_tid (Object::GetTypeId ()),
+  : m_tid (Object::GetTypeId ()),
     m_disposed (false),
-    m_next (this)
-{}
+    m_started (false),
+    m_aggregates ((struct Aggregates *)malloc (sizeof (struct Aggregates))),
+    m_getObjectCount (0)
+{
+  m_aggregates->n = 1;
+  m_aggregates->buffer[0] = this;
+}
 Object::~Object () 
 {
-  m_next = 0;
+  // remove this object from the aggregate list
+  uint32_t n = m_aggregates->n;
+  for (uint32_t i = 0; i < n; i++)
+    {
+      Object *current = m_aggregates->buffer[i];
+      if (current == this)
+        {
+          memmove (&m_aggregates->buffer[i], 
+                   &m_aggregates->buffer[i+1],
+                   sizeof (Object *)*(m_aggregates->n - (i+1)));
+          m_aggregates->n--;
+        }
+    }
+  // finally, if all objects have been removed from the list,
+  // delete the aggregate list
+  if (m_aggregates->n == 0)
+    {
+      free (m_aggregates);
+    }
+  m_aggregates = 0;
 }
 Object::Object (const Object &o)
-  : m_count (1),
-    m_tid (o.m_tid),
+  : m_tid (o.m_tid),
     m_disposed (false),
-    m_next (this)
-{}
-uint32_t
-Object::GetReferenceCount (void) const
+    m_started (false),
+    m_aggregates ((struct Aggregates *)malloc (sizeof (struct Aggregates))),
+    m_getObjectCount (0)
 {
-  return m_count;
+  m_aggregates->n = 1;
+  m_aggregates->buffer[0] = this;
 }
 void
 Object::Construct (const AttributeList &attributes)
@@ -112,34 +131,69 @@
 Object::DoGetObject (TypeId tid) const
 {
   NS_ASSERT (CheckLoose ());
-  const Object *currentObject = this;
+
+  uint32_t n = m_aggregates->n;
   TypeId objectTid = Object::GetTypeId ();
-  do {
-    NS_ASSERT (currentObject != 0);
-    TypeId cur = currentObject->GetInstanceTypeId ();
-    while (cur != tid && cur != objectTid)
-      {
-        cur = cur.GetParent ();
-      }
-    if (cur == tid)
-      {
-        return const_cast<Object *> (currentObject);
-      }
-    currentObject = currentObject->m_next;
-  } while (currentObject != this);
+  for (uint32_t i = 0; i < n; i++)
+    {
+      Object *current = m_aggregates->buffer[i];
+      TypeId cur = current->GetInstanceTypeId ();
+      while (cur != tid && cur != objectTid)
+        {
+          cur = cur.GetParent ();
+        }
+      if (cur == tid)
+        {
+          // This is an attempt to 'cache' the result of this lookup.
+          // the idea is that if we perform a lookup for a TypeId on this object,
+          // we are likely to perform the same lookup later so, we make sure
+          // that the aggregate array is sorted by the number of accesses
+          // to each object.
+
+          // first, increment the access count
+          current->m_getObjectCount++;
+          // then, update the sort
+          UpdateSortedArray (m_aggregates, i);
+          // finally, return the match
+          return const_cast<Object *> (current);
+        }
+    }
   return 0;
 }
+void
+Object::Start (void)
+{
+  uint32_t n = m_aggregates->n;
+  for (uint32_t i = 0; i < n; i++)
+    {
+      Object *current = m_aggregates->buffer[i];
+      current->DoStart ();
+      current->m_started = true;
+    }
+}
 void 
 Object::Dispose (void)
 {
-  Object *current = this;
-  do {
-    NS_ASSERT (current != 0);
-    NS_ASSERT (!current->m_disposed);
-    current->DoDispose ();
-    current->m_disposed = true;
-    current = current->m_next;
-  } while (current != this);
+  uint32_t n = m_aggregates->n;
+  for (uint32_t i = 0; i < n; i++)
+    {
+      Object *current = m_aggregates->buffer[i];
+      NS_ASSERT (!current->m_disposed);
+      current->DoDispose ();
+      current->m_disposed = true;
+    }
+}
+void
+Object::UpdateSortedArray (struct Aggregates *aggregates, uint32_t j) const
+{
+  while (j > 0 && 
+         aggregates->buffer[j]->m_getObjectCount > aggregates->buffer[j-1]->m_getObjectCount)
+    {
+      Object *tmp = aggregates->buffer[j-1];
+      aggregates->buffer[j-1] = aggregates->buffer[j];
+      aggregates->buffer[j] = tmp;
+      j--;
+    }
 }
 void 
 Object::AggregateObject (Ptr<Object> o)
@@ -157,20 +211,42 @@
     }
 
   Object *other = PeekPointer (o);
-  Object *next = m_next;
-  m_next = other->m_next;
-  other->m_next = next;
-  NS_ASSERT (CheckLoose ());
-  NS_ASSERT (o->CheckLoose ());
-  // call NotifyNewAggregate in the listed chain
-  Object *currentObject = this;
-  do 
+  // first create the new aggregate buffer.
+  uint32_t total = m_aggregates->n + other->m_aggregates->n;
+  struct Aggregates *aggregates = 
+    (struct Aggregates *)malloc (sizeof(struct Aggregates)+(total-1)*sizeof(Object*));
+  aggregates->n = total;
+  memcpy (&aggregates->buffer[0], 
+          &m_aggregates->buffer[0], 
+          m_aggregates->n*sizeof(Object*));
+  // append the other aggregates in the new buffer
+  for (uint32_t i = 0; i < other->m_aggregates->n; i++)
     {
-      // the NotifyNewAggregate of the current object implementation
-      // should be called on the next object in the linked chain
-      currentObject->NotifyNewAggregate ();
-      currentObject = currentObject->m_next;
-    } while (currentObject != this);
+      aggregates->buffer[m_aggregates->n+i] = other->m_aggregates->buffer[i];
+      UpdateSortedArray (aggregates, m_aggregates->n + i);
+    }
+
+  // free both aggregate buffers
+  free (m_aggregates);
+  free (other->m_aggregates);
+
+  // Then, assign that buffer to every object
+  uint32_t n = aggregates->n;
+  for (uint32_t i = 0; i < n; i++)
+    {
+      Object *current = aggregates->buffer[i];
+      current->m_aggregates = aggregates;
+    }
+
+  // share the counts
+  ShareCount (other);
+
+  // Finally, call NotifyNewAggregate in the listed chain
+  for (uint32_t i = 0; i < n; i++)
+    {
+      Object *current = m_aggregates->buffer[i];
+      current->NotifyNewAggregate ();
+    }
 }
 /**
  * This function must be implemented in the stack that needs to notify
@@ -201,11 +277,16 @@
   NS_ASSERT (!m_disposed);
 }
 
+void
+Object::DoStart (void)
+{
+  NS_ASSERT (!m_started);
+}
 
 bool 
 Object::Check (void) const
 {
-  return (m_count > 0);
+  return (GetReferenceCount () > 0);
 }
 
 /* In some cases, when an event is scheduled against a subclass of
@@ -219,54 +300,43 @@
 Object::CheckLoose (void) const
 {
   uint32_t refcount = 0;
-  const Object *current = this;
-  do
+  uint32_t n = m_aggregates->n;
+  for (uint32_t i = 0; i < n; i++)
     {
-      refcount += current->m_count;
-      current = current->m_next;
+      Object *current = m_aggregates->buffer[i];
+      refcount += current->GetReferenceCount ();
     }
-  while (current != this);
-
   return (refcount > 0);
 }
-
 void
-Object::MaybeDelete (void) const
+Object::DoDelete (void)
 {
-  // First, check if any of the attached
-  // Object has a non-zero count.
-  const Object *current = this;
-  do {
-    NS_ASSERT (current != 0);
-    if (current->m_count != 0)
-      {
-        return;
-      }
-    current = current->m_next;
-  } while (current != this);
-
+  uint32_t n = m_aggregates->n;
   // Ensure we are disposed.
-  Object *tmp = const_cast<Object *> (this);
-  const Object *end = this;
-  do {
-    NS_ASSERT (current != 0);
-    Object *next = tmp->m_next;
-    if (!tmp->m_disposed)
-      {
-        tmp->DoDispose ();
-      }
-    tmp = next;
-  } while (tmp != end);
+  for (uint32_t i = 0; i < n; i++)
+    {
+      Object *current = m_aggregates->buffer[i];
+      if (!current->m_disposed)
+        {
+          current->DoDispose ();
+        }
+    }
+
+  int *count = PeekCountPtr ();
 
-  // all attached objects have a zero count so, 
-  // we can delete all attached objects.
-  current = this;
-  do {
-    NS_ASSERT (current != 0);
-    Object *next = current->m_next;
-    delete current;
-    current = next;
-  } while (current != end);
+  // Now, actually delete all objects
+  struct Aggregates *aggregates = m_aggregates;
+  for (uint32_t i = 0; i < n; i++)
+    {
+      // There is a trick here: each time we call delete below,
+      // the deleted object is removed from the aggregate buffer
+      // in the destructor so, the index of the next element to 
+      // lookup is always zero
+      Object *current = aggregates->buffer[0];
+      delete current;
+    }
+
+  delete count;
 }
 } // namespace ns3
 
--- a/src/core/object.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/core/object.h	Mon Nov 16 13:35:38 2009 +0300
@@ -28,6 +28,7 @@
 #include "attribute.h"
 #include "object-base.h"
 #include "attribute-list.h"
+#include "object-ref-count.h"
 
 
 namespace ns3 {
@@ -55,7 +56,7 @@
  * invoked from the Object::Unref method before destroying the object, even if the user 
  * did not call Object::Dispose directly.
  */
-class Object : public ObjectBase
+class Object : public ObjectRefCount<Object,ObjectBase>
 {
 public:
   static TypeId GetTypeId (void);
@@ -85,9 +86,9 @@
     Ptr<const Object> Next (void);
   private:
     friend class Object;
-    AggregateIterator (Ptr<const Object> first);
-    Ptr<const Object> m_first;
-    Ptr<const Object> m_current;
+    AggregateIterator (Ptr<const Object> object);
+    Ptr<const Object> m_object;
+    uint32_t m_current;
   };
 
   Object ();
@@ -99,30 +100,10 @@
   virtual TypeId GetInstanceTypeId (void) const;
 
   /**
-   * Increment the reference count. This method should not be called
-   * by user code. Object instances are expected to be used in conjunction
-   * of the Ptr template which would make calling Ref unecessary and 
-   * dangerous.
-   */
-  inline void Ref (void) const;
-  /**
-   * Decrement the reference count. This method should not be called
-   * by user code. Object instances are expected to be used in conjunction
-   * of the Ptr template which would make calling Ref unecessary and 
-   * dangerous.
-   */
-  inline void Unref (void) const;
-
-  /**
-   * Get the reference count of the object.  Normally not needed; for language bindings.
-   */
-  uint32_t GetReferenceCount (void) const;
-
-  /**
    * \returns a pointer to the requested interface or zero if it could not be found.
    */
   template <typename T>
-  Ptr<T> GetObject (void) const;
+  inline Ptr<T> GetObject (void) const;
   /**
    * \param tid the interface id of the requested interface
    * \returns a pointer to the requested interface or zero if it could not be found.
@@ -159,6 +140,12 @@
    */
   AggregateIterator GetAggregateIterator (void) const;
 
+  /**
+   * Execute starting code of an object. What this method does is really up
+   * to the user.
+   */
+  void Start (void);
+
 protected:
  /**
   * This function is called by the AggregateObject on all the objects connected in the listed chain.
@@ -168,6 +155,15 @@
   */
   virtual void NotifyNewAggregate ();
   /**
+   * This method is called only once by Object::Start. If the user
+   * calls Object::Start multiple times, DoStart is called only the
+   * first time.
+   *
+   * Subclasses are expected to override this method and _chain up_
+   * to their parent's implementation once they are done.
+   */
+  virtual void DoStart (void);
+  /**
    * This method is called by Object::Dispose or by the object's 
    * destructor, whichever comes first.
    *
@@ -215,17 +211,25 @@
   friend class ObjectFactory;
   friend class AggregateIterator;
 
+  /**
+   * This data structure uses a classic C-style trick to 
+   * hold an array of variable size without performing
+   * two memory allocations: the declaration of the structure
+   * declares a one-element array but when we allocate
+   * memory for this struct, we effectively allocate a larger
+   * chunk of memory than the struct to allow space for a larger
+   * variable sized buffer whose size is indicated by the element
+   * 'n'
+   */
+  struct Aggregates {
+    uint32_t n;
+    Object *buffer[1];
+  };
+
   Ptr<Object> DoGetObject (TypeId tid) const;
   bool Check (void) const;
   bool CheckLoose (void) const;
   /**
-   * Attempt to delete this object. This method iterates
-   * over all aggregated objects to check if they all 
-   * have a zero refcount. If yes, the object and all
-   * its aggregates are deleted. If not, nothing is done.
-   */
-  void MaybeDelete (void) const;
-  /**
    * \param tid an TypeId
    *
    * Invoked from ns3::CreateObject only.
@@ -243,14 +247,15 @@
    */
   void Construct (const AttributeList &attributes);
 
+  void UpdateSortedArray (struct Aggregates *aggregates, uint32_t i) const;
   /**
-   * The reference count for this object. Each aggregate
-   * has an individual reference count. When the global
-   * reference count (the sum of all reference counts) 
-   * reaches zero, the object and all its aggregates is 
-   * deleted.
+   * Attempt to delete this object. This method iterates
+   * over all aggregated objects to check if they all 
+   * have a zero refcount. If yes, the object and all
+   * its aggregates are deleted. If not, nothing is done.
    */
-  mutable uint32_t m_count;
+  virtual void DoDelete (void);
+
   /**
    * Identifies the type of this object instance.
    */
@@ -261,13 +266,24 @@
    */
   bool m_disposed;
   /**
-   * A pointer to the next aggregate object. This is a circular
-   * linked list of aggregated objects: the last one points
-   * back to the first one. If an object is not aggregated to
-   * any other object, the value of this field is equal to the
-   * value of the 'this' pointer.
+   * Set to true once the DoStart method has run,
+   * false otherwise
    */
-  Object *m_next;
+  bool m_started;
+  /**
+   * a pointer to an array of 'aggregates'. i.e., a pointer to
+   * each object aggregated to this object is stored in this 
+   * array. The array is shared by all aggregated objects
+   * so the size of the array is indirectly a reference count.
+   */
+  struct Aggregates * m_aggregates;
+  /**
+   * Indicates the number of times the object was accessed with a
+   * call to GetObject. This integer is used to implement a
+   * heuristic to sort the array of aggregates to put at the start
+   * of the array the most-frequently accessed elements.
+   */
+  uint32_t m_getObjectCount;
 };
 
 /**
@@ -340,26 +356,15 @@
  *   The Object implementation which depends on templates
  *************************************************************************/
 
-void
-Object::Ref (void) const
-{
-  m_count++;
-}
-void
-Object::Unref (void) const
-{
-  NS_ASSERT (Check ());
-  m_count--;
-  if (m_count == 0)
-    {
-      MaybeDelete ();
-    }
-}
-
 template <typename T>
 Ptr<T> 
 Object::GetObject () const
 {
+  T *result = dynamic_cast<T *> (m_aggregates->buffer[0]);
+  if (result != 0)
+    {
+      return Ptr<T> (result);
+    }
   Ptr<Object> found = DoGetObject (T::GetTypeId ());
   if (found != 0)
     {
--- a/src/core/ref-count-base.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/core/ref-count-base.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -1,52 +1,8 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Georgia Tech Research Corporation
- *
- * 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:  George Riley <riley@ece.gatech.edu>
- * Adapted from original code in object.h by:
- * Authors: Gustavo Carneiro <gjcarneiro@gmail.com>,
- *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
 #include "ref-count-base.h"
 
 namespace ns3 {
 
-RefCountBase::RefCountBase() 
-  : m_count (1) 
-{
-}
-
-RefCountBase::RefCountBase (const RefCountBase &o)
- : m_count (1)
+RefCountBase::~RefCountBase ()
 {}
-RefCountBase &
-RefCountBase::operator = (const RefCountBase &o)
-{
-  return *this;
-}
-
-RefCountBase::~RefCountBase () 
-{
-}
-
-uint32_t
-RefCountBase::GetReferenceCount (void) const
-{
-  return m_count;
-}
 
 } // namespace ns3
--- a/src/core/ref-count-base.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/core/ref-count-base.h	Mon Nov 16 13:35:38 2009 +0300
@@ -23,74 +23,26 @@
 #ifndef __REF_COUNT_BASE_H__
 #define __REF_COUNT_BASE_H__
 
-#include <stdint.h>
+#include "simple-ref-count.h"
 
 namespace ns3 {
 
 /**
- * \brief a base class that provides implementations of reference counting
- *    operations.
- *  
- * A base class that provides implementations of reference counting 
- * operations, for classes that wish to use the templatized smart 
- * pointer for memory management but that do not wish to derive from
- * class ns3::Object.
+ * \brief A deprecated way to get reference-counting powers
  *
+ * Users who wish to use reference counting for a class of their own should use
+ * instead the template \ref ns3::SimpleRefCount. This class is maintained
+ * purely for compatibility to avoid breaking the code of users.
  */
-class RefCountBase 
+class RefCountBase : public SimpleRefCount<RefCountBase>
 { 
 public:
-  RefCountBase();
-  RefCountBase (const RefCountBase &o);
-  RefCountBase &operator = (const RefCountBase &o);
-  virtual ~RefCountBase ();
   /**
-   * Increment the reference count. This method should not be called
-   * by user code. RefCountBase instances are expected to be used in
-   * conjunction with the Ptr template which would make calling Ref
-   * unecessary and dangerous.
+   * This only thing this class does it declare a virtual destructor
    */
-  inline void Ref (void) const;
-  /**
-   * Decrement the reference count. This method should not be called
-   * by user code. RefCountBase instances are expected to be used in 
-   * conjunction with the Ptr template which would make calling Ref
-   * unecessary and dangerous.
-   */
-  inline void Unref (void) const;
-
-  /**
-   * Get the reference count of the object.  Normally not needed; for language bindings.
-   */
-  uint32_t GetReferenceCount (void) const;
-
-private:
-  // Note we make this mutable so that the const methods can still
-  // change it.
-  mutable uint32_t m_count;  // Reference count
+  virtual ~RefCountBase ();
 };
 
 } // namespace ns3
 
-namespace ns3 {
-
-// Implementation of the in-line methods
-void
-RefCountBase::Ref (void) const
-{
-  m_count++;
-}
-
-void
-RefCountBase::Unref (void) const
-{
-  m_count--;
-  if (m_count == 0)
-    { // All references removed, ok to delete
-      delete this;
-    }
-}
-
-} // namespace ns3
-
 #endif /* __REF_COUNT_BASE_H__*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/simple-ref-count.h	Mon Nov 16 13:35:38 2009 +0300
@@ -0,0 +1,103 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech Research Corporation, INRIA
+ *
+ * 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
+ *
+ * Authors: George Riley <riley@ece.gatech.edu>
+ *          Gustavo Carneiro <gjcarneiro@gmail.com>,
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef SIMPLE_REF_COUNT_H
+#define SIMPLE_REF_COUNT_H
+
+#include "empty.h"
+#include <stdint.h>
+
+namespace ns3 {
+
+/**
+ * \brief A template-based reference counting class
+ *
+ * This template can be used to give reference-counting powers
+ * to a class. This template does not require this class to
+ * have a virtual destructor or no parent class.
+ * 
+ * Note: if you are moving to this template from the RefCountBase class,
+ * you need to be careful to mark appropriately your destructor virtual
+ * if needed. i.e., if your class has subclasses, _do_ mark your destructor
+ * virtual.
+ *
+ * \internal
+ * Note: we rely on the fairly common EBCO (empty base class optimization)
+ * to get rid of the empty parent when the user does not provide
+ * a non-trivial parent.
+ */
+template <typename T, typename PARENT = empty>
+class SimpleRefCount : public PARENT
+{
+public:
+  SimpleRefCount ()
+    : m_count (1)
+  {}
+  SimpleRefCount (const SimpleRefCount &o)
+    : m_count (1)
+  {}
+  SimpleRefCount &operator = (const SimpleRefCount &o)
+  {
+    return *this;
+  }
+  /**
+   * Increment the reference count. This method should not be called
+   * by user code. SimpleRefCount instances are expected to be used in
+   * conjunction with the Ptr template which would make calling Ref
+   * unecessary and dangerous.
+   */
+  inline void Ref (void) const
+  {
+    m_count++;
+  }
+  /**
+   * Decrement the reference count. This method should not be called
+   * by user code. SimpleRefCount instances are expected to be used in 
+   * conjunction with the Ptr template which would make calling Ref
+   * unecessary and dangerous.
+   */
+  inline void Unref (void) const
+  {
+    m_count--;
+    if (m_count == 0)
+      {
+	delete static_cast<T*> (const_cast<SimpleRefCount *> (this));
+      }
+  }
+
+  /**
+   * Get the reference count of the object.  
+   * Normally not needed; for language bindings.
+   */
+  uint32_t GetReferenceCount (void) const
+  {
+    return m_count;
+  }
+
+private:
+  // Note we make this mutable so that the const methods can still
+  // change it.
+  mutable uint32_t m_count;
+};
+
+} // namespace ns3
+
+#endif /* SIMPLE_REF_COUNT_H */
--- a/src/core/system-thread.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/core/system-thread.h	Mon Nov 16 13:35:38 2009 +0300
@@ -42,7 +42,7 @@
  *
  * Synchronization between threads is provided via the SystemMutex class.
  */
-class SystemThread 
+class SystemThread : public SimpleRefCount<SystemThread>
 {
 public:
   /**
@@ -72,12 +72,20 @@
    * is asking the SystemThread to call object->MyMethod () in a new thread
    * of execution.
    *
-   * Remember that if you are invoking a callback on an object that is
-   * managed by a smart pointer, you need to call PeekPointer.
+   * If starting a thread in your currently executing object, you can use the
+   * "this" pointer:
+   *
+   *   Ptr<SystemThread> st = Create<SystemThread> (
+   *     MakeCallback (&MyClass::MyMethod, this));
+   *   st->Start ();
+   *
+   * Object lifetime is always an issue with threads, so it is common to use
+   * smart pointers.  If you are spinning up a thread in an object that is 
+   * managed by a smart pointer, you can use that pointer directly:
    *
    *   Ptr<MyClass> myPtr = Create<MyClass> ();
    *   Ptr<SystemThread> st = Create<SystemThread> (
-   *     MakeCallback (&MyClass::MyMethod, PeekPointer (myPtr)));
+   *     MakeCallback (&MyClass::MyMethod, myPtr));
    *   st->Start ();
    *
    * Just like any thread, you can synchronize with its termination.  The 
@@ -108,22 +116,6 @@
   ~SystemThread();
 
   /**
-   * Increment the reference count. This method should not be called
-   * by user code. Object instances are expected to be used in conjunction
-   * of the Ptr template which would make calling Ref unecessary and 
-   * dangerous.
-   */
-  inline void Ref (void) const;
-
-  /**
-   * Decrement the reference count. This method should not be called
-   * by user code. Object instances are expected to be used in conjunction
-   * of the Ptr template which would make calling Ref unecessary and 
-   * dangerous.
-   */
-  inline void Unref (void) const;
-
-  /**
    * @brief Start a thread of execution, running the provided callback.
    */
   void Start (void);
@@ -173,26 +165,9 @@
 
 private:
   SystemThreadImpl * m_impl;
-  mutable uint32_t m_count;
   bool m_break;
 };
 
- void
-SystemThread::Ref (void) const
-{
-  m_count++;
-}
-
- void
-SystemThread::Unref (void) const
-{
-  m_count--;
-  if (m_count == 0)
-    {
-      delete this;
-    }
-}
-
 } //namespace ns3
 
 #endif /* SYSTEM_THREAD_H */
--- a/src/core/test.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/core/test.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -87,6 +87,7 @@
     m_continueOnFailure (false), 
     m_detailsReported (false), 
     m_basedir ("invalid"), 
+    m_tempdir ("invalid"), 
     m_ofs (0), 
     m_error (false)
 {
@@ -203,7 +204,18 @@
 void 
 TestCase::SetBaseDir (std::string basedir)
 {
-  m_basedir = basedir;
+  //
+  // C and C++ allow one to use forward slashes even on systems where the 
+  // separator is actually a backslash.
+  //
+  if (basedir[basedir.length () - 1] != '/')
+    {
+      m_basedir = basedir + "/";
+    }
+  else
+    {
+      m_basedir = basedir;
+    }
 }
 
 std::string 
@@ -212,13 +224,52 @@
   return m_basedir;
 }
 
+void 
+TestCase::SetTempDir (std::string tempdir)
+{
+  //
+  // C and C++ allow one to use forward slashes even on systems where the 
+  // separator is actually a backslash.
+  //
+  if (tempdir[tempdir.length () - 1] != '/')
+    {
+      m_tempdir = tempdir + "/";
+    }
+  else
+    {
+      m_tempdir = tempdir;
+    }
+}
+
+std::string 
+TestCase::GetTempDir (void)
+{
+  return m_tempdir;
+}
+
 std::string 
 TestCase::GetSourceDir (std::string file)
 {
+  //
+  // The <file> parameter is actually going to be __FILE__ which may have 
+  // backslashes in it on win32 systems.  For example,
+  //
+  //   ..\src\common\pcap-file-test-suite.cc  (win32)
+  //
+  // or
+  //
+  //   ../src/common/pcap-file-test-suite.cc  (grown-up systems)
+  //
+#ifdef WIN32
+  std::string::size_type relPathBegin = file.find_first_of ("\\");
+  std::string::size_type relPathEnd = file.find_last_of ("\\");
+#else
   std::string::size_type relPathBegin = file.find_first_of ("/");
-  NS_ABORT_MSG_IF (relPathBegin == std::string::npos, "TestCase::GetSrouceDir(): Internal Error");
   std::string::size_type relPathEnd = file.find_last_of ("/");
-  NS_ABORT_MSG_IF (relPathEnd == std::string::npos, "TestCase::GetSrouceDir(): Internal Error");
+#endif
+
+  NS_ABORT_MSG_IF (relPathBegin == std::string::npos, "TestCase::GetSourceDir(): Internal Error");
+  NS_ABORT_MSG_IF (relPathEnd == std::string::npos, "TestCase::GetSourceDir(): Internal Error");
 
   return GetBaseDir () + file.substr (relPathBegin, relPathEnd + 1 - relPathBegin);
 }
@@ -353,6 +404,7 @@
   : m_name (name), 
     m_verbose (false), 
     m_basedir ("invalid"), 
+    m_tempdir ("invalid"), 
     m_ofs (0), 
     m_error (false), 
     m_type (type)
@@ -476,7 +528,18 @@
 void 
 TestSuite::SetBaseDir (std::string basedir)
 {
-  m_basedir = basedir;
+  //
+  // C and C++ allow one to use forward slashes even on systems where the 
+  // separator is actually a backslash.
+  //
+  if (basedir[basedir.length () - 1] != '/')
+    {
+      m_basedir = basedir + "/";
+    }
+  else
+    {
+      m_basedir = basedir;
+    }
 }
 
 std::string 
@@ -486,6 +549,29 @@
 }
 
 void 
+TestSuite::SetTempDir (std::string tempdir)
+{
+  //
+  // C and C++ allow one to use forward slashes even on systems where the 
+  // separator is actually a backslash.
+  //
+  if (tempdir[tempdir.length () - 1] != '/')
+    {
+      m_tempdir = tempdir + "/";
+    }
+  else
+    {
+      m_tempdir = tempdir;
+    }
+}
+
+std::string 
+TestSuite::GetTempDir (void)
+{
+  return m_tempdir;
+}
+
+void 
 TestSuite::SetStream (std::ofstream *ofs)
 {
   m_ofs = ofs;
@@ -589,6 +675,7 @@
       (*i)->SetVerbose (m_verbose);
       (*i)->SetContinueOnFailure (m_continueOnFailure);
       (*i)->SetBaseDir (m_basedir);
+      (*i)->SetTempDir (m_tempdir);
       (*i)->SetStream (m_ofs);
 
       //
--- a/src/core/test.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/core/test.h	Mon Nov 16 13:35:38 2009 +0300
@@ -662,6 +662,16 @@
    */
   std::string GetBaseDir (void);
 
+  /**
+   * \brief Set the temporary file directory (where to write temporary files).
+   */
+  void SetTempDir (std::string dir);
+
+  /**
+   * \brief Get the temporary file directory .
+   */
+  std::string GetTempDir (void);
+
 /**
  * \brief Get the source directory of the current source file.
  *
@@ -830,6 +840,7 @@
   bool m_continueOnFailure;
   bool m_detailsReported;
   std::string m_basedir;
+  std::string m_tempdir;
   std::ofstream *m_ofs;
   bool m_error;
 };
@@ -945,6 +956,16 @@
   std::string GetBaseDir (void);
 
   /**
+   * \brief Set the temporary file directory (where to write temporary files).
+   */
+  void SetTempDir (std::string dir);
+
+  /**
+   * \brief Get the temporary file directory.
+   */
+  std::string GetTempDir (void);
+
+  /**
    * \brief Set the stream to which status and result messages will be written.
    *
    * We really don't want to have to pass an ofstream around to every function
@@ -1064,6 +1085,7 @@
   bool m_verbose;
   bool m_continueOnFailure;
   std::string m_basedir;
+  std::string m_tempdir;
   std::ofstream *m_ofs;
   bool m_error;
   TestType m_type;
--- a/src/core/trace-source-accessor.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/core/trace-source-accessor.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -22,23 +22,8 @@
 namespace ns3 {
 
 TraceSourceAccessor::TraceSourceAccessor ()
-  : m_count (1)
 {}
 TraceSourceAccessor::~TraceSourceAccessor ()
 {}
-void 
-TraceSourceAccessor::Ref (void) const
-{
-  m_count++;
-}
-void 
-TraceSourceAccessor::Unref (void) const
-{
-  m_count--;
-  if (m_count == 0)
-    {
-      delete this;
-    }
-}
 
 } // namespace ns3
--- a/src/core/trace-source-accessor.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/core/trace-source-accessor.h	Mon Nov 16 13:35:38 2009 +0300
@@ -23,6 +23,7 @@
 #include <stdint.h>
 #include "callback.h"
 #include "ptr.h"
+#include "simple-ref-count.h"
 
 namespace ns3 {
 
@@ -36,13 +37,11 @@
  * This class abstracts the kind of trace source to which we want to connect
  * and provides services to Connect and Disconnect a sink to a trace source.
  */
-class TraceSourceAccessor
+class TraceSourceAccessor : public SimpleRefCount<TraceSourceAccessor>
 {
 public:
   TraceSourceAccessor ();
   virtual ~TraceSourceAccessor ();
-  void Ref (void) const;
-  void Unref (void) const;
 
   /**
    * \param obj the object instance which contains the target trace source.
@@ -66,8 +65,6 @@
    * \param cb the callback to disconnect from the target trace source.
    */
   virtual bool Disconnect (ObjectBase *obj, std::string context, const CallbackBase &cb) const = 0;
-private:
-  mutable uint32_t m_count;
 };
 
 /**
--- a/src/core/unix-system-thread.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/core/unix-system-thread.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -141,8 +141,7 @@
 // class above.
 //
 SystemThread::SystemThread (Callback<void> callback) 
-  : m_impl (new SystemThreadImpl (callback)),
-    m_count (1)
+  : m_impl (new SystemThreadImpl (callback))
 {
   NS_LOG_FUNCTION_NOARGS ();
 }
--- a/src/core/wscript	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/core/wscript	Mon Nov 16 13:35:38 2009 +0300
@@ -90,6 +90,7 @@
         'callback.h',
         'object-base.h',
         'ref-count-base.h',
+        'simple-ref-count.h',
         'type-id.h',
         'attribute-list.h',
         'ptr.h',
@@ -126,6 +127,7 @@
         'abort.h',
         'names.h',
         'vector.h',
+        'object-ref-count.h',
         ]
 
     if sys.platform == 'win32':
--- a/src/devices/csma/csma-channel.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/csma/csma-channel.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -212,8 +212,27 @@
 
   NS_LOG_LOGIC ("Schedule event in " << m_delay.GetSeconds () << " sec");
 
+
+  NS_LOG_LOGIC ("Receive");
+  
+  std::vector<CsmaDeviceRec>::iterator it;
+  uint32_t devId = 0;
+  for (it = m_deviceList.begin (); it < m_deviceList.end(); it++) 
+    {
+      if (it->IsActive ())
+        {
+          // schedule reception events
+          Simulator::ScheduleWithContext (it->devicePtr->GetNode ()->GetId (),
+                                          m_delay,
+                                          &CsmaNetDevice::Receive, it->devicePtr,
+                                          m_currentPkt->Copy (), m_deviceList[m_currentSrc].devicePtr);
+        }
+      devId++;
+    }
+
+  // also schedule for the tx side to go back to IDLE
   Simulator::Schedule (m_delay, &CsmaChannel::PropagationCompleteEvent,
-    this);
+                       this);
   return retVal;
 }
 
@@ -224,19 +243,6 @@
   NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")");
 
   NS_ASSERT (m_state == PROPAGATING);
-
-  NS_LOG_LOGIC ("Receive");
-  
-  std::vector<CsmaDeviceRec>::iterator it;
-  uint32_t devId = 0;
-  for (it = m_deviceList.begin (); it < m_deviceList.end(); it++) 
-    {
-      if (it->IsActive ())
-      {
-        it->devicePtr->Receive (m_currentPkt->Copy (), m_deviceList[m_currentSrc].devicePtr);
-      }
-      devId++;
-    }
   m_state = IDLE;
 }
 
--- a/src/devices/mesh/dot11s/dot11s-test-suite.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/mesh/dot11s/dot11s-test-suite.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -174,9 +174,9 @@
 {
   for (std::vector<Mac48Address>::const_iterator i = precursors.begin (); i != precursors.end (); i++)
     {
-      table->AddPrecursor (dst, iface, *i);
+      table->AddPrecursor (dst, iface, *i, Seconds (100));
       // Check that duplicates are filtered
-      table->AddPrecursor (dst, iface, *i);
+      table->AddPrecursor (dst, iface, *i, Seconds (100));
     }
 }
 
--- a/src/devices/mesh/dot11s/hwmp-protocol.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/mesh/dot11s/hwmp-protocol.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -320,7 +320,7 @@
 {
   NS_ASSERT(destination != Mac48Address::GetBroadcast ());
   HwmpRtable::LookupResult result = m_rtable->LookupReactive (destination);
-  NS_LOG_DEBUG("Requested src = "<<source<<", dst = "<<destination<<", I am "<<GetAddress ()<<", RA = "<<result.retransmitter);
+  NS_LOG_DEBUG ("Requested src = "<<source<<", dst = "<<destination<<", I am "<<GetAddress ()<<", RA = "<<result.retransmitter);
   if (result.retransmitter == Mac48Address::GetBroadcast ())
     {
       result = m_rtable->LookupProactive ();
@@ -401,6 +401,7 @@
   //acceptance cretirea:
   std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
       preq.GetOriginatorAddress ());
+  bool freshInfo (true);
   if (i != m_hwmpSeqnoMetricDatabase.end ())
     {
       if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber ())  > 0)
@@ -409,21 +410,25 @@
         }
       if (i->second.first == preq.GetOriginatorSeqNumber ())
         {
+          freshInfo = false;
           if (i->second.second <= preq.GetMetric ())
             {
               return;
             }
         }
     }
-  m_hwmpSeqnoMetricDatabase[preq.GetOriginatorAddress ()] = std::make_pair (preq.GetOriginatorSeqNumber (), preq.GetMetric ());
-
+  m_hwmpSeqnoMetricDatabase[preq.GetOriginatorAddress ()] =
+    std::make_pair (preq.GetOriginatorSeqNumber (), preq.GetMetric ());
   NS_LOG_DEBUG("I am " << GetAddress () << "Accepted preq from address" << from << ", preq:" << preq);
   std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
   //Add reactive path to originator:
   if (
-      ((m_rtable->LookupReactive (preq.GetOriginatorAddress ())).retransmitter == Mac48Address::GetBroadcast ()) ||
-      ((m_rtable->LookupReactive (preq.GetOriginatorAddress ())).metric > preq.GetMetric ())
+      (freshInfo) ||
+      (
+        (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).retransmitter == Mac48Address::GetBroadcast ()) ||
+        (m_rtable->LookupReactive (preq.GetOriginatorAddress ()).metric > preq.GetMetric ())
       )
+     )
     {
       m_rtable->AddReactivePath (
           preq.GetOriginatorAddress (),
@@ -432,13 +437,12 @@
           preq.GetMetric (),
           MicroSeconds (preq.GetLifetime () * 1024),
           preq.GetOriginatorSeqNumber ()
-          );
+        );
       ReactivePathResolved (preq.GetOriginatorAddress ());
     }
-  //Add reactive path for precursor:
   if (
-      ((m_rtable->LookupReactive (fromMp)).retransmitter == Mac48Address::GetBroadcast ()) ||
-      ((m_rtable->LookupReactive (fromMp)).metric > preq.GetMetric ())
+      (m_rtable->LookupReactive (fromMp).retransmitter == Mac48Address::GetBroadcast ()) ||
+      (m_rtable->LookupReactive (fromMp).metric > metric)
       )
     {
       m_rtable->AddReactivePath (
@@ -484,7 +488,7 @@
                   GetAddress (),
                   preq.GetOriginatorAddress (),
                   from,
-                  preq.GetMetric (),
+                  (uint32_t)0,
                   preq.GetOriginatorSeqNumber (),
                   GetNextHwmpSeqno (),
                   preq.GetLifetime (),
@@ -514,9 +518,6 @@
       if ((! ((*i)->IsDo ())) && (result.retransmitter != Mac48Address::GetBroadcast ()))
         {
           //have a valid information and can answer
-          //!NB: If there is information from peer - set lifetime as
-          //we have got from PREQ, and set the rest lifetime of the
-          //route if the information is correct
           uint32_t lifetime = result.lifetime.GetMicroSeconds () / 1024;
           if ((lifetime > 0) && ((int32_t)(result.seqnum - (*i)->GetDestSeqNumber ()) >= 0))
             {
@@ -530,6 +531,8 @@
                   lifetime,
                   interface
                   );
+              m_rtable->AddPrecursor ((*i)->GetDestinationAddress (), interface, from,
+                  MicroSeconds (preq.GetLifetime () * 1024));
               if ((*i)->IsRf ())
                 {
                   (*i)->SetFlags (true, false, (*i)->IsUsn ()); //DO = 1, RF = 0
@@ -561,38 +564,52 @@
   //acceptance cretirea:
   std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
       prep.GetOriginatorAddress ());
-  if ((i != m_hwmpSeqnoMetricDatabase.end ()) && ((int32_t)(i->second.first - prep.GetOriginatorSeqNumber ()) > 0))
+  bool freshInfo (true);
+  if (i != m_hwmpSeqnoMetricDatabase.end ())
     {
-      return;
+      if ((int32_t)(i->second.first - prep.GetOriginatorSeqNumber ()) > 0)
+        {
+          return;
+        }
+      if (i->second.first == prep.GetOriginatorSeqNumber ())
+        {
+          freshInfo = false;
+        }
     }
   m_hwmpSeqnoMetricDatabase[prep.GetOriginatorAddress ()] = std::make_pair (prep.GetOriginatorSeqNumber (), prep.GetMetric ());
   //update routing info
   //Now add a path to destination and add precursor to source
   NS_LOG_DEBUG ("I am " << GetAddress () << ", received prep from " << prep.GetOriginatorAddress () << ", receiver was:" << from);
   HwmpRtable::LookupResult result = m_rtable->LookupReactive (prep.GetDestinationAddress ());
-  //Add a reactive path only if it is better than existing:
+  //Add a reactive path only if seqno is fresher or it improves the
+  //metric
   if (
-      ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).retransmitter == Mac48Address::GetBroadcast ()) ||
-      ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).metric > prep.GetMetric ())
+      (freshInfo) ||
+      (
+       ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).retransmitter == Mac48Address::GetBroadcast ()) ||
+       ((m_rtable->LookupReactive (prep.GetOriginatorAddress ())).metric > prep.GetMetric ())
       )
+     )
     {
       m_rtable->AddReactivePath (
           prep.GetOriginatorAddress (),
           from,
           interface,
           prep.GetMetric (),
-          MicroSeconds(prep.GetLifetime () * 1024),
+          MicroSeconds (prep.GetLifetime () * 1024),
           prep.GetOriginatorSeqNumber ());
-      m_rtable->AddPrecursor (prep.GetDestinationAddress (), interface, from);
+      m_rtable->AddPrecursor (prep.GetDestinationAddress (), interface, from,
+          MicroSeconds (prep.GetLifetime () * 1024));
       if (result.retransmitter != Mac48Address::GetBroadcast ())
         {
-          m_rtable->AddPrecursor (prep.GetOriginatorAddress (), interface, result.retransmitter);
+          m_rtable->AddPrecursor (prep.GetOriginatorAddress (), interface, result.retransmitter,
+              result.lifetime);
         }
       ReactivePathResolved (prep.GetOriginatorAddress ());
     }
   if (
       ((m_rtable->LookupReactive (fromMp)).retransmitter == Mac48Address::GetBroadcast ()) ||
-      ((m_rtable->LookupReactive (fromMp)).metric > prep.GetMetric ())
+      ((m_rtable->LookupReactive (fromMp)).metric > metric)
       )
     {
       m_rtable->AddReactivePath (
@@ -611,11 +628,6 @@
     }
   if (result.retransmitter == Mac48Address::GetBroadcast ())
     {
-      //try to look for default route
-      result = m_rtable->LookupProactive ();
-    }
-  if (result.retransmitter == Mac48Address::GetBroadcast ())
-    {
       return;
     }
   //Forward PREP
@@ -665,7 +677,7 @@
   prep.SetDestinationAddress (dst);
   prep.SetDestinationSeqNumber (destinationSN);
   prep.SetLifetime (lifetime);
-  prep.SetMetric (0);
+  prep.SetMetric (initMetric);
   prep.SetOriginatorAddress (src);
   prep.SetOriginatorSeqNumber (originatorDsn);
   HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (interface);
@@ -1008,7 +1020,6 @@
   Time randomStart = Seconds (coefficient.GetValue ());
   m_proactivePreqTimer = Simulator::Schedule (randomStart, &HwmpProtocol::SendProactivePreq, this);
   NS_LOG_DEBUG ("ROOT IS: " << m_address);
-  SendProactivePreq ();
   m_isRoot = true;
 }
 void
--- a/src/devices/mesh/dot11s/hwmp-rtable.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/mesh/dot11s/hwmp-rtable.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -84,11 +84,12 @@
 }
 void
 HwmpRtable::AddPrecursor (Mac48Address destination, uint32_t precursorInterface,
-    Mac48Address precursorAddress)
+    Mac48Address precursorAddress, Time lifetime)
 {
-  std::pair<uint32_t, Mac48Address> precursor;
-  precursor.first = precursorInterface;
-  precursor.second = precursorAddress;
+  Precursor precursor;
+  precursor.interface = precursorInterface;
+  precursor.address = precursorAddress;
+  precursor.whenExpire = Simulator::Now () + lifetime;
   std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
   if (i != m_routes.end ())
     {
@@ -97,9 +98,10 @@
         {
           //NB: Only one active route may exist, so do not check
           //interface ID, just address
-          if (i->second.precursors[j].second == precursorAddress)
+          if (i->second.precursors[j].address == precursorAddress)
             {
               should_add = false;
+              i->second.precursors[j].whenExpire = precursor.whenExpire;
               break;
             }
         }
@@ -108,17 +110,6 @@
           i->second.precursors.push_back (precursor);
         }
     }
-  if (m_root.root == destination)
-    {
-      for (unsigned int j = 0; j < m_root.precursors.size (); j++)
-        {
-          if (m_root.precursors[j].second == precursorAddress)
-            {
-              return;
-            }
-        }
-    }
-  m_root.precursors.push_back (precursor);
 }
 void
 HwmpRtable::DeleteProactivePath ()
@@ -221,27 +212,12 @@
   std::map<Mac48Address, ReactiveRoute>::iterator route = m_routes.find (destination);
   if (route != m_routes.end ())
     {
-      for (unsigned int i = 0; i < route->second.precursors.size (); i++)
-        {
-          retval.push_back (route->second.precursors[i]);
-        }
-    }
-  if (m_root.root == destination)
-    {
-      for (unsigned int i = 0; i < m_root.precursors.size (); i++)
+      for (std::vector<Precursor>::const_iterator i = route->second.precursors.begin ();
+          i != route->second.precursors.end (); i++)
         {
-          bool should_add = true;
-          for (unsigned int j = 0; j < retval.size (); j++)
+          if (i->whenExpire > Simulator::Now ())
             {
-              if (retval[j].second == m_root.precursors[i].second)
-                {
-                  should_add = false;
-                  break;
-                }
-            }
-          if (should_add)
-            {
-              retval.push_back (m_root.precursors[i]);
+              retval.push_back (std::make_pair(i->interface, i->address));
             }
         }
     }
--- a/src/devices/mesh/dot11s/hwmp-rtable.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/mesh/dot11s/hwmp-rtable.h	Mon Nov 16 13:35:38 2009 +0300
@@ -85,7 +85,7 @@
     Time  lifetime,
     uint32_t seqnum
   );
-  void AddPrecursor (Mac48Address destination, uint32_t precursorInterface, Mac48Address precursorAddress);
+  void AddPrecursor (Mac48Address destination, uint32_t precursorInterface, Mac48Address precursorAddress, Time lifetime);
   PrecursorList GetPrecursors (Mac48Address destination);
   void DeleteProactivePath ();
   void DeleteProactivePath (Mac48Address root);
@@ -109,6 +109,12 @@
 
 private:
   /// Route found in reactive mode
+  struct Precursor
+  {
+    Mac48Address address;
+    uint32_t interface;
+    Time whenExpire;
+  };
   struct ReactiveRoute
   {
     Mac48Address retransmitter;
@@ -116,7 +122,7 @@
     uint32_t metric;
     Time whenExpire;
     uint32_t seqnum;
-    std::vector<std::pair<uint32_t, Mac48Address> > precursors;
+    std::vector<Precursor> precursors;
   };
   /// Route fond in proactive mode
   struct ProactiveRoute
@@ -127,7 +133,7 @@
     uint32_t metric;
     Time whenExpire;
     uint32_t seqnum;
-    std::vector<std::pair<uint32_t, Mac48Address> > precursors;
+    std::vector<Precursor> precursors;
   };
 
   /// List of routes
--- a/src/devices/mesh/dot11s/ie-dot11s-beacon-timing.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/mesh/dot11s/ie-dot11s-beacon-timing.h	Mon Nov 16 13:35:38 2009 +0300
@@ -31,7 +31,7 @@
  * \ingroup dot11s
  * \brief Describes one unit of beacon timing element
  */
-class IeBeaconTimingUnit : public RefCountBase
+class IeBeaconTimingUnit : public SimpleRefCount<IeBeaconTimingUnit>
 {
 public:
   IeBeaconTimingUnit ();
--- a/src/devices/mesh/dot11s/ie-dot11s-prep.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/mesh/dot11s/ie-dot11s-prep.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -135,6 +135,7 @@
 IePrep::DecrementTtl ()
 {
   m_ttl--;
+  m_hopcount ++;
 }
 
 void
--- a/src/devices/mesh/dot11s/ie-dot11s-preq.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/mesh/dot11s/ie-dot11s-preq.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -317,17 +317,17 @@
 IePreq::Print (std::ostream &os) const
 {
   os << std::endl << "<information_element id=" << ElementId () << ">" << std::endl;
-  os << " originator address  = " << m_originatorAddress << "std::endl";
-  os << " TTL                 = " << (uint16_t) m_ttl << "std::endl";
-  os << " hop count           = " << (uint16_t) m_hopCount << "std::endl";
-  os << " metric              = " << m_metric << "std::endl";
-  os << " seqno               = " << m_originatorSeqNumber << "std::endl";
-  os << " lifetime            = " << m_lifetime << "std::endl";
-  os << " preq ID             = " << m_preqId << "std::endl";
-  os << " Destinations are:std::endl";
+  os << " originator address  = " << m_originatorAddress << std::endl;
+  os << " TTL                 = " << (uint16_t) m_ttl << std::endl;
+  os << " hop count           = " << (uint16_t) m_hopCount << std::endl;
+  os << " metric              = " << m_metric << std::endl;
+  os << " seqno               = " << m_originatorSeqNumber << std::endl;
+  os << " lifetime            = " << m_lifetime << std::endl;
+  os << " preq ID             = " << m_preqId << std::endl;
+  os << " Destinations are:" << std::endl;
   for (int j = 0; j < m_destCount; j++)
     {
-      os << "    " << m_destinations[j]->GetDestinationAddress () << "std::endl";
+      os << "    " << m_destinations[j]->GetDestinationAddress () << std::endl;
     }
   os << "</information_element>" << std::endl;
 }
--- a/src/devices/mesh/dot11s/ie-dot11s-preq.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/mesh/dot11s/ie-dot11s-preq.h	Mon Nov 16 13:35:38 2009 +0300
@@ -33,7 +33,7 @@
  * \brief Describes an address unit in PREQ information element
  * See 7.3.2.96 for more details
  */
-class DestinationAddressUnit : public RefCountBase
+class DestinationAddressUnit : public SimpleRefCount<DestinationAddressUnit>
 {
 public:
   DestinationAddressUnit ();
--- a/src/devices/mesh/dot11s/ie-dot11s-rann.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/mesh/dot11s/ie-dot11s-rann.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -152,12 +152,12 @@
 IeRann::Print (std::ostream &os) const
 {
   os << std::endl << "<information_element id=" << ElementId () << ">" << std::endl;
-  os << "  flags              = " << (int) m_flags << "std::endl";
-  os << "  hop count          = " << (int) m_hopcount << "std::endl";
-  os << "  TTL                = " << (int) m_ttl << "std::endl";
-  os << "  originator address = " << m_originatorAddress << "std::endl";
-  os << "  dst seq. number    = " << m_destSeqNumber << "std::endl";
-  os << "  metric             = " << m_metric << "std::endl";
+  os << "  flags              = " << (int) m_flags << std::endl;
+  os << "  hop count          = " << (int) m_hopcount << std::endl;
+  os << "  TTL                = " << (int) m_ttl << std::endl;
+  os << "  originator address = " << m_originatorAddress << std::endl;
+  os << "  dst seq. number    = " << m_destSeqNumber << std::endl;
+  os << "  metric             = " << m_metric << std::endl;
   os << "</information_element>" << std::endl;
 }
 
--- a/src/devices/mesh/dot11s/peer-link-frame.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/mesh/dot11s/peer-link-frame.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -69,7 +69,7 @@
     }
 }
 PeerLinkFrameStart::PlinkFrameStartFields
-PeerLinkFrameStart::GetFields ()
+PeerLinkFrameStart::GetFields () const
 {
   PlinkFrameStartFields retval;
   //TODO: protocol version:
--- a/src/devices/mesh/dot11s/peer-link-frame.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/mesh/dot11s/peer-link-frame.h	Mon Nov 16 13:35:38 2009 +0300
@@ -62,7 +62,7 @@
   //action header knows about subtype
   void SetPlinkFrameSubtype (uint8_t subtype);
   void SetPlinkFrameStart (PlinkFrameStartFields);
-  PlinkFrameStartFields GetFields ();
+  PlinkFrameStartFields GetFields () const;
   /** \name Inherited from header:
    * \{
    */
--- a/src/devices/mesh/mesh-wifi-interface-mac-plugin.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/mesh/mesh-wifi-interface-mac-plugin.h	Mon Nov 16 13:35:38 2009 +0300
@@ -25,7 +25,7 @@
 #include "ns3/packet.h"
 #include "ns3/mac48-address.h"
 #include "ns3/mesh-wifi-beacon.h"
-#include "ns3/ref-count-base.h"
+#include "ns3/simple-ref-count.h"
 
 namespace ns3 {
 
@@ -38,7 +38,7 @@
  * 
  * TODO: plugins description
  */
-class MeshWifiInterfaceMacPlugin : public RefCountBase
+class MeshWifiInterfaceMacPlugin : public SimpleRefCount<MeshWifiInterfaceMacPlugin>
 {
 public:
   /// This is for subclasses
--- a/src/devices/mesh/wifi-information-element-vector.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/mesh/wifi-information-element-vector.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -36,6 +36,10 @@
 #include "dot11s/ie-dot11s-rann.h"
 
 namespace ns3 {
+
+WifiInformationElement::~WifiInformationElement ()
+{}
+
 bool
 operator< (WifiInformationElement const & a, WifiInformationElement const & b)
 {
@@ -58,7 +62,8 @@
 WifiInformationElementVector::GetTypeId ()
 {
   static TypeId tid = TypeId ("ns3::WifiInformationElementVector")
-                      .SetParent<Header> ();
+                      .SetParent<Header> ()
+                      .AddConstructor<WifiInformationElementVector> ();
   return tid;
 }
 TypeId
--- a/src/devices/mesh/wifi-information-element-vector.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/mesh/wifi-information-element-vector.h	Mon Nov 16 13:35:38 2009 +0300
@@ -23,6 +23,7 @@
 #define IE_VECTOR_H
 
 #include "ns3/header.h"
+#include "ns3/simple-ref-count.h"
 
 namespace ns3 {
 class Packet;
@@ -79,9 +80,10 @@
  * Element ID as defined in this standard. The Length field specifies the number of octets in the Information
  * field.
  */
-class WifiInformationElement : public RefCountBase
+class WifiInformationElement : public SimpleRefCount<WifiInformationElement>
 {
 public:
+  virtual ~WifiInformationElement ();
   ///\name Each subclass must implement
   //\{
   virtual void Print (std::ostream &os) const = 0;
--- a/src/devices/point-to-point/point-to-point-channel.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/point-to-point/point-to-point-channel.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -93,8 +93,9 @@
 
   uint32_t wire = src == m_link[0].m_src ? 0 : 1;
 
-  Simulator::Schedule (txTime + m_delay, &PointToPointNetDevice::Receive,
-    m_link[wire].m_dst, p);
+  Simulator::ScheduleWithContext (m_link[wire].m_dst->GetNode ()->GetId (),
+                                  txTime + m_delay, &PointToPointNetDevice::Receive,
+                                  m_link[wire].m_dst, p);
 
   // Call the tx anim callback on the net device
   m_txrxPointToPoint (p, src, m_link[wire].m_dst, txTime, txTime + m_delay);
--- a/src/devices/point-to-point/point-to-point-net-device.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/point-to-point/point-to-point-net-device.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -173,8 +173,8 @@
 PointToPointNetDevice::AddHeader(Ptr<Packet> p, uint16_t protocolNumber)
 {
   NS_LOG_FUNCTION_NOARGS ();
-  NS_ASSERT_MSG (protocolNumber == 0x800, "PointToPointNetDevice::AddHeader(): protocolNumber must be 0x800");
   PppHeader ppp;
+  ppp.SetProtocol(EtherToPpp(protocolNumber));
   p->AddHeader (ppp);
 }
 
@@ -184,7 +184,7 @@
   NS_LOG_FUNCTION_NOARGS ();
   PppHeader ppp;
   p->RemoveHeader (ppp);
-  param = 0x800;
+  param = PppToEther(ppp.GetProtocol());
   return true;
 }
 
@@ -655,5 +655,29 @@
   return m_mtu;
 }
 
+  uint16_t
+PointToPointNetDevice::PppToEther(uint16_t proto)
+{
+  switch(proto)
+    {
+      case 0x0021: return 0x0800; //IPv4
+      case 0x0057: return 0x86DD; //IPv6
+      default: NS_ASSERT_MSG(false, "PPP Protocol number not defined!");
+    }
+  return 0;
+}
+
+  uint16_t
+PointToPointNetDevice::EtherToPpp(uint16_t proto)
+{
+  switch(proto)
+    {
+      case 0x0800: return 0x0021; //IPv4
+      case 0x86DD: return 0x0057; //IPv6
+      default: NS_ASSERT_MSG(false, "PPP Protocol number not defined!");
+    }
+  return 0;
+}
+
 
 } // namespace ns3
--- a/src/devices/point-to-point/point-to-point-net-device.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/point-to-point/point-to-point-net-device.h	Mon Nov 16 13:35:38 2009 +0300
@@ -548,6 +548,20 @@
   uint32_t m_mtu;
 
   Ptr<Packet> m_currentPkt;
+
+  /**
+   * \brief PPP to Ethernet protocol number mapping
+   * \param protocol A PPP protocol number
+   * \return The corresponding Ethernet protocol number
+   */
+  static uint16_t PppToEther(uint16_t protocol);
+
+  /**
+   * \brief Ethernet to PPP protocol number mapping
+   * \param protocol An Ethernet protocol number
+   * \return The corresponding PPP protocol number
+   */
+  static uint16_t EtherToPpp(uint16_t protocol);
 };
 
 } // namespace ns3
--- a/src/devices/point-to-point/ppp-header.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/point-to-point/ppp-header.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -56,7 +56,7 @@
 void 
 PppHeader::Print (std::ostream &os) const
 {
-  os << "Point-to-Point Protocol: IP (0x0021)";
+  os << "Point-to-Point Protocol: " << m_protocol;
 }
 
   uint32_t
@@ -68,15 +68,27 @@
   void
 PppHeader::Serialize (Buffer::Iterator start) const
 {
-  start.WriteHtonU16 (0x0021);
+  start.WriteHtonU16 (m_protocol);
 }
 
   uint32_t
 PppHeader::Deserialize (Buffer::Iterator start)
 {
-  uint16_t data = start.ReadNtohU16 ();
-  NS_ABORT_MSG_UNLESS (data == 0x0021, "MyHeader::Deserialize(): expected protocol 0x0021");
-  return 2;
+  m_protocol = start.ReadNtohU16 ();
+  return GetSerializedSize();
 }
 
+  void
+PppHeader::SetProtocol (uint16_t protocol)
+{
+  m_protocol=protocol;
+}
+
+  uint16_t
+PppHeader::GetProtocol (void)
+{
+  return m_protocol;
+}
+
+
 } // namespace ns3
--- a/src/devices/point-to-point/ppp-header.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/point-to-point/ppp-header.h	Mon Nov 16 13:35:38 2009 +0300
@@ -28,9 +28,9 @@
  *
  * This class can be used to add a header to PPP packet.  Currently we do not
  * implement any of the state machine in RFC 1661, we just encapsulate the
- * inbound packet as an IP version 4 type and send it on.  The goal here is
- * not really to implement the point-to-point protocol, but to encapsulate our
- * packets in a known protocol so packet sniffers can parse them.
+ * inbound packet send it on.  The goal here is not really to implement the
+ * point-to-point protocol, but to encapsulate our packets in a known protocol
+ * so packet sniffers can parse them.
  *
  * if PPP is transmitted over a serial link, it will typically be framed in
  * some way derivative of IBM SDLC (HDLC) with all that that entails.
@@ -41,20 +41,20 @@
  * teach the PcapWriter about the appropriate data link type (DLT_PPP = 9),
  * and we need to add a PPP header to each packet.  Since we are not using
  * framed PPP, this just means prepending the sixteen bit PPP protocol number
- * (0x0021) to the packet.  The ns-3 way to do this is via a class that 
- * inherits from class Header.
+ * to the packet.  The ns-3 way to do this is via a class that inherits from
+ * class Header.
  */
 class PppHeader : public Header 
 {
 public:
 
   /**
-   * \brief Construct an IP version 4 PPP header.
+   * \brief Construct a PPP header.
    */
   PppHeader ();
 
   /**
-   * \brief Destroy an IP version 4 PPP header.
+   * \brief Destroy a PPP header.
    */
   virtual ~PppHeader ();
 
@@ -64,6 +64,31 @@
   virtual void Serialize (Buffer::Iterator start) const;
   virtual uint32_t Deserialize (Buffer::Iterator start);
   virtual uint32_t GetSerializedSize (void) const;
+
+  /**
+   * \brief Set the protocol type carried by this PPP packet
+   *
+   * The type numbers to be used are defined in RFC3818
+   *
+   * \param protocol the protocol type being carried
+   */
+  void SetProtocol(uint16_t protocol);
+
+  /**
+   * \brief Get the protocol type carried by this PPP packet
+   *
+   * The type numbers to be used are defined in RFC3818
+   *
+   * \return the protocol type being carried
+   */
+  uint16_t GetProtocol(void);
+
+private:
+
+  /**
+   * \brief The PPP protocol type of the payload packet
+   */
+  uint16_t m_protocol;
 };
 
 }; // namespace ns3
--- a/src/devices/wifi/interference-helper.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/wifi/interference-helper.h	Mon Nov 16 13:35:38 2009 +0300
@@ -27,7 +27,7 @@
 #include "wifi-preamble.h"
 #include "wifi-phy-standard.h"
 #include "ns3/nstime.h"
-#include "ns3/ref-count-base.h"
+#include "ns3/simple-ref-count.h"
 
 namespace ns3 {
 
@@ -36,13 +36,13 @@
 class InterferenceHelper
 {
 public:
-  class Event : public RefCountBase
+  class Event : public SimpleRefCount<InterferenceHelper::Event>
   {
   public:
     Event (uint32_t size, WifiMode payloadMode, 
 	     enum WifiPreamble preamble,
 	     Time duration, double rxPower);
-    virtual ~Event ();
+    ~Event ();
   
     Time GetDuration (void) const;
     Time GetStartTime (void) const;
--- a/src/devices/wifi/nqap-wifi-mac.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/wifi/nqap-wifi-mac.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -90,6 +90,8 @@
   m_dca->SetManager (m_dcfManager);
   m_dca->SetTxOkCallback (MakeCallback (&NqapWifiMac::TxOk, this));
   m_dca->SetTxFailedCallback (MakeCallback (&NqapWifiMac::TxFailed, this));
+
+  m_enableBeaconGeneration = false;
 }
 NqapWifiMac::~NqapWifiMac ()
 {
@@ -110,6 +112,7 @@
   m_dca = 0;
   m_beaconDca = 0;
   m_stationManager = 0;
+  m_enableBeaconGeneration = false;
   m_beaconEvent.Cancel ();
   WifiMac::DoDispose ();
 }
@@ -118,20 +121,21 @@
 NqapWifiMac::SetBeaconGeneration (bool enable)
 {
   NS_LOG_FUNCTION (this << enable);
-  if (enable)
+  if (!enable)
+    {
+      m_beaconEvent.Cancel ();
+    } 
+  else if (enable && !m_enableBeaconGeneration)
     {
       m_beaconEvent = Simulator::ScheduleNow (&NqapWifiMac::SendOneBeacon, this);
     }
-  else
-    {
-      m_beaconEvent.Cancel ();
-    }
+  m_enableBeaconGeneration = enable;
 }
 
 bool
 NqapWifiMac::GetBeaconGeneration (void) const
 {
-  return m_beaconEvent.IsRunning ();
+  return m_enableBeaconGeneration;
 }
 Time 
 NqapWifiMac::GetBeaconInterval (void) const
@@ -594,4 +598,15 @@
 }
 
 
+void
+NqapWifiMac::DoStart (void)
+{
+  m_beaconEvent.Cancel ();
+  if (m_enableBeaconGeneration)
+    {
+      m_beaconEvent = Simulator::ScheduleNow (&NqapWifiMac::SendOneBeacon, this);
+    }
+  WifiMac::DoStart ();
+}
+
 } // namespace ns3
--- a/src/devices/wifi/nqap-wifi-mac.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/wifi/nqap-wifi-mac.h	Mon Nov 16 13:35:38 2009 +0300
@@ -112,6 +112,7 @@
   void SetBeaconGeneration (bool enable);
   bool GetBeaconGeneration (void) const;
   virtual void DoDispose (void);
+  virtual void DoStart (void);
   NqapWifiMac (const NqapWifiMac & ctor_arg);
   NqapWifiMac &operator = (const NqapWifiMac &o);
   Ptr<DcaTxop> GetDcaTxop (void) const;
@@ -123,6 +124,7 @@
   Ptr<WifiPhy> m_phy;
   Callback<void, Ptr<Packet>,Mac48Address, Mac48Address> m_upCallback;
   Time m_beaconInterval;
+  bool m_enableBeaconGeneration;
 
   DcfManager *m_dcfManager;
   MacRxMiddle *m_rxMiddle;
--- a/src/devices/wifi/qap-wifi-mac.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/wifi/qap-wifi-mac.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -109,6 +109,8 @@
   SetQueue (AC_VI);
   SetQueue (AC_BE);
   SetQueue (AC_BK);
+
+  m_enableBeaconGeneration = false;
 }
 
 QapWifiMac::~QapWifiMac ()
@@ -129,6 +131,7 @@
   m_low = 0;
   m_phy = 0;
   m_beaconDca = 0;
+  m_enableBeaconGeneration = false;
   m_beaconEvent.Cancel ();
   m_stationManager = 0;
   for (Queues::iterator i = m_queues.begin (); i != m_queues.end (); ++i)
@@ -142,20 +145,21 @@
 QapWifiMac::SetBeaconGeneration (bool enable)
 {
   NS_LOG_FUNCTION (this << enable);
-  if (enable)
+  if (!enable)
+    {
+      m_beaconEvent.Cancel ();
+    }
+  else if (enable && !m_enableBeaconGeneration)
     {
       m_beaconEvent = Simulator::ScheduleNow (&QapWifiMac::SendOneBeacon, this);
     }
-  else
-    {
-      m_beaconEvent.Cancel ();
-    }
+  m_enableBeaconGeneration = enable;
 }
 
 bool
 QapWifiMac::GetBeaconGeneration (void) const
 {
-  return m_beaconEvent.IsRunning ();
+  return m_enableBeaconGeneration;
 }
 
 Time
@@ -772,4 +776,15 @@
     }
 }
 
+void
+QapWifiMac::DoStart (void)
+{
+  m_beaconEvent.Cancel ();
+  if (m_enableBeaconGeneration)
+    {
+      m_beaconEvent = Simulator::ScheduleNow (&QapWifiMac::SendOneBeacon, this);
+    }
+  WifiMac::DoStart ();
+}
+
 }  //namespace ns3
--- a/src/devices/wifi/qap-wifi-mac.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/wifi/qap-wifi-mac.h	Mon Nov 16 13:35:38 2009 +0300
@@ -92,6 +92,7 @@
   typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> >::const_iterator DeaggregatedMsdusCI;
   
   virtual void DoDispose (void);
+  virtual void DoStart (void);
   void Receive (Ptr<Packet> packet, WifiMacHeader const*hdr);
   void ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to);
   void ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to);
@@ -130,6 +131,7 @@
   Ssid m_ssid;
   EventId m_beaconEvent;
   Time m_beaconInterval;
+  bool m_enableBeaconGeneration;
   Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> m_forwardUp;
 };
 
--- a/src/devices/wifi/yans-wifi-channel.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/wifi/yans-wifi-channel.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -92,8 +92,19 @@
           NS_LOG_DEBUG ("propagation: txPower="<<txPowerDbm<<"dbm, rxPower="<<rxPowerDbm<<"dbm, "<<
                         "distance="<<senderMobility->GetDistanceFrom (receiverMobility)<<"m, delay="<<delay);
           Ptr<Packet> copy = packet->Copy ();
-          Simulator::Schedule (delay, &YansWifiChannel::Receive, this, 
-                               j, copy, rxPowerDbm, wifiMode, preamble);
+          Ptr<Object> dstNetDevice = m_phyList[j]->GetDevice ();
+          uint32_t dstNode;
+          if (dstNetDevice == 0)
+            {
+              dstNode = 0xffffffff;
+            }
+          else
+            {
+              dstNode = dstNetDevice->GetObject<NetDevice> ()->GetNode ()->GetId ();
+            }
+          Simulator::ScheduleWithContext (dstNode,
+                                          delay, &YansWifiChannel::Receive, this, 
+                                          j, copy, rxPowerDbm, wifiMode, preamble);
         }
     }
 }
--- a/src/devices/wifi/yans-wifi-phy.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/devices/wifi/yans-wifi-phy.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -52,14 +52,14 @@
     .AddAttribute ("EnergyDetectionThreshold",
                    "The energy of a received signal should be higher than "
                    "this threshold (dbm) to allow the PHY layer to detect the signal.",
-                   DoubleValue (-140.0),
+                   DoubleValue (-96.0),
                    MakeDoubleAccessor (&YansWifiPhy::SetEdThreshold,
                                        &YansWifiPhy::GetEdThreshold),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("CcaMode1Threshold",
                    "The energy of a received signal should be higher than "
                    "this threshold (dbm) to allow the PHY layer to declare CCA BUSY state",
-                   DoubleValue (-140.0),
+                   DoubleValue (-99.0),
                    MakeDoubleAccessor (&YansWifiPhy::SetCcaMode1Threshold,
                                        &YansWifiPhy::GetCcaMode1Threshold),
                    MakeDoubleChecker<double> ())
@@ -114,12 +114,20 @@
                    TimeValue (MicroSeconds (250)),
                    MakeTimeAccessor (&YansWifiPhy::m_channelSwitchDelay), 
                    MakeTimeChecker ())
+    .AddAttribute ("ChannelNumber",
+                   "Channel center frequency = Channel starting frequency + 5 MHz * (nch - 1)",
+                   UintegerValue (1),
+                   MakeUintegerAccessor (&YansWifiPhy::SetChannelNumber, 
+                                         &YansWifiPhy::GetChannelNumber),
+                   MakeUintegerChecker<uint16_t> ())
+
     ;
   return tid;
 }
 
 YansWifiPhy::YansWifiPhy ()
-  :  m_endSyncEvent (),
+  :  m_channelNumber (1),
+     m_endSyncEvent (),
      m_random (0.0, 1.0),
      m_channelStartingFrequency (0)
 {
@@ -304,13 +312,20 @@
 {
   m_channel = channel;
   m_channel->Add (this);
-  m_channelNumber = 1;      // always start on channel starting frequency (channel 1)
 }
 
 void 
 YansWifiPhy::SetChannelNumber (uint16_t nch)
 {
-  NS_ASSERT(!IsStateSwitching()); 
+  if (Simulator::Now () == Seconds (0))
+    {
+      // this is not channel switch, this is initialization 
+      NS_LOG_DEBUG("start at channel " << nch);
+      m_channelNumber = nch;
+      return;
+    }
+
+  NS_ASSERT (!IsStateSwitching()); 
   switch (m_state->GetState ()) {
   case YansWifiPhy::SYNC:
     NS_LOG_DEBUG ("drop packet because of channel switching while reception");
--- a/src/helper/application-container.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/helper/application-container.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -85,7 +85,7 @@
   for (Iterator i = Begin (); i != End (); ++i)
     {
       Ptr<Application> app = *i;
-      app->Start (start);
+      app->SetStartTime (start);
     }
 }
 void 
@@ -94,7 +94,7 @@
   for (Iterator i = Begin (); i != End (); ++i)
     {
       Ptr<Application> app = *i;
-      app->Stop (stop);
+      app->SetStopTime (stop);
     }
 }
 
--- a/src/helper/qos-wifi-mac-helper.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/helper/qos-wifi-mac-helper.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -27,14 +27,7 @@
 namespace ns3 {
 
 QosWifiMacHelper::QosWifiMacHelper ()
-{
-  ObjectFactory defaultAggregator;
-  defaultAggregator.SetTypeId ("ns3::MsduStandardAggregator");
-  m_aggregators.insert (std::make_pair (AC_VO, defaultAggregator));
-  m_aggregators.insert (std::make_pair (AC_VI, defaultAggregator));
-  m_aggregators.insert (std::make_pair (AC_BE, defaultAggregator));
-  m_aggregators.insert (std::make_pair (AC_BK, defaultAggregator));
-}
+{}
 
 QosWifiMacHelper::~QosWifiMacHelper ()
 {}
@@ -77,8 +70,7 @@
                                           std::string n2, const AttributeValue &v2,
                                           std::string n3, const AttributeValue &v3)
 {
-  std::map<AccessClass, ObjectFactory>::iterator it;
-  it = m_aggregators.find (accessClass);
+  std::map<AccessClass, ObjectFactory>::iterator it = m_aggregators.find (accessClass);
   if (it != m_aggregators.end ())
     {
       it->second.SetTypeId (type);
@@ -87,17 +79,32 @@
       it->second.Set (n2, v2);
       it->second.Set (n3, v3);
     }
+  else
+    {
+      ObjectFactory factory;
+      factory.SetTypeId (type);
+      factory.Set (n0, v0);
+      factory.Set (n1, v1);
+      factory.Set (n2, v2);
+      factory.Set (n3, v3);
+      m_aggregators.insert (std::make_pair (accessClass, factory));
+    }
 }
 
 void
 QosWifiMacHelper::Setup (Ptr<WifiMac> mac, enum AccessClass ac, std::string dcaAttrName) const
 {
-  ObjectFactory factory  = m_aggregators.find (ac)->second;
-  PointerValue ptr;
-  mac->GetAttribute (dcaAttrName, ptr);
-  Ptr<EdcaTxopN> edca = ptr.Get<EdcaTxopN> ();
-  Ptr<MsduAggregator> aggregator = factory.Create<MsduAggregator> ();
-  edca->SetMsduAggregator (aggregator);
+  std::map<AccessClass, ObjectFactory>::const_iterator it = m_aggregators.find (ac);
+  if (it != m_aggregators.end ())
+    {
+      ObjectFactory factory = it->second;
+
+      PointerValue ptr;
+      mac->GetAttribute (dcaAttrName, ptr);
+      Ptr<EdcaTxopN> edca = ptr.Get<EdcaTxopN> ();
+      Ptr<MsduAggregator> aggregator = factory.Create<MsduAggregator> ();
+      edca->SetMsduAggregator (aggregator);
+    }
 }
 
 
--- a/src/internet-stack/ipv4-l3-protocol.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/internet-stack/ipv4-l3-protocol.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -82,8 +82,7 @@
 }
 
 Ipv4L3Protocol::Ipv4L3Protocol()
-  : m_nInterfaces (0),
-    m_identification (0)
+  : m_identification (0)
 {
   NS_LOG_FUNCTION_NOARGS ();
 }
@@ -266,9 +265,8 @@
 Ipv4L3Protocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
 {
   NS_LOG_FUNCTION (this << interface);
-  uint32_t index = m_nInterfaces;
+  uint32_t index = m_interfaces.size ();
   m_interfaces.push_back (interface);
-  m_nInterfaces++;
   return index;
 }
 
@@ -276,14 +274,9 @@
 Ipv4L3Protocol::GetInterface (uint32_t index) const
 {
   NS_LOG_FUNCTION (this << index);
-  uint32_t tmp = 0;
-  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
+  if (index < m_interfaces.size ())
     {
-      if (index == tmp) 
-	{
-	  return *i;
-	}
-      tmp++;
+      return m_interfaces[index];
     }
   return 0;
 }
@@ -292,7 +285,7 @@
 Ipv4L3Protocol::GetNInterfaces (void) const
 {
   NS_LOG_FUNCTION_NOARGS ();
-  return m_nInterfaces;
+  return m_interfaces.size ();
 }
 
 int32_t 
@@ -413,7 +406,7 @@
 
   for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
     {
-      NS_LOG_LOGIC ("Forwarding to raw socket");
+      NS_LOG_LOGIC ("Forwarding to raw socket"); 
       Ptr<Ipv4RawSocketImpl> socket = *i;
       socket->ForwardUp (packet, ipHeader, device);
     }
--- a/src/internet-stack/ipv4-l3-protocol.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/internet-stack/ipv4-l3-protocol.h	Mon Nov 16 13:35:38 2009 +0300
@@ -22,6 +22,7 @@
 #define IPV4_L3_PROTOCOL_H
 
 #include <list>
+#include <vector>
 #include <stdint.h>
 #include "ns3/ipv4-address.h"
 #include "ns3/ptr.h"
@@ -233,7 +234,7 @@
   Ptr<Icmpv4L4Protocol> GetIcmp (void) const;
   bool IsUnicast (Ipv4Address ad, Ipv4Mask interfaceMask) const;
 
-  typedef std::list<Ptr<Ipv4Interface> > Ipv4InterfaceList;
+  typedef std::vector<Ptr<Ipv4Interface> > Ipv4InterfaceList;
   typedef std::list<Ptr<Ipv4RawSocketImpl> > SocketList;
   typedef std::list<Ptr<Ipv4L4Protocol> > L4List_t;
 
--- a/src/internet-stack/udp-test.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/internet-stack/udp-test.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -77,6 +77,8 @@
 {
   Ptr<Packet> m_receivedPacket;
   Ptr<Packet> m_receivedPacket2;
+  void DoSendData (Ptr<Socket> socket, std::string to);
+  void SendData (Ptr<Socket> socket, std::string to);
 
 public:
   virtual bool DoRun (void);
@@ -120,6 +122,24 @@
   NS_ASSERT (availableData == m_receivedPacket2->GetSize ());
 }
 
+void
+UdpSocketImplTest::DoSendData (Ptr<Socket> socket, std::string to)
+{
+  Address realTo = InetSocketAddress (Ipv4Address(to.c_str()), 1234);
+  NS_TEST_EXPECT_MSG_EQ (socket->SendTo (Create<Packet> (123), 0, realTo),
+                         123, "XXX");
+}
+
+void
+UdpSocketImplTest::SendData (Ptr<Socket> socket, std::string to)
+{
+  m_receivedPacket = Create<Packet> ();
+  m_receivedPacket2 = Create<Packet> ();
+  Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), Seconds (0),
+                                  &UdpSocketImplTest::DoSendData, this, socket, to);
+  Simulator::Run ();
+}
+
 bool
 UdpSocketImplTest::DoRun (void)
 {
@@ -203,11 +223,7 @@
   // ------ Now the tests ------------
 
   // Unicast test
-  m_receivedPacket = Create<Packet> ();
-  m_receivedPacket2 = Create<Packet> ();
-  NS_TEST_EXPECT_MSG_EQ (txSocket->SendTo ( Create<Packet> (123), 0, 
-    InetSocketAddress (Ipv4Address("10.0.0.1"), 1234)), 123, "trivial");
-  Simulator::Run ();
+  SendData (txSocket, "10.0.0.1");
   NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 123, "trivial");
   NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 0, "second interface should receive it");
 
@@ -216,11 +232,7 @@
 
   // Simple broadcast test
 
-  m_receivedPacket = Create<Packet> ();
-  m_receivedPacket2 = Create<Packet> ();
-  NS_TEST_EXPECT_MSG_EQ (txSocket->SendTo ( Create<Packet> (123), 0, 
-    InetSocketAddress (Ipv4Address("255.255.255.255"), 1234)), 123, "trivial");
-  Simulator::Run ();
+  SendData (txSocket, "255.255.255.255");
   NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 123, "trivial");
   NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 0, "second socket should not receive it (it is bound specifically to the second interface's address");
 
@@ -237,11 +249,7 @@
   rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketImplTest::ReceivePkt2, this));
   NS_TEST_EXPECT_MSG_EQ (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("0.0.0.0"), 1234)), 0, "trivial");
 
-  m_receivedPacket = Create<Packet> ();
-  m_receivedPacket2 = Create<Packet> ();
-  NS_TEST_EXPECT_MSG_EQ (txSocket->SendTo (Create<Packet> (123), 0,
-        InetSocketAddress (Ipv4Address("255.255.255.255"), 1234)), 123, "trivial");
-  Simulator::Run ();
+  SendData (txSocket, "255.255.255.255");
   NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 123, "trivial");
   NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 123, "trivial");
 
--- a/src/mobility/mobility.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/mobility/mobility.h	Mon Nov 16 13:35:38 2009 +0300
@@ -28,4 +28,9 @@
  *   - ns3::RandomDirection2dMobilityModel: a 2d random direction mobility
  *     model where the bounds of the mobility are are a rectangle.
  *
+ *   - ns3::WaypointMobilityModel: A model which determines paths from sets
+ *     of ns3::Waypoint objects, similar to using events to update velocity
+ *     and direction with a ns3::ConstantVelocityMobilityModel. This model
+ *     is slightly faster for this task and uses less memory.
+ *
  */
--- a/src/mobility/position-allocator.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/mobility/position-allocator.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -315,4 +315,72 @@
 }
 
 
+
+NS_OBJECT_ENSURE_REGISTERED (UniformDiscPositionAllocator);
+
+TypeId
+UniformDiscPositionAllocator::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::UniformDiscPositionAllocator")
+    .SetParent<PositionAllocator> ()
+    .SetGroupName ("Mobility")
+    .AddConstructor<UniformDiscPositionAllocator> ()
+    .AddAttribute ("rho",
+                   "The radius of the disc",
+                   DoubleValue (0.0),
+                   MakeDoubleAccessor (&UniformDiscPositionAllocator::m_rho),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("X",
+                   "The x coordinate of the center of the  disc.",
+                   DoubleValue (0.0),
+                   MakeDoubleAccessor (&UniformDiscPositionAllocator::m_x),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Y",
+                   "The y coordinate of the center of the  disc.",
+                   DoubleValue (0.0),
+                   MakeDoubleAccessor (&UniformDiscPositionAllocator::m_y),
+                   MakeDoubleChecker<double> ())
+    ;
+  return tid;
+}   
+
+UniformDiscPositionAllocator::UniformDiscPositionAllocator ()
+{}
+UniformDiscPositionAllocator::~UniformDiscPositionAllocator ()
+{}
+
+void 
+UniformDiscPositionAllocator::SetRho (double rho)
+{
+  m_rho = rho;
+}
+void 
+UniformDiscPositionAllocator::SetX (double x)
+{
+  m_x = x;
+}
+void 
+UniformDiscPositionAllocator::SetY (double y)
+{
+  m_y = y;
+}
+Vector
+UniformDiscPositionAllocator::GetNext (void) const
+{
+  UniformVariable r (-m_rho, m_rho);
+  double x,y;
+  do
+    {
+      x = r.GetValue ();
+      y = r.GetValue ();
+    }
+  while (sqrt(x*x + y*y) > m_rho);
+  
+  x += m_x;
+  y += m_y;
+  NS_LOG_DEBUG ("Disc position x=" << x << ", y=" << y);
+  return Vector (x, y, 0.0);
+}
+
+
 } // namespace ns3 
--- a/src/mobility/position-allocator.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/mobility/position-allocator.h	Mon Nov 16 13:35:38 2009 +0300
@@ -182,7 +182,8 @@
 
 /**
  * \brief allocate random positions within a disc
- * according to a pair of random variables.
+ * according to a given distribution for the polar coordinates of each
+ * node with respect to the provided center of the disc 
  */
 class RandomDiscPositionAllocator : public PositionAllocator
 {
@@ -204,6 +205,54 @@
   double m_y;
 };
 
+
+/**
+ * UniformDiscPositionAllocator allocates the positions randomly within a disc \f$ D \f$ lying on the
+ * plane \f$ z=0 \f$ and having center at coordinates \f$ (x,y,0) \f$
+ * and radius \f$ \rho \f$. The random positions are chosen such that,
+ * for any subset \f$ S \subset D \f$, the expected value of the
+ * fraction of points which fall into \f$ S \subset D \f$ corresponds
+ * to \f$ \frac{|S|}{|D|} \f$, i.e., to the ratio of the area of the
+ * subset to the area of the whole disc. 
+ *
+ * \note using UniformDiscPositionAllocator is not equivalent to using
+ * a RandomDiscPositionAllocator with a uniformly-distributed radius,
+ * since doing that would results in a point distribution which is
+ * more dense towards the center of the disc.
+ */
+class UniformDiscPositionAllocator : public PositionAllocator
+{
+public:
+  static TypeId GetTypeId (void);
+  UniformDiscPositionAllocator ();
+  virtual ~UniformDiscPositionAllocator ();
+
+  /** 
+   * 
+   * @param rho the value of the radius of the disc
+   */
+  void SetRho (double rho);
+
+  /** 
+   * 
+   * 
+   * @param x  the X coordinate of the center of the disc
+   */
+  void SetX (double x);
+
+  /** 
+   * 
+   * @param y   the Y coordinate of the center of the disc 
+   */
+  void SetY (double y);
+
+  virtual Vector GetNext (void) const;
+private:
+  double m_rho;
+  double m_x;
+  double m_y;
+};
+
 } // namespace ns3
 
 #endif /* RANDOM_POSITION_H */
--- a/src/mobility/random-direction-2d-mobility-model.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/mobility/random-direction-2d-mobility-model.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -55,11 +55,6 @@
   return tid;
 }
 
-
-RandomDirection2dMobilityModel::RandomDirection2dMobilityModel ()
-{
-  m_event = Simulator::ScheduleNow (&RandomDirection2dMobilityModel::Start, this);
-}
 void 
 RandomDirection2dMobilityModel::DoDispose (void)
 {
@@ -67,7 +62,14 @@
   MobilityModel::DoDispose ();
 }
 void
-RandomDirection2dMobilityModel::Start (void)
+RandomDirection2dMobilityModel::DoStart (void)
+{
+  DoStartPrivate ();
+  MobilityModel::DoStart ();
+}
+
+void
+RandomDirection2dMobilityModel::DoStartPrivate (void)
 {
   double direction = m_direction.GetValue (0, 2 * PI);
   SetDirectionAndSpeed (direction);
@@ -79,6 +81,7 @@
   m_helper.Update ();
   m_helper.Pause ();
   Time pause = Seconds (m_pause.GetValue ());
+  m_event.Cancel ();
   m_event = Simulator::Schedule (pause, &RandomDirection2dMobilityModel::ResetDirectionAndSpeed, this);
   NotifyCourseChange ();
 }
@@ -97,6 +100,7 @@
   m_helper.Unpause ();
   Vector next = m_bounds.CalculateIntersection (position, vector);
   Time delay = Seconds (CalculateDistance (position, next) / speed);
+  m_event.Cancel ();
   m_event = Simulator::Schedule (delay,
 				 &RandomDirection2dMobilityModel::BeginPause, this);
   NotifyCourseChange ();
@@ -136,7 +140,8 @@
 {
   m_helper.SetPosition (position);
   Simulator::Remove (m_event);
-  m_event = Simulator::ScheduleNow (&RandomDirection2dMobilityModel::Start, this);
+  m_event.Cancel ();
+  m_event = Simulator::ScheduleNow (&RandomDirection2dMobilityModel::DoStartPrivate, this);
 }
 Vector
 RandomDirection2dMobilityModel::DoGetVelocity (void) const
--- a/src/mobility/random-direction-2d-mobility-model.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/mobility/random-direction-2d-mobility-model.h	Mon Nov 16 13:35:38 2009 +0300
@@ -45,14 +45,14 @@
  public:
   static TypeId GetTypeId (void);
 
-  RandomDirection2dMobilityModel ();
  private:
-  void Start (void);
   void ResetDirectionAndSpeed (void);
   void BeginPause (void);
   void SetDirectionAndSpeed (double direction);
   void InitializeDirectionAndSpeed (void);
+  void DoStartPrivate (void);
   virtual void DoDispose (void);
+  virtual void DoStart (void);
   virtual Vector DoGetPosition (void) const;
   virtual void DoSetPosition (const Vector &position);
   virtual Vector DoGetVelocity (void) const;
--- a/src/mobility/random-walk-2d-mobility-model.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/mobility/random-walk-2d-mobility-model.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -72,13 +72,15 @@
   return tid;
 }
 
-RandomWalk2dMobilityModel::RandomWalk2dMobilityModel ()
+void
+RandomWalk2dMobilityModel::DoStart (void)
 {
-  m_event = Simulator::ScheduleNow (&RandomWalk2dMobilityModel::Start, this);
+  DoStartPrivate ();
+  MobilityModel::DoStart ();
 }
 
 void
-RandomWalk2dMobilityModel::Start (void)
+RandomWalk2dMobilityModel::DoStartPrivate (void)
 {
   m_helper.Update ();
   double speed = m_speed.GetValue ();
@@ -109,9 +111,10 @@
   Vector nextPosition = position;
   nextPosition.x += speed.x * delayLeft.GetSeconds ();
   nextPosition.y += speed.y * delayLeft.GetSeconds ();
+  m_event.Cancel ();
   if (m_bounds.IsInside (nextPosition))
     {
-      m_event = Simulator::Schedule (delayLeft, &RandomWalk2dMobilityModel::Start, this);
+      m_event = Simulator::Schedule (delayLeft, &RandomWalk2dMobilityModel::DoStartPrivate, this);
     }
   else
     {
@@ -163,7 +166,7 @@
   NS_ASSERT (m_bounds.IsInside (position));
   m_helper.SetPosition (position);
   Simulator::Remove (m_event);
-  m_event = Simulator::ScheduleNow (&RandomWalk2dMobilityModel::Start, this);
+  m_event = Simulator::ScheduleNow (&RandomWalk2dMobilityModel::DoStartPrivate, this);
 }
 Vector
 RandomWalk2dMobilityModel::DoGetVelocity (void) const
--- a/src/mobility/random-walk-2d-mobility-model.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/mobility/random-walk-2d-mobility-model.h	Mon Nov 16 13:35:38 2009 +0300
@@ -52,13 +52,12 @@
     MODE_TIME
   };
 
-  RandomWalk2dMobilityModel ();
-
  private:
-  void Start (void);
   void Rebound (Time timeLeft);
   void DoWalk (Time timeLeft);
+  void DoStartPrivate (void);
   virtual void DoDispose (void);
+  virtual void DoStart (void);
   virtual Vector DoGetPosition (void) const;
   virtual void DoSetPosition (const Vector &position);
   virtual Vector DoGetVelocity (void) const;
--- a/src/mobility/random-waypoint-mobility-model.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/mobility/random-waypoint-mobility-model.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -54,11 +54,6 @@
   return tid;
 }
 
-RandomWaypointMobilityModel::RandomWaypointMobilityModel ()
-{
-  m_event = Simulator::ScheduleNow (&RandomWaypointMobilityModel::Start, this);
-}
-
 void
 RandomWaypointMobilityModel::BeginWalk (void)
 {
@@ -74,13 +69,21 @@
   m_helper.SetVelocity (Vector (k*dx, k*dy, k*dz));
   m_helper.Unpause ();
   Time travelDelay = Seconds (CalculateDistance (destination, m_current) / speed);
+  m_event.Cancel ();
   m_event = Simulator::Schedule (travelDelay,
-				 &RandomWaypointMobilityModel::Start, this);
+				 &RandomWaypointMobilityModel::DoStartPrivate, this);
   NotifyCourseChange ();
 }
 
 void
-RandomWaypointMobilityModel::Start (void)
+RandomWaypointMobilityModel::DoStart (void)
+{
+  DoStartPrivate ();
+  MobilityModel::DoStart ();
+}
+
+void
+RandomWaypointMobilityModel::DoStartPrivate (void)
 {
   m_helper.Update ();
   m_helper.Pause ();
@@ -100,7 +103,7 @@
 {
   m_helper.SetPosition (position);
   Simulator::Remove (m_event);
-  m_event = Simulator::ScheduleNow (&RandomWaypointMobilityModel::Start, this);
+  m_event = Simulator::ScheduleNow (&RandomWaypointMobilityModel::DoStartPrivate, this);
 }
 Vector
 RandomWaypointMobilityModel::DoGetVelocity (void) const
--- a/src/mobility/random-waypoint-mobility-model.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/mobility/random-waypoint-mobility-model.h	Mon Nov 16 13:35:38 2009 +0300
@@ -45,10 +45,11 @@
 {
 public:
   static TypeId GetTypeId (void);
-  RandomWaypointMobilityModel ();
+protected:
+  virtual void DoStart (void);
 private:
-  void Start (void);
   void BeginWalk (void);
+  void DoStartPrivate (void);
   virtual Vector DoGetPosition (void) const;
   virtual void DoSetPosition (const Vector &position);
   virtual Vector DoGetVelocity (void) const;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mobility/waypoint-mobility-model.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -0,0 +1,180 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Phillip Sitbon
+ *
+ * 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: Phillip Sitbon <phillip@sitbon.net>
+ */
+#include <limits>
+#include "ns3/abort.h"
+#include "ns3/simulator.h"
+#include "ns3/uinteger.h"
+#include "ns3/log.h"
+#include "waypoint-mobility-model.h"
+
+NS_LOG_COMPONENT_DEFINE ("WaypointMobilityModel");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (WaypointMobilityModel);
+
+
+TypeId
+WaypointMobilityModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::WaypointMobilityModel")
+    .SetParent<MobilityModel> ()
+    .SetGroupName ("Mobility")
+    .AddConstructor<WaypointMobilityModel> ()
+    .AddAttribute ("NextWaypoint", "The next waypoint used to determine position.",
+                   TypeId::ATTR_GET,
+                   WaypointValue (),
+                   MakeWaypointAccessor (&WaypointMobilityModel::GetNextWaypoint),
+                   MakeWaypointChecker ())
+    .AddAttribute ("WaypointsLeft", "The number of waypoints remaining.",
+                   TypeId::ATTR_GET,
+                   UintegerValue (0),
+                   MakeUintegerAccessor (&WaypointMobilityModel::WaypointsLeft),
+                   MakeUintegerChecker<uint32_t> ())
+    ;
+  return tid;
+}
+
+
+WaypointMobilityModel::WaypointMobilityModel ()
+ : m_first (true)
+{
+}
+WaypointMobilityModel::~WaypointMobilityModel ()
+{
+}
+void 
+WaypointMobilityModel::DoDispose (void)
+{
+  MobilityModel::DoDispose ();
+}
+void
+WaypointMobilityModel::AddWaypoint (const Waypoint &waypoint)
+{
+  if ( m_first )
+    {
+      m_first = false;
+      m_current = m_next = waypoint;
+    }
+  else
+    {
+      NS_ABORT_MSG_IF ( !m_waypoints.empty () && (m_waypoints.back ().time >= waypoint.time),
+                        "Waypoints must be added in ascending time order");
+      m_waypoints.push_back (waypoint);
+    }
+}
+Waypoint
+WaypointMobilityModel::GetNextWaypoint (void) const
+{
+  Update ();
+  return m_next;
+}
+uint32_t
+WaypointMobilityModel::WaypointsLeft (void) const
+{
+  Update ();
+  return m_waypoints.size();
+}
+void
+WaypointMobilityModel::Update (void) const
+{
+  const Time now = Simulator::Now ();
+  bool newWaypoint = false;
+
+  if ( now <= m_current.time )
+    {
+      return;
+    }
+
+  while ( now >= m_next.time  )
+    {
+      if ( m_waypoints.empty () )
+        {
+          if ( m_current.time <= m_next.time )
+            {
+              m_current.position = m_next.position;
+              m_current.time = now;
+              m_velocity = Vector (0,0,0);
+              NotifyCourseChange ();
+            }
+          else
+            {
+              m_current.time = now;
+            }
+
+          return;
+        }
+
+      m_current = m_next;
+      m_next = m_waypoints.front ();
+      m_waypoints.pop_front ();
+      newWaypoint = true;
+
+      const double t_span = (m_next.time - m_current.time).GetSeconds ();
+      NS_ASSERT (t_span > 0);
+      m_velocity.x = (m_next.position.x - m_current.position.x) / t_span;
+      m_velocity.y = (m_next.position.y - m_current.position.y) / t_span;
+      m_velocity.z = (m_next.position.z - m_current.position.z) / t_span;
+    }
+
+
+  const double t_diff = (now - m_current.time).GetSeconds();
+  m_current.position.x += m_velocity.x * t_diff;
+  m_current.position.y += m_velocity.y * t_diff;
+  m_current.position.z += m_velocity.z * t_diff;
+  m_current.time = now;
+
+  if ( newWaypoint )
+    {
+      NotifyCourseChange ();
+    }
+}
+Vector
+WaypointMobilityModel::DoGetPosition (void) const
+{
+  Update ();
+  return m_current.position;
+}
+void
+WaypointMobilityModel::DoSetPosition (const Vector &position)
+{
+  const Time now = Simulator::Now ();
+  Update ();
+  m_current.time = std::max (now, m_next.time);
+  m_current.position = position;
+  m_velocity = Vector (0,0,0);
+  NotifyCourseChange ();
+}
+void
+WaypointMobilityModel::EndMobility (void)
+{
+  m_waypoints.clear ();
+  m_current.time = Seconds (std::numeric_limits<double>::infinity ());
+  m_next.time = m_current.time;
+  m_first = true;
+}
+Vector
+WaypointMobilityModel::DoGetVelocity (void) const
+{
+  return m_velocity;
+}
+
+} // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mobility/waypoint-mobility-model.h	Mon Nov 16 13:35:38 2009 +0300
@@ -0,0 +1,115 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Phillip Sitbon
+ *
+ * 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: Phillip Sitbon <phillip@sitbon.net>
+ */
+#ifndef WAYPOINT_MOBILITY_MODEL_H
+#define WAYPOINT_MOBILITY_MODEL_H
+
+#include <stdint.h>
+#include <deque>
+#include "mobility-model.h"
+#include "ns3/vector.h"
+#include "waypoint.h"
+
+namespace ns3 {
+
+/**
+ * \brief a waypoint-based mobility model
+ *
+ * Each object determines its velocity and position at a given time
+ * from a set of ns3::Waypoint objects. The position of each object
+ * is not updated unless queried, and past waypoints are discarded
+ * after the current simulation time greater than their time value.
+ * 
+ * The initial position of each object corresponds to the position of
+ * the first waypoint, and the initial velocity of each object is zero.
+ * Upon reaching the last waypoint, object positions becomes static and
+ * velocity is zero.
+ *
+ * When a node is in between waypoints (in time), it moves with a constant
+ * velocity between the position at the previous waypoint and the position
+ * at the current waypoint. To make a node hold a certain position for a
+ * time interval, two waypoints with the same position (but different times)
+ * should be inserted sequentially.
+ *
+ * Waypoints can be added at any time, and setting the current position
+ * of an object will set its velocity to zero until the next waypoint time
+ * (at which time the object jumps to the next waypoint), unless there are
+ * no more waypoints in which case it will not change without user
+ * intervention.
+ *
+ */
+class WaypointMobilityModel : public MobilityModel
+{
+ public:
+  static TypeId GetTypeId (void);
+
+  /**
+   * Create a path with no waypoints at location (0,0,0).
+   */
+  WaypointMobilityModel ();
+  virtual ~WaypointMobilityModel ();
+
+  /**
+   * \param waypoint waypoint to append to the object path.
+   *
+   * Add a waypoint to the path of the object. The time must
+   * be greater than the previous waypoint added, otherwise
+   * a fatal error occurs. The first waypoint is set as the
+   * current position with a velocity of zero.
+   * 
+   */
+  void AddWaypoint (const Waypoint &waypoint);
+
+  /**
+   * Get the waypoint that this object is traveling towards.
+   */
+  Waypoint GetNextWaypoint (void) const;
+
+  /**
+   * Get the number of waypoints left for this object, excluding
+   * the next one.
+   */
+  uint32_t WaypointsLeft (void) const;
+
+  /**
+   * Clear any existing waypoints and set the current waypoint
+   * time to infinity. Calling this is only an optimization and
+   * not required. After calling this function, adding waypoints
+   * behaves as it would for a new object.
+   */
+  void EndMobility (void);
+
+ private:
+  void Update (void) const;
+  virtual void DoDispose (void);
+  virtual Vector DoGetPosition (void) const;
+  virtual void DoSetPosition (const Vector &position);
+  virtual Vector DoGetVelocity (void) const;
+
+  bool m_first;
+  mutable std::deque<Waypoint> m_waypoints;
+  mutable Waypoint m_current;
+  mutable Waypoint m_next;
+  mutable Vector m_velocity;
+};
+
+} // namespace ns3
+
+#endif /* WAYPOINT_MOBILITY_MODEL_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mobility/waypoint.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -0,0 +1,52 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Phillip Sitbon
+ *
+ * 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: Phillip Sitbon <phillip@sitbon.net>
+ */
+#include "waypoint.h"
+
+namespace ns3 {
+
+ATTRIBUTE_HELPER_CPP (Waypoint);
+
+Waypoint::Waypoint (const Time &waypointTime, const Vector &waypointPosition)
+  : time (waypointTime),
+  position (waypointPosition)
+{}
+Waypoint::Waypoint ()
+  : time (0.0),
+  position (0,0,0)
+{}
+
+std::ostream &operator << (std::ostream &os, const Waypoint &waypoint)
+{
+  os << waypoint.time.GetSeconds () << "$" << waypoint.position;
+  return os;
+}
+std::istream &operator >> (std::istream &is, Waypoint &waypoint)
+{
+  char separator;
+  is >> waypoint.time >> separator >> waypoint.position;
+  if (separator != '$')
+    {
+      is.setstate (std::ios_base::failbit);
+    }
+  return is;
+}
+
+} // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mobility/waypoint.h	Mon Nov 16 13:35:38 2009 +0300
@@ -0,0 +1,69 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Phillip Sitbon
+ *
+ * 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: Phillip Sitbon <phillip@sitbon.net>
+ */
+#ifndef WAYPOINT_H
+#define WAYPOINT_H
+
+#include "ns3/attribute.h"
+#include "ns3/attribute-helper.h"
+#include "ns3/nstime.h"
+#include "ns3/vector.h"
+
+namespace ns3 {
+
+/**
+ * \brief a (time, location) pair.
+ *
+ */
+class Waypoint
+{
+public:
+  /**
+   * \param _time time of waypoint.
+   * \param _position position of waypoint corresponding to the given time.
+   *
+   * Create a waypoint.
+   */
+  Waypoint (const Time &waypointTime, const Vector &waypointPosition);
+
+  /**
+   * Create a waypoint at time 0 and position (0,0,0).
+   */
+  Waypoint ();
+  /* The waypoint time */
+  Time time;
+  /* The position of the waypoint */
+  Vector position;
+};
+
+/**
+ * \class ns3::WaypointValue
+ * \brief hold objects of type ns3::Waypoint
+ */
+ATTRIBUTE_HELPER_HEADER ( Waypoint);
+
+std::ostream &
+operator << (std::ostream &os, const Waypoint &waypoint);
+std::istream &
+operator >> (std::istream &is, Waypoint &waypoint);
+
+} // namespace ns3
+
+#endif /* WAYPOINT_H */
+
--- a/src/mobility/wscript	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/mobility/wscript	Mon Nov 16 13:35:38 2009 +0300
@@ -14,6 +14,8 @@
         'random-walk-2d-mobility-model.cc',
         'random-direction-2d-mobility-model.cc',
         'constant-acceleration-mobility-model.cc',
+        'waypoint.cc',
+        'waypoint-mobility-model.cc',
         ]
 
     headers = bld.new_task_gen('ns3header')
@@ -30,4 +32,6 @@
         'random-walk-2d-mobility-model.h',
         'random-direction-2d-mobility-model.h',
         'constant-acceleration-mobility-model.h',
+        'waypoint.h',
+        'waypoint-mobility-model.h',
         ]
--- a/src/node/application.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/node/application.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -40,6 +40,14 @@
 {
   static TypeId tid = TypeId ("ns3::Application")
     .SetParent<Object> ()
+    .AddAttribute ("StartTime", "Time at which the application will start",
+                   TimeValue (Seconds (0.0)),
+                   MakeTimeAccessor (&Application::m_startTime),
+                   MakeTimeChecker ())
+    .AddAttribute ("StopTime", "Time at which the application will stop",
+                   TimeValue (TimeStep (0)),
+                   MakeTimeAccessor (&Application::m_stopTime),
+                   MakeTimeChecker ())
     ;
   return tid;
 }
@@ -52,38 +60,38 @@
 Application::~Application()
 {}
 
+void 
+Application::SetStartTime (Time start)
+{
+  m_startTime = start;
+}
+void 
+Application::SetStopTime (Time stop)
+{
+  m_stopTime = stop;
+}
+
+
 void
 Application::DoDispose (void)
 {
   m_node = 0;
-  Simulator::Cancel(m_startEvent);
-  Simulator::Cancel(m_stopEvent);
+  m_startEvent.Cancel ();
+  m_stopEvent.Cancel ();
   Object::DoDispose ();
 }  
-   
-void Application::Start(const Time& startTime)
+
+void
+Application::DoStart (void)
 {
-  ScheduleStart (startTime);
-}
-
-void Application::Start(const RandomVariable& startVar)
-{
-  RandomVariable v = startVar;
-  ScheduleStart (Seconds (v.GetValue ()));
+  m_startEvent = Simulator::Schedule (m_startTime, &Application::StartApplication, this);
+  if (m_stopTime != TimeStep (0))
+    {
+      m_stopEvent = Simulator::Schedule (m_stopTime, &Application::StopApplication, this);
+    }
+  Object::DoStart ();
 }
-
-   
-void Application::Stop(const Time& stopTime)
-{
-  ScheduleStop (stopTime);
-}
-
-void Application::Stop(const RandomVariable& stopVar)
-{
-  RandomVariable v = stopVar;
-  ScheduleStop (Seconds (v.GetValue ()));
-}
-  
+     
 Ptr<Node> Application::GetNode() const
 {
   return m_node;
@@ -105,20 +113,6 @@
 { // Provide null functionality in case subclass is not interested
 }
 
-
-// Private helpers
-void Application::ScheduleStart (const Time &startTime)
-{
-  m_startEvent = Simulator::Schedule (startTime,
-                                      &Application::StartApplication, this);
-}
-
-void Application::ScheduleStop (const Time &stopTime)
-{
-  m_stopEvent = Simulator::Schedule (stopTime,
-                                    &Application::StopApplication, this);
-}
-
 } //namespace ns3
       
   
--- a/src/node/application.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/node/application.h	Mon Nov 16 13:35:38 2009 +0300
@@ -64,7 +64,7 @@
   static TypeId GetTypeId (void);
   Application ();
   virtual ~Application ();
-  
+
   /**
    * \brief Specify application start time
    * \param startTime Start time for this application,
@@ -76,15 +76,7 @@
    * private "StartApplication" method defined below, which is called at the
    * time specified, to cause the application to begin.
    */
-  void Start (const Time& startTime);
-
-  /** 
-   * \brief Specify application start time.
-   * \param startVariable the random variable to use to pick
-   *        the real start time as a relative time, in units of
-   *        seconds, relative to the current simulation time.
-   */
-  void Start (const RandomVariable& startVariable);
+  void SetStartTime (Time start);
   
   /**
    * \brief Specify application stop time
@@ -97,16 +89,8 @@
    * the private StopApplication method, to be notified when that
    * time has come.
    */
-  void Stop (const Time& stopTime);
-
-  /**
-   * \brief Specify application stop time
-   * \param stopVariable the random variable to use to pick
-   *        the real stop time, in units of seconds, 
-   *        relative to the current simulation time.
-   */
-  void Stop (const RandomVariable& stopVariable);
-
+  void SetStopTime (Time stop);
+  
   /**
    * \returns the Node to which this Application object is attached.
    */
@@ -137,13 +121,13 @@
   virtual void StopApplication (void);
 protected:
   virtual void DoDispose (void);
-private:
-  void ScheduleStart (const Time &time);
-  void ScheduleStop (const Time &time);
+  virtual void DoStart (void);
 
-  EventId         m_startEvent;
-  EventId         m_stopEvent;
   Ptr<Node>       m_node;
+  Time m_startTime;
+  Time m_stopTime;
+  EventId m_startEvent;
+  EventId m_stopEvent;
 };
 
 } //namespace ns3
--- a/src/node/channel.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/node/channel.h	Mon Nov 16 13:35:38 2009 +0300
@@ -36,6 +36,9 @@
  *
  * A channel is a logical path over which information flows.  The path can
  * be as simple as a short piece of wire, or as complicated as space-time.
+ *
+ * Subclasses must use Simulator::ScheduleWithContext to correctly update
+ * event contexts when scheduling an event from one node to another one.
  */
 class Channel : public Object
 {
--- a/src/node/ipv4-route.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/node/ipv4-route.h	Mon Nov 16 13:35:38 2009 +0300
@@ -23,7 +23,7 @@
 #include <vector>
 #include <ostream>
 
-#include "ns3/ref-count-base.h"
+#include "ns3/simple-ref-count.h"
 #include "ipv4-address.h"
 
 namespace ns3 {
@@ -38,7 +38,8 @@
  * This is a reference counted object.  In the future, we will add other 
  * entries from struct dst_entry, struct rtable, and struct dst_ops as needed.
  */
-class Ipv4Route : public RefCountBase {
+class Ipv4Route : public SimpleRefCount<Ipv4Route> 
+{
 public:
   Ipv4Route ();
 
@@ -103,7 +104,8 @@
  * 
  * \brief Ipv4 multicast route cache entry (similar to Linux struct mfc_cache)
  */
-class Ipv4MulticastRoute : public RefCountBase {
+class Ipv4MulticastRoute : public SimpleRefCount<Ipv4MulticastRoute> 
+{
 public:
   Ipv4MulticastRoute ();
 
--- a/src/node/ipv6-route.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/node/ipv6-route.h	Mon Nov 16 13:35:38 2009 +0300
@@ -25,7 +25,7 @@
 #include <vector>
 #include <ostream>
 
-#include "ns3/ref-count-base.h"
+#include "ns3/simple-ref-count.h"
 
 #include "ipv6-address.h"
 
@@ -39,7 +39,7 @@
  * \class Ipv6Route
  * \brief IPv6 route cache entry.
  */
-class Ipv6Route : public RefCountBase
+class Ipv6Route : public SimpleRefCount<Ipv6Route>
 {
   public:
     /**
@@ -129,7 +129,7 @@
  * \class Ipv6MulticastRoute
  * \brief IPv6 multicast route entry.
  */
-class Ipv6MulticastRoute : public RefCountBase
+class Ipv6MulticastRoute : public SimpleRefCount<Ipv6MulticastRoute>
 {
   public:
     /**
--- a/src/node/node-list.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/node/node-list.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -119,6 +119,7 @@
 {
   uint32_t index = m_nodes.size ();
   m_nodes.push_back (node);
+  Simulator::ScheduleWithContext (index, TimeStep (0), &Node::Start, node);
   return index;
   
 }
--- a/src/node/node.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/node/node.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -167,6 +167,24 @@
   m_applications.clear ();
   Object::DoDispose ();
 }
+void 
+Node::DoStart (void)
+{
+  for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
+       i != m_devices.end (); i++)
+    {
+      Ptr<NetDevice> device = *i;
+      device->Start ();
+    }
+  for (std::vector<Ptr<Application> >::iterator i = m_applications.begin ();
+       i != m_applications.end (); i++)
+    {
+      Ptr<Application> application = *i;
+      application->Start ();
+    }
+  
+  Object::DoStart ();
+}
 
 void 
 Node::NotifyDeviceAdded (Ptr<NetDevice> device)
@@ -247,6 +265,9 @@
 Node::ReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
                          const Address &from, const Address &to, NetDevice::PacketType packetType, bool promiscuous)
 {
+  NS_ASSERT_MSG (Simulator::GetContext () == GetId (), "Received packet with erroneous context ; " <<
+                 "make sure the channels in use are correctly updating events context " <<
+                 "when transfering events from one node to another.");
   NS_LOG_DEBUG("Node " << GetId () << " ReceiveFromDevice:  dev "
                << device->GetIfIndex () << " (type=" << device->GetInstanceTypeId ().GetName ()
                << ") Packet UID " << packet->GetUid ());
--- a/src/node/node.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/node/node.h	Mon Nov 16 13:35:38 2009 +0300
@@ -186,6 +186,7 @@
    * end of their own DoDispose method.
    */
   virtual void DoDispose (void);
+  virtual void DoStart (void);
 private:
 
   /**
--- a/src/node/packetbb.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/node/packetbb.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -497,7 +497,6 @@
 
 PbbPacket::PbbPacket (void)
 {
-  m_refCount = 1;
   m_version = VERSION;
   m_hasseqnum = false;
 }
@@ -746,21 +745,6 @@
   m_messageList.clear ();
 }
 
-void
-PbbPacket::Ref (void) const
-{
-  m_refCount++;
-}
-
-void
-PbbPacket::Unref (void) const
-{
-  m_refCount--;
-  if (m_refCount == 0)
-    {
-      delete this;
-    }
-}
 
 TypeId
 PbbPacket::GetTypeId (void)
@@ -947,7 +931,6 @@
 
 PbbMessage::PbbMessage ()
 {
-  m_refCount = 1;
   /* Default to IPv4 */
   m_addrSize = IPV4;
   m_hasOriginatorAddress = false;
@@ -1274,22 +1257,6 @@
   return m_addressBlockList.clear();
 }
 
-void
-PbbMessage::Ref (void) const
-{
-  m_refCount++;
-}
-
-void
-PbbMessage::Unref (void) const
-{
-  m_refCount--;
-  if (m_refCount == 0)
-    {
-      delete this;
-    }
-}
-
 uint32_t
 PbbMessage::GetSerializedSize (void) const
 {
@@ -1699,13 +1666,10 @@
 /* End PbbMessageIpv6 Class */
 
 PbbAddressBlock::PbbAddressBlock ()
-{
-  m_refCount = 1;
-}
+{}
 
 PbbAddressBlock::~PbbAddressBlock ()
-{
-}
+{}
 
 /* Manipulating the address block */
 
@@ -2002,23 +1966,6 @@
 {
   m_addressTlvList.Clear();
 }
-
-void
-PbbAddressBlock::Ref (void) const
-{
-  m_refCount++;
-}
-
-void
-PbbAddressBlock::Unref (void) const
-{
-  m_refCount--;
-  if (m_refCount == 0)
-    {
-      delete this;
-    }
-}
-
 uint32_t
 PbbAddressBlock::GetSerializedSize (void) const
 {
@@ -2448,7 +2395,6 @@
 
 PbbTlv::PbbTlv (void)
 {
-  m_refCount = 1;
   m_hasTypeExt = false;
   m_hasIndexStart = false;
   m_hasIndexStop = false;
@@ -2573,22 +2519,6 @@
   return m_hasValue;
 }
 
-void
-PbbTlv::Ref (void) const
-{
-  m_refCount++;
-}
-
-void
-PbbTlv::Unref (void) const
-{
-  m_refCount--;
-  if (m_refCount == 0)
-    {
-      delete this;
-    }
-}
-
 uint32_t
 PbbTlv::GetSerializedSize (void) const
 {
--- a/src/node/packetbb.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/node/packetbb.h	Mon Nov 16 13:35:38 2009 +0300
@@ -31,6 +31,7 @@
 #include "ns3/address.h"
 #include "ns3/header.h"
 #include "ns3/buffer.h"
+#include "ns3/simple-ref-count.h"
 
 namespace ns3 {
 
@@ -360,7 +361,7 @@
  *
  * See: http://tools.ietf.org/html/rfc5444 for details.
  */
-class PbbPacket : public Header
+class PbbPacket : public SimpleRefCount<PbbPacket,Header>
 {
 public:
   typedef std::list< Ptr<PbbTlv> >::iterator TlvIterator;
@@ -595,10 +596,6 @@
    */
   void MessageClear (void);
 
-  /* Smart pointer methods */
-  void Ref (void) const;
-  void Unref (void) const;
-
   /* Methods implemented by all headers */
   static TypeId GetTypeId (void);
   virtual TypeId GetInstanceTypeId (void) const;
@@ -644,8 +641,6 @@
 
   bool m_hasseqnum;
   uint16_t m_seqnum;
-
-  mutable uint32_t m_refCount;
 };
 
 /**
@@ -655,7 +650,7 @@
  * virtual base class, when creating a message, you should instantiate either
  * PbbMessageIpv4 or PbbMessageIpv6.
  */
-class PbbMessage
+class PbbMessage : public SimpleRefCount<PbbMessage>
 {
 public:
   typedef std::list< Ptr<PbbTlv> >::iterator TlvIterator;
@@ -959,10 +954,6 @@
    */
   void AddressBlockClear (void);
 
-  /* Smart pointer methods */
-  void Ref (void) const;
-  void Unref (void) const;
-
   /**
    * \brief Deserializes a message, returning the correct object depending on
    *        whether it is an IPv4 message or an IPv6 message.
@@ -1048,8 +1039,6 @@
 
   bool m_hasSequenceNumber;
   uint16_t m_sequenceNumber;
-
-  mutable uint32_t m_refCount;
 };
 
 /**
@@ -1098,7 +1087,7 @@
  * This is a pure virtual base class, when creating address blocks, you should
  * instantiate either PbbAddressBlockIpv4 or PbbAddressBlockIpv6.
  */
-class PbbAddressBlock
+class PbbAddressBlock : public SimpleRefCount<PbbAddressBlock>
 {
 public:
   typedef std::list< Address >::iterator AddressIterator;
@@ -1412,10 +1401,6 @@
    */
   void TlvClear (void);
 
-  /* Smart pointer methods */
-  void Ref (void) const;
-  void Unref (void) const;
-
   /**
    * \return The size (in bytes) needed to serialize this address block.
    */
@@ -1475,8 +1460,6 @@
   std::list<Address> m_addressList;
   std::list<uint8_t> m_prefixList;
   PbbAddressTlvBlock m_addressTlvList;
-
-  mutable uint32_t m_refCount;
 };
 
 /**
@@ -1520,11 +1503,11 @@
 /**
  * \brief A packet or message TLV
  */
-class PbbTlv
+class PbbTlv : public SimpleRefCount<PbbTlv>
 {
 public:
   PbbTlv (void);
-  ~PbbTlv (void);
+  virtual ~PbbTlv (void);
 
   /**
    * \brief Sets the type of this TLV.
@@ -1599,10 +1582,6 @@
    */
   bool HasValue (void) const;
 
-  /* Smart pointer methods */
-  void Ref (void) const;
-  void Unref (void) const;
-
   /**
    * \return The size (in bytes) needed to serialize this TLV.
    */
@@ -1672,8 +1651,6 @@
   bool m_isMultivalue;
   bool m_hasValue;
   Buffer m_value;
-
-  mutable uint32_t m_refCount;
 };
 
 /**
--- a/src/node/simple-channel.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/node/simple-channel.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -21,6 +21,7 @@
 #include "simple-net-device.h"
 #include "ns3/simulator.h"
 #include "ns3/packet.h"
+#include "ns3/node.h"
 
 namespace ns3 {
 
@@ -49,7 +50,8 @@
 	{
 	  continue;
 	}
-      Simulator::ScheduleNow (&SimpleNetDevice::Receive, tmp, p->Copy (), protocol, to, from);
+      Simulator::ScheduleWithContext (tmp->GetNode ()->GetId (), Seconds (0),
+                                      &SimpleNetDevice::Receive, tmp, p->Copy (), protocol, to, from);
     }
 }
 
--- a/src/routing/list-routing/ipv4-list-routing.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/routing/list-routing/ipv4-list-routing.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -68,6 +68,19 @@
   m_ipv4 = 0;
 }
 
+void
+Ipv4ListRouting::DoStart (void)
+{
+  for (Ipv4RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end (); rprotoIter++)
+    {
+      Ptr<Ipv4RoutingProtocol> protocol = (*rprotoIter).second;
+      protocol->Start ();
+    }
+  Ipv4RoutingProtocol::DoStart ();
+}
+
+
 Ptr<Ipv4Route>
 Ipv4ListRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, uint32_t oif, enum Socket::SocketErrno &sockerr)
 {
--- a/src/routing/list-routing/ipv4-list-routing.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/routing/list-routing/ipv4-list-routing.h	Mon Nov 16 13:35:38 2009 +0300
@@ -88,6 +88,7 @@
 
 protected:
   void DoDispose (void);
+  void DoStart (void);
 private:
   typedef std::pair<int16_t, Ptr<Ipv4RoutingProtocol> > Ipv4RoutingProtocolEntry;
   typedef std::list<Ipv4RoutingProtocolEntry> Ipv4RoutingProtocolList;
--- a/src/routing/olsr/olsr-header.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/routing/olsr/olsr-header.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -785,7 +785,7 @@
 } g_olsrTestSuite;
 
 OlsrTestSuite::OlsrTestSuite()
-  : TestSuite("olsr-routing", UNIT)
+  : TestSuite("routing-olsr-header", UNIT)
 {
   AddTestCase(new OlsrHnaTestCase());
   AddTestCase(new OlsrTcTestCase());
--- a/src/routing/olsr/olsr-routing-protocol.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/routing/olsr/olsr-routing-protocol.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -213,8 +213,6 @@
   m_linkTupleTimerFirstTime = true;
 
   m_ipv4 = ipv4;
-
-  Simulator::ScheduleNow (&RoutingProtocol::Start, this);
 }
 
 void RoutingProtocol::DoDispose ()
@@ -231,7 +229,7 @@
   Ipv4RoutingProtocol::DoDispose ();
 }
 
-void RoutingProtocol::Start ()
+void RoutingProtocol::DoStart ()
 {
   if (m_mainAddress == Ipv4Address ())
     {
@@ -552,7 +550,23 @@
         }
     }
 
-  NS_LOG_DEBUG ("Size of N2: " << N2.size ());  
+#ifdef NS3_LOG_ENABLE
+  {
+    std::ostringstream os;
+    os << "[";
+    for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
+         iter != N2.end (); iter++)
+      {
+        TwoHopNeighborSet::const_iterator next = iter;
+        next++;
+        os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
+        if (next != N2.end ())
+          os << ", ";
+      }
+    os << "]";
+    NS_LOG_DEBUG ("N2: " << os.str ());
+  }
+#endif  //NS3_LOG_ENABLE
 
   // 1. Start with an MPR set made of all members of N with
   // N_willingness equal to WILL_ALWAYS
@@ -584,31 +598,38 @@
   // 3. Add to the MPR set those nodes in N, which are the *only*
   // nodes to provide reachability to a node in N2.
   std::set<Ipv4Address> coveredTwoHopNeighbors;
-  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
+  for (TwoHopNeighborSet::const_iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
     {
-      NeighborSet::const_iterator onlyNeighbor = N.end ();
-      
-      for (NeighborSet::const_iterator neighbor = N.begin ();
-           neighbor != N.end (); neighbor++)
+      bool onlyOne = true;
+      // try to find another neighbor that can reach twoHopNeigh->twoHopNeighborAddr
+      for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin (); otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
         {
-          if (neighbor->neighborMainAddr == twoHopNeigh->neighborMainAddr)
+          if (otherTwoHopNeigh->twoHopNeighborAddr == twoHopNeigh->twoHopNeighborAddr
+              && otherTwoHopNeigh->neighborMainAddr != twoHopNeigh->neighborMainAddr)
             {
-              if (onlyNeighbor == N.end ())
+              onlyOne = false;
+              break;
+            }
+        }
+      if (onlyOne)
+        {
+          NS_LOG_LOGIC ("Neighbor " << twoHopNeigh->neighborMainAddr
+                        << " is the only that can reach 2-hop neigh. "
+                        << twoHopNeigh->twoHopNeighborAddr
+                        << " => select as MPR.");
+
+          mprSet.insert (twoHopNeigh->neighborMainAddr);
+
+          // take note of all the 2-hop neighbors reachable by the newly elected MPR
+          for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin ();
+               otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
+            {
+              if (otherTwoHopNeigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
                 {
-                  onlyNeighbor = neighbor;
-                }
-              else
-                {
-                  onlyNeighbor = N.end ();
-                  break;
+                  coveredTwoHopNeighbors.insert (otherTwoHopNeigh->twoHopNeighborAddr);
                 }
             }
         }
-      if (onlyNeighbor != N.end ())
-        {
-          mprSet.insert (onlyNeighbor->neighborMainAddr);
-          coveredTwoHopNeighbors.insert (twoHopNeigh->twoHopNeighborAddr);
-        }
     }
   // Remove the nodes from N2 which are now covered by a node in the MPR set.
   for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
@@ -616,6 +637,7 @@
     {
       if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
         {
+          NS_LOG_LOGIC ("2-hop neigh. " << twoHopNeigh->twoHopNeighborAddr << " is already covered by an MPR.");
           twoHopNeigh = N2.erase (twoHopNeigh);
         }
       else
@@ -628,6 +650,26 @@
   // least one node in the MPR set:
   while (N2.begin () != N2.end ())
     {
+
+#ifdef NS3_LOG_ENABLE
+      {
+        std::ostringstream os;
+        os << "[";
+        for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
+             iter != N2.end (); iter++)
+          {
+            TwoHopNeighborSet::const_iterator next = iter;
+            next++;
+            os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
+            if (next != N2.end ())
+              os << ", ";
+          }
+        os << "]";
+        NS_LOG_DEBUG ("Step 4 iteration: N2=" << os.str ());
+      }
+#endif  //NS3_LOG_ENABLE
+
+
       // 4.1. For each node in N, calculate the reachability, i.e., the
       // number of nodes in N2 which are not yet covered by at
       // least one node in the MPR set, and which are reachable
@@ -672,6 +714,10 @@
               if (max == NULL || nb_tuple->willingness > max->willingness)
                 {
                   max = nb_tuple;
+                  for (TwoHopNeighborSet::iterator newCovered = N2.begin (); newCovered != N2.end (); newCovered++)
+                    {
+                      coveredTwoHopNeighbors.insert (newCovered->twoHopNeighborAddr);
+                    }
                   max_r = r;
                 }
               else if (nb_tuple->willingness == max->willingness)
@@ -696,11 +742,12 @@
       if (max != NULL)
         {
           mprSet.insert (max->neighborMainAddr);
-          for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
-               twoHopNeigh != N2.end (); )
+          // Remove the nodes from N2 which are now covered by a node in the MPR set.
+          for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); )
             {
-              if (twoHopNeigh->neighborMainAddr == max->neighborMainAddr)
+              if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
                 {
+                  NS_LOG_LOGIC ("2-hop neigh. " << twoHopNeigh->twoHopNeighborAddr << " is already covered by an MPR.");
                   twoHopNeigh = N2.erase (twoHopNeigh);
                 }
               else
@@ -2736,6 +2783,128 @@
     }
   return retval;
 }
+OlsrMprTestCase::OlsrMprTestCase ()
+  : TestCase ("Check OLSR MPR computing mechanism")
+{
+}
+OlsrMprTestCase::~OlsrMprTestCase ()
+{
+}
+bool
+OlsrMprTestCase::DoRun ()
+{
+  /*
+   * Create a 3x3 grid like the following:
+   *      3---6---9
+   *      |\ /|\ /|
+   *      | X | X |
+   *      |/ \|/ \|
+   *      2---5---8
+   *      |\ /|\ /|
+   *      | X | X |
+   *      |/ \|/ \|
+   *      1---4---7
+   * PrepareTopology fills all 2-hop neighbors of station 1 and creates a routing protocol
+   * We are the station number 2. Obvious, that an only MPR in this case is 5 
+   */
+  Ptr<RoutingProtocol> m_protocol = CreateObject<RoutingProtocol> ();
+  m_protocol->m_mainAddress = Ipv4Address ("10.0.0.2");
+  // we fill all possible 2-hop neighborhood
+  TwoHopNeighborTuple tuple;
+  tuple.expirationTime = Seconds (3600);
+  // All neighbor stations which are seen from station 5
+  tuple.neighborMainAddr = Ipv4Address ("10.0.0.5");
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.1");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.2");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.3");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.4");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.6");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.7");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.8");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.9");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  // All neighbor stations which are seen from station 4
+  tuple.neighborMainAddr = Ipv4Address ("10.0.0.4");
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.1");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.2");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.5");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.8");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.7");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+
+  // All neighbor stations which are seen from station 6
+  tuple.neighborMainAddr = Ipv4Address ("10.0.0.6");
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.3");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.2");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.5");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.8");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.9");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+
+  // All neighbor stations which are seen from station 1
+  tuple.neighborMainAddr = Ipv4Address ("10.0.0.1");
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.2");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.5");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.4");
+
+  // All neighbor stations which are seen from station 3
+  tuple.neighborMainAddr = Ipv4Address ("10.0.0.3");
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.2");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.5");
+  m_protocol->m_state.InsertTwoHopNeighborTuple (tuple);
+  tuple.twoHopNeighborAddr = Ipv4Address ("10.0.0.6");
+  // First, we fill all neighbors
+  // If neighbors willingness = OLSR_WILL_DEFAULT, an only station number 5 will be an MPR
+  NeighborTuple neigbor;
+  neigbor.status = NeighborTuple::STATUS_SYM;
+  neigbor.willingness = OLSR_WILL_DEFAULT;
+  neigbor.neighborMainAddr = Ipv4Address ("10.0.0.3");
+  m_protocol->m_state.InsertNeighborTuple (neigbor);
+  neigbor.neighborMainAddr = Ipv4Address ("10.0.0.6");
+  m_protocol->m_state.InsertNeighborTuple (neigbor);
+  neigbor.neighborMainAddr = Ipv4Address ("10.0.0.5");
+  m_protocol->m_state.InsertNeighborTuple (neigbor);
+  neigbor.neighborMainAddr = Ipv4Address ("10.0.0.4");
+  m_protocol->m_state.InsertNeighborTuple (neigbor);
+  neigbor.neighborMainAddr = Ipv4Address ("10.0.0.1");
+  m_protocol->m_state.InsertNeighborTuple (neigbor);
+  //Now, calculateMPR
+  m_protocol->MprComputation ();
+  //Check results
+  NS_TEST_ASSERT_MSG_EQ (m_protocol->m_state.FindMprAddress (Ipv4Address ("10.0.0.5")), true, "MPR is incorrect!");
+  NS_TEST_ASSERT_MSG_EQ (m_protocol->m_state.GetMprSet ().size (), 1 , "An only address must be chosen!\n");
+  return false;
+}
+
+static class OlsrProtocolTestSuite : public TestSuite
+{
+public:
+  OlsrProtocolTestSuite ();
+} g_olsrProtocolTestSuite;
+
+OlsrProtocolTestSuite::OlsrProtocolTestSuite()
+  : TestSuite("routing-olsr", UNIT)
+{
+  AddTestCase (new OlsrMprTestCase ());
+}
 
 
 }} // namespace olsr, ns3
--- a/src/routing/olsr/olsr-routing-protocol.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/routing/olsr/olsr-routing-protocol.h	Mon Nov 16 13:35:38 2009 +0300
@@ -25,6 +25,7 @@
 #define __OLSR_AGENT_IMPL_H__
 
 #include "olsr-header.h"
+#include "ns3/test.h"
 #include "olsr-state.h"
 #include "olsr-repositories.h"
 
@@ -58,11 +59,21 @@
     destAddr (), nextAddr (),
     interface (0), distance (0) {};
 };
+class RoutingProtocol;
+/// Testcase for MPR computation mechanism
+class OlsrMprTestCase : public TestCase {
+public:
+  OlsrMprTestCase ();
+  ~OlsrMprTestCase ();
+  virtual bool DoRun (void);
+  ;
+};
 
 
 class RoutingProtocol : public Ipv4RoutingProtocol
 {
 public:
+  friend class OlsrMprTestCase;
   static TypeId GetTypeId (void);
 
   RoutingProtocol ();
@@ -70,6 +81,8 @@
 
   void SetMainInterface (uint32_t interface);
 
+protected:
+  virtual void DoStart (void);
 private:
   std::map<Ipv4Address, RoutingTableEntry> m_table; ///< Data structure for the routing table.
 
@@ -100,7 +113,7 @@
   Ptr<Ipv4> m_ipv4;
 	
 private:
-  void Start ();
+
   void Clear ();
   uint32_t GetSize () const { return m_table.size (); }
   std::vector<RoutingTableEntry> GetEntries () const;
--- a/src/routing/olsr/olsr-state.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/routing/olsr/olsr-state.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -272,6 +272,11 @@
 {
   m_mprSet = mprSet;
 }
+MprSet
+OlsrState::GetMprSet () const
+{
+  return m_mprSet;
+}
 
 /********** Duplicate Set Manipulation **********/
 
--- a/src/routing/olsr/olsr-state.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/routing/olsr/olsr-state.h	Mon Nov 16 13:35:38 2009 +0300
@@ -98,7 +98,10 @@
 
   // MPR
   bool FindMprAddress (const Ipv4Address &address);
+  /// MprSet is set by routing protocol after MprCompute
   void SetMprSet (MprSet mprSet);
+  /// Gets an MPR Set needed by tests
+  MprSet GetMprSet () const;
 
   // Duplicate
   DuplicateTuple* FindDuplicateTuple (const Ipv4Address &address,
--- a/src/simulator/default-simulator-impl.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/simulator/default-simulator-impl.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -53,10 +53,11 @@
   // uid 0 is "invalid" events
   // uid 1 is "now" events
   // uid 2 is "destroy" events
-  m_uid = 4; 
+  m_uid = 4;
   // before ::Run is entered, the m_currentUid will be zero
   m_currentUid = 0;
   m_currentTs = 0;
+  m_currentContext = 0xffffffff;
   m_unscheduledEvents = 0;
 }
 
@@ -86,8 +87,10 @@
 }
 
 void
-DefaultSimulatorImpl::SetScheduler (Ptr<Scheduler> scheduler)
+DefaultSimulatorImpl::SetScheduler (ObjectFactory schedulerFactory)
 {
+  Ptr<Scheduler> scheduler = schedulerFactory.Create<Scheduler> ();
+
   if (m_events != 0)
     {
       while (!m_events->IsEmpty ())
@@ -105,10 +108,11 @@
   Scheduler::Event next = m_events->RemoveNext ();
 
   NS_ASSERT (next.key.m_ts >= m_currentTs);
-  --m_unscheduledEvents;
+  m_unscheduledEvents--;
 
   NS_LOG_LOGIC ("handle " << next.key.m_ts);
   m_currentTs = next.key.m_ts;
+  m_currentContext = next.key.m_context;
   m_currentUid = next.key.m_uid;
   next.impl->Invoke ();
   next.impl->Unref ();
@@ -160,6 +164,11 @@
   m_stop = true;
 }
 
+void 
+DefaultSimulatorImpl::Stop (Time const &time)
+{
+  Simulator::Schedule (time, &Simulator::Stop);
+}
 
 //
 // Schedule an event for a _relative_ time in the future.
@@ -167,18 +176,34 @@
 EventId
 DefaultSimulatorImpl::Schedule (Time const &time, EventImpl *event)
 {
-  Time tAbsolute = time + Now();
+  Time tAbsolute = time + TimeStep (m_currentTs);
 
   NS_ASSERT (tAbsolute.IsPositive ());
   NS_ASSERT (tAbsolute >= TimeStep (m_currentTs));
   Scheduler::Event ev;
   ev.impl = event;
   ev.key.m_ts = (uint64_t) tAbsolute.GetTimeStep ();
+  ev.key.m_context = GetContext ();
   ev.key.m_uid = m_uid;
   m_uid++;
-  ++m_unscheduledEvents;
+  m_unscheduledEvents++;
   m_events->Insert (ev);
-  return EventId (event, ev.key.m_ts, ev.key.m_uid);
+  return EventId (event, ev.key.m_ts, ev.key.m_context, ev.key.m_uid);
+}
+
+void
+DefaultSimulatorImpl::ScheduleWithContext (uint32_t context, Time const &time, EventImpl *event)
+{
+  NS_LOG_FUNCTION (this << context << time.GetTimeStep () << m_currentTs << event);
+
+  Scheduler::Event ev;
+  ev.impl = event;
+  ev.key.m_ts = m_currentTs + time.GetTimeStep ();
+  ev.key.m_context = context;
+  ev.key.m_uid = m_uid;
+  m_uid++;
+  m_unscheduledEvents++;
+  m_events->Insert (ev);
 }
 
 EventId
@@ -187,17 +212,18 @@
   Scheduler::Event ev;
   ev.impl = event;
   ev.key.m_ts = m_currentTs;
+  ev.key.m_context = GetContext ();
   ev.key.m_uid = m_uid;
   m_uid++;
-  ++m_unscheduledEvents;
+  m_unscheduledEvents++;
   m_events->Insert (ev);
-  return EventId (event, ev.key.m_ts, ev.key.m_uid);
+  return EventId (event, ev.key.m_ts, ev.key.m_context, ev.key.m_uid);
 }
 
 EventId
 DefaultSimulatorImpl::ScheduleDestroy (EventImpl *event)
 {
-  EventId id (Ptr<EventImpl> (event, false), m_currentTs, 2);
+  EventId id (Ptr<EventImpl> (event, false), m_currentTs, 0xffffffff, 2);
   m_destroyEvents.push_back (id);
   m_uid++;
   return id;
@@ -245,13 +271,14 @@
   Scheduler::Event event;
   event.impl = id.PeekEventImpl ();
   event.key.m_ts = id.GetTs ();
+  event.key.m_context = id.GetContext ();
   event.key.m_uid = id.GetUid ();
   m_events->Remove (event);
   event.impl->Cancel ();
   // whenever we remove an event from the event list, we have to unref it.
   event.impl->Unref ();
 
-  --m_unscheduledEvents;
+  m_unscheduledEvents--;
 }
 
 void
@@ -305,6 +332,12 @@
   return TimeStep (0x7fffffffffffffffLL);
 }
 
+uint32_t
+DefaultSimulatorImpl::GetContext (void) const
+{
+  return m_currentContext;
+}
+
 } // namespace ns3
 
 
--- a/src/simulator/default-simulator-impl.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/simulator/default-simulator-impl.h	Mon Nov 16 13:35:38 2009 +0300
@@ -26,14 +26,12 @@
 #include "event-impl.h"
 
 #include "ns3/ptr.h"
-#include "ns3/assert.h"
-#include "ns3/log.h"
 
 #include <list>
 
 namespace ns3 {
 
-  class DefaultSimulatorImpl : public SimulatorImpl
+class DefaultSimulatorImpl : public SimulatorImpl
 {
 public:
   static TypeId GetTypeId (void);
@@ -45,7 +43,9 @@
   virtual bool IsFinished (void) const;
   virtual Time Next (void) const;
   virtual void Stop (void);
+  virtual void Stop (Time const &time);
   virtual EventId Schedule (Time const &time, EventImpl *event);
+  virtual void ScheduleWithContext (uint32_t context, Time const &time, EventImpl *event);
   virtual EventId ScheduleNow (EventImpl *event);
   virtual EventId ScheduleDestroy (EventImpl *event);
   virtual void Remove (const EventId &ev);
@@ -56,19 +56,21 @@
   virtual Time Now (void) const;
   virtual Time GetDelayLeft (const EventId &id) const;
   virtual Time GetMaximumSimulationTime (void) const;
-  virtual void SetScheduler (Ptr<Scheduler> scheduler);
+  virtual void SetScheduler (ObjectFactory schedulerFactory);
+  virtual uint32_t GetContext (void) const;
 
 private:
   void ProcessOneEvent (void);
   uint64_t NextTs (void) const;
+  typedef std::list<EventId> DestroyEvents;
 
-  typedef std::list<EventId> DestroyEvents;
   DestroyEvents m_destroyEvents;
   bool m_stop;
   Ptr<Scheduler> m_events;
   uint32_t m_uid;
   uint32_t m_currentUid;
   uint64_t m_currentTs;
+  uint32_t m_currentContext;
   // number of events that have been inserted but not yet scheduled,
   // not counting the "destroy" events; this is used for validation
   int m_unscheduledEvents;
--- a/src/simulator/event-id.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/simulator/event-id.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -26,12 +26,14 @@
 EventId::EventId ()
   : m_eventImpl (0),
     m_ts (0),
+    m_context (0),
     m_uid (0)
 {}
   
-EventId::EventId (const Ptr<EventImpl> &impl, uint64_t ts, uint32_t uid)
+EventId::EventId (const Ptr<EventImpl> &impl, uint64_t ts, uint32_t context, uint32_t uid)
   : m_eventImpl (impl),
     m_ts (ts),
+    m_context (context),
     m_uid (uid)
 {}
 void 
@@ -60,6 +62,11 @@
   return m_ts;
 }
 uint32_t 
+EventId::GetContext (void) const
+{
+  return m_context;
+}
+uint32_t 
 EventId::GetUid (void) const
 {
   return m_uid;
@@ -69,6 +76,7 @@
 {
   return 
     a.m_uid == b.m_uid && 
+    a.m_context == b.m_context && 
     a.m_ts == b.m_ts && 
     a.m_eventImpl == b.m_eventImpl;
 }
--- a/src/simulator/event-id.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/simulator/event-id.h	Mon Nov 16 13:35:38 2009 +0300
@@ -47,7 +47,7 @@
 public:
   EventId ();
   // internal.
-  EventId (const Ptr<EventImpl> &impl, uint64_t ts, uint32_t uid);
+  EventId (const Ptr<EventImpl> &impl, uint64_t ts, uint32_t context, uint32_t uid);
   /**
    * This method is syntactic sugar for the ns3::Simulator::cancel
    * method.
@@ -72,11 +72,13 @@
    */
   EventImpl *PeekEventImpl (void) const;
   uint64_t GetTs (void) const;
+  uint32_t GetContext (void) const;
   uint32_t GetUid (void) const;
 private:
   friend bool operator == (const EventId &a, const EventId &b);
   Ptr<EventImpl> m_eventImpl;
   uint64_t m_ts;
+  uint32_t m_context;
   uint32_t m_uid;
 };
 
--- a/src/simulator/event-impl.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/simulator/event-impl.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -20,15 +20,13 @@
 
 #include "event-impl.h"
 
-
 namespace ns3 {
 
 EventImpl::~EventImpl ()
 {}
 
 EventImpl::EventImpl ()
-  : m_cancel (false),
-    m_count (1)
+  : m_cancel (false)
 {}
 
 void 
--- a/src/simulator/event-impl.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/simulator/event-impl.h	Mon Nov 16 13:35:38 2009 +0300
@@ -21,6 +21,7 @@
 #define EVENT_IMPL_H
 
 #include <stdint.h>
+#include "ns3/simple-ref-count.h"
 
 namespace ns3 {
 
@@ -35,12 +36,10 @@
  * most subclasses are usually created by one of the many Simulator::Schedule
  * methods.
  */
-class EventImpl
+class EventImpl : public SimpleRefCount<EventImpl>
 {
 public:
   EventImpl ();
-  inline void Ref (void) const;
-  inline void Unref (void) const;
   virtual ~EventImpl () = 0;
   /**
    * Called by the simulation engine to notify the event that it has expired.
@@ -64,30 +63,8 @@
 
 private:
   bool m_cancel;
-  mutable uint32_t m_count;
 };
 
-}; // namespace ns3
-
-namespace ns3 {
-
-void
-EventImpl::Ref (void) const
-{
-  m_count++;
-}
-
-void
-EventImpl::Unref (void) const
-{
-  uint32_t c;
-  c = --m_count;
-  if (c == 0)
-    {
-      delete this;
-    }
-}
-
 } // namespace ns3
 
 #endif /* EVENT_IMPL_H */
--- a/src/simulator/realtime-simulator-impl.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/simulator/realtime-simulator-impl.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -77,6 +77,7 @@
   // before ::Run is entered, the m_currentUid will be zero
   m_currentUid = 0;
   m_currentTs = 0;
+  m_currentContext = 0xffffffff;
   m_unscheduledEvents = 0;
 
   // Be very careful not to do anything that would cause a change or assignment
@@ -122,10 +123,12 @@
 }
 
 void
-RealtimeSimulatorImpl::SetScheduler (Ptr<Scheduler> scheduler)
+RealtimeSimulatorImpl::SetScheduler (ObjectFactory schedulerFactory)
 {
   NS_LOG_FUNCTION_NOARGS ();
 
+  Ptr<Scheduler> scheduler = schedulerFactory.Create<Scheduler> ();
+
   { 
     CriticalSection cs (m_mutex);
 
@@ -307,7 +310,7 @@
     NS_ASSERT_MSG (m_events->IsEmpty () == false, 
       "RealtimeSimulatorImpl::ProcessOneEvent(): event queue is empty");
     next = m_events->RemoveNext ();
-    --m_unscheduledEvents;
+    m_unscheduledEvents--;
 
     //
     // We cannot make any assumption that "next" is the same event we originally waited 
@@ -325,6 +328,7 @@
     // is frozen until the next event is executed.
     //
     m_currentTs = next.key.m_ts;
+    m_currentContext = next.key.m_context;
     m_currentUid = next.key.m_uid;
 
     // 
@@ -504,10 +508,11 @@
     Scheduler::Event next = m_events->RemoveNext ();
 
     NS_ASSERT (next.key.m_ts >= m_currentTs);
-    --m_unscheduledEvents;
+    m_unscheduledEvents--;
 
     NS_LOG_LOGIC ("handle " << next.key.m_ts);
     m_currentTs = next.key.m_ts;
+    m_currentContext = next.key.m_context;
     m_currentUid = next.key.m_ts;
     event = next.impl;
   }
@@ -522,6 +527,12 @@
   m_stop = true;
 }
 
+void 
+RealtimeSimulatorImpl::Stop (Time const &time)
+{
+  Simulator::Schedule (time, &Simulator::Stop);
+}
+
 //
 // Schedule an event for a _relative_ time in the future.
 //
@@ -544,14 +555,38 @@
     NS_ASSERT_MSG (tAbsolute >= TimeStep (m_currentTs), "RealtimeSimulatorImpl::Schedule(): time < m_currentTs");
     ev.impl = impl;
     ev.key.m_ts = (uint64_t) tAbsolute.GetTimeStep ();
+    ev.key.m_context = GetContext ();
     ev.key.m_uid = m_uid;
     m_uid++;
-    ++m_unscheduledEvents;
+    m_unscheduledEvents++;
     m_events->Insert (ev);
     m_synchronizer->Signal ();
   }
 
-  return EventId (impl, ev.key.m_ts, ev.key.m_uid);
+  return EventId (impl, ev.key.m_ts, ev.key.m_context, ev.key.m_uid);
+}
+
+void
+RealtimeSimulatorImpl::ScheduleWithContext (uint32_t context, Time const &time, EventImpl *impl)
+{
+  NS_LOG_FUNCTION (time << impl);
+
+  {
+    CriticalSection cs (m_mutex);
+    uint64_t ts;
+
+    ts = m_currentTs + time.GetTimeStep ();
+    NS_ASSERT_MSG (ts >= m_currentTs, "RealtimeSimulatorImpl::ScheduleRealtime(): schedule for time < m_currentTs");
+    Scheduler::Event ev;
+    ev.impl = impl;
+    ev.key.m_ts = ts;
+    ev.key.m_context = context;
+    ev.key.m_uid = m_uid;
+    m_uid++;
+    m_unscheduledEvents++;
+    m_events->Insert (ev);
+    m_synchronizer->Signal ();
+  }
 }
 
 EventId
@@ -564,14 +599,15 @@
 
     ev.impl = impl;
     ev.key.m_ts = m_currentTs;
+    ev.key.m_context = GetContext ();
     ev.key.m_uid = m_uid;
     m_uid++;
-    ++m_unscheduledEvents;
+    m_unscheduledEvents++;
     m_events->Insert (ev);
     m_synchronizer->Signal ();
   }
 
-  return EventId (impl, ev.key.m_ts, ev.key.m_uid);
+  return EventId (impl, ev.key.m_ts, ev.key.m_context, ev.key.m_uid);
 }
 
 Time
@@ -599,7 +635,7 @@
     ev.key.m_ts = ts;
     ev.key.m_uid = m_uid;
     m_uid++;
-    ++m_unscheduledEvents;
+    m_unscheduledEvents++;
     m_events->Insert (ev);
     m_synchronizer->Signal ();
   }
@@ -624,7 +660,7 @@
     ev.key.m_ts = ts;
     ev.key.m_uid = m_uid;
     m_uid++;
-    ++m_unscheduledEvents;
+    m_unscheduledEvents++;
     m_events->Insert (ev);
     m_synchronizer->Signal ();
   }
@@ -650,7 +686,7 @@
     // overridden by the uid of 2 which identifies this as an event to be 
     // executed at Simulator::Destroy time.
     //
-    id = EventId (Ptr<EventImpl> (impl, false), m_currentTs, 2);
+    id = EventId (Ptr<EventImpl> (impl, false), m_currentTs, 0xffffffff, 2);
     m_destroyEvents.push_back (id);
     m_uid++;
   }
@@ -702,10 +738,11 @@
     Scheduler::Event event;
     event.impl = id.PeekEventImpl ();
     event.key.m_ts = id.GetTs ();
+    event.key.m_context = id.GetContext ();
     event.key.m_uid = id.GetUid ();
     
     m_events->Remove (event);
-    --m_unscheduledEvents;
+    m_unscheduledEvents--;
     event.impl->Cancel ();
     event.impl->Unref ();
   }
@@ -771,6 +808,12 @@
   return TimeStep (0x7fffffffffffffffLL);
 }
 
+uint32_t
+RealtimeSimulatorImpl::GetContext (void) const
+{
+  return m_currentContext;
+}
+
 void 
 RealtimeSimulatorImpl::SetSynchronizationMode (enum SynchronizationMode mode)
 {
--- a/src/simulator/realtime-simulator-impl.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/simulator/realtime-simulator-impl.h	Mon Nov 16 13:35:38 2009 +0300
@@ -55,7 +55,9 @@
   virtual bool IsFinished (void) const;
   virtual Time Next (void) const;
   virtual void Stop (void);
+  virtual void Stop (Time const &time);
   virtual EventId Schedule (Time const &time, EventImpl *event);
+  virtual void ScheduleWithContext (uint32_t context, Time const &time, EventImpl *event);
   virtual EventId ScheduleNow (EventImpl *event);
   virtual EventId ScheduleDestroy (EventImpl *event);
   virtual void Remove (const EventId &ev);
@@ -66,7 +68,8 @@
   virtual Time Now (void) const;
   virtual Time GetDelayLeft (const EventId &id) const;
   virtual Time GetMaximumSimulationTime (void) const;
-  virtual void SetScheduler (Ptr<Scheduler> scheduler);
+  virtual void SetScheduler (ObjectFactory schedulerFactory);
+  virtual uint32_t GetContext (void) const;
 
   void ScheduleRealtime (Time const &time, EventImpl *event);
   void ScheduleRealtimeNow (EventImpl *event);
@@ -96,6 +99,7 @@
   uint32_t m_uid;
   uint32_t m_currentUid;
   uint64_t m_currentTs;
+  uint32_t m_currentContext;
 
   mutable SystemMutex m_mutex;
 
--- a/src/simulator/scheduler.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/simulator/scheduler.h	Mon Nov 16 13:35:38 2009 +0300
@@ -56,8 +56,9 @@
   static TypeId GetTypeId (void);
 
   struct EventKey {
-      uint64_t m_ts;
-      uint32_t m_uid;
+    uint64_t m_ts;
+    uint32_t m_uid;
+    uint32_t m_context;
   };
   struct Event {
     EventImpl *impl;
--- a/src/simulator/simulator-impl.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/simulator/simulator-impl.h	Mon Nov 16 13:35:38 2009 +0300
@@ -25,6 +25,7 @@
 #include "event-id.h"
 #include "nstime.h"
 #include "ns3/object.h"
+#include "ns3/object-factory.h"
 #include "ns3/ptr.h"
 
 namespace ns3 {
@@ -38,7 +39,9 @@
   virtual bool IsFinished (void) const = 0;
   virtual Time Next (void) const = 0;
   virtual void Stop (void) = 0;
+  virtual void Stop (Time const &time) = 0;
   virtual EventId Schedule (Time const &time, EventImpl *event) = 0;
+  virtual void ScheduleWithContext (uint32_t context, Time const &time, EventImpl *event) = 0;
   virtual EventId ScheduleNow (EventImpl *event) = 0;
   virtual EventId ScheduleDestroy (EventImpl *event) = 0;
   virtual void Remove (const EventId &ev) = 0;
@@ -49,7 +52,8 @@
   virtual Time Now (void) const = 0;
   virtual Time GetDelayLeft (const EventId &id) const = 0;
   virtual Time GetMaximumSimulationTime (void) const = 0;
-  virtual void SetScheduler (Ptr<Scheduler> scheduler) = 0;
+  virtual void SetScheduler (ObjectFactory schedulerFactory) = 0;
+  virtual uint32_t GetContext (void) const = 0;
 };
 
 } // namespace ns3
--- a/src/simulator/simulator.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/simulator/simulator.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -20,11 +20,8 @@
 #include "ns3/core-config.h"
 #include "simulator.h"
 #include "simulator-impl.h"
-#include "default-simulator-impl.h"
-#ifdef HAVE_PTHREAD_H
-# include "realtime-simulator-impl.h"
-#endif
 #include "scheduler.h"
+#include "map-scheduler.h"
 #include "event-impl.h"
 
 #include "ns3/ptr.h"
@@ -51,8 +48,8 @@
 
 GlobalValue g_schedTypeImpl = GlobalValue ("SchedulerType", 
   "The object class to use as the scheduler implementation",
-  StringValue ("ns3::MapScheduler"),
-  MakeStringChecker ());
+  TypeIdValue (MapScheduler::GetTypeId ()),
+  MakeTypeIdChecker ());
 
 
 #ifdef NS3_LOG_ENABLE
@@ -68,21 +65,34 @@
   os << Simulator::Now ().GetSeconds () << "s";
 }
 
+static void
+NodePrinter (std::ostream &os)
+{
+  if (Simulator::GetContext () == 0xffffffff)
+    {
+      os << "-1";
+    }
+  else
+    {
+      os << Simulator::GetContext ();
+    }
+}
+
 #endif /* NS3_LOG_ENABLE */
 
-static Ptr<SimulatorImpl> *PeekImpl (void)
+static SimulatorImpl **PeekImpl (void)
 {
-  static Ptr<SimulatorImpl> impl = 0;
+  static SimulatorImpl *impl = 0;
   return &impl;
 }
 
 static SimulatorImpl * GetImpl (void)
 {
-  Ptr<SimulatorImpl> &impl = *PeekImpl ();
+  SimulatorImpl **pimpl = PeekImpl ();
   /* Please, don't include any calls to logging macros in this function
    * or pay the price, that is, stack explosions.
    */
-  if (impl == 0) 
+  if (*pimpl == 0)
     {
       {
         ObjectFactory factory;
@@ -90,14 +100,14 @@
         
         g_simTypeImpl.GetValue (s);
         factory.SetTypeId (s.Get ());
-        impl = factory.Create<SimulatorImpl> ();
+        *pimpl = GetPointer (factory.Create<SimulatorImpl> ());
       }
       {
         ObjectFactory factory;
         StringValue s;
         g_schedTypeImpl.GetValue (s);
         factory.SetTypeId (s.Get ());
-        impl->SetScheduler (factory.Create<Scheduler> ());
+        (*pimpl)->SetScheduler (factory);
       }
 
 //
@@ -108,8 +118,9 @@
 // in an infinite recursion until the stack explodes.
 //
       LogSetTimePrinter (&TimePrinter);
+      LogSetNodePrinter (&NodePrinter);
     }
-  return PeekPointer (impl);
+  return *pimpl;
 }
 
 void
@@ -117,8 +128,8 @@
 {
   NS_LOG_FUNCTION_NOARGS ();
 
-  Ptr<SimulatorImpl> &impl = *PeekImpl (); 
-  if (impl == 0)
+  SimulatorImpl **pimpl = PeekImpl (); 
+  if (*pimpl == 0)
     {
       return;
     }
@@ -128,15 +139,17 @@
    * the stack explodes.
    */
   LogSetTimePrinter (0);
-  impl->Destroy ();
-  impl = 0;
+  LogSetNodePrinter (0);
+  (*pimpl)->Destroy ();
+  (*pimpl)->Unref ();
+  *pimpl = 0;
 }
 
 void
-Simulator::SetScheduler (Ptr<Scheduler> scheduler)
+Simulator::SetScheduler (ObjectFactory schedulerFactory)
 {
-  NS_LOG_FUNCTION (scheduler);
-  GetImpl ()->SetScheduler (scheduler);
+  NS_LOG_FUNCTION (schedulerFactory);
+  GetImpl ()->SetScheduler (schedulerFactory);
 }
 
 bool 
@@ -178,7 +191,7 @@
 Simulator::Stop (Time const &time)
 {
   NS_LOG_FUNCTION (time);
-  Simulator::Schedule (time, &Simulator::Stop);
+  GetImpl ()->Stop (time);
 }
 
 Time
@@ -204,6 +217,13 @@
   return DoSchedule (time, GetPointer (ev));
 }
 
+void
+Simulator::ScheduleWithContext (uint32_t context, Time const &time, const Ptr<EventImpl> &ev)
+{
+  NS_LOG_FUNCTION (time << context << ev);
+  return DoScheduleWithContext (context, time, GetPointer (ev));
+}
+
 EventId
 Simulator::ScheduleNow (const Ptr<EventImpl> &ev)
 {
@@ -222,6 +242,11 @@
 {
   return GetImpl ()->Schedule (time, impl);
 }
+void
+Simulator::DoScheduleWithContext (uint32_t context, Time const &time, EventImpl *impl)
+{
+  return GetImpl ()->ScheduleWithContext (context, time, impl);
+}
 EventId 
 Simulator::DoScheduleNow (EventImpl *impl)
 {
@@ -241,6 +266,13 @@
   return DoSchedule (time, MakeEvent (f));
 }
 
+void
+Simulator::ScheduleWithContext (uint32_t context, Time const &time, void (*f) (void))
+{
+  NS_LOG_FUNCTION (time << context << f);
+  return DoScheduleWithContext (context, time, MakeEvent (f));
+}
+
 EventId
 Simulator::ScheduleNow (void (*f) (void))
 {
@@ -289,6 +321,13 @@
   return GetImpl ()->GetMaximumSimulationTime ();
 }
 
+uint32_t
+Simulator::GetContext (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return GetImpl ()->GetContext ();
+}
+
 void
 Simulator::SetImplementation (Ptr<SimulatorImpl> impl)
 {
@@ -296,7 +335,13 @@
     {
       NS_FATAL_ERROR ("It is not possible to set the implementation after calling any Simulator:: function. Call Simulator::SetImplementation earlier or after Simulator::Destroy.");
     }
-  *PeekImpl () = impl;
+  *PeekImpl () = GetPointer (impl);
+  // Set the default scheduler
+  ObjectFactory factory;
+  StringValue s;
+  g_schedTypeImpl.GetValue (s);
+  factory.SetTypeId (s.Get ());
+  impl->SetScheduler (factory);
 //
 // Note: we call LogSetTimePrinter _after_ creating the implementation
 // object because the act of creation can trigger calls to the logging 
@@ -305,6 +350,7 @@
 // in an infinite recursion until the stack explodes.
 //
   LogSetTimePrinter (&TimePrinter);
+  LogSetNodePrinter (&NodePrinter);
 }
 Ptr<SimulatorImpl>
 Simulator::GetImplementation (void)
@@ -328,7 +374,7 @@
 class SimulatorEventsTestCase : public TestCase
 {
 public:
-  SimulatorEventsTestCase (Ptr<Scheduler> scheduler);
+  SimulatorEventsTestCase (ObjectFactory schedulerFactory);
   virtual bool DoRun (void);
   void A (int a);
   void B (int b);
@@ -344,10 +390,13 @@
   EventId m_idC;
   bool m_destroy;
   EventId m_destroyId;
+  ObjectFactory m_schedulerFactory;
 };
 
-SimulatorEventsTestCase::SimulatorEventsTestCase (Ptr<Scheduler> scheduler)
-  : TestCase ("Check that basic event handling is working with " + scheduler->GetInstanceTypeId ().GetName ())
+SimulatorEventsTestCase::SimulatorEventsTestCase (ObjectFactory schedulerFactory)
+  : TestCase ("Check that basic event handling is working with " + 
+              schedulerFactory.GetTypeId ().GetName ()),
+    m_schedulerFactory (schedulerFactory)
 {}
 uint64_t
 SimulatorEventsTestCase::NowUs (void)
@@ -416,6 +465,8 @@
   m_c = true;
   m_d = false;
 
+  Simulator::SetScheduler (m_schedulerFactory);
+
   EventId a = Simulator::Schedule (MicroSeconds (10), &SimulatorEventsTestCase::A, this, 1);
   Simulator::Schedule (MicroSeconds (11), &SimulatorEventsTestCase::B, this, 2);
   m_idC = Simulator::Schedule (MicroSeconds (12), &SimulatorEventsTestCase::C, this, 3);
@@ -761,11 +812,18 @@
   SimulatorTestSuite ()
     : TestSuite ("simulator")
   {
-    AddTestCase (new SimulatorEventsTestCase (CreateObject<ListScheduler> ()));
-    AddTestCase (new SimulatorEventsTestCase (CreateObject<MapScheduler> ()));
-    AddTestCase (new SimulatorEventsTestCase (CreateObject<HeapScheduler> ()));
-    AddTestCase (new SimulatorEventsTestCase (CreateObject<CalendarScheduler> ()));
-    AddTestCase (new SimulatorEventsTestCase (CreateObject<Ns2CalendarScheduler> ()));
+    ObjectFactory factory;
+    factory.SetTypeId (ListScheduler::GetTypeId ());
+
+    AddTestCase (new SimulatorEventsTestCase (factory));
+    factory.SetTypeId (MapScheduler::GetTypeId ());
+    AddTestCase (new SimulatorEventsTestCase (factory));
+    factory.SetTypeId (HeapScheduler::GetTypeId ());
+    AddTestCase (new SimulatorEventsTestCase (factory));
+    factory.SetTypeId (CalendarScheduler::GetTypeId ());
+    AddTestCase (new SimulatorEventsTestCase (factory));
+    factory.SetTypeId (Ns2CalendarScheduler::GetTypeId ());
+    AddTestCase (new SimulatorEventsTestCase (factory));
   }
 } g_simulatorTestSuite;
 
--- a/src/simulator/simulator.h	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/simulator/simulator.h	Mon Nov 16 13:35:38 2009 +0300
@@ -27,6 +27,7 @@
 #include "nstime.h"
 
 #include "ns3/deprecated.h"
+#include "ns3/object-factory.h"
 
 #include <stdint.h>
 #include <string>
@@ -80,7 +81,7 @@
    * in the previous scheduler will be transfered to the new scheduler
    * before we start to use it.
    */
-  static void SetScheduler (Ptr<Scheduler> scheduler);
+  static void SetScheduler (ObjectFactory schedulerFactory);
 
   /**
    * Every event scheduled by the Simulator::insertAtDestroy method is
@@ -283,6 +284,145 @@
   static EventId Schedule (Time const &time, void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
 
   /**
+   * Schedule an event with the given context.
+   * A context of 0xffffffff means no context is specified.
+   *
+   * @param time the relative expiration time of the event.
+   * @param context user-specified context parameter
+   * @param mem_ptr member method pointer to invoke
+   * @param obj the object on which to invoke the member method
+   */
+  template <typename MEM, typename OBJ>
+  static void ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj);
+
+  /**
+   * @param time the relative expiration time of the event.
+   * @param context user-specified context parameter
+   * @param mem_ptr member method pointer to invoke
+   * @param obj the object on which to invoke the member method
+   * @param a1 the first argument to pass to the invoked method
+   */
+  template <typename MEM, typename OBJ, typename T1>
+  static void ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1);
+
+  /**
+   * @param time the relative expiration time of the event.
+   * @param context user-specified context parameter
+   * @param mem_ptr member method pointer to invoke
+   * @param obj the object on which to invoke the member method
+   * @param a1 the first argument to pass to the invoked method
+   * @param a2 the second argument to pass to the invoked method
+   */
+  template <typename MEM, typename OBJ, typename T1, typename T2>
+  static void ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2);
+
+  /**
+   * @param time the relative expiration time of the event.
+   * @param context user-specified context parameter
+   * @param mem_ptr member method pointer to invoke
+   * @param obj the object on which to invoke the member method
+   * @param a1 the first argument to pass to the invoked method
+   * @param a2 the second argument to pass to the invoked method
+   * @param a3 the third argument to pass to the invoked method
+   */
+  template <typename MEM, typename OBJ, 
+            typename T1, typename T2, typename T3>
+  static void ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3);
+
+  /**
+   * @param time the relative expiration time of the event.
+   * @param context user-specified context parameter
+   * @param mem_ptr member method pointer to invoke
+   * @param obj the object on which to invoke the member method
+   * @param a1 the first argument to pass to the invoked method
+   * @param a2 the second argument to pass to the invoked method
+   * @param a3 the third argument to pass to the invoked method
+   * @param a4 the fourth argument to pass to the invoked method
+   */
+  template <typename MEM, typename OBJ, 
+            typename T1, typename T2, typename T3, typename T4>
+  static void ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4);
+
+  /**
+   * @param time the relative expiration time of the event.
+   * @param context user-specified context parameter
+   * @param mem_ptr member method pointer to invoke
+   * @param obj the object on which to invoke the member method
+   * @param a1 the first argument to pass to the invoked method
+   * @param a2 the second argument to pass to the invoked method
+   * @param a3 the third argument to pass to the invoked method
+   * @param a4 the fourth argument to pass to the invoked method
+   * @param a5 the fifth argument to pass to the invoked method
+   */
+  template <typename MEM, typename OBJ, 
+            typename T1, typename T2, typename T3, typename T4, typename T5>
+  static void ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, 
+                           T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
+  /**
+   * @param time the relative expiration time of the event.
+   * @param context user-specified context parameter
+   * @param f the function to invoke
+   */
+  static void ScheduleWithContext (uint32_t context, Time const &time, void (*f) (void));
+
+  /**
+   * @param time the relative expiration time of the event.
+   * @param context user-specified context parameter
+   * @param f the function to invoke
+   * @param a1 the first argument to pass to the function to invoke
+   */
+  template <typename U1, typename T1>
+  static void ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1), T1 a1);
+
+  /**
+   * @param time the relative expiration time of the event.
+   * @param context user-specified context parameter
+   * @param f the function to invoke
+   * @param a1 the first argument to pass to the function to invoke
+   * @param a2 the second argument to pass to the function to invoke
+   */
+  template <typename U1, typename U2, typename T1, typename T2>
+  static void ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2), T1 a1, T2 a2);
+
+  /**
+   * @param time the relative expiration time of the event.
+   * @param context user-specified context parameter
+   * @param f the function to invoke
+   * @param a1 the first argument to pass to the function to invoke
+   * @param a2 the second argument to pass to the function to invoke
+   * @param a3 the third argument to pass to the function to invoke
+   */
+  template <typename U1, typename U2, typename U3, typename T1, typename T2, typename T3>
+  static void ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3);
+
+  /**
+   * @param time the relative expiration time of the event.
+   * @param context user-specified context parameter
+   * @param f the function to invoke
+   * @param a1 the first argument to pass to the function to invoke
+   * @param a2 the second argument to pass to the function to invoke
+   * @param a3 the third argument to pass to the function to invoke
+   * @param a4 the fourth argument to pass to the function to invoke
+   */
+  template <typename U1, typename U2, typename U3, typename U4, 
+            typename T1, typename T2, typename T3, typename T4>
+  static void ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4);
+
+  /**
+   * @param time the relative expiration time of the event.
+   * @param context user-specified context parameter
+   * @param f the function to invoke
+   * @param a1 the first argument to pass to the function to invoke
+   * @param a2 the second argument to pass to the function to invoke
+   * @param a3 the third argument to pass to the function to invoke
+   * @param a4 the fourth argument to pass to the function to invoke
+   * @param a5 the fifth argument to pass to the function to invoke
+   */
+  template <typename U1, typename U2, typename U3, typename U4, typename U5,
+            typename T1, typename T2, typename T3, typename T4, typename T5>
+  static void ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
+
+  /**
    * Schedule an event to expire Now. All events scheduled to
    * to expire "Now" are scheduled FIFO, after all normal events
    * have expired. 
@@ -588,6 +728,11 @@
   static Time GetMaximumSimulationTime (void);
 
   /**
+   * \returns the current simulation context
+   */
+  static uint32_t GetContext (void);
+
+  /**
    * \param time delay until the event expires
    * \param event the event to schedule
    * \returns a unique identifier for the newly-scheduled event.
@@ -598,6 +743,17 @@
   static EventId Schedule (Time const &time, const Ptr<EventImpl> &event);  
 
   /**
+   * \param time delay until the event expires
+   * \param context event context
+   * \param event the event to schedule
+   * \returns a unique identifier for the newly-scheduled event.
+   *
+   * This method will be typically used by language bindings
+   * to delegate events to their own subclass of the EventImpl base class.
+   */
+  static void ScheduleWithContext (uint32_t context, Time const &time, const Ptr<EventImpl> &event);
+
+  /**
    * \param event the event to schedule
    * \returns a unique identifier for the newly-scheduled event.
    *
@@ -619,6 +775,7 @@
   ~Simulator ();
 
   static EventId DoSchedule (Time const &time, EventImpl *event);  
+  static void DoScheduleWithContext (uint32_t context, Time const &time, EventImpl *event);
   static EventId DoScheduleNow (EventImpl *event);
   static EventId DoScheduleDestroy (EventImpl *event);
 };
@@ -721,6 +878,86 @@
 
 
 template <typename MEM, typename OBJ>
+void Simulator::ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj)
+{
+  DoScheduleWithContext (context, time, MakeEvent (mem_ptr, obj));
+}
+
+
+template <typename MEM, typename OBJ,
+          typename T1>
+void Simulator::ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1)
+{
+  return DoScheduleWithContext (context, time, MakeEvent (mem_ptr, obj, a1));
+}
+
+template <typename MEM, typename OBJ,
+          typename T1, typename T2>
+void Simulator::ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2)
+{
+  return DoScheduleWithContext (context, time, MakeEvent (mem_ptr, obj, a1, a2));
+}
+
+template <typename MEM, typename OBJ,
+          typename T1, typename T2, typename T3>
+void Simulator::ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3)
+{
+  return DoScheduleWithContext (context, time, MakeEvent (mem_ptr, obj, a1, a2, a3));
+}
+
+template <typename MEM, typename OBJ,
+          typename T1, typename T2, typename T3, typename T4>
+void Simulator::ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4)
+{
+  return DoScheduleWithContext (context, time, MakeEvent (mem_ptr, obj, a1, a2, a3, a4));
+}
+
+template <typename MEM, typename OBJ,
+          typename T1, typename T2, typename T3, typename T4, typename T5>
+void Simulator::ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj,
+                             T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
+{
+  return DoScheduleWithContext (context, time, MakeEvent (mem_ptr, obj, a1, a2, a3, a4, a5));
+}
+
+template <typename U1, typename T1>
+void Simulator::ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1), T1 a1)
+{
+  return DoScheduleWithContext (context, time, MakeEvent (f, a1));
+}
+
+template <typename U1, typename U2,
+          typename T1, typename T2>
+void Simulator::ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2), T1 a1, T2 a2)
+{
+  return DoScheduleWithContext (context, time, MakeEvent (f, a1, a2));
+}
+
+template <typename U1, typename U2, typename U3,
+          typename T1, typename T2, typename T3>
+void Simulator::ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3)
+{
+  return DoScheduleWithContext (context, time, MakeEvent (f, a1, a2, a3));
+}
+
+template <typename U1, typename U2, typename U3, typename U4,
+          typename T1, typename T2, typename T3, typename T4>
+void Simulator::ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4)
+{
+  return DoScheduleWithContext (context, time, MakeEvent (f, a1, a2, a3, a4));
+}
+
+template <typename U1, typename U2, typename U3, typename U4, typename U5,
+          typename T1, typename T2, typename T3, typename T4, typename T5>
+void Simulator::ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
+{
+  return DoScheduleWithContext (context, time, MakeEvent (f, a1, a2, a3, a4, a5));
+}
+
+
+
+
+template <typename MEM, typename OBJ>
 EventId
 Simulator::ScheduleNow (MEM mem_ptr, OBJ obj) 
 {
--- a/src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -303,8 +303,8 @@
   Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
   app->Setup (ns3TcpSocket, sinkAddress, 1040, 10, DataRate ("5Mbps"));
   nodes.Get (0)->AddApplication (app);
-  app->Start (Seconds (1.));
-  app->Stop (Seconds (1.1));
+  app->SetStartTime (Seconds (1.));
+  app->SetStopTime (Seconds (1.1));
 
   //
   // The idea here is that someone will look very closely at the all of the
@@ -484,8 +484,8 @@
   Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
   app->Setup (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("1Mbps"));
   n0n1.Get (0)->AddApplication (app);
-  app->Start (Seconds (1.0));
-  app->Stop (Seconds (5.4));
+  app->SetStartTime (Seconds (1.0));
+  app->SetStopTime (Seconds (5.4));
 
   if (m_writeResults)
     {
--- a/src/test/ns3wifi/wifi-interference-test-suite.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/src/test/ns3wifi/wifi-interference-test-suite.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -211,11 +211,13 @@
   // Tracing
 //  wifiPhy.EnablePcap ("wifi-simple-interference", devices.Get (0));
   
-  Simulator::Schedule (Seconds (startTime), &GenerateTraffic, 
-                       source, PpacketSize, numPackets, interPacketInterval);
+  Simulator::ScheduleWithContext (source->GetNode ()->GetId (),
+				  Seconds (startTime), &GenerateTraffic, 
+				  source, PpacketSize, numPackets, interPacketInterval);
   
-  Simulator::Schedule (Seconds (startTime + delta/1000000.0), &GenerateTraffic, 
-                       interferer, IpacketSize, numPackets, interPacketInterval);
+  Simulator::ScheduleWithContext (interferer->GetNode ()->GetId (),
+				  Seconds (startTime + delta/1000000.0), &GenerateTraffic, 
+				  interferer, IpacketSize, numPackets, interPacketInterval);
   
   Simulator::Run ();
   Simulator::Destroy ();
--- a/test.py	Mon Nov 16 13:32:56 2009 +0300
+++ b/test.py	Mon Nov 16 13:35:38 2009 +0300
@@ -132,6 +132,7 @@
     ("tutorial/second", "True", "True"),
     ("tutorial/third", "True", "True"),
     ("tutorial/fourth", "True", "True"),
+    ("tutorial/fifth", "True", "True"),
 
     ("udp/udp-echo", "True", "True"),
 
@@ -560,7 +561,7 @@
         for path in NS3_MODULE_PATH:
             os.environ["DYLD_LIBRARY_PATH"] += ":" + path
         if options.verbose:
-            print "os.environ[\"DYLD_LIBRARY_PATH\"] == %s" % os.environ["DY_LIBRARY_PATH"]
+            print "os.environ[\"DYLD_LIBRARY_PATH\"] == %s" % os.environ["DYLD_LIBRARY_PATH"]
     elif sys.platform == "win32":
         if not have_PATH:
             os.environ["PATH"] = ""
@@ -616,6 +617,7 @@
         self.shell_command = ""
         self.display_name = ""
         self.basedir = ""
+        self.tempdir = ""
         self.cwd = ""
         self.tmp_file_name = ""
         self.returncode = False
@@ -674,6 +676,13 @@
         self.basedir = basedir
 
     #
+    # This is the directory to which a running test suite should write any 
+    # temporary files.
+    #
+    def set_tempdir(self, tempdir):
+        self.tempdir = tempdir
+
+    #
     # This is the current working directory that will be given to an executing
     # test as it is being run.  It will be used for examples to tell them where
     # to write all of the pcap files that we will be carefully ignoring.  For
@@ -766,7 +775,8 @@
                     # file name
                     #
                     (job.returncode, standard_out, standard_err, et) = run_job_synchronously(job.shell_command + 
-                        " --basedir=%s --out=%s" % (job.basedir, job.tmp_file_name), job.cwd, options.valgrind)
+                        " --basedir=%s --tempdir=%s --out=%s" % (job.basedir, job.tempdir, job.tmp_file_name), 
+                        job.cwd, options.valgrind)
 
                 job.set_elapsed_time(et)
 
@@ -804,11 +814,33 @@
         # For example, if the user only wants to run BVT tests, we only have
         # to build the test-runner and can ignore all of the examples.
         #
+        # If the user only wants to run a single example, then we can just build
+        # that example.
+        #
+        # If there is no constraint, then we have to build everything since the
+        # user wants to run everything.
+        #
         if options.kinds or options.list or (len(options.constrain) and options.constrain in core_kinds):
-            proc = subprocess.Popen("waf --target=test-runner", shell = True)
+            if sys.platform == "win32":
+                waf_cmd = "waf --target=test-runner"
+            else:
+                waf_cmd = "./waf --target=test-runner"
+        elif len(options.example):
+            if sys.platform == "win32":
+                waf_cmd = "waf --target=%s" % os.path.basename(options.example)
+            else:
+                waf_cmd = "./waf --target=%s" % os.path.basename(options.example)
+
         else:
-            proc = subprocess.Popen("waf", shell = True)
+            if sys.platform == "win32":
+                waf_cmd = "waf"
+            else:
+                waf_cmd = "./waf"
 
+        if options.verbose:
+            print "Building: %s" % waf_cmd
+
+        proc = subprocess.Popen(waf_cmd, shell = True)
         proc.communicate()
 
     #
@@ -982,6 +1014,7 @@
             job.set_tmp_file_name(os.path.join(testpy_output_dir, "%s.xml" % test))
             job.set_cwd(os.getcwd())
             job.set_basedir(os.getcwd())
+            job.set_tempdir(testpy_output_dir)
             if (options.multiple):
                 multiple = " --multiple"
             else:
@@ -1052,6 +1085,7 @@
                         job.set_tmp_file_name("")
                         job.set_cwd(testpy_output_dir)
                         job.set_basedir(os.getcwd())
+                        job.set_tempdir(testpy_output_dir)
                         job.set_shell_command("examples/%s" % test)
 
                         if options.valgrind and not eval(do_valgrind_run):
@@ -1075,6 +1109,7 @@
         job.set_tmp_file_name("")
         job.set_cwd(testpy_output_dir)
         job.set_basedir(os.getcwd())
+        job.set_tempdir(testpy_output_dir)
         job.set_shell_command("examples/%s" % options.example)
         
         if options.verbose:
--- a/utils/bench-simulator.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/utils/bench-simulator.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -162,21 +162,26 @@
     }
   while (argc > 0) 
     {
+      ObjectFactory factory;
       if (strcmp ("--list", argv[0]) == 0) 
         {
-          Simulator::SetScheduler (CreateObject<ListScheduler> ());
+          factory.SetTypeId ("ns3::ListScheduler");
+          Simulator::SetScheduler (factory);
         } 
       else if (strcmp ("--heap", argv[0]) == 0) 
         {
-          Simulator::SetScheduler (CreateObject<HeapScheduler> ());
+          factory.SetTypeId ("ns3::HeapScheduler");
+          Simulator::SetScheduler (factory);
         } 
       else if (strcmp ("--map", argv[0]) == 0) 
         {
-          Simulator::SetScheduler (CreateObject<MapScheduler> ());
+          factory.SetTypeId ("ns3::HeapScheduler");
+          Simulator::SetScheduler (factory);
         } 
       else if (strcmp ("--calendar", argv[0]) == 0)
         {
-          Simulator::SetScheduler (CreateObject<CalendarScheduler> ());
+          factory.SetTypeId ("ns3::CalendarScheduler");
+          Simulator::SetScheduler (factory);
         }
       else if (strcmp ("--debug", argv[0]) == 0) 
         {
--- a/utils/test-runner.cc	Mon Nov 16 13:32:56 2009 +0300
+++ b/utils/test-runner.cc	Mon Nov 16 13:35:38 2009 +0300
@@ -40,11 +40,13 @@
   bool doKinds = false;
 
   bool haveBasedir = false;
+  bool haveTempdir = false;
   bool haveOutfile = false;
   bool haveType = false;
 
   std::string suiteName;
   std::string basedir;
+  std::string tempdir;
   std::string outfileName;
   std::string typeName;
 
@@ -96,6 +98,12 @@
           doSuite = true;
         }
 
+      if (arg.find ("--tempdir=") != std::string::npos)
+        {
+          tempdir = arg.substr (arg.find_first_of ("=") + 1, 9999);
+          haveTempdir = true;
+        }
+
       if (arg.compare ("--verbose") == 0)
         {
           doVerbose = true;
@@ -247,6 +255,7 @@
       if (doSuite == false || (doSuite == true && suiteName == testSuite->GetName ()))
         {
           testSuite->SetBaseDir (basedir);
+          testSuite->SetTempDir (tempdir);
           testSuite->SetStream (pofs);
           testSuite->SetVerbose (doVerbose);
           testSuite->SetContinueOnFailure (doMultiple);
--- a/wscript	Mon Nov 16 13:32:56 2009 +0300
+++ b/wscript	Mon Nov 16 13:35:38 2009 +0300
@@ -194,8 +194,13 @@
                    help=('Compile NS-3 statically: works only on linux, without python'),
                    dest='enable_static', action='store_true',
                    default=False)
+    opt.add_option('--doxygen-no-build',
+                   help=('Run doxygen to generate html documentation from source comments, '
+                         'but do not wait for ns-3 to finish the full build.'),
+                   action="store_true", default=False,
+                   dest='doxygen_no_build')
 
-    # options provided in a script in a subdirectory named "src"
+    # options provided in subdirectories
     opt.sub_options('src')
     opt.sub_options('bindings/python')
     opt.sub_options('src/internet-stack')
@@ -596,6 +601,11 @@
             raise Utils.WafError("Cannot run regression tests: building the ns-3 examples is not enabled"
                                  " (regression tests are based on examples)")
 
+
+    if Options.options.doxygen_no_build:
+        _doxygen(bld)
+        raise SystemExit(0)
+
 def shutdown(ctx):
     bld = wutils.bld
     if wutils.bld is None:
@@ -712,9 +722,7 @@
     env = wutils.bld.env
     wutils.run_argv([shell], env, {'NS3_MODULE_PATH': os.pathsep.join(env['NS3_MODULE_PATH'])})
 
-def doxygen(bld):
-    """do a full build, generate the introspected doxygen and then the doxygen"""
-    Scripting.build(bld)
+def _doxygen(bld):
     env = wutils.bld.env
     proc_env = wutils.get_proc_env()
 
@@ -736,6 +744,11 @@
     if subprocess.Popen(['doxygen', doxygen_config]).wait():
         raise SystemExit(1)
 
+def doxygen(bld):
+    """do a full build, generate the introspected doxygen and then the doxygen"""
+    Scripting.build(bld)
+    _doxygen(bld)
+
 def lcov_report():
     env = Build.bld.env
     variant_name = env['NS3_ACTIVE_VARIANT']