merge with HEAD
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Thu, 25 Feb 2010 14:17:21 +0100
changeset 6068 a2127017ecb4
parent 6067 ccbdc2b19ea5 (current diff)
parent 6062 f62b76f5c92a (diff)
child 6069 c21754b56036
merge with HEAD
src/common/ascii-writer.cc
src/common/ascii-writer.h
src/common/pcap-writer.cc
src/common/pcap-writer.h
src/common/propagation-loss-model-test-suite.cc
src/devices/mesh/mesh-wifi-interface-mac.cc
src/devices/wifi/adhoc-wifi-mac.cc
src/devices/wifi/dca-txop.cc
src/devices/wifi/dca-txop.h
src/devices/wifi/edca-txop-n.cc
src/devices/wifi/edca-txop-n.h
src/devices/wifi/jakes-propagation-loss-model.cc
src/devices/wifi/jakes-propagation-loss-model.h
src/devices/wifi/mac-low.cc
src/devices/wifi/mac-low.h
src/devices/wifi/nqap-wifi-mac.cc
src/devices/wifi/nqsta-wifi-mac.cc
src/devices/wifi/propagation-delay-model.cc
src/devices/wifi/propagation-delay-model.h
src/devices/wifi/propagation-loss-model-test-suite.cc
src/devices/wifi/propagation-loss-model.cc
src/devices/wifi/propagation-loss-model.h
src/devices/wifi/qadhoc-wifi-mac.cc
src/devices/wifi/qap-wifi-mac.cc
src/devices/wifi/qsta-wifi-mac.cc
src/devices/wifi/wscript
src/test/ns3wifi/wifi-interference-test-suite.cc
--- a/.hgtags	Thu Feb 25 13:51:59 2010 +0100
+++ b/.hgtags	Thu Feb 25 14:17:21 2010 +0100
@@ -41,3 +41,6 @@
 79ff6ad1adbb7b4677759ddf52028b68b0515168 ns-3.6-RC3
 39a82d7a0d661febe42e75f26ada79424258e330 ns-3.6-RC4
 d55c479666ac6be0575fac695ddf355c0530e0dd ns-3.6
+892efc87a1518fb69b04628c779195aee139d33e ns-3.7-RC3
+17bf6ee332baaa6b6f9b8a26d29c98f4e715648f ns-3.7-RC4
+be3fb855c65a46d22a7693cd156f154f63602e8e ns-3.7
--- a/AUTHORS	Thu Feb 25 13:51:59 2010 +0100
+++ b/AUTHORS	Thu Feb 25 14:17:21 2010 +0100
@@ -6,6 +6,7 @@
 Raj Bhattacharjea (raj.b@gatech.edu)
 Timo Bingmann (timo.bingmann@student.kit.edu)
 Pavel Boyko (boyko@iitp.ru)
+Jonathan Brugge (j.d.brugge@student.utwente.nl)
 Elena Buchatskaia (borovkovaes@iitp.ru)
 Gustavo Carneiro (gjc@inescporto.pt, gjcarneiro@gmail.com)
 Angelos Chatzipapas (chatzipa@ceid.upatras.gr)
@@ -27,6 +28,7 @@
 Fabian Mauchle (f1mauchl@hsr.ch)
 Andrey Mazo (mazo@iitp.ru)
 Faker Moatamri (faker.moatamri@sophia.inria.fr)
+Michael Nowatkowski (nowatkom@gmail.com)
 Duy Nguyen (duy@soe.ucsc.edu)
 Tommaso Pecorella (tommaso.pecorella@unifi.it)
 Yana Podkosova (yanapdk@rambler.ru)
@@ -35,10 +37,12 @@
 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)
+Phillip Sitbon (phillip.sitbon@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)
+Andras Varga (andras@omnetpp.org)
 Sebastien Vincent (vincent@clarinet.u-strasbg.fr)
 Guillaume Vu-Brugier (gvubrugier@gmail.com)
 Tom Wambold (tom5760@gmail.com)
--- a/CHANGES.html	Thu Feb 25 13:51:59 2010 +0100
+++ b/CHANGES.html	Thu Feb 25 14:17:21 2010 +0100
@@ -44,6 +44,63 @@
 us a note on ns-developers mailing list.  </p>
 
 <hr>
+<h1>Changes from ns-3.7 to ns-3.8</h1>
+
+<h2>Changes to build system:</h2>
+
+<h2>New API:</h2>
+
+<h2>Changes to existing API:</h2>
+<ul>
+</pre>
+<li><b>Tracing Helpers</b>: The organization of helpers for both pcap and ascii
+tracing, in devices and protocols, has been reworked.  Instead of each device 
+and protocol helper re-implementing trace enable methods, classes have been 
+developed to implement user-level tracing in a consistent way; and device and 
+protocol helpers use those classes to provide tracing functionality.<br>
+In addition to consistent operation across all helpers, the object name service
+has been integrated into the trace file naming scheme.<br>
+The internet stack helper has been extensively massaged to make it easier to 
+manage traces originating from protocols.  It used to be the case that there 
+was essentially no opportunity to filter tracing on interfaces, and resulting
+trace file names collided with those created by devices.  File names are now
+disambiguated and one can enable traces on a protocol/interface basis analogously
+to the node/device granularity of device-based helpers.<br>
+The primary user-visible results of this change are that trace-related functions
+have been changed from static functions to method calls; and a new object has
+been developed to hold streams for ascii traces.<br>
+New functionality is present for ascii traces.  It is now possible to create
+multiple ascii trace files automatically just as was possible for pcap trace 
+files.<br>
+The implementation of the helper code has been designed also to provide 
+functionality to make it easier for sophisticated users to hook traces of 
+various kinds and write results to (file) streams.
+Before:
+<pre>
+  CsmaHelper::EnablePcapAll ();
+
+  std::ofstream ascii;
+  ascii.open ("csma-one-subnet.tr", std::ios_base::binary | std::ios_base::out);
+  CsmaHelper::EnableAsciiAll (ascii);
+
+  InternetStackHelper::EnableAsciiAll (ascii);
+</pre>
+After:
+<pre>
+  CsmaHelper csmaHelper;
+  InternetStackHelper stack;
+  csmaHelper.EnablePcapAll ();
+
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("csma-one-subnet.tr"));
+
+  stack.EnableAsciiIpv4All (stream);
+
+</pre>
+
+
+
+<hr>
 <h1>Changes from ns-3.6 to ns-3.7</h1>
 
 
@@ -64,7 +121,7 @@
 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.
-<li><b>Aod hoc On-Demand Distance Vector (AODV)</b> routing model, 
+<li><b>Ad hoc On-Demand Distance Vector (AODV)</b> routing model, 
 <a href=http://www.ietf.org/rfc/rfc3561.txt>RFC 3561</a> </li>
 <li><b>Ipv4::IsDestinationAddress (Ipv4Address address, uint32_t iif)</b> Method added to support checks of whether a destination address should be accepted 
 as one of the host's own addresses.  RFC 1122 Strong/Weak end system behavior can be changed with a new attribute (WeakEsModel) in class Ipv4.  </li>
--- a/RELEASE_NOTES	Thu Feb 25 13:51:59 2010 +0100
+++ b/RELEASE_NOTES	Thu Feb 25 14:17:21 2010 +0100
@@ -9,21 +9,76 @@
 Consult the file CHANGES.html for more detailed information about changed
 API and behavior across ns-3 releases.
 
+Release 3.8
+===========
+
+Availability
+------------
+This release is not yet available.
+
+Supported platforms
+-------------------
+ns-3.8 has been tested on the following platforms:
+  - linux x86 gcc 4.4.0, 4.3.2, 4.2, 4.1.1, 4.1 and 3.4.6 (debug and optimized)
+  - linux x86_64 gcc 4.4.0, 4.3.2, 4.2.4, 4.2.3, 4.2.1, 4.1.3, 3.4.6 (debug and optimized)
+  - MacOS X ppc gcc 4.0.x and 4.2.x (debug and optimized)
+  - cygwin gcc 3.4.4 (debug only), gcc 4.3.2 (debug and optimized)
+
+Unofficially supported platform
+-------------------
+- mingw gcc 3.4.5 (debug only)
+
+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
+-------------------------
+  a) 
+
+  b) 
+    
+  c) 
+
+API changes from ns-3.7
+-----------------------
+API changes for this release are documented in the file CHANGES.html. 
+
+Bugs fixed
+----------
+The following lists many of the bugs that were fixed since ns-3.7, in
+many cases referencing the Bugzilla bug number
+   - bug 747 - Listening TCP socket closes on RST
+   - bug 788 - OLSR_NEIGH_HOLD_TIME should be 3 times OLSR_REFRESH_INTERVAL 
+
+Known issues
+------------
+ns-3 builds have been 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.7
 ===========
 
 Availability
 ------------
-This release is not yet available
+This release is immediately available from:
+http://www.nsnam.org/releases/ns-allinone-3.7.tar.bz2
 
 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)
+  - linux x86 gcc 4.4.0, 4.3.2, 4.2, 4.1.1, 4.1 and 3.4.6 (debug and optimized)
+  - linux x86_64 gcc 4.4.0, 4.3.2, 4.2.4, 4.2.3, 4.2.1, 4.1.3, 3.4.6 (debug and optimized)
+  - MacOS X ppc gcc 4.0.x and 4.2.x (debug and optimized)
   - cygwin gcc 3.4.4 (debug only), gcc 4.3.2 (debug and optimized)
 
+Unofficially supported platform
+-------------------
+- mingw gcc 3.4.5 (debug only)
+
 Not all ns-3 options are available on all platforms; consult the
 wiki for more information:
 http://www.nsnam.org/wiki/index.php/Installation
@@ -31,30 +86,98 @@
 New user-visible features
 -------------------------
 
-  a) The ns-3 logging macros (NS_LOG_*) now report automatically the node id
-     of the event which called the macro.
+  a) Ad hoc On-Demand Distance Vector (AODV) routing model (RFC 3561)
 
-  b) Ad hoc On-Demand Distance Vector (AODV) routing model according to RFC 3561. 
+  b) IPv6 extensions support to add IPv6 extensions and options.  Two 
+     examples (fragmentation and loose routing) are available.
 
-  c) Net-anim:
-     - interface for animation of point-to-point links.
-     - dumbbell, grid, and star examples in examples/animation
+  c) NetAnim interface: Provides an interface to the Qt-based NetAnim 
+     animator, which supports static, point-to-point topology-based 
+     packet animations.
 
-  d) Topology Helper classes:
+  d) New topology helpers have been introduced
      - PointToPointDumbbellHelper
      - PointToPointGridHelper
      - PointToPointStarHelper
      - CsmaStarHelper
 
-  e) IPv6 extensions support and two new examples for fragmentation and loose routing.
+  e) Equal-cost multipath for global routing: Enables quagga's equal 
+     cost multipath for Ipv4GlobalRouting, and adds an attribute that
+     can enable it with random packet distribution policy across 
+     equal cost routes.
+
+  f) Binding sockets to devices:  A method analogous to a SO_BINDTODEVICE
+     socket option has been introduced to class Socket
+
+  g) Object::DoStart: 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.
+
+  h) Ipv4::IsDestinationAddress method added to support checks of whether a 
+     destination address should be accepted as one of the host's own 
+     addresses.  
+
+  i) UniformDiscPositionAllocator added; distributes uniformly the nodes 
+     within a disc of given radius. 
+
+  j) ChannelNumber attribute added to YansWifiPhy. Now it is possible to 
+     setup wifi channel using WifiPhyHelper::Set() method.
+
+  k) WaypointMobilityModel provides a method to add mobility as a set of 
+     (time, position) pairs
+
+  l) 802.11p WiFi standards 
+  
+  m) UDP Client/Server application
+
+  n) Support transactions in the SQLite output interface, making it usable for larger amounts of data
 
 API changes from ns-3.6
 -----------------------
 API changes for this release are documented in the file CHANGES.html. 
 
+Bugs fixed
+----------
+The following lists many of the bugs that were fixed since ns-3.6, in
+many cases referencing the Bugzilla bug number
+   - bug 752: Object::DoStart is not executed for objects created at t > 0
+   - bug 767:  Incorrect modulation for 802.11a modes
+   - bug 725: wifi fragmentation and RTS cannot be used at the same time
+   - bug 782: CreateTap () requires IP address in modes other than 
+     CONFIGURE_LOCAL.
+   - bug 769: Queue::GetTotalReceived{Bytes,Packets}() broken
+   - bug 738 ReceiveErrorModel called too late
+   - Fix NSC improper response to FIN
+   - Fixed bug in serialization of PbbAddressBlock.
+   - Fix bug 780 (problem in RoutingTableComputation with asymetric links), 
+     while adding debugging methods to OLSR.  
+   - bug 759: Ipv6 uses wrong outgoing interface.
+   - bug 770: IPv6 size calculation for unknown options is wrong.
+   - bug 771: Radvd does not set ttl value.
+   - Fix bug 606:  Arp depends on IP routing system
+   - pad out CSMA payloads to 46 bytes if needed
+   - Drop CSMA packets with CRC errors, rescan, dox tweaks
+   - Add FCS capability to CSMA
+   - Mesh:Dot11s: fixed airtime metric
+   - Get emu working again:  Add Dix/Llc option, add and use contextual 
+     realtime schedule ops, don't refcount realtime simulator impl
+   - bug 695 - DcfManager::UpdateBackoff () uses slow HighPrecision::Div()
+   - bug 674 - EIFS is not handled correctly in DcfManager::GetAccessGrantStart
+   - bug 739 -  OLSR: Strange HTime value in HELLO messages 
+   - bug 746 -  UDP source address is not set to bound address
+   - bug 735 Update Olsr for local delivery
+   - bug 740 OLSR MprCompute () works wrong: fixed
+   - bug 729 Enable IPv6 over PPP.
+   - bug 645: fixes for opening stats file with OMNeT++
+   - bug 689: default energy detection and CCA thresholds are changed to be 
+     more realistic.
+   - bug 733: OLSR MPR Computation give incorrect result
+   - Mesh: HWMP: fixed proactive routes
+   - Mesh: fixed FLAME PATH_UPDATE procedure, fixed mesh.cc 
+
 Known issues
 ------------
-ns-3.6 build is known to fail on the following platforms:
+ns-3 builds have been 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/callbacks_list.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/callbacks_list.py	Thu Feb 25 14:17:21 2010 +0100
@@ -12,6 +12,8 @@
     ['bool', 'std::string', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['bool', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet const>', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['bool', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet const>', 'unsigned short', 'ns3::Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
+    ['void', 'ns3::Mac48Address', 'unsigned char', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
+    ['void', 'ns3::Mac48Address', 'unsigned char', 'bool', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::Packet const>', 'ns3::Ipv4Header const&', 'ns3::Socket::SocketErrno', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::Ipv4Route>', 'ns3::Ptr<ns3::Packet const>', 'ns3::Ipv4Header const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::Socket>', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_aodv.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_aodv.py	Thu Feb 25 14:17:21 2010 +0100
@@ -387,6 +387,11 @@
                    'uint32_t', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## aodv-packet.h: static ns3::TypeId ns3::aodv::RerrHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
     ## aodv-packet.h: void ns3::aodv::RerrHeader::Print(std::ostream & os) const [member function]
     cls.add_method('Print', 
                    'void', 
@@ -744,6 +749,11 @@
                    'uint32_t', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## aodv-packet.h: static ns3::TypeId ns3::aodv::RrepAckHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
     ## aodv-packet.h: void ns3::aodv::RrepAckHeader::Print(std::ostream & os) const [member function]
     cls.add_method('Print', 
                    'void', 
@@ -813,6 +823,11 @@
                    'uint32_t', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## aodv-packet.h: static ns3::TypeId ns3::aodv::RrepHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
     ## aodv-packet.h: void ns3::aodv::RrepHeader::Print(std::ostream & os) const [member function]
     cls.add_method('Print', 
                    'void', 
@@ -919,6 +934,11 @@
                    'uint32_t', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## aodv-packet.h: static ns3::TypeId ns3::aodv::RreqHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
     ## aodv-packet.h: bool ns3::aodv::RreqHeader::GetUnknownSeqno() const [member function]
     cls.add_method('GetUnknownSeqno', 
                    'bool', 
@@ -999,6 +1019,11 @@
                    'uint32_t', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## aodv-packet.h: static ns3::TypeId ns3::aodv::TypeHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
     ## aodv-packet.h: bool ns3::aodv::TypeHeader::IsValid() const [member function]
     cls.add_method('IsValid', 
                    'bool', 
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_common.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_common.py	Thu Feb 25 14:17:21 2010 +0100
@@ -47,28 +47,50 @@
     module.add_class('Chunk', parent=root_module['ns3::ObjectBase'])
     ## header.h: ns3::Header [class]
     module.add_class('Header', parent=root_module['ns3::Chunk'])
-    ## pcap-writer.h: ns3::PcapWriter [class]
-    module.add_class('PcapWriter', parent=root_module['ns3::Object'])
-    ## simple-ref-count.h: ns3::SimpleRefCount<ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter<ns3::AsciiWriter> > [class]
-    module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::AsciiWriter', 'ns3::empty', 'ns3::DefaultDeleter<ns3::AsciiWriter>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
+    ## pcap-file-wrapper.h: ns3::PcapFileWrapper [class]
+    module.add_class('PcapFileWrapper', parent=root_module['ns3::Object'])
+    ## propagation-delay-model.h: ns3::PropagationDelayModel [class]
+    module.add_class('PropagationDelayModel', parent=root_module['ns3::Object'])
+    ## propagation-loss-model.h: ns3::PropagationLossModel [class]
+    module.add_class('PropagationLossModel', parent=root_module['ns3::Object'])
+    ## propagation-delay-model.h: ns3::RandomPropagationDelayModel [class]
+    module.add_class('RandomPropagationDelayModel', parent=root_module['ns3::PropagationDelayModel'])
+    ## propagation-loss-model.h: ns3::RandomPropagationLossModel [class]
+    module.add_class('RandomPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
+    ## simple-ref-count.h: ns3::SimpleRefCount<ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter<ns3::OutputStreamWrapper> > [class]
+    module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::OutputStreamWrapper', 'ns3::empty', 'ns3::DefaultDeleter<ns3::OutputStreamWrapper>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
     ## simple-ref-count.h: ns3::SimpleRefCount<ns3::Packet, ns3::empty, ns3::DefaultDeleter<ns3::Packet> > [class]
     module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::Packet', 'ns3::empty', 'ns3::DefaultDeleter<ns3::Packet>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
+    ## propagation-loss-model.h: ns3::ThreeLogDistancePropagationLossModel [class]
+    module.add_class('ThreeLogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## trailer.h: ns3::Trailer [class]
     module.add_class('Trailer', parent=root_module['ns3::Chunk'])
-    ## ascii-writer.h: ns3::AsciiWriter [class]
-    module.add_class('AsciiWriter', parent=root_module['ns3::SimpleRefCount< ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter<ns3::AsciiWriter> >'])
-    ## ascii-writer.h: ns3::AsciiWriter::Type [enumeration]
-    module.add_enum('Type', ['ENQUEUE', 'DEQUEUE', 'DROP', 'TX', 'RX'], outer_class=root_module['ns3::AsciiWriter'])
+    ## propagation-loss-model.h: ns3::TwoRayGroundPropagationLossModel [class]
+    module.add_class('TwoRayGroundPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
+    ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel [class]
+    module.add_class('ConstantSpeedPropagationDelayModel', parent=root_module['ns3::PropagationDelayModel'])
     ## data-rate.h: ns3::DataRateChecker [class]
     module.add_class('DataRateChecker', parent=root_module['ns3::AttributeChecker'])
     ## data-rate.h: ns3::DataRateValue [class]
     module.add_class('DataRateValue', parent=root_module['ns3::AttributeValue'])
     ## error-model.h: ns3::ErrorModel [class]
     module.add_class('ErrorModel', parent=root_module['ns3::Object'])
+    ## propagation-loss-model.h: ns3::FixedRssLossModel [class]
+    module.add_class('FixedRssLossModel', parent=root_module['ns3::PropagationLossModel'])
+    ## propagation-loss-model.h: ns3::FriisPropagationLossModel [class]
+    module.add_class('FriisPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
+    ## jakes-propagation-loss-model.h: ns3::JakesPropagationLossModel [class]
+    module.add_class('JakesPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## error-model.h: ns3::ListErrorModel [class]
     module.add_class('ListErrorModel', parent=root_module['ns3::ErrorModel'])
+    ## propagation-loss-model.h: ns3::LogDistancePropagationLossModel [class]
+    module.add_class('LogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
+    ## propagation-loss-model.h: ns3::NakagamiPropagationLossModel [class]
+    module.add_class('NakagamiPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## nix-vector.h: ns3::NixVector [class]
     module.add_class('NixVector', parent=root_module['ns3::Object'])
+    ## output-stream-wrapper.h: ns3::OutputStreamWrapper [class]
+    module.add_class('OutputStreamWrapper', parent=root_module['ns3::SimpleRefCount< ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter<ns3::OutputStreamWrapper> >'])
     ## packet.h: ns3::Packet [class]
     module.add_class('Packet', parent=root_module['ns3::SimpleRefCount< ns3::Packet, ns3::empty, ns3::DefaultDeleter<ns3::Packet> >'])
     ## error-model.h: ns3::RateErrorModel [class]
@@ -175,14 +197,26 @@
     register_Ns3TagBuffer_methods(root_module, root_module['ns3::TagBuffer'])
     register_Ns3Chunk_methods(root_module, root_module['ns3::Chunk'])
     register_Ns3Header_methods(root_module, root_module['ns3::Header'])
-    register_Ns3PcapWriter_methods(root_module, root_module['ns3::PcapWriter'])
+    register_Ns3PcapFileWrapper_methods(root_module, root_module['ns3::PcapFileWrapper'])
+    register_Ns3PropagationDelayModel_methods(root_module, root_module['ns3::PropagationDelayModel'])
+    register_Ns3PropagationLossModel_methods(root_module, root_module['ns3::PropagationLossModel'])
+    register_Ns3RandomPropagationDelayModel_methods(root_module, root_module['ns3::RandomPropagationDelayModel'])
+    register_Ns3RandomPropagationLossModel_methods(root_module, root_module['ns3::RandomPropagationLossModel'])
+    register_Ns3ThreeLogDistancePropagationLossModel_methods(root_module, root_module['ns3::ThreeLogDistancePropagationLossModel'])
     register_Ns3Trailer_methods(root_module, root_module['ns3::Trailer'])
-    register_Ns3AsciiWriter_methods(root_module, root_module['ns3::AsciiWriter'])
+    register_Ns3TwoRayGroundPropagationLossModel_methods(root_module, root_module['ns3::TwoRayGroundPropagationLossModel'])
+    register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, root_module['ns3::ConstantSpeedPropagationDelayModel'])
     register_Ns3DataRateChecker_methods(root_module, root_module['ns3::DataRateChecker'])
     register_Ns3DataRateValue_methods(root_module, root_module['ns3::DataRateValue'])
     register_Ns3ErrorModel_methods(root_module, root_module['ns3::ErrorModel'])
+    register_Ns3FixedRssLossModel_methods(root_module, root_module['ns3::FixedRssLossModel'])
+    register_Ns3FriisPropagationLossModel_methods(root_module, root_module['ns3::FriisPropagationLossModel'])
+    register_Ns3JakesPropagationLossModel_methods(root_module, root_module['ns3::JakesPropagationLossModel'])
     register_Ns3ListErrorModel_methods(root_module, root_module['ns3::ListErrorModel'])
+    register_Ns3LogDistancePropagationLossModel_methods(root_module, root_module['ns3::LogDistancePropagationLossModel'])
+    register_Ns3NakagamiPropagationLossModel_methods(root_module, root_module['ns3::NakagamiPropagationLossModel'])
     register_Ns3NixVector_methods(root_module, root_module['ns3::NixVector'])
+    register_Ns3OutputStreamWrapper_methods(root_module, root_module['ns3::OutputStreamWrapper'])
     register_Ns3Packet_methods(root_module, root_module['ns3::Packet'])
     register_Ns3RateErrorModel_methods(root_module, root_module['ns3::RateErrorModel'])
     return
@@ -216,6 +250,11 @@
                    'void', 
                    [param('std::ostream *', 'os'), param('uint32_t', 'size')], 
                    is_const=True)
+    ## buffer.h: uint32_t ns3::Buffer::CopyData(uint8_t * buffer, uint32_t size) const [member function]
+    cls.add_method('CopyData', 
+                   'uint32_t', 
+                   [param('uint8_t *', 'buffer'), param('uint32_t', 'size')], 
+                   is_const=True)
     ## buffer.h: ns3::Buffer ns3::Buffer::CreateFragment(uint32_t start, uint32_t length) const [member function]
     cls.add_method('CreateFragment', 
                    'ns3::Buffer', 
@@ -948,56 +987,156 @@
                    is_pure_virtual=True, is_const=True, is_virtual=True)
     return
 
-def register_Ns3PcapWriter_methods(root_module, cls):
-    ## pcap-writer.h: ns3::PcapWriter::PcapWriter(ns3::PcapWriter const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::PcapWriter const &', 'arg0')])
-    ## pcap-writer.h: ns3::PcapWriter::PcapWriter() [constructor]
+def register_Ns3PcapFileWrapper_methods(root_module, cls):
+    ## pcap-file-wrapper.h: ns3::PcapFileWrapper::PcapFileWrapper(ns3::PcapFileWrapper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::PcapFileWrapper const &', 'arg0')])
+    ## pcap-file-wrapper.h: ns3::PcapFileWrapper::PcapFileWrapper() [constructor]
     cls.add_constructor([])
-    ## pcap-writer.h: static ns3::TypeId ns3::PcapWriter::GetTypeId() [member function]
+    ## pcap-file-wrapper.h: void ns3::PcapFileWrapper::Close() [member function]
+    cls.add_method('Close', 
+                   'void', 
+                   [])
+    ## pcap-file-wrapper.h: uint32_t ns3::PcapFileWrapper::GetDataLinkType() [member function]
+    cls.add_method('GetDataLinkType', 
+                   'uint32_t', 
+                   [])
+    ## pcap-file-wrapper.h: uint32_t ns3::PcapFileWrapper::GetMagic() [member function]
+    cls.add_method('GetMagic', 
+                   'uint32_t', 
+                   [])
+    ## pcap-file-wrapper.h: uint32_t ns3::PcapFileWrapper::GetSigFigs() [member function]
+    cls.add_method('GetSigFigs', 
+                   'uint32_t', 
+                   [])
+    ## pcap-file-wrapper.h: uint32_t ns3::PcapFileWrapper::GetSnapLen() [member function]
+    cls.add_method('GetSnapLen', 
+                   'uint32_t', 
+                   [])
+    ## pcap-file-wrapper.h: int32_t ns3::PcapFileWrapper::GetTimeZoneOffset() [member function]
+    cls.add_method('GetTimeZoneOffset', 
+                   'int32_t', 
+                   [])
+    ## pcap-file-wrapper.h: static ns3::TypeId ns3::PcapFileWrapper::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
                    [], 
                    is_static=True)
-    ## pcap-writer.h: void ns3::PcapWriter::Open(std::string const & name) [member function]
+    ## pcap-file-wrapper.h: uint16_t ns3::PcapFileWrapper::GetVersionMajor() [member function]
+    cls.add_method('GetVersionMajor', 
+                   'uint16_t', 
+                   [])
+    ## pcap-file-wrapper.h: uint16_t ns3::PcapFileWrapper::GetVersionMinor() [member function]
+    cls.add_method('GetVersionMinor', 
+                   'uint16_t', 
+                   [])
+    ## pcap-file-wrapper.h: bool ns3::PcapFileWrapper::Init(uint32_t dataLinkType, uint32_t snapLen=std::numeric_limits<unsigned int>::max(), int32_t tzCorrection=ns3::PcapFile::ZONE_DEFAULT) [member function]
+    cls.add_method('Init', 
+                   'bool', 
+                   [param('uint32_t', 'dataLinkType'), param('uint32_t', 'snapLen', default_value='std::numeric_limits<unsigned int>::max()'), param('int32_t', 'tzCorrection', default_value='ns3::PcapFile::ZONE_DEFAULT')])
+    ## pcap-file-wrapper.h: bool ns3::PcapFileWrapper::Open(std::string const & filename, std::string const & mode) [member function]
     cls.add_method('Open', 
-                   'void', 
-                   [param('std::string const &', 'name')])
-    ## pcap-writer.h: void ns3::PcapWriter::SetCaptureSize(uint32_t size) [member function]
-    cls.add_method('SetCaptureSize', 
-                   'void', 
-                   [param('uint32_t', 'size')])
-    ## pcap-writer.h: void ns3::PcapWriter::WriteEthernetHeader() [member function]
-    cls.add_method('WriteEthernetHeader', 
-                   'void', 
-                   [])
-    ## pcap-writer.h: void ns3::PcapWriter::WriteIpHeader() [member function]
-    cls.add_method('WriteIpHeader', 
-                   'void', 
-                   [])
-    ## pcap-writer.h: void ns3::PcapWriter::WritePacket(ns3::Ptr<ns3::Packet const> packet) [member function]
-    cls.add_method('WritePacket', 
+                   'bool', 
+                   [param('std::string const &', 'filename'), param('std::string const &', 'mode')])
+    ## pcap-file-wrapper.h: bool ns3::PcapFileWrapper::Write(ns3::Time t, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('Write', 
+                   'bool', 
+                   [param('ns3::Time', 't'), param('ns3::Ptr< ns3::Packet const >', 'p')])
+    ## pcap-file-wrapper.h: bool ns3::PcapFileWrapper::Write(ns3::Time t, ns3::Header & header, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('Write', 
+                   'bool', 
+                   [param('ns3::Time', 't'), param('ns3::Header &', 'header'), param('ns3::Ptr< ns3::Packet const >', 'p')])
+    ## pcap-file-wrapper.h: bool ns3::PcapFileWrapper::Write(ns3::Time t, uint8_t const * buffer, uint32_t length) [member function]
+    cls.add_method('Write', 
+                   'bool', 
+                   [param('ns3::Time', 't'), param('uint8_t const *', 'buffer'), param('uint32_t', 'length')])
+    return
+
+def register_Ns3PropagationDelayModel_methods(root_module, cls):
+    ## propagation-delay-model.h: ns3::PropagationDelayModel::PropagationDelayModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-delay-model.h: ns3::PropagationDelayModel::PropagationDelayModel(ns3::PropagationDelayModel const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::PropagationDelayModel const &', 'arg0')])
+    ## propagation-delay-model.h: ns3::Time ns3::PropagationDelayModel::GetDelay(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('GetDelay', 
+                   'ns3::Time', 
+                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## propagation-delay-model.h: static ns3::TypeId ns3::PropagationDelayModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    return
+
+def register_Ns3PropagationLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::PropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-loss-model.h: ns3::PropagationLossModel::PropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: void ns3::PropagationLossModel::SetNext(ns3::Ptr<ns3::PropagationLossModel> next) [member function]
+    cls.add_method('SetNext', 
                    'void', 
-                   [param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## pcap-writer.h: void ns3::PcapWriter::WritePppHeader() [member function]
-    cls.add_method('WritePppHeader', 
-                   'void', 
-                   [])
-    ## pcap-writer.h: void ns3::PcapWriter::WriteWifiHeader() [member function]
-    cls.add_method('WriteWifiHeader', 
-                   'void', 
-                   [])
-    ## pcap-writer.h: void ns3::PcapWriter::WriteWifiMonitorPacket(ns3::Ptr<ns3::Packet const> packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble, bool isTx, double signalDbm, double noiseDbm) [member function]
-    cls.add_method('WriteWifiMonitorPacket', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'channelFreqMhz'), param('uint16_t', 'channelNumber'), param('uint32_t', 'rate'), param('bool', 'isShortPreamble'), param('bool', 'isTx'), param('double', 'signalDbm'), param('double', 'noiseDbm')])
-    ## pcap-writer.h: void ns3::PcapWriter::WriteWifiPrismHeader() [member function]
-    cls.add_method('WriteWifiPrismHeader', 
-                   'void', 
-                   [])
-    ## pcap-writer.h: void ns3::PcapWriter::WriteWifiRadiotapHeader() [member function]
-    cls.add_method('WriteWifiRadiotapHeader', 
-                   'void', 
-                   [])
+                   [param('ns3::Ptr< ns3::PropagationLossModel >', 'next')])
+    ## propagation-loss-model.h: double ns3::PropagationLossModel::CalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('CalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True)
+    ## propagation-loss-model.h: double ns3::PropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3RandomPropagationDelayModel_methods(root_module, cls):
+    ## propagation-delay-model.h: ns3::RandomPropagationDelayModel::RandomPropagationDelayModel(ns3::RandomPropagationDelayModel const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::RandomPropagationDelayModel const &', 'arg0')])
+    ## propagation-delay-model.h: ns3::RandomPropagationDelayModel::RandomPropagationDelayModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-delay-model.h: ns3::Time ns3::RandomPropagationDelayModel::GetDelay(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('GetDelay', 
+                   'ns3::Time', 
+                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, is_virtual=True)
+    ## propagation-delay-model.h: static ns3::TypeId ns3::RandomPropagationDelayModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    return
+
+def register_Ns3RandomPropagationLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::RandomPropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-loss-model.h: ns3::RandomPropagationLossModel::RandomPropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: double ns3::RandomPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3ThreeLogDistancePropagationLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::ThreeLogDistancePropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-loss-model.h: ns3::ThreeLogDistancePropagationLossModel::ThreeLogDistancePropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: double ns3::ThreeLogDistancePropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
     return
 
 def register_Ns3Trailer_methods(root_module, cls):
@@ -1033,18 +1172,80 @@
                    is_pure_virtual=True, is_const=True, is_virtual=True)
     return
 
-def register_Ns3AsciiWriter_methods(root_module, cls):
-    ## ascii-writer.h: ns3::AsciiWriter::AsciiWriter(ns3::AsciiWriter const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::AsciiWriter const &', 'arg0')])
-    ## ascii-writer.h: static ns3::Ptr<ns3::AsciiWriter> ns3::AsciiWriter::Get(std::ostream & os) [member function]
-    cls.add_method('Get', 
-                   'ns3::Ptr< ns3::AsciiWriter >', 
-                   [param('std::ostream &', 'os')], 
+def register_Ns3TwoRayGroundPropagationLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::TwoRayGroundPropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
                    is_static=True)
-    ## ascii-writer.h: void ns3::AsciiWriter::WritePacket(ns3::AsciiWriter::Type type, std::string message, ns3::Ptr<ns3::Packet const> p) [member function]
-    cls.add_method('WritePacket', 
+    ## propagation-loss-model.h: ns3::TwoRayGroundPropagationLossModel::TwoRayGroundPropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: void ns3::TwoRayGroundPropagationLossModel::SetLambda(double frequency, double speed) [member function]
+    cls.add_method('SetLambda', 
+                   'void', 
+                   [param('double', 'frequency'), param('double', 'speed')])
+    ## propagation-loss-model.h: void ns3::TwoRayGroundPropagationLossModel::SetLambda(double lambda) [member function]
+    cls.add_method('SetLambda', 
+                   'void', 
+                   [param('double', 'lambda')])
+    ## propagation-loss-model.h: void ns3::TwoRayGroundPropagationLossModel::SetSystemLoss(double systemLoss) [member function]
+    cls.add_method('SetSystemLoss', 
+                   'void', 
+                   [param('double', 'systemLoss')])
+    ## propagation-loss-model.h: void ns3::TwoRayGroundPropagationLossModel::SetMinDistance(double minDistance) [member function]
+    cls.add_method('SetMinDistance', 
                    'void', 
-                   [param('ns3::AsciiWriter::Type', 'type'), param('std::string', 'message'), param('ns3::Ptr< ns3::Packet const >', 'p')])
+                   [param('double', 'minDistance')])
+    ## propagation-loss-model.h: double ns3::TwoRayGroundPropagationLossModel::GetMinDistance() const [member function]
+    cls.add_method('GetMinDistance', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-loss-model.h: double ns3::TwoRayGroundPropagationLossModel::GetLambda() const [member function]
+    cls.add_method('GetLambda', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-loss-model.h: double ns3::TwoRayGroundPropagationLossModel::GetSystemLoss() const [member function]
+    cls.add_method('GetSystemLoss', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-loss-model.h: void ns3::TwoRayGroundPropagationLossModel::SetHeightAboveZ(double heightAboveZ) [member function]
+    cls.add_method('SetHeightAboveZ', 
+                   'void', 
+                   [param('double', 'heightAboveZ')])
+    ## propagation-loss-model.h: double ns3::TwoRayGroundPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, cls):
+    ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel::ConstantSpeedPropagationDelayModel(ns3::ConstantSpeedPropagationDelayModel const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::ConstantSpeedPropagationDelayModel const &', 'arg0')])
+    ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel::ConstantSpeedPropagationDelayModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-delay-model.h: ns3::Time ns3::ConstantSpeedPropagationDelayModel::GetDelay(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('GetDelay', 
+                   'ns3::Time', 
+                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, is_virtual=True)
+    ## propagation-delay-model.h: double ns3::ConstantSpeedPropagationDelayModel::GetSpeed() const [member function]
+    cls.add_method('GetSpeed', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-delay-model.h: static ns3::TypeId ns3::ConstantSpeedPropagationDelayModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-delay-model.h: void ns3::ConstantSpeedPropagationDelayModel::SetSpeed(double speed) [member function]
+    cls.add_method('SetSpeed', 
+                   'void', 
+                   [param('double', 'speed')])
     return
 
 def register_Ns3DataRateChecker_methods(root_module, cls):
@@ -1130,6 +1331,104 @@
                    is_pure_virtual=True, visibility='private', is_virtual=True)
     return
 
+def register_Ns3FixedRssLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::FixedRssLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-loss-model.h: ns3::FixedRssLossModel::FixedRssLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: void ns3::FixedRssLossModel::SetRss(double rss) [member function]
+    cls.add_method('SetRss', 
+                   'void', 
+                   [param('double', 'rss')])
+    ## propagation-loss-model.h: double ns3::FixedRssLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3FriisPropagationLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::FriisPropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-loss-model.h: ns3::FriisPropagationLossModel::FriisPropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetLambda(double frequency, double speed) [member function]
+    cls.add_method('SetLambda', 
+                   'void', 
+                   [param('double', 'frequency'), param('double', 'speed')])
+    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetLambda(double lambda) [member function]
+    cls.add_method('SetLambda', 
+                   'void', 
+                   [param('double', 'lambda')])
+    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetSystemLoss(double systemLoss) [member function]
+    cls.add_method('SetSystemLoss', 
+                   'void', 
+                   [param('double', 'systemLoss')])
+    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetMinDistance(double minDistance) [member function]
+    cls.add_method('SetMinDistance', 
+                   'void', 
+                   [param('double', 'minDistance')])
+    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetMinDistance() const [member function]
+    cls.add_method('GetMinDistance', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetLambda() const [member function]
+    cls.add_method('GetLambda', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetSystemLoss() const [member function]
+    cls.add_method('GetSystemLoss', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3JakesPropagationLossModel_methods(root_module, cls):
+    ## jakes-propagation-loss-model.h: ns3::JakesPropagationLossModel::JakesPropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## jakes-propagation-loss-model.h: uint8_t ns3::JakesPropagationLossModel::GetNOscillators() const [member function]
+    cls.add_method('GetNOscillators', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## jakes-propagation-loss-model.h: uint8_t ns3::JakesPropagationLossModel::GetNRays() const [member function]
+    cls.add_method('GetNRays', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## jakes-propagation-loss-model.h: static ns3::TypeId ns3::JakesPropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## jakes-propagation-loss-model.h: void ns3::JakesPropagationLossModel::SetNOscillators(uint8_t nOscillators) [member function]
+    cls.add_method('SetNOscillators', 
+                   'void', 
+                   [param('uint8_t', 'nOscillators')])
+    ## jakes-propagation-loss-model.h: void ns3::JakesPropagationLossModel::SetNRays(uint8_t nRays) [member function]
+    cls.add_method('SetNRays', 
+                   'void', 
+                   [param('uint8_t', 'nRays')])
+    ## jakes-propagation-loss-model.h: double ns3::JakesPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
 def register_Ns3ListErrorModel_methods(root_module, cls):
     ## error-model.h: ns3::ListErrorModel::ListErrorModel(ns3::ListErrorModel const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::ListErrorModel const &', 'arg0')])
@@ -1161,6 +1460,49 @@
                    visibility='private', is_virtual=True)
     return
 
+def register_Ns3LogDistancePropagationLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::LogDistancePropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-loss-model.h: ns3::LogDistancePropagationLossModel::LogDistancePropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetPathLossExponent(double n) [member function]
+    cls.add_method('SetPathLossExponent', 
+                   'void', 
+                   [param('double', 'n')])
+    ## propagation-loss-model.h: double ns3::LogDistancePropagationLossModel::GetPathLossExponent() const [member function]
+    cls.add_method('GetPathLossExponent', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetReference(double referenceDistance, double referenceLoss) [member function]
+    cls.add_method('SetReference', 
+                   'void', 
+                   [param('double', 'referenceDistance'), param('double', 'referenceLoss')])
+    ## propagation-loss-model.h: double ns3::LogDistancePropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3NakagamiPropagationLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::NakagamiPropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-loss-model.h: ns3::NakagamiPropagationLossModel::NakagamiPropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: double ns3::NakagamiPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
 def register_Ns3NixVector_methods(root_module, cls):
     cls.add_output_stream_operator()
     ## nix-vector.h: ns3::NixVector::NixVector() [constructor]
@@ -1215,6 +1557,21 @@
                    is_const=True)
     return
 
+def register_Ns3OutputStreamWrapper_methods(root_module, cls):
+    ## output-stream-wrapper.h: ns3::OutputStreamWrapper::OutputStreamWrapper(ns3::OutputStreamWrapper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::OutputStreamWrapper const &', 'arg0')])
+    ## output-stream-wrapper.h: ns3::OutputStreamWrapper::OutputStreamWrapper() [constructor]
+    cls.add_constructor([])
+    ## output-stream-wrapper.h: std::ostream * ns3::OutputStreamWrapper::GetStream() [member function]
+    cls.add_method('GetStream', 
+                   'std::ostream *', 
+                   [])
+    ## output-stream-wrapper.h: void ns3::OutputStreamWrapper::SetStream(std::ostream * ostream) [member function]
+    cls.add_method('SetStream', 
+                   'void', 
+                   [param('std::ostream *', 'ostream')])
+    return
+
 def register_Ns3Packet_methods(root_module, cls):
     cls.add_output_stream_operator()
     ## packet.h: ns3::Packet::Packet() [constructor]
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_core.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_core.py	Thu Feb 25 14:17:21 2010 +0100
@@ -93,6 +93,8 @@
     module.add_class('Vector3D')
     ## random-variable.h: ns3::WeibullVariable [class]
     module.add_class('WeibullVariable', parent=root_module['ns3::RandomVariable'])
+    ## random-variable.h: ns3::ZetaVariable [class]
+    module.add_class('ZetaVariable', parent=root_module['ns3::RandomVariable'])
     ## random-variable.h: ns3::ZipfVariable [class]
     module.add_class('ZipfVariable', parent=root_module['ns3::RandomVariable'])
     ## empty.h: ns3::empty [class]
@@ -351,6 +353,7 @@
     register_Ns3Vector2D_methods(root_module, root_module['ns3::Vector2D'])
     register_Ns3Vector3D_methods(root_module, root_module['ns3::Vector3D'])
     register_Ns3WeibullVariable_methods(root_module, root_module['ns3::WeibullVariable'])
+    register_Ns3ZetaVariable_methods(root_module, root_module['ns3::ZetaVariable'])
     register_Ns3ZipfVariable_methods(root_module, root_module['ns3::ZipfVariable'])
     register_Ns3Empty_methods(root_module, root_module['ns3::empty'])
     register_Ns3ConstantVariable_methods(root_module, root_module['ns3::ConstantVariable'])
@@ -365,7 +368,6 @@
     register_Ns3Object_methods(root_module, root_module['ns3::Object'])
     register_Ns3ObjectAggregateIterator_methods(root_module, root_module['ns3::Object::AggregateIterator'])
     register_Ns3ParetoVariable_methods(root_module, root_module['ns3::ParetoVariable'])
-    register_Ns3SimpleRefCount__Ns3AsciiWriter_Ns3Empty_Ns3DefaultDeleter__lt__ns3AsciiWriter__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter<ns3::AsciiWriter> >'])
     register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >'])
     register_Ns3SimpleRefCount__Ns3AttributeChecker_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeChecker__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
     register_Ns3SimpleRefCount__Ns3AttributeValue_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeValue__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
@@ -379,6 +381,7 @@
     register_Ns3SimpleRefCount__Ns3Ipv6MulticastRoute_Ns3Empty_Ns3DefaultDeleter__lt__ns3Ipv6MulticastRoute__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::Ipv6MulticastRoute, ns3::empty, ns3::DefaultDeleter<ns3::Ipv6MulticastRoute> >'])
     register_Ns3SimpleRefCount__Ns3Ipv6Route_Ns3Empty_Ns3DefaultDeleter__lt__ns3Ipv6Route__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::Ipv6Route, ns3::empty, ns3::DefaultDeleter<ns3::Ipv6Route> >'])
     register_Ns3SimpleRefCount__Ns3MeshWifiInterfaceMacPlugin_Ns3Empty_Ns3DefaultDeleter__lt__ns3MeshWifiInterfaceMacPlugin__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::MeshWifiInterfaceMacPlugin, ns3::empty, ns3::DefaultDeleter<ns3::MeshWifiInterfaceMacPlugin> >'])
+    register_Ns3SimpleRefCount__Ns3OutputStreamWrapper_Ns3Empty_Ns3DefaultDeleter__lt__ns3OutputStreamWrapper__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter<ns3::OutputStreamWrapper> >'])
     register_Ns3SimpleRefCount__Ns3Packet_Ns3Empty_Ns3DefaultDeleter__lt__ns3Packet__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::Packet, ns3::empty, ns3::DefaultDeleter<ns3::Packet> >'])
     register_Ns3SimpleRefCount__Ns3PbbAddressBlock_Ns3Empty_Ns3DefaultDeleter__lt__ns3PbbAddressBlock__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::PbbAddressBlock, ns3::empty, ns3::DefaultDeleter<ns3::PbbAddressBlock> >'])
     register_Ns3SimpleRefCount__Ns3PbbMessage_Ns3Empty_Ns3DefaultDeleter__lt__ns3PbbMessage__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::PbbMessage, ns3::empty, ns3::DefaultDeleter<ns3::PbbMessage> >'])
@@ -1575,11 +1578,20 @@
     cls.add_constructor([param('double', 'm'), param('double', 's'), param('double', 'b')])
     return
 
+def register_Ns3ZetaVariable_methods(root_module, cls):
+    ## random-variable.h: ns3::ZetaVariable::ZetaVariable(ns3::ZetaVariable const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::ZetaVariable const &', 'arg0')])
+    ## random-variable.h: ns3::ZetaVariable::ZetaVariable(double alpha) [constructor]
+    cls.add_constructor([param('double', 'alpha')])
+    ## random-variable.h: ns3::ZetaVariable::ZetaVariable() [constructor]
+    cls.add_constructor([])
+    return
+
 def register_Ns3ZipfVariable_methods(root_module, cls):
     ## random-variable.h: ns3::ZipfVariable::ZipfVariable(ns3::ZipfVariable const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::ZipfVariable const &', 'arg0')])
-    ## random-variable.h: ns3::ZipfVariable::ZipfVariable(long int n, double alpha) [constructor]
-    cls.add_constructor([param('long int', 'n'), param('double', 'alpha')])
+    ## random-variable.h: ns3::ZipfVariable::ZipfVariable(long int N, double alpha) [constructor]
+    cls.add_constructor([param('long int', 'N'), param('double', 'alpha')])
     ## random-variable.h: ns3::ZipfVariable::ZipfVariable() [constructor]
     cls.add_constructor([])
     return
@@ -1780,18 +1792,6 @@
     cls.add_constructor([param('double', 'm'), param('double', 's'), param('double', 'b')])
     return
 
-def register_Ns3SimpleRefCount__Ns3AsciiWriter_Ns3Empty_Ns3DefaultDeleter__lt__ns3AsciiWriter__gt___methods(root_module, cls):
-    ## simple-ref-count.h: ns3::SimpleRefCount<ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter<ns3::AsciiWriter> >::SimpleRefCount() [constructor]
-    cls.add_constructor([])
-    ## simple-ref-count.h: ns3::SimpleRefCount<ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter<ns3::AsciiWriter> >::SimpleRefCount(ns3::SimpleRefCount<ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter<ns3::AsciiWriter> > const & o) [copy constructor]
-    cls.add_constructor([param('ns3::SimpleRefCount< ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter< ns3::AsciiWriter > > const &', 'o')])
-    ## simple-ref-count.h: static void ns3::SimpleRefCount<ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter<ns3::AsciiWriter> >::Cleanup() [member function]
-    cls.add_method('Cleanup', 
-                   'void', 
-                   [], 
-                   is_static=True)
-    return
-
 def register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, cls):
     ## simple-ref-count.h: ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >::SimpleRefCount() [constructor]
     cls.add_constructor([])
@@ -1948,6 +1948,18 @@
                    is_static=True)
     return
 
+def register_Ns3SimpleRefCount__Ns3OutputStreamWrapper_Ns3Empty_Ns3DefaultDeleter__lt__ns3OutputStreamWrapper__gt___methods(root_module, cls):
+    ## simple-ref-count.h: ns3::SimpleRefCount<ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter<ns3::OutputStreamWrapper> >::SimpleRefCount() [constructor]
+    cls.add_constructor([])
+    ## simple-ref-count.h: ns3::SimpleRefCount<ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter<ns3::OutputStreamWrapper> >::SimpleRefCount(ns3::SimpleRefCount<ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter<ns3::OutputStreamWrapper> > const & o) [copy constructor]
+    cls.add_constructor([param('ns3::SimpleRefCount< ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter< ns3::OutputStreamWrapper > > const &', 'o')])
+    ## simple-ref-count.h: static void ns3::SimpleRefCount<ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter<ns3::OutputStreamWrapper> >::Cleanup() [member function]
+    cls.add_method('Cleanup', 
+                   'void', 
+                   [], 
+                   is_static=True)
+    return
+
 def register_Ns3SimpleRefCount__Ns3Packet_Ns3Empty_Ns3DefaultDeleter__lt__ns3Packet__gt___methods(root_module, cls):
     ## simple-ref-count.h: ns3::SimpleRefCount<ns3::Packet, ns3::empty, ns3::DefaultDeleter<ns3::Packet> >::SimpleRefCount() [constructor]
     cls.add_constructor([])
@@ -3043,6 +3055,21 @@
     module.add_function('MakeBooleanChecker', 
                         'ns3::Ptr< ns3::AttributeChecker const >', 
                         [])
+    ## callback.h: extern ns3::Callback<void,ns3::Ptr<const ns3::Packet>,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> ns3::MakeBoundCallback(void (*)( ::ns3::Ptr<ns3::OutputStreamWrapper>,::ns3::Ptr<ns3::Packet const> ) * fnPtr, ns3::Ptr<ns3::OutputStreamWrapper> a) [free function]
+    module.add_function('MakeBoundCallback', 
+                        'ns3::Callback< void, ns3::Ptr< ns3::Packet const >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 
+                        [param('void ( * ) ( ns3::Ptr< ns3::OutputStreamWrapper >, ns3::Ptr< ns3::Packet const > ) *', 'fnPtr'), param('ns3::Ptr< ns3::OutputStreamWrapper >', 'a')], 
+                        template_parameters=['void', 'ns3::Ptr<ns3::OutputStreamWrapper>', 'ns3::Ptr<ns3::OutputStreamWrapper>', 'ns3::Ptr<ns3::Packet const>'])
+    ## callback.h: extern ns3::Callback<void,ns3::Ptr<const ns3::Packet>,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> ns3::MakeBoundCallback(void (*)( ::ns3::Ptr<ns3::PcapFileWrapper>,::ns3::Ptr<ns3::Packet const> ) * fnPtr, ns3::Ptr<ns3::PcapFileWrapper> a) [free function]
+    module.add_function('MakeBoundCallback', 
+                        'ns3::Callback< void, ns3::Ptr< ns3::Packet const >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 
+                        [param('void ( * ) ( ns3::Ptr< ns3::PcapFileWrapper >, ns3::Ptr< ns3::Packet const > ) *', 'fnPtr'), param('ns3::Ptr< ns3::PcapFileWrapper >', 'a')], 
+                        template_parameters=['void', 'ns3::Ptr<ns3::PcapFileWrapper>', 'ns3::Ptr<ns3::PcapFileWrapper>', 'ns3::Ptr<ns3::Packet const>'])
+    ## callback.h: extern ns3::Callback<void,std::basic_string<char, std::char_traits<char>, std::allocator<char> >,ns3::Ptr<const ns3::Packet>,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> ns3::MakeBoundCallback(void (*)( ::ns3::Ptr<ns3::OutputStreamWrapper>,::std::basic_string<char,std::char_traits<char>,std::allocator<char> >,::ns3::Ptr<ns3::Packet const> ) * fnPtr, ns3::Ptr<ns3::OutputStreamWrapper> a) [free function]
+    module.add_function('MakeBoundCallback', 
+                        'ns3::Callback< void, std::basic_string< char, std::char_traits< char >, std::allocator< char > >, ns3::Ptr< ns3::Packet const >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 
+                        [param('void ( * ) ( ns3::Ptr< ns3::OutputStreamWrapper >, std::string, ns3::Ptr< ns3::Packet const > ) *', 'fnPtr'), param('ns3::Ptr< ns3::OutputStreamWrapper >', 'a')], 
+                        template_parameters=['void', 'ns3::Ptr<ns3::OutputStreamWrapper>', 'ns3::Ptr<ns3::OutputStreamWrapper>', 'std::string', 'ns3::Ptr<ns3::Packet const>'])
     ## callback.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeCallbackChecker() [free function]
     module.add_function('MakeCallbackChecker', 
                         'ns3::Ptr< ns3::AttributeChecker const >', 
@@ -3097,7 +3124,7 @@
     module.add_function('TypeNameGet', 
                         'std::string', 
                         [], 
-                        template_parameters=['long long'])
+                        template_parameters=['long'])
     ## type-name.h: extern std::string ns3::TypeNameGet() [free function]
     module.add_function('TypeNameGet', 
                         'std::string', 
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_csma.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_csma.py	Thu Feb 25 14:17:21 2010 +0100
@@ -266,6 +266,11 @@
     cls.add_method('SetQueue', 
                    'void', 
                    [param('ns3::Ptr< ns3::Queue >', 'queue')])
+    ## csma-net-device.h: ns3::Ptr<ns3::Queue> ns3::CsmaNetDevice::GetQueue() const [member function]
+    cls.add_method('GetQueue', 
+                   'ns3::Ptr< ns3::Queue >', 
+                   [], 
+                   is_const=True)
     ## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveErrorModel(ns3::Ptr<ns3::ErrorModel> em) [member function]
     cls.add_method('SetReceiveErrorModel', 
                    'void', 
@@ -432,11 +437,6 @@
                    'void', 
                    [], 
                    visibility='protected', is_virtual=True)
-    ## csma-net-device.h: ns3::Ptr<ns3::Queue> ns3::CsmaNetDevice::GetQueue() const [member function]
-    cls.add_method('GetQueue', 
-                   'ns3::Ptr< ns3::Queue >', 
-                   [], 
-                   is_const=True, visibility='protected')
     ## csma-net-device.h: void ns3::CsmaNetDevice::AddHeader(ns3::Ptr<ns3::Packet> p, ns3::Mac48Address source, ns3::Mac48Address dest, uint16_t protocolNumber) [member function]
     cls.add_method('AddHeader', 
                    'void', 
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_emu.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_emu.py	Thu Feb 25 14:17:21 2010 +0100
@@ -147,6 +147,11 @@
                    'ns3::Ptr< ns3::Node >', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## emu-net-device.h: ns3::Ptr<ns3::Queue> ns3::EmuNetDevice::GetQueue() const [member function]
+    cls.add_method('GetQueue', 
+                   'ns3::Ptr< ns3::Queue >', 
+                   [], 
+                   is_const=True)
     ## emu-net-device.h: static ns3::TypeId ns3::EmuNetDevice::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_global_routing.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_global_routing.py	Thu Feb 25 14:17:21 2010 +0100
@@ -331,7 +331,7 @@
                    [])
     ## global-router-interface.h: ns3::Ipv4RoutingTableEntry * ns3::GlobalRouter::GetInjectedRoute(uint32_t i) [member function]
     cls.add_method('GetInjectedRoute', 
-                   'ns3::Ipv4RoutingTableEntry *', 
+                   retval('ns3::Ipv4RoutingTableEntry *', caller_owns_return=False), 
                    [param('uint32_t', 'i')])
     ## global-router-interface.h: void ns3::GlobalRouter::RemoveInjectedRoute(uint32_t i) [member function]
     cls.add_method('RemoveInjectedRoute', 
@@ -379,7 +379,7 @@
                    [])
     ## ipv4-global-routing.h: ns3::Ipv4RoutingTableEntry * ns3::Ipv4GlobalRouting::GetRoute(uint32_t i) [member function]
     cls.add_method('GetRoute', 
-                   'ns3::Ipv4RoutingTableEntry *', 
+                   retval('ns3::Ipv4RoutingTableEntry *', caller_owns_return=False), 
                    [param('uint32_t', 'i')])
     ## ipv4-global-routing.h: static ns3::TypeId ns3::Ipv4GlobalRouting::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_helper.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_helper.py	Thu Feb 25 14:17:21 2010 +0100
@@ -7,106 +7,124 @@
     module.add_class('AnimationInterface')
     ## application-container.h: ns3::ApplicationContainer [class]
     module.add_class('ApplicationContainer')
+    ## trace-helper.h: ns3::AsciiTraceHelper [class]
+    module.add_class('AsciiTraceHelper')
+    ## trace-helper.h: ns3::AsciiTraceHelperForDevice [class]
+    module.add_class('AsciiTraceHelperForDevice', allow_subclassing=True)
+    ## trace-helper.h: ns3::AsciiTraceHelperForIpv4 [class]
+    module.add_class('AsciiTraceHelperForIpv4', allow_subclassing=True)
+    ## trace-helper.h: ns3::AsciiTraceHelperForIpv6 [class]
+    module.add_class('AsciiTraceHelperForIpv6', allow_subclassing=True)
     ## athstats-helper.h: ns3::AthstatsHelper [class]
-    module.add_class('AthstatsHelper', allow_subclassing=False)
+    module.add_class('AthstatsHelper')
     ## bridge-helper.h: ns3::BridgeHelper [class]
-    module.add_class('BridgeHelper', allow_subclassing=False)
-    ## csma-helper.h: ns3::CsmaHelper [class]
-    module.add_class('CsmaHelper', allow_subclassing=False)
+    module.add_class('BridgeHelper')
     ## csma-star-helper.h: ns3::CsmaStarHelper [class]
-    module.add_class('CsmaStarHelper', allow_subclassing=False)
-    ## emu-helper.h: ns3::EmuHelper [class]
-    module.add_class('EmuHelper', allow_subclassing=False)
+    module.add_class('CsmaStarHelper')
     ## flow-monitor-helper.h: ns3::FlowMonitorHelper [class]
-    module.add_class('FlowMonitorHelper', allow_subclassing=False)
-    ## internet-stack-helper.h: ns3::InternetStackHelper [class]
-    module.add_class('InternetStackHelper', allow_subclassing=False)
+    module.add_class('FlowMonitorHelper')
     ## ipv4-address-helper.h: ns3::Ipv4AddressHelper [class]
-    module.add_class('Ipv4AddressHelper', allow_subclassing=False)
+    module.add_class('Ipv4AddressHelper')
     ## ipv4-interface-container.h: ns3::Ipv4InterfaceContainer [class]
     module.add_class('Ipv4InterfaceContainer')
     ## ipv4-routing-helper.h: ns3::Ipv4RoutingHelper [class]
-    module.add_class('Ipv4RoutingHelper', allow_subclassing=False)
+    module.add_class('Ipv4RoutingHelper', allow_subclassing=True)
     ## ipv4-static-routing-helper.h: ns3::Ipv4StaticRoutingHelper [class]
-    module.add_class('Ipv4StaticRoutingHelper', allow_subclassing=False, parent=root_module['ns3::Ipv4RoutingHelper'])
+    module.add_class('Ipv4StaticRoutingHelper', parent=root_module['ns3::Ipv4RoutingHelper'])
     ## ipv6-address-helper.h: ns3::Ipv6AddressHelper [class]
-    module.add_class('Ipv6AddressHelper', allow_subclassing=False)
+    module.add_class('Ipv6AddressHelper')
     ## ipv6-interface-container.h: ns3::Ipv6InterfaceContainer [class]
     module.add_class('Ipv6InterfaceContainer')
     ## ipv6-routing-helper.h: ns3::Ipv6RoutingHelper [class]
-    module.add_class('Ipv6RoutingHelper', allow_subclassing=False)
+    module.add_class('Ipv6RoutingHelper', allow_subclassing=True)
     ## ipv6-static-routing-helper.h: ns3::Ipv6StaticRoutingHelper [class]
-    module.add_class('Ipv6StaticRoutingHelper', allow_subclassing=False, parent=root_module['ns3::Ipv6RoutingHelper'])
+    module.add_class('Ipv6StaticRoutingHelper', parent=root_module['ns3::Ipv6RoutingHelper'])
     ## mesh-helper.h: ns3::MeshHelper [class]
-    module.add_class('MeshHelper', allow_subclassing=False)
+    module.add_class('MeshHelper')
     ## mesh-helper.h: ns3::MeshHelper::ChannelPolicy [enumeration]
     module.add_enum('ChannelPolicy', ['SPREAD_CHANNELS', 'ZERO_CHANNEL'], outer_class=root_module['ns3::MeshHelper'])
     ## mobility-helper.h: ns3::MobilityHelper [class]
-    module.add_class('MobilityHelper', allow_subclassing=False)
+    module.add_class('MobilityHelper')
     ## net-device-container.h: ns3::NetDeviceContainer [class]
     module.add_class('NetDeviceContainer')
     ## node-container.h: ns3::NodeContainer [class]
     module.add_class('NodeContainer')
     ## ns2-mobility-helper.h: ns3::Ns2MobilityHelper [class]
-    module.add_class('Ns2MobilityHelper', allow_subclassing=False)
+    module.add_class('Ns2MobilityHelper')
     ## olsr-helper.h: ns3::OlsrHelper [class]
-    module.add_class('OlsrHelper', allow_subclassing=False, parent=root_module['ns3::Ipv4RoutingHelper'])
+    module.add_class('OlsrHelper', parent=root_module['ns3::Ipv4RoutingHelper'])
     ## on-off-helper.h: ns3::OnOffHelper [class]
-    module.add_class('OnOffHelper', allow_subclassing=False)
+    module.add_class('OnOffHelper')
     ## packet-sink-helper.h: ns3::PacketSinkHelper [class]
-    module.add_class('PacketSinkHelper', allow_subclassing=False)
+    module.add_class('PacketSinkHelper')
     ## packet-socket-helper.h: ns3::PacketSocketHelper [class]
-    module.add_class('PacketSocketHelper', allow_subclassing=False)
+    module.add_class('PacketSocketHelper')
+    ## trace-helper.h: ns3::PcapHelper [class]
+    module.add_class('PcapHelper')
+    ## trace-helper.h: ns3::PcapHelper [enumeration]
+    module.add_enum('', ['DLT_NULL', 'DLT_EN10MB', 'DLT_PPP', 'DLT_RAW', 'DLT_IEEE802_11', 'DLT_PRISM_HEADER', 'DLT_IEEE802_11_RADIO'], outer_class=root_module['ns3::PcapHelper'])
+    ## trace-helper.h: ns3::PcapHelperForDevice [class]
+    module.add_class('PcapHelperForDevice', allow_subclassing=True)
+    ## trace-helper.h: ns3::PcapHelperForIpv4 [class]
+    module.add_class('PcapHelperForIpv4', allow_subclassing=True)
+    ## trace-helper.h: ns3::PcapHelperForIpv6 [class]
+    module.add_class('PcapHelperForIpv6', allow_subclassing=True)
     ## ping6-helper.h: ns3::Ping6Helper [class]
-    module.add_class('Ping6Helper', allow_subclassing=False)
+    module.add_class('Ping6Helper')
     ## point-to-point-dumbbell-helper.h: ns3::PointToPointDumbbellHelper [class]
-    module.add_class('PointToPointDumbbellHelper', allow_subclassing=False)
+    module.add_class('PointToPointDumbbellHelper')
     ## point-to-point-grid-helper.h: ns3::PointToPointGridHelper [class]
-    module.add_class('PointToPointGridHelper', allow_subclassing=False)
+    module.add_class('PointToPointGridHelper')
     ## point-to-point-helper.h: ns3::PointToPointHelper [class]
-    module.add_class('PointToPointHelper', allow_subclassing=False)
+    module.add_class('PointToPointHelper', parent=[root_module['ns3::PcapHelperForDevice'], root_module['ns3::AsciiTraceHelperForDevice']])
     ## point-to-point-star-helper.h: ns3::PointToPointStarHelper [class]
-    module.add_class('PointToPointStarHelper', allow_subclassing=False)
+    module.add_class('PointToPointStarHelper')
     ## tap-bridge-helper.h: ns3::TapBridgeHelper [class]
-    module.add_class('TapBridgeHelper', allow_subclassing=False)
+    module.add_class('TapBridgeHelper')
     ## udp-client-server-helper.h: ns3::UdpClientHelper [class]
-    module.add_class('UdpClientHelper', allow_subclassing=False)
+    module.add_class('UdpClientHelper')
     ## udp-echo-helper.h: ns3::UdpEchoClientHelper [class]
-    module.add_class('UdpEchoClientHelper', allow_subclassing=False)
+    module.add_class('UdpEchoClientHelper')
     ## udp-echo-helper.h: ns3::UdpEchoServerHelper [class]
-    module.add_class('UdpEchoServerHelper', allow_subclassing=False)
+    module.add_class('UdpEchoServerHelper')
     ## udp-client-server-helper.h: ns3::UdpServerHelper [class]
-    module.add_class('UdpServerHelper', allow_subclassing=False)
+    module.add_class('UdpServerHelper')
     ## udp-client-server-helper.h: ns3::UdpTraceClientHelper [class]
-    module.add_class('UdpTraceClientHelper', allow_subclassing=False)
+    module.add_class('UdpTraceClientHelper')
     ## v4ping-helper.h: ns3::V4PingHelper [class]
-    module.add_class('V4PingHelper', allow_subclassing=False)
+    module.add_class('V4PingHelper')
     ## wifi-helper.h: ns3::WifiHelper [class]
-    module.add_class('WifiHelper', allow_subclassing=False)
+    module.add_class('WifiHelper')
     ## wifi-helper.h: ns3::WifiMacHelper [class]
-    module.add_class('WifiMacHelper', allow_subclassing=False)
+    module.add_class('WifiMacHelper', allow_subclassing=True)
     ## wifi-helper.h: ns3::WifiPhyHelper [class]
-    module.add_class('WifiPhyHelper', allow_subclassing=False)
+    module.add_class('WifiPhyHelper', allow_subclassing=True)
     ## yans-wifi-helper.h: ns3::YansWifiChannelHelper [class]
-    module.add_class('YansWifiChannelHelper', allow_subclassing=False)
+    module.add_class('YansWifiChannelHelper')
     ## yans-wifi-helper.h: ns3::YansWifiPhyHelper [class]
-    module.add_class('YansWifiPhyHelper', allow_subclassing=False, parent=root_module['ns3::WifiPhyHelper'])
-    ## yans-wifi-helper.h: ns3::YansWifiPhyHelper::PcapFormat [enumeration]
-    module.add_enum('PcapFormat', ['PCAP_FORMAT_80211', 'PCAP_FORMAT_80211_PRISM', 'PCAP_FORMAT_80211_RADIOTAP'], outer_class=root_module['ns3::YansWifiPhyHelper'])
+    module.add_class('YansWifiPhyHelper', parent=[root_module['ns3::WifiPhyHelper'], root_module['ns3::PcapHelperForDevice'], root_module['ns3::AsciiTraceHelperForDevice']])
+    ## yans-wifi-helper.h: ns3::YansWifiPhyHelper::SupportedPcapDataLinkTypes [enumeration]
+    module.add_enum('SupportedPcapDataLinkTypes', ['DLT_IEEE802_11', 'DLT_PRISM_HEADER', 'DLT_IEEE802_11_RADIO'], outer_class=root_module['ns3::YansWifiPhyHelper'])
     ## aodv-helper.h: ns3::AodvHelper [class]
-    module.add_class('AodvHelper', allow_subclassing=False, parent=root_module['ns3::Ipv4RoutingHelper'])
+    module.add_class('AodvHelper', parent=root_module['ns3::Ipv4RoutingHelper'])
+    ## csma-helper.h: ns3::CsmaHelper [class]
+    module.add_class('CsmaHelper', parent=[root_module['ns3::PcapHelperForDevice'], root_module['ns3::AsciiTraceHelperForDevice']])
+    ## emu-helper.h: ns3::EmuHelper [class]
+    module.add_class('EmuHelper', parent=[root_module['ns3::PcapHelperForDevice'], root_module['ns3::AsciiTraceHelperForDevice']])
+    ## internet-stack-helper.h: ns3::InternetStackHelper [class]
+    module.add_class('InternetStackHelper', parent=[root_module['ns3::PcapHelperForIpv4'], root_module['ns3::PcapHelperForIpv6'], root_module['ns3::AsciiTraceHelperForIpv4'], root_module['ns3::AsciiTraceHelperForIpv6']])
     ## ipv4-global-routing-helper.h: ns3::Ipv4GlobalRoutingHelper [class]
-    module.add_class('Ipv4GlobalRoutingHelper', allow_subclassing=False, parent=root_module['ns3::Ipv4RoutingHelper'])
+    module.add_class('Ipv4GlobalRoutingHelper', parent=root_module['ns3::Ipv4RoutingHelper'])
     ## ipv4-list-routing-helper.h: ns3::Ipv4ListRoutingHelper [class]
-    module.add_class('Ipv4ListRoutingHelper', allow_subclassing=False, parent=root_module['ns3::Ipv4RoutingHelper'])
+    module.add_class('Ipv4ListRoutingHelper', parent=root_module['ns3::Ipv4RoutingHelper'])
     ## ipv4-nix-vector-helper.h: ns3::Ipv4NixVectorHelper [class]
-    module.add_class('Ipv4NixVectorHelper', allow_subclassing=False, parent=root_module['ns3::Ipv4RoutingHelper'])
+    module.add_class('Ipv4NixVectorHelper', parent=root_module['ns3::Ipv4RoutingHelper'])
     ## ipv6-list-routing-helper.h: ns3::Ipv6ListRoutingHelper [class]
-    module.add_class('Ipv6ListRoutingHelper', allow_subclassing=False, parent=root_module['ns3::Ipv6RoutingHelper'])
+    module.add_class('Ipv6ListRoutingHelper', parent=root_module['ns3::Ipv6RoutingHelper'])
     ## nqos-wifi-mac-helper.h: ns3::NqosWifiMacHelper [class]
-    module.add_class('NqosWifiMacHelper', allow_subclassing=False, parent=root_module['ns3::WifiMacHelper'])
+    module.add_class('NqosWifiMacHelper', parent=root_module['ns3::WifiMacHelper'])
     ## qos-wifi-mac-helper.h: ns3::QosWifiMacHelper [class]
-    module.add_class('QosWifiMacHelper', allow_subclassing=False, parent=root_module['ns3::WifiMacHelper'])
+    module.add_class('QosWifiMacHelper', parent=root_module['ns3::WifiMacHelper'])
     ## athstats-helper.h: ns3::AthstatsWifiTraceSink [class]
     module.add_class('AthstatsWifiTraceSink', parent=root_module['ns3::Object'])
     ## canvas-location.h: ns3::CanvasLocation [class]
@@ -201,13 +219,14 @@
 def register_methods(root_module):
     register_Ns3AnimationInterface_methods(root_module, root_module['ns3::AnimationInterface'])
     register_Ns3ApplicationContainer_methods(root_module, root_module['ns3::ApplicationContainer'])
+    register_Ns3AsciiTraceHelper_methods(root_module, root_module['ns3::AsciiTraceHelper'])
+    register_Ns3AsciiTraceHelperForDevice_methods(root_module, root_module['ns3::AsciiTraceHelperForDevice'])
+    register_Ns3AsciiTraceHelperForIpv4_methods(root_module, root_module['ns3::AsciiTraceHelperForIpv4'])
+    register_Ns3AsciiTraceHelperForIpv6_methods(root_module, root_module['ns3::AsciiTraceHelperForIpv6'])
     register_Ns3AthstatsHelper_methods(root_module, root_module['ns3::AthstatsHelper'])
     register_Ns3BridgeHelper_methods(root_module, root_module['ns3::BridgeHelper'])
-    register_Ns3CsmaHelper_methods(root_module, root_module['ns3::CsmaHelper'])
     register_Ns3CsmaStarHelper_methods(root_module, root_module['ns3::CsmaStarHelper'])
-    register_Ns3EmuHelper_methods(root_module, root_module['ns3::EmuHelper'])
     register_Ns3FlowMonitorHelper_methods(root_module, root_module['ns3::FlowMonitorHelper'])
-    register_Ns3InternetStackHelper_methods(root_module, root_module['ns3::InternetStackHelper'])
     register_Ns3Ipv4AddressHelper_methods(root_module, root_module['ns3::Ipv4AddressHelper'])
     register_Ns3Ipv4InterfaceContainer_methods(root_module, root_module['ns3::Ipv4InterfaceContainer'])
     register_Ns3Ipv4RoutingHelper_methods(root_module, root_module['ns3::Ipv4RoutingHelper'])
@@ -225,6 +244,10 @@
     register_Ns3OnOffHelper_methods(root_module, root_module['ns3::OnOffHelper'])
     register_Ns3PacketSinkHelper_methods(root_module, root_module['ns3::PacketSinkHelper'])
     register_Ns3PacketSocketHelper_methods(root_module, root_module['ns3::PacketSocketHelper'])
+    register_Ns3PcapHelper_methods(root_module, root_module['ns3::PcapHelper'])
+    register_Ns3PcapHelperForDevice_methods(root_module, root_module['ns3::PcapHelperForDevice'])
+    register_Ns3PcapHelperForIpv4_methods(root_module, root_module['ns3::PcapHelperForIpv4'])
+    register_Ns3PcapHelperForIpv6_methods(root_module, root_module['ns3::PcapHelperForIpv6'])
     register_Ns3Ping6Helper_methods(root_module, root_module['ns3::Ping6Helper'])
     register_Ns3PointToPointDumbbellHelper_methods(root_module, root_module['ns3::PointToPointDumbbellHelper'])
     register_Ns3PointToPointGridHelper_methods(root_module, root_module['ns3::PointToPointGridHelper'])
@@ -243,6 +266,9 @@
     register_Ns3YansWifiChannelHelper_methods(root_module, root_module['ns3::YansWifiChannelHelper'])
     register_Ns3YansWifiPhyHelper_methods(root_module, root_module['ns3::YansWifiPhyHelper'])
     register_Ns3AodvHelper_methods(root_module, root_module['ns3::AodvHelper'])
+    register_Ns3CsmaHelper_methods(root_module, root_module['ns3::CsmaHelper'])
+    register_Ns3EmuHelper_methods(root_module, root_module['ns3::EmuHelper'])
+    register_Ns3InternetStackHelper_methods(root_module, root_module['ns3::InternetStackHelper'])
     register_Ns3Ipv4GlobalRoutingHelper_methods(root_module, root_module['ns3::Ipv4GlobalRoutingHelper'])
     register_Ns3Ipv4ListRoutingHelper_methods(root_module, root_module['ns3::Ipv4ListRoutingHelper'])
     register_Ns3Ipv4NixVectorHelper_methods(root_module, root_module['ns3::Ipv4NixVectorHelper'])
@@ -330,6 +356,245 @@
                    [param('ns3::Time', 'stop')])
     return
 
+def register_Ns3AsciiTraceHelper_methods(root_module, cls):
+    ## trace-helper.h: ns3::AsciiTraceHelper::AsciiTraceHelper(ns3::AsciiTraceHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::AsciiTraceHelper const &', 'arg0')])
+    ## trace-helper.h: ns3::AsciiTraceHelper::AsciiTraceHelper() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: ns3::Ptr<ns3::OutputStreamWrapper> ns3::AsciiTraceHelper::CreateFileStream(std::string filename, std::string filemode="w") [member function]
+    cls.add_method('CreateFileStream', 
+                   'ns3::Ptr< ns3::OutputStreamWrapper >', 
+                   [param('std::string', 'filename'), param('std::string', 'filemode', default_value='"w"')])
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultDequeueSinkWithContext(ns3::Ptr<ns3::OutputStreamWrapper> file, std::string context, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultDequeueSinkWithContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('std::string', 'context'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultDequeueSinkWithoutContext(ns3::Ptr<ns3::OutputStreamWrapper> file, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultDequeueSinkWithoutContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultDropSinkWithContext(ns3::Ptr<ns3::OutputStreamWrapper> file, std::string context, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultDropSinkWithContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('std::string', 'context'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultDropSinkWithoutContext(ns3::Ptr<ns3::OutputStreamWrapper> file, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultDropSinkWithoutContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultEnqueueSinkWithContext(ns3::Ptr<ns3::OutputStreamWrapper> file, std::string context, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultEnqueueSinkWithContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('std::string', 'context'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultEnqueueSinkWithoutContext(ns3::Ptr<ns3::OutputStreamWrapper> file, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultEnqueueSinkWithoutContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultReceiveSinkWithContext(ns3::Ptr<ns3::OutputStreamWrapper> file, std::string context, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultReceiveSinkWithContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('std::string', 'context'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultReceiveSinkWithoutContext(ns3::Ptr<ns3::OutputStreamWrapper> file, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultReceiveSinkWithoutContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: std::string ns3::AsciiTraceHelper::GetFilenameFromDevice(std::string prefix, ns3::Ptr<ns3::NetDevice> device, bool useObjectNames=true) [member function]
+    cls.add_method('GetFilenameFromDevice', 
+                   'std::string', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'device'), param('bool', 'useObjectNames', default_value='true')])
+    ## trace-helper.h: std::string ns3::AsciiTraceHelper::GetFilenameFromInterfacePair(std::string prefix, ns3::Ptr<ns3::Object> object, uint32_t interface, bool useObjectNames=true) [member function]
+    cls.add_method('GetFilenameFromInterfacePair', 
+                   'std::string', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Object >', 'object'), param('uint32_t', 'interface'), param('bool', 'useObjectNames', default_value='true')])
+    return
+
+def register_Ns3AsciiTraceHelperForDevice_methods(root_module, cls):
+    ## trace-helper.h: ns3::AsciiTraceHelperForDevice::AsciiTraceHelperForDevice(ns3::AsciiTraceHelperForDevice const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::AsciiTraceHelperForDevice const &', 'arg0')])
+    ## trace-helper.h: ns3::AsciiTraceHelperForDevice::AsciiTraceHelperForDevice() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(std::string prefix, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::Ptr< ns3::NetDevice >', 'nd')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(std::string prefix, std::string ndName) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('std::string', 'ndName')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string ndName) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'ndName')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(std::string prefix, ns3::NetDeviceContainer d) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NetDeviceContainer', 'd')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::NetDeviceContainer d) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::NetDeviceContainer', 'd')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(std::string prefix, ns3::NodeContainer n) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::NodeContainer n) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(std::string prefix, uint32_t nodeid, uint32_t deviceid) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(ns3::Ptr<ns3::OutputStreamWrapper> stream, uint32_t nodeid, uint32_t deviceid) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAsciiAll(std::string prefix) [member function]
+    cls.add_method('EnableAsciiAll', 
+                   'void', 
+                   [param('std::string', 'prefix')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAsciiAll(ns3::Ptr<ns3::OutputStreamWrapper> stream) [member function]
+    cls.add_method('EnableAsciiAll', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAsciiInternal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnableAsciiInternal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
+def register_Ns3AsciiTraceHelperForIpv4_methods(root_module, cls):
+    ## trace-helper.h: ns3::AsciiTraceHelperForIpv4::AsciiTraceHelperForIpv4(ns3::AsciiTraceHelperForIpv4 const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::AsciiTraceHelperForIpv4 const &', 'arg0')])
+    ## trace-helper.h: ns3::AsciiTraceHelperForIpv4::AsciiTraceHelperForIpv4() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(std::string prefix, ns3::Ptr<ns3::Ipv4> ipv4, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::Ptr<ns3::Ipv4> ipv4, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(std::string prefix, std::string ipv4Name, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('std::string', 'ipv4Name'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string ipv4Name, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'ipv4Name'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(std::string prefix, ns3::Ipv4InterfaceContainer c) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ipv4InterfaceContainer', 'c')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::Ipv4InterfaceContainer c) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::Ipv4InterfaceContainer', 'c')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(std::string prefix, ns3::NodeContainer n) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::NodeContainer n) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(std::string prefix, uint32_t nodeid, uint32_t deviceid) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(ns3::Ptr<ns3::OutputStreamWrapper> stream, uint32_t nodeid, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('uint32_t', 'nodeid'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4All(std::string prefix) [member function]
+    cls.add_method('EnableAsciiIpv4All', 
+                   'void', 
+                   [param('std::string', 'prefix')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4All(ns3::Ptr<ns3::OutputStreamWrapper> stream) [member function]
+    cls.add_method('EnableAsciiIpv4All', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4Internal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::Ipv4> ipv4, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv4Internal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
+def register_Ns3AsciiTraceHelperForIpv6_methods(root_module, cls):
+    ## trace-helper.h: ns3::AsciiTraceHelperForIpv6::AsciiTraceHelperForIpv6(ns3::AsciiTraceHelperForIpv6 const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::AsciiTraceHelperForIpv6 const &', 'arg0')])
+    ## trace-helper.h: ns3::AsciiTraceHelperForIpv6::AsciiTraceHelperForIpv6() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(std::string prefix, ns3::Ptr<ns3::Ipv6> ipv6, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv6 >', 'ipv6'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::Ptr<ns3::Ipv6> ipv6, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::Ptr< ns3::Ipv6 >', 'ipv6'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(std::string prefix, std::string ipv6Name, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('std::string', 'ipv6Name'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string ipv6Name, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'ipv6Name'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(std::string prefix, ns3::Ipv6InterfaceContainer c) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ipv6InterfaceContainer', 'c')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::Ipv6InterfaceContainer c) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::Ipv6InterfaceContainer', 'c')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(std::string prefix, ns3::NodeContainer n) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::NodeContainer n) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(std::string prefix, uint32_t nodeid, uint32_t deviceid) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(ns3::Ptr<ns3::OutputStreamWrapper> stream, uint32_t nodeid, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('uint32_t', 'nodeid'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6All(std::string prefix) [member function]
+    cls.add_method('EnableAsciiIpv6All', 
+                   'void', 
+                   [param('std::string', 'prefix')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6All(ns3::Ptr<ns3::OutputStreamWrapper> stream) [member function]
+    cls.add_method('EnableAsciiIpv6All', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6Internal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::Ipv6> ipv6, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv6Internal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv6 >', 'ipv6'), param('uint32_t', 'interface')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
 def register_Ns3AthstatsHelper_methods(root_module, cls):
     ## athstats-helper.h: ns3::AthstatsHelper::AthstatsHelper(ns3::AthstatsHelper const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::AthstatsHelper const &', 'arg0')])
@@ -372,120 +637,6 @@
                    [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
     return
 
-def register_Ns3CsmaHelper_methods(root_module, cls):
-    ## csma-helper.h: ns3::CsmaHelper::CsmaHelper(ns3::CsmaHelper const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::CsmaHelper const &', 'arg0')])
-    ## csma-helper.h: ns3::CsmaHelper::CsmaHelper() [constructor]
-    cls.add_constructor([])
-    ## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NetDeviceContainer', 'd')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnableAsciiAll(std::ostream & os) [member function]
-    cls.add_method('EnableAsciiAll', 
-                   'void', 
-                   [param('std::ostream &', 'os')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, std::string ndName, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('std::string', 'ndName'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::NodeContainer n, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NodeContainer', 'n'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcapAll(std::string filename, bool promiscuous) [member function]
-    cls.add_method('EnablePcapAll', 
-                   'void', 
-                   [param('std::string', 'filename'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::Ptr<ns3::Node> node) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::Ptr< ns3::Node >', 'node')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(std::string name) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('std::string', 'name')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::Ptr<ns3::Node> node, ns3::Ptr<ns3::CsmaChannel> channel) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::Ptr<ns3::Node> node, std::string channelName) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::Ptr< ns3::Node >', 'node'), param('std::string', 'channelName')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(std::string nodeName, ns3::Ptr<ns3::CsmaChannel> channel) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('std::string', 'nodeName'), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(std::string nodeName, std::string channelName) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('std::string', 'nodeName'), param('std::string', 'channelName')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::NodeContainer const &', 'c')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c, ns3::Ptr<ns3::CsmaChannel> channel) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::NodeContainer const &', 'c'), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c, std::string channelName) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::NodeContainer const &', 'c'), param('std::string', 'channelName')], 
-                   is_const=True)
-    ## csma-helper.h: void ns3::CsmaHelper::SetChannelAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
-    cls.add_method('SetChannelAttribute', 
-                   'void', 
-                   [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
-    ## csma-helper.h: void ns3::CsmaHelper::SetDeviceAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
-    cls.add_method('SetDeviceAttribute', 
-                   'void', 
-                   [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
-    ## csma-helper.h: void ns3::CsmaHelper::SetQueue(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue()) [member function]
-    cls.add_method('SetQueue', 
-                   'void', 
-                   [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()')])
-    return
-
 def register_Ns3CsmaStarHelper_methods(root_module, cls):
     ## csma-star-helper.h: ns3::CsmaStarHelper::CsmaStarHelper(ns3::CsmaStarHelper const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::CsmaStarHelper const &', 'arg0')])
@@ -536,86 +687,6 @@
                    is_const=True)
     return
 
-def register_Ns3EmuHelper_methods(root_module, cls):
-    ## emu-helper.h: ns3::EmuHelper::EmuHelper(ns3::EmuHelper const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::EmuHelper const &', 'arg0')])
-    ## emu-helper.h: ns3::EmuHelper::EmuHelper() [constructor]
-    cls.add_constructor([])
-    ## emu-helper.h: static void ns3::EmuHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NetDeviceContainer', 'd')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnableAsciiAll(std::ostream & os) [member function]
-    cls.add_method('EnableAsciiAll', 
-                   'void', 
-                   [param('std::ostream &', 'os')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, std::string ndName, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('std::string', 'ndName'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, ns3::NodeContainer n, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NodeContainer', 'n'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcapAll(std::string filename, bool promiscuous) [member function]
-    cls.add_method('EnablePcapAll', 
-                   'void', 
-                   [param('std::string', 'filename'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## emu-helper.h: ns3::NetDeviceContainer ns3::EmuHelper::Install(ns3::Ptr<ns3::Node> node) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::Ptr< ns3::Node >', 'node')], 
-                   is_const=True)
-    ## emu-helper.h: ns3::NetDeviceContainer ns3::EmuHelper::Install(std::string nodeName) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('std::string', 'nodeName')], 
-                   is_const=True)
-    ## emu-helper.h: ns3::NetDeviceContainer ns3::EmuHelper::Install(ns3::NodeContainer const & c) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::NodeContainer const &', 'c')], 
-                   is_const=True)
-    ## emu-helper.h: void ns3::EmuHelper::SetAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
-    cls.add_method('SetAttribute', 
-                   'void', 
-                   [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
-    ## emu-helper.h: void ns3::EmuHelper::SetQueue(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue()) [member function]
-    cls.add_method('SetQueue', 
-                   'void', 
-                   [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()')])
-    return
-
 def register_Ns3FlowMonitorHelper_methods(root_module, cls):
     ## flow-monitor-helper.h: ns3::FlowMonitorHelper::FlowMonitorHelper(ns3::FlowMonitorHelper const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::FlowMonitorHelper const &', 'arg0')])
@@ -647,76 +718,6 @@
                    [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
     return
 
-def register_Ns3InternetStackHelper_methods(root_module, cls):
-    ## internet-stack-helper.h: ns3::InternetStackHelper::InternetStackHelper() [constructor]
-    cls.add_constructor([])
-    ## internet-stack-helper.h: ns3::InternetStackHelper::InternetStackHelper(ns3::InternetStackHelper const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::InternetStackHelper const &', 'arg0')])
-    ## internet-stack-helper.h: static void ns3::InternetStackHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')], 
-                   is_static=True)
-    ## internet-stack-helper.h: static void ns3::InternetStackHelper::EnableAsciiAll(std::ostream & os) [member function]
-    cls.add_method('EnableAsciiAll', 
-                   'void', 
-                   [param('std::ostream &', 'os')], 
-                   is_static=True)
-    ## internet-stack-helper.h: static void ns3::InternetStackHelper::EnablePcapAll(std::string filename) [member function]
-    cls.add_method('EnablePcapAll', 
-                   'void', 
-                   [param('std::string', 'filename')], 
-                   is_static=True)
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::Install(std::string nodeName) const [member function]
-    cls.add_method('Install', 
-                   'void', 
-                   [param('std::string', 'nodeName')], 
-                   is_const=True)
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::Install(ns3::Ptr<ns3::Node> node) const [member function]
-    cls.add_method('Install', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::Node >', 'node')], 
-                   is_const=True)
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::Install(ns3::NodeContainer c) const [member function]
-    cls.add_method('Install', 
-                   'void', 
-                   [param('ns3::NodeContainer', 'c')], 
-                   is_const=True)
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::InstallAll() const [member function]
-    cls.add_method('InstallAll', 
-                   'void', 
-                   [], 
-                   is_const=True)
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::Reset() [member function]
-    cls.add_method('Reset', 
-                   'void', 
-                   [])
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetIpv4StackInstall(bool enable) [member function]
-    cls.add_method('SetIpv4StackInstall', 
-                   'void', 
-                   [param('bool', 'enable')])
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetIpv6StackInstall(bool enable) [member function]
-    cls.add_method('SetIpv6StackInstall', 
-                   'void', 
-                   [param('bool', 'enable')])
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetRoutingHelper(ns3::Ipv4RoutingHelper const & routing) [member function]
-    cls.add_method('SetRoutingHelper', 
-                   'void', 
-                   [param('ns3::Ipv4RoutingHelper const &', 'routing')])
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetRoutingHelper(ns3::Ipv6RoutingHelper const & routing) [member function]
-    cls.add_method('SetRoutingHelper', 
-                   'void', 
-                   [param('ns3::Ipv6RoutingHelper const &', 'routing')])
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetTcp(std::string tid) [member function]
-    cls.add_method('SetTcp', 
-                   'void', 
-                   [param('std::string', 'tid')])
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetTcp(std::string tid, std::string attr, ns3::AttributeValue const & val) [member function]
-    cls.add_method('SetTcp', 
-                   'void', 
-                   [param('std::string', 'tid'), param('std::string', 'attr'), param('ns3::AttributeValue const &', 'val')])
-    return
-
 def register_Ns3Ipv4AddressHelper_methods(root_module, cls):
     ## ipv4-address-helper.h: ns3::Ipv4AddressHelper::Ipv4AddressHelper(ns3::Ipv4AddressHelper const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Ipv4AddressHelper const &', 'arg0')])
@@ -763,6 +764,16 @@
     cls.add_method('Add', 
                    'void', 
                    [param('std::string', 'ipv4Name'), param('uint32_t', 'interface')])
+    ## ipv4-interface-container.h: __gnu_cxx::__normal_iterator<const std::pair<ns3::Ptr<ns3::Ipv4>, unsigned int>*,std::vector<std::pair<ns3::Ptr<ns3::Ipv4>, unsigned int>, std::allocator<std::pair<ns3::Ptr<ns3::Ipv4>, unsigned int> > > > ns3::Ipv4InterfaceContainer::Begin() const [member function]
+    cls.add_method('Begin', 
+                   '__gnu_cxx::__normal_iterator< std::pair< ns3::Ptr< ns3::Ipv4 >, unsigned int > const, std::vector< std::pair< ns3::Ptr< ns3::Ipv4 >, unsigned int > > >', 
+                   [], 
+                   is_const=True)
+    ## ipv4-interface-container.h: __gnu_cxx::__normal_iterator<const std::pair<ns3::Ptr<ns3::Ipv4>, unsigned int>*,std::vector<std::pair<ns3::Ptr<ns3::Ipv4>, unsigned int>, std::allocator<std::pair<ns3::Ptr<ns3::Ipv4>, unsigned int> > > > ns3::Ipv4InterfaceContainer::End() const [member function]
+    cls.add_method('End', 
+                   '__gnu_cxx::__normal_iterator< std::pair< ns3::Ptr< ns3::Ipv4 >, unsigned int > const, std::vector< std::pair< ns3::Ptr< ns3::Ipv4 >, unsigned int > > >', 
+                   [], 
+                   is_const=True)
     ## ipv4-interface-container.h: std::pair<ns3::Ptr<ns3::Ipv4>,unsigned int> ns3::Ipv4InterfaceContainer::Get(uint32_t i) const [member function]
     cls.add_method('Get', 
                    'std::pair< ns3::Ptr< ns3::Ipv4 >, unsigned int >', 
@@ -899,6 +910,16 @@
     cls.add_method('Add', 
                    'void', 
                    [param('std::string', 'ipv6Name'), param('uint32_t', 'interface')])
+    ## ipv6-interface-container.h: __gnu_cxx::__normal_iterator<const std::pair<ns3::Ptr<ns3::Ipv6>, unsigned int>*,std::vector<std::pair<ns3::Ptr<ns3::Ipv6>, unsigned int>, std::allocator<std::pair<ns3::Ptr<ns3::Ipv6>, unsigned int> > > > ns3::Ipv6InterfaceContainer::Begin() const [member function]
+    cls.add_method('Begin', 
+                   '__gnu_cxx::__normal_iterator< std::pair< ns3::Ptr< ns3::Ipv6 >, unsigned int > const, std::vector< std::pair< ns3::Ptr< ns3::Ipv6 >, unsigned int > > >', 
+                   [], 
+                   is_const=True)
+    ## ipv6-interface-container.h: __gnu_cxx::__normal_iterator<const std::pair<ns3::Ptr<ns3::Ipv6>, unsigned int>*,std::vector<std::pair<ns3::Ptr<ns3::Ipv6>, unsigned int>, std::allocator<std::pair<ns3::Ptr<ns3::Ipv6>, unsigned int> > > > ns3::Ipv6InterfaceContainer::End() const [member function]
+    cls.add_method('End', 
+                   '__gnu_cxx::__normal_iterator< std::pair< ns3::Ptr< ns3::Ipv6 >, unsigned int > const, std::vector< std::pair< ns3::Ptr< ns3::Ipv6 >, unsigned int > > >', 
+                   [], 
+                   is_const=True)
     ## ipv6-interface-container.h: ns3::Ipv6Address ns3::Ipv6InterfaceContainer::GetAddress(uint32_t i, uint32_t j) const [member function]
     cls.add_method('GetAddress', 
                    'ns3::Ipv6Address', 
@@ -1310,6 +1331,133 @@
                    is_const=True)
     return
 
+def register_Ns3PcapHelper_methods(root_module, cls):
+    ## trace-helper.h: ns3::PcapHelper::PcapHelper(ns3::PcapHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::PcapHelper const &', 'arg0')])
+    ## trace-helper.h: ns3::PcapHelper::PcapHelper() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: ns3::Ptr<ns3::PcapFileWrapper> ns3::PcapHelper::CreateFile(std::string filename, std::string filemode, uint32_t dataLinkType, uint32_t snapLen=65535, int32_t tzCorrection=0) [member function]
+    cls.add_method('CreateFile', 
+                   'ns3::Ptr< ns3::PcapFileWrapper >', 
+                   [param('std::string', 'filename'), param('std::string', 'filemode'), param('uint32_t', 'dataLinkType'), param('uint32_t', 'snapLen', default_value='65535'), param('int32_t', 'tzCorrection', default_value='0')])
+    ## trace-helper.h: std::string ns3::PcapHelper::GetFilenameFromDevice(std::string prefix, ns3::Ptr<ns3::NetDevice> device, bool useObjectNames=true) [member function]
+    cls.add_method('GetFilenameFromDevice', 
+                   'std::string', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'device'), param('bool', 'useObjectNames', default_value='true')])
+    ## trace-helper.h: std::string ns3::PcapHelper::GetFilenameFromInterfacePair(std::string prefix, ns3::Ptr<ns3::Object> object, uint32_t interface, bool useObjectNames=true) [member function]
+    cls.add_method('GetFilenameFromInterfacePair', 
+                   'std::string', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Object >', 'object'), param('uint32_t', 'interface'), param('bool', 'useObjectNames', default_value='true')])
+    return
+
+def register_Ns3PcapHelperForDevice_methods(root_module, cls):
+    ## trace-helper.h: ns3::PcapHelperForDevice::PcapHelperForDevice(ns3::PcapHelperForDevice const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::PcapHelperForDevice const &', 'arg0')])
+    ## trace-helper.h: ns3::PcapHelperForDevice::PcapHelperForDevice() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: void ns3::PcapHelperForDevice::EnablePcap(std::string prefix, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous', default_value='false')])
+    ## trace-helper.h: void ns3::PcapHelperForDevice::EnablePcap(std::string prefix, std::string ndName, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('std::string', 'ndName'), param('bool', 'promiscuous', default_value='false')])
+    ## trace-helper.h: void ns3::PcapHelperForDevice::EnablePcap(std::string prefix, ns3::NetDeviceContainer d, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NetDeviceContainer', 'd'), param('bool', 'promiscuous', default_value='false')])
+    ## trace-helper.h: void ns3::PcapHelperForDevice::EnablePcap(std::string prefix, ns3::NodeContainer n, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NodeContainer', 'n'), param('bool', 'promiscuous', default_value='false')])
+    ## trace-helper.h: void ns3::PcapHelperForDevice::EnablePcap(std::string prefix, uint32_t nodeid, uint32_t deviceid, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid'), param('bool', 'promiscuous', default_value='false')])
+    ## trace-helper.h: void ns3::PcapHelperForDevice::EnablePcapAll(std::string prefix, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcapAll', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('bool', 'promiscuous', default_value='false')])
+    ## trace-helper.h: void ns3::PcapHelperForDevice::EnablePcapInternal(std::string prefix, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous) [member function]
+    cls.add_method('EnablePcapInternal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
+def register_Ns3PcapHelperForIpv4_methods(root_module, cls):
+    ## trace-helper.h: ns3::PcapHelperForIpv4::PcapHelperForIpv4(ns3::PcapHelperForIpv4 const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::PcapHelperForIpv4 const &', 'arg0')])
+    ## trace-helper.h: ns3::PcapHelperForIpv4::PcapHelperForIpv4() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: void ns3::PcapHelperForIpv4::EnablePcapIpv4(std::string prefix, ns3::Ptr<ns3::Ipv4> ipv4, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv4::EnablePcapIpv4(std::string prefix, std::string ipv4Name, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('std::string', 'ipv4Name'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv4::EnablePcapIpv4(std::string prefix, ns3::Ipv4InterfaceContainer c) [member function]
+    cls.add_method('EnablePcapIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ipv4InterfaceContainer', 'c')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv4::EnablePcapIpv4(std::string prefix, ns3::NodeContainer n) [member function]
+    cls.add_method('EnablePcapIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv4::EnablePcapIpv4(std::string prefix, uint32_t nodeid, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('uint32_t', 'nodeid'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv4::EnablePcapIpv4All(std::string prefix) [member function]
+    cls.add_method('EnablePcapIpv4All', 
+                   'void', 
+                   [param('std::string', 'prefix')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv4::EnablePcapIpv4Internal(std::string prefix, ns3::Ptr<ns3::Ipv4> ipv4, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv4Internal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
+def register_Ns3PcapHelperForIpv6_methods(root_module, cls):
+    ## trace-helper.h: ns3::PcapHelperForIpv6::PcapHelperForIpv6(ns3::PcapHelperForIpv6 const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::PcapHelperForIpv6 const &', 'arg0')])
+    ## trace-helper.h: ns3::PcapHelperForIpv6::PcapHelperForIpv6() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: void ns3::PcapHelperForIpv6::EnablePcapIpv6(std::string prefix, ns3::Ptr<ns3::Ipv6> ipv6, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv6 >', 'ipv6'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv6::EnablePcapIpv6(std::string prefix, std::string ipv6Name, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('std::string', 'ipv6Name'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv6::EnablePcapIpv6(std::string prefix, ns3::Ipv6InterfaceContainer c) [member function]
+    cls.add_method('EnablePcapIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ipv6InterfaceContainer', 'c')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv6::EnablePcapIpv6(std::string prefix, ns3::NodeContainer n) [member function]
+    cls.add_method('EnablePcapIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv6::EnablePcapIpv6(std::string prefix, uint32_t nodeid, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('uint32_t', 'nodeid'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv6::EnablePcapIpv6All(std::string prefix) [member function]
+    cls.add_method('EnablePcapIpv6All', 
+                   'void', 
+                   [param('std::string', 'prefix')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv6::EnablePcapIpv6Internal(std::string prefix, ns3::Ptr<ns3::Ipv6> ipv6, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv6Internal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv6 >', 'ipv6'), param('uint32_t', 'interface')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
 def register_Ns3Ping6Helper_methods(root_module, cls):
     ## ping6-helper.h: ns3::Ping6Helper::Ping6Helper(ns3::Ping6Helper const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Ping6Helper const &', 'arg0')])
@@ -1350,10 +1498,10 @@
     cls.add_method('AssignIpv4Addresses', 
                    'void', 
                    [param('ns3::Ipv4AddressHelper', 'leftIp'), param('ns3::Ipv4AddressHelper', 'rightIp'), param('ns3::Ipv4AddressHelper', 'routerIp')])
-    ## point-to-point-dumbbell-helper.h: void ns3::PointToPointDumbbellHelper::BoundingBox(double arg0, double arg1, double arg2, double arg3) [member function]
+    ## point-to-point-dumbbell-helper.h: void ns3::PointToPointDumbbellHelper::BoundingBox(double ulx, double uly, double lrx, double lry) [member function]
     cls.add_method('BoundingBox', 
                    'void', 
-                   [param('double', 'arg0'), param('double', 'arg1'), param('double', 'arg2'), param('double', 'arg3')])
+                   [param('double', 'ulx'), param('double', 'uly'), param('double', 'lrx'), param('double', 'lry')])
     ## point-to-point-dumbbell-helper.h: ns3::Ptr<ns3::Node> ns3::PointToPointDumbbellHelper::GetLeft() const [member function]
     cls.add_method('GetLeft', 
                    'ns3::Ptr< ns3::Node >', 
@@ -1432,56 +1580,6 @@
     cls.add_constructor([param('ns3::PointToPointHelper const &', 'arg0')])
     ## point-to-point-helper.h: ns3::PointToPointHelper::PointToPointHelper() [constructor]
     cls.add_constructor([])
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NetDeviceContainer', 'd')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAsciiAll(std::ostream & os) [member function]
-    cls.add_method('EnableAsciiAll', 
-                   'void', 
-                   [param('std::ostream &', 'os')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, std::string ndName) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('std::string', 'ndName')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcapAll(std::string filename) [member function]
-    cls.add_method('EnablePcapAll', 
-                   'void', 
-                   [param('std::string', 'filename')], 
-                   is_static=True)
     ## point-to-point-helper.h: ns3::NetDeviceContainer ns3::PointToPointHelper::Install(ns3::NodeContainer c) [member function]
     cls.add_method('Install', 
                    'ns3::NetDeviceContainer', 
@@ -1514,6 +1612,16 @@
     cls.add_method('SetQueue', 
                    'void', 
                    [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()')])
+    ## point-to-point-helper.h: void ns3::PointToPointHelper::EnableAsciiInternal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnableAsciiInternal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd')], 
+                   visibility='private', is_virtual=True)
+    ## point-to-point-helper.h: void ns3::PointToPointHelper::EnablePcapInternal(std::string prefix, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcapInternal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous', default_value='false')], 
+                   visibility='private', is_virtual=True)
     return
 
 def register_Ns3PointToPointStarHelper_methods(root_module, cls):
@@ -1837,50 +1945,6 @@
                    'ns3::YansWifiPhyHelper', 
                    [], 
                    is_static=True)
-    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
-                   is_static=True)
-    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NetDeviceContainer', 'd')], 
-                   is_static=True)
-    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')], 
-                   is_static=True)
-    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnableAsciiAll(std::ostream & os) [member function]
-    cls.add_method('EnableAsciiAll', 
-                   'void', 
-                   [param('std::ostream &', 'os')], 
-                   is_static=True)
-    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')])
-    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd')])
-    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, std::string ndName) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('std::string', 'ndName')])
-    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')])
-    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')])
-    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcapAll(std::string filename) [member function]
-    cls.add_method('EnablePcapAll', 
-                   'void', 
-                   [param('std::string', 'filename')])
     ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::Set(std::string name, ns3::AttributeValue const & v) [member function]
     cls.add_method('Set', 
                    'void', 
@@ -1897,15 +1961,25 @@
     cls.add_method('SetErrorRateModel', 
                    'void', 
                    [param('std::string', 'name'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')])
-    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::SetPcapFormat(ns3::YansWifiPhyHelper::PcapFormat format) [member function]
-    cls.add_method('SetPcapFormat', 
+    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::SetPcapDataLinkType(ns3::YansWifiPhyHelper::SupportedPcapDataLinkTypes dlt) [member function]
+    cls.add_method('SetPcapDataLinkType', 
                    'void', 
-                   [param('ns3::YansWifiPhyHelper::PcapFormat', 'format')])
+                   [param('ns3::YansWifiPhyHelper::SupportedPcapDataLinkTypes', 'dlt')])
     ## yans-wifi-helper.h: ns3::Ptr<ns3::WifiPhy> ns3::YansWifiPhyHelper::Create(ns3::Ptr<ns3::Node> node, ns3::Ptr<ns3::WifiNetDevice> device) const [member function]
     cls.add_method('Create', 
                    'ns3::Ptr< ns3::WifiPhy >', 
                    [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Ptr< ns3::WifiNetDevice >', 'device')], 
                    is_const=True, visibility='private', is_virtual=True)
+    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnableAsciiInternal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnableAsciiInternal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd')], 
+                   visibility='private', is_virtual=True)
+    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcapInternal(std::string prefix, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous) [member function]
+    cls.add_method('EnablePcapInternal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous')], 
+                   visibility='private', is_virtual=True)
     return
 
 def register_Ns3AodvHelper_methods(root_module, cls):
@@ -1929,6 +2003,195 @@
                    [param('std::string', 'name'), param('ns3::AttributeValue const &', 'value')])
     return
 
+def register_Ns3CsmaHelper_methods(root_module, cls):
+    ## csma-helper.h: ns3::CsmaHelper::CsmaHelper(ns3::CsmaHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::CsmaHelper const &', 'arg0')])
+    ## csma-helper.h: ns3::CsmaHelper::CsmaHelper() [constructor]
+    cls.add_constructor([])
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::Ptr<ns3::Node> node) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::Ptr< ns3::Node >', 'node')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(std::string name) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('std::string', 'name')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::Ptr<ns3::Node> node, ns3::Ptr<ns3::CsmaChannel> channel) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::Ptr<ns3::Node> node, std::string channelName) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::Ptr< ns3::Node >', 'node'), param('std::string', 'channelName')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(std::string nodeName, ns3::Ptr<ns3::CsmaChannel> channel) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('std::string', 'nodeName'), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(std::string nodeName, std::string channelName) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('std::string', 'nodeName'), param('std::string', 'channelName')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::NodeContainer const &', 'c')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c, ns3::Ptr<ns3::CsmaChannel> channel) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::NodeContainer const &', 'c'), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c, std::string channelName) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::NodeContainer const &', 'c'), param('std::string', 'channelName')], 
+                   is_const=True)
+    ## csma-helper.h: void ns3::CsmaHelper::SetChannelAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
+    cls.add_method('SetChannelAttribute', 
+                   'void', 
+                   [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
+    ## csma-helper.h: void ns3::CsmaHelper::SetDeviceAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
+    cls.add_method('SetDeviceAttribute', 
+                   'void', 
+                   [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
+    ## csma-helper.h: void ns3::CsmaHelper::SetQueue(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue()) [member function]
+    cls.add_method('SetQueue', 
+                   'void', 
+                   [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()')])
+    ## csma-helper.h: void ns3::CsmaHelper::EnableAsciiInternal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnableAsciiInternal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd')], 
+                   visibility='private', is_virtual=True)
+    ## csma-helper.h: void ns3::CsmaHelper::EnablePcapInternal(std::string prefix, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcapInternal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous', default_value='false')], 
+                   visibility='private', is_virtual=True)
+    return
+
+def register_Ns3EmuHelper_methods(root_module, cls):
+    ## emu-helper.h: ns3::EmuHelper::EmuHelper(ns3::EmuHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::EmuHelper const &', 'arg0')])
+    ## emu-helper.h: ns3::EmuHelper::EmuHelper() [constructor]
+    cls.add_constructor([])
+    ## emu-helper.h: ns3::NetDeviceContainer ns3::EmuHelper::Install(ns3::Ptr<ns3::Node> node) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::Ptr< ns3::Node >', 'node')], 
+                   is_const=True)
+    ## emu-helper.h: ns3::NetDeviceContainer ns3::EmuHelper::Install(std::string nodeName) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('std::string', 'nodeName')], 
+                   is_const=True)
+    ## emu-helper.h: ns3::NetDeviceContainer ns3::EmuHelper::Install(ns3::NodeContainer const & c) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::NodeContainer const &', 'c')], 
+                   is_const=True)
+    ## emu-helper.h: void ns3::EmuHelper::SetAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
+    cls.add_method('SetAttribute', 
+                   'void', 
+                   [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
+    ## emu-helper.h: void ns3::EmuHelper::SetQueue(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue()) [member function]
+    cls.add_method('SetQueue', 
+                   'void', 
+                   [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()')])
+    ## emu-helper.h: void ns3::EmuHelper::EnableAsciiInternal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnableAsciiInternal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd')], 
+                   visibility='private', is_virtual=True)
+    ## emu-helper.h: void ns3::EmuHelper::EnablePcapInternal(std::string prefix, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcapInternal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous', default_value='false')], 
+                   visibility='private', is_virtual=True)
+    return
+
+def register_Ns3InternetStackHelper_methods(root_module, cls):
+    ## internet-stack-helper.h: ns3::InternetStackHelper::InternetStackHelper() [constructor]
+    cls.add_constructor([])
+    ## internet-stack-helper.h: ns3::InternetStackHelper::InternetStackHelper(ns3::InternetStackHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::InternetStackHelper const &', 'arg0')])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::Install(std::string nodeName) const [member function]
+    cls.add_method('Install', 
+                   'void', 
+                   [param('std::string', 'nodeName')], 
+                   is_const=True)
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::Install(ns3::Ptr<ns3::Node> node) const [member function]
+    cls.add_method('Install', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Node >', 'node')], 
+                   is_const=True)
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::Install(ns3::NodeContainer c) const [member function]
+    cls.add_method('Install', 
+                   'void', 
+                   [param('ns3::NodeContainer', 'c')], 
+                   is_const=True)
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::InstallAll() const [member function]
+    cls.add_method('InstallAll', 
+                   'void', 
+                   [], 
+                   is_const=True)
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::Reset() [member function]
+    cls.add_method('Reset', 
+                   'void', 
+                   [])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetIpv4StackInstall(bool enable) [member function]
+    cls.add_method('SetIpv4StackInstall', 
+                   'void', 
+                   [param('bool', 'enable')])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetIpv6StackInstall(bool enable) [member function]
+    cls.add_method('SetIpv6StackInstall', 
+                   'void', 
+                   [param('bool', 'enable')])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetRoutingHelper(ns3::Ipv4RoutingHelper const & routing) [member function]
+    cls.add_method('SetRoutingHelper', 
+                   'void', 
+                   [param('ns3::Ipv4RoutingHelper const &', 'routing')])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetRoutingHelper(ns3::Ipv6RoutingHelper const & routing) [member function]
+    cls.add_method('SetRoutingHelper', 
+                   'void', 
+                   [param('ns3::Ipv6RoutingHelper const &', 'routing')])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetTcp(std::string tid) [member function]
+    cls.add_method('SetTcp', 
+                   'void', 
+                   [param('std::string', 'tid')])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetTcp(std::string tid, std::string attr, ns3::AttributeValue const & val) [member function]
+    cls.add_method('SetTcp', 
+                   'void', 
+                   [param('std::string', 'tid'), param('std::string', 'attr'), param('ns3::AttributeValue const &', 'val')])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::EnableAsciiIpv4Internal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::Ipv4> ipv4, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv4Internal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')], 
+                   visibility='private', is_virtual=True)
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::EnableAsciiIpv6Internal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::Ipv6> ipv6, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv6Internal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv6 >', 'ipv6'), param('uint32_t', 'interface')], 
+                   visibility='private', is_virtual=True)
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::EnablePcapIpv4Internal(std::string prefix, ns3::Ptr<ns3::Ipv4> ipv4, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv4Internal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')], 
+                   visibility='private', is_virtual=True)
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::EnablePcapIpv6Internal(std::string prefix, ns3::Ptr<ns3::Ipv6> ipv6, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv6Internal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv6 >', 'ipv6'), param('uint32_t', 'interface')], 
+                   visibility='private', is_virtual=True)
+    return
+
 def register_Ns3Ipv4GlobalRoutingHelper_methods(root_module, cls):
     ## ipv4-global-routing-helper.h: ns3::Ipv4GlobalRoutingHelper::Ipv4GlobalRoutingHelper() [constructor]
     cls.add_constructor([])
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_internet_stack.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_internet_stack.py	Thu Feb 25 14:17:21 2010 +0100
@@ -59,6 +59,8 @@
     module.add_class('Icmpv6TooBig', parent=root_module['ns3::Icmpv6Header'])
     ## ipv6-extension-header.h: ns3::Ipv6ExtensionHeader [class]
     module.add_class('Ipv6ExtensionHeader', parent=root_module['ns3::Header'])
+    ## ipv6-extension-header.h: ns3::Ipv6ExtensionHopByHopHeader [class]
+    module.add_class('Ipv6ExtensionHopByHopHeader', parent=[root_module['ns3::Ipv6ExtensionHeader'], root_module['ns3::OptionField']])
     ## ipv6-extension-header.h: ns3::Ipv6ExtensionRoutingHeader [class]
     module.add_class('Ipv6ExtensionRoutingHeader', parent=root_module['ns3::Ipv6ExtensionHeader'])
     ## ipv6-option-header.h: ns3::Ipv6OptionHeader [class]
@@ -101,6 +103,8 @@
     module.add_enum('RxStatus', ['RX_OK', 'RX_CSUM_FAILED', 'RX_ENDPOINT_CLOSED', 'RX_ENDPOINT_UNREACH'], outer_class=root_module['ns3::Ipv4L4Protocol'])
     ## ipv6-extension-header.h: ns3::Ipv6ExtensionAHHeader [class]
     module.add_class('Ipv6ExtensionAHHeader', parent=root_module['ns3::Ipv6ExtensionHeader'])
+    ## ipv6-extension-header.h: ns3::Ipv6ExtensionDestinationHeader [class]
+    module.add_class('Ipv6ExtensionDestinationHeader', parent=[root_module['ns3::Ipv6ExtensionHeader'], root_module['ns3::OptionField']])
     ## ipv6-extension-header.h: ns3::Ipv6ExtensionESPHeader [class]
     module.add_class('Ipv6ExtensionESPHeader', parent=root_module['ns3::Ipv6ExtensionHeader'])
     ## ipv6-extension-header.h: ns3::Ipv6ExtensionFragmentHeader [class]
@@ -231,6 +235,7 @@
     register_Ns3Icmpv6TimeExceeded_methods(root_module, root_module['ns3::Icmpv6TimeExceeded'])
     register_Ns3Icmpv6TooBig_methods(root_module, root_module['ns3::Icmpv6TooBig'])
     register_Ns3Ipv6ExtensionHeader_methods(root_module, root_module['ns3::Ipv6ExtensionHeader'])
+    register_Ns3Ipv6ExtensionHopByHopHeader_methods(root_module, root_module['ns3::Ipv6ExtensionHopByHopHeader'])
     register_Ns3Ipv6ExtensionRoutingHeader_methods(root_module, root_module['ns3::Ipv6ExtensionRoutingHeader'])
     register_Ns3Ipv6OptionHeader_methods(root_module, root_module['ns3::Ipv6OptionHeader'])
     register_Ns3Ipv6OptionHeaderAlignment_methods(root_module, root_module['ns3::Ipv6OptionHeader::Alignment'])
@@ -249,6 +254,7 @@
     register_Ns3Ipv4L3Protocol_methods(root_module, root_module['ns3::Ipv4L3Protocol'])
     register_Ns3Ipv4L4Protocol_methods(root_module, root_module['ns3::Ipv4L4Protocol'])
     register_Ns3Ipv6ExtensionAHHeader_methods(root_module, root_module['ns3::Ipv6ExtensionAHHeader'])
+    register_Ns3Ipv6ExtensionDestinationHeader_methods(root_module, root_module['ns3::Ipv6ExtensionDestinationHeader'])
     register_Ns3Ipv6ExtensionESPHeader_methods(root_module, root_module['ns3::Ipv6ExtensionESPHeader'])
     register_Ns3Ipv6ExtensionFragmentHeader_methods(root_module, root_module['ns3::Ipv6ExtensionFragmentHeader'])
     register_Ns3Ipv6ExtensionLooseRoutingHeader_methods(root_module, root_module['ns3::Ipv6ExtensionLooseRoutingHeader'])
@@ -1481,6 +1487,43 @@
                    [param('uint8_t', 'nextHeader')])
     return
 
+def register_Ns3Ipv6ExtensionHopByHopHeader_methods(root_module, cls):
+    ## ipv6-extension-header.h: ns3::Ipv6ExtensionHopByHopHeader::Ipv6ExtensionHopByHopHeader(ns3::Ipv6ExtensionHopByHopHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Ipv6ExtensionHopByHopHeader const &', 'arg0')])
+    ## ipv6-extension-header.h: ns3::Ipv6ExtensionHopByHopHeader::Ipv6ExtensionHopByHopHeader() [constructor]
+    cls.add_constructor([])
+    ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionHopByHopHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## ipv6-extension-header.h: ns3::TypeId ns3::Ipv6ExtensionHopByHopHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionHopByHopHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ipv6-extension-header.h: static ns3::TypeId ns3::Ipv6ExtensionHopByHopHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## ipv6-extension-header.h: void ns3::Ipv6ExtensionHopByHopHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## ipv6-extension-header.h: void ns3::Ipv6ExtensionHopByHopHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    return
+
 def register_Ns3Ipv6ExtensionRoutingHeader_methods(root_module, cls):
     ## ipv6-extension-header.h: ns3::Ipv6ExtensionRoutingHeader::Ipv6ExtensionRoutingHeader(ns3::Ipv6ExtensionRoutingHeader const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Ipv6ExtensionRoutingHeader const &', 'arg0')])
@@ -2616,6 +2659,43 @@
                    is_const=True, is_virtual=True)
     return
 
+def register_Ns3Ipv6ExtensionDestinationHeader_methods(root_module, cls):
+    ## ipv6-extension-header.h: ns3::Ipv6ExtensionDestinationHeader::Ipv6ExtensionDestinationHeader(ns3::Ipv6ExtensionDestinationHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Ipv6ExtensionDestinationHeader const &', 'arg0')])
+    ## ipv6-extension-header.h: ns3::Ipv6ExtensionDestinationHeader::Ipv6ExtensionDestinationHeader() [constructor]
+    cls.add_constructor([])
+    ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionDestinationHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## ipv6-extension-header.h: ns3::TypeId ns3::Ipv6ExtensionDestinationHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionDestinationHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ipv6-extension-header.h: static ns3::TypeId ns3::Ipv6ExtensionDestinationHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## ipv6-extension-header.h: void ns3::Ipv6ExtensionDestinationHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## ipv6-extension-header.h: void ns3::Ipv6ExtensionDestinationHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    return
+
 def register_Ns3Ipv6ExtensionESPHeader_methods(root_module, cls):
     ## ipv6-extension-header.h: ns3::Ipv6ExtensionESPHeader::Ipv6ExtensionESPHeader(ns3::Ipv6ExtensionESPHeader const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Ipv6ExtensionESPHeader const &', 'arg0')])
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_mobility.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_mobility.py	Thu Feb 25 14:17:21 2010 +0100
@@ -4,7 +4,7 @@
     root_module = module.get_root()
     
     ## constant-velocity-helper.h: ns3::ConstantVelocityHelper [class]
-    module.add_class('ConstantVelocityHelper', allow_subclassing=False)
+    module.add_class('ConstantVelocityHelper')
     ## rectangle.h: ns3::Rectangle [class]
     module.add_class('Rectangle')
     ## rectangle.h: ns3::Rectangle::Side [enumeration]
@@ -39,6 +39,8 @@
     module.add_class('RectangleChecker', parent=root_module['ns3::AttributeChecker'])
     ## rectangle.h: ns3::RectangleValue [class]
     module.add_class('RectangleValue', parent=root_module['ns3::AttributeValue'])
+    ## steady-state-random-waypoint-mobility-model.h: ns3::SteadyStateRandomWaypointMobilityModel [class]
+    module.add_class('SteadyStateRandomWaypointMobilityModel', parent=root_module['ns3::MobilityModel'])
     ## waypoint.h: ns3::WaypointChecker [class]
     module.add_class('WaypointChecker', parent=root_module['ns3::AttributeChecker'])
     ## waypoint-mobility-model.h: ns3::WaypointMobilityModel [class]
@@ -150,6 +152,7 @@
     register_Ns3RandomWaypointMobilityModel_methods(root_module, root_module['ns3::RandomWaypointMobilityModel'])
     register_Ns3RectangleChecker_methods(root_module, root_module['ns3::RectangleChecker'])
     register_Ns3RectangleValue_methods(root_module, root_module['ns3::RectangleValue'])
+    register_Ns3SteadyStateRandomWaypointMobilityModel_methods(root_module, root_module['ns3::SteadyStateRandomWaypointMobilityModel'])
     register_Ns3WaypointChecker_methods(root_module, root_module['ns3::WaypointChecker'])
     register_Ns3WaypointMobilityModel_methods(root_module, root_module['ns3::WaypointMobilityModel'])
     register_Ns3WaypointValue_methods(root_module, root_module['ns3::WaypointValue'])
@@ -646,6 +649,38 @@
                    [param('ns3::Rectangle const &', 'value')])
     return
 
+def register_Ns3SteadyStateRandomWaypointMobilityModel_methods(root_module, cls):
+    ## steady-state-random-waypoint-mobility-model.h: ns3::SteadyStateRandomWaypointMobilityModel::SteadyStateRandomWaypointMobilityModel(ns3::SteadyStateRandomWaypointMobilityModel const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::SteadyStateRandomWaypointMobilityModel const &', 'arg0')])
+    ## steady-state-random-waypoint-mobility-model.h: ns3::SteadyStateRandomWaypointMobilityModel::SteadyStateRandomWaypointMobilityModel() [constructor]
+    cls.add_constructor([])
+    ## steady-state-random-waypoint-mobility-model.h: static ns3::TypeId ns3::SteadyStateRandomWaypointMobilityModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## steady-state-random-waypoint-mobility-model.h: void ns3::SteadyStateRandomWaypointMobilityModel::DoStart() [member function]
+    cls.add_method('DoStart', 
+                   'void', 
+                   [], 
+                   visibility='protected', is_virtual=True)
+    ## steady-state-random-waypoint-mobility-model.h: ns3::Vector ns3::SteadyStateRandomWaypointMobilityModel::DoGetPosition() const [member function]
+    cls.add_method('DoGetPosition', 
+                   'ns3::Vector', 
+                   [], 
+                   is_const=True, visibility='private', is_virtual=True)
+    ## steady-state-random-waypoint-mobility-model.h: ns3::Vector ns3::SteadyStateRandomWaypointMobilityModel::DoGetVelocity() const [member function]
+    cls.add_method('DoGetVelocity', 
+                   'ns3::Vector', 
+                   [], 
+                   is_const=True, visibility='private', is_virtual=True)
+    ## steady-state-random-waypoint-mobility-model.h: void ns3::SteadyStateRandomWaypointMobilityModel::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_Ns3WaypointChecker_methods(root_module, cls):
     ## waypoint.h: ns3::WaypointChecker::WaypointChecker() [constructor]
     cls.add_constructor([])
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_nix_vector_routing.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_nix_vector_routing.py	Thu Feb 25 14:17:21 2010 +0100
@@ -110,10 +110,10 @@
                    'ns3::TypeId', 
                    [], 
                    is_static=True)
-    ## ipv4-nix-vector-routing.h: void ns3::Ipv4NixVectorRouting::SetNode(ns3::Ptr<ns3::Node> arg0) [member function]
+    ## ipv4-nix-vector-routing.h: void ns3::Ipv4NixVectorRouting::SetNode(ns3::Ptr<ns3::Node> node) [member function]
     cls.add_method('SetNode', 
                    'void', 
-                   [param('ns3::Ptr< ns3::Node >', 'arg0')])
+                   [param('ns3::Ptr< ns3::Node >', 'node')])
     ## ipv4-nix-vector-routing.h: void ns3::Ipv4NixVectorRouting::DoDispose() [member function]
     cls.add_method('DoDispose', 
                    'void', 
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_node.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_node.py	Thu Feb 25 14:17:21 2010 +0100
@@ -73,6 +73,12 @@
     module.add_class('LlcSnapHeader', parent=root_module['ns3::Header'])
     ## queue.h: ns3::Queue [class]
     module.add_class('Queue', parent=root_module['ns3::Object'])
+    ## radiotap-header.h: ns3::RadiotapHeader [class]
+    module.add_class('RadiotapHeader', parent=root_module['ns3::Header'])
+    ## radiotap-header.h: ns3::RadiotapHeader [enumeration]
+    module.add_enum('', ['FRAME_FLAG_NONE', 'FRAME_FLAG_CFP', 'FRAME_FLAG_SHORT_PREAMBLE', 'FRAME_FLAG_WEP', 'FRAME_FLAG_FRAGMENTED', 'FRAME_FLAG_FCS_INCLUDED', 'FRAME_FLAG_DATA_PADDING', 'FRAME_FLAG_BAD_FCS', 'FRAME_FLAG_SHORT_GUARD'], outer_class=root_module['ns3::RadiotapHeader'])
+    ## radiotap-header.h: ns3::RadiotapHeader [enumeration]
+    module.add_enum('', ['CHANNEL_FLAG_NONE', 'CHANNEL_FLAG_TURBO', 'CHANNEL_FLAG_CCK', 'CHANNEL_FLAG_OFDM', 'CHANNEL_FLAG_SPECTRUM_2GHZ', 'CHANNEL_FLAG_SPECTRUM_5GHZ', 'CHANNEL_FLAG_PASSIVE', 'CHANNEL_FLAG_DYNAMIC', 'CHANNEL_FLAG_GFSK'], outer_class=root_module['ns3::RadiotapHeader'])
     ## simple-ref-count.h: ns3::SimpleRefCount<ns3::Ipv4MulticastRoute, ns3::empty, ns3::DefaultDeleter<ns3::Ipv4MulticastRoute> > [class]
     module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::Ipv4MulticastRoute', 'ns3::empty', 'ns3::DefaultDeleter<ns3::Ipv4MulticastRoute>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
     ## simple-ref-count.h: ns3::SimpleRefCount<ns3::Ipv4Route, ns3::empty, ns3::DefaultDeleter<ns3::Ipv4Route> > [class]
@@ -302,6 +308,7 @@
     register_Ns3Ipv6Header_methods(root_module, root_module['ns3::Ipv6Header'])
     register_Ns3LlcSnapHeader_methods(root_module, root_module['ns3::LlcSnapHeader'])
     register_Ns3Queue_methods(root_module, root_module['ns3::Queue'])
+    register_Ns3RadiotapHeader_methods(root_module, root_module['ns3::RadiotapHeader'])
     register_Ns3Socket_methods(root_module, root_module['ns3::Socket'])
     register_Ns3SocketAddressTag_methods(root_module, root_module['ns3::SocketAddressTag'])
     register_Ns3SocketFactory_methods(root_module, root_module['ns3::SocketFactory'])
@@ -1864,6 +1871,110 @@
                    is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
     return
 
+def register_Ns3RadiotapHeader_methods(root_module, cls):
+    ## radiotap-header.h: ns3::RadiotapHeader::RadiotapHeader(ns3::RadiotapHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::RadiotapHeader const &', 'arg0')])
+    ## radiotap-header.h: ns3::RadiotapHeader::RadiotapHeader() [constructor]
+    cls.add_constructor([])
+    ## radiotap-header.h: uint32_t ns3::RadiotapHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## radiotap-header.h: uint8_t ns3::RadiotapHeader::GetAntennaNoisePower() const [member function]
+    cls.add_method('GetAntennaNoisePower', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## radiotap-header.h: uint8_t ns3::RadiotapHeader::GetAntennaSignalPower() const [member function]
+    cls.add_method('GetAntennaSignalPower', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## radiotap-header.h: uint16_t ns3::RadiotapHeader::GetChannelFlags() const [member function]
+    cls.add_method('GetChannelFlags', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## radiotap-header.h: uint16_t ns3::RadiotapHeader::GetChannelFrequency() const [member function]
+    cls.add_method('GetChannelFrequency', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## radiotap-header.h: uint8_t ns3::RadiotapHeader::GetFrameFlags() const [member function]
+    cls.add_method('GetFrameFlags', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## radiotap-header.h: ns3::TypeId ns3::RadiotapHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## radiotap-header.h: uint8_t ns3::RadiotapHeader::GetRate() const [member function]
+    cls.add_method('GetRate', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## radiotap-header.h: uint32_t ns3::RadiotapHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## radiotap-header.h: uint64_t ns3::RadiotapHeader::GetTsft() const [member function]
+    cls.add_method('GetTsft', 
+                   'uint64_t', 
+                   [], 
+                   is_const=True)
+    ## radiotap-header.h: static ns3::TypeId ns3::RadiotapHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## radiotap-header.h: void ns3::RadiotapHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## radiotap-header.h: void ns3::RadiotapHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetAntennaNoisePower(int8_t noise) [member function]
+    cls.add_method('SetAntennaNoisePower', 
+                   'void', 
+                   [param('int8_t', 'noise')])
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetAntennaNoisePower(double noise) [member function]
+    cls.add_method('SetAntennaNoisePower', 
+                   'void', 
+                   [param('double', 'noise')])
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetAntennaSignalPower(int8_t signal) [member function]
+    cls.add_method('SetAntennaSignalPower', 
+                   'void', 
+                   [param('int8_t', 'signal')])
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetAntennaSignalPower(double signal) [member function]
+    cls.add_method('SetAntennaSignalPower', 
+                   'void', 
+                   [param('double', 'signal')])
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetChannelFrequencyAndFlags(uint16_t frequency, uint16_t flags) [member function]
+    cls.add_method('SetChannelFrequencyAndFlags', 
+                   'void', 
+                   [param('uint16_t', 'frequency'), param('uint16_t', 'flags')])
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetFrameFlags(uint8_t flags) [member function]
+    cls.add_method('SetFrameFlags', 
+                   'void', 
+                   [param('uint8_t', 'flags')])
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetRate(uint8_t rate) [member function]
+    cls.add_method('SetRate', 
+                   'void', 
+                   [param('uint8_t', 'rate')])
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetTsft(uint64_t tsft) [member function]
+    cls.add_method('SetTsft', 
+                   'void', 
+                   [param('uint64_t', 'tsft')])
+    return
+
 def register_Ns3Socket_methods(root_module, cls):
     ## socket.h: ns3::Socket::Socket(ns3::Socket const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Socket const &', 'arg0')])
@@ -4580,11 +4691,6 @@
                    'int', 
                    [], 
                    is_const=True)
-    ## packetbb.h: void ns3::PbbPacket::SerializePacketTlv(ns3::Buffer::Iterator & start) const [member function]
-    cls.add_method('SerializePacketTlv', 
-                   'void', 
-                   [param('ns3::Buffer::Iterator &', 'start')], 
-                   is_const=True, visibility='protected')
     return
 
 def register_Ns3PbbTlv_methods(root_module, cls):
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_olsr.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_olsr.py	Thu Feb 25 14:17:21 2010 +0100
@@ -133,6 +133,7 @@
     module.add_class('TwoHopNeighborTuple')
     module.add_container('std::vector< ns3::olsr::MessageHeader::Hello::LinkMessage >', 'ns3::olsr::MessageHeader::Hello::LinkMessage', container_type='vector')
     module.add_container('std::vector< ns3::olsr::MessageHeader::Hna::Association >', 'ns3::olsr::MessageHeader::Hna::Association', container_type='vector')
+    module.add_container('std::vector< ns3::olsr::RoutingTableEntry >', 'ns3::olsr::RoutingTableEntry', container_type='vector')
     typehandlers.add_type_alias('std::vector< ns3::olsr::DuplicateTuple, std::allocator< ns3::olsr::DuplicateTuple > >', 'ns3::olsr::DuplicateSet')
     typehandlers.add_type_alias('std::vector< ns3::olsr::DuplicateTuple, std::allocator< ns3::olsr::DuplicateTuple > >*', 'ns3::olsr::DuplicateSet*')
     typehandlers.add_type_alias('std::vector< ns3::olsr::DuplicateTuple, std::allocator< ns3::olsr::DuplicateTuple > >&', 'ns3::olsr::DuplicateSet&')
@@ -812,6 +813,11 @@
     cls.add_method('Dump', 
                    'void', 
                    [])
+    ## olsr-routing-protocol.h: std::vector<ns3::olsr::RoutingTableEntry,std::allocator<ns3::olsr::RoutingTableEntry> > ns3::olsr::RoutingProtocol::GetRoutingTableEntries() const [member function]
+    cls.add_method('GetRoutingTableEntries', 
+                   'std::vector< ns3::olsr::RoutingTableEntry >', 
+                   [], 
+                   is_const=True)
     ## olsr-routing-protocol.h: static ns3::TypeId ns3::olsr::RoutingProtocol::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_point_to_point.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_point_to_point.py	Thu Feb 25 14:17:21 2010 +0100
@@ -235,6 +235,11 @@
                    'ns3::Ptr< ns3::Node >', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## point-to-point-net-device.h: ns3::Ptr<ns3::Queue> ns3::PointToPointNetDevice::GetQueue() const [member function]
+    cls.add_method('GetQueue', 
+                   'ns3::Ptr< ns3::Queue >', 
+                   [], 
+                   is_const=True)
     ## point-to-point-net-device.h: static ns3::TypeId ns3::PointToPointNetDevice::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_stats.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_stats.py	Thu Feb 25 14:17:21 2010 +0100
@@ -13,8 +13,12 @@
     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'], root_module['ns3::StatisticalSummary']])
     ## 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]
@@ -116,7 +120,9 @@
     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 >'])
@@ -364,6 +370,67 @@
                    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: long int ns3::MinMaxAvgTotalCalculator<unsigned int>::getCount() const [member function]
+    cls.add_method('getCount', 
+                   'long int', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator<unsigned int>::getMax() const [member function]
+    cls.add_method('getMax', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator<unsigned int>::getMean() const [member function]
+    cls.add_method('getMean', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator<unsigned int>::getMin() const [member function]
+    cls.add_method('getMin', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator<unsigned int>::getSqrSum() const [member function]
+    cls.add_method('getSqrSum', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator<unsigned int>::getStddev() const [member function]
+    cls.add_method('getStddev', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator<unsigned int>::getSum() const [member function]
+    cls.add_method('getSum', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator<unsigned int>::getVariance() const [member function]
+    cls.add_method('getVariance', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## 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')])
@@ -381,6 +448,26 @@
                    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')])
--- a/bindings/python/apidefs/gcc-ILP32/ns3_module_wifi.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_wifi.py	Thu Feb 25 14:17:21 2010 +0100
@@ -15,6 +15,14 @@
     module.add_enum('AccessClass', ['AC_VO', 'AC_VI', 'AC_BE', 'AC_BK', 'AC_BE_NQOS', 'AC_UNDEF'])
     ## edca-txop-n.h: ns3::TypeOfStation [enumeration]
     module.add_enum('TypeOfStation', ['STA', 'AP', 'ADHOC_STA'])
+    ## ctrl-headers.h: ns3::BlockAckType [enumeration]
+    module.add_enum('BlockAckType', ['BASIC_BLOCK_ACK', 'COMPRESSED_BLOCK_ACK', 'MULTI_TID_BLOCK_ACK'])
+    ## block-ack-manager.h: ns3::Bar [struct]
+    module.add_class('Bar')
+    ## block-ack-agreement.h: ns3::BlockAckAgreement [class]
+    module.add_class('BlockAckAgreement')
+    ## block-ack-manager.h: ns3::BlockAckManager [class]
+    module.add_class('BlockAckManager')
     ## capability-information.h: ns3::CapabilityInformation [class]
     module.add_class('CapabilityInformation')
     ## dcf-manager.h: ns3::DcfManager [class]
@@ -22,9 +30,11 @@
     ## dcf-manager.h: ns3::DcfState [class]
     module.add_class('DcfState', allow_subclassing=True)
     ## interference-helper.h: ns3::InterferenceHelper [class]
-    module.add_class('InterferenceHelper', allow_subclassing=False)
+    module.add_class('InterferenceHelper')
     ## interference-helper.h: ns3::InterferenceHelper::SnrPer [struct]
     module.add_class('SnrPer', outer_class=root_module['ns3::InterferenceHelper'])
+    ## mac-low.h: ns3::MacLowBlockAckEventListener [class]
+    module.add_class('MacLowBlockAckEventListener', allow_subclassing=True)
     ## mac-low.h: ns3::MacLowDcfListener [class]
     module.add_class('MacLowDcfListener', allow_subclassing=True)
     ## mac-low.h: ns3::MacLowTransmissionListener [class]
@@ -33,6 +43,10 @@
     module.add_class('MacLowTransmissionParameters')
     ## mac-rx-middle.h: ns3::MacRxMiddle [class]
     module.add_class('MacRxMiddle')
+    ## originator-block-ack-agreement.h: ns3::OriginatorBlockAckAgreement [class]
+    module.add_class('OriginatorBlockAckAgreement', parent=root_module['ns3::BlockAckAgreement'])
+    ## originator-block-ack-agreement.h: ns3::OriginatorBlockAckAgreement::State [enumeration]
+    module.add_enum('State', ['PENDING', 'ESTABLISHED', 'INACTIVE', 'UNSUCCESSFUL'], outer_class=root_module['ns3::OriginatorBlockAckAgreement'])
     ## minstrel-wifi-manager.h: ns3::RateInfo [struct]
     module.add_class('RateInfo')
     ## ssid.h: ns3::Ssid [class]
@@ -46,7 +60,7 @@
     ## wifi-mode.h: ns3::WifiMode [class]
     module.add_class('WifiMode')
     ## wifi-mode.h: ns3::WifiMode::ModulationType [enumeration]
-    module.add_enum('ModulationType', ['BPSK', 'DBPSK', 'DQPSK', 'QAM', 'UNKNOWN'], outer_class=root_module['ns3::WifiMode'])
+    module.add_enum('ModulationType', ['BPSK', 'QPSK', 'DBPSK', 'DQPSK', 'QAM', 'UNKNOWN'], outer_class=root_module['ns3::WifiMode'])
     ## wifi-mode.h: ns3::WifiModeFactory [class]
     module.add_class('WifiModeFactory')
     ## wifi-phy.h: ns3::WifiPhyListener [class]
@@ -61,10 +75,16 @@
     module.add_class('ConstantRateWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation'])
     ## ideal-wifi-manager.h: ns3::IdealWifiRemoteStation [class]
     module.add_class('IdealWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation'])
+    ## mgt-headers.h: ns3::MgtAddBaRequestHeader [class]
+    module.add_class('MgtAddBaRequestHeader', parent=root_module['ns3::Header'])
+    ## mgt-headers.h: ns3::MgtAddBaResponseHeader [class]
+    module.add_class('MgtAddBaResponseHeader', parent=root_module['ns3::Header'])
     ## mgt-headers.h: ns3::MgtAssocRequestHeader [class]
     module.add_class('MgtAssocRequestHeader', parent=root_module['ns3::Header'])
     ## mgt-headers.h: ns3::MgtAssocResponseHeader [class]
     module.add_class('MgtAssocResponseHeader', parent=root_module['ns3::Header'])
+    ## mgt-headers.h: ns3::MgtDelBaHeader [class]
+    module.add_class('MgtDelBaHeader', parent=root_module['ns3::Header'])
     ## mgt-headers.h: ns3::MgtProbeRequestHeader [class]
     module.add_class('MgtProbeRequestHeader', parent=root_module['ns3::Header'])
     ## mgt-headers.h: ns3::MgtProbeResponseHeader [class]
@@ -73,26 +93,16 @@
     module.add_class('MinstrelWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation'])
     ## onoe-wifi-manager.h: ns3::OnoeWifiRemoteStation [class]
     module.add_class('OnoeWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation'])
-    ## propagation-delay-model.h: ns3::PropagationDelayModel [class]
-    module.add_class('PropagationDelayModel', parent=root_module['ns3::Object'])
-    ## propagation-loss-model.h: ns3::PropagationLossModel [class]
-    module.add_class('PropagationLossModel', parent=root_module['ns3::Object'])
     ## qos-tag.h: ns3::QosTag [class]
     module.add_class('QosTag', parent=root_module['ns3::Tag'])
-    ## propagation-delay-model.h: ns3::RandomPropagationDelayModel [class]
-    module.add_class('RandomPropagationDelayModel', parent=root_module['ns3::PropagationDelayModel'])
-    ## propagation-loss-model.h: ns3::RandomPropagationLossModel [class]
-    module.add_class('RandomPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## rraa-wifi-manager.h: ns3::RraaWifiRemoteStation [class]
     module.add_class('RraaWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation'])
     ## simple-ref-count.h: ns3::SimpleRefCount<ns3::InterferenceHelper::Event, ns3::empty, ns3::DefaultDeleter<ns3::InterferenceHelper::Event> > [class]
     module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::InterferenceHelper::Event', 'ns3::empty', 'ns3::DefaultDeleter<ns3::InterferenceHelper::Event>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
-    ## propagation-loss-model.h: ns3::ThreeLogDistancePropagationLossModel [class]
-    module.add_class('ThreeLogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## mgt-headers.h: ns3::WifiActionHeader [class]
     module.add_class('WifiActionHeader', parent=root_module['ns3::Header'])
     ## mgt-headers.h: ns3::WifiActionHeader::CategoryValue [enumeration]
-    module.add_enum('CategoryValue', ['MESH_PEERING_MGT', 'MESH_LINK_METRIC', 'MESH_PATH_SELECTION', 'MESH_INTERWORKING', 'MESH_RESOURCE_COORDINATION', 'MESH_PROXY_FORWARDING'], outer_class=root_module['ns3::WifiActionHeader'])
+    module.add_enum('CategoryValue', ['BLOCK_ACK', 'MESH_PEERING_MGT', 'MESH_LINK_METRIC', 'MESH_PATH_SELECTION', 'MESH_INTERWORKING', 'MESH_RESOURCE_COORDINATION', 'MESH_PROXY_FORWARDING'], outer_class=root_module['ns3::WifiActionHeader'])
     ## mgt-headers.h: ns3::WifiActionHeader::PeerLinkMgtActionValue [enumeration]
     module.add_enum('PeerLinkMgtActionValue', ['PEER_LINK_OPEN', 'PEER_LINK_CONFIRM', 'PEER_LINK_CLOSE'], outer_class=root_module['ns3::WifiActionHeader'])
     ## mgt-headers.h: ns3::WifiActionHeader::LinkMetricActionValue [enumeration]
@@ -103,6 +113,8 @@
     module.add_enum('InterworkActionValue', ['PORTAL_ANNOUNCEMENT'], outer_class=root_module['ns3::WifiActionHeader'])
     ## mgt-headers.h: ns3::WifiActionHeader::ResourceCoordinationActionValue [enumeration]
     module.add_enum('ResourceCoordinationActionValue', ['CONGESTION_CONTROL_NOTIFICATION', 'MDA_SETUP_REQUEST', 'MDA_SETUP_REPLY', 'MDAOP_ADVERTISMENT_REQUEST', 'MDAOP_ADVERTISMENTS', 'MDAOP_SET_TEARDOWN', 'BEACON_TIMING_REQUEST', 'BEACON_TIMING_RESPONSE', 'TBTT_ADJUSTMENT_REQUEST', 'MESH_CHANNEL_SWITCH_ANNOUNCEMENT'], outer_class=root_module['ns3::WifiActionHeader'])
+    ## mgt-headers.h: ns3::WifiActionHeader::BlockAckActionValue [enumeration]
+    module.add_enum('BlockAckActionValue', ['BLOCK_ACK_ADDBA_REQUEST', 'BLOCK_ACK_ADDBA_RESPONSE', 'BLOCK_ACK_DELBA'], outer_class=root_module['ns3::WifiActionHeader'])
     ## mgt-headers.h: ns3::WifiActionHeader::ActionValue [union]
     module.add_class('ActionValue', outer_class=root_module['ns3::WifiActionHeader'])
     ## wifi-mac.h: ns3::WifiMac [class]
@@ -133,24 +145,18 @@
     module.add_class('ArfWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
     ## constant-rate-wifi-manager.h: ns3::ConstantRateWifiManager [class]
     module.add_class('ConstantRateWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
-    ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel [class]
-    module.add_class('ConstantSpeedPropagationDelayModel', parent=root_module['ns3::PropagationDelayModel'])
+    ## ctrl-headers.h: ns3::CtrlBAckRequestHeader [class]
+    module.add_class('CtrlBAckRequestHeader', parent=root_module['ns3::Header'])
+    ## ctrl-headers.h: ns3::CtrlBAckResponseHeader [class]
+    module.add_class('CtrlBAckResponseHeader', parent=root_module['ns3::Header'])
     ## dcf.h: ns3::Dcf [class]
     module.add_class('Dcf', parent=root_module['ns3::Object'])
     ## edca-txop-n.h: ns3::EdcaTxopN [class]
     module.add_class('EdcaTxopN', parent=root_module['ns3::Dcf'])
     ## error-rate-model.h: ns3::ErrorRateModel [class]
     module.add_class('ErrorRateModel', parent=root_module['ns3::Object'])
-    ## propagation-loss-model.h: ns3::FixedRssLossModel [class]
-    module.add_class('FixedRssLossModel', parent=root_module['ns3::PropagationLossModel'])
-    ## propagation-loss-model.h: ns3::FriisPropagationLossModel [class]
-    module.add_class('FriisPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## ideal-wifi-manager.h: ns3::IdealWifiManager [class]
     module.add_class('IdealWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
-    ## jakes-propagation-loss-model.h: ns3::JakesPropagationLossModel [class]
-    module.add_class('JakesPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
-    ## propagation-loss-model.h: ns3::LogDistancePropagationLossModel [class]
-    module.add_class('LogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## mac-low.h: ns3::MacLow [class]
     module.add_class('MacLow', parent=root_module['ns3::Object'])
     ## mgt-headers.h: ns3::MgtBeaconHeader [class]
@@ -159,8 +165,6 @@
     module.add_class('MinstrelWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
     ## msdu-aggregator.h: ns3::MsduAggregator [class]
     module.add_class('MsduAggregator', parent=root_module['ns3::Object'])
-    ## propagation-loss-model.h: ns3::NakagamiPropagationLossModel [class]
-    module.add_class('NakagamiPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## nqap-wifi-mac.h: ns3::NqapWifiMac [class]
     module.add_class('NqapWifiMac', parent=root_module['ns3::WifiMac'])
     ## nqsta-wifi-mac.h: ns3::NqstaWifiMac [class]
@@ -286,15 +290,20 @@
     
 
 def register_methods(root_module):
+    register_Ns3Bar_methods(root_module, root_module['ns3::Bar'])
+    register_Ns3BlockAckAgreement_methods(root_module, root_module['ns3::BlockAckAgreement'])
+    register_Ns3BlockAckManager_methods(root_module, root_module['ns3::BlockAckManager'])
     register_Ns3CapabilityInformation_methods(root_module, root_module['ns3::CapabilityInformation'])
     register_Ns3DcfManager_methods(root_module, root_module['ns3::DcfManager'])
     register_Ns3DcfState_methods(root_module, root_module['ns3::DcfState'])
     register_Ns3InterferenceHelper_methods(root_module, root_module['ns3::InterferenceHelper'])
     register_Ns3InterferenceHelperSnrPer_methods(root_module, root_module['ns3::InterferenceHelper::SnrPer'])
+    register_Ns3MacLowBlockAckEventListener_methods(root_module, root_module['ns3::MacLowBlockAckEventListener'])
     register_Ns3MacLowDcfListener_methods(root_module, root_module['ns3::MacLowDcfListener'])
     register_Ns3MacLowTransmissionListener_methods(root_module, root_module['ns3::MacLowTransmissionListener'])
     register_Ns3MacLowTransmissionParameters_methods(root_module, root_module['ns3::MacLowTransmissionParameters'])
     register_Ns3MacRxMiddle_methods(root_module, root_module['ns3::MacRxMiddle'])
+    register_Ns3OriginatorBlockAckAgreement_methods(root_module, root_module['ns3::OriginatorBlockAckAgreement'])
     register_Ns3RateInfo_methods(root_module, root_module['ns3::RateInfo'])
     register_Ns3Ssid_methods(root_module, root_module['ns3::Ssid'])
     register_Ns3StatusCode_methods(root_module, root_module['ns3::StatusCode'])
@@ -308,19 +317,17 @@
     register_Ns3ArfWifiRemoteStation_methods(root_module, root_module['ns3::ArfWifiRemoteStation'])
     register_Ns3ConstantRateWifiRemoteStation_methods(root_module, root_module['ns3::ConstantRateWifiRemoteStation'])
     register_Ns3IdealWifiRemoteStation_methods(root_module, root_module['ns3::IdealWifiRemoteStation'])
+    register_Ns3MgtAddBaRequestHeader_methods(root_module, root_module['ns3::MgtAddBaRequestHeader'])
+    register_Ns3MgtAddBaResponseHeader_methods(root_module, root_module['ns3::MgtAddBaResponseHeader'])
     register_Ns3MgtAssocRequestHeader_methods(root_module, root_module['ns3::MgtAssocRequestHeader'])
     register_Ns3MgtAssocResponseHeader_methods(root_module, root_module['ns3::MgtAssocResponseHeader'])
+    register_Ns3MgtDelBaHeader_methods(root_module, root_module['ns3::MgtDelBaHeader'])
     register_Ns3MgtProbeRequestHeader_methods(root_module, root_module['ns3::MgtProbeRequestHeader'])
     register_Ns3MgtProbeResponseHeader_methods(root_module, root_module['ns3::MgtProbeResponseHeader'])
     register_Ns3MinstrelWifiRemoteStation_methods(root_module, root_module['ns3::MinstrelWifiRemoteStation'])
     register_Ns3OnoeWifiRemoteStation_methods(root_module, root_module['ns3::OnoeWifiRemoteStation'])
-    register_Ns3PropagationDelayModel_methods(root_module, root_module['ns3::PropagationDelayModel'])
-    register_Ns3PropagationLossModel_methods(root_module, root_module['ns3::PropagationLossModel'])
     register_Ns3QosTag_methods(root_module, root_module['ns3::QosTag'])
-    register_Ns3RandomPropagationDelayModel_methods(root_module, root_module['ns3::RandomPropagationDelayModel'])
-    register_Ns3RandomPropagationLossModel_methods(root_module, root_module['ns3::RandomPropagationLossModel'])
     register_Ns3RraaWifiRemoteStation_methods(root_module, root_module['ns3::RraaWifiRemoteStation'])
-    register_Ns3ThreeLogDistancePropagationLossModel_methods(root_module, root_module['ns3::ThreeLogDistancePropagationLossModel'])
     register_Ns3WifiActionHeader_methods(root_module, root_module['ns3::WifiActionHeader'])
     register_Ns3WifiActionHeaderActionValue_methods(root_module, root_module['ns3::WifiActionHeader::ActionValue'])
     register_Ns3WifiMac_methods(root_module, root_module['ns3::WifiMac'])
@@ -334,20 +341,16 @@
     register_Ns3AmsduSubframeHeader_methods(root_module, root_module['ns3::AmsduSubframeHeader'])
     register_Ns3ArfWifiManager_methods(root_module, root_module['ns3::ArfWifiManager'])
     register_Ns3ConstantRateWifiManager_methods(root_module, root_module['ns3::ConstantRateWifiManager'])
-    register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, root_module['ns3::ConstantSpeedPropagationDelayModel'])
+    register_Ns3CtrlBAckRequestHeader_methods(root_module, root_module['ns3::CtrlBAckRequestHeader'])
+    register_Ns3CtrlBAckResponseHeader_methods(root_module, root_module['ns3::CtrlBAckResponseHeader'])
     register_Ns3Dcf_methods(root_module, root_module['ns3::Dcf'])
     register_Ns3EdcaTxopN_methods(root_module, root_module['ns3::EdcaTxopN'])
     register_Ns3ErrorRateModel_methods(root_module, root_module['ns3::ErrorRateModel'])
-    register_Ns3FixedRssLossModel_methods(root_module, root_module['ns3::FixedRssLossModel'])
-    register_Ns3FriisPropagationLossModel_methods(root_module, root_module['ns3::FriisPropagationLossModel'])
     register_Ns3IdealWifiManager_methods(root_module, root_module['ns3::IdealWifiManager'])
-    register_Ns3JakesPropagationLossModel_methods(root_module, root_module['ns3::JakesPropagationLossModel'])
-    register_Ns3LogDistancePropagationLossModel_methods(root_module, root_module['ns3::LogDistancePropagationLossModel'])
     register_Ns3MacLow_methods(root_module, root_module['ns3::MacLow'])
     register_Ns3MgtBeaconHeader_methods(root_module, root_module['ns3::MgtBeaconHeader'])
     register_Ns3MinstrelWifiManager_methods(root_module, root_module['ns3::MinstrelWifiManager'])
     register_Ns3MsduAggregator_methods(root_module, root_module['ns3::MsduAggregator'])
-    register_Ns3NakagamiPropagationLossModel_methods(root_module, root_module['ns3::NakagamiPropagationLossModel'])
     register_Ns3NqapWifiMac_methods(root_module, root_module['ns3::NqapWifiMac'])
     register_Ns3NqstaWifiMac_methods(root_module, root_module['ns3::NqstaWifiMac'])
     register_Ns3OnoeWifiManager_methods(root_module, root_module['ns3::OnoeWifiManager'])
@@ -367,6 +370,216 @@
     register_Ns3DcaTxop_methods(root_module, root_module['ns3::DcaTxop'])
     return
 
+def register_Ns3Bar_methods(root_module, cls):
+    ## block-ack-manager.h: ns3::Bar::Bar(ns3::Bar const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Bar const &', 'arg0')])
+    ## block-ack-manager.h: ns3::Bar::Bar() [constructor]
+    cls.add_constructor([])
+    ## block-ack-manager.h: ns3::Bar::Bar(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address recipient, uint8_t tid, bool immediate) [constructor]
+    cls.add_constructor([param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('bool', 'immediate')])
+    ## block-ack-manager.h: ns3::Bar::bar [variable]
+    cls.add_instance_attribute('bar', 'ns3::Ptr< ns3::Packet const >', is_const=False)
+    ## block-ack-manager.h: ns3::Bar::immediate [variable]
+    cls.add_instance_attribute('immediate', 'bool', is_const=False)
+    ## block-ack-manager.h: ns3::Bar::recipient [variable]
+    cls.add_instance_attribute('recipient', 'ns3::Mac48Address', is_const=False)
+    ## block-ack-manager.h: ns3::Bar::tid [variable]
+    cls.add_instance_attribute('tid', 'uint8_t', is_const=False)
+    return
+
+def register_Ns3BlockAckAgreement_methods(root_module, cls):
+    ## block-ack-agreement.h: ns3::BlockAckAgreement::BlockAckAgreement(ns3::BlockAckAgreement const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::BlockAckAgreement const &', 'arg0')])
+    ## block-ack-agreement.h: ns3::BlockAckAgreement::BlockAckAgreement() [constructor]
+    cls.add_constructor([])
+    ## block-ack-agreement.h: ns3::BlockAckAgreement::BlockAckAgreement(ns3::Mac48Address peer, uint8_t tid) [constructor]
+    cls.add_constructor([param('ns3::Mac48Address', 'peer'), param('uint8_t', 'tid')])
+    ## block-ack-agreement.h: uint16_t ns3::BlockAckAgreement::GetBufferSize() const [member function]
+    cls.add_method('GetBufferSize', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: ns3::Mac48Address ns3::BlockAckAgreement::GetPeer() const [member function]
+    cls.add_method('GetPeer', 
+                   'ns3::Mac48Address', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: uint16_t ns3::BlockAckAgreement::GetStartingSequence() const [member function]
+    cls.add_method('GetStartingSequence', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: uint16_t ns3::BlockAckAgreement::GetStartingSequenceControl() const [member function]
+    cls.add_method('GetStartingSequenceControl', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: uint8_t ns3::BlockAckAgreement::GetTid() const [member function]
+    cls.add_method('GetTid', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: uint16_t ns3::BlockAckAgreement::GetTimeout() const [member function]
+    cls.add_method('GetTimeout', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: bool ns3::BlockAckAgreement::IsAmsduSupported() const [member function]
+    cls.add_method('IsAmsduSupported', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: bool ns3::BlockAckAgreement::IsImmediateBlockAck() const [member function]
+    cls.add_method('IsImmediateBlockAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: void ns3::BlockAckAgreement::SetAmsduSupport(bool supported) [member function]
+    cls.add_method('SetAmsduSupport', 
+                   'void', 
+                   [param('bool', 'supported')])
+    ## block-ack-agreement.h: void ns3::BlockAckAgreement::SetBufferSize(uint16_t bufferSize) [member function]
+    cls.add_method('SetBufferSize', 
+                   'void', 
+                   [param('uint16_t', 'bufferSize')])
+    ## block-ack-agreement.h: void ns3::BlockAckAgreement::SetDelayedBlockAck() [member function]
+    cls.add_method('SetDelayedBlockAck', 
+                   'void', 
+                   [])
+    ## block-ack-agreement.h: void ns3::BlockAckAgreement::SetImmediateBlockAck() [member function]
+    cls.add_method('SetImmediateBlockAck', 
+                   'void', 
+                   [])
+    ## block-ack-agreement.h: void ns3::BlockAckAgreement::SetStartingSequence(uint16_t seq) [member function]
+    cls.add_method('SetStartingSequence', 
+                   'void', 
+                   [param('uint16_t', 'seq')])
+    ## block-ack-agreement.h: void ns3::BlockAckAgreement::SetTimeout(uint16_t timeout) [member function]
+    cls.add_method('SetTimeout', 
+                   'void', 
+                   [param('uint16_t', 'timeout')])
+    return
+
+def register_Ns3BlockAckManager_methods(root_module, cls):
+    ## block-ack-manager.h: ns3::BlockAckManager::BlockAckManager() [constructor]
+    cls.add_constructor([])
+    ## block-ack-manager.h: void ns3::BlockAckManager::CreateAgreement(ns3::MgtAddBaRequestHeader const * reqHdr, ns3::Mac48Address recipient) [member function]
+    cls.add_method('CreateAgreement', 
+                   'void', 
+                   [param('ns3::MgtAddBaRequestHeader const *', 'reqHdr'), param('ns3::Mac48Address', 'recipient')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::DestroyAgreement(ns3::Mac48Address recipient, uint8_t tid) [member function]
+    cls.add_method('DestroyAgreement', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')])
+    ## block-ack-manager.h: bool ns3::BlockAckManager::ExistsAgreement(ns3::Mac48Address recipient, uint8_t tid) const [member function]
+    cls.add_method('ExistsAgreement', 
+                   'bool', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], 
+                   is_const=True)
+    ## block-ack-manager.h: bool ns3::BlockAckManager::ExistsAgreementInState(ns3::Mac48Address recipient, uint8_t tid, ns3::OriginatorBlockAckAgreement::State state) const [member function]
+    cls.add_method('ExistsAgreementInState', 
+                   'bool', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('ns3::OriginatorBlockAckAgreement::State', 'state')], 
+                   is_const=True)
+    ## block-ack-manager.h: uint32_t ns3::BlockAckManager::GetNBufferedPackets(ns3::Mac48Address recipient, uint8_t tid) const [member function]
+    cls.add_method('GetNBufferedPackets', 
+                   'uint32_t', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], 
+                   is_const=True)
+    ## block-ack-manager.h: uint32_t ns3::BlockAckManager::GetNRetryNeededPackets(ns3::Mac48Address recipient, uint8_t tid) const [member function]
+    cls.add_method('GetNRetryNeededPackets', 
+                   'uint32_t', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], 
+                   is_const=True)
+    ## block-ack-manager.h: ns3::Ptr<ns3::Packet const> ns3::BlockAckManager::GetNextPacket(ns3::WifiMacHeader & hdr) [member function]
+    cls.add_method('GetNextPacket', 
+                   'ns3::Ptr< ns3::Packet const >', 
+                   [param('ns3::WifiMacHeader &', 'hdr')])
+    ## block-ack-manager.h: uint32_t ns3::BlockAckManager::GetNextPacketSize() const [member function]
+    cls.add_method('GetNextPacketSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True)
+    ## block-ack-manager.h: bool ns3::BlockAckManager::HasBar(ns3::Bar & bar) [member function]
+    cls.add_method('HasBar', 
+                   'bool', 
+                   [param('ns3::Bar &', 'bar')])
+    ## block-ack-manager.h: bool ns3::BlockAckManager::HasOtherFragments(uint16_t sequenceNumber) const [member function]
+    cls.add_method('HasOtherFragments', 
+                   'bool', 
+                   [param('uint16_t', 'sequenceNumber')], 
+                   is_const=True)
+    ## block-ack-manager.h: bool ns3::BlockAckManager::HasPackets() const [member function]
+    cls.add_method('HasPackets', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## block-ack-manager.h: void ns3::BlockAckManager::NotifyAgreementEstablished(ns3::Mac48Address recipient, uint8_t tid, uint16_t startingSeq) [member function]
+    cls.add_method('NotifyAgreementEstablished', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('uint16_t', 'startingSeq')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::NotifyAgreementUnsuccessful(ns3::Mac48Address recipient, uint8_t tid) [member function]
+    cls.add_method('NotifyAgreementUnsuccessful', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::NotifyGotBlockAck(ns3::CtrlBAckResponseHeader const * blockAck, ns3::Mac48Address recipient) [member function]
+    cls.add_method('NotifyGotBlockAck', 
+                   'void', 
+                   [param('ns3::CtrlBAckResponseHeader const *', 'blockAck'), param('ns3::Mac48Address', 'recipient')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::NotifyMpduTransmission(ns3::Mac48Address recipient, uint8_t tid) [member function]
+    cls.add_method('NotifyMpduTransmission', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetBlockAckInactivityCallback(ns3::Callback<void, ns3::Mac48Address, unsigned char, bool, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
+    cls.add_method('SetBlockAckInactivityCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Mac48Address, unsigned char, bool, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetBlockAckThreshold(uint8_t nPackets) [member function]
+    cls.add_method('SetBlockAckThreshold', 
+                   'void', 
+                   [param('uint8_t', 'nPackets')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetBlockAckType(ns3::BlockAckType bAckType) [member function]
+    cls.add_method('SetBlockAckType', 
+                   'void', 
+                   [param('ns3::BlockAckType', 'bAckType')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetBlockDestinationCallback(ns3::Callback<void, ns3::Mac48Address, unsigned char, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
+    cls.add_method('SetBlockDestinationCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Mac48Address, unsigned char, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetMaxPacketDelay(ns3::Time maxDelay) [member function]
+    cls.add_method('SetMaxPacketDelay', 
+                   'void', 
+                   [param('ns3::Time', 'maxDelay')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetQueue(ns3::Ptr<ns3::WifiMacQueue> queue) [member function]
+    cls.add_method('SetQueue', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::WifiMacQueue >', 'queue')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetTxMiddle(ns3::MacTxMiddle * txMiddle) [member function]
+    cls.add_method('SetTxMiddle', 
+                   'void', 
+                   [param('ns3::MacTxMiddle *', 'txMiddle')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetUnblockDestinationCallback(ns3::Callback<void, ns3::Mac48Address, unsigned char, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
+    cls.add_method('SetUnblockDestinationCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Mac48Address, unsigned char, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::StorePacket(ns3::Ptr<ns3::Packet const> packet, ns3::WifiMacHeader const & hdr, ns3::Time tStamp) [member function]
+    cls.add_method('StorePacket', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const &', 'hdr'), param('ns3::Time', 'tStamp')])
+    ## block-ack-manager.h: bool ns3::BlockAckManager::SwitchToBlockAckIfNeeded(ns3::Mac48Address recipient, uint8_t tid, uint16_t startingSeq) [member function]
+    cls.add_method('SwitchToBlockAckIfNeeded', 
+                   'bool', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('uint16_t', 'startingSeq')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::TearDownBlockAck(ns3::Mac48Address recipient, uint8_t tid) [member function]
+    cls.add_method('TearDownBlockAck', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::UpdateAgreement(ns3::MgtAddBaResponseHeader const * respHdr, ns3::Mac48Address recipient) [member function]
+    cls.add_method('UpdateAgreement', 
+                   'void', 
+                   [param('ns3::MgtAddBaResponseHeader const *', 'respHdr'), param('ns3::Mac48Address', 'recipient')])
+    return
+
 def register_Ns3CapabilityInformation_methods(root_module, cls):
     ## capability-information.h: ns3::CapabilityInformation::CapabilityInformation(ns3::CapabilityInformation const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::CapabilityInformation const &', 'arg0')])
@@ -645,6 +858,18 @@
     cls.add_instance_attribute('snr', 'double', is_const=False)
     return
 
+def register_Ns3MacLowBlockAckEventListener_methods(root_module, cls):
+    ## mac-low.h: ns3::MacLowBlockAckEventListener::MacLowBlockAckEventListener(ns3::MacLowBlockAckEventListener const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::MacLowBlockAckEventListener const &', 'arg0')])
+    ## mac-low.h: ns3::MacLowBlockAckEventListener::MacLowBlockAckEventListener() [constructor]
+    cls.add_constructor([])
+    ## mac-low.h: void ns3::MacLowBlockAckEventListener::BlockAckInactivityTimeout(ns3::Mac48Address originator, uint8_t tid) [member function]
+    cls.add_method('BlockAckInactivityTimeout', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'originator'), param('uint8_t', 'tid')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
 def register_Ns3MacLowDcfListener_methods(root_module, cls):
     ## mac-low.h: ns3::MacLowDcfListener::MacLowDcfListener(ns3::MacLowDcfListener const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::MacLowDcfListener const &', 'arg0')])
@@ -697,6 +922,11 @@
                    'void', 
                    [param('double', 'snr'), param('ns3::WifiMode', 'txMode')], 
                    is_pure_virtual=True, is_virtual=True)
+    ## mac-low.h: void ns3::MacLowTransmissionListener::GotBlockAck(ns3::CtrlBAckResponseHeader const * blockAck, ns3::Mac48Address source) [member function]
+    cls.add_method('GotBlockAck', 
+                   'void', 
+                   [param('ns3::CtrlBAckResponseHeader const *', 'blockAck'), param('ns3::Mac48Address', 'source')], 
+                   is_virtual=True)
     ## mac-low.h: void ns3::MacLowTransmissionListener::GotCts(double snr, ns3::WifiMode txMode) [member function]
     cls.add_method('GotCts', 
                    'void', 
@@ -707,6 +937,11 @@
                    'void', 
                    [], 
                    is_pure_virtual=True, is_virtual=True)
+    ## mac-low.h: void ns3::MacLowTransmissionListener::MissedBlockAck() [member function]
+    cls.add_method('MissedBlockAck', 
+                   'void', 
+                   [], 
+                   is_virtual=True)
     ## mac-low.h: void ns3::MacLowTransmissionListener::MissedCts() [member function]
     cls.add_method('MissedCts', 
                    'void', 
@@ -745,10 +980,22 @@
     cls.add_method('EnableAck', 
                    'void', 
                    [])
+    ## mac-low.h: void ns3::MacLowTransmissionParameters::EnableBasicBlockAck() [member function]
+    cls.add_method('EnableBasicBlockAck', 
+                   'void', 
+                   [])
+    ## mac-low.h: void ns3::MacLowTransmissionParameters::EnableCompressedBlockAck() [member function]
+    cls.add_method('EnableCompressedBlockAck', 
+                   'void', 
+                   [])
     ## mac-low.h: void ns3::MacLowTransmissionParameters::EnableFastAck() [member function]
     cls.add_method('EnableFastAck', 
                    'void', 
                    [])
+    ## mac-low.h: void ns3::MacLowTransmissionParameters::EnableMultiTidBlockAck() [member function]
+    cls.add_method('EnableMultiTidBlockAck', 
+                   'void', 
+                   [])
     ## mac-low.h: void ns3::MacLowTransmissionParameters::EnableNextData(uint32_t size) [member function]
     cls.add_method('EnableNextData', 
                    'void', 
@@ -795,11 +1042,26 @@
                    'bool', 
                    [], 
                    is_const=True)
+    ## mac-low.h: bool ns3::MacLowTransmissionParameters::MustWaitBasicBlockAck() const [member function]
+    cls.add_method('MustWaitBasicBlockAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## mac-low.h: bool ns3::MacLowTransmissionParameters::MustWaitCompressedBlockAck() const [member function]
+    cls.add_method('MustWaitCompressedBlockAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
     ## mac-low.h: bool ns3::MacLowTransmissionParameters::MustWaitFastAck() const [member function]
     cls.add_method('MustWaitFastAck', 
                    'bool', 
                    [], 
                    is_const=True)
+    ## mac-low.h: bool ns3::MacLowTransmissionParameters::MustWaitMultiTidBlockAck() const [member function]
+    cls.add_method('MustWaitMultiTidBlockAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
     ## mac-low.h: bool ns3::MacLowTransmissionParameters::MustWaitNormalAck() const [member function]
     cls.add_method('MustWaitNormalAck', 
                    'bool', 
@@ -827,6 +1089,52 @@
                    [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::WifiMacHeader const *, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
     return
 
+def register_Ns3OriginatorBlockAckAgreement_methods(root_module, cls):
+    ## originator-block-ack-agreement.h: ns3::OriginatorBlockAckAgreement::OriginatorBlockAckAgreement(ns3::OriginatorBlockAckAgreement const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::OriginatorBlockAckAgreement const &', 'arg0')])
+    ## originator-block-ack-agreement.h: ns3::OriginatorBlockAckAgreement::OriginatorBlockAckAgreement() [constructor]
+    cls.add_constructor([])
+    ## originator-block-ack-agreement.h: ns3::OriginatorBlockAckAgreement::OriginatorBlockAckAgreement(ns3::Mac48Address recipient, uint8_t tid) [constructor]
+    cls.add_constructor([param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')])
+    ## originator-block-ack-agreement.h: void ns3::OriginatorBlockAckAgreement::CompleteExchange() [member function]
+    cls.add_method('CompleteExchange', 
+                   'void', 
+                   [])
+    ## originator-block-ack-agreement.h: bool ns3::OriginatorBlockAckAgreement::IsEstablished() const [member function]
+    cls.add_method('IsEstablished', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## originator-block-ack-agreement.h: bool ns3::OriginatorBlockAckAgreement::IsInactive() const [member function]
+    cls.add_method('IsInactive', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## originator-block-ack-agreement.h: bool ns3::OriginatorBlockAckAgreement::IsPending() const [member function]
+    cls.add_method('IsPending', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## originator-block-ack-agreement.h: bool ns3::OriginatorBlockAckAgreement::IsUnsuccessful() const [member function]
+    cls.add_method('IsUnsuccessful', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## originator-block-ack-agreement.h: bool ns3::OriginatorBlockAckAgreement::NeedBlockAckRequest() const [member function]
+    cls.add_method('NeedBlockAckRequest', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## originator-block-ack-agreement.h: void ns3::OriginatorBlockAckAgreement::NotifyMpduTransmission() [member function]
+    cls.add_method('NotifyMpduTransmission', 
+                   'void', 
+                   [])
+    ## originator-block-ack-agreement.h: void ns3::OriginatorBlockAckAgreement::SetState(ns3::OriginatorBlockAckAgreement::State state) [member function]
+    cls.add_method('SetState', 
+                   'void', 
+                   [param('ns3::OriginatorBlockAckAgreement::State', 'state')])
+    return
+
 def register_Ns3RateInfo_methods(root_module, cls):
     ## minstrel-wifi-manager.h: ns3::RateInfo::RateInfo() [constructor]
     cls.add_constructor([])
@@ -1093,6 +1401,11 @@
                    'ns3::WifiMode', 
                    [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate'), param('uint8_t', 'constellationSize'), param('ns3::WifiPhyStandard', 'standard')], 
                    is_static=True)
+    ## wifi-mode.h: static ns3::WifiMode ns3::WifiModeFactory::CreateQpsk(std::string uniqueName, bool isMandatory, uint32_t bandwidth, uint32_t dataRate, uint32_t phyRate, ns3::WifiPhyStandard standard) [member function]
+    cls.add_method('CreateQpsk', 
+                   'ns3::WifiMode', 
+                   [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate'), param('ns3::WifiPhyStandard', 'standard')], 
+                   is_static=True)
     return
 
 def register_Ns3WifiPhyListener_methods(root_module, cls):
@@ -1607,6 +1920,196 @@
                    is_const=True, visibility='private', is_virtual=True)
     return
 
+def register_Ns3MgtAddBaRequestHeader_methods(root_module, cls):
+    ## mgt-headers.h: ns3::MgtAddBaRequestHeader::MgtAddBaRequestHeader(ns3::MgtAddBaRequestHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::MgtAddBaRequestHeader const &', 'arg0')])
+    ## mgt-headers.h: ns3::MgtAddBaRequestHeader::MgtAddBaRequestHeader() [constructor]
+    cls.add_constructor([])
+    ## mgt-headers.h: uint32_t ns3::MgtAddBaRequestHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## mgt-headers.h: uint16_t ns3::MgtAddBaRequestHeader::GetBufferSize() const [member function]
+    cls.add_method('GetBufferSize', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: ns3::TypeId ns3::MgtAddBaRequestHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: uint32_t ns3::MgtAddBaRequestHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: uint16_t ns3::MgtAddBaRequestHeader::GetStartingSequence() const [member function]
+    cls.add_method('GetStartingSequence', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: uint8_t ns3::MgtAddBaRequestHeader::GetTid() const [member function]
+    cls.add_method('GetTid', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: uint16_t ns3::MgtAddBaRequestHeader::GetTimeout() const [member function]
+    cls.add_method('GetTimeout', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: static ns3::TypeId ns3::MgtAddBaRequestHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## mgt-headers.h: bool ns3::MgtAddBaRequestHeader::IsAmsduSupported() const [member function]
+    cls.add_method('IsAmsduSupported', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: bool ns3::MgtAddBaRequestHeader::IsImmediateBlockAck() const [member function]
+    cls.add_method('IsImmediateBlockAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::SetAmsduSupport(bool supported) [member function]
+    cls.add_method('SetAmsduSupport', 
+                   'void', 
+                   [param('bool', 'supported')])
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::SetBufferSize(uint16_t size) [member function]
+    cls.add_method('SetBufferSize', 
+                   'void', 
+                   [param('uint16_t', 'size')])
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::SetDelayedBlockAck() [member function]
+    cls.add_method('SetDelayedBlockAck', 
+                   'void', 
+                   [])
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::SetImmediateBlockAck() [member function]
+    cls.add_method('SetImmediateBlockAck', 
+                   'void', 
+                   [])
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::SetStartingSequence(uint16_t seq) [member function]
+    cls.add_method('SetStartingSequence', 
+                   'void', 
+                   [param('uint16_t', 'seq')])
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::SetTid(uint8_t tid) [member function]
+    cls.add_method('SetTid', 
+                   'void', 
+                   [param('uint8_t', 'tid')])
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::SetTimeout(uint16_t timeout) [member function]
+    cls.add_method('SetTimeout', 
+                   'void', 
+                   [param('uint16_t', 'timeout')])
+    return
+
+def register_Ns3MgtAddBaResponseHeader_methods(root_module, cls):
+    ## mgt-headers.h: ns3::MgtAddBaResponseHeader::MgtAddBaResponseHeader(ns3::MgtAddBaResponseHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::MgtAddBaResponseHeader const &', 'arg0')])
+    ## mgt-headers.h: ns3::MgtAddBaResponseHeader::MgtAddBaResponseHeader() [constructor]
+    cls.add_constructor([])
+    ## mgt-headers.h: uint32_t ns3::MgtAddBaResponseHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## mgt-headers.h: uint16_t ns3::MgtAddBaResponseHeader::GetBufferSize() const [member function]
+    cls.add_method('GetBufferSize', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: ns3::TypeId ns3::MgtAddBaResponseHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: uint32_t ns3::MgtAddBaResponseHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: ns3::StatusCode ns3::MgtAddBaResponseHeader::GetStatusCode() const [member function]
+    cls.add_method('GetStatusCode', 
+                   'ns3::StatusCode', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: uint8_t ns3::MgtAddBaResponseHeader::GetTid() const [member function]
+    cls.add_method('GetTid', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: uint16_t ns3::MgtAddBaResponseHeader::GetTimeout() const [member function]
+    cls.add_method('GetTimeout', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: static ns3::TypeId ns3::MgtAddBaResponseHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## mgt-headers.h: bool ns3::MgtAddBaResponseHeader::IsAmsduSupported() const [member function]
+    cls.add_method('IsAmsduSupported', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: bool ns3::MgtAddBaResponseHeader::IsImmediateBlockAck() const [member function]
+    cls.add_method('IsImmediateBlockAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::SetAmsduSupport(bool supported) [member function]
+    cls.add_method('SetAmsduSupport', 
+                   'void', 
+                   [param('bool', 'supported')])
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::SetBufferSize(uint16_t size) [member function]
+    cls.add_method('SetBufferSize', 
+                   'void', 
+                   [param('uint16_t', 'size')])
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::SetDelayedBlockAck() [member function]
+    cls.add_method('SetDelayedBlockAck', 
+                   'void', 
+                   [])
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::SetImmediateBlockAck() [member function]
+    cls.add_method('SetImmediateBlockAck', 
+                   'void', 
+                   [])
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::SetStatusCode(ns3::StatusCode code) [member function]
+    cls.add_method('SetStatusCode', 
+                   'void', 
+                   [param('ns3::StatusCode', 'code')])
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::SetTid(uint8_t tid) [member function]
+    cls.add_method('SetTid', 
+                   'void', 
+                   [param('uint8_t', 'tid')])
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::SetTimeout(uint16_t timeout) [member function]
+    cls.add_method('SetTimeout', 
+                   'void', 
+                   [param('uint16_t', 'timeout')])
+    return
+
 def register_Ns3MgtAssocRequestHeader_methods(root_module, cls):
     ## mgt-headers.h: ns3::MgtAssocRequestHeader::MgtAssocRequestHeader(ns3::MgtAssocRequestHeader const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::MgtAssocRequestHeader const &', 'arg0')])
@@ -1724,6 +2227,65 @@
                    [param('ns3::SupportedRates', 'rates')])
     return
 
+def register_Ns3MgtDelBaHeader_methods(root_module, cls):
+    ## mgt-headers.h: ns3::MgtDelBaHeader::MgtDelBaHeader(ns3::MgtDelBaHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::MgtDelBaHeader const &', 'arg0')])
+    ## mgt-headers.h: ns3::MgtDelBaHeader::MgtDelBaHeader() [constructor]
+    cls.add_constructor([])
+    ## mgt-headers.h: uint32_t ns3::MgtDelBaHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## mgt-headers.h: ns3::TypeId ns3::MgtDelBaHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: uint32_t ns3::MgtDelBaHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: uint8_t ns3::MgtDelBaHeader::GetTid() const [member function]
+    cls.add_method('GetTid', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: static ns3::TypeId ns3::MgtDelBaHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## mgt-headers.h: bool ns3::MgtDelBaHeader::IsByOriginator() const [member function]
+    cls.add_method('IsByOriginator', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: void ns3::MgtDelBaHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: void ns3::MgtDelBaHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: void ns3::MgtDelBaHeader::SetByOriginator() [member function]
+    cls.add_method('SetByOriginator', 
+                   'void', 
+                   [])
+    ## mgt-headers.h: void ns3::MgtDelBaHeader::SetByRecipient() [member function]
+    cls.add_method('SetByRecipient', 
+                   'void', 
+                   [])
+    ## mgt-headers.h: void ns3::MgtDelBaHeader::SetTid(uint8_t arg0) [member function]
+    cls.add_method('SetTid', 
+                   'void', 
+                   [param('uint8_t', 'arg0')])
+    return
+
 def register_Ns3MgtProbeRequestHeader_methods(root_module, cls):
     ## mgt-headers.h: ns3::MgtProbeRequestHeader::MgtProbeRequestHeader() [constructor]
     cls.add_constructor([])
@@ -1961,47 +2523,6 @@
                    is_const=True, visibility='private', is_virtual=True)
     return
 
-def register_Ns3PropagationDelayModel_methods(root_module, cls):
-    ## propagation-delay-model.h: ns3::PropagationDelayModel::PropagationDelayModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-delay-model.h: ns3::PropagationDelayModel::PropagationDelayModel(ns3::PropagationDelayModel const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::PropagationDelayModel const &', 'arg0')])
-    ## propagation-delay-model.h: ns3::Time ns3::PropagationDelayModel::GetDelay(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('GetDelay', 
-                   'ns3::Time', 
-                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_pure_virtual=True, is_const=True, is_virtual=True)
-    ## propagation-delay-model.h: static ns3::TypeId ns3::PropagationDelayModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    return
-
-def register_Ns3PropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: static ns3::TypeId ns3::PropagationLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## propagation-loss-model.h: ns3::PropagationLossModel::PropagationLossModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-loss-model.h: void ns3::PropagationLossModel::SetNext(ns3::Ptr<ns3::PropagationLossModel> next) [member function]
-    cls.add_method('SetNext', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::PropagationLossModel >', 'next')])
-    ## propagation-loss-model.h: double ns3::PropagationLossModel::CalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('CalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True)
-    ## propagation-loss-model.h: double ns3::PropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
-    return
-
 def register_Ns3QosTag_methods(root_module, cls):
     ## qos-tag.h: ns3::QosTag::QosTag(ns3::QosTag const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::QosTag const &', 'arg0')])
@@ -2054,38 +2575,6 @@
                    [param('ns3::UserPriority', 'up')])
     return
 
-def register_Ns3RandomPropagationDelayModel_methods(root_module, cls):
-    ## propagation-delay-model.h: ns3::RandomPropagationDelayModel::RandomPropagationDelayModel(ns3::RandomPropagationDelayModel const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::RandomPropagationDelayModel const &', 'arg0')])
-    ## propagation-delay-model.h: ns3::RandomPropagationDelayModel::RandomPropagationDelayModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-delay-model.h: ns3::Time ns3::RandomPropagationDelayModel::GetDelay(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('GetDelay', 
-                   'ns3::Time', 
-                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, is_virtual=True)
-    ## propagation-delay-model.h: static ns3::TypeId ns3::RandomPropagationDelayModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    return
-
-def register_Ns3RandomPropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: static ns3::TypeId ns3::RandomPropagationLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## propagation-loss-model.h: ns3::RandomPropagationLossModel::RandomPropagationLossModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-loss-model.h: double ns3::RandomPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, visibility='private', is_virtual=True)
-    return
-
 def register_Ns3RraaWifiRemoteStation_methods(root_module, cls):
     ## rraa-wifi-manager.h: ns3::RraaWifiRemoteStation::RraaWifiRemoteStation(ns3::RraaWifiRemoteStation const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::RraaWifiRemoteStation const &', 'arg0')])
@@ -2148,21 +2637,6 @@
                    is_const=True, visibility='private', is_virtual=True)
     return
 
-def register_Ns3ThreeLogDistancePropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: static ns3::TypeId ns3::ThreeLogDistancePropagationLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## propagation-loss-model.h: ns3::ThreeLogDistancePropagationLossModel::ThreeLogDistancePropagationLossModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-loss-model.h: double ns3::ThreeLogDistancePropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, visibility='private', is_virtual=True)
-    return
-
 def register_Ns3WifiActionHeader_methods(root_module, cls):
     ## mgt-headers.h: ns3::WifiActionHeader::WifiActionHeader(ns3::WifiActionHeader const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::WifiActionHeader const &', 'arg0')])
@@ -2217,6 +2691,8 @@
     cls.add_constructor([])
     ## mgt-headers.h: ns3::WifiActionHeader::ActionValue::ActionValue(ns3::WifiActionHeader::ActionValue const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::WifiActionHeader::ActionValue const &', 'arg0')])
+    ## mgt-headers.h: ns3::WifiActionHeader::ActionValue::blockAck [variable]
+    cls.add_instance_attribute('blockAck', 'ns3::WifiActionHeader::BlockAckActionValue', is_const=False)
     ## mgt-headers.h: ns3::WifiActionHeader::ActionValue::interwork [variable]
     cls.add_instance_attribute('interwork', 'ns3::WifiActionHeader::InterworkActionValue', is_const=False)
     ## mgt-headers.h: ns3::WifiActionHeader::ActionValue::linkMetrtic [variable]
@@ -2258,11 +2734,21 @@
                    'ns3::Mac48Address', 
                    [], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## wifi-mac.h: ns3::Time ns3::WifiMac::GetBasicBlockAckTimeout() const [member function]
+    cls.add_method('GetBasicBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
     ## wifi-mac.h: ns3::Mac48Address ns3::WifiMac::GetBssid() const [member function]
     cls.add_method('GetBssid', 
                    'ns3::Mac48Address', 
                    [], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## wifi-mac.h: ns3::Time ns3::WifiMac::GetCompressedBlockAckTimeout() const [member function]
+    cls.add_method('GetCompressedBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
     ## wifi-mac.h: ns3::Time ns3::WifiMac::GetCtsTimeout() const [member function]
     cls.add_method('GetCtsTimeout', 
                    'ns3::Time', 
@@ -2343,6 +2829,16 @@
                    'void', 
                    [param('ns3::Mac48Address', 'address')], 
                    is_pure_virtual=True, is_virtual=True)
+    ## wifi-mac.h: void ns3::WifiMac::SetBasicBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetBasicBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
+    ## wifi-mac.h: void ns3::WifiMac::SetCompressedBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetCompressedBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
     ## wifi-mac.h: void ns3::WifiMac::SetCtsTimeout(ns3::Time ctsTimeout) [member function]
     cls.add_method('SetCtsTimeout', 
                    'void', 
@@ -2554,6 +3050,16 @@
                    'bool', 
                    [], 
                    is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsBlockAck() const [member function]
+    cls.add_method('IsBlockAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsBlockAckReq() const [member function]
+    cls.add_method('IsBlockAckReq', 
+                   'bool', 
+                   [], 
+                   is_const=True)
     ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsCfpoll() const [member function]
     cls.add_method('IsCfpoll', 
                    'bool', 
@@ -2711,6 +3217,14 @@
     cls.add_method('SetBeacon', 
                    'void', 
                    [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetBlockAck() [member function]
+    cls.add_method('SetBlockAck', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetBlockAckReq() [member function]
+    cls.add_method('SetBlockAckReq', 
+                   'void', 
+                   [])
     ## wifi-mac-header.h: void ns3::WifiMacHeader::SetDsFrom() [member function]
     cls.add_method('SetDsFrom', 
                    'void', 
@@ -2771,10 +3285,18 @@
     cls.add_method('SetQosAmsdu', 
                    'void', 
                    [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosBlockAck() [member function]
+    cls.add_method('SetQosBlockAck', 
+                   'void', 
+                   [])
     ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosEosp() [member function]
     cls.add_method('SetQosEosp', 
                    'void', 
                    [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosNoAck() [member function]
+    cls.add_method('SetQosNoAck', 
+                   'void', 
+                   [])
     ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosNoAmsdu() [member function]
     cls.add_method('SetQosNoAmsdu', 
                    'void', 
@@ -2783,6 +3305,10 @@
     cls.add_method('SetQosNoEosp', 
                    'void', 
                    [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosNormalAck() [member function]
+    cls.add_method('SetQosNormalAck', 
+                   'void', 
+                   [])
     ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosTid(uint8_t tid) [member function]
     cls.add_method('SetQosTid', 
                    'void', 
@@ -3754,30 +4280,202 @@
                    visibility='private', is_virtual=True)
     return
 
-def register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, cls):
-    ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel::ConstantSpeedPropagationDelayModel(ns3::ConstantSpeedPropagationDelayModel const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::ConstantSpeedPropagationDelayModel const &', 'arg0')])
-    ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel::ConstantSpeedPropagationDelayModel() [constructor]
+def register_Ns3CtrlBAckRequestHeader_methods(root_module, cls):
+    ## ctrl-headers.h: ns3::CtrlBAckRequestHeader::CtrlBAckRequestHeader(ns3::CtrlBAckRequestHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::CtrlBAckRequestHeader const &', 'arg0')])
+    ## ctrl-headers.h: ns3::CtrlBAckRequestHeader::CtrlBAckRequestHeader() [constructor]
     cls.add_constructor([])
-    ## propagation-delay-model.h: ns3::Time ns3::ConstantSpeedPropagationDelayModel::GetDelay(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('GetDelay', 
-                   'ns3::Time', 
-                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, is_virtual=True)
-    ## propagation-delay-model.h: double ns3::ConstantSpeedPropagationDelayModel::GetSpeed() const [member function]
-    cls.add_method('GetSpeed', 
-                   'double', 
-                   [], 
-                   is_const=True)
-    ## propagation-delay-model.h: static ns3::TypeId ns3::ConstantSpeedPropagationDelayModel::GetTypeId() [member function]
+    ## ctrl-headers.h: uint32_t ns3::CtrlBAckRequestHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## ctrl-headers.h: ns3::TypeId ns3::CtrlBAckRequestHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: uint32_t ns3::CtrlBAckRequestHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: uint16_t ns3::CtrlBAckRequestHeader::GetStartingSequence() const [member function]
+    cls.add_method('GetStartingSequence', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: uint16_t ns3::CtrlBAckRequestHeader::GetStartingSequenceControl() const [member function]
+    cls.add_method('GetStartingSequenceControl', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: uint8_t ns3::CtrlBAckRequestHeader::GetTidInfo() const [member function]
+    cls.add_method('GetTidInfo', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: static ns3::TypeId ns3::CtrlBAckRequestHeader::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
                    [], 
                    is_static=True)
-    ## propagation-delay-model.h: void ns3::ConstantSpeedPropagationDelayModel::SetSpeed(double speed) [member function]
-    cls.add_method('SetSpeed', 
-                   'void', 
-                   [param('double', 'speed')])
+    ## ctrl-headers.h: bool ns3::CtrlBAckRequestHeader::IsBasic() const [member function]
+    cls.add_method('IsBasic', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckRequestHeader::IsCompressed() const [member function]
+    cls.add_method('IsCompressed', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckRequestHeader::IsMultiTid() const [member function]
+    cls.add_method('IsMultiTid', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckRequestHeader::MustSendHtImmediateAck() const [member function]
+    cls.add_method('MustSendHtImmediateAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: void ns3::CtrlBAckRequestHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: void ns3::CtrlBAckRequestHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: void ns3::CtrlBAckRequestHeader::SetHtImmediateAck(bool immediateAck) [member function]
+    cls.add_method('SetHtImmediateAck', 
+                   'void', 
+                   [param('bool', 'immediateAck')])
+    ## ctrl-headers.h: void ns3::CtrlBAckRequestHeader::SetStartingSequence(uint16_t seq) [member function]
+    cls.add_method('SetStartingSequence', 
+                   'void', 
+                   [param('uint16_t', 'seq')])
+    ## ctrl-headers.h: void ns3::CtrlBAckRequestHeader::SetTidInfo(uint8_t tid) [member function]
+    cls.add_method('SetTidInfo', 
+                   'void', 
+                   [param('uint8_t', 'tid')])
+    ## ctrl-headers.h: void ns3::CtrlBAckRequestHeader::SetType(ns3::BlockAckType type) [member function]
+    cls.add_method('SetType', 
+                   'void', 
+                   [param('ns3::BlockAckType', 'type')])
+    return
+
+def register_Ns3CtrlBAckResponseHeader_methods(root_module, cls):
+    ## ctrl-headers.h: ns3::CtrlBAckResponseHeader::CtrlBAckResponseHeader(ns3::CtrlBAckResponseHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::CtrlBAckResponseHeader const &', 'arg0')])
+    ## ctrl-headers.h: ns3::CtrlBAckResponseHeader::CtrlBAckResponseHeader() [constructor]
+    cls.add_constructor([])
+    ## ctrl-headers.h: uint32_t ns3::CtrlBAckResponseHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## ctrl-headers.h: ns3::TypeId ns3::CtrlBAckResponseHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: uint32_t ns3::CtrlBAckResponseHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: uint16_t ns3::CtrlBAckResponseHeader::GetStartingSequence() const [member function]
+    cls.add_method('GetStartingSequence', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: uint16_t ns3::CtrlBAckResponseHeader::GetStartingSequenceControl() const [member function]
+    cls.add_method('GetStartingSequenceControl', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: uint8_t ns3::CtrlBAckResponseHeader::GetTidInfo() const [member function]
+    cls.add_method('GetTidInfo', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: static ns3::TypeId ns3::CtrlBAckResponseHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckResponseHeader::IsBasic() const [member function]
+    cls.add_method('IsBasic', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckResponseHeader::IsCompressed() const [member function]
+    cls.add_method('IsCompressed', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckResponseHeader::IsFragmentReceived(uint16_t seq, uint8_t frag) const [member function]
+    cls.add_method('IsFragmentReceived', 
+                   'bool', 
+                   [param('uint16_t', 'seq'), param('uint8_t', 'frag')], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckResponseHeader::IsMultiTid() const [member function]
+    cls.add_method('IsMultiTid', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckResponseHeader::IsPacketReceived(uint16_t seq) const [member function]
+    cls.add_method('IsPacketReceived', 
+                   'bool', 
+                   [param('uint16_t', 'seq')], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckResponseHeader::MustSendHtImmediateAck() const [member function]
+    cls.add_method('MustSendHtImmediateAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::SetHtImmediateAck(bool immeadiateAck) [member function]
+    cls.add_method('SetHtImmediateAck', 
+                   'void', 
+                   [param('bool', 'immeadiateAck')])
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::SetReceivedFragment(uint16_t seq, uint8_t frag) [member function]
+    cls.add_method('SetReceivedFragment', 
+                   'void', 
+                   [param('uint16_t', 'seq'), param('uint8_t', 'frag')])
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::SetReceivedPacket(uint16_t seq) [member function]
+    cls.add_method('SetReceivedPacket', 
+                   'void', 
+                   [param('uint16_t', 'seq')])
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::SetStartingSequence(uint16_t seq) [member function]
+    cls.add_method('SetStartingSequence', 
+                   'void', 
+                   [param('uint16_t', 'seq')])
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::SetStartingSequenceControl(uint16_t seqControl) [member function]
+    cls.add_method('SetStartingSequenceControl', 
+                   'void', 
+                   [param('uint16_t', 'seqControl')])
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::SetTidInfo(uint8_t tid) [member function]
+    cls.add_method('SetTidInfo', 
+                   'void', 
+                   [param('uint8_t', 'tid')])
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::SetType(ns3::BlockAckType type) [member function]
+    cls.add_method('SetType', 
+                   'void', 
+                   [param('ns3::BlockAckType', 'type')])
     return
 
 def register_Ns3Dcf_methods(root_module, cls):
@@ -3948,6 +4646,22 @@
     cls.add_method('GotAck', 
                    'void', 
                    [param('double', 'snr'), param('ns3::WifiMode', 'txMode')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::GotBlockAck(ns3::CtrlBAckResponseHeader const * blockAck, ns3::Mac48Address recipient) [member function]
+    cls.add_method('GotBlockAck', 
+                   'void', 
+                   [param('ns3::CtrlBAckResponseHeader const *', 'blockAck'), param('ns3::Mac48Address', 'recipient')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::MissedBlockAck() [member function]
+    cls.add_method('MissedBlockAck', 
+                   'void', 
+                   [])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::GotAddBaResponse(ns3::MgtAddBaResponseHeader const * respHdr, ns3::Mac48Address recipient) [member function]
+    cls.add_method('GotAddBaResponse', 
+                   'void', 
+                   [param('ns3::MgtAddBaResponseHeader const *', 'respHdr'), param('ns3::Mac48Address', 'recipient')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::GotDelBaFrame(ns3::MgtDelBaHeader const * delBaHdr, ns3::Mac48Address recipient) [member function]
+    cls.add_method('GotDelBaFrame', 
+                   'void', 
+                   [param('ns3::MgtDelBaHeader const *', 'delBaHdr'), param('ns3::Mac48Address', 'recipient')])
     ## edca-txop-n.h: void ns3::EdcaTxopN::MissedAck() [member function]
     cls.add_method('MissedAck', 
                    'void', 
@@ -4015,6 +4729,10 @@
     cls.add_method('GetFragmentPacket', 
                    'ns3::Ptr< ns3::Packet >', 
                    [param('ns3::WifiMacHeader *', 'hdr')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetAccessClass(ns3::AccessClass ac) [member function]
+    cls.add_method('SetAccessClass', 
+                   'void', 
+                   [param('ns3::AccessClass', 'ac')])
     ## edca-txop-n.h: void ns3::EdcaTxopN::Queue(ns3::Ptr<ns3::Packet const> packet, ns3::WifiMacHeader const & hdr) [member function]
     cls.add_method('Queue', 
                    'void', 
@@ -4023,6 +4741,27 @@
     cls.add_method('SetMsduAggregator', 
                    'void', 
                    [param('ns3::Ptr< ns3::MsduAggregator >', 'aggr')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::PushFront(ns3::Ptr<ns3::Packet const> packet, ns3::WifiMacHeader const & hdr) [member function]
+    cls.add_method('PushFront', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const &', 'hdr')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::CompleteConfig() [member function]
+    cls.add_method('CompleteConfig', 
+                   'void', 
+                   [])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetBlockAckThreshold(uint8_t threshold) [member function]
+    cls.add_method('SetBlockAckThreshold', 
+                   'void', 
+                   [param('uint8_t', 'threshold')])
+    ## edca-txop-n.h: uint8_t ns3::EdcaTxopN::GetBlockAckThreshold() const [member function]
+    cls.add_method('GetBlockAckThreshold', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SendDelbaFrame(ns3::Mac48Address addr, uint8_t tid, bool byOriginator) [member function]
+    cls.add_method('SendDelbaFrame', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'addr'), param('uint8_t', 'tid'), param('bool', 'byOriginator')])
     return
 
 def register_Ns3ErrorRateModel_methods(root_module, cls):
@@ -4047,71 +4786,6 @@
                    is_static=True)
     return
 
-def register_Ns3FixedRssLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: static ns3::TypeId ns3::FixedRssLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## propagation-loss-model.h: ns3::FixedRssLossModel::FixedRssLossModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-loss-model.h: void ns3::FixedRssLossModel::SetRss(double rss) [member function]
-    cls.add_method('SetRss', 
-                   'void', 
-                   [param('double', 'rss')])
-    ## propagation-loss-model.h: double ns3::FixedRssLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, visibility='private', is_virtual=True)
-    return
-
-def register_Ns3FriisPropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: static ns3::TypeId ns3::FriisPropagationLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## propagation-loss-model.h: ns3::FriisPropagationLossModel::FriisPropagationLossModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetLambda(double frequency, double speed) [member function]
-    cls.add_method('SetLambda', 
-                   'void', 
-                   [param('double', 'frequency'), param('double', 'speed')])
-    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetLambda(double lambda) [member function]
-    cls.add_method('SetLambda', 
-                   'void', 
-                   [param('double', 'lambda')])
-    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetSystemLoss(double systemLoss) [member function]
-    cls.add_method('SetSystemLoss', 
-                   'void', 
-                   [param('double', 'systemLoss')])
-    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetMinDistance(double minDistance) [member function]
-    cls.add_method('SetMinDistance', 
-                   'void', 
-                   [param('double', 'minDistance')])
-    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetMinDistance() const [member function]
-    cls.add_method('GetMinDistance', 
-                   'double', 
-                   [], 
-                   is_const=True)
-    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetLambda() const [member function]
-    cls.add_method('GetLambda', 
-                   'double', 
-                   [], 
-                   is_const=True)
-    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetSystemLoss() const [member function]
-    cls.add_method('GetSystemLoss', 
-                   'double', 
-                   [], 
-                   is_const=True)
-    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, visibility='private', is_virtual=True)
-    return
-
 def register_Ns3IdealWifiManager_methods(root_module, cls):
     ## ideal-wifi-manager.h: ns3::IdealWifiManager::IdealWifiManager(ns3::IdealWifiManager const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::IdealWifiManager const &', 'arg0')])
@@ -4143,67 +4817,6 @@
                    visibility='private', is_virtual=True)
     return
 
-def register_Ns3JakesPropagationLossModel_methods(root_module, cls):
-    ## jakes-propagation-loss-model.h: ns3::JakesPropagationLossModel::JakesPropagationLossModel() [constructor]
-    cls.add_constructor([])
-    ## jakes-propagation-loss-model.h: uint8_t ns3::JakesPropagationLossModel::GetNOscillators() const [member function]
-    cls.add_method('GetNOscillators', 
-                   'uint8_t', 
-                   [], 
-                   is_const=True)
-    ## jakes-propagation-loss-model.h: uint8_t ns3::JakesPropagationLossModel::GetNRays() const [member function]
-    cls.add_method('GetNRays', 
-                   'uint8_t', 
-                   [], 
-                   is_const=True)
-    ## jakes-propagation-loss-model.h: static ns3::TypeId ns3::JakesPropagationLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## jakes-propagation-loss-model.h: void ns3::JakesPropagationLossModel::SetNOscillators(uint8_t nOscillators) [member function]
-    cls.add_method('SetNOscillators', 
-                   'void', 
-                   [param('uint8_t', 'nOscillators')])
-    ## jakes-propagation-loss-model.h: void ns3::JakesPropagationLossModel::SetNRays(uint8_t nRays) [member function]
-    cls.add_method('SetNRays', 
-                   'void', 
-                   [param('uint8_t', 'nRays')])
-    ## jakes-propagation-loss-model.h: double ns3::JakesPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, visibility='private', is_virtual=True)
-    return
-
-def register_Ns3LogDistancePropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: static ns3::TypeId ns3::LogDistancePropagationLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## propagation-loss-model.h: ns3::LogDistancePropagationLossModel::LogDistancePropagationLossModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetPathLossExponent(double n) [member function]
-    cls.add_method('SetPathLossExponent', 
-                   'void', 
-                   [param('double', 'n')])
-    ## propagation-loss-model.h: double ns3::LogDistancePropagationLossModel::GetPathLossExponent() const [member function]
-    cls.add_method('GetPathLossExponent', 
-                   'double', 
-                   [], 
-                   is_const=True)
-    ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetReference(double referenceDistance, double referenceLoss) [member function]
-    cls.add_method('SetReference', 
-                   'void', 
-                   [param('double', 'referenceDistance'), param('double', 'referenceLoss')])
-    ## propagation-loss-model.h: double ns3::LogDistancePropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, visibility='private', is_virtual=True)
-    return
-
 def register_Ns3MacLow_methods(root_module, cls):
     ## mac-low.h: ns3::MacLow::MacLow(ns3::MacLow const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::MacLow const &', 'arg0')])
@@ -4214,6 +4827,14 @@
                    'ns3::Time', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr'), param('ns3::MacLowTransmissionParameters const &', 'parameters')], 
                    is_const=True)
+    ## mac-low.h: void ns3::MacLow::CreateBlockAckAgreement(ns3::MgtAddBaResponseHeader const * respHdr, ns3::Mac48Address originator, uint16_t startingSeq) [member function]
+    cls.add_method('CreateBlockAckAgreement', 
+                   'void', 
+                   [param('ns3::MgtAddBaResponseHeader const *', 'respHdr'), param('ns3::Mac48Address', 'originator'), param('uint16_t', 'startingSeq')])
+    ## mac-low.h: void ns3::MacLow::DestroyBlockAckAgreement(ns3::Mac48Address originator, uint8_t tid) [member function]
+    cls.add_method('DestroyBlockAckAgreement', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'originator'), param('uint8_t', 'tid')])
     ## mac-low.h: ns3::Time ns3::MacLow::GetAckTimeout() const [member function]
     cls.add_method('GetAckTimeout', 
                    'ns3::Time', 
@@ -4224,11 +4845,21 @@
                    'ns3::Mac48Address', 
                    [], 
                    is_const=True)
+    ## mac-low.h: ns3::Time ns3::MacLow::GetBasicBlockAckTimeout() const [member function]
+    cls.add_method('GetBasicBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True)
     ## mac-low.h: ns3::Mac48Address ns3::MacLow::GetBssid() const [member function]
     cls.add_method('GetBssid', 
                    'ns3::Mac48Address', 
                    [], 
                    is_const=True)
+    ## mac-low.h: ns3::Time ns3::MacLow::GetCompressedBlockAckTimeout() const [member function]
+    cls.add_method('GetCompressedBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True)
     ## mac-low.h: ns3::Time ns3::MacLow::GetCtsTimeout() const [member function]
     cls.add_method('GetCtsTimeout', 
                    'ns3::Time', 
@@ -4261,6 +4892,10 @@
     cls.add_method('ReceiveOk', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet >', 'packet'), param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode'), param('ns3::WifiPreamble', 'preamble')])
+    ## mac-low.h: void ns3::MacLow::RegisterBlockAckListenerForAc(ns3::AccessClass ac, ns3::MacLowBlockAckEventListener * listener) [member function]
+    cls.add_method('RegisterBlockAckListenerForAc', 
+                   'void', 
+                   [param('ns3::AccessClass', 'ac'), param('ns3::MacLowBlockAckEventListener *', 'listener')])
     ## mac-low.h: void ns3::MacLow::RegisterDcfListener(ns3::MacLowDcfListener * listener) [member function]
     cls.add_method('RegisterDcfListener', 
                    'void', 
@@ -4273,10 +4908,18 @@
     cls.add_method('SetAddress', 
                    'void', 
                    [param('ns3::Mac48Address', 'ad')])
+    ## mac-low.h: void ns3::MacLow::SetBasicBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetBasicBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')])
     ## mac-low.h: void ns3::MacLow::SetBssid(ns3::Mac48Address ad) [member function]
     cls.add_method('SetBssid', 
                    'void', 
                    [param('ns3::Mac48Address', 'ad')])
+    ## mac-low.h: void ns3::MacLow::SetCompressedBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetCompressedBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')])
     ## mac-low.h: void ns3::MacLow::SetCtsTimeout(ns3::Time ctsTimeout) [member function]
     cls.add_method('SetCtsTimeout', 
                    'void', 
@@ -4376,21 +5019,6 @@
                    is_static=True)
     return
 
-def register_Ns3NakagamiPropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: static ns3::TypeId ns3::NakagamiPropagationLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## propagation-loss-model.h: ns3::NakagamiPropagationLossModel::NakagamiPropagationLossModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-loss-model.h: double ns3::NakagamiPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, visibility='private', is_virtual=True)
-    return
-
 def register_Ns3NqapWifiMac_methods(root_module, cls):
     ## nqap-wifi-mac.h: static ns3::TypeId ns3::NqapWifiMac::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
@@ -4865,6 +5493,26 @@
                    'ns3::Mac48Address', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetBasicBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetBasicBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetCompressedBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetCompressedBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: ns3::Time ns3::QadhocWifiMac::GetBasicBlockAckTimeout() const [member function]
+    cls.add_method('GetBasicBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qadhoc-wifi-mac.h: ns3::Time ns3::QadhocWifiMac::GetCompressedBlockAckTimeout() const [member function]
+    cls.add_method('GetCompressedBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
     ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::DoDispose() [member function]
     cls.add_method('DoDispose', 
                    'void', 
@@ -5010,6 +5658,26 @@
                    'ns3::Mac48Address', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetBasicBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetBasicBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetCompressedBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetCompressedBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: ns3::Time ns3::QapWifiMac::GetBasicBlockAckTimeout() const [member function]
+    cls.add_method('GetBasicBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qap-wifi-mac.h: ns3::Time ns3::QapWifiMac::GetCompressedBlockAckTimeout() const [member function]
+    cls.add_method('GetCompressedBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
     ## qap-wifi-mac.h: void ns3::QapWifiMac::SetBeaconInterval(ns3::Time interval) [member function]
     cls.add_method('SetBeaconInterval', 
                    'void', 
@@ -5173,6 +5841,26 @@
                    'ns3::Mac48Address', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetBasicBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetBasicBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetCompressedBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetCompressedBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: ns3::Time ns3::QstaWifiMac::GetBasicBlockAckTimeout() const [member function]
+    cls.add_method('GetBasicBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qsta-wifi-mac.h: ns3::Time ns3::QstaWifiMac::GetCompressedBlockAckTimeout() const [member function]
+    cls.add_method('GetCompressedBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
     ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetMaxMissedBeacons(uint32_t missed) [member function]
     cls.add_method('SetMaxMissedBeacons', 
                    'void', 
@@ -5657,6 +6345,10 @@
     module.add_function('QosUtilsGetTidForPacket', 
                         'uint8_t', 
                         [param('ns3::Ptr< ns3::Packet const >', 'packet')])
+    ## qos-utils.h: extern uint32_t ns3::QosUtilsMapSeqControlToUniqueInteger(uint16_t seqControl, uint16_t endSequence) [free function]
+    module.add_function('QosUtilsMapSeqControlToUniqueInteger', 
+                        'uint32_t', 
+                        [param('uint16_t', 'seqControl'), param('uint16_t', 'endSequence')])
     ## qos-utils.h: extern ns3::AccessClass ns3::QosUtilsMapTidToAc(uint8_t tid) [free function]
     module.add_function('QosUtilsMapTidToAc', 
                         'ns3::AccessClass', 
--- a/bindings/python/apidefs/gcc-LP64/callbacks_list.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/callbacks_list.py	Thu Feb 25 14:17:21 2010 +0100
@@ -12,6 +12,8 @@
     ['bool', 'std::string', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['bool', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet const>', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['bool', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet const>', 'unsigned short', 'ns3::Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
+    ['void', 'ns3::Mac48Address', 'unsigned char', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
+    ['void', 'ns3::Mac48Address', 'unsigned char', 'bool', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::Packet const>', 'ns3::Ipv4Header const&', 'ns3::Socket::SocketErrno', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::Ipv4Route>', 'ns3::Ptr<ns3::Packet const>', 'ns3::Ipv4Header const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::Socket>', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_aodv.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_aodv.py	Thu Feb 25 14:17:21 2010 +0100
@@ -387,6 +387,11 @@
                    'uint32_t', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## aodv-packet.h: static ns3::TypeId ns3::aodv::RerrHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
     ## aodv-packet.h: void ns3::aodv::RerrHeader::Print(std::ostream & os) const [member function]
     cls.add_method('Print', 
                    'void', 
@@ -744,6 +749,11 @@
                    'uint32_t', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## aodv-packet.h: static ns3::TypeId ns3::aodv::RrepAckHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
     ## aodv-packet.h: void ns3::aodv::RrepAckHeader::Print(std::ostream & os) const [member function]
     cls.add_method('Print', 
                    'void', 
@@ -813,6 +823,11 @@
                    'uint32_t', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## aodv-packet.h: static ns3::TypeId ns3::aodv::RrepHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
     ## aodv-packet.h: void ns3::aodv::RrepHeader::Print(std::ostream & os) const [member function]
     cls.add_method('Print', 
                    'void', 
@@ -919,6 +934,11 @@
                    'uint32_t', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## aodv-packet.h: static ns3::TypeId ns3::aodv::RreqHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
     ## aodv-packet.h: bool ns3::aodv::RreqHeader::GetUnknownSeqno() const [member function]
     cls.add_method('GetUnknownSeqno', 
                    'bool', 
@@ -999,6 +1019,11 @@
                    'uint32_t', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## aodv-packet.h: static ns3::TypeId ns3::aodv::TypeHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
     ## aodv-packet.h: bool ns3::aodv::TypeHeader::IsValid() const [member function]
     cls.add_method('IsValid', 
                    'bool', 
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_common.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_common.py	Thu Feb 25 14:17:21 2010 +0100
@@ -47,28 +47,50 @@
     module.add_class('Chunk', parent=root_module['ns3::ObjectBase'])
     ## header.h: ns3::Header [class]
     module.add_class('Header', parent=root_module['ns3::Chunk'])
-    ## pcap-writer.h: ns3::PcapWriter [class]
-    module.add_class('PcapWriter', parent=root_module['ns3::Object'])
-    ## simple-ref-count.h: ns3::SimpleRefCount<ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter<ns3::AsciiWriter> > [class]
-    module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::AsciiWriter', 'ns3::empty', 'ns3::DefaultDeleter<ns3::AsciiWriter>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
+    ## pcap-file-wrapper.h: ns3::PcapFileWrapper [class]
+    module.add_class('PcapFileWrapper', parent=root_module['ns3::Object'])
+    ## propagation-delay-model.h: ns3::PropagationDelayModel [class]
+    module.add_class('PropagationDelayModel', parent=root_module['ns3::Object'])
+    ## propagation-loss-model.h: ns3::PropagationLossModel [class]
+    module.add_class('PropagationLossModel', parent=root_module['ns3::Object'])
+    ## propagation-delay-model.h: ns3::RandomPropagationDelayModel [class]
+    module.add_class('RandomPropagationDelayModel', parent=root_module['ns3::PropagationDelayModel'])
+    ## propagation-loss-model.h: ns3::RandomPropagationLossModel [class]
+    module.add_class('RandomPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
+    ## simple-ref-count.h: ns3::SimpleRefCount<ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter<ns3::OutputStreamWrapper> > [class]
+    module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::OutputStreamWrapper', 'ns3::empty', 'ns3::DefaultDeleter<ns3::OutputStreamWrapper>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
     ## simple-ref-count.h: ns3::SimpleRefCount<ns3::Packet, ns3::empty, ns3::DefaultDeleter<ns3::Packet> > [class]
     module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::Packet', 'ns3::empty', 'ns3::DefaultDeleter<ns3::Packet>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
+    ## propagation-loss-model.h: ns3::ThreeLogDistancePropagationLossModel [class]
+    module.add_class('ThreeLogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## trailer.h: ns3::Trailer [class]
     module.add_class('Trailer', parent=root_module['ns3::Chunk'])
-    ## ascii-writer.h: ns3::AsciiWriter [class]
-    module.add_class('AsciiWriter', parent=root_module['ns3::SimpleRefCount< ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter<ns3::AsciiWriter> >'])
-    ## ascii-writer.h: ns3::AsciiWriter::Type [enumeration]
-    module.add_enum('Type', ['ENQUEUE', 'DEQUEUE', 'DROP', 'TX', 'RX'], outer_class=root_module['ns3::AsciiWriter'])
+    ## propagation-loss-model.h: ns3::TwoRayGroundPropagationLossModel [class]
+    module.add_class('TwoRayGroundPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
+    ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel [class]
+    module.add_class('ConstantSpeedPropagationDelayModel', parent=root_module['ns3::PropagationDelayModel'])
     ## data-rate.h: ns3::DataRateChecker [class]
     module.add_class('DataRateChecker', parent=root_module['ns3::AttributeChecker'])
     ## data-rate.h: ns3::DataRateValue [class]
     module.add_class('DataRateValue', parent=root_module['ns3::AttributeValue'])
     ## error-model.h: ns3::ErrorModel [class]
     module.add_class('ErrorModel', parent=root_module['ns3::Object'])
+    ## propagation-loss-model.h: ns3::FixedRssLossModel [class]
+    module.add_class('FixedRssLossModel', parent=root_module['ns3::PropagationLossModel'])
+    ## propagation-loss-model.h: ns3::FriisPropagationLossModel [class]
+    module.add_class('FriisPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
+    ## jakes-propagation-loss-model.h: ns3::JakesPropagationLossModel [class]
+    module.add_class('JakesPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## error-model.h: ns3::ListErrorModel [class]
     module.add_class('ListErrorModel', parent=root_module['ns3::ErrorModel'])
+    ## propagation-loss-model.h: ns3::LogDistancePropagationLossModel [class]
+    module.add_class('LogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
+    ## propagation-loss-model.h: ns3::NakagamiPropagationLossModel [class]
+    module.add_class('NakagamiPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## nix-vector.h: ns3::NixVector [class]
     module.add_class('NixVector', parent=root_module['ns3::Object'])
+    ## output-stream-wrapper.h: ns3::OutputStreamWrapper [class]
+    module.add_class('OutputStreamWrapper', parent=root_module['ns3::SimpleRefCount< ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter<ns3::OutputStreamWrapper> >'])
     ## packet.h: ns3::Packet [class]
     module.add_class('Packet', parent=root_module['ns3::SimpleRefCount< ns3::Packet, ns3::empty, ns3::DefaultDeleter<ns3::Packet> >'])
     ## error-model.h: ns3::RateErrorModel [class]
@@ -175,14 +197,26 @@
     register_Ns3TagBuffer_methods(root_module, root_module['ns3::TagBuffer'])
     register_Ns3Chunk_methods(root_module, root_module['ns3::Chunk'])
     register_Ns3Header_methods(root_module, root_module['ns3::Header'])
-    register_Ns3PcapWriter_methods(root_module, root_module['ns3::PcapWriter'])
+    register_Ns3PcapFileWrapper_methods(root_module, root_module['ns3::PcapFileWrapper'])
+    register_Ns3PropagationDelayModel_methods(root_module, root_module['ns3::PropagationDelayModel'])
+    register_Ns3PropagationLossModel_methods(root_module, root_module['ns3::PropagationLossModel'])
+    register_Ns3RandomPropagationDelayModel_methods(root_module, root_module['ns3::RandomPropagationDelayModel'])
+    register_Ns3RandomPropagationLossModel_methods(root_module, root_module['ns3::RandomPropagationLossModel'])
+    register_Ns3ThreeLogDistancePropagationLossModel_methods(root_module, root_module['ns3::ThreeLogDistancePropagationLossModel'])
     register_Ns3Trailer_methods(root_module, root_module['ns3::Trailer'])
-    register_Ns3AsciiWriter_methods(root_module, root_module['ns3::AsciiWriter'])
+    register_Ns3TwoRayGroundPropagationLossModel_methods(root_module, root_module['ns3::TwoRayGroundPropagationLossModel'])
+    register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, root_module['ns3::ConstantSpeedPropagationDelayModel'])
     register_Ns3DataRateChecker_methods(root_module, root_module['ns3::DataRateChecker'])
     register_Ns3DataRateValue_methods(root_module, root_module['ns3::DataRateValue'])
     register_Ns3ErrorModel_methods(root_module, root_module['ns3::ErrorModel'])
+    register_Ns3FixedRssLossModel_methods(root_module, root_module['ns3::FixedRssLossModel'])
+    register_Ns3FriisPropagationLossModel_methods(root_module, root_module['ns3::FriisPropagationLossModel'])
+    register_Ns3JakesPropagationLossModel_methods(root_module, root_module['ns3::JakesPropagationLossModel'])
     register_Ns3ListErrorModel_methods(root_module, root_module['ns3::ListErrorModel'])
+    register_Ns3LogDistancePropagationLossModel_methods(root_module, root_module['ns3::LogDistancePropagationLossModel'])
+    register_Ns3NakagamiPropagationLossModel_methods(root_module, root_module['ns3::NakagamiPropagationLossModel'])
     register_Ns3NixVector_methods(root_module, root_module['ns3::NixVector'])
+    register_Ns3OutputStreamWrapper_methods(root_module, root_module['ns3::OutputStreamWrapper'])
     register_Ns3Packet_methods(root_module, root_module['ns3::Packet'])
     register_Ns3RateErrorModel_methods(root_module, root_module['ns3::RateErrorModel'])
     return
@@ -216,6 +250,11 @@
                    'void', 
                    [param('std::ostream *', 'os'), param('uint32_t', 'size')], 
                    is_const=True)
+    ## buffer.h: uint32_t ns3::Buffer::CopyData(uint8_t * buffer, uint32_t size) const [member function]
+    cls.add_method('CopyData', 
+                   'uint32_t', 
+                   [param('uint8_t *', 'buffer'), param('uint32_t', 'size')], 
+                   is_const=True)
     ## buffer.h: ns3::Buffer ns3::Buffer::CreateFragment(uint32_t start, uint32_t length) const [member function]
     cls.add_method('CreateFragment', 
                    'ns3::Buffer', 
@@ -948,56 +987,156 @@
                    is_pure_virtual=True, is_const=True, is_virtual=True)
     return
 
-def register_Ns3PcapWriter_methods(root_module, cls):
-    ## pcap-writer.h: ns3::PcapWriter::PcapWriter(ns3::PcapWriter const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::PcapWriter const &', 'arg0')])
-    ## pcap-writer.h: ns3::PcapWriter::PcapWriter() [constructor]
+def register_Ns3PcapFileWrapper_methods(root_module, cls):
+    ## pcap-file-wrapper.h: ns3::PcapFileWrapper::PcapFileWrapper(ns3::PcapFileWrapper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::PcapFileWrapper const &', 'arg0')])
+    ## pcap-file-wrapper.h: ns3::PcapFileWrapper::PcapFileWrapper() [constructor]
     cls.add_constructor([])
-    ## pcap-writer.h: static ns3::TypeId ns3::PcapWriter::GetTypeId() [member function]
+    ## pcap-file-wrapper.h: void ns3::PcapFileWrapper::Close() [member function]
+    cls.add_method('Close', 
+                   'void', 
+                   [])
+    ## pcap-file-wrapper.h: uint32_t ns3::PcapFileWrapper::GetDataLinkType() [member function]
+    cls.add_method('GetDataLinkType', 
+                   'uint32_t', 
+                   [])
+    ## pcap-file-wrapper.h: uint32_t ns3::PcapFileWrapper::GetMagic() [member function]
+    cls.add_method('GetMagic', 
+                   'uint32_t', 
+                   [])
+    ## pcap-file-wrapper.h: uint32_t ns3::PcapFileWrapper::GetSigFigs() [member function]
+    cls.add_method('GetSigFigs', 
+                   'uint32_t', 
+                   [])
+    ## pcap-file-wrapper.h: uint32_t ns3::PcapFileWrapper::GetSnapLen() [member function]
+    cls.add_method('GetSnapLen', 
+                   'uint32_t', 
+                   [])
+    ## pcap-file-wrapper.h: int32_t ns3::PcapFileWrapper::GetTimeZoneOffset() [member function]
+    cls.add_method('GetTimeZoneOffset', 
+                   'int32_t', 
+                   [])
+    ## pcap-file-wrapper.h: static ns3::TypeId ns3::PcapFileWrapper::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
                    [], 
                    is_static=True)
-    ## pcap-writer.h: void ns3::PcapWriter::Open(std::string const & name) [member function]
+    ## pcap-file-wrapper.h: uint16_t ns3::PcapFileWrapper::GetVersionMajor() [member function]
+    cls.add_method('GetVersionMajor', 
+                   'uint16_t', 
+                   [])
+    ## pcap-file-wrapper.h: uint16_t ns3::PcapFileWrapper::GetVersionMinor() [member function]
+    cls.add_method('GetVersionMinor', 
+                   'uint16_t', 
+                   [])
+    ## pcap-file-wrapper.h: bool ns3::PcapFileWrapper::Init(uint32_t dataLinkType, uint32_t snapLen=std::numeric_limits<unsigned int>::max(), int32_t tzCorrection=ns3::PcapFile::ZONE_DEFAULT) [member function]
+    cls.add_method('Init', 
+                   'bool', 
+                   [param('uint32_t', 'dataLinkType'), param('uint32_t', 'snapLen', default_value='std::numeric_limits<unsigned int>::max()'), param('int32_t', 'tzCorrection', default_value='ns3::PcapFile::ZONE_DEFAULT')])
+    ## pcap-file-wrapper.h: bool ns3::PcapFileWrapper::Open(std::string const & filename, std::string const & mode) [member function]
     cls.add_method('Open', 
-                   'void', 
-                   [param('std::string const &', 'name')])
-    ## pcap-writer.h: void ns3::PcapWriter::SetCaptureSize(uint32_t size) [member function]
-    cls.add_method('SetCaptureSize', 
-                   'void', 
-                   [param('uint32_t', 'size')])
-    ## pcap-writer.h: void ns3::PcapWriter::WriteEthernetHeader() [member function]
-    cls.add_method('WriteEthernetHeader', 
-                   'void', 
-                   [])
-    ## pcap-writer.h: void ns3::PcapWriter::WriteIpHeader() [member function]
-    cls.add_method('WriteIpHeader', 
-                   'void', 
-                   [])
-    ## pcap-writer.h: void ns3::PcapWriter::WritePacket(ns3::Ptr<ns3::Packet const> packet) [member function]
-    cls.add_method('WritePacket', 
+                   'bool', 
+                   [param('std::string const &', 'filename'), param('std::string const &', 'mode')])
+    ## pcap-file-wrapper.h: bool ns3::PcapFileWrapper::Write(ns3::Time t, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('Write', 
+                   'bool', 
+                   [param('ns3::Time', 't'), param('ns3::Ptr< ns3::Packet const >', 'p')])
+    ## pcap-file-wrapper.h: bool ns3::PcapFileWrapper::Write(ns3::Time t, ns3::Header & header, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('Write', 
+                   'bool', 
+                   [param('ns3::Time', 't'), param('ns3::Header &', 'header'), param('ns3::Ptr< ns3::Packet const >', 'p')])
+    ## pcap-file-wrapper.h: bool ns3::PcapFileWrapper::Write(ns3::Time t, uint8_t const * buffer, uint32_t length) [member function]
+    cls.add_method('Write', 
+                   'bool', 
+                   [param('ns3::Time', 't'), param('uint8_t const *', 'buffer'), param('uint32_t', 'length')])
+    return
+
+def register_Ns3PropagationDelayModel_methods(root_module, cls):
+    ## propagation-delay-model.h: ns3::PropagationDelayModel::PropagationDelayModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-delay-model.h: ns3::PropagationDelayModel::PropagationDelayModel(ns3::PropagationDelayModel const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::PropagationDelayModel const &', 'arg0')])
+    ## propagation-delay-model.h: ns3::Time ns3::PropagationDelayModel::GetDelay(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('GetDelay', 
+                   'ns3::Time', 
+                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## propagation-delay-model.h: static ns3::TypeId ns3::PropagationDelayModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    return
+
+def register_Ns3PropagationLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::PropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-loss-model.h: ns3::PropagationLossModel::PropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: void ns3::PropagationLossModel::SetNext(ns3::Ptr<ns3::PropagationLossModel> next) [member function]
+    cls.add_method('SetNext', 
                    'void', 
-                   [param('ns3::Ptr< ns3::Packet const >', 'packet')])
-    ## pcap-writer.h: void ns3::PcapWriter::WritePppHeader() [member function]
-    cls.add_method('WritePppHeader', 
-                   'void', 
-                   [])
-    ## pcap-writer.h: void ns3::PcapWriter::WriteWifiHeader() [member function]
-    cls.add_method('WriteWifiHeader', 
-                   'void', 
-                   [])
-    ## pcap-writer.h: void ns3::PcapWriter::WriteWifiMonitorPacket(ns3::Ptr<ns3::Packet const> packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble, bool isTx, double signalDbm, double noiseDbm) [member function]
-    cls.add_method('WriteWifiMonitorPacket', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'channelFreqMhz'), param('uint16_t', 'channelNumber'), param('uint32_t', 'rate'), param('bool', 'isShortPreamble'), param('bool', 'isTx'), param('double', 'signalDbm'), param('double', 'noiseDbm')])
-    ## pcap-writer.h: void ns3::PcapWriter::WriteWifiPrismHeader() [member function]
-    cls.add_method('WriteWifiPrismHeader', 
-                   'void', 
-                   [])
-    ## pcap-writer.h: void ns3::PcapWriter::WriteWifiRadiotapHeader() [member function]
-    cls.add_method('WriteWifiRadiotapHeader', 
-                   'void', 
-                   [])
+                   [param('ns3::Ptr< ns3::PropagationLossModel >', 'next')])
+    ## propagation-loss-model.h: double ns3::PropagationLossModel::CalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('CalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True)
+    ## propagation-loss-model.h: double ns3::PropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3RandomPropagationDelayModel_methods(root_module, cls):
+    ## propagation-delay-model.h: ns3::RandomPropagationDelayModel::RandomPropagationDelayModel(ns3::RandomPropagationDelayModel const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::RandomPropagationDelayModel const &', 'arg0')])
+    ## propagation-delay-model.h: ns3::RandomPropagationDelayModel::RandomPropagationDelayModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-delay-model.h: ns3::Time ns3::RandomPropagationDelayModel::GetDelay(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('GetDelay', 
+                   'ns3::Time', 
+                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, is_virtual=True)
+    ## propagation-delay-model.h: static ns3::TypeId ns3::RandomPropagationDelayModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    return
+
+def register_Ns3RandomPropagationLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::RandomPropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-loss-model.h: ns3::RandomPropagationLossModel::RandomPropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: double ns3::RandomPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3ThreeLogDistancePropagationLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::ThreeLogDistancePropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-loss-model.h: ns3::ThreeLogDistancePropagationLossModel::ThreeLogDistancePropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: double ns3::ThreeLogDistancePropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
     return
 
 def register_Ns3Trailer_methods(root_module, cls):
@@ -1033,18 +1172,80 @@
                    is_pure_virtual=True, is_const=True, is_virtual=True)
     return
 
-def register_Ns3AsciiWriter_methods(root_module, cls):
-    ## ascii-writer.h: ns3::AsciiWriter::AsciiWriter(ns3::AsciiWriter const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::AsciiWriter const &', 'arg0')])
-    ## ascii-writer.h: static ns3::Ptr<ns3::AsciiWriter> ns3::AsciiWriter::Get(std::ostream & os) [member function]
-    cls.add_method('Get', 
-                   'ns3::Ptr< ns3::AsciiWriter >', 
-                   [param('std::ostream &', 'os')], 
+def register_Ns3TwoRayGroundPropagationLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::TwoRayGroundPropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
                    is_static=True)
-    ## ascii-writer.h: void ns3::AsciiWriter::WritePacket(ns3::AsciiWriter::Type type, std::string message, ns3::Ptr<ns3::Packet const> p) [member function]
-    cls.add_method('WritePacket', 
+    ## propagation-loss-model.h: ns3::TwoRayGroundPropagationLossModel::TwoRayGroundPropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: void ns3::TwoRayGroundPropagationLossModel::SetLambda(double frequency, double speed) [member function]
+    cls.add_method('SetLambda', 
+                   'void', 
+                   [param('double', 'frequency'), param('double', 'speed')])
+    ## propagation-loss-model.h: void ns3::TwoRayGroundPropagationLossModel::SetLambda(double lambda) [member function]
+    cls.add_method('SetLambda', 
+                   'void', 
+                   [param('double', 'lambda')])
+    ## propagation-loss-model.h: void ns3::TwoRayGroundPropagationLossModel::SetSystemLoss(double systemLoss) [member function]
+    cls.add_method('SetSystemLoss', 
+                   'void', 
+                   [param('double', 'systemLoss')])
+    ## propagation-loss-model.h: void ns3::TwoRayGroundPropagationLossModel::SetMinDistance(double minDistance) [member function]
+    cls.add_method('SetMinDistance', 
                    'void', 
-                   [param('ns3::AsciiWriter::Type', 'type'), param('std::string', 'message'), param('ns3::Ptr< ns3::Packet const >', 'p')])
+                   [param('double', 'minDistance')])
+    ## propagation-loss-model.h: double ns3::TwoRayGroundPropagationLossModel::GetMinDistance() const [member function]
+    cls.add_method('GetMinDistance', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-loss-model.h: double ns3::TwoRayGroundPropagationLossModel::GetLambda() const [member function]
+    cls.add_method('GetLambda', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-loss-model.h: double ns3::TwoRayGroundPropagationLossModel::GetSystemLoss() const [member function]
+    cls.add_method('GetSystemLoss', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-loss-model.h: void ns3::TwoRayGroundPropagationLossModel::SetHeightAboveZ(double heightAboveZ) [member function]
+    cls.add_method('SetHeightAboveZ', 
+                   'void', 
+                   [param('double', 'heightAboveZ')])
+    ## propagation-loss-model.h: double ns3::TwoRayGroundPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, cls):
+    ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel::ConstantSpeedPropagationDelayModel(ns3::ConstantSpeedPropagationDelayModel const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::ConstantSpeedPropagationDelayModel const &', 'arg0')])
+    ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel::ConstantSpeedPropagationDelayModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-delay-model.h: ns3::Time ns3::ConstantSpeedPropagationDelayModel::GetDelay(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('GetDelay', 
+                   'ns3::Time', 
+                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, is_virtual=True)
+    ## propagation-delay-model.h: double ns3::ConstantSpeedPropagationDelayModel::GetSpeed() const [member function]
+    cls.add_method('GetSpeed', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-delay-model.h: static ns3::TypeId ns3::ConstantSpeedPropagationDelayModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-delay-model.h: void ns3::ConstantSpeedPropagationDelayModel::SetSpeed(double speed) [member function]
+    cls.add_method('SetSpeed', 
+                   'void', 
+                   [param('double', 'speed')])
     return
 
 def register_Ns3DataRateChecker_methods(root_module, cls):
@@ -1130,6 +1331,104 @@
                    is_pure_virtual=True, visibility='private', is_virtual=True)
     return
 
+def register_Ns3FixedRssLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::FixedRssLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-loss-model.h: ns3::FixedRssLossModel::FixedRssLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: void ns3::FixedRssLossModel::SetRss(double rss) [member function]
+    cls.add_method('SetRss', 
+                   'void', 
+                   [param('double', 'rss')])
+    ## propagation-loss-model.h: double ns3::FixedRssLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3FriisPropagationLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::FriisPropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-loss-model.h: ns3::FriisPropagationLossModel::FriisPropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetLambda(double frequency, double speed) [member function]
+    cls.add_method('SetLambda', 
+                   'void', 
+                   [param('double', 'frequency'), param('double', 'speed')])
+    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetLambda(double lambda) [member function]
+    cls.add_method('SetLambda', 
+                   'void', 
+                   [param('double', 'lambda')])
+    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetSystemLoss(double systemLoss) [member function]
+    cls.add_method('SetSystemLoss', 
+                   'void', 
+                   [param('double', 'systemLoss')])
+    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetMinDistance(double minDistance) [member function]
+    cls.add_method('SetMinDistance', 
+                   'void', 
+                   [param('double', 'minDistance')])
+    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetMinDistance() const [member function]
+    cls.add_method('GetMinDistance', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetLambda() const [member function]
+    cls.add_method('GetLambda', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetSystemLoss() const [member function]
+    cls.add_method('GetSystemLoss', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3JakesPropagationLossModel_methods(root_module, cls):
+    ## jakes-propagation-loss-model.h: ns3::JakesPropagationLossModel::JakesPropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## jakes-propagation-loss-model.h: uint8_t ns3::JakesPropagationLossModel::GetNOscillators() const [member function]
+    cls.add_method('GetNOscillators', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## jakes-propagation-loss-model.h: uint8_t ns3::JakesPropagationLossModel::GetNRays() const [member function]
+    cls.add_method('GetNRays', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## jakes-propagation-loss-model.h: static ns3::TypeId ns3::JakesPropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## jakes-propagation-loss-model.h: void ns3::JakesPropagationLossModel::SetNOscillators(uint8_t nOscillators) [member function]
+    cls.add_method('SetNOscillators', 
+                   'void', 
+                   [param('uint8_t', 'nOscillators')])
+    ## jakes-propagation-loss-model.h: void ns3::JakesPropagationLossModel::SetNRays(uint8_t nRays) [member function]
+    cls.add_method('SetNRays', 
+                   'void', 
+                   [param('uint8_t', 'nRays')])
+    ## jakes-propagation-loss-model.h: double ns3::JakesPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
 def register_Ns3ListErrorModel_methods(root_module, cls):
     ## error-model.h: ns3::ListErrorModel::ListErrorModel(ns3::ListErrorModel const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::ListErrorModel const &', 'arg0')])
@@ -1161,6 +1460,49 @@
                    visibility='private', is_virtual=True)
     return
 
+def register_Ns3LogDistancePropagationLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::LogDistancePropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-loss-model.h: ns3::LogDistancePropagationLossModel::LogDistancePropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetPathLossExponent(double n) [member function]
+    cls.add_method('SetPathLossExponent', 
+                   'void', 
+                   [param('double', 'n')])
+    ## propagation-loss-model.h: double ns3::LogDistancePropagationLossModel::GetPathLossExponent() const [member function]
+    cls.add_method('GetPathLossExponent', 
+                   'double', 
+                   [], 
+                   is_const=True)
+    ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetReference(double referenceDistance, double referenceLoss) [member function]
+    cls.add_method('SetReference', 
+                   'void', 
+                   [param('double', 'referenceDistance'), param('double', 'referenceLoss')])
+    ## propagation-loss-model.h: double ns3::LogDistancePropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
+def register_Ns3NakagamiPropagationLossModel_methods(root_module, cls):
+    ## propagation-loss-model.h: static ns3::TypeId ns3::NakagamiPropagationLossModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## propagation-loss-model.h: ns3::NakagamiPropagationLossModel::NakagamiPropagationLossModel() [constructor]
+    cls.add_constructor([])
+    ## propagation-loss-model.h: double ns3::NakagamiPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+    cls.add_method('DoCalcRxPower', 
+                   'double', 
+                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
+                   is_const=True, visibility='private', is_virtual=True)
+    return
+
 def register_Ns3NixVector_methods(root_module, cls):
     cls.add_output_stream_operator()
     ## nix-vector.h: ns3::NixVector::NixVector() [constructor]
@@ -1215,6 +1557,21 @@
                    is_const=True)
     return
 
+def register_Ns3OutputStreamWrapper_methods(root_module, cls):
+    ## output-stream-wrapper.h: ns3::OutputStreamWrapper::OutputStreamWrapper(ns3::OutputStreamWrapper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::OutputStreamWrapper const &', 'arg0')])
+    ## output-stream-wrapper.h: ns3::OutputStreamWrapper::OutputStreamWrapper() [constructor]
+    cls.add_constructor([])
+    ## output-stream-wrapper.h: std::ostream * ns3::OutputStreamWrapper::GetStream() [member function]
+    cls.add_method('GetStream', 
+                   'std::ostream *', 
+                   [])
+    ## output-stream-wrapper.h: void ns3::OutputStreamWrapper::SetStream(std::ostream * ostream) [member function]
+    cls.add_method('SetStream', 
+                   'void', 
+                   [param('std::ostream *', 'ostream')])
+    return
+
 def register_Ns3Packet_methods(root_module, cls):
     cls.add_output_stream_operator()
     ## packet.h: ns3::Packet::Packet() [constructor]
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_core.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_core.py	Thu Feb 25 14:17:21 2010 +0100
@@ -93,6 +93,8 @@
     module.add_class('Vector3D')
     ## random-variable.h: ns3::WeibullVariable [class]
     module.add_class('WeibullVariable', parent=root_module['ns3::RandomVariable'])
+    ## random-variable.h: ns3::ZetaVariable [class]
+    module.add_class('ZetaVariable', parent=root_module['ns3::RandomVariable'])
     ## random-variable.h: ns3::ZipfVariable [class]
     module.add_class('ZipfVariable', parent=root_module['ns3::RandomVariable'])
     ## empty.h: ns3::empty [class]
@@ -351,6 +353,7 @@
     register_Ns3Vector2D_methods(root_module, root_module['ns3::Vector2D'])
     register_Ns3Vector3D_methods(root_module, root_module['ns3::Vector3D'])
     register_Ns3WeibullVariable_methods(root_module, root_module['ns3::WeibullVariable'])
+    register_Ns3ZetaVariable_methods(root_module, root_module['ns3::ZetaVariable'])
     register_Ns3ZipfVariable_methods(root_module, root_module['ns3::ZipfVariable'])
     register_Ns3Empty_methods(root_module, root_module['ns3::empty'])
     register_Ns3ConstantVariable_methods(root_module, root_module['ns3::ConstantVariable'])
@@ -365,7 +368,6 @@
     register_Ns3Object_methods(root_module, root_module['ns3::Object'])
     register_Ns3ObjectAggregateIterator_methods(root_module, root_module['ns3::Object::AggregateIterator'])
     register_Ns3ParetoVariable_methods(root_module, root_module['ns3::ParetoVariable'])
-    register_Ns3SimpleRefCount__Ns3AsciiWriter_Ns3Empty_Ns3DefaultDeleter__lt__ns3AsciiWriter__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter<ns3::AsciiWriter> >'])
     register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >'])
     register_Ns3SimpleRefCount__Ns3AttributeChecker_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeChecker__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
     register_Ns3SimpleRefCount__Ns3AttributeValue_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeValue__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
@@ -379,6 +381,7 @@
     register_Ns3SimpleRefCount__Ns3Ipv6MulticastRoute_Ns3Empty_Ns3DefaultDeleter__lt__ns3Ipv6MulticastRoute__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::Ipv6MulticastRoute, ns3::empty, ns3::DefaultDeleter<ns3::Ipv6MulticastRoute> >'])
     register_Ns3SimpleRefCount__Ns3Ipv6Route_Ns3Empty_Ns3DefaultDeleter__lt__ns3Ipv6Route__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::Ipv6Route, ns3::empty, ns3::DefaultDeleter<ns3::Ipv6Route> >'])
     register_Ns3SimpleRefCount__Ns3MeshWifiInterfaceMacPlugin_Ns3Empty_Ns3DefaultDeleter__lt__ns3MeshWifiInterfaceMacPlugin__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::MeshWifiInterfaceMacPlugin, ns3::empty, ns3::DefaultDeleter<ns3::MeshWifiInterfaceMacPlugin> >'])
+    register_Ns3SimpleRefCount__Ns3OutputStreamWrapper_Ns3Empty_Ns3DefaultDeleter__lt__ns3OutputStreamWrapper__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter<ns3::OutputStreamWrapper> >'])
     register_Ns3SimpleRefCount__Ns3Packet_Ns3Empty_Ns3DefaultDeleter__lt__ns3Packet__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::Packet, ns3::empty, ns3::DefaultDeleter<ns3::Packet> >'])
     register_Ns3SimpleRefCount__Ns3PbbAddressBlock_Ns3Empty_Ns3DefaultDeleter__lt__ns3PbbAddressBlock__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::PbbAddressBlock, ns3::empty, ns3::DefaultDeleter<ns3::PbbAddressBlock> >'])
     register_Ns3SimpleRefCount__Ns3PbbMessage_Ns3Empty_Ns3DefaultDeleter__lt__ns3PbbMessage__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::PbbMessage, ns3::empty, ns3::DefaultDeleter<ns3::PbbMessage> >'])
@@ -1575,11 +1578,20 @@
     cls.add_constructor([param('double', 'm'), param('double', 's'), param('double', 'b')])
     return
 
+def register_Ns3ZetaVariable_methods(root_module, cls):
+    ## random-variable.h: ns3::ZetaVariable::ZetaVariable(ns3::ZetaVariable const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::ZetaVariable const &', 'arg0')])
+    ## random-variable.h: ns3::ZetaVariable::ZetaVariable(double alpha) [constructor]
+    cls.add_constructor([param('double', 'alpha')])
+    ## random-variable.h: ns3::ZetaVariable::ZetaVariable() [constructor]
+    cls.add_constructor([])
+    return
+
 def register_Ns3ZipfVariable_methods(root_module, cls):
     ## random-variable.h: ns3::ZipfVariable::ZipfVariable(ns3::ZipfVariable const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::ZipfVariable const &', 'arg0')])
-    ## random-variable.h: ns3::ZipfVariable::ZipfVariable(long int n, double alpha) [constructor]
-    cls.add_constructor([param('long int', 'n'), param('double', 'alpha')])
+    ## random-variable.h: ns3::ZipfVariable::ZipfVariable(long int N, double alpha) [constructor]
+    cls.add_constructor([param('long int', 'N'), param('double', 'alpha')])
     ## random-variable.h: ns3::ZipfVariable::ZipfVariable() [constructor]
     cls.add_constructor([])
     return
@@ -1780,18 +1792,6 @@
     cls.add_constructor([param('double', 'm'), param('double', 's'), param('double', 'b')])
     return
 
-def register_Ns3SimpleRefCount__Ns3AsciiWriter_Ns3Empty_Ns3DefaultDeleter__lt__ns3AsciiWriter__gt___methods(root_module, cls):
-    ## simple-ref-count.h: ns3::SimpleRefCount<ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter<ns3::AsciiWriter> >::SimpleRefCount() [constructor]
-    cls.add_constructor([])
-    ## simple-ref-count.h: ns3::SimpleRefCount<ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter<ns3::AsciiWriter> >::SimpleRefCount(ns3::SimpleRefCount<ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter<ns3::AsciiWriter> > const & o) [copy constructor]
-    cls.add_constructor([param('ns3::SimpleRefCount< ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter< ns3::AsciiWriter > > const &', 'o')])
-    ## simple-ref-count.h: static void ns3::SimpleRefCount<ns3::AsciiWriter, ns3::empty, ns3::DefaultDeleter<ns3::AsciiWriter> >::Cleanup() [member function]
-    cls.add_method('Cleanup', 
-                   'void', 
-                   [], 
-                   is_static=True)
-    return
-
 def register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, cls):
     ## simple-ref-count.h: ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >::SimpleRefCount() [constructor]
     cls.add_constructor([])
@@ -1948,6 +1948,18 @@
                    is_static=True)
     return
 
+def register_Ns3SimpleRefCount__Ns3OutputStreamWrapper_Ns3Empty_Ns3DefaultDeleter__lt__ns3OutputStreamWrapper__gt___methods(root_module, cls):
+    ## simple-ref-count.h: ns3::SimpleRefCount<ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter<ns3::OutputStreamWrapper> >::SimpleRefCount() [constructor]
+    cls.add_constructor([])
+    ## simple-ref-count.h: ns3::SimpleRefCount<ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter<ns3::OutputStreamWrapper> >::SimpleRefCount(ns3::SimpleRefCount<ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter<ns3::OutputStreamWrapper> > const & o) [copy constructor]
+    cls.add_constructor([param('ns3::SimpleRefCount< ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter< ns3::OutputStreamWrapper > > const &', 'o')])
+    ## simple-ref-count.h: static void ns3::SimpleRefCount<ns3::OutputStreamWrapper, ns3::empty, ns3::DefaultDeleter<ns3::OutputStreamWrapper> >::Cleanup() [member function]
+    cls.add_method('Cleanup', 
+                   'void', 
+                   [], 
+                   is_static=True)
+    return
+
 def register_Ns3SimpleRefCount__Ns3Packet_Ns3Empty_Ns3DefaultDeleter__lt__ns3Packet__gt___methods(root_module, cls):
     ## simple-ref-count.h: ns3::SimpleRefCount<ns3::Packet, ns3::empty, ns3::DefaultDeleter<ns3::Packet> >::SimpleRefCount() [constructor]
     cls.add_constructor([])
@@ -3043,6 +3055,21 @@
     module.add_function('MakeBooleanChecker', 
                         'ns3::Ptr< ns3::AttributeChecker const >', 
                         [])
+    ## callback.h: extern ns3::Callback<void,ns3::Ptr<const ns3::Packet>,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> ns3::MakeBoundCallback(void (*)( ::ns3::Ptr<ns3::OutputStreamWrapper>,::ns3::Ptr<ns3::Packet const> ) * fnPtr, ns3::Ptr<ns3::OutputStreamWrapper> a) [free function]
+    module.add_function('MakeBoundCallback', 
+                        'ns3::Callback< void, ns3::Ptr< ns3::Packet const >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 
+                        [param('void ( * ) ( ns3::Ptr< ns3::OutputStreamWrapper >, ns3::Ptr< ns3::Packet const > ) *', 'fnPtr'), param('ns3::Ptr< ns3::OutputStreamWrapper >', 'a')], 
+                        template_parameters=['void', 'ns3::Ptr<ns3::OutputStreamWrapper>', 'ns3::Ptr<ns3::OutputStreamWrapper>', 'ns3::Ptr<ns3::Packet const>'])
+    ## callback.h: extern ns3::Callback<void,ns3::Ptr<const ns3::Packet>,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> ns3::MakeBoundCallback(void (*)( ::ns3::Ptr<ns3::PcapFileWrapper>,::ns3::Ptr<ns3::Packet const> ) * fnPtr, ns3::Ptr<ns3::PcapFileWrapper> a) [free function]
+    module.add_function('MakeBoundCallback', 
+                        'ns3::Callback< void, ns3::Ptr< ns3::Packet const >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 
+                        [param('void ( * ) ( ns3::Ptr< ns3::PcapFileWrapper >, ns3::Ptr< ns3::Packet const > ) *', 'fnPtr'), param('ns3::Ptr< ns3::PcapFileWrapper >', 'a')], 
+                        template_parameters=['void', 'ns3::Ptr<ns3::PcapFileWrapper>', 'ns3::Ptr<ns3::PcapFileWrapper>', 'ns3::Ptr<ns3::Packet const>'])
+    ## callback.h: extern ns3::Callback<void,std::basic_string<char, std::char_traits<char>, std::allocator<char> >,ns3::Ptr<const ns3::Packet>,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> ns3::MakeBoundCallback(void (*)( ::ns3::Ptr<ns3::OutputStreamWrapper>,::std::basic_string<char,std::char_traits<char>,std::allocator<char> >,::ns3::Ptr<ns3::Packet const> ) * fnPtr, ns3::Ptr<ns3::OutputStreamWrapper> a) [free function]
+    module.add_function('MakeBoundCallback', 
+                        'ns3::Callback< void, std::basic_string< char, std::char_traits< char >, std::allocator< char > >, ns3::Ptr< ns3::Packet const >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 
+                        [param('void ( * ) ( ns3::Ptr< ns3::OutputStreamWrapper >, std::string, ns3::Ptr< ns3::Packet const > ) *', 'fnPtr'), param('ns3::Ptr< ns3::OutputStreamWrapper >', 'a')], 
+                        template_parameters=['void', 'ns3::Ptr<ns3::OutputStreamWrapper>', 'ns3::Ptr<ns3::OutputStreamWrapper>', 'std::string', 'ns3::Ptr<ns3::Packet const>'])
     ## callback.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeCallbackChecker() [free function]
     module.add_function('MakeCallbackChecker', 
                         'ns3::Ptr< ns3::AttributeChecker const >', 
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_csma.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_csma.py	Thu Feb 25 14:17:21 2010 +0100
@@ -266,6 +266,11 @@
     cls.add_method('SetQueue', 
                    'void', 
                    [param('ns3::Ptr< ns3::Queue >', 'queue')])
+    ## csma-net-device.h: ns3::Ptr<ns3::Queue> ns3::CsmaNetDevice::GetQueue() const [member function]
+    cls.add_method('GetQueue', 
+                   'ns3::Ptr< ns3::Queue >', 
+                   [], 
+                   is_const=True)
     ## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveErrorModel(ns3::Ptr<ns3::ErrorModel> em) [member function]
     cls.add_method('SetReceiveErrorModel', 
                    'void', 
@@ -432,11 +437,6 @@
                    'void', 
                    [], 
                    visibility='protected', is_virtual=True)
-    ## csma-net-device.h: ns3::Ptr<ns3::Queue> ns3::CsmaNetDevice::GetQueue() const [member function]
-    cls.add_method('GetQueue', 
-                   'ns3::Ptr< ns3::Queue >', 
-                   [], 
-                   is_const=True, visibility='protected')
     ## csma-net-device.h: void ns3::CsmaNetDevice::AddHeader(ns3::Ptr<ns3::Packet> p, ns3::Mac48Address source, ns3::Mac48Address dest, uint16_t protocolNumber) [member function]
     cls.add_method('AddHeader', 
                    'void', 
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_emu.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_emu.py	Thu Feb 25 14:17:21 2010 +0100
@@ -147,6 +147,11 @@
                    'ns3::Ptr< ns3::Node >', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## emu-net-device.h: ns3::Ptr<ns3::Queue> ns3::EmuNetDevice::GetQueue() const [member function]
+    cls.add_method('GetQueue', 
+                   'ns3::Ptr< ns3::Queue >', 
+                   [], 
+                   is_const=True)
     ## emu-net-device.h: static ns3::TypeId ns3::EmuNetDevice::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_global_routing.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_global_routing.py	Thu Feb 25 14:17:21 2010 +0100
@@ -331,7 +331,7 @@
                    [])
     ## global-router-interface.h: ns3::Ipv4RoutingTableEntry * ns3::GlobalRouter::GetInjectedRoute(uint32_t i) [member function]
     cls.add_method('GetInjectedRoute', 
-                   'ns3::Ipv4RoutingTableEntry *', 
+                   retval('ns3::Ipv4RoutingTableEntry *', caller_owns_return=False), 
                    [param('uint32_t', 'i')])
     ## global-router-interface.h: void ns3::GlobalRouter::RemoveInjectedRoute(uint32_t i) [member function]
     cls.add_method('RemoveInjectedRoute', 
@@ -379,7 +379,7 @@
                    [])
     ## ipv4-global-routing.h: ns3::Ipv4RoutingTableEntry * ns3::Ipv4GlobalRouting::GetRoute(uint32_t i) [member function]
     cls.add_method('GetRoute', 
-                   'ns3::Ipv4RoutingTableEntry *', 
+                   retval('ns3::Ipv4RoutingTableEntry *', caller_owns_return=False), 
                    [param('uint32_t', 'i')])
     ## ipv4-global-routing.h: static ns3::TypeId ns3::Ipv4GlobalRouting::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_helper.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_helper.py	Thu Feb 25 14:17:21 2010 +0100
@@ -7,106 +7,124 @@
     module.add_class('AnimationInterface')
     ## application-container.h: ns3::ApplicationContainer [class]
     module.add_class('ApplicationContainer')
+    ## trace-helper.h: ns3::AsciiTraceHelper [class]
+    module.add_class('AsciiTraceHelper')
+    ## trace-helper.h: ns3::AsciiTraceHelperForDevice [class]
+    module.add_class('AsciiTraceHelperForDevice', allow_subclassing=True)
+    ## trace-helper.h: ns3::AsciiTraceHelperForIpv4 [class]
+    module.add_class('AsciiTraceHelperForIpv4', allow_subclassing=True)
+    ## trace-helper.h: ns3::AsciiTraceHelperForIpv6 [class]
+    module.add_class('AsciiTraceHelperForIpv6', allow_subclassing=True)
     ## athstats-helper.h: ns3::AthstatsHelper [class]
-    module.add_class('AthstatsHelper', allow_subclassing=False)
+    module.add_class('AthstatsHelper')
     ## bridge-helper.h: ns3::BridgeHelper [class]
-    module.add_class('BridgeHelper', allow_subclassing=False)
-    ## csma-helper.h: ns3::CsmaHelper [class]
-    module.add_class('CsmaHelper', allow_subclassing=False)
+    module.add_class('BridgeHelper')
     ## csma-star-helper.h: ns3::CsmaStarHelper [class]
-    module.add_class('CsmaStarHelper', allow_subclassing=False)
-    ## emu-helper.h: ns3::EmuHelper [class]
-    module.add_class('EmuHelper', allow_subclassing=False)
+    module.add_class('CsmaStarHelper')
     ## flow-monitor-helper.h: ns3::FlowMonitorHelper [class]
-    module.add_class('FlowMonitorHelper', allow_subclassing=False)
-    ## internet-stack-helper.h: ns3::InternetStackHelper [class]
-    module.add_class('InternetStackHelper', allow_subclassing=False)
+    module.add_class('FlowMonitorHelper')
     ## ipv4-address-helper.h: ns3::Ipv4AddressHelper [class]
-    module.add_class('Ipv4AddressHelper', allow_subclassing=False)
+    module.add_class('Ipv4AddressHelper')
     ## ipv4-interface-container.h: ns3::Ipv4InterfaceContainer [class]
     module.add_class('Ipv4InterfaceContainer')
     ## ipv4-routing-helper.h: ns3::Ipv4RoutingHelper [class]
-    module.add_class('Ipv4RoutingHelper', allow_subclassing=False)
+    module.add_class('Ipv4RoutingHelper', allow_subclassing=True)
     ## ipv4-static-routing-helper.h: ns3::Ipv4StaticRoutingHelper [class]
-    module.add_class('Ipv4StaticRoutingHelper', allow_subclassing=False, parent=root_module['ns3::Ipv4RoutingHelper'])
+    module.add_class('Ipv4StaticRoutingHelper', parent=root_module['ns3::Ipv4RoutingHelper'])
     ## ipv6-address-helper.h: ns3::Ipv6AddressHelper [class]
-    module.add_class('Ipv6AddressHelper', allow_subclassing=False)
+    module.add_class('Ipv6AddressHelper')
     ## ipv6-interface-container.h: ns3::Ipv6InterfaceContainer [class]
     module.add_class('Ipv6InterfaceContainer')
     ## ipv6-routing-helper.h: ns3::Ipv6RoutingHelper [class]
-    module.add_class('Ipv6RoutingHelper', allow_subclassing=False)
+    module.add_class('Ipv6RoutingHelper', allow_subclassing=True)
     ## ipv6-static-routing-helper.h: ns3::Ipv6StaticRoutingHelper [class]
-    module.add_class('Ipv6StaticRoutingHelper', allow_subclassing=False, parent=root_module['ns3::Ipv6RoutingHelper'])
+    module.add_class('Ipv6StaticRoutingHelper', parent=root_module['ns3::Ipv6RoutingHelper'])
     ## mesh-helper.h: ns3::MeshHelper [class]
-    module.add_class('MeshHelper', allow_subclassing=False)
+    module.add_class('MeshHelper')
     ## mesh-helper.h: ns3::MeshHelper::ChannelPolicy [enumeration]
     module.add_enum('ChannelPolicy', ['SPREAD_CHANNELS', 'ZERO_CHANNEL'], outer_class=root_module['ns3::MeshHelper'])
     ## mobility-helper.h: ns3::MobilityHelper [class]
-    module.add_class('MobilityHelper', allow_subclassing=False)
+    module.add_class('MobilityHelper')
     ## net-device-container.h: ns3::NetDeviceContainer [class]
     module.add_class('NetDeviceContainer')
     ## node-container.h: ns3::NodeContainer [class]
     module.add_class('NodeContainer')
     ## ns2-mobility-helper.h: ns3::Ns2MobilityHelper [class]
-    module.add_class('Ns2MobilityHelper', allow_subclassing=False)
+    module.add_class('Ns2MobilityHelper')
     ## olsr-helper.h: ns3::OlsrHelper [class]
-    module.add_class('OlsrHelper', allow_subclassing=False, parent=root_module['ns3::Ipv4RoutingHelper'])
+    module.add_class('OlsrHelper', parent=root_module['ns3::Ipv4RoutingHelper'])
     ## on-off-helper.h: ns3::OnOffHelper [class]
-    module.add_class('OnOffHelper', allow_subclassing=False)
+    module.add_class('OnOffHelper')
     ## packet-sink-helper.h: ns3::PacketSinkHelper [class]
-    module.add_class('PacketSinkHelper', allow_subclassing=False)
+    module.add_class('PacketSinkHelper')
     ## packet-socket-helper.h: ns3::PacketSocketHelper [class]
-    module.add_class('PacketSocketHelper', allow_subclassing=False)
+    module.add_class('PacketSocketHelper')
+    ## trace-helper.h: ns3::PcapHelper [class]
+    module.add_class('PcapHelper')
+    ## trace-helper.h: ns3::PcapHelper [enumeration]
+    module.add_enum('', ['DLT_NULL', 'DLT_EN10MB', 'DLT_PPP', 'DLT_RAW', 'DLT_IEEE802_11', 'DLT_PRISM_HEADER', 'DLT_IEEE802_11_RADIO'], outer_class=root_module['ns3::PcapHelper'])
+    ## trace-helper.h: ns3::PcapHelperForDevice [class]
+    module.add_class('PcapHelperForDevice', allow_subclassing=True)
+    ## trace-helper.h: ns3::PcapHelperForIpv4 [class]
+    module.add_class('PcapHelperForIpv4', allow_subclassing=True)
+    ## trace-helper.h: ns3::PcapHelperForIpv6 [class]
+    module.add_class('PcapHelperForIpv6', allow_subclassing=True)
     ## ping6-helper.h: ns3::Ping6Helper [class]
-    module.add_class('Ping6Helper', allow_subclassing=False)
+    module.add_class('Ping6Helper')
     ## point-to-point-dumbbell-helper.h: ns3::PointToPointDumbbellHelper [class]
-    module.add_class('PointToPointDumbbellHelper', allow_subclassing=False)
+    module.add_class('PointToPointDumbbellHelper')
     ## point-to-point-grid-helper.h: ns3::PointToPointGridHelper [class]
-    module.add_class('PointToPointGridHelper', allow_subclassing=False)
+    module.add_class('PointToPointGridHelper')
     ## point-to-point-helper.h: ns3::PointToPointHelper [class]
-    module.add_class('PointToPointHelper', allow_subclassing=False)
+    module.add_class('PointToPointHelper', parent=[root_module['ns3::PcapHelperForDevice'], root_module['ns3::AsciiTraceHelperForDevice']])
     ## point-to-point-star-helper.h: ns3::PointToPointStarHelper [class]
-    module.add_class('PointToPointStarHelper', allow_subclassing=False)
+    module.add_class('PointToPointStarHelper')
     ## tap-bridge-helper.h: ns3::TapBridgeHelper [class]
-    module.add_class('TapBridgeHelper', allow_subclassing=False)
+    module.add_class('TapBridgeHelper')
     ## udp-client-server-helper.h: ns3::UdpClientHelper [class]
-    module.add_class('UdpClientHelper', allow_subclassing=False)
+    module.add_class('UdpClientHelper')
     ## udp-echo-helper.h: ns3::UdpEchoClientHelper [class]
-    module.add_class('UdpEchoClientHelper', allow_subclassing=False)
+    module.add_class('UdpEchoClientHelper')
     ## udp-echo-helper.h: ns3::UdpEchoServerHelper [class]
-    module.add_class('UdpEchoServerHelper', allow_subclassing=False)
+    module.add_class('UdpEchoServerHelper')
     ## udp-client-server-helper.h: ns3::UdpServerHelper [class]
-    module.add_class('UdpServerHelper', allow_subclassing=False)
+    module.add_class('UdpServerHelper')
     ## udp-client-server-helper.h: ns3::UdpTraceClientHelper [class]
-    module.add_class('UdpTraceClientHelper', allow_subclassing=False)
+    module.add_class('UdpTraceClientHelper')
     ## v4ping-helper.h: ns3::V4PingHelper [class]
-    module.add_class('V4PingHelper', allow_subclassing=False)
+    module.add_class('V4PingHelper')
     ## wifi-helper.h: ns3::WifiHelper [class]
-    module.add_class('WifiHelper', allow_subclassing=False)
+    module.add_class('WifiHelper')
     ## wifi-helper.h: ns3::WifiMacHelper [class]
-    module.add_class('WifiMacHelper', allow_subclassing=False)
+    module.add_class('WifiMacHelper', allow_subclassing=True)
     ## wifi-helper.h: ns3::WifiPhyHelper [class]
-    module.add_class('WifiPhyHelper', allow_subclassing=False)
+    module.add_class('WifiPhyHelper', allow_subclassing=True)
     ## yans-wifi-helper.h: ns3::YansWifiChannelHelper [class]
-    module.add_class('YansWifiChannelHelper', allow_subclassing=False)
+    module.add_class('YansWifiChannelHelper')
     ## yans-wifi-helper.h: ns3::YansWifiPhyHelper [class]
-    module.add_class('YansWifiPhyHelper', allow_subclassing=False, parent=root_module['ns3::WifiPhyHelper'])
-    ## yans-wifi-helper.h: ns3::YansWifiPhyHelper::PcapFormat [enumeration]
-    module.add_enum('PcapFormat', ['PCAP_FORMAT_80211', 'PCAP_FORMAT_80211_PRISM', 'PCAP_FORMAT_80211_RADIOTAP'], outer_class=root_module['ns3::YansWifiPhyHelper'])
+    module.add_class('YansWifiPhyHelper', parent=[root_module['ns3::WifiPhyHelper'], root_module['ns3::PcapHelperForDevice'], root_module['ns3::AsciiTraceHelperForDevice']])
+    ## yans-wifi-helper.h: ns3::YansWifiPhyHelper::SupportedPcapDataLinkTypes [enumeration]
+    module.add_enum('SupportedPcapDataLinkTypes', ['DLT_IEEE802_11', 'DLT_PRISM_HEADER', 'DLT_IEEE802_11_RADIO'], outer_class=root_module['ns3::YansWifiPhyHelper'])
     ## aodv-helper.h: ns3::AodvHelper [class]
-    module.add_class('AodvHelper', allow_subclassing=False, parent=root_module['ns3::Ipv4RoutingHelper'])
+    module.add_class('AodvHelper', parent=root_module['ns3::Ipv4RoutingHelper'])
+    ## csma-helper.h: ns3::CsmaHelper [class]
+    module.add_class('CsmaHelper', parent=[root_module['ns3::PcapHelperForDevice'], root_module['ns3::AsciiTraceHelperForDevice']])
+    ## emu-helper.h: ns3::EmuHelper [class]
+    module.add_class('EmuHelper', parent=[root_module['ns3::PcapHelperForDevice'], root_module['ns3::AsciiTraceHelperForDevice']])
+    ## internet-stack-helper.h: ns3::InternetStackHelper [class]
+    module.add_class('InternetStackHelper', parent=[root_module['ns3::PcapHelperForIpv4'], root_module['ns3::PcapHelperForIpv6'], root_module['ns3::AsciiTraceHelperForIpv4'], root_module['ns3::AsciiTraceHelperForIpv6']])
     ## ipv4-global-routing-helper.h: ns3::Ipv4GlobalRoutingHelper [class]
-    module.add_class('Ipv4GlobalRoutingHelper', allow_subclassing=False, parent=root_module['ns3::Ipv4RoutingHelper'])
+    module.add_class('Ipv4GlobalRoutingHelper', parent=root_module['ns3::Ipv4RoutingHelper'])
     ## ipv4-list-routing-helper.h: ns3::Ipv4ListRoutingHelper [class]
-    module.add_class('Ipv4ListRoutingHelper', allow_subclassing=False, parent=root_module['ns3::Ipv4RoutingHelper'])
+    module.add_class('Ipv4ListRoutingHelper', parent=root_module['ns3::Ipv4RoutingHelper'])
     ## ipv4-nix-vector-helper.h: ns3::Ipv4NixVectorHelper [class]
-    module.add_class('Ipv4NixVectorHelper', allow_subclassing=False, parent=root_module['ns3::Ipv4RoutingHelper'])
+    module.add_class('Ipv4NixVectorHelper', parent=root_module['ns3::Ipv4RoutingHelper'])
     ## ipv6-list-routing-helper.h: ns3::Ipv6ListRoutingHelper [class]
-    module.add_class('Ipv6ListRoutingHelper', allow_subclassing=False, parent=root_module['ns3::Ipv6RoutingHelper'])
+    module.add_class('Ipv6ListRoutingHelper', parent=root_module['ns3::Ipv6RoutingHelper'])
     ## nqos-wifi-mac-helper.h: ns3::NqosWifiMacHelper [class]
-    module.add_class('NqosWifiMacHelper', allow_subclassing=False, parent=root_module['ns3::WifiMacHelper'])
+    module.add_class('NqosWifiMacHelper', parent=root_module['ns3::WifiMacHelper'])
     ## qos-wifi-mac-helper.h: ns3::QosWifiMacHelper [class]
-    module.add_class('QosWifiMacHelper', allow_subclassing=False, parent=root_module['ns3::WifiMacHelper'])
+    module.add_class('QosWifiMacHelper', parent=root_module['ns3::WifiMacHelper'])
     ## athstats-helper.h: ns3::AthstatsWifiTraceSink [class]
     module.add_class('AthstatsWifiTraceSink', parent=root_module['ns3::Object'])
     ## canvas-location.h: ns3::CanvasLocation [class]
@@ -201,13 +219,14 @@
 def register_methods(root_module):
     register_Ns3AnimationInterface_methods(root_module, root_module['ns3::AnimationInterface'])
     register_Ns3ApplicationContainer_methods(root_module, root_module['ns3::ApplicationContainer'])
+    register_Ns3AsciiTraceHelper_methods(root_module, root_module['ns3::AsciiTraceHelper'])
+    register_Ns3AsciiTraceHelperForDevice_methods(root_module, root_module['ns3::AsciiTraceHelperForDevice'])
+    register_Ns3AsciiTraceHelperForIpv4_methods(root_module, root_module['ns3::AsciiTraceHelperForIpv4'])
+    register_Ns3AsciiTraceHelperForIpv6_methods(root_module, root_module['ns3::AsciiTraceHelperForIpv6'])
     register_Ns3AthstatsHelper_methods(root_module, root_module['ns3::AthstatsHelper'])
     register_Ns3BridgeHelper_methods(root_module, root_module['ns3::BridgeHelper'])
-    register_Ns3CsmaHelper_methods(root_module, root_module['ns3::CsmaHelper'])
     register_Ns3CsmaStarHelper_methods(root_module, root_module['ns3::CsmaStarHelper'])
-    register_Ns3EmuHelper_methods(root_module, root_module['ns3::EmuHelper'])
     register_Ns3FlowMonitorHelper_methods(root_module, root_module['ns3::FlowMonitorHelper'])
-    register_Ns3InternetStackHelper_methods(root_module, root_module['ns3::InternetStackHelper'])
     register_Ns3Ipv4AddressHelper_methods(root_module, root_module['ns3::Ipv4AddressHelper'])
     register_Ns3Ipv4InterfaceContainer_methods(root_module, root_module['ns3::Ipv4InterfaceContainer'])
     register_Ns3Ipv4RoutingHelper_methods(root_module, root_module['ns3::Ipv4RoutingHelper'])
@@ -225,6 +244,10 @@
     register_Ns3OnOffHelper_methods(root_module, root_module['ns3::OnOffHelper'])
     register_Ns3PacketSinkHelper_methods(root_module, root_module['ns3::PacketSinkHelper'])
     register_Ns3PacketSocketHelper_methods(root_module, root_module['ns3::PacketSocketHelper'])
+    register_Ns3PcapHelper_methods(root_module, root_module['ns3::PcapHelper'])
+    register_Ns3PcapHelperForDevice_methods(root_module, root_module['ns3::PcapHelperForDevice'])
+    register_Ns3PcapHelperForIpv4_methods(root_module, root_module['ns3::PcapHelperForIpv4'])
+    register_Ns3PcapHelperForIpv6_methods(root_module, root_module['ns3::PcapHelperForIpv6'])
     register_Ns3Ping6Helper_methods(root_module, root_module['ns3::Ping6Helper'])
     register_Ns3PointToPointDumbbellHelper_methods(root_module, root_module['ns3::PointToPointDumbbellHelper'])
     register_Ns3PointToPointGridHelper_methods(root_module, root_module['ns3::PointToPointGridHelper'])
@@ -243,6 +266,9 @@
     register_Ns3YansWifiChannelHelper_methods(root_module, root_module['ns3::YansWifiChannelHelper'])
     register_Ns3YansWifiPhyHelper_methods(root_module, root_module['ns3::YansWifiPhyHelper'])
     register_Ns3AodvHelper_methods(root_module, root_module['ns3::AodvHelper'])
+    register_Ns3CsmaHelper_methods(root_module, root_module['ns3::CsmaHelper'])
+    register_Ns3EmuHelper_methods(root_module, root_module['ns3::EmuHelper'])
+    register_Ns3InternetStackHelper_methods(root_module, root_module['ns3::InternetStackHelper'])
     register_Ns3Ipv4GlobalRoutingHelper_methods(root_module, root_module['ns3::Ipv4GlobalRoutingHelper'])
     register_Ns3Ipv4ListRoutingHelper_methods(root_module, root_module['ns3::Ipv4ListRoutingHelper'])
     register_Ns3Ipv4NixVectorHelper_methods(root_module, root_module['ns3::Ipv4NixVectorHelper'])
@@ -330,6 +356,245 @@
                    [param('ns3::Time', 'stop')])
     return
 
+def register_Ns3AsciiTraceHelper_methods(root_module, cls):
+    ## trace-helper.h: ns3::AsciiTraceHelper::AsciiTraceHelper(ns3::AsciiTraceHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::AsciiTraceHelper const &', 'arg0')])
+    ## trace-helper.h: ns3::AsciiTraceHelper::AsciiTraceHelper() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: ns3::Ptr<ns3::OutputStreamWrapper> ns3::AsciiTraceHelper::CreateFileStream(std::string filename, std::string filemode="w") [member function]
+    cls.add_method('CreateFileStream', 
+                   'ns3::Ptr< ns3::OutputStreamWrapper >', 
+                   [param('std::string', 'filename'), param('std::string', 'filemode', default_value='"w"')])
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultDequeueSinkWithContext(ns3::Ptr<ns3::OutputStreamWrapper> file, std::string context, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultDequeueSinkWithContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('std::string', 'context'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultDequeueSinkWithoutContext(ns3::Ptr<ns3::OutputStreamWrapper> file, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultDequeueSinkWithoutContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultDropSinkWithContext(ns3::Ptr<ns3::OutputStreamWrapper> file, std::string context, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultDropSinkWithContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('std::string', 'context'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultDropSinkWithoutContext(ns3::Ptr<ns3::OutputStreamWrapper> file, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultDropSinkWithoutContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultEnqueueSinkWithContext(ns3::Ptr<ns3::OutputStreamWrapper> file, std::string context, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultEnqueueSinkWithContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('std::string', 'context'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultEnqueueSinkWithoutContext(ns3::Ptr<ns3::OutputStreamWrapper> file, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultEnqueueSinkWithoutContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultReceiveSinkWithContext(ns3::Ptr<ns3::OutputStreamWrapper> file, std::string context, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultReceiveSinkWithContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('std::string', 'context'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: static void ns3::AsciiTraceHelper::DefaultReceiveSinkWithoutContext(ns3::Ptr<ns3::OutputStreamWrapper> file, ns3::Ptr<ns3::Packet const> p) [member function]
+    cls.add_method('DefaultReceiveSinkWithoutContext', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'file'), param('ns3::Ptr< ns3::Packet const >', 'p')], 
+                   is_static=True)
+    ## trace-helper.h: std::string ns3::AsciiTraceHelper::GetFilenameFromDevice(std::string prefix, ns3::Ptr<ns3::NetDevice> device, bool useObjectNames=true) [member function]
+    cls.add_method('GetFilenameFromDevice', 
+                   'std::string', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'device'), param('bool', 'useObjectNames', default_value='true')])
+    ## trace-helper.h: std::string ns3::AsciiTraceHelper::GetFilenameFromInterfacePair(std::string prefix, ns3::Ptr<ns3::Object> object, uint32_t interface, bool useObjectNames=true) [member function]
+    cls.add_method('GetFilenameFromInterfacePair', 
+                   'std::string', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Object >', 'object'), param('uint32_t', 'interface'), param('bool', 'useObjectNames', default_value='true')])
+    return
+
+def register_Ns3AsciiTraceHelperForDevice_methods(root_module, cls):
+    ## trace-helper.h: ns3::AsciiTraceHelperForDevice::AsciiTraceHelperForDevice(ns3::AsciiTraceHelperForDevice const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::AsciiTraceHelperForDevice const &', 'arg0')])
+    ## trace-helper.h: ns3::AsciiTraceHelperForDevice::AsciiTraceHelperForDevice() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(std::string prefix, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::Ptr< ns3::NetDevice >', 'nd')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(std::string prefix, std::string ndName) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('std::string', 'ndName')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string ndName) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'ndName')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(std::string prefix, ns3::NetDeviceContainer d) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NetDeviceContainer', 'd')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::NetDeviceContainer d) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::NetDeviceContainer', 'd')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(std::string prefix, ns3::NodeContainer n) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::NodeContainer n) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(std::string prefix, uint32_t nodeid, uint32_t deviceid) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAscii(ns3::Ptr<ns3::OutputStreamWrapper> stream, uint32_t nodeid, uint32_t deviceid) [member function]
+    cls.add_method('EnableAscii', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAsciiAll(std::string prefix) [member function]
+    cls.add_method('EnableAsciiAll', 
+                   'void', 
+                   [param('std::string', 'prefix')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAsciiAll(ns3::Ptr<ns3::OutputStreamWrapper> stream) [member function]
+    cls.add_method('EnableAsciiAll', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForDevice::EnableAsciiInternal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnableAsciiInternal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
+def register_Ns3AsciiTraceHelperForIpv4_methods(root_module, cls):
+    ## trace-helper.h: ns3::AsciiTraceHelperForIpv4::AsciiTraceHelperForIpv4(ns3::AsciiTraceHelperForIpv4 const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::AsciiTraceHelperForIpv4 const &', 'arg0')])
+    ## trace-helper.h: ns3::AsciiTraceHelperForIpv4::AsciiTraceHelperForIpv4() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(std::string prefix, ns3::Ptr<ns3::Ipv4> ipv4, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::Ptr<ns3::Ipv4> ipv4, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(std::string prefix, std::string ipv4Name, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('std::string', 'ipv4Name'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string ipv4Name, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'ipv4Name'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(std::string prefix, ns3::Ipv4InterfaceContainer c) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ipv4InterfaceContainer', 'c')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::Ipv4InterfaceContainer c) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::Ipv4InterfaceContainer', 'c')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(std::string prefix, ns3::NodeContainer n) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::NodeContainer n) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(std::string prefix, uint32_t nodeid, uint32_t deviceid) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4(ns3::Ptr<ns3::OutputStreamWrapper> stream, uint32_t nodeid, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv4', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('uint32_t', 'nodeid'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4All(std::string prefix) [member function]
+    cls.add_method('EnableAsciiIpv4All', 
+                   'void', 
+                   [param('std::string', 'prefix')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4All(ns3::Ptr<ns3::OutputStreamWrapper> stream) [member function]
+    cls.add_method('EnableAsciiIpv4All', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv4::EnableAsciiIpv4Internal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::Ipv4> ipv4, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv4Internal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
+def register_Ns3AsciiTraceHelperForIpv6_methods(root_module, cls):
+    ## trace-helper.h: ns3::AsciiTraceHelperForIpv6::AsciiTraceHelperForIpv6(ns3::AsciiTraceHelperForIpv6 const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::AsciiTraceHelperForIpv6 const &', 'arg0')])
+    ## trace-helper.h: ns3::AsciiTraceHelperForIpv6::AsciiTraceHelperForIpv6() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(std::string prefix, ns3::Ptr<ns3::Ipv6> ipv6, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv6 >', 'ipv6'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::Ptr<ns3::Ipv6> ipv6, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::Ptr< ns3::Ipv6 >', 'ipv6'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(std::string prefix, std::string ipv6Name, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('std::string', 'ipv6Name'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string ipv6Name, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'ipv6Name'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(std::string prefix, ns3::Ipv6InterfaceContainer c) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ipv6InterfaceContainer', 'c')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::Ipv6InterfaceContainer c) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::Ipv6InterfaceContainer', 'c')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(std::string prefix, ns3::NodeContainer n) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(ns3::Ptr<ns3::OutputStreamWrapper> stream, ns3::NodeContainer n) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(std::string prefix, uint32_t nodeid, uint32_t deviceid) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6(ns3::Ptr<ns3::OutputStreamWrapper> stream, uint32_t nodeid, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv6', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('uint32_t', 'nodeid'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6All(std::string prefix) [member function]
+    cls.add_method('EnableAsciiIpv6All', 
+                   'void', 
+                   [param('std::string', 'prefix')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6All(ns3::Ptr<ns3::OutputStreamWrapper> stream) [member function]
+    cls.add_method('EnableAsciiIpv6All', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream')])
+    ## trace-helper.h: void ns3::AsciiTraceHelperForIpv6::EnableAsciiIpv6Internal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::Ipv6> ipv6, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv6Internal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv6 >', 'ipv6'), param('uint32_t', 'interface')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
 def register_Ns3AthstatsHelper_methods(root_module, cls):
     ## athstats-helper.h: ns3::AthstatsHelper::AthstatsHelper(ns3::AthstatsHelper const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::AthstatsHelper const &', 'arg0')])
@@ -372,120 +637,6 @@
                    [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
     return
 
-def register_Ns3CsmaHelper_methods(root_module, cls):
-    ## csma-helper.h: ns3::CsmaHelper::CsmaHelper(ns3::CsmaHelper const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::CsmaHelper const &', 'arg0')])
-    ## csma-helper.h: ns3::CsmaHelper::CsmaHelper() [constructor]
-    cls.add_constructor([])
-    ## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NetDeviceContainer', 'd')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnableAsciiAll(std::ostream & os) [member function]
-    cls.add_method('EnableAsciiAll', 
-                   'void', 
-                   [param('std::ostream &', 'os')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, std::string ndName, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('std::string', 'ndName'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::NodeContainer n, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NodeContainer', 'n'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcapAll(std::string filename, bool promiscuous) [member function]
-    cls.add_method('EnablePcapAll', 
-                   'void', 
-                   [param('std::string', 'filename'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::Ptr<ns3::Node> node) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::Ptr< ns3::Node >', 'node')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(std::string name) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('std::string', 'name')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::Ptr<ns3::Node> node, ns3::Ptr<ns3::CsmaChannel> channel) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::Ptr<ns3::Node> node, std::string channelName) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::Ptr< ns3::Node >', 'node'), param('std::string', 'channelName')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(std::string nodeName, ns3::Ptr<ns3::CsmaChannel> channel) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('std::string', 'nodeName'), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(std::string nodeName, std::string channelName) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('std::string', 'nodeName'), param('std::string', 'channelName')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::NodeContainer const &', 'c')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c, ns3::Ptr<ns3::CsmaChannel> channel) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::NodeContainer const &', 'c'), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')], 
-                   is_const=True)
-    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c, std::string channelName) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::NodeContainer const &', 'c'), param('std::string', 'channelName')], 
-                   is_const=True)
-    ## csma-helper.h: void ns3::CsmaHelper::SetChannelAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
-    cls.add_method('SetChannelAttribute', 
-                   'void', 
-                   [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
-    ## csma-helper.h: void ns3::CsmaHelper::SetDeviceAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
-    cls.add_method('SetDeviceAttribute', 
-                   'void', 
-                   [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
-    ## csma-helper.h: void ns3::CsmaHelper::SetQueue(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue()) [member function]
-    cls.add_method('SetQueue', 
-                   'void', 
-                   [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()')])
-    return
-
 def register_Ns3CsmaStarHelper_methods(root_module, cls):
     ## csma-star-helper.h: ns3::CsmaStarHelper::CsmaStarHelper(ns3::CsmaStarHelper const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::CsmaStarHelper const &', 'arg0')])
@@ -536,86 +687,6 @@
                    is_const=True)
     return
 
-def register_Ns3EmuHelper_methods(root_module, cls):
-    ## emu-helper.h: ns3::EmuHelper::EmuHelper(ns3::EmuHelper const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::EmuHelper const &', 'arg0')])
-    ## emu-helper.h: ns3::EmuHelper::EmuHelper() [constructor]
-    cls.add_constructor([])
-    ## emu-helper.h: static void ns3::EmuHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NetDeviceContainer', 'd')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnableAsciiAll(std::ostream & os) [member function]
-    cls.add_method('EnableAsciiAll', 
-                   'void', 
-                   [param('std::ostream &', 'os')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, std::string ndName, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('std::string', 'ndName'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, ns3::NodeContainer n, bool promiscuous) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NodeContainer', 'n'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcapAll(std::string filename, bool promiscuous) [member function]
-    cls.add_method('EnablePcapAll', 
-                   'void', 
-                   [param('std::string', 'filename'), param('bool', 'promiscuous')], 
-                   is_static=True)
-    ## emu-helper.h: ns3::NetDeviceContainer ns3::EmuHelper::Install(ns3::Ptr<ns3::Node> node) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::Ptr< ns3::Node >', 'node')], 
-                   is_const=True)
-    ## emu-helper.h: ns3::NetDeviceContainer ns3::EmuHelper::Install(std::string nodeName) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('std::string', 'nodeName')], 
-                   is_const=True)
-    ## emu-helper.h: ns3::NetDeviceContainer ns3::EmuHelper::Install(ns3::NodeContainer const & c) const [member function]
-    cls.add_method('Install', 
-                   'ns3::NetDeviceContainer', 
-                   [param('ns3::NodeContainer const &', 'c')], 
-                   is_const=True)
-    ## emu-helper.h: void ns3::EmuHelper::SetAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
-    cls.add_method('SetAttribute', 
-                   'void', 
-                   [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
-    ## emu-helper.h: void ns3::EmuHelper::SetQueue(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue()) [member function]
-    cls.add_method('SetQueue', 
-                   'void', 
-                   [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()')])
-    return
-
 def register_Ns3FlowMonitorHelper_methods(root_module, cls):
     ## flow-monitor-helper.h: ns3::FlowMonitorHelper::FlowMonitorHelper(ns3::FlowMonitorHelper const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::FlowMonitorHelper const &', 'arg0')])
@@ -647,76 +718,6 @@
                    [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
     return
 
-def register_Ns3InternetStackHelper_methods(root_module, cls):
-    ## internet-stack-helper.h: ns3::InternetStackHelper::InternetStackHelper() [constructor]
-    cls.add_constructor([])
-    ## internet-stack-helper.h: ns3::InternetStackHelper::InternetStackHelper(ns3::InternetStackHelper const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::InternetStackHelper const &', 'arg0')])
-    ## internet-stack-helper.h: static void ns3::InternetStackHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')], 
-                   is_static=True)
-    ## internet-stack-helper.h: static void ns3::InternetStackHelper::EnableAsciiAll(std::ostream & os) [member function]
-    cls.add_method('EnableAsciiAll', 
-                   'void', 
-                   [param('std::ostream &', 'os')], 
-                   is_static=True)
-    ## internet-stack-helper.h: static void ns3::InternetStackHelper::EnablePcapAll(std::string filename) [member function]
-    cls.add_method('EnablePcapAll', 
-                   'void', 
-                   [param('std::string', 'filename')], 
-                   is_static=True)
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::Install(std::string nodeName) const [member function]
-    cls.add_method('Install', 
-                   'void', 
-                   [param('std::string', 'nodeName')], 
-                   is_const=True)
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::Install(ns3::Ptr<ns3::Node> node) const [member function]
-    cls.add_method('Install', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::Node >', 'node')], 
-                   is_const=True)
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::Install(ns3::NodeContainer c) const [member function]
-    cls.add_method('Install', 
-                   'void', 
-                   [param('ns3::NodeContainer', 'c')], 
-                   is_const=True)
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::InstallAll() const [member function]
-    cls.add_method('InstallAll', 
-                   'void', 
-                   [], 
-                   is_const=True)
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::Reset() [member function]
-    cls.add_method('Reset', 
-                   'void', 
-                   [])
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetIpv4StackInstall(bool enable) [member function]
-    cls.add_method('SetIpv4StackInstall', 
-                   'void', 
-                   [param('bool', 'enable')])
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetIpv6StackInstall(bool enable) [member function]
-    cls.add_method('SetIpv6StackInstall', 
-                   'void', 
-                   [param('bool', 'enable')])
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetRoutingHelper(ns3::Ipv4RoutingHelper const & routing) [member function]
-    cls.add_method('SetRoutingHelper', 
-                   'void', 
-                   [param('ns3::Ipv4RoutingHelper const &', 'routing')])
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetRoutingHelper(ns3::Ipv6RoutingHelper const & routing) [member function]
-    cls.add_method('SetRoutingHelper', 
-                   'void', 
-                   [param('ns3::Ipv6RoutingHelper const &', 'routing')])
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetTcp(std::string tid) [member function]
-    cls.add_method('SetTcp', 
-                   'void', 
-                   [param('std::string', 'tid')])
-    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetTcp(std::string tid, std::string attr, ns3::AttributeValue const & val) [member function]
-    cls.add_method('SetTcp', 
-                   'void', 
-                   [param('std::string', 'tid'), param('std::string', 'attr'), param('ns3::AttributeValue const &', 'val')])
-    return
-
 def register_Ns3Ipv4AddressHelper_methods(root_module, cls):
     ## ipv4-address-helper.h: ns3::Ipv4AddressHelper::Ipv4AddressHelper(ns3::Ipv4AddressHelper const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Ipv4AddressHelper const &', 'arg0')])
@@ -763,6 +764,16 @@
     cls.add_method('Add', 
                    'void', 
                    [param('std::string', 'ipv4Name'), param('uint32_t', 'interface')])
+    ## ipv4-interface-container.h: __gnu_cxx::__normal_iterator<const std::pair<ns3::Ptr<ns3::Ipv4>, unsigned int>*,std::vector<std::pair<ns3::Ptr<ns3::Ipv4>, unsigned int>, std::allocator<std::pair<ns3::Ptr<ns3::Ipv4>, unsigned int> > > > ns3::Ipv4InterfaceContainer::Begin() const [member function]
+    cls.add_method('Begin', 
+                   '__gnu_cxx::__normal_iterator< std::pair< ns3::Ptr< ns3::Ipv4 >, unsigned int > const, std::vector< std::pair< ns3::Ptr< ns3::Ipv4 >, unsigned int > > >', 
+                   [], 
+                   is_const=True)
+    ## ipv4-interface-container.h: __gnu_cxx::__normal_iterator<const std::pair<ns3::Ptr<ns3::Ipv4>, unsigned int>*,std::vector<std::pair<ns3::Ptr<ns3::Ipv4>, unsigned int>, std::allocator<std::pair<ns3::Ptr<ns3::Ipv4>, unsigned int> > > > ns3::Ipv4InterfaceContainer::End() const [member function]
+    cls.add_method('End', 
+                   '__gnu_cxx::__normal_iterator< std::pair< ns3::Ptr< ns3::Ipv4 >, unsigned int > const, std::vector< std::pair< ns3::Ptr< ns3::Ipv4 >, unsigned int > > >', 
+                   [], 
+                   is_const=True)
     ## ipv4-interface-container.h: std::pair<ns3::Ptr<ns3::Ipv4>,unsigned int> ns3::Ipv4InterfaceContainer::Get(uint32_t i) const [member function]
     cls.add_method('Get', 
                    'std::pair< ns3::Ptr< ns3::Ipv4 >, unsigned int >', 
@@ -899,6 +910,16 @@
     cls.add_method('Add', 
                    'void', 
                    [param('std::string', 'ipv6Name'), param('uint32_t', 'interface')])
+    ## ipv6-interface-container.h: __gnu_cxx::__normal_iterator<const std::pair<ns3::Ptr<ns3::Ipv6>, unsigned int>*,std::vector<std::pair<ns3::Ptr<ns3::Ipv6>, unsigned int>, std::allocator<std::pair<ns3::Ptr<ns3::Ipv6>, unsigned int> > > > ns3::Ipv6InterfaceContainer::Begin() const [member function]
+    cls.add_method('Begin', 
+                   '__gnu_cxx::__normal_iterator< std::pair< ns3::Ptr< ns3::Ipv6 >, unsigned int > const, std::vector< std::pair< ns3::Ptr< ns3::Ipv6 >, unsigned int > > >', 
+                   [], 
+                   is_const=True)
+    ## ipv6-interface-container.h: __gnu_cxx::__normal_iterator<const std::pair<ns3::Ptr<ns3::Ipv6>, unsigned int>*,std::vector<std::pair<ns3::Ptr<ns3::Ipv6>, unsigned int>, std::allocator<std::pair<ns3::Ptr<ns3::Ipv6>, unsigned int> > > > ns3::Ipv6InterfaceContainer::End() const [member function]
+    cls.add_method('End', 
+                   '__gnu_cxx::__normal_iterator< std::pair< ns3::Ptr< ns3::Ipv6 >, unsigned int > const, std::vector< std::pair< ns3::Ptr< ns3::Ipv6 >, unsigned int > > >', 
+                   [], 
+                   is_const=True)
     ## ipv6-interface-container.h: ns3::Ipv6Address ns3::Ipv6InterfaceContainer::GetAddress(uint32_t i, uint32_t j) const [member function]
     cls.add_method('GetAddress', 
                    'ns3::Ipv6Address', 
@@ -1310,6 +1331,133 @@
                    is_const=True)
     return
 
+def register_Ns3PcapHelper_methods(root_module, cls):
+    ## trace-helper.h: ns3::PcapHelper::PcapHelper(ns3::PcapHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::PcapHelper const &', 'arg0')])
+    ## trace-helper.h: ns3::PcapHelper::PcapHelper() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: ns3::Ptr<ns3::PcapFileWrapper> ns3::PcapHelper::CreateFile(std::string filename, std::string filemode, uint32_t dataLinkType, uint32_t snapLen=65535, int32_t tzCorrection=0) [member function]
+    cls.add_method('CreateFile', 
+                   'ns3::Ptr< ns3::PcapFileWrapper >', 
+                   [param('std::string', 'filename'), param('std::string', 'filemode'), param('uint32_t', 'dataLinkType'), param('uint32_t', 'snapLen', default_value='65535'), param('int32_t', 'tzCorrection', default_value='0')])
+    ## trace-helper.h: std::string ns3::PcapHelper::GetFilenameFromDevice(std::string prefix, ns3::Ptr<ns3::NetDevice> device, bool useObjectNames=true) [member function]
+    cls.add_method('GetFilenameFromDevice', 
+                   'std::string', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'device'), param('bool', 'useObjectNames', default_value='true')])
+    ## trace-helper.h: std::string ns3::PcapHelper::GetFilenameFromInterfacePair(std::string prefix, ns3::Ptr<ns3::Object> object, uint32_t interface, bool useObjectNames=true) [member function]
+    cls.add_method('GetFilenameFromInterfacePair', 
+                   'std::string', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Object >', 'object'), param('uint32_t', 'interface'), param('bool', 'useObjectNames', default_value='true')])
+    return
+
+def register_Ns3PcapHelperForDevice_methods(root_module, cls):
+    ## trace-helper.h: ns3::PcapHelperForDevice::PcapHelperForDevice(ns3::PcapHelperForDevice const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::PcapHelperForDevice const &', 'arg0')])
+    ## trace-helper.h: ns3::PcapHelperForDevice::PcapHelperForDevice() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: void ns3::PcapHelperForDevice::EnablePcap(std::string prefix, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous', default_value='false')])
+    ## trace-helper.h: void ns3::PcapHelperForDevice::EnablePcap(std::string prefix, std::string ndName, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('std::string', 'ndName'), param('bool', 'promiscuous', default_value='false')])
+    ## trace-helper.h: void ns3::PcapHelperForDevice::EnablePcap(std::string prefix, ns3::NetDeviceContainer d, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NetDeviceContainer', 'd'), param('bool', 'promiscuous', default_value='false')])
+    ## trace-helper.h: void ns3::PcapHelperForDevice::EnablePcap(std::string prefix, ns3::NodeContainer n, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NodeContainer', 'n'), param('bool', 'promiscuous', default_value='false')])
+    ## trace-helper.h: void ns3::PcapHelperForDevice::EnablePcap(std::string prefix, uint32_t nodeid, uint32_t deviceid, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid'), param('bool', 'promiscuous', default_value='false')])
+    ## trace-helper.h: void ns3::PcapHelperForDevice::EnablePcapAll(std::string prefix, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcapAll', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('bool', 'promiscuous', default_value='false')])
+    ## trace-helper.h: void ns3::PcapHelperForDevice::EnablePcapInternal(std::string prefix, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous) [member function]
+    cls.add_method('EnablePcapInternal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
+def register_Ns3PcapHelperForIpv4_methods(root_module, cls):
+    ## trace-helper.h: ns3::PcapHelperForIpv4::PcapHelperForIpv4(ns3::PcapHelperForIpv4 const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::PcapHelperForIpv4 const &', 'arg0')])
+    ## trace-helper.h: ns3::PcapHelperForIpv4::PcapHelperForIpv4() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: void ns3::PcapHelperForIpv4::EnablePcapIpv4(std::string prefix, ns3::Ptr<ns3::Ipv4> ipv4, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv4::EnablePcapIpv4(std::string prefix, std::string ipv4Name, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('std::string', 'ipv4Name'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv4::EnablePcapIpv4(std::string prefix, ns3::Ipv4InterfaceContainer c) [member function]
+    cls.add_method('EnablePcapIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ipv4InterfaceContainer', 'c')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv4::EnablePcapIpv4(std::string prefix, ns3::NodeContainer n) [member function]
+    cls.add_method('EnablePcapIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv4::EnablePcapIpv4(std::string prefix, uint32_t nodeid, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv4', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('uint32_t', 'nodeid'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv4::EnablePcapIpv4All(std::string prefix) [member function]
+    cls.add_method('EnablePcapIpv4All', 
+                   'void', 
+                   [param('std::string', 'prefix')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv4::EnablePcapIpv4Internal(std::string prefix, ns3::Ptr<ns3::Ipv4> ipv4, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv4Internal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
+def register_Ns3PcapHelperForIpv6_methods(root_module, cls):
+    ## trace-helper.h: ns3::PcapHelperForIpv6::PcapHelperForIpv6(ns3::PcapHelperForIpv6 const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::PcapHelperForIpv6 const &', 'arg0')])
+    ## trace-helper.h: ns3::PcapHelperForIpv6::PcapHelperForIpv6() [constructor]
+    cls.add_constructor([])
+    ## trace-helper.h: void ns3::PcapHelperForIpv6::EnablePcapIpv6(std::string prefix, ns3::Ptr<ns3::Ipv6> ipv6, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv6 >', 'ipv6'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv6::EnablePcapIpv6(std::string prefix, std::string ipv6Name, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('std::string', 'ipv6Name'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv6::EnablePcapIpv6(std::string prefix, ns3::Ipv6InterfaceContainer c) [member function]
+    cls.add_method('EnablePcapIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ipv6InterfaceContainer', 'c')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv6::EnablePcapIpv6(std::string prefix, ns3::NodeContainer n) [member function]
+    cls.add_method('EnablePcapIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::NodeContainer', 'n')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv6::EnablePcapIpv6(std::string prefix, uint32_t nodeid, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv6', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('uint32_t', 'nodeid'), param('uint32_t', 'interface')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv6::EnablePcapIpv6All(std::string prefix) [member function]
+    cls.add_method('EnablePcapIpv6All', 
+                   'void', 
+                   [param('std::string', 'prefix')])
+    ## trace-helper.h: void ns3::PcapHelperForIpv6::EnablePcapIpv6Internal(std::string prefix, ns3::Ptr<ns3::Ipv6> ipv6, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv6Internal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv6 >', 'ipv6'), param('uint32_t', 'interface')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
 def register_Ns3Ping6Helper_methods(root_module, cls):
     ## ping6-helper.h: ns3::Ping6Helper::Ping6Helper(ns3::Ping6Helper const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Ping6Helper const &', 'arg0')])
@@ -1350,10 +1498,10 @@
     cls.add_method('AssignIpv4Addresses', 
                    'void', 
                    [param('ns3::Ipv4AddressHelper', 'leftIp'), param('ns3::Ipv4AddressHelper', 'rightIp'), param('ns3::Ipv4AddressHelper', 'routerIp')])
-    ## point-to-point-dumbbell-helper.h: void ns3::PointToPointDumbbellHelper::BoundingBox(double arg0, double arg1, double arg2, double arg3) [member function]
+    ## point-to-point-dumbbell-helper.h: void ns3::PointToPointDumbbellHelper::BoundingBox(double ulx, double uly, double lrx, double lry) [member function]
     cls.add_method('BoundingBox', 
                    'void', 
-                   [param('double', 'arg0'), param('double', 'arg1'), param('double', 'arg2'), param('double', 'arg3')])
+                   [param('double', 'ulx'), param('double', 'uly'), param('double', 'lrx'), param('double', 'lry')])
     ## point-to-point-dumbbell-helper.h: ns3::Ptr<ns3::Node> ns3::PointToPointDumbbellHelper::GetLeft() const [member function]
     cls.add_method('GetLeft', 
                    'ns3::Ptr< ns3::Node >', 
@@ -1432,56 +1580,6 @@
     cls.add_constructor([param('ns3::PointToPointHelper const &', 'arg0')])
     ## point-to-point-helper.h: ns3::PointToPointHelper::PointToPointHelper() [constructor]
     cls.add_constructor([])
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NetDeviceContainer', 'd')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAsciiAll(std::ostream & os) [member function]
-    cls.add_method('EnableAsciiAll', 
-                   'void', 
-                   [param('std::ostream &', 'os')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, std::string ndName) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('std::string', 'ndName')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], 
-                   is_static=True)
-    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcapAll(std::string filename) [member function]
-    cls.add_method('EnablePcapAll', 
-                   'void', 
-                   [param('std::string', 'filename')], 
-                   is_static=True)
     ## point-to-point-helper.h: ns3::NetDeviceContainer ns3::PointToPointHelper::Install(ns3::NodeContainer c) [member function]
     cls.add_method('Install', 
                    'ns3::NetDeviceContainer', 
@@ -1514,6 +1612,16 @@
     cls.add_method('SetQueue', 
                    'void', 
                    [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()')])
+    ## point-to-point-helper.h: void ns3::PointToPointHelper::EnableAsciiInternal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnableAsciiInternal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd')], 
+                   visibility='private', is_virtual=True)
+    ## point-to-point-helper.h: void ns3::PointToPointHelper::EnablePcapInternal(std::string prefix, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcapInternal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous', default_value='false')], 
+                   visibility='private', is_virtual=True)
     return
 
 def register_Ns3PointToPointStarHelper_methods(root_module, cls):
@@ -1837,50 +1945,6 @@
                    'ns3::YansWifiPhyHelper', 
                    [], 
                    is_static=True)
-    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
-                   is_static=True)
-    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NetDeviceContainer', 'd')], 
-                   is_static=True)
-    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
-    cls.add_method('EnableAscii', 
-                   'void', 
-                   [param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')], 
-                   is_static=True)
-    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnableAsciiAll(std::ostream & os) [member function]
-    cls.add_method('EnableAsciiAll', 
-                   'void', 
-                   [param('std::ostream &', 'os')], 
-                   is_static=True)
-    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')])
-    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd')])
-    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, std::string ndName) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('std::string', 'ndName')])
-    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')])
-    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
-    cls.add_method('EnablePcap', 
-                   'void', 
-                   [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')])
-    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcapAll(std::string filename) [member function]
-    cls.add_method('EnablePcapAll', 
-                   'void', 
-                   [param('std::string', 'filename')])
     ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::Set(std::string name, ns3::AttributeValue const & v) [member function]
     cls.add_method('Set', 
                    'void', 
@@ -1897,15 +1961,25 @@
     cls.add_method('SetErrorRateModel', 
                    'void', 
                    [param('std::string', 'name'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')])
-    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::SetPcapFormat(ns3::YansWifiPhyHelper::PcapFormat format) [member function]
-    cls.add_method('SetPcapFormat', 
+    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::SetPcapDataLinkType(ns3::YansWifiPhyHelper::SupportedPcapDataLinkTypes dlt) [member function]
+    cls.add_method('SetPcapDataLinkType', 
                    'void', 
-                   [param('ns3::YansWifiPhyHelper::PcapFormat', 'format')])
+                   [param('ns3::YansWifiPhyHelper::SupportedPcapDataLinkTypes', 'dlt')])
     ## yans-wifi-helper.h: ns3::Ptr<ns3::WifiPhy> ns3::YansWifiPhyHelper::Create(ns3::Ptr<ns3::Node> node, ns3::Ptr<ns3::WifiNetDevice> device) const [member function]
     cls.add_method('Create', 
                    'ns3::Ptr< ns3::WifiPhy >', 
                    [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Ptr< ns3::WifiNetDevice >', 'device')], 
                    is_const=True, visibility='private', is_virtual=True)
+    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnableAsciiInternal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnableAsciiInternal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd')], 
+                   visibility='private', is_virtual=True)
+    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcapInternal(std::string prefix, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous) [member function]
+    cls.add_method('EnablePcapInternal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous')], 
+                   visibility='private', is_virtual=True)
     return
 
 def register_Ns3AodvHelper_methods(root_module, cls):
@@ -1929,6 +2003,195 @@
                    [param('std::string', 'name'), param('ns3::AttributeValue const &', 'value')])
     return
 
+def register_Ns3CsmaHelper_methods(root_module, cls):
+    ## csma-helper.h: ns3::CsmaHelper::CsmaHelper(ns3::CsmaHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::CsmaHelper const &', 'arg0')])
+    ## csma-helper.h: ns3::CsmaHelper::CsmaHelper() [constructor]
+    cls.add_constructor([])
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::Ptr<ns3::Node> node) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::Ptr< ns3::Node >', 'node')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(std::string name) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('std::string', 'name')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::Ptr<ns3::Node> node, ns3::Ptr<ns3::CsmaChannel> channel) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::Ptr<ns3::Node> node, std::string channelName) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::Ptr< ns3::Node >', 'node'), param('std::string', 'channelName')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(std::string nodeName, ns3::Ptr<ns3::CsmaChannel> channel) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('std::string', 'nodeName'), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(std::string nodeName, std::string channelName) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('std::string', 'nodeName'), param('std::string', 'channelName')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::NodeContainer const &', 'c')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c, ns3::Ptr<ns3::CsmaChannel> channel) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::NodeContainer const &', 'c'), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')], 
+                   is_const=True)
+    ## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c, std::string channelName) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::NodeContainer const &', 'c'), param('std::string', 'channelName')], 
+                   is_const=True)
+    ## csma-helper.h: void ns3::CsmaHelper::SetChannelAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
+    cls.add_method('SetChannelAttribute', 
+                   'void', 
+                   [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
+    ## csma-helper.h: void ns3::CsmaHelper::SetDeviceAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
+    cls.add_method('SetDeviceAttribute', 
+                   'void', 
+                   [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
+    ## csma-helper.h: void ns3::CsmaHelper::SetQueue(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue()) [member function]
+    cls.add_method('SetQueue', 
+                   'void', 
+                   [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()')])
+    ## csma-helper.h: void ns3::CsmaHelper::EnableAsciiInternal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnableAsciiInternal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd')], 
+                   visibility='private', is_virtual=True)
+    ## csma-helper.h: void ns3::CsmaHelper::EnablePcapInternal(std::string prefix, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcapInternal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous', default_value='false')], 
+                   visibility='private', is_virtual=True)
+    return
+
+def register_Ns3EmuHelper_methods(root_module, cls):
+    ## emu-helper.h: ns3::EmuHelper::EmuHelper(ns3::EmuHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::EmuHelper const &', 'arg0')])
+    ## emu-helper.h: ns3::EmuHelper::EmuHelper() [constructor]
+    cls.add_constructor([])
+    ## emu-helper.h: ns3::NetDeviceContainer ns3::EmuHelper::Install(ns3::Ptr<ns3::Node> node) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::Ptr< ns3::Node >', 'node')], 
+                   is_const=True)
+    ## emu-helper.h: ns3::NetDeviceContainer ns3::EmuHelper::Install(std::string nodeName) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('std::string', 'nodeName')], 
+                   is_const=True)
+    ## emu-helper.h: ns3::NetDeviceContainer ns3::EmuHelper::Install(ns3::NodeContainer const & c) const [member function]
+    cls.add_method('Install', 
+                   'ns3::NetDeviceContainer', 
+                   [param('ns3::NodeContainer const &', 'c')], 
+                   is_const=True)
+    ## emu-helper.h: void ns3::EmuHelper::SetAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
+    cls.add_method('SetAttribute', 
+                   'void', 
+                   [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
+    ## emu-helper.h: void ns3::EmuHelper::SetQueue(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue()) [member function]
+    cls.add_method('SetQueue', 
+                   'void', 
+                   [param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()')])
+    ## emu-helper.h: void ns3::EmuHelper::EnableAsciiInternal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnableAsciiInternal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd')], 
+                   visibility='private', is_virtual=True)
+    ## emu-helper.h: void ns3::EmuHelper::EnablePcapInternal(std::string prefix, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous=false) [member function]
+    cls.add_method('EnablePcapInternal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous', default_value='false')], 
+                   visibility='private', is_virtual=True)
+    return
+
+def register_Ns3InternetStackHelper_methods(root_module, cls):
+    ## internet-stack-helper.h: ns3::InternetStackHelper::InternetStackHelper() [constructor]
+    cls.add_constructor([])
+    ## internet-stack-helper.h: ns3::InternetStackHelper::InternetStackHelper(ns3::InternetStackHelper const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::InternetStackHelper const &', 'arg0')])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::Install(std::string nodeName) const [member function]
+    cls.add_method('Install', 
+                   'void', 
+                   [param('std::string', 'nodeName')], 
+                   is_const=True)
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::Install(ns3::Ptr<ns3::Node> node) const [member function]
+    cls.add_method('Install', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Node >', 'node')], 
+                   is_const=True)
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::Install(ns3::NodeContainer c) const [member function]
+    cls.add_method('Install', 
+                   'void', 
+                   [param('ns3::NodeContainer', 'c')], 
+                   is_const=True)
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::InstallAll() const [member function]
+    cls.add_method('InstallAll', 
+                   'void', 
+                   [], 
+                   is_const=True)
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::Reset() [member function]
+    cls.add_method('Reset', 
+                   'void', 
+                   [])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetIpv4StackInstall(bool enable) [member function]
+    cls.add_method('SetIpv4StackInstall', 
+                   'void', 
+                   [param('bool', 'enable')])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetIpv6StackInstall(bool enable) [member function]
+    cls.add_method('SetIpv6StackInstall', 
+                   'void', 
+                   [param('bool', 'enable')])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetRoutingHelper(ns3::Ipv4RoutingHelper const & routing) [member function]
+    cls.add_method('SetRoutingHelper', 
+                   'void', 
+                   [param('ns3::Ipv4RoutingHelper const &', 'routing')])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetRoutingHelper(ns3::Ipv6RoutingHelper const & routing) [member function]
+    cls.add_method('SetRoutingHelper', 
+                   'void', 
+                   [param('ns3::Ipv6RoutingHelper const &', 'routing')])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetTcp(std::string tid) [member function]
+    cls.add_method('SetTcp', 
+                   'void', 
+                   [param('std::string', 'tid')])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::SetTcp(std::string tid, std::string attr, ns3::AttributeValue const & val) [member function]
+    cls.add_method('SetTcp', 
+                   'void', 
+                   [param('std::string', 'tid'), param('std::string', 'attr'), param('ns3::AttributeValue const &', 'val')])
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::EnableAsciiIpv4Internal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::Ipv4> ipv4, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv4Internal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')], 
+                   visibility='private', is_virtual=True)
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::EnableAsciiIpv6Internal(ns3::Ptr<ns3::OutputStreamWrapper> stream, std::string prefix, ns3::Ptr<ns3::Ipv6> ipv6, uint32_t interface) [member function]
+    cls.add_method('EnableAsciiIpv6Internal', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::OutputStreamWrapper >', 'stream'), param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv6 >', 'ipv6'), param('uint32_t', 'interface')], 
+                   visibility='private', is_virtual=True)
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::EnablePcapIpv4Internal(std::string prefix, ns3::Ptr<ns3::Ipv4> ipv4, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv4Internal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')], 
+                   visibility='private', is_virtual=True)
+    ## internet-stack-helper.h: void ns3::InternetStackHelper::EnablePcapIpv6Internal(std::string prefix, ns3::Ptr<ns3::Ipv6> ipv6, uint32_t interface) [member function]
+    cls.add_method('EnablePcapIpv6Internal', 
+                   'void', 
+                   [param('std::string', 'prefix'), param('ns3::Ptr< ns3::Ipv6 >', 'ipv6'), param('uint32_t', 'interface')], 
+                   visibility='private', is_virtual=True)
+    return
+
 def register_Ns3Ipv4GlobalRoutingHelper_methods(root_module, cls):
     ## ipv4-global-routing-helper.h: ns3::Ipv4GlobalRoutingHelper::Ipv4GlobalRoutingHelper() [constructor]
     cls.add_constructor([])
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_internet_stack.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_internet_stack.py	Thu Feb 25 14:17:21 2010 +0100
@@ -59,6 +59,8 @@
     module.add_class('Icmpv6TooBig', parent=root_module['ns3::Icmpv6Header'])
     ## ipv6-extension-header.h: ns3::Ipv6ExtensionHeader [class]
     module.add_class('Ipv6ExtensionHeader', parent=root_module['ns3::Header'])
+    ## ipv6-extension-header.h: ns3::Ipv6ExtensionHopByHopHeader [class]
+    module.add_class('Ipv6ExtensionHopByHopHeader', parent=[root_module['ns3::Ipv6ExtensionHeader'], root_module['ns3::OptionField']])
     ## ipv6-extension-header.h: ns3::Ipv6ExtensionRoutingHeader [class]
     module.add_class('Ipv6ExtensionRoutingHeader', parent=root_module['ns3::Ipv6ExtensionHeader'])
     ## ipv6-option-header.h: ns3::Ipv6OptionHeader [class]
@@ -101,6 +103,8 @@
     module.add_enum('RxStatus', ['RX_OK', 'RX_CSUM_FAILED', 'RX_ENDPOINT_CLOSED', 'RX_ENDPOINT_UNREACH'], outer_class=root_module['ns3::Ipv4L4Protocol'])
     ## ipv6-extension-header.h: ns3::Ipv6ExtensionAHHeader [class]
     module.add_class('Ipv6ExtensionAHHeader', parent=root_module['ns3::Ipv6ExtensionHeader'])
+    ## ipv6-extension-header.h: ns3::Ipv6ExtensionDestinationHeader [class]
+    module.add_class('Ipv6ExtensionDestinationHeader', parent=[root_module['ns3::Ipv6ExtensionHeader'], root_module['ns3::OptionField']])
     ## ipv6-extension-header.h: ns3::Ipv6ExtensionESPHeader [class]
     module.add_class('Ipv6ExtensionESPHeader', parent=root_module['ns3::Ipv6ExtensionHeader'])
     ## ipv6-extension-header.h: ns3::Ipv6ExtensionFragmentHeader [class]
@@ -231,6 +235,7 @@
     register_Ns3Icmpv6TimeExceeded_methods(root_module, root_module['ns3::Icmpv6TimeExceeded'])
     register_Ns3Icmpv6TooBig_methods(root_module, root_module['ns3::Icmpv6TooBig'])
     register_Ns3Ipv6ExtensionHeader_methods(root_module, root_module['ns3::Ipv6ExtensionHeader'])
+    register_Ns3Ipv6ExtensionHopByHopHeader_methods(root_module, root_module['ns3::Ipv6ExtensionHopByHopHeader'])
     register_Ns3Ipv6ExtensionRoutingHeader_methods(root_module, root_module['ns3::Ipv6ExtensionRoutingHeader'])
     register_Ns3Ipv6OptionHeader_methods(root_module, root_module['ns3::Ipv6OptionHeader'])
     register_Ns3Ipv6OptionHeaderAlignment_methods(root_module, root_module['ns3::Ipv6OptionHeader::Alignment'])
@@ -249,6 +254,7 @@
     register_Ns3Ipv4L3Protocol_methods(root_module, root_module['ns3::Ipv4L3Protocol'])
     register_Ns3Ipv4L4Protocol_methods(root_module, root_module['ns3::Ipv4L4Protocol'])
     register_Ns3Ipv6ExtensionAHHeader_methods(root_module, root_module['ns3::Ipv6ExtensionAHHeader'])
+    register_Ns3Ipv6ExtensionDestinationHeader_methods(root_module, root_module['ns3::Ipv6ExtensionDestinationHeader'])
     register_Ns3Ipv6ExtensionESPHeader_methods(root_module, root_module['ns3::Ipv6ExtensionESPHeader'])
     register_Ns3Ipv6ExtensionFragmentHeader_methods(root_module, root_module['ns3::Ipv6ExtensionFragmentHeader'])
     register_Ns3Ipv6ExtensionLooseRoutingHeader_methods(root_module, root_module['ns3::Ipv6ExtensionLooseRoutingHeader'])
@@ -1481,6 +1487,43 @@
                    [param('uint8_t', 'nextHeader')])
     return
 
+def register_Ns3Ipv6ExtensionHopByHopHeader_methods(root_module, cls):
+    ## ipv6-extension-header.h: ns3::Ipv6ExtensionHopByHopHeader::Ipv6ExtensionHopByHopHeader(ns3::Ipv6ExtensionHopByHopHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Ipv6ExtensionHopByHopHeader const &', 'arg0')])
+    ## ipv6-extension-header.h: ns3::Ipv6ExtensionHopByHopHeader::Ipv6ExtensionHopByHopHeader() [constructor]
+    cls.add_constructor([])
+    ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionHopByHopHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## ipv6-extension-header.h: ns3::TypeId ns3::Ipv6ExtensionHopByHopHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionHopByHopHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ipv6-extension-header.h: static ns3::TypeId ns3::Ipv6ExtensionHopByHopHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## ipv6-extension-header.h: void ns3::Ipv6ExtensionHopByHopHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## ipv6-extension-header.h: void ns3::Ipv6ExtensionHopByHopHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    return
+
 def register_Ns3Ipv6ExtensionRoutingHeader_methods(root_module, cls):
     ## ipv6-extension-header.h: ns3::Ipv6ExtensionRoutingHeader::Ipv6ExtensionRoutingHeader(ns3::Ipv6ExtensionRoutingHeader const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Ipv6ExtensionRoutingHeader const &', 'arg0')])
@@ -2616,6 +2659,43 @@
                    is_const=True, is_virtual=True)
     return
 
+def register_Ns3Ipv6ExtensionDestinationHeader_methods(root_module, cls):
+    ## ipv6-extension-header.h: ns3::Ipv6ExtensionDestinationHeader::Ipv6ExtensionDestinationHeader(ns3::Ipv6ExtensionDestinationHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Ipv6ExtensionDestinationHeader const &', 'arg0')])
+    ## ipv6-extension-header.h: ns3::Ipv6ExtensionDestinationHeader::Ipv6ExtensionDestinationHeader() [constructor]
+    cls.add_constructor([])
+    ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionDestinationHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## ipv6-extension-header.h: ns3::TypeId ns3::Ipv6ExtensionDestinationHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionDestinationHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ipv6-extension-header.h: static ns3::TypeId ns3::Ipv6ExtensionDestinationHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## ipv6-extension-header.h: void ns3::Ipv6ExtensionDestinationHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## ipv6-extension-header.h: void ns3::Ipv6ExtensionDestinationHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    return
+
 def register_Ns3Ipv6ExtensionESPHeader_methods(root_module, cls):
     ## ipv6-extension-header.h: ns3::Ipv6ExtensionESPHeader::Ipv6ExtensionESPHeader(ns3::Ipv6ExtensionESPHeader const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Ipv6ExtensionESPHeader const &', 'arg0')])
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_mobility.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_mobility.py	Thu Feb 25 14:17:21 2010 +0100
@@ -4,7 +4,7 @@
     root_module = module.get_root()
     
     ## constant-velocity-helper.h: ns3::ConstantVelocityHelper [class]
-    module.add_class('ConstantVelocityHelper', allow_subclassing=False)
+    module.add_class('ConstantVelocityHelper')
     ## rectangle.h: ns3::Rectangle [class]
     module.add_class('Rectangle')
     ## rectangle.h: ns3::Rectangle::Side [enumeration]
@@ -39,6 +39,8 @@
     module.add_class('RectangleChecker', parent=root_module['ns3::AttributeChecker'])
     ## rectangle.h: ns3::RectangleValue [class]
     module.add_class('RectangleValue', parent=root_module['ns3::AttributeValue'])
+    ## steady-state-random-waypoint-mobility-model.h: ns3::SteadyStateRandomWaypointMobilityModel [class]
+    module.add_class('SteadyStateRandomWaypointMobilityModel', parent=root_module['ns3::MobilityModel'])
     ## waypoint.h: ns3::WaypointChecker [class]
     module.add_class('WaypointChecker', parent=root_module['ns3::AttributeChecker'])
     ## waypoint-mobility-model.h: ns3::WaypointMobilityModel [class]
@@ -150,6 +152,7 @@
     register_Ns3RandomWaypointMobilityModel_methods(root_module, root_module['ns3::RandomWaypointMobilityModel'])
     register_Ns3RectangleChecker_methods(root_module, root_module['ns3::RectangleChecker'])
     register_Ns3RectangleValue_methods(root_module, root_module['ns3::RectangleValue'])
+    register_Ns3SteadyStateRandomWaypointMobilityModel_methods(root_module, root_module['ns3::SteadyStateRandomWaypointMobilityModel'])
     register_Ns3WaypointChecker_methods(root_module, root_module['ns3::WaypointChecker'])
     register_Ns3WaypointMobilityModel_methods(root_module, root_module['ns3::WaypointMobilityModel'])
     register_Ns3WaypointValue_methods(root_module, root_module['ns3::WaypointValue'])
@@ -646,6 +649,38 @@
                    [param('ns3::Rectangle const &', 'value')])
     return
 
+def register_Ns3SteadyStateRandomWaypointMobilityModel_methods(root_module, cls):
+    ## steady-state-random-waypoint-mobility-model.h: ns3::SteadyStateRandomWaypointMobilityModel::SteadyStateRandomWaypointMobilityModel(ns3::SteadyStateRandomWaypointMobilityModel const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::SteadyStateRandomWaypointMobilityModel const &', 'arg0')])
+    ## steady-state-random-waypoint-mobility-model.h: ns3::SteadyStateRandomWaypointMobilityModel::SteadyStateRandomWaypointMobilityModel() [constructor]
+    cls.add_constructor([])
+    ## steady-state-random-waypoint-mobility-model.h: static ns3::TypeId ns3::SteadyStateRandomWaypointMobilityModel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## steady-state-random-waypoint-mobility-model.h: void ns3::SteadyStateRandomWaypointMobilityModel::DoStart() [member function]
+    cls.add_method('DoStart', 
+                   'void', 
+                   [], 
+                   visibility='protected', is_virtual=True)
+    ## steady-state-random-waypoint-mobility-model.h: ns3::Vector ns3::SteadyStateRandomWaypointMobilityModel::DoGetPosition() const [member function]
+    cls.add_method('DoGetPosition', 
+                   'ns3::Vector', 
+                   [], 
+                   is_const=True, visibility='private', is_virtual=True)
+    ## steady-state-random-waypoint-mobility-model.h: ns3::Vector ns3::SteadyStateRandomWaypointMobilityModel::DoGetVelocity() const [member function]
+    cls.add_method('DoGetVelocity', 
+                   'ns3::Vector', 
+                   [], 
+                   is_const=True, visibility='private', is_virtual=True)
+    ## steady-state-random-waypoint-mobility-model.h: void ns3::SteadyStateRandomWaypointMobilityModel::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_Ns3WaypointChecker_methods(root_module, cls):
     ## waypoint.h: ns3::WaypointChecker::WaypointChecker() [constructor]
     cls.add_constructor([])
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_nix_vector_routing.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_nix_vector_routing.py	Thu Feb 25 14:17:21 2010 +0100
@@ -110,10 +110,10 @@
                    'ns3::TypeId', 
                    [], 
                    is_static=True)
-    ## ipv4-nix-vector-routing.h: void ns3::Ipv4NixVectorRouting::SetNode(ns3::Ptr<ns3::Node> arg0) [member function]
+    ## ipv4-nix-vector-routing.h: void ns3::Ipv4NixVectorRouting::SetNode(ns3::Ptr<ns3::Node> node) [member function]
     cls.add_method('SetNode', 
                    'void', 
-                   [param('ns3::Ptr< ns3::Node >', 'arg0')])
+                   [param('ns3::Ptr< ns3::Node >', 'node')])
     ## ipv4-nix-vector-routing.h: void ns3::Ipv4NixVectorRouting::DoDispose() [member function]
     cls.add_method('DoDispose', 
                    'void', 
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_node.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_node.py	Thu Feb 25 14:17:21 2010 +0100
@@ -73,6 +73,12 @@
     module.add_class('LlcSnapHeader', parent=root_module['ns3::Header'])
     ## queue.h: ns3::Queue [class]
     module.add_class('Queue', parent=root_module['ns3::Object'])
+    ## radiotap-header.h: ns3::RadiotapHeader [class]
+    module.add_class('RadiotapHeader', parent=root_module['ns3::Header'])
+    ## radiotap-header.h: ns3::RadiotapHeader [enumeration]
+    module.add_enum('', ['FRAME_FLAG_NONE', 'FRAME_FLAG_CFP', 'FRAME_FLAG_SHORT_PREAMBLE', 'FRAME_FLAG_WEP', 'FRAME_FLAG_FRAGMENTED', 'FRAME_FLAG_FCS_INCLUDED', 'FRAME_FLAG_DATA_PADDING', 'FRAME_FLAG_BAD_FCS', 'FRAME_FLAG_SHORT_GUARD'], outer_class=root_module['ns3::RadiotapHeader'])
+    ## radiotap-header.h: ns3::RadiotapHeader [enumeration]
+    module.add_enum('', ['CHANNEL_FLAG_NONE', 'CHANNEL_FLAG_TURBO', 'CHANNEL_FLAG_CCK', 'CHANNEL_FLAG_OFDM', 'CHANNEL_FLAG_SPECTRUM_2GHZ', 'CHANNEL_FLAG_SPECTRUM_5GHZ', 'CHANNEL_FLAG_PASSIVE', 'CHANNEL_FLAG_DYNAMIC', 'CHANNEL_FLAG_GFSK'], outer_class=root_module['ns3::RadiotapHeader'])
     ## simple-ref-count.h: ns3::SimpleRefCount<ns3::Ipv4MulticastRoute, ns3::empty, ns3::DefaultDeleter<ns3::Ipv4MulticastRoute> > [class]
     module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::Ipv4MulticastRoute', 'ns3::empty', 'ns3::DefaultDeleter<ns3::Ipv4MulticastRoute>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
     ## simple-ref-count.h: ns3::SimpleRefCount<ns3::Ipv4Route, ns3::empty, ns3::DefaultDeleter<ns3::Ipv4Route> > [class]
@@ -302,6 +308,7 @@
     register_Ns3Ipv6Header_methods(root_module, root_module['ns3::Ipv6Header'])
     register_Ns3LlcSnapHeader_methods(root_module, root_module['ns3::LlcSnapHeader'])
     register_Ns3Queue_methods(root_module, root_module['ns3::Queue'])
+    register_Ns3RadiotapHeader_methods(root_module, root_module['ns3::RadiotapHeader'])
     register_Ns3Socket_methods(root_module, root_module['ns3::Socket'])
     register_Ns3SocketAddressTag_methods(root_module, root_module['ns3::SocketAddressTag'])
     register_Ns3SocketFactory_methods(root_module, root_module['ns3::SocketFactory'])
@@ -1864,6 +1871,110 @@
                    is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
     return
 
+def register_Ns3RadiotapHeader_methods(root_module, cls):
+    ## radiotap-header.h: ns3::RadiotapHeader::RadiotapHeader(ns3::RadiotapHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::RadiotapHeader const &', 'arg0')])
+    ## radiotap-header.h: ns3::RadiotapHeader::RadiotapHeader() [constructor]
+    cls.add_constructor([])
+    ## radiotap-header.h: uint32_t ns3::RadiotapHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## radiotap-header.h: uint8_t ns3::RadiotapHeader::GetAntennaNoisePower() const [member function]
+    cls.add_method('GetAntennaNoisePower', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## radiotap-header.h: uint8_t ns3::RadiotapHeader::GetAntennaSignalPower() const [member function]
+    cls.add_method('GetAntennaSignalPower', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## radiotap-header.h: uint16_t ns3::RadiotapHeader::GetChannelFlags() const [member function]
+    cls.add_method('GetChannelFlags', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## radiotap-header.h: uint16_t ns3::RadiotapHeader::GetChannelFrequency() const [member function]
+    cls.add_method('GetChannelFrequency', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## radiotap-header.h: uint8_t ns3::RadiotapHeader::GetFrameFlags() const [member function]
+    cls.add_method('GetFrameFlags', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## radiotap-header.h: ns3::TypeId ns3::RadiotapHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## radiotap-header.h: uint8_t ns3::RadiotapHeader::GetRate() const [member function]
+    cls.add_method('GetRate', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## radiotap-header.h: uint32_t ns3::RadiotapHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## radiotap-header.h: uint64_t ns3::RadiotapHeader::GetTsft() const [member function]
+    cls.add_method('GetTsft', 
+                   'uint64_t', 
+                   [], 
+                   is_const=True)
+    ## radiotap-header.h: static ns3::TypeId ns3::RadiotapHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## radiotap-header.h: void ns3::RadiotapHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## radiotap-header.h: void ns3::RadiotapHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetAntennaNoisePower(int8_t noise) [member function]
+    cls.add_method('SetAntennaNoisePower', 
+                   'void', 
+                   [param('int8_t', 'noise')])
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetAntennaNoisePower(double noise) [member function]
+    cls.add_method('SetAntennaNoisePower', 
+                   'void', 
+                   [param('double', 'noise')])
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetAntennaSignalPower(int8_t signal) [member function]
+    cls.add_method('SetAntennaSignalPower', 
+                   'void', 
+                   [param('int8_t', 'signal')])
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetAntennaSignalPower(double signal) [member function]
+    cls.add_method('SetAntennaSignalPower', 
+                   'void', 
+                   [param('double', 'signal')])
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetChannelFrequencyAndFlags(uint16_t frequency, uint16_t flags) [member function]
+    cls.add_method('SetChannelFrequencyAndFlags', 
+                   'void', 
+                   [param('uint16_t', 'frequency'), param('uint16_t', 'flags')])
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetFrameFlags(uint8_t flags) [member function]
+    cls.add_method('SetFrameFlags', 
+                   'void', 
+                   [param('uint8_t', 'flags')])
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetRate(uint8_t rate) [member function]
+    cls.add_method('SetRate', 
+                   'void', 
+                   [param('uint8_t', 'rate')])
+    ## radiotap-header.h: void ns3::RadiotapHeader::SetTsft(uint64_t tsft) [member function]
+    cls.add_method('SetTsft', 
+                   'void', 
+                   [param('uint64_t', 'tsft')])
+    return
+
 def register_Ns3Socket_methods(root_module, cls):
     ## socket.h: ns3::Socket::Socket(ns3::Socket const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Socket const &', 'arg0')])
@@ -4580,11 +4691,6 @@
                    'int', 
                    [], 
                    is_const=True)
-    ## packetbb.h: void ns3::PbbPacket::SerializePacketTlv(ns3::Buffer::Iterator & start) const [member function]
-    cls.add_method('SerializePacketTlv', 
-                   'void', 
-                   [param('ns3::Buffer::Iterator &', 'start')], 
-                   is_const=True, visibility='protected')
     return
 
 def register_Ns3PbbTlv_methods(root_module, cls):
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_olsr.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_olsr.py	Thu Feb 25 14:17:21 2010 +0100
@@ -133,6 +133,7 @@
     module.add_class('TwoHopNeighborTuple')
     module.add_container('std::vector< ns3::olsr::MessageHeader::Hello::LinkMessage >', 'ns3::olsr::MessageHeader::Hello::LinkMessage', container_type='vector')
     module.add_container('std::vector< ns3::olsr::MessageHeader::Hna::Association >', 'ns3::olsr::MessageHeader::Hna::Association', container_type='vector')
+    module.add_container('std::vector< ns3::olsr::RoutingTableEntry >', 'ns3::olsr::RoutingTableEntry', container_type='vector')
     typehandlers.add_type_alias('std::vector< ns3::olsr::DuplicateTuple, std::allocator< ns3::olsr::DuplicateTuple > >', 'ns3::olsr::DuplicateSet')
     typehandlers.add_type_alias('std::vector< ns3::olsr::DuplicateTuple, std::allocator< ns3::olsr::DuplicateTuple > >*', 'ns3::olsr::DuplicateSet*')
     typehandlers.add_type_alias('std::vector< ns3::olsr::DuplicateTuple, std::allocator< ns3::olsr::DuplicateTuple > >&', 'ns3::olsr::DuplicateSet&')
@@ -812,6 +813,11 @@
     cls.add_method('Dump', 
                    'void', 
                    [])
+    ## olsr-routing-protocol.h: std::vector<ns3::olsr::RoutingTableEntry,std::allocator<ns3::olsr::RoutingTableEntry> > ns3::olsr::RoutingProtocol::GetRoutingTableEntries() const [member function]
+    cls.add_method('GetRoutingTableEntries', 
+                   'std::vector< ns3::olsr::RoutingTableEntry >', 
+                   [], 
+                   is_const=True)
     ## olsr-routing-protocol.h: static ns3::TypeId ns3::olsr::RoutingProtocol::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_point_to_point.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_point_to_point.py	Thu Feb 25 14:17:21 2010 +0100
@@ -235,6 +235,11 @@
                    'ns3::Ptr< ns3::Node >', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## point-to-point-net-device.h: ns3::Ptr<ns3::Queue> ns3::PointToPointNetDevice::GetQueue() const [member function]
+    cls.add_method('GetQueue', 
+                   'ns3::Ptr< ns3::Queue >', 
+                   [], 
+                   is_const=True)
     ## point-to-point-net-device.h: static ns3::TypeId ns3::PointToPointNetDevice::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_stats.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_stats.py	Thu Feb 25 14:17:21 2010 +0100
@@ -13,8 +13,12 @@
     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'], root_module['ns3::StatisticalSummary']])
     ## 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]
@@ -116,7 +120,9 @@
     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 >'])
@@ -364,6 +370,67 @@
                    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: long int ns3::MinMaxAvgTotalCalculator<unsigned int>::getCount() const [member function]
+    cls.add_method('getCount', 
+                   'long int', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator<unsigned int>::getMax() const [member function]
+    cls.add_method('getMax', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator<unsigned int>::getMean() const [member function]
+    cls.add_method('getMean', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator<unsigned int>::getMin() const [member function]
+    cls.add_method('getMin', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator<unsigned int>::getSqrSum() const [member function]
+    cls.add_method('getSqrSum', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator<unsigned int>::getStddev() const [member function]
+    cls.add_method('getStddev', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator<unsigned int>::getSum() const [member function]
+    cls.add_method('getSum', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator<unsigned int>::getVariance() const [member function]
+    cls.add_method('getVariance', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## 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')])
@@ -381,6 +448,26 @@
                    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')])
--- a/bindings/python/apidefs/gcc-LP64/ns3_module_wifi.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/apidefs/gcc-LP64/ns3_module_wifi.py	Thu Feb 25 14:17:21 2010 +0100
@@ -15,6 +15,14 @@
     module.add_enum('AccessClass', ['AC_VO', 'AC_VI', 'AC_BE', 'AC_BK', 'AC_BE_NQOS', 'AC_UNDEF'])
     ## edca-txop-n.h: ns3::TypeOfStation [enumeration]
     module.add_enum('TypeOfStation', ['STA', 'AP', 'ADHOC_STA'])
+    ## ctrl-headers.h: ns3::BlockAckType [enumeration]
+    module.add_enum('BlockAckType', ['BASIC_BLOCK_ACK', 'COMPRESSED_BLOCK_ACK', 'MULTI_TID_BLOCK_ACK'])
+    ## block-ack-manager.h: ns3::Bar [struct]
+    module.add_class('Bar')
+    ## block-ack-agreement.h: ns3::BlockAckAgreement [class]
+    module.add_class('BlockAckAgreement')
+    ## block-ack-manager.h: ns3::BlockAckManager [class]
+    module.add_class('BlockAckManager')
     ## capability-information.h: ns3::CapabilityInformation [class]
     module.add_class('CapabilityInformation')
     ## dcf-manager.h: ns3::DcfManager [class]
@@ -22,9 +30,11 @@
     ## dcf-manager.h: ns3::DcfState [class]
     module.add_class('DcfState', allow_subclassing=True)
     ## interference-helper.h: ns3::InterferenceHelper [class]
-    module.add_class('InterferenceHelper', allow_subclassing=False)
+    module.add_class('InterferenceHelper')
     ## interference-helper.h: ns3::InterferenceHelper::SnrPer [struct]
     module.add_class('SnrPer', outer_class=root_module['ns3::InterferenceHelper'])
+    ## mac-low.h: ns3::MacLowBlockAckEventListener [class]
+    module.add_class('MacLowBlockAckEventListener', allow_subclassing=True)
     ## mac-low.h: ns3::MacLowDcfListener [class]
     module.add_class('MacLowDcfListener', allow_subclassing=True)
     ## mac-low.h: ns3::MacLowTransmissionListener [class]
@@ -33,6 +43,10 @@
     module.add_class('MacLowTransmissionParameters')
     ## mac-rx-middle.h: ns3::MacRxMiddle [class]
     module.add_class('MacRxMiddle')
+    ## originator-block-ack-agreement.h: ns3::OriginatorBlockAckAgreement [class]
+    module.add_class('OriginatorBlockAckAgreement', parent=root_module['ns3::BlockAckAgreement'])
+    ## originator-block-ack-agreement.h: ns3::OriginatorBlockAckAgreement::State [enumeration]
+    module.add_enum('State', ['PENDING', 'ESTABLISHED', 'INACTIVE', 'UNSUCCESSFUL'], outer_class=root_module['ns3::OriginatorBlockAckAgreement'])
     ## minstrel-wifi-manager.h: ns3::RateInfo [struct]
     module.add_class('RateInfo')
     ## ssid.h: ns3::Ssid [class]
@@ -46,7 +60,7 @@
     ## wifi-mode.h: ns3::WifiMode [class]
     module.add_class('WifiMode')
     ## wifi-mode.h: ns3::WifiMode::ModulationType [enumeration]
-    module.add_enum('ModulationType', ['BPSK', 'DBPSK', 'DQPSK', 'QAM', 'UNKNOWN'], outer_class=root_module['ns3::WifiMode'])
+    module.add_enum('ModulationType', ['BPSK', 'QPSK', 'DBPSK', 'DQPSK', 'QAM', 'UNKNOWN'], outer_class=root_module['ns3::WifiMode'])
     ## wifi-mode.h: ns3::WifiModeFactory [class]
     module.add_class('WifiModeFactory')
     ## wifi-phy.h: ns3::WifiPhyListener [class]
@@ -61,10 +75,16 @@
     module.add_class('ConstantRateWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation'])
     ## ideal-wifi-manager.h: ns3::IdealWifiRemoteStation [class]
     module.add_class('IdealWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation'])
+    ## mgt-headers.h: ns3::MgtAddBaRequestHeader [class]
+    module.add_class('MgtAddBaRequestHeader', parent=root_module['ns3::Header'])
+    ## mgt-headers.h: ns3::MgtAddBaResponseHeader [class]
+    module.add_class('MgtAddBaResponseHeader', parent=root_module['ns3::Header'])
     ## mgt-headers.h: ns3::MgtAssocRequestHeader [class]
     module.add_class('MgtAssocRequestHeader', parent=root_module['ns3::Header'])
     ## mgt-headers.h: ns3::MgtAssocResponseHeader [class]
     module.add_class('MgtAssocResponseHeader', parent=root_module['ns3::Header'])
+    ## mgt-headers.h: ns3::MgtDelBaHeader [class]
+    module.add_class('MgtDelBaHeader', parent=root_module['ns3::Header'])
     ## mgt-headers.h: ns3::MgtProbeRequestHeader [class]
     module.add_class('MgtProbeRequestHeader', parent=root_module['ns3::Header'])
     ## mgt-headers.h: ns3::MgtProbeResponseHeader [class]
@@ -73,26 +93,16 @@
     module.add_class('MinstrelWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation'])
     ## onoe-wifi-manager.h: ns3::OnoeWifiRemoteStation [class]
     module.add_class('OnoeWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation'])
-    ## propagation-delay-model.h: ns3::PropagationDelayModel [class]
-    module.add_class('PropagationDelayModel', parent=root_module['ns3::Object'])
-    ## propagation-loss-model.h: ns3::PropagationLossModel [class]
-    module.add_class('PropagationLossModel', parent=root_module['ns3::Object'])
     ## qos-tag.h: ns3::QosTag [class]
     module.add_class('QosTag', parent=root_module['ns3::Tag'])
-    ## propagation-delay-model.h: ns3::RandomPropagationDelayModel [class]
-    module.add_class('RandomPropagationDelayModel', parent=root_module['ns3::PropagationDelayModel'])
-    ## propagation-loss-model.h: ns3::RandomPropagationLossModel [class]
-    module.add_class('RandomPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## rraa-wifi-manager.h: ns3::RraaWifiRemoteStation [class]
     module.add_class('RraaWifiRemoteStation', parent=root_module['ns3::WifiRemoteStation'])
     ## simple-ref-count.h: ns3::SimpleRefCount<ns3::InterferenceHelper::Event, ns3::empty, ns3::DefaultDeleter<ns3::InterferenceHelper::Event> > [class]
     module.add_class('SimpleRefCount', automatic_type_narrowing=True, template_parameters=['ns3::InterferenceHelper::Event', 'ns3::empty', 'ns3::DefaultDeleter<ns3::InterferenceHelper::Event>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
-    ## propagation-loss-model.h: ns3::ThreeLogDistancePropagationLossModel [class]
-    module.add_class('ThreeLogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## mgt-headers.h: ns3::WifiActionHeader [class]
     module.add_class('WifiActionHeader', parent=root_module['ns3::Header'])
     ## mgt-headers.h: ns3::WifiActionHeader::CategoryValue [enumeration]
-    module.add_enum('CategoryValue', ['MESH_PEERING_MGT', 'MESH_LINK_METRIC', 'MESH_PATH_SELECTION', 'MESH_INTERWORKING', 'MESH_RESOURCE_COORDINATION', 'MESH_PROXY_FORWARDING'], outer_class=root_module['ns3::WifiActionHeader'])
+    module.add_enum('CategoryValue', ['BLOCK_ACK', 'MESH_PEERING_MGT', 'MESH_LINK_METRIC', 'MESH_PATH_SELECTION', 'MESH_INTERWORKING', 'MESH_RESOURCE_COORDINATION', 'MESH_PROXY_FORWARDING'], outer_class=root_module['ns3::WifiActionHeader'])
     ## mgt-headers.h: ns3::WifiActionHeader::PeerLinkMgtActionValue [enumeration]
     module.add_enum('PeerLinkMgtActionValue', ['PEER_LINK_OPEN', 'PEER_LINK_CONFIRM', 'PEER_LINK_CLOSE'], outer_class=root_module['ns3::WifiActionHeader'])
     ## mgt-headers.h: ns3::WifiActionHeader::LinkMetricActionValue [enumeration]
@@ -103,6 +113,8 @@
     module.add_enum('InterworkActionValue', ['PORTAL_ANNOUNCEMENT'], outer_class=root_module['ns3::WifiActionHeader'])
     ## mgt-headers.h: ns3::WifiActionHeader::ResourceCoordinationActionValue [enumeration]
     module.add_enum('ResourceCoordinationActionValue', ['CONGESTION_CONTROL_NOTIFICATION', 'MDA_SETUP_REQUEST', 'MDA_SETUP_REPLY', 'MDAOP_ADVERTISMENT_REQUEST', 'MDAOP_ADVERTISMENTS', 'MDAOP_SET_TEARDOWN', 'BEACON_TIMING_REQUEST', 'BEACON_TIMING_RESPONSE', 'TBTT_ADJUSTMENT_REQUEST', 'MESH_CHANNEL_SWITCH_ANNOUNCEMENT'], outer_class=root_module['ns3::WifiActionHeader'])
+    ## mgt-headers.h: ns3::WifiActionHeader::BlockAckActionValue [enumeration]
+    module.add_enum('BlockAckActionValue', ['BLOCK_ACK_ADDBA_REQUEST', 'BLOCK_ACK_ADDBA_RESPONSE', 'BLOCK_ACK_DELBA'], outer_class=root_module['ns3::WifiActionHeader'])
     ## mgt-headers.h: ns3::WifiActionHeader::ActionValue [union]
     module.add_class('ActionValue', outer_class=root_module['ns3::WifiActionHeader'])
     ## wifi-mac.h: ns3::WifiMac [class]
@@ -133,24 +145,18 @@
     module.add_class('ArfWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
     ## constant-rate-wifi-manager.h: ns3::ConstantRateWifiManager [class]
     module.add_class('ConstantRateWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
-    ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel [class]
-    module.add_class('ConstantSpeedPropagationDelayModel', parent=root_module['ns3::PropagationDelayModel'])
+    ## ctrl-headers.h: ns3::CtrlBAckRequestHeader [class]
+    module.add_class('CtrlBAckRequestHeader', parent=root_module['ns3::Header'])
+    ## ctrl-headers.h: ns3::CtrlBAckResponseHeader [class]
+    module.add_class('CtrlBAckResponseHeader', parent=root_module['ns3::Header'])
     ## dcf.h: ns3::Dcf [class]
     module.add_class('Dcf', parent=root_module['ns3::Object'])
     ## edca-txop-n.h: ns3::EdcaTxopN [class]
     module.add_class('EdcaTxopN', parent=root_module['ns3::Dcf'])
     ## error-rate-model.h: ns3::ErrorRateModel [class]
     module.add_class('ErrorRateModel', parent=root_module['ns3::Object'])
-    ## propagation-loss-model.h: ns3::FixedRssLossModel [class]
-    module.add_class('FixedRssLossModel', parent=root_module['ns3::PropagationLossModel'])
-    ## propagation-loss-model.h: ns3::FriisPropagationLossModel [class]
-    module.add_class('FriisPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## ideal-wifi-manager.h: ns3::IdealWifiManager [class]
     module.add_class('IdealWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
-    ## jakes-propagation-loss-model.h: ns3::JakesPropagationLossModel [class]
-    module.add_class('JakesPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
-    ## propagation-loss-model.h: ns3::LogDistancePropagationLossModel [class]
-    module.add_class('LogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## mac-low.h: ns3::MacLow [class]
     module.add_class('MacLow', parent=root_module['ns3::Object'])
     ## mgt-headers.h: ns3::MgtBeaconHeader [class]
@@ -159,8 +165,6 @@
     module.add_class('MinstrelWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
     ## msdu-aggregator.h: ns3::MsduAggregator [class]
     module.add_class('MsduAggregator', parent=root_module['ns3::Object'])
-    ## propagation-loss-model.h: ns3::NakagamiPropagationLossModel [class]
-    module.add_class('NakagamiPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
     ## nqap-wifi-mac.h: ns3::NqapWifiMac [class]
     module.add_class('NqapWifiMac', parent=root_module['ns3::WifiMac'])
     ## nqsta-wifi-mac.h: ns3::NqstaWifiMac [class]
@@ -286,15 +290,20 @@
     
 
 def register_methods(root_module):
+    register_Ns3Bar_methods(root_module, root_module['ns3::Bar'])
+    register_Ns3BlockAckAgreement_methods(root_module, root_module['ns3::BlockAckAgreement'])
+    register_Ns3BlockAckManager_methods(root_module, root_module['ns3::BlockAckManager'])
     register_Ns3CapabilityInformation_methods(root_module, root_module['ns3::CapabilityInformation'])
     register_Ns3DcfManager_methods(root_module, root_module['ns3::DcfManager'])
     register_Ns3DcfState_methods(root_module, root_module['ns3::DcfState'])
     register_Ns3InterferenceHelper_methods(root_module, root_module['ns3::InterferenceHelper'])
     register_Ns3InterferenceHelperSnrPer_methods(root_module, root_module['ns3::InterferenceHelper::SnrPer'])
+    register_Ns3MacLowBlockAckEventListener_methods(root_module, root_module['ns3::MacLowBlockAckEventListener'])
     register_Ns3MacLowDcfListener_methods(root_module, root_module['ns3::MacLowDcfListener'])
     register_Ns3MacLowTransmissionListener_methods(root_module, root_module['ns3::MacLowTransmissionListener'])
     register_Ns3MacLowTransmissionParameters_methods(root_module, root_module['ns3::MacLowTransmissionParameters'])
     register_Ns3MacRxMiddle_methods(root_module, root_module['ns3::MacRxMiddle'])
+    register_Ns3OriginatorBlockAckAgreement_methods(root_module, root_module['ns3::OriginatorBlockAckAgreement'])
     register_Ns3RateInfo_methods(root_module, root_module['ns3::RateInfo'])
     register_Ns3Ssid_methods(root_module, root_module['ns3::Ssid'])
     register_Ns3StatusCode_methods(root_module, root_module['ns3::StatusCode'])
@@ -308,19 +317,17 @@
     register_Ns3ArfWifiRemoteStation_methods(root_module, root_module['ns3::ArfWifiRemoteStation'])
     register_Ns3ConstantRateWifiRemoteStation_methods(root_module, root_module['ns3::ConstantRateWifiRemoteStation'])
     register_Ns3IdealWifiRemoteStation_methods(root_module, root_module['ns3::IdealWifiRemoteStation'])
+    register_Ns3MgtAddBaRequestHeader_methods(root_module, root_module['ns3::MgtAddBaRequestHeader'])
+    register_Ns3MgtAddBaResponseHeader_methods(root_module, root_module['ns3::MgtAddBaResponseHeader'])
     register_Ns3MgtAssocRequestHeader_methods(root_module, root_module['ns3::MgtAssocRequestHeader'])
     register_Ns3MgtAssocResponseHeader_methods(root_module, root_module['ns3::MgtAssocResponseHeader'])
+    register_Ns3MgtDelBaHeader_methods(root_module, root_module['ns3::MgtDelBaHeader'])
     register_Ns3MgtProbeRequestHeader_methods(root_module, root_module['ns3::MgtProbeRequestHeader'])
     register_Ns3MgtProbeResponseHeader_methods(root_module, root_module['ns3::MgtProbeResponseHeader'])
     register_Ns3MinstrelWifiRemoteStation_methods(root_module, root_module['ns3::MinstrelWifiRemoteStation'])
     register_Ns3OnoeWifiRemoteStation_methods(root_module, root_module['ns3::OnoeWifiRemoteStation'])
-    register_Ns3PropagationDelayModel_methods(root_module, root_module['ns3::PropagationDelayModel'])
-    register_Ns3PropagationLossModel_methods(root_module, root_module['ns3::PropagationLossModel'])
     register_Ns3QosTag_methods(root_module, root_module['ns3::QosTag'])
-    register_Ns3RandomPropagationDelayModel_methods(root_module, root_module['ns3::RandomPropagationDelayModel'])
-    register_Ns3RandomPropagationLossModel_methods(root_module, root_module['ns3::RandomPropagationLossModel'])
     register_Ns3RraaWifiRemoteStation_methods(root_module, root_module['ns3::RraaWifiRemoteStation'])
-    register_Ns3ThreeLogDistancePropagationLossModel_methods(root_module, root_module['ns3::ThreeLogDistancePropagationLossModel'])
     register_Ns3WifiActionHeader_methods(root_module, root_module['ns3::WifiActionHeader'])
     register_Ns3WifiActionHeaderActionValue_methods(root_module, root_module['ns3::WifiActionHeader::ActionValue'])
     register_Ns3WifiMac_methods(root_module, root_module['ns3::WifiMac'])
@@ -334,20 +341,16 @@
     register_Ns3AmsduSubframeHeader_methods(root_module, root_module['ns3::AmsduSubframeHeader'])
     register_Ns3ArfWifiManager_methods(root_module, root_module['ns3::ArfWifiManager'])
     register_Ns3ConstantRateWifiManager_methods(root_module, root_module['ns3::ConstantRateWifiManager'])
-    register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, root_module['ns3::ConstantSpeedPropagationDelayModel'])
+    register_Ns3CtrlBAckRequestHeader_methods(root_module, root_module['ns3::CtrlBAckRequestHeader'])
+    register_Ns3CtrlBAckResponseHeader_methods(root_module, root_module['ns3::CtrlBAckResponseHeader'])
     register_Ns3Dcf_methods(root_module, root_module['ns3::Dcf'])
     register_Ns3EdcaTxopN_methods(root_module, root_module['ns3::EdcaTxopN'])
     register_Ns3ErrorRateModel_methods(root_module, root_module['ns3::ErrorRateModel'])
-    register_Ns3FixedRssLossModel_methods(root_module, root_module['ns3::FixedRssLossModel'])
-    register_Ns3FriisPropagationLossModel_methods(root_module, root_module['ns3::FriisPropagationLossModel'])
     register_Ns3IdealWifiManager_methods(root_module, root_module['ns3::IdealWifiManager'])
-    register_Ns3JakesPropagationLossModel_methods(root_module, root_module['ns3::JakesPropagationLossModel'])
-    register_Ns3LogDistancePropagationLossModel_methods(root_module, root_module['ns3::LogDistancePropagationLossModel'])
     register_Ns3MacLow_methods(root_module, root_module['ns3::MacLow'])
     register_Ns3MgtBeaconHeader_methods(root_module, root_module['ns3::MgtBeaconHeader'])
     register_Ns3MinstrelWifiManager_methods(root_module, root_module['ns3::MinstrelWifiManager'])
     register_Ns3MsduAggregator_methods(root_module, root_module['ns3::MsduAggregator'])
-    register_Ns3NakagamiPropagationLossModel_methods(root_module, root_module['ns3::NakagamiPropagationLossModel'])
     register_Ns3NqapWifiMac_methods(root_module, root_module['ns3::NqapWifiMac'])
     register_Ns3NqstaWifiMac_methods(root_module, root_module['ns3::NqstaWifiMac'])
     register_Ns3OnoeWifiManager_methods(root_module, root_module['ns3::OnoeWifiManager'])
@@ -367,6 +370,216 @@
     register_Ns3DcaTxop_methods(root_module, root_module['ns3::DcaTxop'])
     return
 
+def register_Ns3Bar_methods(root_module, cls):
+    ## block-ack-manager.h: ns3::Bar::Bar(ns3::Bar const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::Bar const &', 'arg0')])
+    ## block-ack-manager.h: ns3::Bar::Bar() [constructor]
+    cls.add_constructor([])
+    ## block-ack-manager.h: ns3::Bar::Bar(ns3::Ptr<ns3::Packet const> packet, ns3::Mac48Address recipient, uint8_t tid, bool immediate) [constructor]
+    cls.add_constructor([param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('bool', 'immediate')])
+    ## block-ack-manager.h: ns3::Bar::bar [variable]
+    cls.add_instance_attribute('bar', 'ns3::Ptr< ns3::Packet const >', is_const=False)
+    ## block-ack-manager.h: ns3::Bar::immediate [variable]
+    cls.add_instance_attribute('immediate', 'bool', is_const=False)
+    ## block-ack-manager.h: ns3::Bar::recipient [variable]
+    cls.add_instance_attribute('recipient', 'ns3::Mac48Address', is_const=False)
+    ## block-ack-manager.h: ns3::Bar::tid [variable]
+    cls.add_instance_attribute('tid', 'uint8_t', is_const=False)
+    return
+
+def register_Ns3BlockAckAgreement_methods(root_module, cls):
+    ## block-ack-agreement.h: ns3::BlockAckAgreement::BlockAckAgreement(ns3::BlockAckAgreement const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::BlockAckAgreement const &', 'arg0')])
+    ## block-ack-agreement.h: ns3::BlockAckAgreement::BlockAckAgreement() [constructor]
+    cls.add_constructor([])
+    ## block-ack-agreement.h: ns3::BlockAckAgreement::BlockAckAgreement(ns3::Mac48Address peer, uint8_t tid) [constructor]
+    cls.add_constructor([param('ns3::Mac48Address', 'peer'), param('uint8_t', 'tid')])
+    ## block-ack-agreement.h: uint16_t ns3::BlockAckAgreement::GetBufferSize() const [member function]
+    cls.add_method('GetBufferSize', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: ns3::Mac48Address ns3::BlockAckAgreement::GetPeer() const [member function]
+    cls.add_method('GetPeer', 
+                   'ns3::Mac48Address', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: uint16_t ns3::BlockAckAgreement::GetStartingSequence() const [member function]
+    cls.add_method('GetStartingSequence', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: uint16_t ns3::BlockAckAgreement::GetStartingSequenceControl() const [member function]
+    cls.add_method('GetStartingSequenceControl', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: uint8_t ns3::BlockAckAgreement::GetTid() const [member function]
+    cls.add_method('GetTid', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: uint16_t ns3::BlockAckAgreement::GetTimeout() const [member function]
+    cls.add_method('GetTimeout', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: bool ns3::BlockAckAgreement::IsAmsduSupported() const [member function]
+    cls.add_method('IsAmsduSupported', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: bool ns3::BlockAckAgreement::IsImmediateBlockAck() const [member function]
+    cls.add_method('IsImmediateBlockAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## block-ack-agreement.h: void ns3::BlockAckAgreement::SetAmsduSupport(bool supported) [member function]
+    cls.add_method('SetAmsduSupport', 
+                   'void', 
+                   [param('bool', 'supported')])
+    ## block-ack-agreement.h: void ns3::BlockAckAgreement::SetBufferSize(uint16_t bufferSize) [member function]
+    cls.add_method('SetBufferSize', 
+                   'void', 
+                   [param('uint16_t', 'bufferSize')])
+    ## block-ack-agreement.h: void ns3::BlockAckAgreement::SetDelayedBlockAck() [member function]
+    cls.add_method('SetDelayedBlockAck', 
+                   'void', 
+                   [])
+    ## block-ack-agreement.h: void ns3::BlockAckAgreement::SetImmediateBlockAck() [member function]
+    cls.add_method('SetImmediateBlockAck', 
+                   'void', 
+                   [])
+    ## block-ack-agreement.h: void ns3::BlockAckAgreement::SetStartingSequence(uint16_t seq) [member function]
+    cls.add_method('SetStartingSequence', 
+                   'void', 
+                   [param('uint16_t', 'seq')])
+    ## block-ack-agreement.h: void ns3::BlockAckAgreement::SetTimeout(uint16_t timeout) [member function]
+    cls.add_method('SetTimeout', 
+                   'void', 
+                   [param('uint16_t', 'timeout')])
+    return
+
+def register_Ns3BlockAckManager_methods(root_module, cls):
+    ## block-ack-manager.h: ns3::BlockAckManager::BlockAckManager() [constructor]
+    cls.add_constructor([])
+    ## block-ack-manager.h: void ns3::BlockAckManager::CreateAgreement(ns3::MgtAddBaRequestHeader const * reqHdr, ns3::Mac48Address recipient) [member function]
+    cls.add_method('CreateAgreement', 
+                   'void', 
+                   [param('ns3::MgtAddBaRequestHeader const *', 'reqHdr'), param('ns3::Mac48Address', 'recipient')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::DestroyAgreement(ns3::Mac48Address recipient, uint8_t tid) [member function]
+    cls.add_method('DestroyAgreement', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')])
+    ## block-ack-manager.h: bool ns3::BlockAckManager::ExistsAgreement(ns3::Mac48Address recipient, uint8_t tid) const [member function]
+    cls.add_method('ExistsAgreement', 
+                   'bool', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], 
+                   is_const=True)
+    ## block-ack-manager.h: bool ns3::BlockAckManager::ExistsAgreementInState(ns3::Mac48Address recipient, uint8_t tid, ns3::OriginatorBlockAckAgreement::State state) const [member function]
+    cls.add_method('ExistsAgreementInState', 
+                   'bool', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('ns3::OriginatorBlockAckAgreement::State', 'state')], 
+                   is_const=True)
+    ## block-ack-manager.h: uint32_t ns3::BlockAckManager::GetNBufferedPackets(ns3::Mac48Address recipient, uint8_t tid) const [member function]
+    cls.add_method('GetNBufferedPackets', 
+                   'uint32_t', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], 
+                   is_const=True)
+    ## block-ack-manager.h: uint32_t ns3::BlockAckManager::GetNRetryNeededPackets(ns3::Mac48Address recipient, uint8_t tid) const [member function]
+    cls.add_method('GetNRetryNeededPackets', 
+                   'uint32_t', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], 
+                   is_const=True)
+    ## block-ack-manager.h: ns3::Ptr<ns3::Packet const> ns3::BlockAckManager::GetNextPacket(ns3::WifiMacHeader & hdr) [member function]
+    cls.add_method('GetNextPacket', 
+                   'ns3::Ptr< ns3::Packet const >', 
+                   [param('ns3::WifiMacHeader &', 'hdr')])
+    ## block-ack-manager.h: uint32_t ns3::BlockAckManager::GetNextPacketSize() const [member function]
+    cls.add_method('GetNextPacketSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True)
+    ## block-ack-manager.h: bool ns3::BlockAckManager::HasBar(ns3::Bar & bar) [member function]
+    cls.add_method('HasBar', 
+                   'bool', 
+                   [param('ns3::Bar &', 'bar')])
+    ## block-ack-manager.h: bool ns3::BlockAckManager::HasOtherFragments(uint16_t sequenceNumber) const [member function]
+    cls.add_method('HasOtherFragments', 
+                   'bool', 
+                   [param('uint16_t', 'sequenceNumber')], 
+                   is_const=True)
+    ## block-ack-manager.h: bool ns3::BlockAckManager::HasPackets() const [member function]
+    cls.add_method('HasPackets', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## block-ack-manager.h: void ns3::BlockAckManager::NotifyAgreementEstablished(ns3::Mac48Address recipient, uint8_t tid, uint16_t startingSeq) [member function]
+    cls.add_method('NotifyAgreementEstablished', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('uint16_t', 'startingSeq')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::NotifyAgreementUnsuccessful(ns3::Mac48Address recipient, uint8_t tid) [member function]
+    cls.add_method('NotifyAgreementUnsuccessful', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::NotifyGotBlockAck(ns3::CtrlBAckResponseHeader const * blockAck, ns3::Mac48Address recipient) [member function]
+    cls.add_method('NotifyGotBlockAck', 
+                   'void', 
+                   [param('ns3::CtrlBAckResponseHeader const *', 'blockAck'), param('ns3::Mac48Address', 'recipient')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::NotifyMpduTransmission(ns3::Mac48Address recipient, uint8_t tid) [member function]
+    cls.add_method('NotifyMpduTransmission', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetBlockAckInactivityCallback(ns3::Callback<void, ns3::Mac48Address, unsigned char, bool, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
+    cls.add_method('SetBlockAckInactivityCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Mac48Address, unsigned char, bool, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetBlockAckThreshold(uint8_t nPackets) [member function]
+    cls.add_method('SetBlockAckThreshold', 
+                   'void', 
+                   [param('uint8_t', 'nPackets')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetBlockAckType(ns3::BlockAckType bAckType) [member function]
+    cls.add_method('SetBlockAckType', 
+                   'void', 
+                   [param('ns3::BlockAckType', 'bAckType')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetBlockDestinationCallback(ns3::Callback<void, ns3::Mac48Address, unsigned char, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
+    cls.add_method('SetBlockDestinationCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Mac48Address, unsigned char, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetMaxPacketDelay(ns3::Time maxDelay) [member function]
+    cls.add_method('SetMaxPacketDelay', 
+                   'void', 
+                   [param('ns3::Time', 'maxDelay')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetQueue(ns3::Ptr<ns3::WifiMacQueue> queue) [member function]
+    cls.add_method('SetQueue', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::WifiMacQueue >', 'queue')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetTxMiddle(ns3::MacTxMiddle * txMiddle) [member function]
+    cls.add_method('SetTxMiddle', 
+                   'void', 
+                   [param('ns3::MacTxMiddle *', 'txMiddle')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::SetUnblockDestinationCallback(ns3::Callback<void, ns3::Mac48Address, unsigned char, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
+    cls.add_method('SetUnblockDestinationCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Mac48Address, unsigned char, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::StorePacket(ns3::Ptr<ns3::Packet const> packet, ns3::WifiMacHeader const & hdr, ns3::Time tStamp) [member function]
+    cls.add_method('StorePacket', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const &', 'hdr'), param('ns3::Time', 'tStamp')])
+    ## block-ack-manager.h: bool ns3::BlockAckManager::SwitchToBlockAckIfNeeded(ns3::Mac48Address recipient, uint8_t tid, uint16_t startingSeq) [member function]
+    cls.add_method('SwitchToBlockAckIfNeeded', 
+                   'bool', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('uint16_t', 'startingSeq')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::TearDownBlockAck(ns3::Mac48Address recipient, uint8_t tid) [member function]
+    cls.add_method('TearDownBlockAck', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')])
+    ## block-ack-manager.h: void ns3::BlockAckManager::UpdateAgreement(ns3::MgtAddBaResponseHeader const * respHdr, ns3::Mac48Address recipient) [member function]
+    cls.add_method('UpdateAgreement', 
+                   'void', 
+                   [param('ns3::MgtAddBaResponseHeader const *', 'respHdr'), param('ns3::Mac48Address', 'recipient')])
+    return
+
 def register_Ns3CapabilityInformation_methods(root_module, cls):
     ## capability-information.h: ns3::CapabilityInformation::CapabilityInformation(ns3::CapabilityInformation const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::CapabilityInformation const &', 'arg0')])
@@ -645,6 +858,18 @@
     cls.add_instance_attribute('snr', 'double', is_const=False)
     return
 
+def register_Ns3MacLowBlockAckEventListener_methods(root_module, cls):
+    ## mac-low.h: ns3::MacLowBlockAckEventListener::MacLowBlockAckEventListener(ns3::MacLowBlockAckEventListener const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::MacLowBlockAckEventListener const &', 'arg0')])
+    ## mac-low.h: ns3::MacLowBlockAckEventListener::MacLowBlockAckEventListener() [constructor]
+    cls.add_constructor([])
+    ## mac-low.h: void ns3::MacLowBlockAckEventListener::BlockAckInactivityTimeout(ns3::Mac48Address originator, uint8_t tid) [member function]
+    cls.add_method('BlockAckInactivityTimeout', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'originator'), param('uint8_t', 'tid')], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
 def register_Ns3MacLowDcfListener_methods(root_module, cls):
     ## mac-low.h: ns3::MacLowDcfListener::MacLowDcfListener(ns3::MacLowDcfListener const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::MacLowDcfListener const &', 'arg0')])
@@ -697,6 +922,11 @@
                    'void', 
                    [param('double', 'snr'), param('ns3::WifiMode', 'txMode')], 
                    is_pure_virtual=True, is_virtual=True)
+    ## mac-low.h: void ns3::MacLowTransmissionListener::GotBlockAck(ns3::CtrlBAckResponseHeader const * blockAck, ns3::Mac48Address source) [member function]
+    cls.add_method('GotBlockAck', 
+                   'void', 
+                   [param('ns3::CtrlBAckResponseHeader const *', 'blockAck'), param('ns3::Mac48Address', 'source')], 
+                   is_virtual=True)
     ## mac-low.h: void ns3::MacLowTransmissionListener::GotCts(double snr, ns3::WifiMode txMode) [member function]
     cls.add_method('GotCts', 
                    'void', 
@@ -707,6 +937,11 @@
                    'void', 
                    [], 
                    is_pure_virtual=True, is_virtual=True)
+    ## mac-low.h: void ns3::MacLowTransmissionListener::MissedBlockAck() [member function]
+    cls.add_method('MissedBlockAck', 
+                   'void', 
+                   [], 
+                   is_virtual=True)
     ## mac-low.h: void ns3::MacLowTransmissionListener::MissedCts() [member function]
     cls.add_method('MissedCts', 
                    'void', 
@@ -745,10 +980,22 @@
     cls.add_method('EnableAck', 
                    'void', 
                    [])
+    ## mac-low.h: void ns3::MacLowTransmissionParameters::EnableBasicBlockAck() [member function]
+    cls.add_method('EnableBasicBlockAck', 
+                   'void', 
+                   [])
+    ## mac-low.h: void ns3::MacLowTransmissionParameters::EnableCompressedBlockAck() [member function]
+    cls.add_method('EnableCompressedBlockAck', 
+                   'void', 
+                   [])
     ## mac-low.h: void ns3::MacLowTransmissionParameters::EnableFastAck() [member function]
     cls.add_method('EnableFastAck', 
                    'void', 
                    [])
+    ## mac-low.h: void ns3::MacLowTransmissionParameters::EnableMultiTidBlockAck() [member function]
+    cls.add_method('EnableMultiTidBlockAck', 
+                   'void', 
+                   [])
     ## mac-low.h: void ns3::MacLowTransmissionParameters::EnableNextData(uint32_t size) [member function]
     cls.add_method('EnableNextData', 
                    'void', 
@@ -795,11 +1042,26 @@
                    'bool', 
                    [], 
                    is_const=True)
+    ## mac-low.h: bool ns3::MacLowTransmissionParameters::MustWaitBasicBlockAck() const [member function]
+    cls.add_method('MustWaitBasicBlockAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## mac-low.h: bool ns3::MacLowTransmissionParameters::MustWaitCompressedBlockAck() const [member function]
+    cls.add_method('MustWaitCompressedBlockAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
     ## mac-low.h: bool ns3::MacLowTransmissionParameters::MustWaitFastAck() const [member function]
     cls.add_method('MustWaitFastAck', 
                    'bool', 
                    [], 
                    is_const=True)
+    ## mac-low.h: bool ns3::MacLowTransmissionParameters::MustWaitMultiTidBlockAck() const [member function]
+    cls.add_method('MustWaitMultiTidBlockAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
     ## mac-low.h: bool ns3::MacLowTransmissionParameters::MustWaitNormalAck() const [member function]
     cls.add_method('MustWaitNormalAck', 
                    'bool', 
@@ -827,6 +1089,52 @@
                    [param('ns3::Callback< void, ns3::Ptr< ns3::Packet >, ns3::WifiMacHeader const *, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
     return
 
+def register_Ns3OriginatorBlockAckAgreement_methods(root_module, cls):
+    ## originator-block-ack-agreement.h: ns3::OriginatorBlockAckAgreement::OriginatorBlockAckAgreement(ns3::OriginatorBlockAckAgreement const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::OriginatorBlockAckAgreement const &', 'arg0')])
+    ## originator-block-ack-agreement.h: ns3::OriginatorBlockAckAgreement::OriginatorBlockAckAgreement() [constructor]
+    cls.add_constructor([])
+    ## originator-block-ack-agreement.h: ns3::OriginatorBlockAckAgreement::OriginatorBlockAckAgreement(ns3::Mac48Address recipient, uint8_t tid) [constructor]
+    cls.add_constructor([param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')])
+    ## originator-block-ack-agreement.h: void ns3::OriginatorBlockAckAgreement::CompleteExchange() [member function]
+    cls.add_method('CompleteExchange', 
+                   'void', 
+                   [])
+    ## originator-block-ack-agreement.h: bool ns3::OriginatorBlockAckAgreement::IsEstablished() const [member function]
+    cls.add_method('IsEstablished', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## originator-block-ack-agreement.h: bool ns3::OriginatorBlockAckAgreement::IsInactive() const [member function]
+    cls.add_method('IsInactive', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## originator-block-ack-agreement.h: bool ns3::OriginatorBlockAckAgreement::IsPending() const [member function]
+    cls.add_method('IsPending', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## originator-block-ack-agreement.h: bool ns3::OriginatorBlockAckAgreement::IsUnsuccessful() const [member function]
+    cls.add_method('IsUnsuccessful', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## originator-block-ack-agreement.h: bool ns3::OriginatorBlockAckAgreement::NeedBlockAckRequest() const [member function]
+    cls.add_method('NeedBlockAckRequest', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## originator-block-ack-agreement.h: void ns3::OriginatorBlockAckAgreement::NotifyMpduTransmission() [member function]
+    cls.add_method('NotifyMpduTransmission', 
+                   'void', 
+                   [])
+    ## originator-block-ack-agreement.h: void ns3::OriginatorBlockAckAgreement::SetState(ns3::OriginatorBlockAckAgreement::State state) [member function]
+    cls.add_method('SetState', 
+                   'void', 
+                   [param('ns3::OriginatorBlockAckAgreement::State', 'state')])
+    return
+
 def register_Ns3RateInfo_methods(root_module, cls):
     ## minstrel-wifi-manager.h: ns3::RateInfo::RateInfo() [constructor]
     cls.add_constructor([])
@@ -1093,6 +1401,11 @@
                    'ns3::WifiMode', 
                    [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate'), param('uint8_t', 'constellationSize'), param('ns3::WifiPhyStandard', 'standard')], 
                    is_static=True)
+    ## wifi-mode.h: static ns3::WifiMode ns3::WifiModeFactory::CreateQpsk(std::string uniqueName, bool isMandatory, uint32_t bandwidth, uint32_t dataRate, uint32_t phyRate, ns3::WifiPhyStandard standard) [member function]
+    cls.add_method('CreateQpsk', 
+                   'ns3::WifiMode', 
+                   [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate'), param('ns3::WifiPhyStandard', 'standard')], 
+                   is_static=True)
     return
 
 def register_Ns3WifiPhyListener_methods(root_module, cls):
@@ -1607,6 +1920,196 @@
                    is_const=True, visibility='private', is_virtual=True)
     return
 
+def register_Ns3MgtAddBaRequestHeader_methods(root_module, cls):
+    ## mgt-headers.h: ns3::MgtAddBaRequestHeader::MgtAddBaRequestHeader(ns3::MgtAddBaRequestHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::MgtAddBaRequestHeader const &', 'arg0')])
+    ## mgt-headers.h: ns3::MgtAddBaRequestHeader::MgtAddBaRequestHeader() [constructor]
+    cls.add_constructor([])
+    ## mgt-headers.h: uint32_t ns3::MgtAddBaRequestHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## mgt-headers.h: uint16_t ns3::MgtAddBaRequestHeader::GetBufferSize() const [member function]
+    cls.add_method('GetBufferSize', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: ns3::TypeId ns3::MgtAddBaRequestHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: uint32_t ns3::MgtAddBaRequestHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: uint16_t ns3::MgtAddBaRequestHeader::GetStartingSequence() const [member function]
+    cls.add_method('GetStartingSequence', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: uint8_t ns3::MgtAddBaRequestHeader::GetTid() const [member function]
+    cls.add_method('GetTid', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: uint16_t ns3::MgtAddBaRequestHeader::GetTimeout() const [member function]
+    cls.add_method('GetTimeout', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: static ns3::TypeId ns3::MgtAddBaRequestHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## mgt-headers.h: bool ns3::MgtAddBaRequestHeader::IsAmsduSupported() const [member function]
+    cls.add_method('IsAmsduSupported', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: bool ns3::MgtAddBaRequestHeader::IsImmediateBlockAck() const [member function]
+    cls.add_method('IsImmediateBlockAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::SetAmsduSupport(bool supported) [member function]
+    cls.add_method('SetAmsduSupport', 
+                   'void', 
+                   [param('bool', 'supported')])
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::SetBufferSize(uint16_t size) [member function]
+    cls.add_method('SetBufferSize', 
+                   'void', 
+                   [param('uint16_t', 'size')])
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::SetDelayedBlockAck() [member function]
+    cls.add_method('SetDelayedBlockAck', 
+                   'void', 
+                   [])
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::SetImmediateBlockAck() [member function]
+    cls.add_method('SetImmediateBlockAck', 
+                   'void', 
+                   [])
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::SetStartingSequence(uint16_t seq) [member function]
+    cls.add_method('SetStartingSequence', 
+                   'void', 
+                   [param('uint16_t', 'seq')])
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::SetTid(uint8_t tid) [member function]
+    cls.add_method('SetTid', 
+                   'void', 
+                   [param('uint8_t', 'tid')])
+    ## mgt-headers.h: void ns3::MgtAddBaRequestHeader::SetTimeout(uint16_t timeout) [member function]
+    cls.add_method('SetTimeout', 
+                   'void', 
+                   [param('uint16_t', 'timeout')])
+    return
+
+def register_Ns3MgtAddBaResponseHeader_methods(root_module, cls):
+    ## mgt-headers.h: ns3::MgtAddBaResponseHeader::MgtAddBaResponseHeader(ns3::MgtAddBaResponseHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::MgtAddBaResponseHeader const &', 'arg0')])
+    ## mgt-headers.h: ns3::MgtAddBaResponseHeader::MgtAddBaResponseHeader() [constructor]
+    cls.add_constructor([])
+    ## mgt-headers.h: uint32_t ns3::MgtAddBaResponseHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## mgt-headers.h: uint16_t ns3::MgtAddBaResponseHeader::GetBufferSize() const [member function]
+    cls.add_method('GetBufferSize', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: ns3::TypeId ns3::MgtAddBaResponseHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: uint32_t ns3::MgtAddBaResponseHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: ns3::StatusCode ns3::MgtAddBaResponseHeader::GetStatusCode() const [member function]
+    cls.add_method('GetStatusCode', 
+                   'ns3::StatusCode', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: uint8_t ns3::MgtAddBaResponseHeader::GetTid() const [member function]
+    cls.add_method('GetTid', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: uint16_t ns3::MgtAddBaResponseHeader::GetTimeout() const [member function]
+    cls.add_method('GetTimeout', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: static ns3::TypeId ns3::MgtAddBaResponseHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## mgt-headers.h: bool ns3::MgtAddBaResponseHeader::IsAmsduSupported() const [member function]
+    cls.add_method('IsAmsduSupported', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: bool ns3::MgtAddBaResponseHeader::IsImmediateBlockAck() const [member function]
+    cls.add_method('IsImmediateBlockAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::SetAmsduSupport(bool supported) [member function]
+    cls.add_method('SetAmsduSupport', 
+                   'void', 
+                   [param('bool', 'supported')])
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::SetBufferSize(uint16_t size) [member function]
+    cls.add_method('SetBufferSize', 
+                   'void', 
+                   [param('uint16_t', 'size')])
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::SetDelayedBlockAck() [member function]
+    cls.add_method('SetDelayedBlockAck', 
+                   'void', 
+                   [])
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::SetImmediateBlockAck() [member function]
+    cls.add_method('SetImmediateBlockAck', 
+                   'void', 
+                   [])
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::SetStatusCode(ns3::StatusCode code) [member function]
+    cls.add_method('SetStatusCode', 
+                   'void', 
+                   [param('ns3::StatusCode', 'code')])
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::SetTid(uint8_t tid) [member function]
+    cls.add_method('SetTid', 
+                   'void', 
+                   [param('uint8_t', 'tid')])
+    ## mgt-headers.h: void ns3::MgtAddBaResponseHeader::SetTimeout(uint16_t timeout) [member function]
+    cls.add_method('SetTimeout', 
+                   'void', 
+                   [param('uint16_t', 'timeout')])
+    return
+
 def register_Ns3MgtAssocRequestHeader_methods(root_module, cls):
     ## mgt-headers.h: ns3::MgtAssocRequestHeader::MgtAssocRequestHeader(ns3::MgtAssocRequestHeader const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::MgtAssocRequestHeader const &', 'arg0')])
@@ -1724,6 +2227,65 @@
                    [param('ns3::SupportedRates', 'rates')])
     return
 
+def register_Ns3MgtDelBaHeader_methods(root_module, cls):
+    ## mgt-headers.h: ns3::MgtDelBaHeader::MgtDelBaHeader(ns3::MgtDelBaHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::MgtDelBaHeader const &', 'arg0')])
+    ## mgt-headers.h: ns3::MgtDelBaHeader::MgtDelBaHeader() [constructor]
+    cls.add_constructor([])
+    ## mgt-headers.h: uint32_t ns3::MgtDelBaHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## mgt-headers.h: ns3::TypeId ns3::MgtDelBaHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: uint32_t ns3::MgtDelBaHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: uint8_t ns3::MgtDelBaHeader::GetTid() const [member function]
+    cls.add_method('GetTid', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: static ns3::TypeId ns3::MgtDelBaHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## mgt-headers.h: bool ns3::MgtDelBaHeader::IsByOriginator() const [member function]
+    cls.add_method('IsByOriginator', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## mgt-headers.h: void ns3::MgtDelBaHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: void ns3::MgtDelBaHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    ## mgt-headers.h: void ns3::MgtDelBaHeader::SetByOriginator() [member function]
+    cls.add_method('SetByOriginator', 
+                   'void', 
+                   [])
+    ## mgt-headers.h: void ns3::MgtDelBaHeader::SetByRecipient() [member function]
+    cls.add_method('SetByRecipient', 
+                   'void', 
+                   [])
+    ## mgt-headers.h: void ns3::MgtDelBaHeader::SetTid(uint8_t arg0) [member function]
+    cls.add_method('SetTid', 
+                   'void', 
+                   [param('uint8_t', 'arg0')])
+    return
+
 def register_Ns3MgtProbeRequestHeader_methods(root_module, cls):
     ## mgt-headers.h: ns3::MgtProbeRequestHeader::MgtProbeRequestHeader() [constructor]
     cls.add_constructor([])
@@ -1961,47 +2523,6 @@
                    is_const=True, visibility='private', is_virtual=True)
     return
 
-def register_Ns3PropagationDelayModel_methods(root_module, cls):
-    ## propagation-delay-model.h: ns3::PropagationDelayModel::PropagationDelayModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-delay-model.h: ns3::PropagationDelayModel::PropagationDelayModel(ns3::PropagationDelayModel const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::PropagationDelayModel const &', 'arg0')])
-    ## propagation-delay-model.h: ns3::Time ns3::PropagationDelayModel::GetDelay(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('GetDelay', 
-                   'ns3::Time', 
-                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_pure_virtual=True, is_const=True, is_virtual=True)
-    ## propagation-delay-model.h: static ns3::TypeId ns3::PropagationDelayModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    return
-
-def register_Ns3PropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: static ns3::TypeId ns3::PropagationLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## propagation-loss-model.h: ns3::PropagationLossModel::PropagationLossModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-loss-model.h: void ns3::PropagationLossModel::SetNext(ns3::Ptr<ns3::PropagationLossModel> next) [member function]
-    cls.add_method('SetNext', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::PropagationLossModel >', 'next')])
-    ## propagation-loss-model.h: double ns3::PropagationLossModel::CalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('CalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True)
-    ## propagation-loss-model.h: double ns3::PropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
-    return
-
 def register_Ns3QosTag_methods(root_module, cls):
     ## qos-tag.h: ns3::QosTag::QosTag(ns3::QosTag const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::QosTag const &', 'arg0')])
@@ -2054,38 +2575,6 @@
                    [param('ns3::UserPriority', 'up')])
     return
 
-def register_Ns3RandomPropagationDelayModel_methods(root_module, cls):
-    ## propagation-delay-model.h: ns3::RandomPropagationDelayModel::RandomPropagationDelayModel(ns3::RandomPropagationDelayModel const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::RandomPropagationDelayModel const &', 'arg0')])
-    ## propagation-delay-model.h: ns3::RandomPropagationDelayModel::RandomPropagationDelayModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-delay-model.h: ns3::Time ns3::RandomPropagationDelayModel::GetDelay(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('GetDelay', 
-                   'ns3::Time', 
-                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, is_virtual=True)
-    ## propagation-delay-model.h: static ns3::TypeId ns3::RandomPropagationDelayModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    return
-
-def register_Ns3RandomPropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: static ns3::TypeId ns3::RandomPropagationLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## propagation-loss-model.h: ns3::RandomPropagationLossModel::RandomPropagationLossModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-loss-model.h: double ns3::RandomPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, visibility='private', is_virtual=True)
-    return
-
 def register_Ns3RraaWifiRemoteStation_methods(root_module, cls):
     ## rraa-wifi-manager.h: ns3::RraaWifiRemoteStation::RraaWifiRemoteStation(ns3::RraaWifiRemoteStation const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::RraaWifiRemoteStation const &', 'arg0')])
@@ -2148,21 +2637,6 @@
                    is_const=True, visibility='private', is_virtual=True)
     return
 
-def register_Ns3ThreeLogDistancePropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: static ns3::TypeId ns3::ThreeLogDistancePropagationLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## propagation-loss-model.h: ns3::ThreeLogDistancePropagationLossModel::ThreeLogDistancePropagationLossModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-loss-model.h: double ns3::ThreeLogDistancePropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, visibility='private', is_virtual=True)
-    return
-
 def register_Ns3WifiActionHeader_methods(root_module, cls):
     ## mgt-headers.h: ns3::WifiActionHeader::WifiActionHeader(ns3::WifiActionHeader const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::WifiActionHeader const &', 'arg0')])
@@ -2217,6 +2691,8 @@
     cls.add_constructor([])
     ## mgt-headers.h: ns3::WifiActionHeader::ActionValue::ActionValue(ns3::WifiActionHeader::ActionValue const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::WifiActionHeader::ActionValue const &', 'arg0')])
+    ## mgt-headers.h: ns3::WifiActionHeader::ActionValue::blockAck [variable]
+    cls.add_instance_attribute('blockAck', 'ns3::WifiActionHeader::BlockAckActionValue', is_const=False)
     ## mgt-headers.h: ns3::WifiActionHeader::ActionValue::interwork [variable]
     cls.add_instance_attribute('interwork', 'ns3::WifiActionHeader::InterworkActionValue', is_const=False)
     ## mgt-headers.h: ns3::WifiActionHeader::ActionValue::linkMetrtic [variable]
@@ -2258,11 +2734,21 @@
                    'ns3::Mac48Address', 
                    [], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## wifi-mac.h: ns3::Time ns3::WifiMac::GetBasicBlockAckTimeout() const [member function]
+    cls.add_method('GetBasicBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
     ## wifi-mac.h: ns3::Mac48Address ns3::WifiMac::GetBssid() const [member function]
     cls.add_method('GetBssid', 
                    'ns3::Mac48Address', 
                    [], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## wifi-mac.h: ns3::Time ns3::WifiMac::GetCompressedBlockAckTimeout() const [member function]
+    cls.add_method('GetCompressedBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
     ## wifi-mac.h: ns3::Time ns3::WifiMac::GetCtsTimeout() const [member function]
     cls.add_method('GetCtsTimeout', 
                    'ns3::Time', 
@@ -2343,6 +2829,16 @@
                    'void', 
                    [param('ns3::Mac48Address', 'address')], 
                    is_pure_virtual=True, is_virtual=True)
+    ## wifi-mac.h: void ns3::WifiMac::SetBasicBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetBasicBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
+    ## wifi-mac.h: void ns3::WifiMac::SetCompressedBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetCompressedBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
     ## wifi-mac.h: void ns3::WifiMac::SetCtsTimeout(ns3::Time ctsTimeout) [member function]
     cls.add_method('SetCtsTimeout', 
                    'void', 
@@ -2554,6 +3050,16 @@
                    'bool', 
                    [], 
                    is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsBlockAck() const [member function]
+    cls.add_method('IsBlockAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsBlockAckReq() const [member function]
+    cls.add_method('IsBlockAckReq', 
+                   'bool', 
+                   [], 
+                   is_const=True)
     ## wifi-mac-header.h: bool ns3::WifiMacHeader::IsCfpoll() const [member function]
     cls.add_method('IsCfpoll', 
                    'bool', 
@@ -2711,6 +3217,14 @@
     cls.add_method('SetBeacon', 
                    'void', 
                    [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetBlockAck() [member function]
+    cls.add_method('SetBlockAck', 
+                   'void', 
+                   [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetBlockAckReq() [member function]
+    cls.add_method('SetBlockAckReq', 
+                   'void', 
+                   [])
     ## wifi-mac-header.h: void ns3::WifiMacHeader::SetDsFrom() [member function]
     cls.add_method('SetDsFrom', 
                    'void', 
@@ -2771,10 +3285,18 @@
     cls.add_method('SetQosAmsdu', 
                    'void', 
                    [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosBlockAck() [member function]
+    cls.add_method('SetQosBlockAck', 
+                   'void', 
+                   [])
     ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosEosp() [member function]
     cls.add_method('SetQosEosp', 
                    'void', 
                    [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosNoAck() [member function]
+    cls.add_method('SetQosNoAck', 
+                   'void', 
+                   [])
     ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosNoAmsdu() [member function]
     cls.add_method('SetQosNoAmsdu', 
                    'void', 
@@ -2783,6 +3305,10 @@
     cls.add_method('SetQosNoEosp', 
                    'void', 
                    [])
+    ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosNormalAck() [member function]
+    cls.add_method('SetQosNormalAck', 
+                   'void', 
+                   [])
     ## wifi-mac-header.h: void ns3::WifiMacHeader::SetQosTid(uint8_t tid) [member function]
     cls.add_method('SetQosTid', 
                    'void', 
@@ -3754,30 +4280,202 @@
                    visibility='private', is_virtual=True)
     return
 
-def register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, cls):
-    ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel::ConstantSpeedPropagationDelayModel(ns3::ConstantSpeedPropagationDelayModel const & arg0) [copy constructor]
-    cls.add_constructor([param('ns3::ConstantSpeedPropagationDelayModel const &', 'arg0')])
-    ## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel::ConstantSpeedPropagationDelayModel() [constructor]
+def register_Ns3CtrlBAckRequestHeader_methods(root_module, cls):
+    ## ctrl-headers.h: ns3::CtrlBAckRequestHeader::CtrlBAckRequestHeader(ns3::CtrlBAckRequestHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::CtrlBAckRequestHeader const &', 'arg0')])
+    ## ctrl-headers.h: ns3::CtrlBAckRequestHeader::CtrlBAckRequestHeader() [constructor]
     cls.add_constructor([])
-    ## propagation-delay-model.h: ns3::Time ns3::ConstantSpeedPropagationDelayModel::GetDelay(ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('GetDelay', 
-                   'ns3::Time', 
-                   [param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, is_virtual=True)
-    ## propagation-delay-model.h: double ns3::ConstantSpeedPropagationDelayModel::GetSpeed() const [member function]
-    cls.add_method('GetSpeed', 
-                   'double', 
-                   [], 
-                   is_const=True)
-    ## propagation-delay-model.h: static ns3::TypeId ns3::ConstantSpeedPropagationDelayModel::GetTypeId() [member function]
+    ## ctrl-headers.h: uint32_t ns3::CtrlBAckRequestHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## ctrl-headers.h: ns3::TypeId ns3::CtrlBAckRequestHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: uint32_t ns3::CtrlBAckRequestHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: uint16_t ns3::CtrlBAckRequestHeader::GetStartingSequence() const [member function]
+    cls.add_method('GetStartingSequence', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: uint16_t ns3::CtrlBAckRequestHeader::GetStartingSequenceControl() const [member function]
+    cls.add_method('GetStartingSequenceControl', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: uint8_t ns3::CtrlBAckRequestHeader::GetTidInfo() const [member function]
+    cls.add_method('GetTidInfo', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: static ns3::TypeId ns3::CtrlBAckRequestHeader::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
                    [], 
                    is_static=True)
-    ## propagation-delay-model.h: void ns3::ConstantSpeedPropagationDelayModel::SetSpeed(double speed) [member function]
-    cls.add_method('SetSpeed', 
-                   'void', 
-                   [param('double', 'speed')])
+    ## ctrl-headers.h: bool ns3::CtrlBAckRequestHeader::IsBasic() const [member function]
+    cls.add_method('IsBasic', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckRequestHeader::IsCompressed() const [member function]
+    cls.add_method('IsCompressed', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckRequestHeader::IsMultiTid() const [member function]
+    cls.add_method('IsMultiTid', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckRequestHeader::MustSendHtImmediateAck() const [member function]
+    cls.add_method('MustSendHtImmediateAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: void ns3::CtrlBAckRequestHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: void ns3::CtrlBAckRequestHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: void ns3::CtrlBAckRequestHeader::SetHtImmediateAck(bool immediateAck) [member function]
+    cls.add_method('SetHtImmediateAck', 
+                   'void', 
+                   [param('bool', 'immediateAck')])
+    ## ctrl-headers.h: void ns3::CtrlBAckRequestHeader::SetStartingSequence(uint16_t seq) [member function]
+    cls.add_method('SetStartingSequence', 
+                   'void', 
+                   [param('uint16_t', 'seq')])
+    ## ctrl-headers.h: void ns3::CtrlBAckRequestHeader::SetTidInfo(uint8_t tid) [member function]
+    cls.add_method('SetTidInfo', 
+                   'void', 
+                   [param('uint8_t', 'tid')])
+    ## ctrl-headers.h: void ns3::CtrlBAckRequestHeader::SetType(ns3::BlockAckType type) [member function]
+    cls.add_method('SetType', 
+                   'void', 
+                   [param('ns3::BlockAckType', 'type')])
+    return
+
+def register_Ns3CtrlBAckResponseHeader_methods(root_module, cls):
+    ## ctrl-headers.h: ns3::CtrlBAckResponseHeader::CtrlBAckResponseHeader(ns3::CtrlBAckResponseHeader const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::CtrlBAckResponseHeader const &', 'arg0')])
+    ## ctrl-headers.h: ns3::CtrlBAckResponseHeader::CtrlBAckResponseHeader() [constructor]
+    cls.add_constructor([])
+    ## ctrl-headers.h: uint32_t ns3::CtrlBAckResponseHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## ctrl-headers.h: ns3::TypeId ns3::CtrlBAckResponseHeader::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: uint32_t ns3::CtrlBAckResponseHeader::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: uint16_t ns3::CtrlBAckResponseHeader::GetStartingSequence() const [member function]
+    cls.add_method('GetStartingSequence', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: uint16_t ns3::CtrlBAckResponseHeader::GetStartingSequenceControl() const [member function]
+    cls.add_method('GetStartingSequenceControl', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: uint8_t ns3::CtrlBAckResponseHeader::GetTidInfo() const [member function]
+    cls.add_method('GetTidInfo', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: static ns3::TypeId ns3::CtrlBAckResponseHeader::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckResponseHeader::IsBasic() const [member function]
+    cls.add_method('IsBasic', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckResponseHeader::IsCompressed() const [member function]
+    cls.add_method('IsCompressed', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckResponseHeader::IsFragmentReceived(uint16_t seq, uint8_t frag) const [member function]
+    cls.add_method('IsFragmentReceived', 
+                   'bool', 
+                   [param('uint16_t', 'seq'), param('uint8_t', 'frag')], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckResponseHeader::IsMultiTid() const [member function]
+    cls.add_method('IsMultiTid', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckResponseHeader::IsPacketReceived(uint16_t seq) const [member function]
+    cls.add_method('IsPacketReceived', 
+                   'bool', 
+                   [param('uint16_t', 'seq')], 
+                   is_const=True)
+    ## ctrl-headers.h: bool ns3::CtrlBAckResponseHeader::MustSendHtImmediateAck() const [member function]
+    cls.add_method('MustSendHtImmediateAck', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::SetHtImmediateAck(bool immeadiateAck) [member function]
+    cls.add_method('SetHtImmediateAck', 
+                   'void', 
+                   [param('bool', 'immeadiateAck')])
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::SetReceivedFragment(uint16_t seq, uint8_t frag) [member function]
+    cls.add_method('SetReceivedFragment', 
+                   'void', 
+                   [param('uint16_t', 'seq'), param('uint8_t', 'frag')])
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::SetReceivedPacket(uint16_t seq) [member function]
+    cls.add_method('SetReceivedPacket', 
+                   'void', 
+                   [param('uint16_t', 'seq')])
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::SetStartingSequence(uint16_t seq) [member function]
+    cls.add_method('SetStartingSequence', 
+                   'void', 
+                   [param('uint16_t', 'seq')])
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::SetStartingSequenceControl(uint16_t seqControl) [member function]
+    cls.add_method('SetStartingSequenceControl', 
+                   'void', 
+                   [param('uint16_t', 'seqControl')])
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::SetTidInfo(uint8_t tid) [member function]
+    cls.add_method('SetTidInfo', 
+                   'void', 
+                   [param('uint8_t', 'tid')])
+    ## ctrl-headers.h: void ns3::CtrlBAckResponseHeader::SetType(ns3::BlockAckType type) [member function]
+    cls.add_method('SetType', 
+                   'void', 
+                   [param('ns3::BlockAckType', 'type')])
     return
 
 def register_Ns3Dcf_methods(root_module, cls):
@@ -3948,6 +4646,22 @@
     cls.add_method('GotAck', 
                    'void', 
                    [param('double', 'snr'), param('ns3::WifiMode', 'txMode')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::GotBlockAck(ns3::CtrlBAckResponseHeader const * blockAck, ns3::Mac48Address recipient) [member function]
+    cls.add_method('GotBlockAck', 
+                   'void', 
+                   [param('ns3::CtrlBAckResponseHeader const *', 'blockAck'), param('ns3::Mac48Address', 'recipient')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::MissedBlockAck() [member function]
+    cls.add_method('MissedBlockAck', 
+                   'void', 
+                   [])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::GotAddBaResponse(ns3::MgtAddBaResponseHeader const * respHdr, ns3::Mac48Address recipient) [member function]
+    cls.add_method('GotAddBaResponse', 
+                   'void', 
+                   [param('ns3::MgtAddBaResponseHeader const *', 'respHdr'), param('ns3::Mac48Address', 'recipient')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::GotDelBaFrame(ns3::MgtDelBaHeader const * delBaHdr, ns3::Mac48Address recipient) [member function]
+    cls.add_method('GotDelBaFrame', 
+                   'void', 
+                   [param('ns3::MgtDelBaHeader const *', 'delBaHdr'), param('ns3::Mac48Address', 'recipient')])
     ## edca-txop-n.h: void ns3::EdcaTxopN::MissedAck() [member function]
     cls.add_method('MissedAck', 
                    'void', 
@@ -4015,6 +4729,10 @@
     cls.add_method('GetFragmentPacket', 
                    'ns3::Ptr< ns3::Packet >', 
                    [param('ns3::WifiMacHeader *', 'hdr')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetAccessClass(ns3::AccessClass ac) [member function]
+    cls.add_method('SetAccessClass', 
+                   'void', 
+                   [param('ns3::AccessClass', 'ac')])
     ## edca-txop-n.h: void ns3::EdcaTxopN::Queue(ns3::Ptr<ns3::Packet const> packet, ns3::WifiMacHeader const & hdr) [member function]
     cls.add_method('Queue', 
                    'void', 
@@ -4023,6 +4741,27 @@
     cls.add_method('SetMsduAggregator', 
                    'void', 
                    [param('ns3::Ptr< ns3::MsduAggregator >', 'aggr')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::PushFront(ns3::Ptr<ns3::Packet const> packet, ns3::WifiMacHeader const & hdr) [member function]
+    cls.add_method('PushFront', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const &', 'hdr')])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::CompleteConfig() [member function]
+    cls.add_method('CompleteConfig', 
+                   'void', 
+                   [])
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SetBlockAckThreshold(uint8_t threshold) [member function]
+    cls.add_method('SetBlockAckThreshold', 
+                   'void', 
+                   [param('uint8_t', 'threshold')])
+    ## edca-txop-n.h: uint8_t ns3::EdcaTxopN::GetBlockAckThreshold() const [member function]
+    cls.add_method('GetBlockAckThreshold', 
+                   'uint8_t', 
+                   [], 
+                   is_const=True)
+    ## edca-txop-n.h: void ns3::EdcaTxopN::SendDelbaFrame(ns3::Mac48Address addr, uint8_t tid, bool byOriginator) [member function]
+    cls.add_method('SendDelbaFrame', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'addr'), param('uint8_t', 'tid'), param('bool', 'byOriginator')])
     return
 
 def register_Ns3ErrorRateModel_methods(root_module, cls):
@@ -4047,71 +4786,6 @@
                    is_static=True)
     return
 
-def register_Ns3FixedRssLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: static ns3::TypeId ns3::FixedRssLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## propagation-loss-model.h: ns3::FixedRssLossModel::FixedRssLossModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-loss-model.h: void ns3::FixedRssLossModel::SetRss(double rss) [member function]
-    cls.add_method('SetRss', 
-                   'void', 
-                   [param('double', 'rss')])
-    ## propagation-loss-model.h: double ns3::FixedRssLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, visibility='private', is_virtual=True)
-    return
-
-def register_Ns3FriisPropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: static ns3::TypeId ns3::FriisPropagationLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## propagation-loss-model.h: ns3::FriisPropagationLossModel::FriisPropagationLossModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetLambda(double frequency, double speed) [member function]
-    cls.add_method('SetLambda', 
-                   'void', 
-                   [param('double', 'frequency'), param('double', 'speed')])
-    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetLambda(double lambda) [member function]
-    cls.add_method('SetLambda', 
-                   'void', 
-                   [param('double', 'lambda')])
-    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetSystemLoss(double systemLoss) [member function]
-    cls.add_method('SetSystemLoss', 
-                   'void', 
-                   [param('double', 'systemLoss')])
-    ## propagation-loss-model.h: void ns3::FriisPropagationLossModel::SetMinDistance(double minDistance) [member function]
-    cls.add_method('SetMinDistance', 
-                   'void', 
-                   [param('double', 'minDistance')])
-    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetMinDistance() const [member function]
-    cls.add_method('GetMinDistance', 
-                   'double', 
-                   [], 
-                   is_const=True)
-    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetLambda() const [member function]
-    cls.add_method('GetLambda', 
-                   'double', 
-                   [], 
-                   is_const=True)
-    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::GetSystemLoss() const [member function]
-    cls.add_method('GetSystemLoss', 
-                   'double', 
-                   [], 
-                   is_const=True)
-    ## propagation-loss-model.h: double ns3::FriisPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, visibility='private', is_virtual=True)
-    return
-
 def register_Ns3IdealWifiManager_methods(root_module, cls):
     ## ideal-wifi-manager.h: ns3::IdealWifiManager::IdealWifiManager(ns3::IdealWifiManager const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::IdealWifiManager const &', 'arg0')])
@@ -4143,67 +4817,6 @@
                    visibility='private', is_virtual=True)
     return
 
-def register_Ns3JakesPropagationLossModel_methods(root_module, cls):
-    ## jakes-propagation-loss-model.h: ns3::JakesPropagationLossModel::JakesPropagationLossModel() [constructor]
-    cls.add_constructor([])
-    ## jakes-propagation-loss-model.h: uint8_t ns3::JakesPropagationLossModel::GetNOscillators() const [member function]
-    cls.add_method('GetNOscillators', 
-                   'uint8_t', 
-                   [], 
-                   is_const=True)
-    ## jakes-propagation-loss-model.h: uint8_t ns3::JakesPropagationLossModel::GetNRays() const [member function]
-    cls.add_method('GetNRays', 
-                   'uint8_t', 
-                   [], 
-                   is_const=True)
-    ## jakes-propagation-loss-model.h: static ns3::TypeId ns3::JakesPropagationLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## jakes-propagation-loss-model.h: void ns3::JakesPropagationLossModel::SetNOscillators(uint8_t nOscillators) [member function]
-    cls.add_method('SetNOscillators', 
-                   'void', 
-                   [param('uint8_t', 'nOscillators')])
-    ## jakes-propagation-loss-model.h: void ns3::JakesPropagationLossModel::SetNRays(uint8_t nRays) [member function]
-    cls.add_method('SetNRays', 
-                   'void', 
-                   [param('uint8_t', 'nRays')])
-    ## jakes-propagation-loss-model.h: double ns3::JakesPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, visibility='private', is_virtual=True)
-    return
-
-def register_Ns3LogDistancePropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: static ns3::TypeId ns3::LogDistancePropagationLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## propagation-loss-model.h: ns3::LogDistancePropagationLossModel::LogDistancePropagationLossModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetPathLossExponent(double n) [member function]
-    cls.add_method('SetPathLossExponent', 
-                   'void', 
-                   [param('double', 'n')])
-    ## propagation-loss-model.h: double ns3::LogDistancePropagationLossModel::GetPathLossExponent() const [member function]
-    cls.add_method('GetPathLossExponent', 
-                   'double', 
-                   [], 
-                   is_const=True)
-    ## propagation-loss-model.h: void ns3::LogDistancePropagationLossModel::SetReference(double referenceDistance, double referenceLoss) [member function]
-    cls.add_method('SetReference', 
-                   'void', 
-                   [param('double', 'referenceDistance'), param('double', 'referenceLoss')])
-    ## propagation-loss-model.h: double ns3::LogDistancePropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, visibility='private', is_virtual=True)
-    return
-
 def register_Ns3MacLow_methods(root_module, cls):
     ## mac-low.h: ns3::MacLow::MacLow(ns3::MacLow const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::MacLow const &', 'arg0')])
@@ -4214,6 +4827,14 @@
                    'ns3::Time', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr'), param('ns3::MacLowTransmissionParameters const &', 'parameters')], 
                    is_const=True)
+    ## mac-low.h: void ns3::MacLow::CreateBlockAckAgreement(ns3::MgtAddBaResponseHeader const * respHdr, ns3::Mac48Address originator, uint16_t startingSeq) [member function]
+    cls.add_method('CreateBlockAckAgreement', 
+                   'void', 
+                   [param('ns3::MgtAddBaResponseHeader const *', 'respHdr'), param('ns3::Mac48Address', 'originator'), param('uint16_t', 'startingSeq')])
+    ## mac-low.h: void ns3::MacLow::DestroyBlockAckAgreement(ns3::Mac48Address originator, uint8_t tid) [member function]
+    cls.add_method('DestroyBlockAckAgreement', 
+                   'void', 
+                   [param('ns3::Mac48Address', 'originator'), param('uint8_t', 'tid')])
     ## mac-low.h: ns3::Time ns3::MacLow::GetAckTimeout() const [member function]
     cls.add_method('GetAckTimeout', 
                    'ns3::Time', 
@@ -4224,11 +4845,21 @@
                    'ns3::Mac48Address', 
                    [], 
                    is_const=True)
+    ## mac-low.h: ns3::Time ns3::MacLow::GetBasicBlockAckTimeout() const [member function]
+    cls.add_method('GetBasicBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True)
     ## mac-low.h: ns3::Mac48Address ns3::MacLow::GetBssid() const [member function]
     cls.add_method('GetBssid', 
                    'ns3::Mac48Address', 
                    [], 
                    is_const=True)
+    ## mac-low.h: ns3::Time ns3::MacLow::GetCompressedBlockAckTimeout() const [member function]
+    cls.add_method('GetCompressedBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True)
     ## mac-low.h: ns3::Time ns3::MacLow::GetCtsTimeout() const [member function]
     cls.add_method('GetCtsTimeout', 
                    'ns3::Time', 
@@ -4261,6 +4892,10 @@
     cls.add_method('ReceiveOk', 
                    'void', 
                    [param('ns3::Ptr< ns3::Packet >', 'packet'), param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode'), param('ns3::WifiPreamble', 'preamble')])
+    ## mac-low.h: void ns3::MacLow::RegisterBlockAckListenerForAc(ns3::AccessClass ac, ns3::MacLowBlockAckEventListener * listener) [member function]
+    cls.add_method('RegisterBlockAckListenerForAc', 
+                   'void', 
+                   [param('ns3::AccessClass', 'ac'), param('ns3::MacLowBlockAckEventListener *', 'listener')])
     ## mac-low.h: void ns3::MacLow::RegisterDcfListener(ns3::MacLowDcfListener * listener) [member function]
     cls.add_method('RegisterDcfListener', 
                    'void', 
@@ -4273,10 +4908,18 @@
     cls.add_method('SetAddress', 
                    'void', 
                    [param('ns3::Mac48Address', 'ad')])
+    ## mac-low.h: void ns3::MacLow::SetBasicBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetBasicBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')])
     ## mac-low.h: void ns3::MacLow::SetBssid(ns3::Mac48Address ad) [member function]
     cls.add_method('SetBssid', 
                    'void', 
                    [param('ns3::Mac48Address', 'ad')])
+    ## mac-low.h: void ns3::MacLow::SetCompressedBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetCompressedBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')])
     ## mac-low.h: void ns3::MacLow::SetCtsTimeout(ns3::Time ctsTimeout) [member function]
     cls.add_method('SetCtsTimeout', 
                    'void', 
@@ -4376,21 +5019,6 @@
                    is_static=True)
     return
 
-def register_Ns3NakagamiPropagationLossModel_methods(root_module, cls):
-    ## propagation-loss-model.h: static ns3::TypeId ns3::NakagamiPropagationLossModel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 
-                   'ns3::TypeId', 
-                   [], 
-                   is_static=True)
-    ## propagation-loss-model.h: ns3::NakagamiPropagationLossModel::NakagamiPropagationLossModel() [constructor]
-    cls.add_constructor([])
-    ## propagation-loss-model.h: double ns3::NakagamiPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
-    cls.add_method('DoCalcRxPower', 
-                   'double', 
-                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
-                   is_const=True, visibility='private', is_virtual=True)
-    return
-
 def register_Ns3NqapWifiMac_methods(root_module, cls):
     ## nqap-wifi-mac.h: static ns3::TypeId ns3::NqapWifiMac::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
@@ -4865,6 +5493,26 @@
                    'ns3::Mac48Address', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetBasicBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetBasicBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::SetCompressedBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetCompressedBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
+    ## qadhoc-wifi-mac.h: ns3::Time ns3::QadhocWifiMac::GetBasicBlockAckTimeout() const [member function]
+    cls.add_method('GetBasicBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qadhoc-wifi-mac.h: ns3::Time ns3::QadhocWifiMac::GetCompressedBlockAckTimeout() const [member function]
+    cls.add_method('GetCompressedBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
     ## qadhoc-wifi-mac.h: void ns3::QadhocWifiMac::DoDispose() [member function]
     cls.add_method('DoDispose', 
                    'void', 
@@ -5010,6 +5658,26 @@
                    'ns3::Mac48Address', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetBasicBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetBasicBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: void ns3::QapWifiMac::SetCompressedBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetCompressedBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
+    ## qap-wifi-mac.h: ns3::Time ns3::QapWifiMac::GetBasicBlockAckTimeout() const [member function]
+    cls.add_method('GetBasicBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qap-wifi-mac.h: ns3::Time ns3::QapWifiMac::GetCompressedBlockAckTimeout() const [member function]
+    cls.add_method('GetCompressedBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
     ## qap-wifi-mac.h: void ns3::QapWifiMac::SetBeaconInterval(ns3::Time interval) [member function]
     cls.add_method('SetBeaconInterval', 
                    'void', 
@@ -5173,6 +5841,26 @@
                    'ns3::Mac48Address', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetBasicBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetBasicBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetCompressedBlockAckTimeout(ns3::Time blockAckTimeout) [member function]
+    cls.add_method('SetCompressedBlockAckTimeout', 
+                   'void', 
+                   [param('ns3::Time', 'blockAckTimeout')], 
+                   is_virtual=True)
+    ## qsta-wifi-mac.h: ns3::Time ns3::QstaWifiMac::GetBasicBlockAckTimeout() const [member function]
+    cls.add_method('GetBasicBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## qsta-wifi-mac.h: ns3::Time ns3::QstaWifiMac::GetCompressedBlockAckTimeout() const [member function]
+    cls.add_method('GetCompressedBlockAckTimeout', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True, is_virtual=True)
     ## qsta-wifi-mac.h: void ns3::QstaWifiMac::SetMaxMissedBeacons(uint32_t missed) [member function]
     cls.add_method('SetMaxMissedBeacons', 
                    'void', 
@@ -5657,6 +6345,10 @@
     module.add_function('QosUtilsGetTidForPacket', 
                         'uint8_t', 
                         [param('ns3::Ptr< ns3::Packet const >', 'packet')])
+    ## qos-utils.h: extern uint32_t ns3::QosUtilsMapSeqControlToUniqueInteger(uint16_t seqControl, uint16_t endSequence) [free function]
+    module.add_function('QosUtilsMapSeqControlToUniqueInteger', 
+                        'uint32_t', 
+                        [param('uint16_t', 'seqControl'), param('uint16_t', 'endSequence')])
     ## qos-utils.h: extern ns3::AccessClass ns3::QosUtilsMapTidToAc(uint8_t tid) [free function]
     module.add_function('QosUtilsMapTidToAc', 
                         'ns3::AccessClass', 
--- a/bindings/python/ns3modulegen.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/ns3modulegen.py	Thu Feb 25 14:17:21 2010 +0100
@@ -95,6 +95,7 @@
     ns3modulegen_core_customizations.CommandLine_customizations(root_module)
     ns3modulegen_core_customizations.TypeId_customizations(root_module)
     ns3modulegen_core_customizations.add_std_ofstream(root_module)
+    ns3modulegen_core_customizations.add_ipv4_address_tp_hash(root_module)
 
 
     for local_module in LOCAL_MODULES:
@@ -137,7 +138,8 @@
             pass
 
     if 'Threading' not in enabled_features:
-        for clsname in ['SystemThread', 'SystemMutex', 'SystemCondition', 'CriticalSection', 'SimpleRefCount< ns3::SystemThread, ns3::empty >']:
+        for clsname in ['SystemThread', 'SystemMutex', 'SystemCondition', 'CriticalSection',
+                        'SimpleRefCount< ns3::SystemThread, ns3::empty, ns3::DefaultDeleter<ns3::SystemThread> >']:
             root_module.classes.remove(root_module['ns3::%s' % clsname])
 
     if 'EmuNetDevice' not in enabled_features:
--- a/bindings/python/ns3modulegen_core_customizations.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/ns3modulegen_core_customizations.py	Thu Feb 25 14:17:21 2010 +0100
@@ -572,3 +572,14 @@
                               Parameter.new("::std::ofstream::openmode", 'mode', default_value="std::ios_base::out")])
     ofstream.add_method('close', None, [])
 
+def add_ipv4_address_tp_hash(module):
+    module.body.writeln('''
+long
+_ns3_Ipv4Address_tp_hash (PyObject *obj)
+{
+   PyNs3Ipv4Address *addr = reinterpret_cast<PyNs3Ipv4Address *> (obj);
+   return static_cast<long> (ns3::Ipv4AddressHash () (*addr->obj));
+}
+''')
+    module.header.writeln('long _ns3_Ipv4Address_tp_hash (PyObject *obj);')
+    module['Ipv4Address'].pytype.slots['tp_hash'] = "_ns3_Ipv4Address_tp_hash"
--- a/bindings/python/ns3modulescan.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/ns3modulescan.py	Thu Feb 25 14:17:21 2010 +0100
@@ -87,6 +87,13 @@
     'extern void ns3::PythonCompleteConstruct(ns3::Ptr<ns3::Object> object, ns3::TypeId typeId, ns3::AttributeList const & attributes) [free function]': {
         'ignore': None # used transparently by, should not be wrapped
         },
+    'ns3::Ipv4RoutingTableEntry * ns3::GlobalRouter::GetInjectedRoute(uint32_t i) [member function]': {
+        'params': {'return': { 'caller_owns_return': 'false',}},
+        },
+    'ns3::Ipv4RoutingTableEntry * ns3::Ipv4GlobalRouting::GetRoute(uint32_t i) [member function]': {
+        'params': {'return': { 'caller_owns_return': 'false',}},
+        },
+
     }
 
 def get_ns3_relative_path(path):
@@ -150,8 +157,8 @@
     ## classes
     if isinstance(pygccxml_definition, class_t):
         # no need for helper classes to allow subclassing in Python, I think...
-        if pygccxml_definition.name.endswith('Helper'):
-            global_annotations['allow_subclassing'] = 'false'
+        #if pygccxml_definition.name.endswith('Helper'):
+        #    global_annotations['allow_subclassing'] = 'false'
 
         if pygccxml_definition.decl_string.startswith('::ns3::SimpleRefCount<'):
             global_annotations['incref_method'] = 'Ref'
--- a/bindings/python/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/bindings/python/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -15,7 +15,7 @@
 import Utils
 
 ## https://launchpad.net/pybindgen/
-REQUIRED_PYBINDGEN_VERSION = (0, 12, 0, 710)
+REQUIRED_PYBINDGEN_VERSION = (0, 13, 0, 745)
 REQUIRED_PYGCCXML_VERSION = (0, 9, 5)
 
 
@@ -346,7 +346,7 @@
                         all_headers_inputs.append(node)
         assert all_headers_inputs
         all_headers_outputs = [self.path.find_or_declare("everything.h")]
-        task = self.create_task('gen_everything_h', self.env)
+        task = self.create_task('gen_everything_h', env=self.env)
         task.set_inputs(all_headers_inputs)
         task.set_outputs(all_headers_outputs)
 
--- a/doc/doxygen.conf	Thu Feb 25 13:51:59 2010 +0100
+++ b/doc/doxygen.conf	Thu Feb 25 14:17:21 2010 +0100
@@ -1,4 +1,4 @@
-# Doxyfile 1.5.4
+# Doxyfile 1.6.1
 
 # This file describes the settings to be used by the documentation system
 # doxygen (www.doxygen.org) for a project
@@ -14,198 +14,215 @@
 # Project related configuration options
 #---------------------------------------------------------------------------
 
-# This tag specifies the encoding used for all characters in the config file that 
-# follow. The default is UTF-8 which is also the encoding used for all text before 
-# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into 
-# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of 
-# possible encodings.
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
 
 DOXYFILE_ENCODING      = UTF-8
 
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
 # by quotes) that should identify the project.
 
 PROJECT_NAME           = "NS-3 "
 
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
-# This could be handy for archiving the generated documentation or 
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
 # if some version control system is used.
 
-PROJECT_NUMBER         = 
+PROJECT_NUMBER         =
 
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
-# base path where the generated documentation will be put. 
-# If a relative path is entered, it will be relative to the location 
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
 # where doxygen was started. If left blank the current directory will be used.
 
 OUTPUT_DIRECTORY       = doc
 
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
-# 4096 sub-directories (in 2 levels) under the output directory of each output 
-# format and will distribute the generated files over these directories. 
-# Enabling this option can be useful when feeding doxygen a huge amount of 
-# source files, where putting all generated files in the same directory would 
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
 # otherwise cause performance problems for the file system.
 
 CREATE_SUBDIRS         = NO
 
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
-# documentation generated by doxygen is written. Doxygen will use this 
-# information to generate all constant output in the proper language. 
-# The default language is English, other supported languages are: 
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
-# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, 
-# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, 
-# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, 
-# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
 
 OUTPUT_LANGUAGE        = English
 
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
-# include brief member descriptions after the members that are listed in 
-# the file and class documentation (similar to JavaDoc). 
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
 # Set to NO to disable this.
 
 BRIEF_MEMBER_DESC      = YES
 
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
-# the brief description of a member or function before the detailed description. 
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
 # brief descriptions will be completely suppressed.
 
 REPEAT_BRIEF           = YES
 
-# This tag implements a quasi-intelligent brief description abbreviator 
-# that is used to form the text in various listings. Each string 
-# in this list, if found as the leading text of the brief description, will be 
-# stripped from the text and the result after processing the whole list, is 
-# used as the annotated text. Otherwise, the brief description is used as-is. 
-# If left blank, the following values are used ("$name" is automatically 
-# replaced with the name of the entity): "The $name class" "The $name widget" 
-# "The $name file" "is" "provides" "specifies" "contains" 
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
 # "represents" "a" "an" "the"
 
-ABBREVIATE_BRIEF       = 
+ABBREVIATE_BRIEF       =
 
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
-# Doxygen will generate a detailed section even if there is only a brief 
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
 # description.
 
 ALWAYS_DETAILED_SEC    = NO
 
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
-# inherited members of a class in the documentation of that class as if those 
-# members were ordinary class members. Constructors, destructors and assignment 
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
 # operators of the base classes will not be shown.
 
 INLINE_INHERITED_MEMB  = NO
 
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
-# path before files name in the file list and in the header files. If set 
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
 # to NO the shortest path that makes the file name unique will be used.
 
 FULL_PATH_NAMES        = YES
 
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
-# can be used to strip a user-defined part of the path. Stripping is 
-# only done if one of the specified strings matches the left-hand part of 
-# the path. The tag can be used to show relative paths in the file list. 
-# If left blank the directory from which doxygen is run is used as the 
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
 # path to strip.
 
-STRIP_FROM_PATH        = 
+STRIP_FROM_PATH        =
 
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
-# the path mentioned in the documentation of a class, which tells 
-# the reader which header file to include in order to use a class. 
-# If left blank only the name of the header file containing the class 
-# definition is used. Otherwise one should specify the include paths that 
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
 # are normally passed to the compiler using the -I flag.
 
-STRIP_FROM_INC_PATH    = 
+STRIP_FROM_INC_PATH    =
 
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
-# (but less readable) file names. This can be useful is your file systems 
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
 # doesn't support long names like on DOS, Mac, or CD-ROM.
 
 SHORT_NAMES            = NO
 
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
-# will interpret the first line (until the first dot) of a JavaDoc-style 
-# comment as the brief description. If set to NO, the JavaDoc 
-# comments will behave just like regular Qt-style comments 
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
 # (thus requiring an explicit @brief command for a brief description.)
 
 JAVADOC_AUTOBRIEF      = NO
 
-# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
-# interpret the first line (until the first dot) of a Qt-style 
-# comment as the brief description. If set to NO, the comments 
-# will behave just like regular Qt-style comments (thus requiring 
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
 # an explicit \brief command for a brief description.)
 
 QT_AUTOBRIEF           = NO
 
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
-# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
-# comments) as a brief description. This used to be the default behaviour. 
-# The new default is to treat a multi-line C++ comment block as a detailed 
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
 # description. Set this tag to YES if you prefer the old behaviour instead.
 
 MULTILINE_CPP_IS_BRIEF = NO
 
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member 
-# documentation.
-
-DETAILS_AT_TOP         = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
-# member inherits the documentation from any documented member that it 
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
 # re-implements.
 
 INHERIT_DOCS           = YES
 
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
-# a new page for each member. If set to NO, the documentation of a member will 
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
 # be part of the file/class/namespace that contains it.
 
 SEPARATE_MEMBER_PAGES  = NO
 
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
 # Doxygen uses this value to replace tabs by spaces in code fragments.
 
 TAB_SIZE               = 4
 
-# This tag can be used to specify a number of aliases that acts 
-# as commands in the documentation. An alias has the form "name=value". 
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
-# put the command \sideeffect (or @sideeffect) in the documentation, which 
-# will result in a user-defined paragraph with heading "Side Effects:". 
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
 # You can put \n's in the value part of an alias to insert newlines.
 
-ALIASES                = 
+ALIASES                =
 
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
-# sources only. Doxygen will then generate output that is more tailored for C. 
-# For instance, some of the names that are used will be different. The list 
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
 # of all members will be omitted, etc.
 
 OPTIMIZE_OUTPUT_FOR_C  = NO
 
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
-# sources only. Doxygen will then generate output that is more tailored for Java. 
-# For instance, namespaces will be presented as packages, qualified scopes 
-# will look different, etc.
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
 
 OPTIMIZE_OUTPUT_JAVA   = NO
 
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
-# include (a tag file for) the STL sources as input, then you should 
-# set this tag to YES in order to let doxygen match functions declarations and 
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
-# func(std::string) {}). This also make the inheritance and collaboration 
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses.
+# With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this tag.
+# The format is ext=language, where ext is a file extension, and language is one of
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran),
+# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING      =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
 # diagrams that involve STL classes more complete and accurate.
 
 BUILTIN_STL_SUPPORT    = NO
@@ -215,315 +232,375 @@
 
 CPP_CLI_SUPPORT        = NO
 
-# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
-# Doxygen will parse them like normal C++ but will assume all classes use public 
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
 # instead of private inheritance when no explicit protection keyword is present.
 
 SIP_SUPPORT            = NO
 
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
-# tag is set to YES, then doxygen will reuse the documentation of the first 
-# member in the group (if any) for the other members of the group. By default 
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
 # all members of a group must be documented explicitly.
 
 DISTRIBUTE_GROUP_DOC   = NO
 
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
-# the same type (for instance a group of public functions) to be put as a 
-# subgroup of that type (e.g. under the Public Functions section). Set it to 
-# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
 # the \nosubgrouping command.
 
 SUBGROUPING            = YES
 
-# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct (or union) is 
-# documented as struct with the name of the typedef. So 
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
-# with name TypeT. When disabled the typedef will appear as a member of a file, 
-# namespace, or class. And the struct will be named TypeS. This can typically 
-# be useful for C code where the coding convention is that all structs are 
-# typedef'ed and only the typedef is referenced never the struct's name.
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
 
 TYPEDEF_HIDES_STRUCT   = NO
 
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penality.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will rougly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE      = 0
+
 #---------------------------------------------------------------------------
 # Build related configuration options
 #---------------------------------------------------------------------------
 
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
-# documentation are documented, even if no documentation was available. 
-# Private class members and static file members will be hidden unless 
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
 # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
 
 EXTRACT_ALL            = NO
 
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
 # will be included in the documentation.
 
 EXTRACT_PRIVATE        = NO
 
-# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
 # will be included in the documentation.
 
 EXTRACT_STATIC         = NO
 
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
-# defined locally in source files will be included in the documentation. 
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
 # If set to NO only classes defined in header files are included.
 
 EXTRACT_LOCAL_CLASSES  = NO
 
-# This flag is only useful for Objective-C code. When set to YES local 
-# methods, which are defined in the implementation section but not in 
-# the interface are included in the documentation. 
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
 # If set to NO (the default) only methods in the interface are included.
 
 EXTRACT_LOCAL_METHODS  = NO
 
-# If this flag is set to YES, the members of anonymous namespaces will be extracted 
-# and appear in the documentation as a namespace called 'anonymous_namespace{file}', 
-# where file will be replaced with the base name of the file that contains the anonymous 
-# namespace. By default anonymous namespace are hidden.
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
 
 EXTRACT_ANON_NSPACES   = NO
 
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
-# undocumented members of documented classes, files or namespaces. 
-# If set to NO (the default) these members will be included in the 
-# various overviews, but no documentation section is generated. 
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
 # This option has no effect if EXTRACT_ALL is enabled.
 
-HIDE_UNDOC_MEMBERS     = NO 
+HIDE_UNDOC_MEMBERS     = NO
 
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
-# undocumented classes that are normally visible in the class hierarchy. 
-# If set to NO (the default) these classes will be included in the various 
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
 # overviews. This option has no effect if EXTRACT_ALL is enabled.
 
-HIDE_UNDOC_CLASSES     = NO 
+HIDE_UNDOC_CLASSES     = NO
 
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
-# friend (class|struct|union) declarations. 
-# If set to NO (the default) these declarations will be included in the 
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
 # documentation.
 
 HIDE_FRIEND_COMPOUNDS  = NO
 
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
-# documentation blocks found inside the body of a function. 
-# If set to NO (the default) these blocks will be appended to the 
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
 # function's detailed documentation block.
 
 HIDE_IN_BODY_DOCS      = NO
 
-# The INTERNAL_DOCS tag determines if documentation 
-# that is typed after a \internal command is included. If the tag is set 
-# to NO (the default) then the documentation will be excluded. 
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
 # Set it to YES to include the internal documentation.
 
 INTERNAL_DOCS          = NO
 
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
-# file names in lower-case letters. If set to YES upper-case letters are also 
-# allowed. This is useful if you have classes or files whose names only differ 
-# in case and if your file system supports case sensitive file names. Windows 
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
 # and Mac users are advised to set this option to NO.
 
 CASE_SENSE_NAMES       = NO
 
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
-# will show members with their full class and namespace scopes in the 
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
 # documentation. If set to YES the scope will be hidden.
 
 HIDE_SCOPE_NAMES       = NO
 
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
-# will put a list of the files that are included by a file in the documentation 
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
 # of that file.
 
 SHOW_INCLUDE_FILES     = YES
 
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
 # is inserted in the documentation for inline members.
 
 INLINE_INFO            = YES
 
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
-# will sort the (detailed) documentation of file and class members 
-# alphabetically by member name. If set to NO the members will appear in 
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
 # declaration order.
 
 SORT_MEMBER_DOCS       = YES
 
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
-# brief documentation of file, namespace and class members alphabetically 
-# by member name. If set to NO (the default) the members will appear in 
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
 # declaration order.
 
 SORT_BRIEF_DOCS        = NO
 
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
-# sorted by fully-qualified names, including namespaces. If set to 
-# NO (the default), the class list will be sorted only by class name, 
-# not including the namespace part. 
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
 # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the 
+# Note: This option applies only to the class list, not to the
 # alphabetical list.
 
 SORT_BY_SCOPE_NAME     = NO
 
-# The GENERATE_TODOLIST tag can be used to enable (YES) or 
-# disable (NO) the todo list. This list is created by putting \todo 
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
 # commands in the documentation.
 
 GENERATE_TODOLIST      = YES
 
-# The GENERATE_TESTLIST tag can be used to enable (YES) or 
-# disable (NO) the test list. This list is created by putting \test 
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
 # commands in the documentation.
 
 GENERATE_TESTLIST      = YES
 
-# The GENERATE_BUGLIST tag can be used to enable (YES) or 
-# disable (NO) the bug list. This list is created by putting \bug 
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
 # commands in the documentation.
 
 GENERATE_BUGLIST       = YES
 
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
-# disable (NO) the deprecated list. This list is created by putting 
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
 # \deprecated commands in the documentation.
 
 GENERATE_DEPRECATEDLIST= YES
 
-# The ENABLED_SECTIONS tag can be used to enable conditional 
+# The ENABLED_SECTIONS tag can be used to enable conditional
 # documentation sections, marked by \if sectionname ... \endif.
 
-ENABLED_SECTIONS       = 
+ENABLED_SECTIONS       =
 
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
-# the initial value of a variable or define consists of for it to appear in 
-# the documentation. If the initializer consists of more lines than specified 
-# here it will be hidden. Use a value of 0 to hide initializers completely. 
-# The appearance of the initializer of individual variables and defines in the 
-# documentation can be controlled using \showinitializer or \hideinitializer 
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
 # command in the documentation regardless of this setting.
 
 MAX_INITIALIZER_LINES  = 30
 
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
-# at the bottom of the documentation of classes and structs. If set to YES the 
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
 # list will mention the files that were used to generate the documentation.
 
 SHOW_USED_FILES        = YES
 
-# If the sources in your project are distributed over multiple directories 
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
 # in the documentation. The default is NO.
 
 SHOW_DIRECTORIES       = NO
 
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
-# doxygen should invoke to get the current version for each file (typically from the 
-# version control system). Doxygen will invoke the program by executing (via 
-# popen()) the command <command> <input-file>, where <command> is the value of 
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
-# provided by doxygen. Whatever the program writes to standard output 
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
 # is used as the file version. See the manual for examples.
 
-FILE_VERSION_FILTER    = 
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
+# doxygen. The layout file controls the global structure of the generated output files
+# in an output format independent way. The create the layout file that represents
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name
+# of the layout file.
+
+LAYOUT_FILE            =
 
 #---------------------------------------------------------------------------
 # configuration options related to warning and progress messages
 #---------------------------------------------------------------------------
 
-# The QUIET tag can be used to turn on/off the messages that are generated 
+# The QUIET tag can be used to turn on/off the messages that are generated
 # by doxygen. Possible values are YES and NO. If left blank NO is used.
 
 QUIET                  = YES
 
-# The WARNINGS tag can be used to turn on/off the warning messages that are 
-# generated by doxygen. Possible values are YES and NO. If left blank 
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
 # NO is used.
 
 WARNINGS               = YES
 
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
 # automatically be disabled.
 
 WARN_IF_UNDOCUMENTED   = YES
 
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
-# potential errors in the documentation, such as not documenting some 
-# parameters in a documented function, or documenting parameters that 
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
 # don't exist or using markup commands wrongly.
 
 WARN_IF_DOC_ERROR      = YES
 
-# This WARN_NO_PARAMDOC option can be abled to get warnings for 
-# functions that are documented, but have no documentation for their parameters 
-# or return value. If set to NO (the default) doxygen will only warn about 
-# wrong or incomplete parameter documentation, but not about the absence of 
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
 # documentation.
 
-WARN_NO_PARAMDOC       = YES 
+WARN_NO_PARAMDOC       = YES
 
-# The WARN_FORMAT tag determines the format of the warning messages that 
-# doxygen can produce. The string should contain the $file, $line, and $text 
-# tags, which will be replaced by the file and line number from which the 
-# warning originated and the warning text. Optionally the format may contain 
-# $version, which will be replaced by the version of the file (if it could 
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
 # be obtained via FILE_VERSION_FILTER)
 
 WARN_FORMAT            = "$file:$line: $text "
 
-# The WARN_LOGFILE tag can be used to specify a file to which warning 
-# and error messages should be written. If left blank the output is written 
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
 # to stderr.
 
-WARN_LOGFILE           = 
+WARN_LOGFILE           =
 
 #---------------------------------------------------------------------------
 # configuration options related to the input files
 #---------------------------------------------------------------------------
 
-# The INPUT tag can be used to specify the files and/or directories that contain 
-# documented source files. You may enter file names like "myfile.cpp" or 
-# directories like "/usr/src/myproject". Separate the files or directories 
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
 # with spaces.
 
 INPUT                  = doc/modules \
                          doc/main.h \
                          doc/introspected-doxygen.h \
+                         utils \
                          src
 
-# This tag can be used to specify the character encoding of the source files that 
-# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default 
-# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. 
-# See http://www.gnu.org/software/libiconv for the list of possible encodings.
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
 
 INPUT_ENCODING         = UTF-8
 
-# If the value of the INPUT tag contains directories, you can use the 
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank the following patterns are tested: 
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
 # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
 
 FILE_PATTERNS          = *.h \
                          *.tcc \
-			 node-list.cc
+                         node-list.cc
 
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
-# should be searched for input files as well. Possible values are YES and NO. 
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
 # If left blank NO is used.
 
 RECURSIVE              = YES
 
-# The EXCLUDE tag can be used to specify files and/or directories that should 
-# excluded from the INPUT source files. This way you can easily exclude a 
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
 # subdirectory from a directory tree whose root is specified with the INPUT tag.
 
 EXCLUDE                = src/routing/olsr/olsr-state.h \
@@ -532,74 +609,78 @@
                          src/simulator/high-precision-128.h \
                          src/simulator/high-precision-double.h
 
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
-# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
 # from the input.
 
 EXCLUDE_SYMLINKS       = NO
 
-# If the value of the INPUT tag contains directories, you can use the 
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
-# certain files from those directories. Note that the wildcards are matched 
-# against the file with absolute path, so to exclude all test directories 
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
 # for example use the pattern */test/*
 
 EXCLUDE_PATTERNS       = */test/*
 
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
-# (namespaces, classes, functions, etc.) that should be excluded from the output. 
-# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, 
-# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
 
-EXCLUDE_SYMBOLS        = 
+EXCLUDE_SYMBOLS        =
 
-# The EXAMPLE_PATH tag can be used to specify one or more files or 
-# directories that contain example code fragments that are included (see 
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
 # the \include command).
 
 EXAMPLE_PATH           = samples
 
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
 # blank all files are included.
 
-EXAMPLE_PATTERNS       = 
+EXAMPLE_PATTERNS       =
 
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
-# searched for input files to be used with the \include or \dontinclude 
-# commands irrespective of the value of the RECURSIVE tag. 
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
 # Possible values are YES and NO. If left blank NO is used.
 
 EXAMPLE_RECURSIVE      = NO
 
-# The IMAGE_PATH tag can be used to specify one or more files or 
-# directories that contain image that are included in the documentation (see 
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
 # the \image command).
 
 IMAGE_PATH             = doc
 
-# The INPUT_FILTER tag can be used to specify a program that doxygen should 
-# invoke to filter for each input file. Doxygen will invoke the filter program 
-# by executing (via popen()) the command <filter> <input-file>, where <filter> 
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
-# input file. Doxygen will then use the output that the filter program writes 
-# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
 # ignored.
 
-INPUT_FILTER           = 
+INPUT_FILTER           =
 
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
-# basis.  Doxygen will compare the file name with each pattern and apply the 
-# filter if there is a match.  The filters are a list of the form: 
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
 # is applied to all files.
 
-FILTER_PATTERNS        = 
+FILTER_PATTERNS        =
 
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
-# INPUT_FILTER) will be used to filter the input files when producing source 
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
 # files to browse (i.e. when SOURCE_BROWSER is set to YES).
 
 FILTER_SOURCE_FILES    = NO
@@ -608,34 +689,32 @@
 # configuration options related to source browsing
 #---------------------------------------------------------------------------
 
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
-# be generated. Documented entities will be cross-referenced with these sources. 
-# Note: To get rid of all source code in the generated output, make sure also 
-# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH 
-# then you must also enable this option. If you don't then doxygen will produce 
-# a warning and turn it on anyway
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
 
 SOURCE_BROWSER         = NO
 
-# Setting the INLINE_SOURCES tag to YES will include the body 
+# Setting the INLINE_SOURCES tag to YES will include the body
 # of functions and classes directly in the documentation.
 
 INLINE_SOURCES         = NO
 
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
-# doxygen to hide any special comment blocks from generated source code 
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
 # fragments. Normal C and C++ comments will always remain visible.
 
 STRIP_CODE_COMMENTS    = YES
 
-# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
-# then for each documented function all documented 
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
 # functions referencing it will be listed.
 
 REFERENCED_BY_RELATION = YES
 
-# If the REFERENCES_RELATION tag is set to YES (the default) 
-# then for each documented function all documented entities 
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
 # called/used by that function will be listed.
 
 REFERENCES_RELATION    = YES
@@ -643,20 +722,21 @@
 # If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
 # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
 # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code.  Otherwise they will link to the documentstion.
+# link to the source code.
+# Otherwise they will link to the documentation.
 
 REFERENCES_LINK_SOURCE = YES
 
-# If the USE_HTAGS tag is set to YES then the references to source code 
-# will point to the HTML generated by the htags(1) tool instead of doxygen 
-# built-in source browser. The htags tool is part of GNU's global source 
-# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
 # will need version 4.8.6 or higher.
 
 USE_HTAGS              = NO
 
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
-# will generate a verbatim copy of the header file for each class for 
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
 # which an include is specified. Set to NO to disable this.
 
 VERBATIM_HEADERS       = NO
@@ -665,287 +745,393 @@
 # configuration options related to the alphabetical class index
 #---------------------------------------------------------------------------
 
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
-# of all compounds will be generated. Enable this if the project 
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
 # contains a lot of classes, structs, unions or interfaces.
 
 ALPHABETICAL_INDEX     = NO
 
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
 # in which this list will be split (can be a number in the range [1..20])
 
 COLS_IN_ALPHA_INDEX    = 5
 
-# In case all classes in a project start with a common prefix, all 
-# classes will be put under the same header in the alphabetical index. 
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
 # should be ignored while generating the index headers.
 
-IGNORE_PREFIX          = 
+IGNORE_PREFIX          =
 
 #---------------------------------------------------------------------------
 # configuration options related to the HTML output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
 # generate HTML output.
 
 GENERATE_HTML          = YES
 
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
 # put in front of it. If left blank `html' will be used as the default path.
 
 HTML_OUTPUT            = html
 
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
 # doxygen will generate files with .html extension.
 
 HTML_FILE_EXTENSION    = .html
 
-# The HTML_HEADER tag can be used to specify a personal HTML header for 
-# each generated HTML page. If it is left blank doxygen will generate a 
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
 # standard header.
 
-HTML_HEADER            = 
+HTML_HEADER            =
 
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
-# each generated HTML page. If it is left blank doxygen will generate a 
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
 # standard footer.
 
-HTML_FOOTER            = 
+HTML_FOOTER            =
 
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
-# style sheet that is used by each HTML page. It can be used to 
-# fine-tune the look of the HTML output. If the tag is left blank doxygen 
-# will generate a default style sheet. Note that doxygen will try to copy 
-# the style sheet file to the HTML output directory, so don't put your own 
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
 # stylesheet in the HTML output directory as well, or it will be erased!
 
-HTML_STYLESHEET        = 
+HTML_STYLESHEET        =
 
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
-# files or namespaces will be aligned in HTML using tables. If set to 
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
 # NO a bullet list will be used.
 
 HTML_ALIGN_MEMBERS     = YES
 
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
-# will be generated that can be used as input for tools like the 
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
 # of the generated HTML documentation.
 
 GENERATE_HTMLHELP      = NO
 
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
-# documentation will contain sections that can be hidden and shown after the 
-# page has loaded. For this to work a browser that supports 
-# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
-# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
-
-HTML_DYNAMIC_SECTIONS  = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
-# be used to specify the file name of the resulting .chm file. You 
-# can add a path in front of the file if the result should not be 
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
 # written to the html output directory.
 
-CHM_FILE               = 
+CHM_FILE               =
 
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
-# be used to specify the location (absolute path including file name) of 
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
 # the HTML help compiler on the generated index.hhp.
 
-HHC_LOCATION           = 
+HHC_LOCATION           =
 
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
-# controls if a separate .chi index file is generated (YES) or that 
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
 # it should be included in the master .chm file (NO).
 
 GENERATE_CHI           = NO
 
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
-# controls whether a binary table of contents is generated (YES) or a 
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING     =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
 # normal table of contents (NO) in the .chm file.
 
 BINARY_TOC             = NO
 
-# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
 # to the contents of the HTML help documentation and to the tree view.
 
 TOC_EXPAND             = NO
 
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
-# top of each HTML page. The value NO (the default) enables the index and 
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
+# are set, an additional index file will be generated that can be used as input for
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
+# HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          =
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.
+# For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION           =
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
 # the value YES disables it.
 
 DISABLE_INDEX          = NO
 
-# This tag can be used to set the number of enum values (range [1..20]) 
+# This tag can be used to set the number of enum values (range [1..20])
 # that doxygen will group on one line in the generated HTML documentation.
 
 ENUM_VALUES_PER_LINE   = 4
 
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that 
-# is generated for HTML Help). For this to work a browser that supports 
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
-# probably better off using the HTML help feature.
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
 
 GENERATE_TREEVIEW      = YES
 
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
-# used to set the initial width (in pixels) of the frame in which the tree 
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES       = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
 # is shown.
 
 TREEVIEW_WIDTH         = 250
 
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP)
+# there is already a search function so this one should typically
+# be disabled.
+
+SEARCHENGINE           = NO
+
 #---------------------------------------------------------------------------
 # configuration options related to the LaTeX output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
 # generate Latex output.
 
 GENERATE_LATEX         = YES
 
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
 # put in front of it. If left blank `latex' will be used as the default path.
 
 LATEX_OUTPUT           = latex
 
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
 # invoked. If left blank `latex' will be used as the default command name.
 
 LATEX_CMD_NAME         = latex
 
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
-# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
 # default command name.
 
 MAKEINDEX_CMD_NAME     = makeindex
 
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
-# LaTeX documents. This may be useful for small projects and may help to 
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
 # save some trees in general.
 
 COMPACT_LATEX          = YES
 
-# The PAPER_TYPE tag can be used to set the paper type that is used 
-# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
 # executive. If left blank a4wide will be used.
 
 PAPER_TYPE             = a4wide
 
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
 # packages that should be included in the LaTeX output.
 
 EXTRA_PACKAGES         = amsmath
 
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
-# the generated latex document. The header should contain everything until 
-# the first chapter. If it is left blank doxygen will generate a 
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
 # standard header. Notice: only use this tag if you know what you are doing!
 
-LATEX_HEADER           = 
+LATEX_HEADER           =
 
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
-# contain links (just like the HTML output) instead of page references 
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
 # This makes the output suitable for online browsing using a pdf viewer.
 
 PDF_HYPERLINKS         = YES
 
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
-# plain latex in the generated Makefile. Set this option to YES to get a 
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
 # higher quality PDF documentation.
 
 USE_PDFLATEX           = YES
 
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
-# command to the generated LaTeX files. This will instruct LaTeX to keep 
-# running if errors occur, instead of asking the user for help. 
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
 # This option is also used when generating formulas in HTML.
 
 LATEX_BATCHMODE        = NO
 
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
-# include the index chapters (such as File Index, Compound Index, etc.) 
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
 # in the output.
 
 LATEX_HIDE_INDICES     = YES
 
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = NO
+
 #---------------------------------------------------------------------------
 # configuration options related to the RTF output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
-# The RTF output is optimized for Word 97 and may not look very pretty with 
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
 # other RTF readers or editors.
 
 GENERATE_RTF           = NO
 
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
 # put in front of it. If left blank `rtf' will be used as the default path.
 
 RTF_OUTPUT             = rtf
 
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
-# RTF documents. This may be useful for small projects and may help to 
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
 # save some trees in general.
 
 COMPACT_RTF            = NO
 
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
-# will contain hyperlink fields. The RTF file will 
-# contain links (just like the HTML output) instead of page references. 
-# This makes the output suitable for online browsing using WORD or other 
-# programs which support those fields. 
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
 # Note: wordpad (write) and others do not support links.
 
 RTF_HYPERLINKS         = NO
 
-# Load stylesheet definitions from file. Syntax is similar to doxygen's 
-# config file, i.e. a series of assignments. You only have to provide 
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
 # replacements, missing definitions are set to their default value.
 
-RTF_STYLESHEET_FILE    = 
+RTF_STYLESHEET_FILE    =
 
-# Set optional variables used in the generation of an rtf document. 
+# Set optional variables used in the generation of an rtf document.
 # Syntax is similar to doxygen's config file.
 
-RTF_EXTENSIONS_FILE    = 
+RTF_EXTENSIONS_FILE    =
 
 #---------------------------------------------------------------------------
 # configuration options related to the man page output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
 # generate man pages
 
 GENERATE_MAN           = NO
 
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
 # put in front of it. If left blank `man' will be used as the default path.
 
 MAN_OUTPUT             = man
 
-# The MAN_EXTENSION tag determines the extension that is added to 
+# The MAN_EXTENSION tag determines the extension that is added to
 # the generated man pages (default is the subroutine's section .3)
 
 MAN_EXTENSION          = .3
 
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
-# then it will generate one additional man file for each entity 
-# documented in the real man page(s). These additional files 
-# only source the real man page, but without them the man command 
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
 # would be unable to find the correct page. The default is NO.
 
 MAN_LINKS              = NO
@@ -954,33 +1140,33 @@
 # configuration options related to the XML output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_XML tag is set to YES Doxygen will 
-# generate an XML file that captures the structure of 
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
 # the code including all documentation.
 
 GENERATE_XML           = NO
 
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
 # put in front of it. If left blank `xml' will be used as the default path.
 
 XML_OUTPUT             = xml
 
-# The XML_SCHEMA tag can be used to specify an XML schema, 
-# which can be used by a validating XML parser to check the 
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
 # syntax of the XML files.
 
-XML_SCHEMA             = 
+XML_SCHEMA             =
 
-# The XML_DTD tag can be used to specify an XML DTD, 
-# which can be used by a validating XML parser to check the 
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
 # syntax of the XML files.
 
-XML_DTD                = 
+XML_DTD                =
 
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
-# dump the program listings (including syntax highlighting 
-# and cross-referencing information) to the XML output. Note that 
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
 # enabling this will significantly increase the size of the XML output.
 
 XML_PROGRAMLISTING     = YES
@@ -989,10 +1175,10 @@
 # configuration options for the AutoGen Definitions output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
-# generate an AutoGen Definitions (see autogen.sf.net) file 
-# that captures the structure of the code including all 
-# documentation. Note that this feature is still experimental 
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
 # and incomplete at the moment.
 
 GENERATE_AUTOGEN_DEF   = NO
@@ -1001,323 +1187,341 @@
 # configuration options related to the Perl module output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
-# generate a Perl module file that captures the structure of 
-# the code including all documentation. Note that this 
-# feature is still experimental and incomplete at the 
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
 # moment.
 
 GENERATE_PERLMOD       = NO
 
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
 # to generate PDF and DVI output from the Perl module output.
 
 PERLMOD_LATEX          = NO
 
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
-# nicely formatted so it can be parsed by a human reader.  This is useful 
-# if you want to understand what is going on.  On the other hand, if this 
-# tag is set to NO the size of the Perl module output will be much smaller 
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
 # and Perl will parse it just the same.
 
 PERLMOD_PRETTY         = YES
 
-# The names of the make variables in the generated doxyrules.make file 
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
-# This is useful so different doxyrules.make files included by the same 
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
 # Makefile don't overwrite each other's variables.
 
-PERLMOD_MAKEVAR_PREFIX = 
+PERLMOD_MAKEVAR_PREFIX =
 
 #---------------------------------------------------------------------------
-# Configuration options related to the preprocessor   
+# Configuration options related to the preprocessor
 #---------------------------------------------------------------------------
 
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
-# evaluate all C-preprocessor directives found in the sources and include 
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
 # files.
 
 ENABLE_PREPROCESSING   = YES
 
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
-# names in the source code. If set to NO (the default) only conditional 
-# compilation will be performed. Macro expansion can be done in a controlled 
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
 # way by setting EXPAND_ONLY_PREDEF to YES.
 
 MACRO_EXPANSION        = YES
 
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
-# then the macro expansion is limited to the macros specified with the 
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
 # PREDEFINED and EXPAND_AS_DEFINED tags.
 
 EXPAND_ONLY_PREDEF     = YES
 
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
 # in the INCLUDE_PATH (see below) will be search if a #include is found.
 
 SEARCH_INCLUDES        = YES
 
-# The INCLUDE_PATH tag can be used to specify one or more directories that 
-# contain include files that are not input files but should be processed by 
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
 # the preprocessor.
 
-INCLUDE_PATH           = 
+INCLUDE_PATH           =
 
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
-# patterns (like *.h and *.hpp) to filter out the header-files in the 
-# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
 # be used.
 
-INCLUDE_FILE_PATTERNS  = 
+INCLUDE_FILE_PATTERNS  =
 
-# The PREDEFINED tag can be used to specify one or more macro names that 
-# are defined before the preprocessor is started (similar to the -D option of 
-# gcc). The argument of the tag is a list of macros of the form: name 
-# or name=definition (no spaces). If the definition and the = are 
-# omitted =1 is assumed. To prevent a macro definition from being 
-# undefined via #undef or recursively expanded use the := operator 
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
 # instead of the = operator.
 
-PREDEFINED             = RUN_SELF_TESTS \
-                         NS3_ASSERT_ENABLE \
+PREDEFINED             = NS3_ASSERT_ENABLE \
                          NS3_LOG_ENABLE
 
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
-# this tag can be used to specify a list of macro names that should be expanded. 
-# The macro definition that is found in the sources will be used. 
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
 # Use the PREDEFINED tag if you want to use a different macro definition.
 
 EXPAND_AS_DEFINED      = ATTRIBUTE_VALUE_DEFINE \
-		       ATTRIBUTE_VALUE_DEFINE_WITH_NAME \
-		       ATTRIBUTE_HELPER_HEADER_2
+                         ATTRIBUTE_VALUE_DEFINE_WITH_NAME \
+                         ATTRIBUTE_HELPER_HEADER_2
 
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
-# doxygen's preprocessor will remove all function-like macros that are alone 
-# on a line, have an all uppercase name, and do not end with a semicolon. Such 
-# function macros are typically used for boiler-plate code, and will confuse 
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
 # the parser if not removed.
 
 SKIP_FUNCTION_MACROS   = YES
 
 #---------------------------------------------------------------------------
-# Configuration::additions related to external references   
+# Configuration::additions related to external references
 #---------------------------------------------------------------------------
 
-# The TAGFILES option can be used to specify one or more tagfiles. 
-# Optionally an initial location of the external documentation 
-# can be added for each tagfile. The format of a tag file without 
-# this location is as follows: 
-#   TAGFILES = file1 file2 ... 
-# Adding location for the tag files is done as follows: 
-#   TAGFILES = file1=loc1 "file2 = loc2" ... 
-# where "loc1" and "loc2" can be relative or absolute paths or 
-# URLs. If a location is present for each tag, the installdox tool 
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
 # does not have to be run to correct the links.
 # Note that each tag file must have a unique name
 # (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen 
+# If a tag file is not located in the directory in which doxygen
 # is run, you must also specify the path to the tagfile here.
 
-TAGFILES               = 
+TAGFILES               =
 
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
 # a tag file that is based on the input files it reads.
 
-GENERATE_TAGFILE       = 
+GENERATE_TAGFILE       =
 
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
-# in the class index. If set to NO only the inherited external classes 
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
 # will be listed.
 
 ALLEXTERNALS           = NO
 
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
-# in the modules index. If set to NO, only the current project's groups will 
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
 # be listed.
 
 EXTERNAL_GROUPS        = YES
 
-# The PERL_PATH should be the absolute path and name of the perl script 
+# The PERL_PATH should be the absolute path and name of the perl script
 # interpreter (i.e. the result of `which perl').
 
 PERL_PATH              = /usr/bin/perl
 
 #---------------------------------------------------------------------------
-# Configuration options related to the dot tool   
+# Configuration options related to the dot tool
 #---------------------------------------------------------------------------
 
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
-# or super classes. Setting the tag to NO turns the diagrams off. Note that 
-# this option is superseded by the HAVE_DOT option below. This is only a 
-# fallback. It is recommended to install and use dot, since it yields more 
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
 # powerful graphs.
 
 CLASS_DIAGRAMS         = YES
 
-# You can define message sequence charts within doxygen comments using the \msc 
-# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to 
-# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to 
-# specify the directory where the mscgen tool resides. If left empty the tool is assumed to 
-# be found in the default search path.
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
 
-MSCGEN_PATH            = 
+MSCGEN_PATH            =
 
-# If set to YES, the inheritance and collaboration graphs will hide 
-# inheritance and usage relations if the target is undocumented 
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
 # or is not a class.
 
 HIDE_UNDOC_RELATIONS   = YES
 
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
-# available from the path. This tool is part of Graphviz, a graph visualization 
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
 # have no effect if this option is set to NO (the default)
 
 HAVE_DOT               = YES
 
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect inheritance relations. Setting this tag to YES will force the 
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME           = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
 # the CLASS_DIAGRAMS tag to NO.
 
 CLASS_GRAPH            = YES
 
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect implementation dependencies (inheritance, containment, and 
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
 # class references variables) of the class with other documented classes.
 
 COLLABORATION_GRAPH    = YES
 
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
 # will generate a graph for groups, showing the direct groups dependencies
 
 GROUP_GRAPHS           = YES
 
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
-# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
 # Language.
 
 UML_LOOK               = NO
 
-# If set to YES, the inheritance and collaboration graphs will show the 
+# If set to YES, the inheritance and collaboration graphs will show the
 # relations between templates and their instances.
 
 TEMPLATE_RELATIONS     = NO
 
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
-# tags are set to YES then doxygen will generate a graph for each documented 
-# file showing the direct and indirect include dependencies of the file with 
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
 # other documented files.
 
 INCLUDE_GRAPH          = YES
 
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
-# documented header file showing the documented files that directly or 
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
 # indirectly include this file.
 
 INCLUDED_BY_GRAPH      = YES
 
-# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will 
-# generate a call dependency graph for every global function or class method. 
-# Note that enabling this option will significantly increase the time of a run. 
-# So in most cases it will be better to enable call graphs for selected 
-# functions only using the \callgraph command.
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
 
 CALL_GRAPH             = NO
 
-# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will 
-# generate a caller dependency graph for every global function or class method. 
-# Note that enabling this option will significantly increase the time of a run. 
-# So in most cases it will be better to enable caller graphs for selected 
-# functions only using the \callergraph command.
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
 
 CALLER_GRAPH           = NO
 
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
 # will graphical hierarchy of all classes instead of a textual one.
 
 GRAPHICAL_HIERARCHY    = YES
 
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
-# then doxygen will show the dependencies a directory has on other directories 
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
 # in a graphical way. The dependency relations are determined by the #include
 # relations between the files in the directories.
 
 DIRECTORY_GRAPH        = YES
 
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
 # generated by dot. Possible values are png, jpg, or gif
 # If left blank png will be used.
 
 DOT_IMAGE_FORMAT       = png
 
-# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
 # found. If left blank, it is assumed the dot tool can be found in the path.
 
-DOT_PATH               = 
+DOT_PATH               =
 
-# The DOTFILE_DIRS tag can be used to specify one or more directories that 
-# contain dot files that are included in the documentation (see the 
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
 # \dotfile command).
 
-DOTFILE_DIRS           = 
+DOTFILE_DIRS           =
 
-# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
-# nodes that will be shown in the graph. If the number of nodes in a graph 
-# becomes larger than this value, doxygen will truncate the graph, which is 
-# visualized by representing a node as a red box. Note that doxygen if the number 
-# of direct children of the root node in a graph is already larger than 
-# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note 
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
 # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
 
 DOT_GRAPH_MAX_NODES    = 50
 
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
-# graphs generated by dot. A depth value of 3 means that only nodes reachable 
-# from the root by following a path via at most 3 edges will be shown. Nodes 
-# that lay further from the root node will be omitted. Note that setting this 
-# option to 1 or 2 may greatly reduce the computation time needed for large 
-# code bases. Also note that the size of a graph can be further restricted by 
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
 # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
 
 MAX_DOT_GRAPH_DEPTH    = 0
 
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
-# background. This is disabled by default, which results in a white background. 
-# Warning: Depending on the platform used, enabling this option may lead to 
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
-# read).
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
 
 DOT_TRANSPARENT        = NO
 
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
-# files in one run (i.e. multiple -o and -T options on the command line). This 
-# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
 # support this, this feature is disabled by default.
 
 DOT_MULTI_TARGETS      = NO
 
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
-# generate a legend page explaining the meaning of the various boxes and 
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
 # arrows in the dot generated graphs.
 
 GENERATE_LEGEND        = YES
 
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
-# remove the intermediate dot files that are used to generate 
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
 # the various graphs.
 
 DOT_CLEANUP            = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine   
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be 
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE           = NO
--- a/doc/manual/animation.texi	Thu Feb 25 13:51:59 2010 +0100
+++ b/doc/manual/animation.texi	Thu Feb 25 14:17:21 2010 +0100
@@ -8,23 +8,22 @@
 @end menu
 
 Animation is an important tool for network simulation. While ns-3 does 
-not contain a graphical animation tool, it does provide an animation interface 
-for use with stand-alone animators. Currently, the animation 
-interface only supports point-to-point links; however, we hope
-to support other link types such as CSMA and wireless in the near future.
-The animation interface in ns-3 allows the generation of a custom trace 
-file to be used by an animation program.
-
-An existing stand-alone program, NetAnim, uses these custom traces to 
-graphically display the simulation. NetAnim depicts packets traveling 
-on point-to-point links as they travel from node to node.
+not contain a default graphical animation tool, it does provide an 
+animation interface for use with stand-alone animators.  One such
+animator called NetAnim, presently supporting packet flow animation
+for point-to-point links, has been developed.  Other animators and
+visualization tools are in development; they may make use of the
+existing animation interface or may develop new ones,   
 
 @node Animation interface
 @section Animation interface
 
+The animation interface uses underlying ns-3 trace sources to construct
+a timestamped ASCII file that can be read by a standalone animator.
 The animation interface in ns-3 currently only supports point-to-point 
-links and can generate a custom trace file for use by an animation 
-program.  A snippet from a sample trace file is shown below.
+links; however, we hope
+to support other link types such as CSMA and wireless in the near future.
+A snippet from a sample trace file is shown below.
 
 @verbatim
 0.0 N 0 4 5.5
--- a/doc/manual/flow-monitor.texi	Thu Feb 25 13:51:59 2010 +0100
+++ b/doc/manual/flow-monitor.texi	Thu Feb 25 14:17:21 2010 +0100
@@ -5,6 +5,7 @@
 Placeholder chapter
 @end cartouche
 
-This feature was added as contributed code (@code{src/contrib}) in ns-3.6.
+This feature was added as contributed code (@code{src/contrib}) in ns-3.6 and
+to the main distribution for ns-3.7.
 A paper on this feature is published in the proceedings of NSTools: @*
 @uref{http://www.nstools.org/techprog.shtml,,http://www.nstools.org/techprog.shtml}
--- a/doc/manual/objects.texi	Thu Feb 25 13:51:59 2010 +0100
+++ b/doc/manual/objects.texi	Thu Feb 25 14:17:21 2010 +0100
@@ -10,6 +10,7 @@
 * Object-oriented behavior::
 * Object base classes::
 * Memory management and class Ptr::
+* Object factories::
 * Downcasting::
 @end menu
 
@@ -62,7 +63,7 @@
 @itemize @bullet
 @item @code{class Object}
 @item @code{class ObjectBase}
-@item @code{class RefCountBase}
+@item @code{class SimpleRefCount}
 @end itemize
 It is not required that ns-3 objects inherit from these class, but 
 those that do get special properties.  Classes deriving from 
@@ -75,7 +76,7 @@
 
 Classes that derive from @code{class ObjectBase} get the first two
 properties above, but do not get smart pointers.  Classes that
-derive from @code{class RefCountBase} get only the smart-pointer
+derive from @code{class SimpleRefCount} get only the smart-pointer
 reference counting system.
 
 In practice, @code{class Object} is the variant of the three above that
@@ -134,7 +135,7 @@
 we recommend you to use the CreateObject template functions
 to create the object and store it in a smart pointer to avoid
 memory leaks. These functions are really small convenience
-functions and their goal is just is save you a small
+functions and their goal is just to save you a small
 bit of typing.
 
 @subsection CreateObject and Create
@@ -152,11 +153,8 @@
 Please do not create such objects using @code{operator new}; create them
 using @code{CreateObject()} instead.
 
-For objects deriving from @code{class RefCountBase}, or other
-objects that support usage of the smart pointer class
-(in particular, the ns-3 Packet class does not derive from RefCountBase
-in order to avoid a vtable, but separately implements @code{Ref ()} and 
-@code{Unref ()}),
+For objects deriving from @code{class SimpleRefCount}, or other
+objects that support usage of the smart pointer class,
 a templated helper function is available and recommended to be used:
 @verbatim
   Ptr<B> b = Create<B> ();
@@ -164,6 +162,10 @@
 This is simply a wrapper around operator new that correctly handles
 the reference counting system.
 
+In summary, use @code{Create<B>} if B is not an object but just uses
+reference counting (e.g. @code{class Packet}), and use @code{CreateObject<B>}
+if B derives from @code{ns3::Object}.
+
 @subsection Aggregation
 
 The ns-3 object aggregation system is motivated in strong part by 
@@ -255,6 +257,43 @@
 We hope that this mode of programming will require much less 
 need for developers to modify the base classes.
 
+@node Object factories
+@section Object factories
+
+A common use case is to create lots of similarly configured objects.
+One can repeatedly call @code{CreateObject} but there is also a 
+factory design pattern in use in the ns-3 system.  It is heavily
+used in the "helper" API. 
+
+Class @code{ObjectFactory} can be used to instantiate objects and
+to configure the attributes on those objects 
+
+@verbatim
+  void SetTypeId (TypeId tid);
+  void Set (std::string name, const AttributeValue &value);
+  Ptr<T> Create (void) const;
+@end verbatim
+
+The first method allows one to use the ns-3 TypeId system to specify
+the type of objects created.  The second allows one to set 
+attributes on the objects to be created, and the third allows one
+to create the objects themselves. 
+
+For example:
+@verbatim
+  ObjectFactory factory;
+  // Make this factory create objects of type FriisPropagationLossModel
+  factory.SetTypeId ("ns3::FriisPropagationLossModel")
+  // Make this factory object change a default value of an attribute, for
+  // subsequently created objects
+  factory.Set ("SystemLoss", DoubleValue (2.0));
+  // Create one such object
+  Ptr<Object> object = m_factory.Create (); 
+  factory.Set ("SystemLoss", DoubleValue (3.0));
+  // Create another object
+  Ptr<Object> object = m_factory.Create (); 
+@end verbatim
+
 @node Downcasting
 @section Downcasting
 
--- a/doc/manual/routing.texi	Thu Feb 25 13:51:59 2010 +0100
+++ b/doc/manual/routing.texi	Thu Feb 25 14:17:21 2010 +0100
@@ -270,22 +270,49 @@
 
 @subsection Optimized Link State Routing (OLSR)
 
-This is the first dynamic routing protocol for @command{ns-3}.  The implementation
+This IPv4 routing protocol was originally ported from the OLSR-UM 
+implementation for ns-2.  The implementation
 is found in the src/routing/olsr directory, and an example script is in
 examples/simple-point-to-point-olsr.cc.
 
-The following commands will enable OLSR in a simulation.  
+Typically, OLSR is enabled in a main program by use of an OlsrHelper class
+that installs OLSR into an Ipv4ListRoutingProtocol object.  
+The following sample commands will enable OLSR in a simulation using
+this helper class along with some other routing helper objects.
+The setting of priority value 10, ahead of
+the staticRouting priority of 0, means that OLSR will be consulted for
+a route before the node's static routing table.  
 
 @verbatim
-  olsr::EnableAllNodes ();  // Start OLSR on all nodes
-  olsr::EnableNodes(InputIterator begin, InputIterator end); // Start on
-    // a list of nodes
-  olsr::EnableNode (Ptr<Node> node);  // Start OLSR on "node" only
+  NodeContainer c:
+  ...
+ // Enable OLSR
+  NS_LOG_INFO ("Enabling OLSR Routing.");
+  OlsrHelper olsr;
+
+  Ipv4StaticRoutingHelper staticRouting;
+
+  Ipv4ListRoutingHelper list;
+  list.Add (staticRouting, 0);
+  list.Add (olsr, 10);
+
+  InternetStackHelper internet;
+  internet.SetRoutingHelper (list);
+  internet.Install (c);
 @end verbatim
 
-Once instantiated, the agent can be started with the Start() command,
-and the OLSR "main interface" can be set with the SetMainInterface()
-command.  A number of protocol constants are defined in olsr-agent-impl.cc.
+Once installed,the OLSR "main interface" can be set with the 
+SetMainInterface() command.  If the user does not specify a main address,
+the protocol will select the first primary IP address that it finds, starting
+first the loopback interface and then the next non-loopback interface
+found, in order of Ipv4 interface index.  The loopback address of 127.0.0.1
+is not selected.  In addition, a number of protocol constants are defined in 
+olsr-routing-protocol.cc.
+
+Olsr is started at time zero of the simulation, based on a call to
+Object::Start() that eventually calls OlsrRoutingProtocol::DoStart().
+Note:  a patch to allow the user to start and stop the protocol at other
+times would be welcome.
 
 Presently, OLSR is limited to use with an Ipv4ListRouting object, and
 does not respond to dynamic changes to a device's IP address or link up/down
--- a/doc/manual/tracing.texi	Thu Feb 25 13:51:59 2010 +0100
+++ b/doc/manual/tracing.texi	Thu Feb 25 14:17:21 2010 +0100
@@ -16,6 +16,7 @@
 * Tracing Motivation::
 * Overview::
 * Using the Tracing API::
+* Using the Tracing Helpers::
 * Tracing implementation details::
 @end menu
 
@@ -339,5 +340,835 @@
 sinks. 
 @end itemize
 
+@node Using the Tracing Helpers
+@section Using the Tracing Helpers
+
+The @code{ns-3} trace helpers provide a rich environment for configuring and
+selecting different trace events and writing them to files.  In previous
+sections, primarily ``Building Topologies,'' we have seen several varieties
+of the trace helper methods designed for use inside other (device) helpers.
+
+Perhaps you will recall seeing some of these variations: 
+
+@verbatim
+  pointToPoint.EnablePcapAll ("second");
+  pointToPoint.EnablePcap ("second", p2pNodes.Get (0)->GetId (), 0);
+  csma.EnablePcap ("third", csmaDevices.Get (0), true);
+  pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));
+@end verbatim
+
+What may not be obvious, though, is that there is a consistent model for all of 
+the trace-related methods found in the system.  We will now take a little time
+and take a look at the ``big picture''.
+
+There are currently two primary use cases of the tracing helpers in @code{ns-3}:
+Device helpers and protocol helpers.  Device helpers look at the problem
+of specifying which traces should be enabled through a node, device pair.  For 
+example, you may want to specify that pcap tracing should be enabled on a 
+particular device on a specific node.  This follows from the @code{ns-3} device
+conceptual model, and also the conceptual models of the various device helpers.
+Following naturallyu from this, the files created follow a 
+<prefix>-<node>-<device> naming convention.  
+
+Protocol helpers look at the problem of specifying which traces should be
+enabled through a protocol and interface pair.  This follows from the @code{ns-3}
+protocol stack conceptual model, and also the conceptual models of internet
+stack helpers.  Naturally, the trace files should follow a 
+<prefix>-<protocol>-<interface> naming convention.
+
+The trace helpers therefore fall naturally into a two-dimensional taxonomy.
+There are subtleties that prevent all four classes from behaving identically,
+but we do strive to make them all work as similarly as possible; and whenever
+possible there are analogs for all methods in all classes.
+
+@verbatim
+                   | pcap | ascii |
+  -----------------+------+-------|
+  Device Helper    |      |       |
+  -----------------+------+-------|
+  Protocol Helper  |      |       |
+  -----------------+------+-------|
+@end verbatim
+
+Let say at this point that @code{mixins} would probably be the best way to 
+approach the kind of class hierarchy found in @code{src/helper/trace-helper.h}
+but our Python bindings generator does not support multiple inheritance and so
+this choice is excluded for now.  We were forced to linearize the inheritance
+tree and use single inheritance for the trace functionality.  This results in a
+somewhat odd arrangement of classes, an unusual naming convention and implies
+a hierarchy of functionality avialable in those classes. This isn't really a
+concern for users of this functionality, but it does make our discussion here
+a bit more difficult in some cases.
+
+Let's take a quick look at all four of these cases.
+
+@subsection Pcap Tracing Device Helpers
+
+The goal of these helpers is to make it easy to add a consistent pcap trace
+facility to an @code{ns-3} device.  We want all of the various flavors of
+pcap tracing to work the same across all devices, so the methods of these 
+helpers are inherited by device helpers.  Take a look at 
+@code{src/helper/trace-helper.h} if you want to follow the discussion while 
+looking at real code.
+
+The class @code{PcapHelperForDevice} provides the high level functionality
+for using pcap tracing in an @code{ns-3} device.  Every device must implement a
+single virtual method inherited from this class.
+
+@verbatim
+  virtual void EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous) = 0;
+@end verbatim
+
+The signature of this method reflects the device-centric view of the situation
+at this level.  All of the public methods inherited from class 
+2@code{PcapUserHelperForDevice} reduce to calling this single device-dependent
+implementation method.  For example, the lowest level pcap method,
+
+@verbatim
+  void EnablePcap (std::string prefix, Ptr<NetDevice> nd, bool promiscuous = false);
+@verbatim
+
+will call the device implementation of @code{EnablePcapInternal} directly.  All
+other public pcap tracing methods build on this implementation to provide 
+additional user-level functionality.  What this means to the user is that all 
+device helpers in the system will have all of the pcap trace methods available;
+and these methods will all work in the same way across devices if the device 
+implements @code{EnablePcapInternal} correctly.
+
+@subsubsection Pcap Tracing Device Helper Methods
+
+@verbatim
+  void EnablePcap (std::string prefix, Ptr<NetDevice> nd, bool promiscuous = false);
+  void EnablePcap (std::string prefix, std::string ndName, bool promiscuous = false);
+  void EnablePcap (std::string prefix, NetDeviceContainer d, bool promiscuous = false);
+  void EnablePcap (std::string prefix, NodeContainer n, bool promiscuous = false);
+  void EnablePcap (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool promiscuous = false);
+  void EnablePcapAll (std::string prefix, bool promiscuous = false);
+@end verbatim
+
+You are encouraged to peruse the Doxygen for class @code{PcapHelperForDevice}
+to find the details of these methods; but to summarize ...
+
+You can enable pcap tracing on a particular node/net-device pair by providing a
+@code{Ptr<NetDevice>} to an @code{EnablePcap} method.  The @code{Ptr<Node>} is 
+implicit since the net device must belong to exactly one @code{Node}.
+For example, 
+
+@verbatim
+  Ptr<NetDevice> nd;
+  ...
+  helper.EnablePcap ("prefix", nd);
+@end verbatim
+
+You can enable pcap tracing on a particular node/net-device pair by providing a
+@code{std::string} representing an object name service string to an 
+@code{EnablePcap} method.  The @code{Ptr<NetDevice>} is looked up from the name
+string.  Again, the @code<Node> is implicit since the named net device must 
+belong to exactly one @code{Node}.  For example, 
+
+@verbatim
+  Names::Add ("server" ...);
+  Names::Add ("server/eth0" ...);
+  ...
+  helper.EnablePcap ("prefix", "server/ath0");
+@end verbatim
+
+You can enable pcap tracing on a collection of node/net-device pairs by 
+providing a @code{NetDeviceContainer}.  For each @code{NetDevice} in the container
+the type is checked.  For each device of the proper type (the same type as is 
+managed by the device helper), tracing is enabled.    Again, the @code<Node> is 
+implicit since the found net device must belong to exactly one @code{Node}.
+For example, 
+
+@verbatim
+  NetDeviceContainer d = ...;
+  ...
+  helper.EnablePcap ("prefix", d);
+@end verbatim
+
+You can enable pcap tracing on a collection of node/net-device pairs by 
+providing a @code{NodeContainer}.  For each @code{Node} in the @code{NodeContainer}
+its attached @code{NetDevices} are iterated.  For each @code{NetDevice} attached
+to each node in the container, the type of that device is checked.  For each 
+device of the proper type (the same type as is managed by the device helper), 
+tracing is enabled.
+
+@verbatim
+  NodeContainer n;
+  ...
+  helper.EnablePcap ("prefix", n);
+@end verbatim
+
+You can enable pcap tracing on the basis of node ID and device ID as well as
+with explicit @code{Ptr}.  Each @code{Node} in the system has an integer node ID
+and each device connected to a node has an integer device ID.
+
+@verbatim
+  helper.EnablePcap ("prefix", 21, 1);
+@end verbatim
+
+Finally, you can enable pcap tracing for all devices in the system, with the
+same type as that managed by the device helper.
+
+@verbatim
+  helper.EnablePcapAll ("prefix");
+@end verbatim
+
+In each of these cases, there is an additional parameter that defaults to false.
+This parameter indicates that the trace should not be gathered in promiscuous
+mode.  If you do want your traces to include all traffic seen by the device
+(and the device supports promiscuous mode) simply add a true parameter to any
+of the calls above.  For example,
+
+@verbatim
+  Ptr<NetDevice> nd;
+  ...
+  helper.EnablePcap ("prefix", nd, true);
+@end verbatim
+
+will enable promiscuous mode captures on the @code{NetDevice} specified by @code{nd}.
+
+@subsubsection Pcap Tracing Device Helper Filename Selection
+
+Implicit in all of the method descriptions above is the construction of the
+complete filenames by the implementation method.  By convention, pcap traces
+in the @code{ns-3} system are of the form ``<prefix>-<node id>-<device id>.pcap''
+
+As previously mentioned, every node in the system will have a system-assigned
+node id; and every device will have an interface index (also called a device id)
+relative to its node.  By default, then, a pcap trace file created as a result
+of enabling tracing on the first device of node 21 using the prefix ``prefix''
+would be ``prefix-21-1.pcap''.
+
+You can always use the @code{ns-3} object name service to make this more clear.
+For example, if you use the object name service to assign the name ``server''
+to node 21, the resulting pcap trace file name will automatically become,
+``prefix-server-1.pcap'' and if you also assign the name ``eth0'' to the 
+device, your pcap file name will automatically pick this up and be called
+``prefix-server-eth0.pcap''.
+
+@subsection Ascii Tracing Device Helpers
+
+The behavior of the ascii trace helpers is substantially similar to the pcap
+case.  Take a look at @code{src/helper/trace-helper.h} if you want to 
+follow the discussion while looking at real code.
+
+The class @code{TraceHelperForDevice} adds the high level functionality for 
+using ascii tracing to class @code{PcapHelperForDevice}.  If a device helper
+inherits from class @code{TraceHelperForDevice} it gets both pcap and ascii
+tracing powers.  Along with the internal pcap function, every device must 
+also implement a single virtual method inherited from the ascii trace additions
+to this class.
+
+@verbatim
+  virtual void EnableAsciiInternal (Ptr<OutputStreamWrapper> stream, std::string prefix, Ptr<NetDevice> nd) = 0;
+@end verbatim
+
+The signature of this method reflects the device-centric view of the situation
+at this level; and also the fact that the helper may be writing to a shared
+output stream.  All of the public ascii-trace-related methods inherited from 
+class @code{TraceHelperForDevice} reduce to calling this single device-
+dependent implementation method.  For example, the lowest level ascii trace
+methods,
+
+@verbatim
+  void EnableAscii (std::string prefix, Ptr<NetDevice> nd);
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, Ptr<NetDevice> nd);
+@verbatim
+
+will call the device implementation of @code{EnableAsciiInternal} directly,
+providing either a valid prefix or stream.  All other public ascii tracing 
+methods will build on these low-level functions to provide additional user-level
+functionality.  What this means to the user is that all device helpers in the 
+system will have all of the ascii trace methods available; and these methods
+will all work in the same way across devices if the devices implement 
+@code{EnablAsciiInternal} correctly.
+
+@subsubsection Ascii Tracing Device Helper Methods
+
+@verbatim
+  void EnableAscii (std::string prefix, Ptr<NetDevice> nd);
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, Ptr<NetDevice> nd);
+
+  void EnableAscii (std::string prefix, std::string ndName);
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, std::string ndName);
+
+  void EnableAscii (std::string prefix, NetDeviceContainer d);
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, NetDeviceContainer d);
+
+  void EnableAscii (std::string prefix, NodeContainer n);
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, NodeContainer n);
+
+  void EnableAscii (std::string prefix, uint32_t nodeid, uint32_t deviceid);
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, uint32_t nodeid, uint32_t deviceid);
+
+  void EnableAsciiAll (std::string prefix);
+  void EnableAsciiAll (Ptr<OutputStreamWrapper> stream);
+@end verbatim
+
+You are encouraged to peruse the Doxygen for class @code{TraceHelperForDevice}
+to find the details of these methods; but to summarize ...
+
+There are twice as many methods available for ascii tracing as there were for
+pcap tracing.  This is because, in addition to the pcap-style model where traces
+from each unique node/device pair are written to a unique file, we support a model
+in which trace information for many node/device pairs is written to a common file.
+This means that the <prefix>-<node>-<device> file name generation mechanism is 
+replaced by a mechanism to refer to a common file; and the number of API methods
+is doubled to allow all combinations.
+
+Just as in pcap tracing, you can enable ascii tracing on a particular 
+node/net-device pair by providing a @code{Ptr<NetDevice>} to an @code{EnableAscii}
+method.  The @code{Ptr<Node>} is implicit since the net device must belong to 
+exactly one @code{Node}.  For example, 
+
+@verbatim
+  Ptr<NetDevice> nd;
+  ...
+  helper.EnableAscii ("prefix", nd);
+@end verbatim
+
+In this case, no trace contexts are written to the ascii trace file since they
+would be redundant.  The system will pick the file name to be created using
+the same rules as described in the pcap section, except that the file will
+have the suffix ``.tr'' instead of ``.pcap''.
+
+If you want to enable ascii tracing on more than one net device and have all 
+traces sent to a single file, you can do that as well by using an object to
+refer to a single file.  We have already seen this in the ``cwnd'' example
+above:
+
+@verbatim
+  Ptr<NetDevice> nd1;
+  Ptr<NetDevice> nd2;
+  ...
+  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
+  ...
+  helper.EnableAscii (stream, nd1);
+  helper.EnableAscii (stream, nd2);
+@verbatim
+
+In this case, trace contexts are written to the ascii trace file since they
+are required to disambiguate traces from the two devices.  Note that since the
+user is completely specifying the file name, the string should include the ``,tr''
+for consistency.
+
+You can enable ascii tracing on a particular node/net-device pair by providing a
+@code{std::string} representing an object name service string to an 
+@code{EnablePcap} method.  The @code{Ptr<NetDevice>} is looked up from the name
+string.  Again, the @code<Node> is implicit since the named net device must 
+belong to exactly one @code{Node}.  For example, 
+
+@verbatim
+  Names::Add ("client" ...);
+  Names::Add ("client/eth0" ...);
+  Names::Add ("server" ...);
+  Names::Add ("server/eth0" ...);
+  ...
+  helper.EnableAscii ("prefix", "client/eth0");
+  helper.EnableAscii ("prefix", "server/eth0");
+@end verbatim
+
+This would result in two files named ``prefix-client-eth0.tr'' and 
+``prefix-server-eth0.tr'' with traces for each device in the respective trace
+file.  Since all of the EnableAscii functions are overloaded to take a stream object,
+you can use that form as well:
+
+@verbatim
+  Names::Add ("client" ...);
+  Names::Add ("client/eth0" ...);
+  Names::Add ("server" ...);
+  Names::Add ("server/eth0" ...);
+  ...
+  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
+  ...
+  helper.EnableAscii (stream, "client/eth0");
+  helper.EnableAscii (stream, "server/eth0");
+@end verbatim
+
+This would result in a single trace file called ``trace-file-name.tr'' that 
+contains all of the trace events for both devices.  The events would be 
+disambiguated by trace context strings.
+
+You can enable ascii tracing on a collection of node/net-device pairs by 
+providing a @code{NetDeviceContainer}.  For each @code{NetDevice} in the container
+the type is checked.  For each device of the proper type (the same type as is 
+managed by the device helper), tracing is enabled.    Again, the @code<Node> is 
+implicit since the found net device must belong to exactly one @code{Node}.
+For example, 
+
+@verbatim
+  NetDeviceContainer d = ...;
+  ...
+  helper.EnableAscii ("prefix", d);
+@end verbatim
+
+This would result in a number of ascii trace files being created, each of which
+follows the <prefix>-<node id>-<device id>.tr convention.  Combining all of the
+traces into a single file is accomplished similarly to the examples above:
+
+@verbatim
+  NetDeviceContainer d = ...;
+  ...
+  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
+  ...
+  helper.EnableAscii (stream, d);
+@end verbatim
+
+You can enable ascii tracing on a collection of node/net-device pairs by 
+providing a @code{NodeContainer}.  For each @code{Node} in the @code{NodeContainer}
+its attached @code{NetDevices} are iterated.  For each @code{NetDevice} attached
+to each node in the container, the type of that device is checked.  For each 
+device of the proper type (the same type as is managed by the device helper), 
+tracing is enabled.
+
+@verbatim
+  NodeContainer n;
+  ...
+  helper.EnableAscii ("prefix", n);
+@end verbatim
+
+This would result in a number of ascii trace files being created, each of which
+follows the <prefix>-<node id>-<device id>.tr convention.  Combining all of the
+traces into a single file is accomplished similarly to the examples above:
+
+You can enable pcap tracing on the basis of node ID and device ID as well as
+with explicit @code{Ptr}.  Each @code{Node} in the system has an integer node ID
+and each device connected to a node has an integer device ID.
+
+@verbatim
+  helper.EnableAscii ("prefix", 21, 1);
+@end verbatim
+
+Of course, the traces can be combined into a single file as shown above.
+
+Finally, you can enable pcap tracing for all devices in the system, with the
+same type as that managed by the device helper.
+
+@verbatim
+  helper.EnableAsciiAll ("prefix");
+@end verbatim
+
+This would result in a number of ascii trace files being created, one for
+every device in the system of the type managed by the helper.  All of these
+files will follow the <prefix>-<node id>-<device id>.tr convention.  Combining
+all of the traces into a single file is accomplished similarly to the examples
+above.
+
+@subsubsection Ascii Tracing Device Helper Filename Selection
+
+Implicit in the prefix-style method descriptions above is the construction of the
+complete filenames by the implementation method.  By convention, ascii traces
+in the @code{ns-3} system are of the form ``<prefix>-<node id>-<device id>.tr''
+
+As previously mentioned, every node in the system will have a system-assigned
+node id; and every device will have an interface index (also called a device id)
+relative to its node.  By default, then, an ascii trace file created as a result
+of enabling tracing on the first device of node 21, using the prefix ``prefix'',
+would be ``prefix-21-1.tr''.
+
+You can always use the @code{ns-3} object name service to make this more clear.
+For example, if you use the object name service to assign the name ``server''
+to node 21, the resulting ascii trace file name will automatically become,
+``prefix-server-1.tr'' and if you also assign the name ``eth0'' to the 
+device, your ascii trace file name will automatically pick this up and be called
+``prefix-server-eth0.tr''.
+
+@subsection Pcap Tracing Protocol Helpers
+
+The goal of these helpers is to make it easy to add a consistent pcap trace
+facility to protocols.  We want all of the various flavors of pcap tracing to 
+work the same across all protocols, so the methods of these helpers are 
+inherited by stack helpers.  Take a look at @code{src/helper/trace-helper.h} 
+if you want to follow the discussion while looking at real code.
+
+In this section we will be illustrating the methods as applied to the protocol
+@code{Ipv4}.  To specify traces in similar protocols, just substitute the
+appropriate type.  For example, use a @code{Ptr<Ipv6>} instead of a
+@code{Ptr<Ipv4>} and call @code{EnablePcapIpv6} instead of @code{EnablePcapIpv4}.
+
+The class @code{PcapHelperForIpv4} provides the high level functionality for
+using pcap tracing in the @code{Ipv4} protocol.  Every protocol enabling these
+methods must implement a single virtual method inherited from this class.  There
+will be a separate implementation for @code{Ipv6}, for example, but the only
+difference will be in the method names and signatures.  Different method names
+are required to disambiguate class @code{Ipv4} from @coe{Ipv6} which are both 
+derived from class @code{Object}, and methods that share the same signature.
+
+@verbatim
+  virtual void EnablePcapIpv4Internal (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface) = 0;
+@end verbatim
+
+The signature of this method reflects the protocol and interface-centric view 
+of the situation at this level.  All of the public methods inherited from class 
+@code{PcapHelperForIpv4} reduce to calling this single device-dependent
+implementation method.  For example, the lowest level pcap method,
+
+@verbatim
+  void EnablePcapIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface);
+@verbatim
+
+will call the device implementation of @code{EnablePcapIpv4Internal} directly.
+All other public pcap tracing methods build on this implementation to provide 
+additional user-level functionality.  What this means to the user is that all 
+protocol helpers in the system will have all of the pcap trace methods 
+available; and these methods will all work in the same way across 
+protocols if the helper implements @code{EnablePcapIpv4Internal} correctly.
+
+@subsubsection Pcap Tracing Protocol Helper Methods
+
+These methods are designed to be in one-to-one correspondence with the @code{Node}-
+and @code{NetDevice}- centric versions of the device versions.  Instead of
+@code{Node} and @code{NetDevice} pair constraints, we use protocol and interface
+constraints.
+
+Note that just like in the device version, there are six methods:
+
+@verbatim
+  void EnablePcapIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface);
+  void EnablePcapIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface);
+  void EnablePcapIpv4 (std::string prefix, Ipv4InterfaceContainer c);
+  void EnablePcapIpv4 (std::string prefix, NodeContainer n);
+  void EnablePcapIpv4 (std::string prefix, uint32_t nodeid, uint32_t interface);
+  void EnablePcapIpv4All (std::string prefix);
+@end verbatim
+
+You are encouraged to peruse the Doxygen for class @code{PcapHelperForIpv4}
+to find the details of these methods; but to summarize ...
+
+You can enable pcap tracing on a particular protocol/interface pair by providing a
+@code{Ptr<Ipv4>} and @code{interface} to an @code{EnablePcap} method.  For example, 
+
+@verbatim
+  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+  ...
+  helper.EnablePcapIpv4 ("prefix", ipv4, 0);
+@end verbatim
+
+You can enable pcap tracing on a particular node/net-device pair by providing a
+@code{std::string} representing an object name service string to an 
+@code{EnablePcap} method.  The @code{Ptr<Ipv4>} is looked up from the name
+string.  For example, 
+
+@verbatim
+  Names::Add ("serverIPv4" ...);
+  ...
+  helper.EnablePcapIpv4 ("prefix", "serverIpv4", 1);
+@end verbatim
+
+You can enable pcap tracing on a collection of protocol/interface pairs by 
+providing an @code{Ipv4InterfaceContainer}.  For each @code{Ipv4} / interface
+pair in the container the protocol type is checked.  For each protocol of the 
+proper type (the same type as is managed by the device helper), tracing is 
+enabled for the corresponding interface.  For example, 
+
+@verbatim
+  NodeContainer nodes;
+  ...
+  NetDeviceContainer devices = deviceHelper.Install (nodes);
+  ... 
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer interfaces = ipv4.Assign (devices);
+  ...
+  helper.EnablePcapIpv4 ("prefix", interfaces);
+@end verbatim
+
+You can enable pcap tracing on a collection of protocol/interface pairs by 
+providing a @code{NodeContainer}.  For each @code{Node} in the @code{NodeContainer}
+the appropriate protocol is found.  For each protocol, its interfaces are 
+enumerated and tracing is enabled on the resulting pairs.  For example,
+
+@verbatim
+  NodeContainer n;
+  ...
+  helper.EnablePcapIpv4 ("prefix", n);
+@end verbatim
+
+You can enable pcap tracing on the basis of node ID and interface as well.  In
+this case, the node-id is translated to a @code{Ptr{Node} and the appropriate
+protocol is looked up in the node.  The resulting protocol and interface are
+used to specify the resulting trace source.
+
+@verbatim
+  helper.EnablePcapIpv4 ("prefix", 21, 1);
+@end verbatim
+
+Finally, you can enable pcap tracing for all interfaces in the system, with
+associated protocol being the same type as that managed by the device helper.
+
+@verbatim
+  helper.EnablePcapIpv4All ("prefix");
+@end verbatim
+
+@subsubsection Pcap Tracing Protocol Helper Filename Selection
+
+Implicit in all of the method descriptions above is the construction of the
+complete filenames by the implementation method.  By convention, pcap traces
+taken for devices in the @code{ns-3} system are of the form 
+``<prefix>-<node id>-<device id>.pcap''.  In the case of protocol traces,
+there is a one-to-one correspondence between protocols and @code{Nodes}.
+This is because protocol @code{Objects} are aggregated to @code{Node Objects}.
+Since there is no global protocol id in the system, we use the corresponding
+node id in file naming.  Threfore there is a possibility for file name 
+collisions in automatically chosen trace file names.  For this reason, the
+file name convention is changed for protocol traces.
+
+As previously mentioned, every node in the system will have a system-assigned
+node id.  Since there is a one-to-one correspondence between protocol instances
+and node instances we use the node id.  Each interface has an interface id 
+relative to its protocol.  We use the convention 
+"<prefix>-n<node id>-i<interface id>.pcap" for trace file naming in protocol
+helpers.
+
+Therefore, by default, a pcap trace file created as a result of enabling tracing
+on interface 1 of the Ipv4 protocol of node 21 using the prefix ``prefix''
+would be ``prefix-n21-i1.pcap''.
+
+You can always use the @code{ns-3} object name service to make this more clear.
+For example, if you use the object name service to assign the name ``serverIpv4''
+to the Ptr<Ipv4> on node 21, the resulting pcap trace file name will 
+automatically become, ``prefix-nserverIpv4-i1.pcap''.
+
+@subsection Ascii Tracing Protocol Helpers
+
+The behavior of the ascii trace helpers is substantially similar to the pcap
+case.  Take a look at @code{src/helper/trace-helper.h} if you want to 
+follow the discussion while looking at real code.
+
+In this section we will be illustrating the methods as applied to the protocol
+@code{Ipv4}.  To specify traces in similar protocols, just substitute the
+appropriate type.  For example, use a @code{Ptr<Ipv6>} instead of a
+@code{Ptr<Ipv4>} and call @code{EnableAsciiIpv6} instead of @code{EnableAsciiIpv4}.
+
+The class @code{PcapAndAsciiHelperForIpv4} adds the high level functionality
+for using ascii tracing to the PcapHelperForIpv4.  Every protocol must 
+additionally implement a single virtual method inherited from this class.
+
+@verbatim
+  virtual void EnableAsciiIpv4Internal (Ptr<OutputStreamWrapper> stream, std::string prefix, 
+                                        Ptr<Ipv4> ipv4, uint32_t interface) = 0;
+@end verbatim
+
+The signature of this method reflects the protocol- and interface-centric view 
+of the situation at this level; and also the fact that the helper may be writing
+to a shared output stream.  All of the public methods inherited from class 
+@code{PcapAndAsciiTraceHelperForIpv4} reduce to calling this single device-
+dependent implementation method.  For example, the lowest level ascii trace
+methods,
+
+@verbatim
+  void EnableAsciiIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface);
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, Ptr<Ipv4> ipv4, uint32_t interface);
+@verbatim
+
+will call the device implementation of @code{EnableAsciiIpv4Internal} directly,
+providing either the prefix or the stream.  All other public ascii tracing 
+methods will build on these low-level functions to provide additional user-level
+functionality.  What this means to the user is that all device helpers in the 
+system will have all of the ascii trace methods available; and these methods
+will all work in the same way across protocols if the protocols implement 
+@code{EnablAsciiIpv4Internal} correctly.
+
+@subsubsection Ascii Tracing Device Helper Methods
+
+@verbatim
+  void EnableAsciiIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface);
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, Ptr<Ipv4> ipv4, uint32_t interface);
+
+  void EnableAsciiIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface);
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, std::string ipv4Name, uint32_t interface);
+
+  void EnableAsciiIpv4 (std::string prefix, Ipv4InterfaceContainer c);
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, Ipv4InterfaceContainer c);
+
+  void EnableAsciiIpv4 (std::string prefix, NodeContainer n);
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, NodeContainer n);
+
+  void EnableAsciiIpv4 (std::string prefix, uint32_t nodeid, uint32_t deviceid);
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, uint32_t nodeid, uint32_t interface);
+
+  void EnableAsciiIpv4All (std::string prefix);
+  void EnableAsciiIpv4All (Ptr<OutputStreamWrapper> stream);
+@end verbatim
+
+You are encouraged to peruse the Doxygen for class @code{PcapAndAsciiHelperForIpv4}
+to find the details of these methods; but to summarize ...
+
+There are twice as many methods available for ascii tracing as there were for
+pcap tracing.  This is because, in addition to the pcap-style model where traces
+from each unique protocol/interface pair are written to a unique file, we 
+support a model in which trace information for many protocol/interface pairs is 
+written to a common file.  This means that the <prefix>-n<node id>-<interface>
+file name generation mechanism is replaced by a mechanism to refer to a common 
+file; and the number of API methods is doubled to allow all combinations.
+
+Just as in pcap tracing, you can enable ascii tracing on a particular 
+protocol/interface pair by providing a @code{Ptr<Ipv4>} and an @code{interface}
+to an @code{EnableAscii} method.
+For example, 
+
+@verbatim
+  Ptr<Ipv4> ipv4;
+  ...
+  helper.EnableAsciiIpv4 ("prefix", ipv4, 1);
+@end verbatim
+
+In this case, no trace contexts are written to the ascii trace file since they
+would be redundant.  The system will pick the file name to be created using
+the same rules as described in the pcap section, except that the file will
+have the suffix ``.tr'' instead of ``.pcap''.
+
+If you want to enable ascii tracing on more than one interface and have all 
+traces sent to a single file, you can do that as well by using an object to
+refer to a single file.  We have already something similar to this in the
+``cwnd'' example above:
+
+@verbatim
+  Ptr<Ipv4> protocol1 = node1->GetObject<Ipv4> ();
+  Ptr<Ipv4> protocol2 = node2->GetObject<Ipv4> ();
+  ...
+  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
+  ...
+  helper.EnableAsciiIpv4 (stream, protocol1, 1);
+  helper.EnableAsciiIpv4 (stream, protocol2, 1);
+@verbatim
+
+In this case, trace contexts are written to the ascii trace file since they
+are required to disambiguate traces from the two interfaces.  Note that since 
+the user is completely specifying the file name, the string should include the
+``,tr'' for consistency.
+
+You can enable ascii tracing on a particular protocol by providing a 
+@code{std::string} representing an object name service string to an 
+@code{EnablePcap} method.  The @code{Ptr<Ipv4>} is looked up from the name
+string.  The @code<Node> in the resulting filenames is implicit since there
+is a one-to-one correspondence between protocol instances and nodes,
+For example, 
+
+@verbatim
+  Names::Add ("node1Ipv4" ...);
+  Names::Add ("node2Ipv4" ...);
+  ...
+  helper.EnableAsciiIpv4 ("prefix", "node1Ipv4", 1);
+  helper.EnableAsciiIpv4 ("prefix", "node2Ipv4", 1);
+@end verbatim
+
+This would result in two files named ``prefix-nnode1Ipv4-i1.tr'' and 
+``prefix-nnode2Ipv4-i1.tr'' with traces for each interface in the respective 
+trace file.  Since all of the EnableAscii functions are overloaded to take a 
+stream object, you can use that form as well:
+
+@verbatim
+  Names::Add ("node1Ipv4" ...);
+  Names::Add ("node2Ipv4" ...);
+  ...
+  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
+  ...
+  helper.EnableAsciiIpv4 (stream, "node1Ipv4", 1);
+  helper.EnableAsciiIpv4 (stream, "node2Ipv4", 1);
+@end verbatim
+
+This would result in a single trace file called ``trace-file-name.tr'' that 
+contains all of the trace events for both interfaces.  The events would be 
+disambiguated by trace context strings.
+
+You can enable ascii tracing on a collection of protocol/interface pairs by 
+providing an @code{Ipv4InterfaceContainer}.  For each protocol of the proper 
+type (the same type as is managed by the device helper), tracing is enabled
+for the corresponding interface.  Again, the @code<Node> is implicit since 
+there is a one-to-one correspondence between each protocol and its node.
+For example, 
+
+@verbatim
+  NodeContainer nodes;
+  ...
+  NetDeviceContainer devices = deviceHelper.Install (nodes);
+  ... 
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer interfaces = ipv4.Assign (devices);
+  ...
+  ...
+  helper.EnableAsciiIpv4 ("prefix", interfaces);
+@end verbatim
+
+This would result in a number of ascii trace files being created, each of which
+follows the <prefix>-n<node id>-i<interface>.tr convention.  Combining all of the
+traces into a single file is accomplished similarly to the examples above:
+
+@verbatim
+  NodeContainer nodes;
+  ...
+  NetDeviceContainer devices = deviceHelper.Install (nodes);
+  ... 
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer interfaces = ipv4.Assign (devices);
+  ...
+  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
+  ...
+  helper.EnableAsciiIpv4 (stream, interfaces);
+@end verbatim
+
+You can enable ascii tracing on a collection of protocol/interface pairs by 
+providing a @code{NodeContainer}.  For each @code{Node} in the @code{NodeContainer}
+the appropriate protocol is found.  For each protocol, its interfaces are 
+enumerated and tracing is enabled on the resulting pairs.  For example,
+
+@verbatim
+  NodeContainer n;
+  ...
+  helper.EnableAsciiIpv4 ("prefix", n);
+@end verbatim
+
+This would result in a number of ascii trace files being created, each of which
+follows the <prefix>-<node id>-<device id>.tr convention.  Combining all of the
+traces into a single file is accomplished similarly to the examples above:
+
+You can enable pcap tracing on the basis of node ID and device ID as well.  In
+this case, the node-id is translated to a @code{Ptr{Node} and the appropriate
+protocol is looked up in the node.  The resulting protocol and interface are
+used to specify the resulting trace source.
+
+@verbatim
+  helper.EnableAsciiIpv4 ("prefix", 21, 1);
+@end verbatim
+
+Of course, the traces can be combined into a single file as shown above.
+
+Finally, you can enable ascii tracing for all interfaces in the system, with
+associated protocol being the same type as that managed by the device helper.
+
+@verbatim
+  helper.EnableAsciiIpv4All ("prefix");
+@end verbatim
+
+This would result in a number of ascii trace files being created, one for
+every interface in the system related to a protocol of the type managed by the
+helper.  All of these files will follow the <prefix>-n<node id>-i<interface.tr
+convention.  Combining all of the traces into a single file is accomplished 
+similarly to the examples above.
+
+@subsubsection Ascii Tracing Device Helper Filename Selection
+
+Implicit in the prefix-style method descriptions above is the construction of the
+complete filenames by the implementation method.  By convention, ascii traces
+in the @code{ns-3} system are of the form ``<prefix>-<node id>-<device id>.tr''
+
+As previously mentioned, every node in the system will have a system-assigned
+node id.  Since there is a one-to-one correspondence between protocols and nodes
+we use to node-id to identify the protocol identity.  Every interface on a 
+given rotocol will have an interface index (also called simply an interface) 
+relative to its protocol.  By default, then, an ascii trace file created as a result
+of enabling tracing on the first device of node 21, using the prefix ``prefix'',
+would be ``prefix-n21-i1.tr''.  Use the prefix to disambiguate multiple protocols
+per node.
+
+You can always use the @code{ns-3} object name service to make this more clear.
+For example, if you use the object name service to assign the name ``serverIpv4''
+to the protocol on node 21, and also specify interface one, the resulting ascii 
+trace file name will automatically become, ``prefix-nserverIpv4-1.tr''.
+
 @node Tracing implementation details
 @section Implementation details
--- a/doc/modules	Thu Feb 25 13:51:59 2010 +0100
+++ b/doc/modules	Thu Feb 25 14:17:21 2010 +0100
@@ -60,5 +60,9 @@
  * @defgroup constants Constants
  * @brief Constants you can change
  *
+ * @defgroup utils Utils
+ * @brief The utils directory is for various programs and scripts related 
+ * to code coverage, test suites, style checking, and benchmarking.
+ * 
  * @defgroup contrib Contrib
  */
--- a/doc/tutorial/building-topologies.texi	Thu Feb 25 13:51:59 2010 +0100
+++ b/doc/tutorial/building-topologies.texi	Thu Feb 25 14:17:21 2010 +0100
@@ -316,8 +316,8 @@
 you haven't encountered yet.
 
 @verbatim
-  PointToPointHelper::EnablePcapAll ("second");
-  CsmaHelper::EnablePcap ("second", csmaDevices.Get (1), true);
+  pointToPoint.EnablePcapAll ("second");
+  csma.EnablePcap ("second", csmaDevices.Get (1), true);
 @end verbatim
 
 The CSMA network is a multi-point-to-point network.  This means that there 
@@ -582,9 +582,9 @@
 @code{EnablePcap} calls with the calls below.
 
 @verbatim
-  PointToPointHelper::EnablePcap ("second", p2pNodes.Get (0)->GetId (), 0);
-  CsmaHelper::EnablePcap ("second", csmaNodes.Get (nCsma)->GetId (), 0, false);
-  CsmaHelper::EnablePcap ("second", csmaNodes.Get (nCsma-1)->GetId (), 0, false);
+  pointToPoint.EnablePcap ("second", p2pNodes.Get (0)->GetId (), 0);
+  csma.EnablePcap ("second", csmaNodes.Get (nCsma)->GetId (), 0, false);
+  csma.EnablePcap ("second", csmaNodes.Get (nCsma-1)->GetId (), 0, false);
 @end verbatim
 
 We know that we want to create a pcap file with the base name "second" and
@@ -1082,9 +1082,9 @@
 We create just enough tracing to cover all three networks:
 
 @verbatim
-  PointToPointHelper::EnablePcapAll ("third");
+  pointToPoint.EnablePcapAll ("third");
   phy.EnablePcap ("third", apDevices.Get (0));
-  CsmaHelper::EnablePcap ("third", csmaDevices.Get (0), true);
+  csma.EnablePcap ("third", csmaDevices.Get (0), true);
 @end verbatim
 
 These three lines of code will start pcap tracing on both of the point-to-point
--- a/doc/tutorial/tracing.texi	Thu Feb 25 13:51:59 2010 +0100
+++ b/doc/tutorial/tracing.texi	Thu Feb 25 14:17:21 2010 +0100
@@ -17,6 +17,8 @@
 @menu
 * Background::
 * Overview::
+* A Real Example::
+* Using Mid-Level Trace Helpers::
 @end menu
 
 @c ============================================================================
@@ -48,14 +50,16 @@
 @code{ns-3} provides another mechanism, called Tracing, that avoids some of the 
 problems inherent in the bulk output mechanisms.  It has several important 
 advantages.  First, you can reduce the amount of data you have to manage by only
-tracing the events of interest to you.  Second, if you use this method, you can 
-control the format of the output directly so you avoid the postprocessing step 
-with sed or awk script.  If you desire, your output can be formatted directly into
-a form acceptable by gnuplot, for example.  You can add hooks in the core which 
-can then be accessed by other users, but which will produce no information unless
-explicitly asked to do so.  For these reasons, we believe that the @code{ns-3}
-Tracing system is the best way to get information out of a simulation and is also
-therefore one of the most important mechanisms to understand in @command{ns-3}.
+tracing the events of interest to you (for large simulations, dumping everything
+to disk for post-processing can create I/O bottlenecks).  Second, if you use this
+method, you can control the format of the output directly so you avoid the 
+postprocessing step with sed or awk script.  If you desire, your output can be 
+formatted directly into a form acceptable by gnuplot, for example.  You can add 
+hooks in the core which can then be accessed by other users, but which will 
+produce no information unless explicitly asked to do so.  For these reasons, we 
+believe that the @code{ns-3} tracing system is the best way to get information 
+out of a simulation and is also therefore one of the most important mechanisms
+to understand in @command{ns-3}.
 
 @subsection Blunt Instruments
 There are many ways to get information out of a program.  The most 
@@ -151,21 +155,20 @@
 whenever you want to do anything.
 
 Since there are no guarantees in @code{ns-3} about the stability of @code{NS_LOG}
-messages, you may also discover that pieces of log output on which you depend 
+output, you may also discover that pieces of log output on which you depend 
 disappear or change between releases.  If you depend on the structure of the 
 output, you may find other messages being added or deleted which may affect your
 parsing code.
 
 For these reasons, we consider prints to @code{std::cout} and NS_LOG messages 
-simple ways to get more information out of @code{ns-3}, but they are really 
-unstable and quite blunt instruments.
+to be quick and dirty ways to get more information out of @code{ns-3}.
 
 It is desirable to have a stable facility using stable APIs that allow one to 
 reach into the core system and only get the information required.  It is
 desirable to be able to do this without having to change and recompile the
 core system.  Even better would be a system that notified the user when an item
 of interest changed or an interesting event happened so the user doesn't have 
-to actively go poke around in the system looking for things.
+to actively poke around in the system looking for things.
 
 The @command{ns-3} tracing system is designed to work along those lines and is 
 well-integrated with the Attribute and Config subsystems allowing for relatively
@@ -181,7 +184,7 @@
 provide access to interesting underlying data.  For example, a trace source could
 indicate when a packet is received by a net device and provide access to the 
 packet contents for interested trace sinks.  A trace source might also indicate 
-when an iteresting state change happens in a model.  For example, the congestion
+when an interesting state change happens in a model.  For example, the congestion
 window of a TCP model is a prime candidate for a trace source.
 
 Trace sources are not useful by themselves; they must be connected to other pieces
@@ -572,7 +575,7 @@
 
 We are now at the last Object in the path, so we turn our attention to the 
 Attributes of that Object.  The @code{MobilityModel} class defines an Attribute 
-called ``CourseChange.''  You can see this by looking at the source code in
+called ``CourseChange''.  You can see this by looking at the source code in
 @code{src/mobility/mobility-model.cc} and searching for ``CourseChange'' in your
 favorite editor.  You should find,
 
@@ -622,7 +625,7 @@
 the config path.  Therefore, the @code{CourseChange} function that was hooked 
 from Node number seven will be the only Callback called.
 
-The final piece of the puzzle is the ``context.''  Recall that we saw an output 
+The final piece of the puzzle is the ``context''.  Recall that we saw an output 
 looking something like the following from @code{third.cc}:
 
 @verbatim
@@ -667,7 +670,7 @@
 @item The list of all global values
 @end itemize
 
-The list of interest to us here is ``the list of all trace sources.''  Go 
+The list of interest to us here is ``the list of all trace sources''.  Go 
 ahead and select that link.  You will see, perhaps not too surprisingly, a
 list of all of the trace sources available in the @code{ns-3} core.
 
@@ -712,7 +715,7 @@
 list of all of the classes in @code{ns-3}.  Scroll down until you see the
 entry for @code{ns3::RandomWalk2dMobilityModel} and follow that link.
 You should now be looking at the ``ns3::RandomWalk2dMobilityModel Class 
-Reference.''
+Reference''.
 
 If you now scroll down to the ``Member Function Documentation'' section, you
 will see documentation for the @code{GetTypeId} function.  You constructed one
@@ -1261,7 +1264,7 @@
 We haven't visited any of the test code yet, so let's take a look there.  You
 will typically find that test code is fairly minimal, so this is probably a
 very good bet.  Open @code{src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc} in your
-favorite editor and search for ``CongestionWindow.''  You will find,
+favorite editor and search for ``CongestionWindow''.  You will find,
 
 @verbatim
   ns3TcpSocket->TraceConnectWithoutContext (``CongestionWindow'', 
@@ -1796,7 +1799,7 @@
 we just made (during configuration time) and use it in simulation time.  We now 
 have to instantiate that @code{Application}.  We didn't go to any trouble to
 create a helper to manage the @code{Application} so we are going to have to 
-create and install it ``manually.''  This is actually quite easy:
+create and install it ``manually''.  This is actually quite easy:
 
 @verbatim
   Ptr<MyApp> app = CreateObject<MyApp> ();
@@ -1901,4 +1904,1121 @@
 @sp 1
 @center @image{figures/cwnd,,,,png}
 
-
+@subsection Using Mid-Level Helpers
+
+In the previous section, we showed how to hook a trace source and get hopefully
+interesting information out of a simulation.  Perhaps you will recall that we 
+called logging to the standard output using @code{std::cout} a ``Blunt Instrument'' 
+much earlier in this chapter.  We also wrote about how it was a problem having
+to parse the log output in order to isolate interesting information.  It may 
+have occurred to you that we just spent a lot of time implementing an example
+that exhibits all of the problems we purport to fix with the @code{ns-3} tracing
+system!  You would be correct.  But, bear with us.  We're not done yet.
+
+One of the most important things we want to do is to is to have the ability to 
+easily control the amount of output coming out of the simulation; and we also 
+want to save those data to a file so we can refer back to it later.  We can use
+the mid-level trace helpers provided in @code{ns-3} to do just that and complete
+the picture.
+
+We provide a script that writes the cwnd change and drop events developed in 
+the example @code{fifth.cc } to disk in separate files.  The cwnd changes are 
+stored as a tab-separated ASCII file and the drop events are stored in a pcap
+file.  The changes to make this happen are quite small.
+
+@subsubsection A sixth.cc Walkthrough
+
+Let's take a look at the changes required to go from @code{fifth.cc} to 
+@code{sixth.cc}.  Open @code{examples/tutorial/fifth.cc} in your favorite 
+editor.  You can see the first change by searching for CwndChange.  You will 
+find that we have changed the signatures for the trace sinks and have added 
+a single line to each sink that writes the traced information to a stream
+representing a file.
+
+@verbatim
+  static void
+  CwndChange (Ptr<OutputStreamWrapper> stream, uint32_t oldCwnd, uint32_t newCwnd)
+  {
+    NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
+    *stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
+  }
+  
+  static void
+  RxDrop (Ptr<PcapFileWrapper> file, Ptr<const Packet> p)
+  {
+    NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
+    file->Write(Simulator::Now(), p);
+  }
+@end verbatim
+
+We have added a ``stream'' parameter to the @code{CwndChange} trace sink.  
+This is an object that holds (keeps safely alive) a C++ output stream.  It 
+turns out that this is a very simple object, but one that manages lifetime 
+issues for the stream and solves a problem that even experienced C++ users 
+run into.  It turns out that the copy constructor for ostream is marked 
+private.  This means that ostreams do not obey value semantics and cannot 
+be used in any mechanism that requires the stream to be copied.  This includes
+the @command{ns-3} callback system, which as you may recall, requires objects
+that obey value semantics.  Further notice that we have added the following 
+line in the @code{CwndChange} trace sink implementation:
+
+@verbatim
+  *stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
+@end verbatim  
+
+This would be very familiar code if you replaced @code{*stream->GetStream ()}
+with @code{std::cout}, as in:
+
+@verbatim
+  std::cout << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
+@end verbatim  
+
+This illustrates that the @code{Ptr<OutputStreamWrapper>} is really just
+carrying around a @code{std::ofstream} for you, and you can use it here like 
+any other output stream.
+
+A similar situation happens in @code{RxDrop} except that the object being 
+passed around (a @code{Ptr<PcapFileWrapper>}) represents a pcap file.  There
+is a one-liner in the trace sink to write a timestamp and the contents of the 
+packet being dropped to the pcap file:
+
+@end verbatim
+  file->Write(Simulator::Now(), p);
+@end verbatim
+
+Of course, if we have objects representing the two files, we need to create
+them somewhere and also cause them to be passed to the trace sinks.  If you 
+look in the @code{main} function, you will find new code to do just that:
+
+@verbatim
+  AsciiTraceHelper asciiTraceHelper;
+  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("sixth.cwnd");
+  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeBoundCallback (&CwndChange, stream));
+
+  ...
+
+  PcapHelper pcapHelper;
+  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile ("sixth.pcap", "w", PcapHelper::DLT_PPP);
+  devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file));
+@end verbatim
+
+In the first section of the code snippet above, we are creating the ASCII
+trace file, creating an object responsible for managing it and using a
+variant of the callback creation function to arrange for the object to be 
+passed to the sink.  Our ASCII trace helpers provide a rich set of
+functions to make using text (ASCII) files easy.  We are just going to 
+illustrate the use of the file stream creation function here.
+
+The @code{CreateFileStream{}} function is basically going to instantiate
+a std::ofstream object and create a new file (or truncate an existing file).
+This ofstream is packaged up in an @code{ns-3} object for lifetime management
+and copy constructor issue resolution.
+
+We then take this @code{ns-3} object representing the file and pass it to
+@code{MakeBoundCallback()}.  This function creates a callback just like
+@code{MakeCallback()}, but it ``binds'' a new value to the callback.  This
+value is added to the callback before it is called.  
+
+Essentially, @code{MakeBoundCallback(&CwndChange, stream)} causes the trace 
+source to add the additional ``stream'' parameter to the front of the formal
+parameter list before invoking the callback.  This changes the required 
+signature of the @code{CwndChange} sink to match the one shown above, which
+includes the ``extra'' parameter @code{Ptr<OutputStreamWrapper> stream}.
+
+In the second section of code in the snippet above, we instantiate a 
+@code{PcapHelper} to do the same thing for our pcap trace file that we did
+with the @code{AsciiTraceHelper}. The line of code,
+
+@verbatim
+  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile ("sixth.pcap", "w", PcapHelper::DLT_PPP);
+@end verbatim
+
+creates a pcap file named ``sixth.pcap'' with file mode ``w''.   This means that
+the new file is to truncated if an existing file with that name is found.  The
+final parameter is the ``data link type'' of the new pcap file.  These are 
+the same as the pcap library data link types defined in @code{bpf.h} if you are
+familar with pcap.  In this case, @code{DLT_PPP} indicates that the pcap file
+is going to contain packets prefixed with point to point headers.  This is true
+since the packets are coming from our point-to-point device driver.  Other
+common data link types are DLT_EN10MB (10 MB Ethernet) appropriate for csma
+devices and DLT_IEEE802_11 (IEEE 802.11) appropriate for wifi devices.  These
+are defined in @code{src/helper/trace-helper.h"} if you are interested in seeing
+the list.  The entries in the list match those in @code{bpf.h} but we duplicate
+them to avoid a pcap source dependence.
+
+A @code{ns-3} object representing the pcap file is returned from @code{CreateFile}
+and used in a bound callback exactly as it was in the ascii case.
+
+An important detour:  It is important to notice that even though both of these 
+objects are declared in very similar ways,
+
+@verbatim
+  Ptr<PcapFileWrapper> file ...
+  Ptr<OutputStreamWrapper> stream ...
+@end verbatim
+
+The underlying objects are entirely different.  For example, the 
+Ptr<PcapFileWrapper> is a smart pointer to an @command{ns-3} Object that is a 
+fairly heaviweight thing that supports @code{Attributes} and is integrated into
+the config system.  The Ptr<OutputStreamWrapper>, on the other hand, is a smart 
+pointer to a reference counted object that is a very lightweight thing.
+Remember to always look at the object you are referencing before making any
+assumptions about the ``powers'' that object may have.  
+
+For example, take a look at @code{src/common/pcap-file-object.h} in the 
+distribution and notice, 
+
+@verbatim
+  class PcapFileWrapper : public Object
+@end verbatim
+
+that class @code{PcapFileWrapper} is an @command{ns-3} Object by virtue of 
+its inheritance.  Then look at @code{src/common/output-stream-wrapper.h} and 
+notice,
+
+@verbatim
+  class OutputStreamWrapper : public SimpleRefCount<OutputStreamWrapper>
+@end verbatim
+
+that this object is not an @command{ns-3} Object at all, it is ``merely'' a
+C++ object that happens to support intrusive reference counting.
+
+The point here is that just because you read Ptr<something> it does not necessarily
+mean that ``something'' is an @command{ns-3} Object on which you can hang @command{ns-3}
+@code{Attributes}, for example.
+
+Now, back to the example.  If you now build and run this example,
+
+@verbatim
+  ./waf --run sixth
+@end verbatim
+
+you will see the same messages appear as when you ran ``fifth'', but two new 
+files will appear in the top-level directory of your @code{ns-3} distribution.
+
+@verbatim
+  sixth.cwnd  sixth.pcap
+@end verbatim
+
+Since ``sixth.cwnd'' is an ASCII text file, you can view it with @code{cat}
+or your favorite file viewer.
+
+@verbatim
+  1.20919 536     1072
+  1.21511 1072    1608
+  ...
+  9.30922 8893    8925
+  9.31754 8925    8957
+@end verbatim
+
+You have a tab separated file with a timestamp, an old congestion window and a
+new congestion window suitable for directly importing into your plot program.
+There are no extraneous prints in the file, no parsing or editing is required.
+
+Since ``sixth.pcap'' is a pcap file, you can fiew it with @code{tcpdump}.
+
+@verbatim
+  reading from file ../../sixth.pcap, link-type PPP (PPP)
+  1.251507 IP 10.1.1.1.49153 > 10.1.1.2.8080: . 17689:18225(536) ack 1 win 65535
+  1.411478 IP 10.1.1.1.49153 > 10.1.1.2.8080: . 33808:34312(504) ack 1 win 65535
+  ...
+  7.393557 IP 10.1.1.1.49153 > 10.1.1.2.8080: . 781568:782072(504) ack 1 win 65535
+  8.141483 IP 10.1.1.1.49153 > 10.1.1.2.8080: . 874632:875168(536) ack 1 win 65535
+@end verbatim
+
+You have a pcap file with the packets that were dropped in the simulation.  There
+are no other packets present in the file and there is nothing else present to
+make life difficult.
+
+It's been a long journey, but we are now at a point where we can appreciate the
+@code{ns-3} tracing system.  We have pulled important events out of the middle
+of a TCP implementation and a device driver.  We stored those events directly in
+files usable with commonly known tools.  We did this without modifying any of the
+core code involved, and we did this in only 18 lines of code:
+
+@verbatim
+  static void
+  CwndChange (Ptr<OutputStreamWrapper> stream, uint32_t oldCwnd, uint32_t newCwnd)
+  {
+    NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
+    *stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
+  }
+
+  ...
+
+  AsciiTraceHelper asciiTraceHelper;
+  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("sixth.cwnd");
+  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeBoundCallback (&CwndChange, stream));
+
+  ...
+
+  static void
+  RxDrop (Ptr<PcapFileWrapper> file, Ptr<const Packet> p)
+  {
+    NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
+    file->Write(Simulator::Now(), p);
+  }
+
+  ...
+  
+  PcapHelper pcapHelper;
+  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile ("sixth.pcap", "w", PcapHelper::DLT_PPP);
+  devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file));
+@end verbatim
+
+@c ============================================================================
+@c Using Trace Helpers
+@c ============================================================================
+@node Using Trace Helpers
+@section Using Trace Helpers
+
+The @code{ns-3} trace helpers provide a rich environment for configuring and
+selecting different trace events and writing them to files.  In previous
+sections, primarily ``Building Topologies,'' we have seen several varieties
+of the trace helper methods designed for use inside other (device) helpers.
+
+Perhaps you will recall seeing some of these variations: 
+
+@verbatim
+  pointToPoint.EnablePcapAll ("second");
+  pointToPoint.EnablePcap ("second", p2pNodes.Get (0)->GetId (), 0);
+  csma.EnablePcap ("third", csmaDevices.Get (0), true);
+  pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));
+@end verbatim
+
+What may not be obvious, though, is that there is a consistent model for all of 
+the trace-related methods found in the system.  We will now take a little time
+and take a look at the ``big picture''.
+
+There are currently two primary use cases of the tracing helpers in @code{ns-3}:
+Device helpers and protocol helpers.  Device helpers look at the problem
+of specifying which traces should be enabled through a node, device pair.  For 
+example, you may want to specify that pcap tracing should be enabled on a 
+particular device on a specific node.  This follows from the @code{ns-3} device
+conceptual model, and also the conceptual models of the various device helpers.
+Following naturallyu from this, the files created follow a 
+<prefix>-<node>-<device> naming convention.  
+
+Protocol helpers look at the problem of specifying which traces should be
+enabled through a protocol and interface pair.  This follows from the @code{ns-3}
+protocol stack conceptual model, and also the conceptual models of internet
+stack helpers.  Naturally, the trace files should follow a 
+<prefix>-<protocol>-<interface> naming convention.
+
+The trace helpers therefore fall naturally into a two-dimensional taxonomy.
+There are subtleties that prevent all four classes from behaving identically,
+but we do strive to make them all work as similarly as possible; and whenever
+possible there are analogs for all methods in all classes.
+
+@verbatim
+                   | pcap | ascii |
+  -----------------+------+-------|
+  Device Helper    |      |       |
+  -----------------+------+-------|
+  Protocol Helper  |      |       |
+  -----------------+------+-------|
+@end verbatim
+
+Let say at this point that @code{mixins} would probably be the best way to 
+approach the kind of class hierarchy found in @code{src/helper/trace-helper.h}
+but our Python bindings generator does not support multiple inheritance and so
+this choice is excluded for now.  We were forced to linearize the inheritance
+tree and use single inheritance for the trace functionality.  This results in a
+somewhat odd arrangement of classes, an unusual naming convention and implies
+a hierarchy of functionality avialable in those classes. This isn't really a
+concern for users of this functionality, but it does make our discussion here
+a bit more difficult in some cases.
+
+Let's take a quick look at all four of these cases.
+
+@subsection Pcap Tracing Device Helpers
+
+The goal of these helpers is to make it easy to add a consistent pcap trace
+facility to an @code{ns-3} device.  We want all of the various flavors of
+pcap tracing to work the same across all devices, so the methods of these 
+helpers are inherited by device helpers.  Take a look at 
+@code{src/helper/trace-helper.h} if you want to follow the discussion while 
+looking at real code.
+
+The class @code{PcapHelperForDevice} provides the high level functionality
+for using pcap tracing in an @code{ns-3} device.  Every device must implement a
+single virtual method inherited from this class.
+
+@verbatim
+  virtual void EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous) = 0;
+@end verbatim
+
+The signature of this method reflects the device-centric view of the situation
+at this level.  All of the public methods inherited from class 
+2@code{PcapUserHelperForDevice} reduce to calling this single device-dependent
+implementation method.  For example, the lowest level pcap method,
+
+@verbatim
+  void EnablePcap (std::string prefix, Ptr<NetDevice> nd, bool promiscuous = false);
+@end verbatim
+
+will call the device implementation of @code{EnablePcapInternal} directly.  All
+other public pcap tracing methods build on this implementation to provide 
+additional user-level functionality.  What this means to the user is that all 
+device helpers in the system will have all of the pcap trace methods available;
+and these methods will all work in the same way across devices if the device 
+implements @code{EnablePcapInternal} correctly.
+
+@subsubsection Pcap Tracing Device Helper Methods
+
+@verbatim
+  void EnablePcap (std::string prefix, Ptr<NetDevice> nd, bool promiscuous = false);
+  void EnablePcap (std::string prefix, std::string ndName, bool promiscuous = false);
+  void EnablePcap (std::string prefix, NetDeviceContainer d, bool promiscuous = false);
+  void EnablePcap (std::string prefix, NodeContainer n, bool promiscuous = false);
+  void EnablePcap (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool promiscuous = false);
+  void EnablePcapAll (std::string prefix, bool promiscuous = false);
+@end verbatim
+
+You are encouraged to peruse the Doxygen for class @code{PcapHelperForDevice}
+to find the details of these methods; but to summarize ...
+
+You can enable pcap tracing on a particular node/net-device pair by providing a
+@code{Ptr<NetDevice>} to an @code{EnablePcap} method.  The @code{Ptr<Node>} is 
+implicit since the net device must belong to exactly one @code{Node}.
+For example, 
+
+@verbatim
+  Ptr<NetDevice> nd;
+  ...
+  helper.EnablePcap ("prefix", nd);
+@end verbatim
+
+You can enable pcap tracing on a particular node/net-device pair by providing a
+@code{std::string} representing an object name service string to an 
+@code{EnablePcap} method.  The @code{Ptr<NetDevice>} is looked up from the name
+string.  Again, the @code<Node> is implicit since the named net device must 
+belong to exactly one @code{Node}.  For example, 
+
+@verbatim
+  Names::Add ("server" ...);
+  Names::Add ("server/eth0" ...);
+  ...
+  helper.EnablePcap ("prefix", "server/ath0");
+@end verbatim
+
+You can enable pcap tracing on a collection of node/net-device pairs by 
+providing a @code{NetDeviceContainer}.  For each @code{NetDevice} in the container
+the type is checked.  For each device of the proper type (the same type as is 
+managed by the device helper), tracing is enabled.    Again, the @code<Node> is 
+implicit since the found net device must belong to exactly one @code{Node}.
+For example, 
+
+@verbatim
+  NetDeviceContainer d = ...;
+  ...
+  helper.EnablePcap ("prefix", d);
+@end verbatim
+
+You can enable pcap tracing on a collection of node/net-device pairs by 
+providing a @code{NodeContainer}.  For each @code{Node} in the @code{NodeContainer}
+its attached @code{NetDevices} are iterated.  For each @code{NetDevice} attached
+to each node in the container, the type of that device is checked.  For each 
+device of the proper type (the same type as is managed by the device helper), 
+tracing is enabled.
+
+@verbatim
+  NodeContainer n;
+  ...
+  helper.EnablePcap ("prefix", n);
+@end verbatim
+
+You can enable pcap tracing on the basis of node ID and device ID as well as
+with explicit @code{Ptr}.  Each @code{Node} in the system has an integer node ID
+and each device connected to a node has an integer device ID.
+
+@verbatim
+  helper.EnablePcap ("prefix", 21, 1);
+@end verbatim
+
+Finally, you can enable pcap tracing for all devices in the system, with the
+same type as that managed by the device helper.
+
+@verbatim
+  helper.EnablePcapAll ("prefix");
+@end verbatim
+
+In each of these cases, there is an additional parameter that defaults to false.
+This parameter indicates that the trace should not be gathered in promiscuous
+mode.  If you do want your traces to include all traffic seen by the device
+(and the device supports promiscuous mode) simply add a true parameter to any
+of the calls above.  For example,
+
+@verbatim
+  Ptr<NetDevice> nd;
+  ...
+  helper.EnablePcap ("prefix", nd, true);
+@end verbatim
+
+will enable promiscuous mode captures on the @code{NetDevice} specified by @code{nd}.
+
+@subsubsection Pcap Tracing Device Helper Filename Selection
+
+Implicit in all of the method descriptions above is the construction of the
+complete filenames by the implementation method.  By convention, pcap traces
+in the @code{ns-3} system are of the form ``<prefix>-<node id>-<device id>.pcap''
+
+As previously mentioned, every node in the system will have a system-assigned
+node id; and every device will have an interface index (also called a device id)
+relative to its node.  By default, then, a pcap trace file created as a result
+of enabling tracing on the first device of node 21 using the prefix ``prefix''
+would be ``prefix-21-1.pcap''.
+
+You can always use the @code{ns-3} object name service to make this more clear.
+For example, if you use the object name service to assign the name ``server''
+to node 21, the resulting pcap trace file name will automatically become,
+``prefix-server-1.pcap'' and if you also assign the name ``eth0'' to the 
+device, your pcap file name will automatically pick this up and be called
+``prefix-server-eth0.pcap''.
+
+@subsection Ascii Tracing Device Helpers
+
+The behavior of the ascii trace helpers is substantially similar to the pcap
+case.  Take a look at @code{src/helper/trace-helper.h} if you want to 
+follow the discussion while looking at real code.
+
+The class @code{TraceHelperForDevice} adds the high level functionality for 
+using ascii tracing to class @code{PcapHelperForDevice}.  If a device helper
+inherits from class @code{TraceHelperForDevice} it gets both pcap and ascii
+tracing powers.  Along with the internal pcap function, every device must 
+also implement a single virtual method inherited from the ascii trace additions
+to this class.
+
+@verbatim
+  virtual void EnableAsciiInternal (Ptr<OutputStreamWrapper> stream, std::string prefix, Ptr<NetDevice> nd) = 0;
+@end verbatim
+
+The signature of this method reflects the device-centric view of the situation
+at this level; and also the fact that the helper may be writing to a shared
+output stream.  All of the public ascii-trace-related methods inherited from 
+class @code{TraceHelperForDevice} reduce to calling this single device-
+dependent implementation method.  For example, the lowest level ascii trace
+methods,
+
+@verbatim
+  void EnableAscii (std::string prefix, Ptr<NetDevice> nd);
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, Ptr<NetDevice> nd);
+@verbatim
+
+will call the device implementation of @code{EnableAsciiInternal} directly,
+providing either a valid prefix or stream.  All other public ascii tracing 
+methods will build on these low-level functions to provide additional user-level
+functionality.  What this means to the user is that all device helpers in the 
+system will have all of the ascii trace methods available; and these methods
+will all work in the same way across devices if the devices implement 
+@code{EnablAsciiInternal} correctly.
+
+@subsubsection Ascii Tracing Device Helper Methods
+
+@verbatim
+  void EnableAscii (std::string prefix, Ptr<NetDevice> nd);
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, Ptr<NetDevice> nd);
+
+  void EnableAscii (std::string prefix, std::string ndName);
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, std::string ndName);
+
+  void EnableAscii (std::string prefix, NetDeviceContainer d);
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, NetDeviceContainer d);
+
+  void EnableAscii (std::string prefix, NodeContainer n);
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, NodeContainer n);
+
+  void EnableAscii (std::string prefix, uint32_t nodeid, uint32_t deviceid);
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, uint32_t nodeid, uint32_t deviceid);
+
+  void EnableAsciiAll (std::string prefix);
+  void EnableAsciiAll (Ptr<OutputStreamWrapper> stream);
+@end verbatim
+
+You are encouraged to peruse the Doxygen for class @code{TraceHelperForDevice}
+to find the details of these methods; but to summarize ...
+
+There are twice as many methods available for ascii tracing as there were for
+pcap tracing.  This is because, in addition to the pcap-style model where traces
+from each unique node/device pair are written to a unique file, we support a model
+in which trace information for many node/device pairs is written to a common file.
+This means that the <prefix>-<node>-<device> file name generation mechanism is 
+replaced by a mechanism to refer to a common file; and the number of API methods
+is doubled to allow all combinations.
+
+Just as in pcap tracing, you can enable ascii tracing on a particular 
+node/net-device pair by providing a @code{Ptr<NetDevice>} to an @code{EnableAscii}
+method.  The @code{Ptr<Node>} is implicit since the net device must belong to 
+exactly one @code{Node}.  For example, 
+
+@verbatim
+  Ptr<NetDevice> nd;
+  ...
+  helper.EnableAscii ("prefix", nd);
+@end verbatim
+
+In this case, no trace contexts are written to the ascii trace file since they
+would be redundant.  The system will pick the file name to be created using
+the same rules as described in the pcap section, except that the file will
+have the suffix ``.tr'' instead of ``.pcap''.
+
+If you want to enable ascii tracing on more than one net device and have all 
+traces sent to a single file, you can do that as well by using an object to
+refer to a single file.  We have already seen this in the ``cwnd'' example
+above:
+
+@verbatim
+  Ptr<NetDevice> nd1;
+  Ptr<NetDevice> nd2;
+  ...
+  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
+  ...
+  helper.EnableAscii (stream, nd1);
+  helper.EnableAscii (stream, nd2);
+@verbatim
+
+In this case, trace contexts are written to the ascii trace file since they
+are required to disambiguate traces from the two devices.  Note that since the
+user is completely specifying the file name, the string should include the ``,tr''
+for consistency.
+
+You can enable ascii tracing on a particular node/net-device pair by providing a
+@code{std::string} representing an object name service string to an 
+@code{EnablePcap} method.  The @code{Ptr<NetDevice>} is looked up from the name
+string.  Again, the @code<Node> is implicit since the named net device must 
+belong to exactly one @code{Node}.  For example, 
+
+@verbatim
+  Names::Add ("client" ...);
+  Names::Add ("client/eth0" ...);
+  Names::Add ("server" ...);
+  Names::Add ("server/eth0" ...);
+  ...
+  helper.EnableAscii ("prefix", "client/eth0");
+  helper.EnableAscii ("prefix", "server/eth0");
+@end verbatim
+
+This would result in two files named ``prefix-client-eth0.tr'' and 
+``prefix-server-eth0.tr'' with traces for each device in the respective trace
+file.  Since all of the EnableAscii functions are overloaded to take a stream wrapper,
+you can use that form as well:
+
+@verbatim
+  Names::Add ("client" ...);
+  Names::Add ("client/eth0" ...);
+  Names::Add ("server" ...);
+  Names::Add ("server/eth0" ...);
+  ...
+  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
+  ...
+  helper.EnableAscii (stream, "client/eth0");
+  helper.EnableAscii (stream, "server/eth0");
+@end verbatim
+
+This would result in a single trace file called ``trace-file-name.tr'' that 
+contains all of the trace events for both devices.  The events would be 
+disambiguated by trace context strings.
+
+You can enable ascii tracing on a collection of node/net-device pairs by 
+providing a @code{NetDeviceContainer}.  For each @code{NetDevice} in the container
+the type is checked.  For each device of the proper type (the same type as is 
+managed by the device helper), tracing is enabled.    Again, the @code<Node> is 
+implicit since the found net device must belong to exactly one @code{Node}.
+For example, 
+
+@verbatim
+  NetDeviceContainer d = ...;
+  ...
+  helper.EnableAscii ("prefix", d);
+@end verbatim
+
+This would result in a number of ascii trace files being created, each of which
+follows the <prefix>-<node id>-<device id>.tr convention.  Combining all of the
+traces into a single file is accomplished similarly to the examples above:
+
+@verbatim
+  NetDeviceContainer d = ...;
+  ...
+  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
+  ...
+  helper.EnableAscii (stream, d);
+@end verbatim
+
+You can enable ascii tracing on a collection of node/net-device pairs by 
+providing a @code{NodeContainer}.  For each @code{Node} in the @code{NodeContainer}
+its attached @code{NetDevices} are iterated.  For each @code{NetDevice} attached
+to each node in the container, the type of that device is checked.  For each 
+device of the proper type (the same type as is managed by the device helper), 
+tracing is enabled.
+
+@verbatim
+  NodeContainer n;
+  ...
+  helper.EnableAscii ("prefix", n);
+@end verbatim
+
+This would result in a number of ascii trace files being created, each of which
+follows the <prefix>-<node id>-<device id>.tr convention.  Combining all of the
+traces into a single file is accomplished similarly to the examples above:
+
+You can enable pcap tracing on the basis of node ID and device ID as well as
+with explicit @code{Ptr}.  Each @code{Node} in the system has an integer node ID
+and each device connected to a node has an integer device ID.
+
+@verbatim
+  helper.EnableAscii ("prefix", 21, 1);
+@end verbatim
+
+Of course, the traces can be combined into a single file as shown above.
+
+Finally, you can enable pcap tracing for all devices in the system, with the
+same type as that managed by the device helper.
+
+@verbatim
+  helper.EnableAsciiAll ("prefix");
+@end verbatim
+
+This would result in a number of ascii trace files being created, one for
+every device in the system of the type managed by the helper.  All of these
+files will follow the <prefix>-<node id>-<device id>.tr convention.  Combining
+all of the traces into a single file is accomplished similarly to the examples
+above.
+
+@subsubsection Ascii Tracing Device Helper Filename Selection
+
+Implicit in the prefix-style method descriptions above is the construction of the
+complete filenames by the implementation method.  By convention, ascii traces
+in the @code{ns-3} system are of the form ``<prefix>-<node id>-<device id>.tr''
+
+As previously mentioned, every node in the system will have a system-assigned
+node id; and every device will have an interface index (also called a device id)
+relative to its node.  By default, then, an ascii trace file created as a result
+of enabling tracing on the first device of node 21, using the prefix ``prefix'',
+would be ``prefix-21-1.tr''.
+
+You can always use the @code{ns-3} object name service to make this more clear.
+For example, if you use the object name service to assign the name ``server''
+to node 21, the resulting ascii trace file name will automatically become,
+``prefix-server-1.tr'' and if you also assign the name ``eth0'' to the 
+device, your ascii trace file name will automatically pick this up and be called
+``prefix-server-eth0.tr''.
+
+@subsection Pcap Tracing Protocol Helpers
+
+The goal of these helpers is to make it easy to add a consistent pcap trace
+facility to protocols.  We want all of the various flavors of pcap tracing to 
+work the same across all protocols, so the methods of these helpers are 
+inherited by stack helpers.  Take a look at @code{src/helper/trace-helper.h} 
+if you want to follow the discussion while looking at real code.
+
+In this section we will be illustrating the methods as applied to the protocol
+@code{Ipv4}.  To specify traces in similar protocols, just substitute the
+appropriate type.  For example, use a @code{Ptr<Ipv6>} instead of a
+@code{Ptr<Ipv4>} and call @code{EnablePcapIpv6} instead of @code{EnablePcapIpv4}.
+
+The class @code{PcapHelperForIpv4} provides the high level functionality for
+using pcap tracing in the @code{Ipv4} protocol.  Every protocol enabling these
+methods must implement a single virtual method inherited from this class.  There
+will be a separate implementation for @code{Ipv6}, for example, but the only
+difference will be in the method names and signatures.  Different method names
+are required to disambiguate class @code{Ipv4} from @coe{Ipv6} which are both 
+derived from class @code{Object}, and methods that share the same signature.
+
+@verbatim
+  virtual void EnablePcapIpv4Internal (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface) = 0;
+@end verbatim
+
+The signature of this method reflects the protocol and interface-centric view 
+of the situation at this level.  All of the public methods inherited from class 
+@code{PcapHelperForIpv4} reduce to calling this single device-dependent
+implementation method.  For example, the lowest level pcap method,
+
+@verbatim
+  void EnablePcapIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface);
+@verbatim
+
+will call the device implementation of @code{EnablePcapIpv4Internal} directly.
+All other public pcap tracing methods build on this implementation to provide 
+additional user-level functionality.  What this means to the user is that all 
+protocol helpers in the system will have all of the pcap trace methods 
+available; and these methods will all work in the same way across 
+protocols if the helper implements @code{EnablePcapIpv4Internal} correctly.
+
+@subsubsection Pcap Tracing Protocol Helper Methods
+
+These methods are designed to be in one-to-one correspondence with the @code{Node}-
+and @code{NetDevice}- centric versions of the device versions.  Instead of
+@code{Node} and @code{NetDevice} pair constraints, we use protocol and interface
+constraints.
+
+Note that just like in the device version, there are six methods:
+
+@verbatim
+  void EnablePcapIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface);
+  void EnablePcapIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface);
+  void EnablePcapIpv4 (std::string prefix, Ipv4InterfaceContainer c);
+  void EnablePcapIpv4 (std::string prefix, NodeContainer n);
+  void EnablePcapIpv4 (std::string prefix, uint32_t nodeid, uint32_t interface);
+  void EnablePcapIpv4All (std::string prefix);
+@end verbatim
+
+You are encouraged to peruse the Doxygen for class @code{PcapHelperForIpv4}
+to find the details of these methods; but to summarize ...
+
+You can enable pcap tracing on a particular protocol/interface pair by providing a
+@code{Ptr<Ipv4>} and @code{interface} to an @code{EnablePcap} method.  For example, 
+
+@verbatim
+  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+  ...
+  helper.EnablePcapIpv4 ("prefix", ipv4, 0);
+@end verbatim
+
+You can enable pcap tracing on a particular node/net-device pair by providing a
+@code{std::string} representing an object name service string to an 
+@code{EnablePcap} method.  The @code{Ptr<Ipv4>} is looked up from the name
+string.  For example, 
+
+@verbatim
+  Names::Add ("serverIPv4" ...);
+  ...
+  helper.EnablePcapIpv4 ("prefix", "serverIpv4", 1);
+@end verbatim
+
+You can enable pcap tracing on a collection of protocol/interface pairs by 
+providing an @code{Ipv4InterfaceContainer}.  For each @code{Ipv4} / interface
+pair in the container the protocol type is checked.  For each protocol of the 
+proper type (the same type as is managed by the device helper), tracing is 
+enabled for the corresponding interface.  For example, 
+
+@verbatim
+  NodeContainer nodes;
+  ...
+  NetDeviceContainer devices = deviceHelper.Install (nodes);
+  ... 
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer interfaces = ipv4.Assign (devices);
+  ...
+  helper.EnablePcapIpv4 ("prefix", interfaces);
+@end verbatim
+
+You can enable pcap tracing on a collection of protocol/interface pairs by 
+providing a @code{NodeContainer}.  For each @code{Node} in the @code{NodeContainer}
+the appropriate protocol is found.  For each protocol, its interfaces are 
+enumerated and tracing is enabled on the resulting pairs.  For example,
+
+@verbatim
+  NodeContainer n;
+  ...
+  helper.EnablePcapIpv4 ("prefix", n);
+@end verbatim
+
+You can enable pcap tracing on the basis of node ID and interface as well.  In
+this case, the node-id is translated to a @code{Ptr{Node} and the appropriate
+protocol is looked up in the node.  The resulting protocol and interface are
+used to specify the resulting trace source.
+
+@verbatim
+  helper.EnablePcapIpv4 ("prefix", 21, 1);
+@end verbatim
+
+Finally, you can enable pcap tracing for all interfaces in the system, with
+associated protocol being the same type as that managed by the device helper.
+
+@verbatim
+  helper.EnablePcapIpv4All ("prefix");
+@end verbatim
+
+@subsubsection Pcap Tracing Protocol Helper Filename Selection
+
+Implicit in all of the method descriptions above is the construction of the
+complete filenames by the implementation method.  By convention, pcap traces
+taken for devices in the @code{ns-3} system are of the form 
+``<prefix>-<node id>-<device id>.pcap''.  In the case of protocol traces,
+there is a one-to-one correspondence between protocols and @code{Nodes}.
+This is because protocol @code{Objects} are aggregated to @code{Node Objects}.
+Since there is no global protocol id in the system, we use the corresponding
+node id in file naming.  Threfore there is a possibility for file name 
+collisions in automatically chosen trace file names.  For this reason, the
+file name convention is changed for protocol traces.
+
+As previously mentioned, every node in the system will have a system-assigned
+node id.  Since there is a one-to-one correspondence between protocol instances
+and node instances we use the node id.  Each interface has an interface id 
+relative to its protocol.  We use the convention 
+"<prefix>-n<node id>-i<interface id>.pcap" for trace file naming in protocol
+helpers.
+
+Therefore, by default, a pcap trace file created as a result of enabling tracing
+on interface 1 of the Ipv4 protocol of node 21 using the prefix ``prefix''
+would be ``prefix-n21-i1.pcap''.
+
+You can always use the @code{ns-3} object name service to make this more clear.
+For example, if you use the object name service to assign the name ``serverIpv4''
+to the Ptr<Ipv4> on node 21, the resulting pcap trace file name will 
+automatically become, ``prefix-nserverIpv4-i1.pcap''.
+
+@subsection Ascii Tracing Protocol Helpers
+
+The behavior of the ascii trace helpers is substantially similar to the pcap
+case.  Take a look at @code{src/helper/trace-helper.h} if you want to 
+follow the discussion while looking at real code.
+
+In this section we will be illustrating the methods as applied to the protocol
+@code{Ipv4}.  To specify traces in similar protocols, just substitute the
+appropriate type.  For example, use a @code{Ptr<Ipv6>} instead of a
+@code{Ptr<Ipv4>} and call @code{EnableAsciiIpv6} instead of @code{EnableAsciiIpv4}.
+
+The class @code{PcapAndAsciiHelperForIpv4} adds the high level functionality
+for using ascii tracing to the PcapHelperForIpv4.  Every protocol must 
+additionally implement a single virtual method inherited from this class.
+
+@verbatim
+  virtual void EnableAsciiIpv4Internal (Ptr<OutputStreamWrapper> stream, std::string prefix, 
+                                        Ptr<Ipv4> ipv4, uint32_t interface) = 0;
+@end verbatim
+
+The signature of this method reflects the protocol- and interface-centric view 
+of the situation at this level; and also the fact that the helper may be writing
+to a shared output stream.  All of the public methods inherited from class 
+@code{PcapAndAsciiTraceHelperForIpv4} reduce to calling this single device-
+dependent implementation method.  For example, the lowest level ascii trace
+methods,
+
+@verbatim
+  void EnableAsciiIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface);
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, Ptr<Ipv4> ipv4, uint32_t interface);
+@verbatim
+
+will call the device implementation of @code{EnableAsciiIpv4Internal} directly,
+providing either the prefix or the stream.  All other public ascii tracing 
+methods will build on these low-level functions to provide additional user-level
+functionality.  What this means to the user is that all device helpers in the 
+system will have all of the ascii trace methods available; and these methods
+will all work in the same way across protocols if the protocols implement 
+@code{EnablAsciiIpv4Internal} correctly.
+
+@subsubsection Ascii Tracing Device Helper Methods
+
+@verbatim
+  void EnableAsciiIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface);
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, Ptr<Ipv4> ipv4, uint32_t interface);
+
+  void EnableAsciiIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface);
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, std::string ipv4Name, uint32_t interface);
+
+  void EnableAsciiIpv4 (std::string prefix, Ipv4InterfaceContainer c);
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, Ipv4InterfaceContainer c);
+
+  void EnableAsciiIpv4 (std::string prefix, NodeContainer n);
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, NodeContainer n);
+
+  void EnableAsciiIpv4 (std::string prefix, uint32_t nodeid, uint32_t deviceid);
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, uint32_t nodeid, uint32_t interface);
+
+  void EnableAsciiIpv4All (std::string prefix);
+  void EnableAsciiIpv4All (Ptr<OutputStreamWrapper> stream);
+@end verbatim
+
+You are encouraged to peruse the Doxygen for class @code{PcapAndAsciiHelperForIpv4}
+to find the details of these methods; but to summarize ...
+
+There are twice as many methods available for ascii tracing as there were for
+pcap tracing.  This is because, in addition to the pcap-style model where traces
+from each unique protocol/interface pair are written to a unique file, we 
+support a model in which trace information for many protocol/interface pairs is 
+written to a common file.  This means that the <prefix>-n<node id>-<interface>
+file name generation mechanism is replaced by a mechanism to refer to a common 
+file; and the number of API methods is doubled to allow all combinations.
+
+Just as in pcap tracing, you can enable ascii tracing on a particular 
+protocol/interface pair by providing a @code{Ptr<Ipv4>} and an @code{interface}
+to an @code{EnableAscii} method.
+For example, 
+
+@verbatim
+  Ptr<Ipv4> ipv4;
+  ...
+  helper.EnableAsciiIpv4 ("prefix", ipv4, 1);
+@end verbatim
+
+In this case, no trace contexts are written to the ascii trace file since they
+would be redundant.  The system will pick the file name to be created using
+the same rules as described in the pcap section, except that the file will
+have the suffix ``.tr'' instead of ``.pcap''.
+
+If you want to enable ascii tracing on more than one interface and have all 
+traces sent to a single file, you can do that as well by using an object to
+refer to a single file.  We have already something similar to this in the
+``cwnd'' example above:
+
+@verbatim
+  Ptr<Ipv4> protocol1 = node1->GetObject<Ipv4> ();
+  Ptr<Ipv4> protocol2 = node2->GetObject<Ipv4> ();
+  ...
+  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
+  ...
+  helper.EnableAsciiIpv4 (stream, protocol1, 1);
+  helper.EnableAsciiIpv4 (stream, protocol2, 1);
+@verbatim
+
+In this case, trace contexts are written to the ascii trace file since they
+are required to disambiguate traces from the two interfaces.  Note that since 
+the user is completely specifying the file name, the string should include the
+``,tr'' for consistency.
+
+You can enable ascii tracing on a particular protocol by providing a 
+@code{std::string} representing an object name service string to an 
+@code{EnablePcap} method.  The @code{Ptr<Ipv4>} is looked up from the name
+string.  The @code<Node> in the resulting filenames is implicit since there
+is a one-to-one correspondence between protocol instances and nodes,
+For example, 
+
+@verbatim
+  Names::Add ("node1Ipv4" ...);
+  Names::Add ("node2Ipv4" ...);
+  ...
+  helper.EnableAsciiIpv4 ("prefix", "node1Ipv4", 1);
+  helper.EnableAsciiIpv4 ("prefix", "node2Ipv4", 1);
+@end verbatim
+
+This would result in two files named ``prefix-nnode1Ipv4-i1.tr'' and 
+``prefix-nnode2Ipv4-i1.tr'' with traces for each interface in the respective 
+trace file.  Since all of the EnableAscii functions are overloaded to take a 
+stream wrapper, you can use that form as well:
+
+@verbatim
+  Names::Add ("node1Ipv4" ...);
+  Names::Add ("node2Ipv4" ...);
+  ...
+  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
+  ...
+  helper.EnableAsciiIpv4 (stream, "node1Ipv4", 1);
+  helper.EnableAsciiIpv4 (stream, "node2Ipv4", 1);
+@end verbatim
+
+This would result in a single trace file called ``trace-file-name.tr'' that 
+contains all of the trace events for both interfaces.  The events would be 
+disambiguated by trace context strings.
+
+You can enable ascii tracing on a collection of protocol/interface pairs by 
+providing an @code{Ipv4InterfaceContainer}.  For each protocol of the proper 
+type (the same type as is managed by the device helper), tracing is enabled
+for the corresponding interface.  Again, the @code<Node> is implicit since 
+there is a one-to-one correspondence between each protocol and its node.
+For example, 
+
+@verbatim
+  NodeContainer nodes;
+  ...
+  NetDeviceContainer devices = deviceHelper.Install (nodes);
+  ... 
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer interfaces = ipv4.Assign (devices);
+  ...
+  ...
+  helper.EnableAsciiIpv4 ("prefix", interfaces);
+@end verbatim
+
+This would result in a number of ascii trace files being created, each of which
+follows the <prefix>-n<node id>-i<interface>.tr convention.  Combining all of the
+traces into a single file is accomplished similarly to the examples above:
+
+@verbatim
+  NodeContainer nodes;
+  ...
+  NetDeviceContainer devices = deviceHelper.Install (nodes);
+  ... 
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer interfaces = ipv4.Assign (devices);
+  ...
+  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
+  ...
+  helper.EnableAsciiIpv4 (stream, interfaces);
+@end verbatim
+
+You can enable ascii tracing on a collection of protocol/interface pairs by 
+providing a @code{NodeContainer}.  For each @code{Node} in the @code{NodeContainer}
+the appropriate protocol is found.  For each protocol, its interfaces are 
+enumerated and tracing is enabled on the resulting pairs.  For example,
+
+@verbatim
+  NodeContainer n;
+  ...
+  helper.EnableAsciiIpv4 ("prefix", n);
+@end verbatim
+
+This would result in a number of ascii trace files being created, each of which
+follows the <prefix>-<node id>-<device id>.tr convention.  Combining all of the
+traces into a single file is accomplished similarly to the examples above:
+
+You can enable pcap tracing on the basis of node ID and device ID as well.  In
+this case, the node-id is translated to a @code{Ptr{Node} and the appropriate
+protocol is looked up in the node.  The resulting protocol and interface are
+used to specify the resulting trace source.
+
+@verbatim
+  helper.EnableAsciiIpv4 ("prefix", 21, 1);
+@end verbatim
+
+Of course, the traces can be combined into a single file as shown above.
+
+Finally, you can enable ascii tracing for all interfaces in the system, with
+associated protocol being the same type as that managed by the device helper.
+
+@verbatim
+  helper.EnableAsciiIpv4All ("prefix");
+@end verbatim
+
+This would result in a number of ascii trace files being created, one for
+every interface in the system related to a protocol of the type managed by the
+helper.  All of these files will follow the <prefix>-n<node id>-i<interface.tr
+convention.  Combining all of the traces into a single file is accomplished 
+similarly to the examples above.
+
+@subsubsection Ascii Tracing Device Helper Filename Selection
+
+Implicit in the prefix-style method descriptions above is the construction of the
+complete filenames by the implementation method.  By convention, ascii traces
+in the @code{ns-3} system are of the form ``<prefix>-<node id>-<device id>.tr''
+
+As previously mentioned, every node in the system will have a system-assigned
+node id.  Since there is a one-to-one correspondence between protocols and nodes
+we use to node-id to identify the protocol identity.  Every interface on a 
+given rotocol will have an interface index (also called simply an interface) 
+relative to its protocol.  By default, then, an ascii trace file created as a result
+of enabling tracing on the first device of node 21, using the prefix ``prefix'',
+would be ``prefix-n21-i1.tr''.  Use the prefix to disambiguate multiple protocols
+per node.
+
+You can always use the @code{ns-3} object name service to make this more clear.
+For example, if you use the object name service to assign the name ``serverIpv4''
+to the protocol on node 21, and also specify interface one, the resulting ascii 
+trace file name will automatically become, ``prefix-nserverIpv4-1.tr''.
+
+@c ============================================================================
+@c Summary
+@c ============================================================================
+@node Summary
+@section Summary
+
+@code{ns-3} includes an extremely rich environment allowing users at several 
+levels to customize the kinds of information that can be extracted from 
+simulations.  
+
+There are high-level helper functions that allow users to simply control the 
+collection of pre-defined outputs to a fine granularity.  There are mid-level
+helper functions to allow more sophisticated users to customize how information
+is extracted and saved; and there are low-level core functions to allow expert
+users to alter the system to present new and previously unexported information
+in a way that will be immediatly accessible to users at higher levels.
+
+This is a very comprehensive system, and we realize that it is a lot to 
+digest, especially for new users or those not intimately familiar with C++
+and its idioms.  We do consider the tracing system a very important part of
+@code{ns-3} and so recommend becoming as familiar as possible with it.  It is
+probably the case that understanding the rest of the @code{ns-3} system will
+be quite simple once you have mastered the tracing system
--- a/doc/tutorial/tweaking.texi	Thu Feb 25 13:51:59 2010 +0100
+++ b/doc/tutorial/tweaking.texi	Thu Feb 25 14:17:21 2010 +0100
@@ -812,32 +812,30 @@
 
 @cindex tracing packets
 Let's just jump right in and add some ASCII tracing output to our 
-@code{scratch/myfirst.cc} script.  
-
-The first thing you need to do is to add the following include to the top of
-the script just after the GNU GPL comment:
-
-@verbatim
-  #include <fstream>
-@end verbatim
-
-Then, right before the call to @code{Simulator::Run ()}, add the
-following lines of code:
+@code{scratch/myfirst.cc} script.  Right before the call to 
+@code{Simulator::Run ()}, add the following line of code:
 
 @verbatim
-  std::ofstream ascii;
-  ascii.open ("myfirst.tr");
-  PointToPointHelper::EnableAsciiAll (ascii);
+  pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));
 @end verbatim
 
-The first two lines are just vanilla C++ code to open a stream that will be
-written to a file named ``myfirst.tr''.  See your favorite C++ tutorial if you
-are unfamiliar with this code.  The last line of code in the snippet above
-tells @command{ns-3} that you want to enable ASCII tracing on all 
-point-to-point devices in your simulation; and you want the (provided) trace
-sinks to write out information about packet movement in ASCII format to the 
-stream provided. For those familiar with @command{ns-2}, the traced events are
-equivalent to the popular trace points that log "+", "-", "d", and "r" events.
+This line of code contains two nested method calls.  The inside method,
+@code{CreateFileStream()} uses an unnamed object idiom to create a file stream
+object on the stack (without an object  name) and pass it down to the called 
+method.  We'll go into this more in the future, but all you have to know at 
+this point is that you are creating an object representing a file named 
+``myfirst.tr'' and passing it into @code{ns-3}.  You are telling @code{ns-3} 
+to deal with the lifetime issues of the created object and also to deal with 
+problems caused by a little-known (intentional) limitation of C++ ofstream
+objects relating to copy constructors.
+
+The outside call, to @code{EnableAsciiAll()}, tells the helper that you 
+want to enable ASCII tracing on all point-to-point devices in your simulation; 
+and you want the (provided) trace sinks to write out information about packet 
+movement in ASCII format.
+
+For those familiar with @command{ns-2}, the traced events are equivalent to 
+the popular trace points that log "+", "-", "d", and "r" events.
 
 You can now build the script and run it from the command line:
 
@@ -984,7 +982,7 @@
 The code used to enable pcap tracing is a one-liner.  
 
 @verbatim
-  PointToPointHelper::EnablePcapAll ("myfirst");
+  pointToPoint.EnablePcapAll ("myfirst");
 @end verbatim
 
 Go ahead and insert this line of code after the ASCII tracing code we just 
@@ -993,7 +991,7 @@
 parameter is a prefix, not a complete file name.  The helper will actually 
 create a trace file for every point-to-point device in the simulation.  The 
 file names will be built using the prefix, the node number, the device number
- and a ``.pcap'' suffix.
+and a ``.pcap'' suffix.
 
 In our example script, we will eventually see files named ``myfirst-0-0.pcap'' 
 and ``myfirst-1-0.pcap'' which are the pcap traces for node 0-device 0 and 
--- a/examples/csma/csma-bridge-one-hop.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/csma/csma-bridge-one-hop.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -209,23 +209,23 @@
   sink2.Start (Seconds (1.1));
   sink2.Stop (Seconds (10.0));
 
+  NS_LOG_INFO ("Configure Tracing.");
+
   //
   // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
   // Trace output will be sent to the file "csma-bridge-one-hop.tr"
   //
-  NS_LOG_INFO ("Configure Tracing.");
-  std::ofstream ascii;
-  ascii.open ("csma-bridge-one-hop.tr");
-  CsmaHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("csma-bridge-one-hop.tr"));
 
   //
   // Also configure some tcpdump traces; each interface will be traced.
   // The output files will be named:
-  //     csma-bridge-<nodeId>-<interfaceId>.pcap
+  //     csma-bridge-one-hop-<nodeId>-<interfaceId>.pcap
   // and can be read by the "tcpdump -r" command (use "-tt" option to
   // display timestamps correctly)
   //
-  CsmaHelper::EnablePcapAll ("csma-bridge-one-hop", false);
+  csma.EnablePcapAll ("csma-bridge-one-hop", false);
 
   //
   // Now, do the actual simulation.
--- a/examples/csma/csma-bridge.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/csma/csma-bridge.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -137,15 +137,14 @@
   app = sink.Install (terminals.Get (0));
   app.Start (Seconds (0.0));
 
+  NS_LOG_INFO ("Configure Tracing.");
 
   //
   // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
   // Trace output will be sent to the file "csma-bridge.tr"
   //
-  NS_LOG_INFO ("Configure Tracing.");
-  std::ofstream ascii;
-  ascii.open ("csma-bridge.tr");
-  CsmaHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("csma-bridge.tr"));
 
   //
   // Also configure some tcpdump traces; each interface will be traced.
@@ -154,7 +153,7 @@
   // and can be read by the "tcpdump -r" command (use "-tt" option to
   // display timestamps correctly)
   //
-  CsmaHelper::EnablePcapAll ("csma-bridge", false);
+  csma.EnablePcapAll ("csma-bridge", false);
 
   //
   // Now, do the actual simulation.
--- a/examples/csma/csma-bridge.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/csma/csma-bridge.py	Thu Feb 25 14:17:21 2010 +0100
@@ -134,7 +134,7 @@
     # and can be read by the "tcpdump -r" command(use "-tt" option to
     # display timestamps correctly)
     #
-    ns3.CsmaHelper.EnablePcapAll("csma-bridge", False)
+    csma.EnablePcapAll("csma-bridge", False)
 
     #
     # Now, do the actual simulation.
--- a/examples/csma/csma-broadcast.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/csma/csma-broadcast.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -107,14 +107,17 @@
   app.Start (Seconds (1.0));
   app.Stop (Seconds (10.0));
 
+  // Configure ascii tracing of all enqueue, dequeue, and NetDevice receive 
+  // events on all devices.  Trace output will be sent to the file 
+  // "csma-one-subnet.tr"
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("csma-broadcast.tr"));
+
   // Also configure some tcpdump traces; each interface will be traced
   // The output files will be named 
   // csma-broadcast-<nodeId>-<interfaceId>.pcap
   // and can be read by the "tcpdump -tt -r" command 
-  CsmaHelper::EnablePcapAll ("csma-broadcast", false);
-  std::ofstream ascii;
-  ascii.open ("csma-broadcast.tr", std::ios_base::binary | std::ios_base::out);
-  CsmaHelper::EnableAsciiAll (ascii);
+  csma.EnablePcapAll ("csma-broadcast", false);
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();    
--- a/examples/csma/csma-multicast.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/csma/csma-multicast.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -155,22 +155,21 @@
   sinkC.Start (Seconds (1.0));
   sinkC.Stop (Seconds (10.0));
 
-  //
-  // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
   NS_LOG_INFO ("Configure Tracing.");
   //
+  // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
   // Ascii trace output will be sent to the file "csma-multicast.tr"
   //
-  std::ofstream ascii;
-  ascii.open ("csma-multicast.tr",std::ios_base::binary | std::ios_base::out);
-  CsmaHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("csma-multicast.tr"));
 
   // Also configure some tcpdump traces; each interface will be traced.
   // The output files will be named:
   //     csma-multicast-<nodeId>-<interfaceId>.pcap
   // and can be read by the "tcpdump -r" command (use "-tt" option to
   // display timestamps correctly)
-  CsmaHelper::EnablePcapAll ("csma-multicast", false);
+  csma.EnablePcapAll ("csma-multicast", false);
+
   //
   // Now, do the actual simulation.
   //
--- a/examples/csma/csma-one-subnet.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/csma/csma-one-subnet.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -114,22 +114,25 @@
   app = sink.Install (nodes.Get (0));
   app.Start (Seconds (0.0));
 
-//
-// Configure tracing of all enqueue, dequeue, and NetDevice receive events.
-// Trace output will be sent to the file "csma-one-subnet.tr"
+  NS_LOG_INFO ("Configure Tracing.");
 //
-  NS_LOG_INFO ("Configure Tracing.");
-  std::ofstream ascii;
-  ascii.open ("csma-one-subnet.tr", std::ios_base::binary | std::ios_base::out);
-  CsmaHelper::EnableAsciiAll (ascii);
+// Configure ascii tracing of all enqueue, dequeue, and NetDevice receive 
+// events on all devices.  Trace output will be sent to the file 
+// "csma-one-subnet.tr"
+//
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("csma-one-subnet.tr"));
+
 //
 // Also configure some tcpdump traces; each interface will be traced.
 // The output files will be named:
-//     csma-one-subnet-<nodeId>-<interfaceId>.pcap
+//
+//     csma-one-subnet-<node ID>-<device's interface index>.pcap
+//
 // and can be read by the "tcpdump -r" command (use "-tt" option to
 // display timestamps correctly)
 //
-  CsmaHelper::EnablePcapAll ("csma-one-subnet", false);
+  csma.EnablePcapAll ("csma-one-subnet", false);
 //
 // Now, do the actual simulation.
 //
--- a/examples/csma/csma-packet-socket.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/csma/csma-packet-socket.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -14,7 +14,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-// Port of ns-2/tcl/ex/simple.tcl to ns-3
 //
 // Network topology
 //
@@ -22,11 +21,9 @@
 //       |     |    |    |
 //     =====================
 //
-// - CBR/UDP flows from n0 to n1, and from n3 to n0
-// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
-//   (i.e., DataRate of 448,000 bps)
-// - DropTail queues 
-// - Tracing of queues and packet receptions to file "csma-one-subnet.tr"
+// - Packet socket flow from n0 to n3
+// - Default 512 byte packets generated by traffic generator
+//   Trace output will be sent to the csma-packet-socket.tr file
 
 #include <iostream>
 #include <fstream>
@@ -116,9 +113,9 @@
   // Configure tracing of all enqueue, dequeue, and NetDevice receive events
   // Trace output will be sent to the csma-packet-socket.tr file
   NS_LOG_INFO ("Configure Tracing.");
-  std::ofstream os;
-  os.open ("csma-packet-socket.tr", std::ios_base::binary | std::ios_base::out);
-  csma.EnableAsciiAll (os);
+
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("csma-packet-socket.tr"));
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
--- a/examples/csma/csma-ping.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/csma/csma-ping.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -14,19 +14,14 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-// Port of ns-2/tcl/ex/simple.tcl to ns-3
-//
 // Network topology
 //
 //       n0    n1   n2   n3
 //       |     |    |    |
 //     =====================
 //
-// - CBR/UDP flows from n0 to n1, and from n3 to n0
-// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
-//   (i.e., DataRate of 448,000 bps)
-// - DropTail queues 
-// - Tracing of queues and packet receptions to file "csma-one-subnet.tr"
+//  node n0,n1,n3 pings to node n2
+//  node n0 generates protocol 2 (IGMP) to node n3
 
 #include <iostream>
 #include <fstream>
@@ -83,8 +78,6 @@
   ip.SetBase ("192.168.1.0", "255.255.255.0");
   Ipv4InterfaceContainer addresses = ip.Assign (devs);
 
-  // setup global router
-  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
   NS_LOG_INFO ("Create Source");
   Config::SetDefault ("ns3::Ipv4RawSocketImpl::Protocol", StringValue ("2"));
   InetSocketAddress dst = InetSocketAddress (addresses.GetAddress (3));
--- a/examples/csma/csma-raw-ip-socket.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/csma/csma-raw-ip-socket.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -14,19 +14,17 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-// Port of ns-2/tcl/ex/simple.tcl to ns-3
 //
 // Network topology
-//
+//    (sender)         (receiver)
 //       n0    n1   n2   n3
 //       |     |    |    |
 //     =====================
 //
-// - CBR/UDP flows from n0 to n1, and from n3 to n0
-// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
-//   (i.e., DataRate of 448,000 bps)
-// - DropTail queues 
-// - Tracing of queues and packet receptions to file "csma-one-subnet.tr"
+// Node n0 sends data to node n3 over a raw IP socket.  The protocol
+// number used is 2.
+// The default traffic rate is to send 1250 bytes/second for 10 kb/s 
+// The data rate can be toggled by command line argument
 
 #include <iostream>
 #include <fstream>
@@ -44,7 +42,9 @@
 
 static void SinkRx (Ptr<const Packet> p, const Address &ad)
 {
-  //std::cout << *p << std::endl;
+  // Enable the below line to see the packet contents printed out at the
+  // receive sink
+  //std::cout << Simulator::Now().GetSeconds () << " " << *p << std::endl;
 }
 
 int
@@ -53,8 +53,9 @@
 #if 0 
   LogComponentEnable ("CsmaPacketSocketExample", LOG_LEVEL_INFO);
 #endif
-
+  uint32_t dataRate = 10;
   CommandLine cmd;
+  cmd.AddValue ("dataRate", "application dataRate (Kb/s)", dataRate);
   cmd.Parse (argc, argv);
 
   // Here, we will explicitly create four nodes.
@@ -82,23 +83,24 @@
   Ipv4InterfaceContainer addresses = ip.Assign (devs);
 
   NS_LOG_INFO ("Create Source");
+  // IP protocol configuration
   Config::SetDefault ("ns3::Ipv4RawSocketImpl::Protocol", StringValue ("2"));
   InetSocketAddress dst = InetSocketAddress (addresses.GetAddress (3));
   OnOffHelper onoff = OnOffHelper ("ns3::Ipv4RawSocketFactory", dst);
   onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1.0)));
   onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0)));
-  onoff.SetAttribute ("DataRate", DataRateValue (DataRate (6000)));
-  onoff.SetAttribute ("PacketSize", UintegerValue (1200));
+  onoff.SetAttribute ("DataRate", DataRateValue (DataRate (dataRate*1000)));
+  onoff.SetAttribute ("PacketSize", UintegerValue (1250));
 
   ApplicationContainer apps = onoff.Install (c.Get (0));
-  apps.Start (Seconds (1.0));
-  apps.Stop (Seconds (10.0));
+  apps.Start (Seconds (0.5));
+  apps.Stop (Seconds (11));
 
   NS_LOG_INFO ("Create Sink.");
   PacketSinkHelper sink = PacketSinkHelper ("ns3::Ipv4RawSocketFactory", dst);
   apps = sink.Install (c.Get (3));
   apps.Start (Seconds (0.0));
-  apps.Stop (Seconds (11.0));
+  apps.Stop (Seconds (12.0));
 
   NS_LOG_INFO ("Configure Tracing.");
   // first, pcap tracing in non-promiscuous mode
--- a/examples/csma/csma-star.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/csma/csma-star.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -182,7 +182,7 @@
   //
   // Do pcap tracing on all devices on all nodes.
   //
-  CsmaHelper::EnablePcapAll ("csma-star", false);
+  csma.EnablePcapAll ("csma-star", false);
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
--- a/examples/emulation/emu-ping.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/emulation/emu-ping.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -203,7 +203,8 @@
   //
   // Enable a promiscuous pcap trace to see what is coming and going on our device.
   //
-  EmuHelper::EnablePcap ("emu-ping", device, true);
+  EmuHelper emu;
+  emu.EnablePcap ("emu-ping", device, true);
 
   //
   // Now, do the actual emulation.
--- a/examples/emulation/emu-udp-echo.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/emulation/emu-udp-echo.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -150,7 +150,7 @@
 
   std::ofstream ascii;
   ascii.open ("emu-udp-echo.tr");
-  EmuHelper::EnablePcapAll ("emu-udp-echo", true);
+  emu.EnablePcapAll ("emu-udp-echo", true);
 
   //
   // Now, do the actual simulation.
--- a/examples/error-model/simple-error-model.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/error-model/simple-error-model.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -13,12 +13,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * ns-2 simple.tcl script (ported from ns-2)
- * Originally authored by Steve McCanne, 12/19/1996
  */
 
-// Port of ns-2/tcl/ex/simple.tcl to ns-3
-//
 // Network topology
 //
 //  n0
@@ -166,10 +162,9 @@
   pem->SetList (sampleList);
   d0d2.Get (1)->SetAttribute ("ReceiveErrorModel", PointerValue (pem));
 
-  std::ofstream ascii;
-  ascii.open ("simple-error-model.tr");
-  PointToPointHelper::EnablePcapAll ("simple-error-model");
-  PointToPointHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  p2p.EnableAsciiAll (ascii.CreateFileStream ("simple-error-model.tr"));
+  p2p.EnablePcapAll ("simple-error-model");
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();    
--- a/examples/ipv6/fragmentation-ipv6.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/ipv6/fragmentation-ipv6.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -150,10 +150,9 @@
   apps.Start (Seconds (2.0));
   apps.Stop (Seconds (20.0));
 
-  std::ofstream ascii;
-  ascii.open ("fragmentation-ipv6.tr");
-  CsmaHelper::EnablePcapAll (std::string ("fragmentation-ipv6"), true);
-  CsmaHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("fragmentation-ipv6.tr"));
+  csma.EnablePcapAll (std::string ("fragmentation-ipv6"), true);
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
--- a/examples/ipv6/icmpv6-redirect.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/ipv6/icmpv6-redirect.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -173,10 +173,9 @@
   apps.Start (Seconds (2.0));
   apps.Stop (Seconds (10.0));
 
-  std::ofstream ascii;
-  ascii.open ("icmpv6-redirect.tr");
-  CsmaHelper::EnablePcapAll ("icmpv6-redirect", true);
-  CsmaHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("icmpv6-redirect.tr"));
+  csma.EnablePcapAll ("icmpv6-redirect", true);
 
   /* Now, do the actual simulation. */
   NS_LOG_INFO ("Run Simulation.");
--- a/examples/ipv6/loose-routing-ipv6.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/ipv6/loose-routing-ipv6.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -158,10 +158,9 @@
   apps.Start (Seconds (1.0));
   apps.Stop (Seconds (10.0));
 
-  std::ofstream ascii;
-  ascii.open ("loose-routing-ipv6.tr");
-  CsmaHelper::EnablePcapAll ("loose-routing-ipv6", true);
-  CsmaHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("loose-routing-ipv6.tr"));
+  csma.EnablePcapAll ("loose-routing-ipv6", true);
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
--- a/examples/ipv6/ping6.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/ipv6/ping6.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -98,10 +98,9 @@
   apps.Start (Seconds (2.0));
   apps.Stop (Seconds (10.0));
 
-  std::ofstream ascii;
-  ascii.open ("ping6.tr");
-  CsmaHelper::EnablePcapAll (std::string ("ping6"), true);
-  CsmaHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("ping6.tr"));
+  csma.EnablePcapAll (std::string ("ping6"), true);
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
--- a/examples/ipv6/radvd-two-prefix.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/ipv6/radvd-two-prefix.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -208,10 +208,9 @@
   /* at the end, RA addresses and routes should be cleared */
   Simulator::Schedule (Seconds (10.0), &StackHelper::PrintRoutingTable, &stackHelper, n0); 
 
-  std::ofstream ascii;
-  ascii.open ("radvd-two-prefix.tr");
-  CsmaHelper::EnablePcapAll (std::string ("radvd-two-prefix"), true);
-  CsmaHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("radvd-two-prefix.tr"));
+  csma.EnablePcapAll (std::string ("radvd-two-prefix"), true);
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
--- a/examples/ipv6/radvd.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/ipv6/radvd.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -143,10 +143,9 @@
   apps.Start (Seconds (2.0));
   apps.Stop (Seconds (7.0));
 
-  std::ofstream ascii;
-  ascii.open ("radvd.tr");
-  CsmaHelper::EnablePcapAll (std::string ("radvd"), true);
-  CsmaHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("radvd.tr"));
+  csma.EnablePcapAll (std::string ("radvd"), true);
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
--- a/examples/naming/object-names.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/naming/object-names.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -153,6 +153,24 @@
   //
   Config::Connect ("/Names/client/eth0/MacRx", MakeCallback (&RxEvent));
 
+  //
+  // Set up some pcap tracing on the CSMA devices.  The names of the trace 
+  // files will automatically correspond to the object names if present.
+  // In this case, you will find trace files called:
+  //
+  //   object-names-client-eth0.pcap
+  //   object-names-server-eth0.pcap
+  //
+  // since those nodes and devices have had names associated with them.  You
+  // will also see:
+  //
+  //   object-names-2-1.pcap
+  //   object-names-3-1.pcap
+  //
+  // since nodes two and three have no associated names.
+  //
+  csma.EnablePcapAll ("object-names");
+
   Simulator::Run ();
   Simulator::Destroy ();
 }
--- a/examples/realtime/realtime-udp-echo.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/realtime/realtime-udp-echo.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -105,10 +105,9 @@
   apps.Start (Seconds (2.0));
   apps.Stop (Seconds (10.0));
 
-  std::ofstream ascii;
-  ascii.open ("realtime-udp-echo.tr");
-  CsmaHelper::EnablePcapAll ("realtime-udp-echo", false);
-  CsmaHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("realtime-udp-echo.tr"));
+  csma.EnablePcapAll ("realtime-udp-echo", false);
 
   //
   // Now, do the actual simulation.
--- a/examples/routing/dynamic-global-routing.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/routing/dynamic-global-routing.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -190,13 +190,14 @@
   apps2.Stop (Seconds (16.0));
 
 
-  std::ofstream ascii;
-  ascii.open ("dynamic-global-routing.tr", std::ios_base::binary | std::ios_base::out);
-  PointToPointHelper::EnablePcapAll ("dynamic-global-routing");
-  PointToPointHelper::EnableAsciiAll (ascii);
-  CsmaHelper::EnablePcapAll ("dynamic-global-routing", false);
-  CsmaHelper::EnableAsciiAll (ascii);
-  InternetStackHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream ("dynamic-global-routing.tr");
+  p2p.EnableAsciiAll (stream);
+  csma.EnableAsciiAll (stream);
+  internet.EnableAsciiIpv4All (stream);
+
+  p2p.EnablePcapAll ("dynamic-global-routing");
+  csma.EnablePcapAll ("dynamic-global-routing", false);
  
   Ptr<Node> n1 = c.Get (1);
   Ptr<Ipv4> ipv41 = n1->GetObject<Ipv4> ();
--- a/examples/routing/global-injection-slash32.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/routing/global-injection-slash32.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -146,10 +146,9 @@
   apps.Start (Seconds (1.0));
   apps.Stop (Seconds (10.0));
 
-  std::ofstream ascii;
-  ascii.open ("global-routing-injection32.tr", std::ios_base::binary | std::ios_base::out);
-  PointToPointHelper::EnablePcapAll ("global-routing-injection32");
-  PointToPointHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  p2p.EnableAsciiAll (ascii.CreateFileStream ("global-routing-injection32.tr"));
+  p2p.EnablePcapAll ("global-routing-injection32");
 
   Simulator::Run ();
   Simulator::Destroy ();
--- a/examples/routing/global-routing-slash32.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/routing/global-routing-slash32.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -119,10 +119,9 @@
   apps.Start (Seconds (1.0));
   apps.Stop (Seconds (10.0));
 
-  std::ofstream ascii;
-  ascii.open ("global-routing-slash32.tr", std::ios_base::binary | std::ios_base::out);
-  PointToPointHelper::EnablePcapAll ("global-routing-slash32");
-  PointToPointHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  p2p.EnableAsciiAll (ascii.CreateFileStream ("global-routing-slash32.tr"));
+  p2p.EnablePcapAll ("global-routing-slash32");
 
   Simulator::Run ();
   Simulator::Destroy ();
--- a/examples/routing/mixed-global-routing.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/routing/mixed-global-routing.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -120,13 +120,13 @@
   apps.Start (Seconds (1.0));
   apps.Stop (Seconds (10.0));
 
-  std::ofstream ascii;
-  ascii.open ("mixed-global-routing.tr");
-  PointToPointHelper::EnablePcapAll ("mixed-global-routing");
-  PointToPointHelper::EnableAsciiAll (ascii);
-  CsmaHelper::EnablePcapAll ("mixed-global-routing", false);
-  CsmaHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream ("mixed-global-routing.tr");
+  p2p.EnableAsciiAll (stream);
+  csma.EnableAsciiAll (stream);
 
+  p2p.EnablePcapAll ("mixed-global-routing");
+  csma.EnablePcapAll ("mixed-global-routing", false);
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
--- a/examples/routing/simple-alternate-routing.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/routing/simple-alternate-routing.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -152,10 +152,9 @@
   apps.Start (Seconds (1.1));
   apps.Stop (Seconds (10.0));
 
-  std::ofstream ascii;
-  ascii.open ("simple-alternate-routing.tr");
-  PointToPointHelper::EnablePcapAll ("simple-alternate-routing");
-  PointToPointHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  p2p.EnableAsciiAll (ascii.CreateFileStream ("simple-alternate-routing.tr"));
+  p2p.EnablePcapAll ("simple-alternate-routing");
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
--- a/examples/routing/simple-global-routing.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/routing/simple-global-routing.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -13,11 +13,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * ns-2 simple.tcl script (ported from ns-2)
- * Originally authored by Steve McCanne, 12/19/1996
  */
 
-// Port of ns-2/tcl/ex/simple.tcl to ns-3
 //
 // Network topology
 //
@@ -145,10 +142,9 @@
   apps.Start (Seconds (1.1));
   apps.Stop (Seconds (10.0));
 
-  std::ofstream ascii;
-  ascii.open ("simple-global-routing.tr");
-  PointToPointHelper::EnablePcapAll ("simple-global-routing");
-  PointToPointHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  p2p.EnableAsciiAll (ascii.CreateFileStream ("simple-global-routing.tr"));
+  p2p.EnablePcapAll ("simple-global-routing");
 
   // Flow Monitor
   Ptr<FlowMonitor> flowmon;
--- a/examples/routing/simple-point-to-point-olsr.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/routing/simple-point-to-point-olsr.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -13,11 +13,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * ns-2 simple.tcl script (ported from ns-2)
- * Originally authored by Steve McCanne, 12/19/1996
  */
 
-// Port of ns-2/tcl/ex/simple.tcl to ns-3
+//
+// Simple example of OLSR routing over some point-to-point links
 //
 // Network topology
 //
@@ -157,10 +156,9 @@
   apps.Start (Seconds (1.1));
   apps.Stop (Seconds (10.0));
 
-  std::ofstream ascii;
-  ascii.open ("simple-point-to-point-olsr.tr");
-  PointToPointHelper::EnablePcapAll ("simple-point-to-point-olsr");
-  PointToPointHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  p2p.EnableAsciiAll (ascii.CreateFileStream ("simple-point-to-point-olsr.tr"));
+  p2p.EnablePcapAll ("simple-point-to-point-olsr");
 
   Simulator::Stop (Seconds (30));
 
--- a/examples/routing/simple-routing-ping6.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/routing/simple-routing-ping6.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -151,10 +151,9 @@
   apps.Start (Seconds (2.0));
   apps.Stop (Seconds (20.0));
 
-  std::ofstream ascii;
-  ascii.open ("simple-routing-ping6.tr");
-  CsmaHelper::EnablePcapAll (std::string ("simple-routing-ping6"), true);
-  CsmaHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("simple-routing-ping6.tr"));
+  csma.EnablePcapAll ("simple-routing-ping6", true);
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
--- a/examples/routing/static-routing-slash32.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/routing/static-routing-slash32.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -124,10 +124,9 @@
   apps.Start (Seconds (1.0));
   apps.Stop (Seconds (10.0));
 
-  std::ofstream ascii;
-  ascii.open ("static-routing-slash32.tr");
-  PointToPointHelper::EnablePcapAll ("static-routing-slash32");
-  PointToPointHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  p2p.EnableAsciiAll (ascii.CreateFileStream ("static-routing-slash32.tr"));
+  p2p.EnablePcapAll ("static-routing-slash32");
 
   Simulator::Run ();
   Simulator::Destroy ();
--- a/examples/socket/socket-bound-static-routing.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/socket/socket-bound-static-routing.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -145,10 +145,9 @@
   dstSocket->Bind (dst);
   dstSocket->SetRecvCallback (MakeCallback (&dstSocketRecv));
   
-  std::ofstream ascii;
-  ascii.open ("socket-bound-static-routing.tr");
-  PointToPointHelper::EnablePcapAll ("socket-bound-static-routing");
-  PointToPointHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  p2p.EnableAsciiAll (ascii.CreateFileStream ("socket-bound-static-routing.tr"));
+  p2p.EnablePcapAll ("socket-bound-static-routing");
 
   LogComponentEnableAll (LOG_PREFIX_TIME);
   LogComponentEnable ("SocketBoundRoutingExample", LOG_LEVEL_INFO);
--- a/examples/socket/socket-bound-tcp-static-routing.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/socket/socket-bound-tcp-static-routing.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -161,10 +161,9 @@
   apps.Start (Seconds (0.0));
   apps.Stop (Seconds (10.0));
   
-  std::ofstream ascii;
-  ascii.open ("socket-bound-tcp-static-routing.tr");
-  PointToPointHelper::EnablePcapAll ("socket-bound-tcp-static-routing");
-  PointToPointHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  p2p.EnableAsciiAll (ascii.CreateFileStream ("socket-bound-tcp-static-routing.tr"));
+  p2p.EnablePcapAll ("socket-bound-tcp-static-routing");
 
   LogComponentEnableAll (LOG_PREFIX_TIME);
   LogComponentEnable ("SocketBoundTcpRoutingExample", LOG_LEVEL_INFO);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/tap/lxc-left.conf	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,7 @@
+# Container with network virtualized using a pre-configured bridge named br-left and
+# veth pair virtual network devices
+lxc.utsname = left
+lxc.network.type = veth
+lxc.network.flags = up
+lxc.network.link = br-left
+lxc.network.ipv4 = 10.0.0.1/24
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/tap/lxc-right.conf	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,7 @@
+# Container with network virtualized using a pre-configured bridge named br-right and
+# veth pair virtual network devices
+lxc.utsname = right
+lxc.network.type = veth
+lxc.network.flags = up
+lxc.network.link = br-right
+lxc.network.ipv4 = 10.0.0.2/24
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/tap/tap-csma-virtual-machine.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,133 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ */
+
+//
+// This is an illustration of how one could use virtualization techniques to
+// allow running applications on virtual machines talking over simulated
+// networks.
+//
+// The actual steps required to configure the virtual machines can be rather
+// involved, so we don't go into that here.  Please have a look at one of
+// our HOWTOs on the nsnam wiki for more details about how to get the 
+// system confgured.  For an example, have a look at "HOWTO Use Linux 
+// Containers to set up virtual networks" which uses this code as an 
+// example.
+//
+// The configuration you are after is explained in great detail in the 
+// HOWTO, but looks like the following:
+//
+//  +----------+                           +----------+
+//  | virtual  |                           | virtual  |
+//  |  Linux   |                           |  Linux   |
+//  |   Host   |                           |   Host   |
+//  |          |                           |          |
+//  |   eth0   |                           |   eth0   |
+//  +----------+                           +----------+
+//       |                                      |
+//  +----------+                           +----------+
+//  |  Linux   |                           |  Linux   |
+//  |  Bridge  |                           |  Bridge  |
+//  +----------+                           +----------+
+//       |                                      |
+//  +------------+                       +-------------+
+//  | "tap-left" |                       | "tap-right" |
+//  +------------+                       +-------------+
+//       |           n0            n1           |
+//       |       +--------+    +--------+       |
+//       +-------|  tap   |    |  tap   |-------+
+//               | bridge |    | bridge |
+//               +--------+    +--------+
+//               |  CSMA  |    |  CSMA  |
+//               +--------+    +--------+
+//                   |             |     
+//                   |             |     
+//                   |             |     
+//                   ===============
+//                   CSMA LAN 10.0.0
+//
+// The CSMA device on node zero is:  10.0.0.1
+// The CSMA device on node one is:   10.0.0.2
+//
+#include <iostream>
+#include <fstream>
+
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/core-module.h"
+#include "ns3/helper-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("TapCsmaVirtualMachineExample");
+
+int 
+main (int argc, char *argv[])
+{
+  CommandLine cmd;
+  cmd.Parse (argc, argv);
+
+  //
+  // We are interacting with the outside, real, world.  This means we have to 
+  // interact in real-time and therefore means we have to use the real-time
+  // simulator and take the time to calculate checksums.
+  //
+  GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
+  GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
+
+  //
+  // Create two ghost nodes.  The first will represent the virtual machine host
+  // on the left side of the network; and the second will represent the VM on 
+  // the right side.
+  //
+  NodeContainer nodes;
+  nodes.Create (2);
+
+  //
+  // Use a CsmaHelper to get a CSMA channel created, and the needed net 
+  // devices installed on both of the nodes.  The data rate and delay for the
+  // channel can be set through the command-line parser.  For example,
+  //
+  // ./waf --run "tap=csma-virtual-machine --ns3::CsmaChannel::DataRate=10000000"
+  //
+  CsmaHelper csma;
+  NetDeviceContainer devices = csma.Install (nodes);
+
+  //
+  // Use the TapBridgeHelper to connect to the pre-configured tap devices for 
+  // the left side.  We go with "UseBridge" mode since the CSMA devices support
+  // promiscuous mode and can therefore make it appear that the bridge is 
+  // extended into ns-3.  The install method essentially bridges the specified
+  // tap to the specified CSMA device.
+  //
+  TapBridgeHelper tapBridge;
+  tapBridge.SetAttribute ("Mode", StringValue ("UseBridge"));
+  tapBridge.SetAttribute ("DeviceName", StringValue ("tap-left"));
+  tapBridge.Install (nodes.Get (0), devices.Get (0));
+
+  //
+  // Connect the right side tap to the right side CSMA device on the right-side
+  // ghost node.
+  //
+  tapBridge.SetAttribute ("DeviceName", StringValue ("tap-right"));
+  tapBridge.Install (nodes.Get (1), devices.Get (1));
+
+  //
+  // Run the simulation for ten minutes to give the user time to play around
+  //
+  Simulator::Stop (Seconds (600.));
+  Simulator::Run ();
+  Simulator::Destroy ();
+}
--- a/examples/tap/tap-csma.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/tap/tap-csma.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -102,7 +102,7 @@
   tapBridge.SetAttribute ("DeviceName", StringValue (tapName));
   tapBridge.Install (nodes.Get (0), devices.Get (0));
 
-  CsmaHelper::EnablePcapAll ("tap-csma", false);
+  csma.EnablePcapAll ("tap-csma", false);
   Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
 
   Simulator::Stop (Seconds (60.));
--- a/examples/tap/tap-wifi-dumbbell.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/tap/tap-wifi-dumbbell.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -217,7 +217,8 @@
   apps.Start (Seconds (1.0));
 
   wifiPhy.EnablePcapAll ("tap-wifi-dumbbell");
-  CsmaHelper::EnablePcapAll ("tap-wifi-dumbbell", false);
+
+  csmaRight.EnablePcapAll ("tap-wifi-dumbbell", false);
   Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
 
   Simulator::Stop (Seconds (60.));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/tap/tap-wifi-virtual-machine.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,171 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ */
+
+//
+// This is an illustration of how one could use virtualization techniques to
+// allow running applications on virtual machines talking over simulated
+// networks.
+//
+// The actual steps required to configure the virtual machines can be rather
+// involved, so we don't go into that here.  Please have a look at one of
+// our HOWTOs on the nsnam wiki for more details about how to get the 
+// system confgured.  For an example, have a look at "HOWTO Use Linux 
+// Containers to set up virtual networks" which uses this code as an 
+// example.
+//
+// The configuration you are after is explained in great detail in the 
+// HOWTO, but looks like the following:
+//
+//  +----------+                           +----------+
+//  | virtual  |                           | virtual  |
+//  |  Linux   |                           |  Linux   |
+//  |   Host   |                           |   Host   |
+//  |          |                           |          |
+//  |   eth0   |                           |   eth0   |
+//  +----------+                           +----------+
+//       |                                      |
+//  +----------+                           +----------+
+//  |  Linux   |                           |  Linux   |
+//  |  Bridge  |                           |  Bridge  |
+//  +----------+                           +----------+
+//       |                                      |
+//  +------------+                       +-------------+
+//  | "tap-left" |                       | "tap-right" |
+//  +------------+                       +-------------+
+//       |           n0            n1           |
+//       |       +--------+    +--------+       |
+//       +-------|  tap   |    |  tap   |-------+
+//               | bridge |    | bridge |
+//               +--------+    +--------+
+//               |  wifi  |    |  wifi  |
+//               +--------+    +--------+
+//                   |             |     
+//                 ((*))         ((*))
+//
+//                   Wifi LAN 10.0.0
+//
+//                        ((*))
+//                          |
+//                     +--------+
+//                     |  wifi  |
+//                     +--------+
+//                     | access |
+//                     |  point |
+//                     +--------+
+//
+// The wifi device on node zero is:  10.0.0.1
+// The wifi device on node one is:   10.0.0.2
+// The wifi device (AP) is:          10.0.0.3
+//
+#include <iostream>
+#include <fstream>
+
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/core-module.h"
+#include "ns3/wifi-module.h"
+#include "ns3/helper-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("TapWifiVirtualMachineExample");
+
+int 
+main (int argc, char *argv[])
+{
+  CommandLine cmd;
+  cmd.Parse (argc, argv);
+
+  //
+  // We are interacting with the outside, real, world.  This means we have to 
+  // interact in real-time and therefore means we have to use the real-time
+  // simulator and take the time to calculate checksums.
+  //
+  GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
+  GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
+
+  //
+  // Create two ghost nodes.  The first will represent the virtual machine host
+  // on the left side of the network; and the second will represent the VM on 
+  // the right side.
+  //
+  NodeContainer nodes;
+  nodes.Create (2);
+
+  //
+  // We're going to use 802.11 A so set up a wifi helper to reflect that.
+  //
+  WifiHelper wifi = WifiHelper::Default ();
+  wifi.SetStandard (WIFI_PHY_STANDARD_80211a);
+  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue ("wifia-54mbs"));
+
+  //
+  // No reason for pesky access points, so we'll use an ad-hoc network.
+  //
+  NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
+  wifiMac.SetType ("ns3::AdhocWifiMac");
+
+  //
+  // Configure the physcial layer.
+  //
+  YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
+  YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
+  wifiPhy.SetChannel (wifiChannel.Create ());
+
+  //
+  // Install the wireless devices onto our ghost nodes.
+  //
+  NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, nodes);
+
+  //
+  // We need location information since we are talking about wifi, so add a
+  // constant position to the ghost nodes.
+  //
+  MobilityHelper mobility;
+  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
+  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
+  positionAlloc->Add (Vector (5.0, 0.0, 0.0));
+  mobility.SetPositionAllocator (positionAlloc);
+  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+  mobility.Install (nodes);
+
+  //
+  // Use the TapBridgeHelper to connect to the pre-configured tap devices for 
+  // the left side.  We go with "UseLocal" mode since the wifi devices do not
+  // support promiscuous mode (because of their natures0.  This is a special
+  // case mode that allows us to extend a linux bridge into ns-3 IFF we will
+  // only see traffic from one other device on that bridge.  That is the case
+  // for this configuration.
+  //
+  TapBridgeHelper tapBridge;
+  tapBridge.SetAttribute ("Mode", StringValue ("UseLocal"));
+  tapBridge.SetAttribute ("DeviceName", StringValue ("tap-left"));
+  tapBridge.Install (nodes.Get (0), devices.Get (0));
+
+  //
+  // Connect the right side tap to the right side wifi device on the right-side
+  // ghost node.
+  //
+  tapBridge.SetAttribute ("DeviceName", StringValue ("tap-right"));
+  tapBridge.Install (nodes.Get (1), devices.Get (1));
+
+  //
+  // Run the simulation for ten minutes to give the user time to play around
+  //
+  Simulator::Stop (Seconds (600.));
+  Simulator::Run ();
+  Simulator::Destroy ();
+}
--- a/examples/tap/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/tap/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -5,5 +5,9 @@
     if env['ENABLE_TAP']:
         obj = bld.create_ns3_program('tap-csma', ['csma', 'tap-bridge', 'internet-stack'])
         obj.source = 'tap-csma.cc'
+        obj = bld.create_ns3_program('tap-csma-virtual-machine', ['csma', 'tap-bridge', 'internet-stack'])
+        obj.source = 'tap-csma-virtual-machine.cc'
+        obj = bld.create_ns3_program('tap-wifi-virtual-machine', ['csma', 'tap-bridge', 'internet-stack'])
+        obj.source = 'tap-wifi-virtual-machine.cc'
         obj = bld.create_ns3_program('tap-wifi-dumbbell', ['wifi', 'csma', 'point-to-point', 'tap-bridge', 'internet-stack'])
         obj.source = 'tap-wifi-dumbbell.cc'
--- a/examples/tcp/star.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/tcp/star.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -109,7 +109,7 @@
   //
   // Do pcap tracing on all point-to-point devices on all nodes.
   //
-  PointToPointHelper::EnablePcapAll ("star");
+  pointToPoint.EnablePcapAll ("star");
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
--- a/examples/tcp/tcp-large-transfer.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/tcp/tcp-large-transfer.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -168,10 +168,9 @@
   //localSocket->SetAttribute("SndBufSize", UintegerValue(4096));
 
   //Ask for ASCII and pcap traces of network traffic
-  std::ofstream ascii;
-  ascii.open ("tcp-large-transfer.tr");
-  PointToPointHelper::EnableAsciiAll (ascii);
-  PointToPointHelper::EnablePcapAll ("tcp-large-transfer");
+  AsciiTraceHelper ascii;
+  p2p.EnableAsciiAll (ascii.CreateFileStream ("tcp-large-transfer.tr"));
+  p2p.EnablePcapAll ("tcp-large-transfer");
 
   // Finally, set up the simulator to run.  The 1000 second hard limit is a
   // failsafe in case some change above causes the simulation to never end
--- a/examples/tcp/tcp-nsc-lfn.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/tcp/tcp-nsc-lfn.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -42,12 +42,6 @@
 
 NS_LOG_COMPONENT_DEFINE ("TcpNscLfn");
 
-static void 
-CwndTracer (uint32_t oldval, uint32_t newval)
-{
-  NS_LOG_INFO ("Moving cwnd from " << oldval << " to " << newval);
-}
-
 int main (int argc, char *argv[])
 {
 
@@ -137,12 +131,8 @@
       clientApp.Stop (Seconds (runtime + 1.0 + i));
     }
 
-  // Trace changes to the congestion window
-  Config::ConnectWithoutContext ("/NodeList/1/$ns3::NscTcpL4Protocol/SocketList/0/CongestionWindow", 
-                                 MakeCallback (&CwndTracer));
-
   // This tells ns-3 to generate pcap traces.
-  PointToPointHelper::EnablePcapAll ("tcp-nsc-lfn");
+  p2p.EnablePcapAll ("tcp-nsc-lfn");
 
   Simulator::Stop (Seconds(900));
   Simulator::Run ();
--- a/examples/tcp/tcp-nsc-zoo.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/tcp/tcp-nsc-zoo.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -134,7 +134,7 @@
 	}
     }
 
-  CsmaHelper::EnablePcapAll ("tcp-nsc-zoo", false);
+  csma.EnablePcapAll ("tcp-nsc-zoo", false);
 
   Simulator::Stop (Seconds(100));
   Simulator::Run ();
--- a/examples/tcp/tcp-star-server.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/tcp/tcp-star-server.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -153,10 +153,9 @@
 
 
   //configure tracing
-  std::ofstream ascii;
-  ascii.open ("tcp-star-server.tr");
-  PointToPointHelper::EnablePcapAll ("tcp-star-server");
-  PointToPointHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  p2p.EnableAsciiAll (ascii.CreateFileStream ("tcp-star-server.tr"));
+  p2p.EnablePcapAll ("tcp-star-server");
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
--- a/examples/tunneling/virtual-net-device.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/tunneling/virtual-net-device.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -14,8 +14,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Based on simple-global-routing.cc
- * ns-2 simple.tcl script (ported from ns-2)
- * Originally authored by Steve McCanne, 12/19/1996
  */
 
 // Network topology
@@ -289,10 +287,9 @@
   apps.Start (Seconds (1.1));
   //apps.Stop (Seconds (10.0));
 
-  std::ofstream ascii;
-  ascii.open ("virtual-net-device.tr");
-  PointToPointHelper::EnablePcapAll ("virtual-net-device");
-  PointToPointHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  p2p.EnableAsciiAll (ascii.CreateFileStream ("virtual-net-device.tr"));
+  p2p.EnablePcapAll ("virtual-net-device");
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
--- a/examples/tutorial/second.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/tutorial/second.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -103,8 +103,8 @@
 
   Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
 
-  PointToPointHelper::EnablePcapAll ("second");
-  CsmaHelper::EnablePcap ("second", csmaDevices.Get (1), true);
+  pointToPoint.EnablePcapAll ("second");
+  csma.EnablePcap ("second", csmaDevices.Get (1), true);
 
   Simulator::Run ();
   Simulator::Destroy ();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/tutorial/sixth.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,231 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ */
+
+#include <fstream>
+#include "ns3/core-module.h"
+#include "ns3/common-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("SixthScriptExample");
+
+// ===========================================================================
+//
+//         node 0                 node 1
+//   +----------------+    +----------------+
+//   |    ns-3 TCP    |    |    ns-3 TCP    |
+//   +----------------+    +----------------+
+//   |    10.1.1.1    |    |    10.1.1.2    |
+//   +----------------+    +----------------+
+//   | point-to-point |    | point-to-point |
+//   +----------------+    +----------------+
+//           |                     |
+//           +---------------------+
+//                5 Mbps, 2 ms
+//
+//
+// We want to look at changes in the ns-3 TCP congestion window.  We need
+// to crank up a flow and hook the CongestionWindow attribute on the socket
+// of the sender.  Normally one would use an on-off application to generate a
+// flow, but this has a couple of problems.  First, the socket of the on-off 
+// application is not created until Application Start time, so we wouldn't be 
+// able to hook the socket (now) at configuration time.  Second, even if we 
+// could arrange a call after start time, the socket is not public so we 
+// couldn't get at it.
+//
+// So, we can cook up a simple version of the on-off application that does what
+// we want.  On the plus side we don't need all of the complexity of the on-off
+// application.  On the minus side, we don't have a helper, so we have to get
+// a little more involved in the details, but this is trivial.
+//
+// So first, we create a socket and do the trace connect on it; then we pass 
+// this socket into the constructor of our simple application which we then 
+// install in the source node.
+// ===========================================================================
+//
+class MyApp : public Application 
+{
+public:
+
+  MyApp ();
+  virtual ~MyApp();
+
+  void Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate);
+
+private:
+  virtual void StartApplication (void);  
+  virtual void StopApplication (void);
+
+  void ScheduleTx (void);
+  void SendPacket (void);
+
+  Ptr<Socket>     m_socket;
+  Address         m_peer;
+  uint32_t        m_packetSize;
+  uint32_t        m_nPackets;
+  DataRate        m_dataRate;
+  EventId         m_sendEvent;
+  bool            m_running;
+  uint32_t        m_packetsSent;
+};
+
+MyApp::MyApp ()
+  : m_socket (0), 
+    m_peer (), 
+    m_packetSize (0), 
+    m_nPackets (0), 
+    m_dataRate (0), 
+    m_sendEvent (), 
+    m_running (false), 
+    m_packetsSent (0)
+{
+}
+
+MyApp::~MyApp()
+{
+  m_socket = 0;
+}
+
+void
+MyApp::Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate)
+{
+  m_socket = socket;
+  m_peer = address;
+  m_packetSize = packetSize;
+  m_nPackets = nPackets;
+  m_dataRate = dataRate;
+}
+
+void
+MyApp::StartApplication (void)
+{
+  m_running = true;
+  m_packetsSent = 0;
+  m_socket->Bind ();
+  m_socket->Connect (m_peer);
+  SendPacket ();
+}
+
+void 
+MyApp::StopApplication (void)
+{
+  m_running = false;
+
+  if (m_sendEvent.IsRunning ())
+    {
+      Simulator::Cancel (m_sendEvent);
+    }
+
+  if (m_socket)
+    {
+      m_socket->Close ();
+    }
+}
+
+void 
+MyApp::SendPacket (void)
+{
+  Ptr<Packet> packet = Create<Packet> (m_packetSize);
+  m_socket->Send (packet);
+
+  if (++m_packetsSent < m_nPackets)
+    {
+      ScheduleTx ();
+    }
+}
+
+void 
+MyApp::ScheduleTx (void)
+{
+  if (m_running)
+    {
+      Time tNext (Seconds (m_packetSize * 8 / static_cast<double> (m_dataRate.GetBitRate ())));
+      m_sendEvent = Simulator::Schedule (tNext, &MyApp::SendPacket, this);
+    }
+}
+
+static void
+CwndChange (Ptr<OutputStreamWrapper> stream, uint32_t oldCwnd, uint32_t newCwnd)
+{
+  NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
+  *stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
+}
+
+static void
+RxDrop (Ptr<PcapFileWrapper> file, Ptr<const Packet> p)
+{
+  NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
+  file->Write(Simulator::Now(), p);
+}
+
+int 
+main (int argc, char *argv[])
+{
+  NodeContainer nodes;
+  nodes.Create (2);
+
+  PointToPointHelper pointToPoint;
+  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
+
+  NetDeviceContainer devices;
+  devices = pointToPoint.Install (nodes);
+
+  Ptr<RateErrorModel> em = CreateObjectWithAttributes<RateErrorModel> (
+    "RanVar", RandomVariableValue (UniformVariable (0., 1.)),
+    "ErrorRate", DoubleValue (0.00001));
+  devices.Get (1)->SetAttribute ("ReceiveErrorModel", PointerValue (em));
+
+  InternetStackHelper stack;
+  stack.Install (nodes);
+
+  Ipv4AddressHelper address;
+  address.SetBase ("10.1.1.0", "255.255.255.252");
+  Ipv4InterfaceContainer interfaces = address.Assign (devices);
+
+  uint16_t sinkPort = 8080;
+  Address sinkAddress (InetSocketAddress(interfaces.GetAddress (1), sinkPort));
+  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
+  ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (1));
+  sinkApps.Start (Seconds (0.));
+  sinkApps.Stop (Seconds (20.));
+
+  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (nodes.Get (0), TcpSocketFactory::GetTypeId ());
+
+  Ptr<MyApp> app = CreateObject<MyApp> ();
+  app->Setup (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("1Mbps"));
+  nodes.Get (0)->AddApplication (app);
+  app->SetStartTime (Seconds (1.));
+  app->SetStopTime (Seconds (20.));
+
+  AsciiTraceHelper asciiTraceHelper;
+  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("sixth.cwnd");
+  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeBoundCallback (&CwndChange, stream));
+
+  PcapHelper pcapHelper;
+  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile ("sixth.pcap", "w", PcapHelper::DLT_PPP);
+  devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file));
+
+  Simulator::Stop (Seconds(20));
+  Simulator::Run ();
+  Simulator::Destroy ();
+
+  return 0;
+}
+
--- a/examples/tutorial/third.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/tutorial/third.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -162,9 +162,9 @@
 
   Simulator::Stop (Seconds (10.0));
 
-  PointToPointHelper::EnablePcapAll ("third");
+  pointToPoint.EnablePcapAll ("third");
   phy.EnablePcap ("third", apDevices.Get (0));
-  CsmaHelper::EnablePcap ("third", csmaDevices.Get (0), true);
+  csma.EnablePcap ("third", csmaDevices.Get (0), true);
 
   Simulator::Run ();
   Simulator::Destroy ();
--- a/examples/tutorial/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/tutorial/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -18,3 +18,6 @@
 
     obj = bld.create_ns3_program('fifth', ['core', 'simulator', 'point-to-point', 'internet-stack'])
     obj.source = 'fifth.cc'
+
+    obj = bld.create_ns3_program('sixth', ['core', 'simulator', 'point-to-point', 'internet-stack'])
+    obj.source = 'sixth.cc'
--- a/examples/udp/udp-echo.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/udp/udp-echo.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -118,10 +118,9 @@
   client.SetFill(apps.Get (0), fill, sizeof(fill), 1024);
 #endif
 
-  std::ofstream ascii;
-  ascii.open ("udp-echo.tr");
-  CsmaHelper::EnablePcapAll ("udp-echo", false);
-  CsmaHelper::EnableAsciiAll (ascii);
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("udp-echo.tr"));
+  csma.EnablePcapAll ("udp-echo", false);
 
 //
 // Now, do the actual simulation.
--- a/examples/wireless/mixed-wireless.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/wireless/mixed-wireless.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -381,20 +381,26 @@
   /////////////////////////////////////////////////////////////////////////// 
 
   NS_LOG_INFO ("Configure Tracing.");
-  std::ofstream ascii;
   if (enableTracing == true)
    {
-      //
-      // Let's set up some ns-2-like ascii traces, using another helper class
-      //
-      ascii.open ("mixed-wireless.tr");
-      YansWifiPhyHelper::EnableAsciiAll (ascii);
-      CsmaHelper::EnableAsciiAll (ascii);
-      InternetStackHelper::EnableAsciiAll (ascii);
+      CsmaHelper csma;
+
+     //
+     // Let's set up some ns-2-like ascii traces, using another helper class
+     //
+     AsciiTraceHelper ascii;
+     Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream ("mixed-wireless.tr");
+     wifiPhy.EnableAsciiAll (stream);
+     csma.EnableAsciiAll (stream);
+     internet.EnableAsciiIpv4All (stream);
 
       // Let's do a pcap trace on the application source and sink, ifIndex 0
       // Csma captures in non-promiscuous mode
-      CsmaHelper::EnablePcap ("mixed-wireless", appSource->GetId (), 0, false);
+#if 0
+      csma.EnablePcap ("mixed-wireless", appSource->GetId (), 0, false);
+#else
+      csma.EnablePcapAll ("mixed-wireless", false);
+#endif
       wifiPhy.EnablePcap ("mixed-wireless", appSink->GetId (), 0);
       wifiPhy.EnablePcap ("mixed-wireless", 9, 2);
       wifiPhy.EnablePcap ("mixed-wireless", 9, 0);
--- a/examples/wireless/multirate.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/wireless/multirate.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -493,9 +493,8 @@
 
   if (enableTracing)
     {
-      std::ofstream ascii;
-      ascii.open ((GetOutputFileName() + ".tr").c_str());
-      phy.EnableAsciiAll (ascii);
+      AsciiTraceHelper ascii;
+      phy.EnableAsciiAll (ascii.CreateFileStream (GetOutputFileName() + ".tr"));
     }
 
   Ptr<FlowMonitor> flowmon;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/wireless/wifi-blockack.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,141 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * 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: Mirko Banchi <mk.banchi@gmail.com>
+ */
+
+/**
+ * This is a simple example in order to show how 802.11n compressed block ack mechanism could be used.
+ *
+ * Network topology:
+ * 
+ *  Wifi 192.168.1.0
+ * 
+ *        AP
+ *   *    *
+ *   |    |
+ *   n1   n2 
+ *
+ * In this example a QoS sta sends UDP datagram packets to access point. On the access point
+ * there is no application installed so it replies to every packet with an ICMP frame. However
+ * our attention is on originator sta n1. We have set blockAckThreshold (mininum number of packets to use
+ * block ack) to 2 so if there are in the BestEffort queue more than 2 packets a block ack will be
+ * negotiated. We also set a timeout for block ack inactivity to 3 blocks of 1024 microseconds. This timer is
+ * reset when:
+ *    - the originator receives a block ack frame.
+ *    - the recipient receives a block ack request or a MPDU with ack policy Block Ack. 
+ */
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/global-routing-module.h"
+#include "ns3/wifi-module.h"
+#include "ns3/mobility-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("Test-block-ack");
+
+int main (int argc, char const* argv[])
+{
+  LogComponentEnable ("EdcaTxopN", LOG_LEVEL_DEBUG);
+  LogComponentEnable ("BlockAckManager", LOG_LEVEL_INFO);
+ 
+  Ptr<Node> sta = CreateObject<Node> ();
+  Ptr<Node> ap = CreateObject<Node> ();
+  
+  YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
+  YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
+  phy.SetChannel (channel.Create ());
+
+  WifiHelper wifi = WifiHelper::Default ();
+  QosWifiMacHelper mac = QosWifiMacHelper::Default ();
+  /* disable fragmentation */
+  wifi.SetRemoteStationManager ("ns3::AarfWifiManager", "FragmentationThreshold", UintegerValue (2500));
+
+  Ssid ssid ("My-network");
+  
+  mac.SetType ("ns3::QstaWifiMac", "Ssid" , SsidValue (ssid), "ActiveProbing", BooleanValue (false));
+  NetDeviceContainer staDevice = wifi.Install (phy, mac, sta);
+
+  mac.SetType ("ns3::QapWifiMac", "Ssid", SsidValue (ssid), "BeaconGeneration", BooleanValue (true),
+               "BeaconInterval", TimeValue (Seconds (2.5)));
+  NetDeviceContainer apDevice = wifi.Install (phy, mac, ap);
+
+  /* setting blockack threshold for sta's BE queue */
+  Config::Set ("/NodeList/0/DeviceList/0/Mac/BE_EdcaTxopN/BlockAckThreshold", UintegerValue (2));
+  /* setting block inactivity timeout to 3*1024 = 3072 microseconds */ 
+  //Config::Set ("/NodeList/0/DeviceList/0/Mac/BE_EdcaTxopN/BlockAckInactivityTimeout", UintegerValue (3));
+
+  /* Setting mobility model */
+  MobilityHelper mobility;
+
+  mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
+    "MinX", DoubleValue (0.0),
+    "MinY", DoubleValue (0.0),
+    "DeltaX", DoubleValue (5.0),
+    "DeltaY", DoubleValue (10.0),
+    "GridWidth", UintegerValue (3),
+    "LayoutType", StringValue ("RowFirst"));
+
+  mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",
+    "Bounds", RectangleValue (Rectangle (-50, 50, -50, 50)));
+  mobility.Install (sta);
+
+  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+  mobility.Install (ap);
+
+  /* Internet stack*/
+  InternetStackHelper stack;
+  stack.Install (sta);
+  stack.Install (ap);
+  
+  Ipv4AddressHelper address;
+
+  address.SetBase ("192.168.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer staIf;
+  Ipv4InterfaceContainer apIf;
+  staIf = address.Assign (staDevice);
+  apIf = address.Assign (apDevice);
+
+  /* Setting applications */
+  
+  uint16_t port = 9;
+
+  DataRate dataRate ("1Mb/s");
+  OnOffHelper onOff ("ns3::UdpSocketFactory", Address (InetSocketAddress (apIf.GetAddress (0), port)));
+  onOff.SetAttribute ("DataRate", DataRateValue (dataRate));
+  onOff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (0.01)));
+  onOff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (8)));
+  onOff.SetAttribute ("PacketSize", UintegerValue (50));
+
+  ApplicationContainer staApps = onOff.Install (sta);
+
+  staApps.Start (Seconds (1.0));
+  staApps.Stop (Seconds (10.0));
+
+  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+
+  Simulator::Stop (Seconds (10.0));
+
+  phy.EnablePcap ("test-blockack-2", ap->GetId (), 0);
+  Simulator::Run ();
+  Simulator::Destroy ();
+
+  return 0;
+}
--- a/examples/wireless/wifi-simple-adhoc-grid.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/wireless/wifi-simple-adhoc-grid.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -159,8 +159,8 @@
   // This is one parameter that matters when using FixedRssLossModel
   // set it to zero; otherwise, gain will be added
   wifiPhy.Set ("RxGain", DoubleValue (-10) ); 
-  // ns-3 support RadioTap and Prism tracing extensions for 802.11b
-  wifiPhy.SetPcapFormat (YansWifiPhyHelper::PCAP_FORMAT_80211_RADIOTAP); 
+  // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
+  wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO); 
 
   YansWifiChannelHelper wifiChannel ;
   wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
@@ -216,10 +216,10 @@
 
   if (tracing == true)
     {
+      AsciiTraceHelper ascii;
+      wifiPhy.EnableAsciiAll (ascii.CreateFileStream ("wifi-simple-adhoc-grid.tr"));
       wifiPhy.EnablePcap ("wifi-simple-adhoc-grid", devices);
-      std::ofstream ascii;
-      ascii.open ("wifi-simple-adhoc-grid.tr");
-      YansWifiPhyHelper::EnableAsciiAll (ascii);
+
       // To do-- enable an IP-level trace that shows forwarding events only
     }
   
--- a/examples/wireless/wifi-simple-adhoc.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/wireless/wifi-simple-adhoc.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -134,8 +134,8 @@
   // This is one parameter that matters when using FixedRssLossModel
   // set it to zero; otherwise, gain will be added
   wifiPhy.Set ("RxGain", DoubleValue (0) ); 
-  // ns-3 support RadioTap and Prism tracing extensions for 802.11b
-  wifiPhy.SetPcapFormat (YansWifiPhyHelper::PCAP_FORMAT_80211_RADIOTAP); 
+  // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
+  wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO); 
 
   YansWifiChannelHelper wifiChannel ;
   wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
--- a/examples/wireless/wifi-simple-infra.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/wireless/wifi-simple-infra.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -135,8 +135,8 @@
   // This is one parameter that matters when using FixedRssLossModel
   // set it to zero; otherwise, gain will be added
   wifiPhy.Set ("RxGain", DoubleValue (0) ); 
-  // ns-3 support RadioTap and Prism tracing extensions for 802.11b
-  wifiPhy.SetPcapFormat (YansWifiPhyHelper::PCAP_FORMAT_80211_RADIOTAP); 
+  // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
+  wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO); 
 
   YansWifiChannelHelper wifiChannel ;
   wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
--- a/examples/wireless/wifi-simple-interference.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/wireless/wifi-simple-interference.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -180,8 +180,8 @@
   wifiPhy.Set ("RxGain", DoubleValue (0) ); 
   wifiPhy.Set ("CcaMode1Threshold", DoubleValue (0.0) );
 
-  // ns-3 support RadioTap and Prism tracing extensions for 802.11b
-  wifiPhy.SetPcapFormat (YansWifiPhyHelper::PCAP_FORMAT_80211_RADIOTAP); 
+  // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
+  wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO); 
 
   YansWifiChannelHelper wifiChannel ;
   wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
--- a/examples/wireless/wifi-wired-bridging.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/wireless/wifi-wired-bridging.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -90,7 +90,7 @@
   double wifiX = 0.0;
 
   YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
-  wifiPhy.SetPcapFormat(YansWifiPhyHelper::PCAP_FORMAT_80211_RADIOTAP);
+  wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO); 
 
   for (uint32_t i = 0; i < nWifis; ++i)
     {
--- a/examples/wireless/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/examples/wireless/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -34,3 +34,6 @@
 
     obj = bld.create_ns3_program('wifi-simple-interference', ['core', 'simulator', 'mobility', 'wifi'])
     obj.source = 'wifi-simple-interference.cc'
+
+    obj = bld.create_ns3_program('wifi-blockack', ['core', 'simulator', 'mobility', 'wifi'])
+    obj.source = 'wifi-blockack.cc'
--- a/src/applications/udp-client-server/udp-trace-client.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/applications/udp-client-server/udp-trace-client.h	Thu Feb 25 14:17:21 2010 +0100
@@ -61,7 +61,7 @@
 
   /**
    * \brief creates a traceBasedStreamer application
-   * \param dataSize ip the destination ip address to which the stream will be sent
+   * \param ip the destination ip address to which the stream will be sent
    * \param port the destination udp port to which the stream will be sent
    * \param traceFile a path to an MPEG4 trace file formatted as follows:
    *  FrameNo Frametype   Time[ms]    Length [byte]
@@ -83,7 +83,7 @@
 
   /**
    * \brief set the trace file to be used by the application
-   * \param traceFile a path to an MPEG4 trace file formatted as follows:
+   * \param filename a path to an MPEG4 trace file formatted as follows:
    *  Frame No Frametype   Time[ms]    Length [byte]
    *  Frame No Frametype   Time[ms]    Length [byte]
    *  ...
--- a/src/common/ascii-writer.cc	Thu Feb 25 13:51:59 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 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
- *
- * Author: Guillaume Seguin <guillaume@segu.in>
- */
-#include "ascii-writer.h"
-
-#include "ns3/log.h"
-#include "ns3/simulator.h"
-#include "ns3/simulation-singleton.h"
-#include "ns3/packet.h"
-
-#include <fstream>
-#include <map>
-
-
-NS_LOG_COMPONENT_DEFINE ("AsciiWriter");
-
-namespace ns3 {
-
-typedef std::map<std::ostream*, Ptr<AsciiWriter> > AsciiWritersMap;
-
-Ptr<AsciiWriter>
-AsciiWriter::Get (std::ostream &os)
-{
-  AsciiWritersMap *map = SimulationSingleton<AsciiWritersMap>::Get ();
-  Ptr<AsciiWriter> writer = (*map)[&os];
-  if (writer == 0)
-    {
-      // don't call Create<> because constructor is private
-      writer = Ptr<AsciiWriter> (new AsciiWriter (&os), false);
-      (*map)[&os] = writer;
-    }
-  return writer;
-}
-
-AsciiWriter::AsciiWriter (std::ostream *os)
-  : m_writer (os)
-{
-  NS_LOG_FUNCTION (this);
-}
-
-AsciiWriter::~AsciiWriter (void)
-{
-  NS_LOG_FUNCTION (this);
-}
-
-void
-AsciiWriter::WritePacket (enum Type type, std::string message, Ptr<const Packet> packet)
-{
-  std::string typeString;
-  switch (type)
-    {
-    case ENQUEUE:
-      typeString = "+";
-      break;
-    case DEQUEUE:
-      typeString = "-";
-      break;
-    case RX:
-      typeString = "r";
-      break;
-    case TX:
-      typeString = "t";
-      break;
-    case DROP:
-      typeString = "d";
-      break;
-    }
-  NS_LOG_FUNCTION (this << typeString << message);
-  *m_writer << typeString << " " << Simulator::Now ().GetSeconds () << " "
-            << message << " " << *packet << std::endl;
-}
-
-} // namespace ns3
--- a/src/common/ascii-writer.h	Thu Feb 25 13:51:59 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 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
- *
- * Author: Guillaume Seguin <guilla...@segu.in>
- */
-
-#ifndef ASCII_WRITER_H
-#define ASCII_WRITER_H
-
-#include <stdint.h>
-#include <ostream>
-#include "ns3/simple-ref-count.h"
-#include "ns3/ptr.h"
-
-namespace ns3 {
-
-class Packet;
-
-/**
- * \ingroup common
- *
- * \brief Ascii output
- */
-class AsciiWriter : public SimpleRefCount<AsciiWriter>
-{
-public:
-  static Ptr<AsciiWriter> Get (std::ostream &os);
-
-  enum Type {
-    ENQUEUE,
-    DEQUEUE,
-    DROP,
-    TX,
-    RX
-  };
-
-  ~AsciiWriter (void);
-
-  /**
-   * Writes a message in the output file, checking if the files will
-   * need to be reordered.
-   */
-  void WritePacket (enum Type type, std::string message, Ptr<const Packet> p);
-
-private:
-  AsciiWriter (std::ostream *os);
-
-  std::ostream *m_writer;
-};
-
-} // namespace ns3
-
-#endif /* ASCII_WRITER_H */
--- a/src/common/buffer.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/common/buffer.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -39,6 +39,21 @@
 #define HEURISTICS(x)
 #endif
 
+namespace {
+
+static struct Zeroes
+{
+  Zeroes ()
+    : size (1000)
+  {
+    memset (buffer, 0, size);
+  }
+  char buffer[1000];
+  const uint32_t size;
+} g_zeroes;
+
+}
+
 //#define PRINT_STATS 1
 
 namespace ns3 {
@@ -694,10 +709,12 @@
         { 
           size -= m_zeroAreaStart-m_start;
           tmpsize = std::min (m_zeroAreaEnd - m_zeroAreaStart, size);
-          char zero = 0;
-          for (uint32_t i = 0; i < tmpsize; ++i)
+          uint32_t left = tmpsize;
+          while (left > 0)
             {
-              os->write (&zero, 1);
+              uint32_t toWrite = std::min (left, g_zeroes.size);
+              os->write (g_zeroes.buffer, toWrite);
+              left -= toWrite;
             }
           if (size > tmpsize)
             {
@@ -709,6 +726,38 @@
     }
 }
 
+uint32_t 
+Buffer::CopyData (uint8_t *buffer, uint32_t size) const
+{
+  uint32_t originalSize = size;
+  if (size > 0)
+    {
+      uint32_t tmpsize = std::min (m_zeroAreaStart-m_start, size);
+      memcpy (buffer, (const char*)(m_data->m_data + m_start), tmpsize);
+      buffer += tmpsize;
+      if (size > tmpsize) 
+        { 
+          size -= m_zeroAreaStart-m_start;
+          tmpsize = std::min (m_zeroAreaEnd - m_zeroAreaStart, size);
+          uint32_t left = tmpsize;
+          while (left > 0)
+            {
+              uint32_t toWrite = std::min (left, g_zeroes.size);
+              memcpy (buffer, g_zeroes.buffer, toWrite);
+              left -= toWrite;
+              buffer += toWrite;
+            }
+          if (size > tmpsize)
+            {
+              size -= tmpsize;
+              tmpsize = std::min (m_end - m_zeroAreaEnd, size);
+              memcpy (buffer, (const char*)(m_data->m_data + m_zeroAreaStart), tmpsize);
+            }
+        }
+    }
+  return originalSize - size;
+}
+
 /******************************************************
  *            The buffer iterator below.
  ******************************************************/
--- a/src/common/buffer.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/common/buffer.h	Thu Feb 25 14:17:21 2010 +0100
@@ -487,6 +487,8 @@
    */
   void CopyData (std::ostream *os, uint32_t size) const;
 
+  uint32_t CopyData (uint8_t *buffer, uint32_t size) const;
+
   Buffer (Buffer const &o);
   Buffer &operator = (Buffer const &o);
   Buffer ();
--- a/src/common/error-model.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/common/error-model.h	Thu Feb 25 14:17:21 2010 +0100
@@ -45,7 +45,8 @@
  * the packet is to be corrupted according to the underlying model.
  * Depending on the error model, the packet itself may have its packet
  * data buffer errored or not, or side information may be returned to
- * the client in the form of a packet tag.
+ * the client in the form of a packet tag.  (Note:  No such error models
+ * that actually error the bits in a packet presently exist).
  * The object can have state (resettable by Reset()).  
  * The object can also be enabled and disabled via two public member functions.
  * 
@@ -77,6 +78,9 @@
   virtual ~ErrorModel ();
 
  /**
+  * Note:  Depending on the error model, this function may or may not
+  * alter the contents of the packet upon returning true.
+  *
   * \returns true if the Packet is to be considered as errored/corrupted
   * \param pkt Packet to apply error model to
   */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/jakes-propagation-loss-model.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,259 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 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
+ *
+ * Author: Federico Maguolo <maguolof@dei.unipd.it>
+ */
+
+#include "ns3/simulator.h"
+#include "ns3/uinteger.h"
+#include "ns3/double.h"
+#include "ns3/random-variable.h"
+#include "ns3/mobility-model.h"
+#include "ns3/log.h"
+#include "jakes-propagation-loss-model.h"
+#include <math.h>
+
+NS_LOG_COMPONENT_DEFINE ("Jakes");
+
+namespace ns3 {
+
+class JakesPropagationLossModel::PathCoefficients 
+{
+public:
+  PathCoefficients (Ptr<const JakesPropagationLossModel> jakes,
+                    Ptr<MobilityModel> receiver, 
+                    uint8_t nRays, 
+                    uint8_t nOscillators);
+  ~PathCoefficients ();
+  double GetLoss (void);
+  Ptr<MobilityModel> GetReceiver (void);
+private:
+  void DoConstruct (void);
+  Ptr<MobilityModel> m_receiver;
+  uint8_t m_nOscillators;
+  uint8_t m_nRays;
+  double **m_phases;
+  Time m_lastUpdate;
+  Ptr<const JakesPropagationLossModel> m_jakes;
+};
+
+
+JakesPropagationLossModel::PathCoefficients::PathCoefficients (Ptr<const JakesPropagationLossModel> jakes, 
+                                                           Ptr<MobilityModel> receiver, 
+                                                           uint8_t nRays, 
+							   uint8_t nOscillators)
+  : m_receiver (receiver),
+    m_nOscillators (nOscillators),
+    m_nRays (nRays),
+    m_jakes(jakes)
+{
+  DoConstruct ();
+}
+
+JakesPropagationLossModel::PathCoefficients::~PathCoefficients ()
+{
+  for (uint8_t i = 0; i < m_nRays; i++) 
+    {
+      delete [] m_phases[i];
+    }
+  delete [] m_phases;
+}
+
+void
+JakesPropagationLossModel::PathCoefficients::DoConstruct ()
+{
+  m_phases = new double*[m_nRays];
+  for (uint8_t i = 0; i < m_nRays; i++) 
+    {
+      m_phases[i] = new double[m_nOscillators + 1];
+      for (uint8_t j = 0; j <= m_nOscillators; j++) 
+        {
+          m_phases[i][j] = 2.0 * JakesPropagationLossModel::PI * m_jakes->m_variable.GetValue ();
+        }
+    }
+  m_lastUpdate = Simulator::Now ();
+}
+
+Ptr<MobilityModel>
+JakesPropagationLossModel::PathCoefficients::GetReceiver ()
+{
+  return m_receiver;
+}
+
+double
+JakesPropagationLossModel::PathCoefficients::GetLoss (void)
+{
+  uint16_t N = 4 * m_nOscillators + 2;
+  Time interval = Simulator::Now () - m_lastUpdate;
+  ComplexNumber coef= {0.0, 0.0};
+  ComplexNumber fading;
+  double norm = 0.0;
+  for (uint8_t i = 0; i < m_nRays; i++) 
+    {
+      fading.real = 0.0;
+      fading.imag = 0.0;
+      for (uint8_t j = 0; j <= m_nOscillators; j++) 
+        {
+          m_phases[i][j] += 2.0 * JakesPropagationLossModel::PI * 
+            cos (2.0 * JakesPropagationLossModel::PI * j / N) * m_jakes->m_fd * interval.GetSeconds ();
+          m_phases[i][j] -= 2.0 * JakesPropagationLossModel::PI * 
+            floor (m_phases[i][j] / 2.0 / JakesPropagationLossModel::PI);
+          fading.real += m_jakes->m_amp[j].real * cos (m_phases[i][j]);
+          fading.imag += m_jakes->m_amp[j].imag * cos (m_phases[i][j]);
+          norm += sqrt(pow (m_jakes->m_amp[j].real, 2) + pow(m_jakes->m_amp[j].imag, 2));
+        }
+    coef.real += fading.real;
+    coef.imag += fading.imag;
+    }
+  m_lastUpdate = Simulator::Now ();
+  double k = sqrt (pow (coef.real, 2) + pow (coef.imag, 2)) / norm;
+  NS_LOG_DEBUG ("Jakes coef "<< k << " (" << 10 * log10 (k) << "dB)");
+  return 10 * log10 (k);
+}
+
+NS_OBJECT_ENSURE_REGISTERED (JakesPropagationLossModel);
+
+const double JakesPropagationLossModel::PI = 3.14159265358979323846;
+
+TypeId
+JakesPropagationLossModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::JakesPropagationLossModel")
+    .SetParent<PropagationLossModel> ()
+    .AddConstructor<JakesPropagationLossModel> ()
+    .AddAttribute ("NumberOfRaysPerPath",
+                   "The number of rays to use by default for compute the fading coeficent for a given path (default is 1)",
+                   UintegerValue (1),
+		   MakeUintegerAccessor (&JakesPropagationLossModel::SetNRays,
+                                         &JakesPropagationLossModel::GetNRays),
+		   MakeUintegerChecker<uint8_t> ())
+    .AddAttribute ("NumberOfOscillatorsPerRay",
+                   "The number of oscillators to use by default for compute the coeficent for a given ray of a given "
+                   "path (default is 4)",
+                   UintegerValue (4),
+		   MakeUintegerAccessor (&JakesPropagationLossModel::SetNOscillators,
+                                         &JakesPropagationLossModel::GetNOscillators),
+		   MakeUintegerChecker<uint8_t> ())
+    .AddAttribute ("DopplerFreq",
+                   "The doppler frequency in Hz (f_d = v / lambda = v * f / c), the default is 0)",
+                   DoubleValue (0.0),
+		   MakeDoubleAccessor (&JakesPropagationLossModel::m_fd),
+		   MakeDoubleChecker<double> ())
+    .AddAttribute ("Distribution",
+                   "The distribution to choose the initial phases.",
+                   RandomVariableValue (ConstantVariable (1.0)),
+                   MakeRandomVariableAccessor (&JakesPropagationLossModel::m_variable),
+                   MakeRandomVariableChecker ())
+    ;
+  return tid;
+}
+
+JakesPropagationLossModel::JakesPropagationLossModel ()
+  : m_amp (0),
+    m_nRays (0),
+    m_nOscillators (0)
+{}
+
+JakesPropagationLossModel::~JakesPropagationLossModel ()
+{
+  delete [] m_amp;
+  for (PathsList::iterator i = m_paths.end (); i != m_paths.begin (); i--) 
+    {
+      PathsSet *ps = *i;
+      for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++) 
+        {
+          PathCoefficients *pc = *r;
+          delete pc;
+        }
+      delete ps;
+    }
+}
+
+void
+JakesPropagationLossModel::SetNRays (uint8_t nRays)
+{
+  m_nRays = nRays;
+}
+
+void
+JakesPropagationLossModel::SetNOscillators (uint8_t nOscillators)
+{
+  m_nOscillators = nOscillators;
+  delete [] m_amp;
+  uint16_t N = 4 * m_nOscillators + 2;
+  m_amp = new ComplexNumber[m_nOscillators + 1];
+  m_amp[0].real = 2.0 * sqrt(2.0 / N) * cos (PI / 4.0);
+  m_amp[0].imag = 2.0 * sqrt(2.0 / N) * sin (PI / 4.0);
+  for (uint8_t i = 1; i <= m_nOscillators; i++) 
+    {
+      double beta = PI * (double)i / m_nOscillators;
+      m_amp[i].real = 4.0 * cos (beta) / sqrt(N);
+      m_amp[i].imag = 4.0 * sin (beta) / sqrt(N);
+    }
+}
+
+uint8_t 
+JakesPropagationLossModel::GetNRays (void) const
+{
+  return m_nRays;
+}
+uint8_t 
+JakesPropagationLossModel::GetNOscillators (void) const
+{
+  return m_nOscillators;
+}
+
+
+double 
+JakesPropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                          Ptr<MobilityModel> a,
+                                          Ptr<MobilityModel> b) const
+{
+  PathsList::iterator i = m_paths.end ();
+  while (i != m_paths.begin ()) 
+    {
+      i--;
+      PathsSet *ps = *i;
+      if (ps->sender == a) 
+        {
+          m_paths.erase (i);
+          m_paths.push_back (ps);
+          for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++) 
+            {
+              PathCoefficients *pc = *r;
+              if (pc->GetReceiver () == b) 
+                {
+                  ps->receivers.erase (r);
+                  ps->receivers.push_back (pc);
+                  return txPowerDbm + pc->GetLoss ();
+                }
+            }
+          PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators);
+          ps->receivers.push_back (pc);
+          return txPowerDbm + pc->GetLoss ();
+        }
+    }
+  PathsSet *ps = new PathsSet;
+  ps->sender = a;
+  PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators);
+  ps->receivers.push_back (pc);
+  m_paths.push_back (ps);
+  return txPowerDbm + pc->GetLoss ();
+}
+
+} // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/jakes-propagation-loss-model.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,137 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 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
+ *
+ * Author: Federico Maguolo <maguolof@dei.unipd.it>
+ */
+#ifndef PROPAGATION_JAKES_MODEL_H
+#define PROPAGATION_JAKES_MODEL_H
+
+#include "ns3/nstime.h"
+#include "propagation-loss-model.h"
+
+namespace ns3 {
+
+
+/**
+ * \brief a Jakes propagation loss model
+ *
+ * The Jakes propagation loss model implemented here is 
+ * described in [1].
+ * 
+ *
+ * We call path the set of rays that depart from a given 
+ * transmitter and arrive to a given receiver. For each ray
+ * The complex coefficient is compute as follow:
+ * \f[ u(t)=u_c(t) + j u_s(t)\f]
+ * \f[ u_c(t) = \frac{2}{\sqrt{N}}\sum_{n=0}^{M}a_n\cos(\omega_n t+\phi_n)\f]
+ * \f[ u_s(t) = \frac{2}{\sqrt{N}}\sum_{n=0}^{M}b_n\cos(\omega_n t+\phi_n)\f]
+ * where
+ * \f[ a_n=\left \{ \begin{array}{ll}
+ * \sqrt{2}\cos\beta_0 & n=0 \\
+ * 2\cos\beta_n & n=1,2,\ldots,M
+ * \end{array}
+ * \right .\f]
+ * \f[ b_n=\left \{ \begin{array}{ll}
+ * \sqrt{2}\sin\beta_0 & n=0 \\
+ * 2\sin\beta_n & n=1,2,\ldots,M
+ * \end{array}
+ * \right .\f]
+ * \f[ \beta_n=\left \{ \begin{array}{ll}
+ * \frac{\pi}{4} & n=0 \\
+ * \frac{\pi n}{M} & n=1,2,\ldots,M
+ * \end{array}
+ * \right .\f]
+ * \f[ \omega_n=\left \{ \begin{array}{ll}
+ * 2\pi f_d & n=0 \\
+ * 2\pi f_d \cos\frac{2\pi n}{N} & n=1,2,\ldots,M
+ * \end{array}
+ * \right .\f]
+ *
+ * The parameter \f$f_d\f$ is the doppler frequency and \f$N=4M+2\f$ where
+ * \f$M\f$ is the number of oscillators per ray.
+ *
+ * The attenuation coefficent of the path is the magnitude of the sum of 
+ * all the ray coefficients. This attenuation coefficient could be greater than
+ * \f$1\f$, hence it is divide by \f$ \frac{2N_r}{\sqrt{N}} \sum_{n+0}^{M}\sqrt{a_n^2 +b_n^2}\f$
+ * where \f$N_r\f$ is the number of rays.
+ *
+ * The initail phases \f$\phi_i\f$ are random and they are choosen according 
+ * to a given distribution.
+ * 
+ * [1] Y. R. Zheng and C. Xiao, "Simulation Models With Correct 
+ * Statistical Properties for Rayleigh Fading Channel", IEEE
+ * Trans. on Communications, Vol. 51, pp 920-928, June 2003
+ */
+class JakesPropagationLossModel : public PropagationLossModel
+{
+public:
+  static TypeId GetTypeId (void);
+  JakesPropagationLossModel ();
+  virtual ~JakesPropagationLossModel ();
+
+  /**
+   * \param nRays Number of rays per path
+   *
+   * Set the number of rays for each path
+   */
+  void SetNRays (uint8_t nRays);
+  /**
+   * \param nOscillators Number of oscillators
+   *
+   * Set the number of oscillators to use to compute the ray coefficient
+   */
+  void SetNOscillators (uint8_t nOscillators);
+
+  uint8_t GetNRays (void) const;
+  uint8_t GetNOscillators (void) const;
+
+private:
+  JakesPropagationLossModel (const JakesPropagationLossModel &o);
+  JakesPropagationLossModel & operator = (const JakesPropagationLossModel &o);
+  void DoConstruct (void);
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
+
+  class PathCoefficients;
+  struct ComplexNumber {
+    double real;
+    double imag;
+  };
+  friend class PathCoefficents;
+  typedef std::vector<PathCoefficients *> DestinationList;
+  struct PathsSet {
+    Ptr<MobilityModel> sender;
+    DestinationList receivers;
+  };
+  typedef std::vector<PathsSet *> PathsList;
+
+  
+  static const double PI;
+  ComplexNumber* m_amp;
+  RandomVariable m_variable;
+  double m_fd;  
+  mutable PathsList m_paths;
+  uint8_t m_nRays;
+  uint8_t m_nOscillators;
+};
+
+} // namespace ns3
+
+#endif /* PROPAGATION_JAKES_MODEL_H */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/output-stream-wrapper.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 University of Washington
+ *
+ * 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
+ */
+
+#include "ns3/log.h"
+#include "output-stream-wrapper.h"
+
+NS_LOG_COMPONENT_DEFINE ("OutputStreamWrapper");
+
+namespace ns3 {
+
+OutputStreamWrapper::OutputStreamWrapper ()
+  : m_ostream (0)
+{
+}
+
+OutputStreamWrapper::~OutputStreamWrapper ()
+{
+  delete m_ostream;
+  m_ostream = 0;
+}
+
+void
+OutputStreamWrapper::SetStream (std::ostream *ostream)
+{
+  delete m_ostream;
+  m_ostream = ostream;
+}
+
+std::ostream *
+OutputStreamWrapper::GetStream (void)
+{
+  return m_ostream;
+}
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/output-stream-wrapper.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 University of Washington
+ *
+ * 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
+ */
+
+#ifndef OUTPUT_STREAM_WRAPPER_H
+#define OUTPUT_STREAM_WRAPPER_H
+
+#include <ostream>
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+#include "ns3/simple-ref-count.h"
+
+namespace ns3 {
+
+/*
+ * @brief A class encapsulating an STL output stream.
+ *
+ * One of the common issues users run into when trying to use tracing in ns-3
+ * is actually due to a design decision made in the C++ stream library.  
+ *
+ * It is not widely known, but copy and assignment of iostreams is forbidden by 
+ * std::basic_ios<>.  This is because it is not possible to predict the 
+ * semantics of the stream desired by a user.
+ *
+ * When writing traced information to a file, the tempting ns-3 idiom is to 
+ * create a bound callback with an ofstream as the bound object.  Unfortunately,
+ * this implies a copy construction in order to get the ofstream object into the
+ * callback.  This operation, as mentioned above, is forbidden by the STL.  One
+ * could use a global ostream and pass a pointer to it, but that is pretty ugly.  
+ * One could also create an ostream on the stack and pass a pointer to it in the
+ * callback, but object lifetime issues will quickly rear their ugly heads.  It
+ * turns out that ns-3 has a nifty reference counted object that can solve the 
+ * value semantics and object lifetime issues, so we provide one of those to 
+ * carry the stream around.
+ *
+ * The experienced C++ wizard may ask, "what's the point of such a simple class."
+ * but this isn't oriented toward them.  We use this to make a simple thing 
+ * simple to do for new users; and also as a simple example of ns-3 objects at a
+ * high level.  We know of a couple of high-powered experienced developers that 
+ * have been tripped up by this and decided that it must be an ns-3 bug.
+ *
+ * One could imagine having this object inherit from stream to get the various
+ * overloaded operator<< defined, but we're going to be using a
+ * Ptr<OutputStreamWrapper> when passing this object around.  In this case, the 
+ * Ptr<> wouldn't understand the operators and we would have to dereference it
+ * to access the underlying object methods.  Since we would have to dereference
+ * the Ptr<>, we don't bother and just expect the user to Get a saved pointer
+ * to an ostream and dereference it him or herself.  As in:
+ *
+ * \verbatim
+ *   void 
+ *   TraceSink (Ptr<OutputStreamWrapper> streamWrapper, Ptr<const Packet> packet)
+ *   {
+ *     std::ostream *stream = streamWrapper->GetStream ();
+ *     *stream << "got packet" << std::endl;
+ *   }
+ * \endverbatim
+ */
+class OutputStreamWrapper : public SimpleRefCount<OutputStreamWrapper>
+{
+public:
+  OutputStreamWrapper ();
+  ~OutputStreamWrapper ();
+
+  void SetStream (std::ostream *ostream);
+  std::ostream *GetStream (void);
+  
+private:
+  std::ostream *m_ostream;
+};
+
+} //namespace ns3
+
+#endif // OUTPUT_STREAM_WRAPPER_H
--- a/src/common/packet.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/common/packet.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -350,14 +350,7 @@
 uint32_t 
 Packet::CopyData (uint8_t *buffer, uint32_t size) const
 {
-  Buffer::Iterator i = m_buffer.Begin ();
-  uint32_t cur = 0;
-  while (!i.IsEnd () && cur < size)
-    {
-      buffer[cur] = i.ReadU8 ();
-      cur++;
-    }
-  return cur;
+  return m_buffer.CopyData (buffer, size);
 }
 
 void
--- a/src/common/packet.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/common/packet.h	Thu Feb 25 14:17:21 2010 +0100
@@ -202,7 +202,6 @@
 class Packet : public SimpleRefCount<Packet>
 {
 public:
-  Ptr<Packet> Copy (void) const;
 
   /**
    * Create an empty packet with a new uid (as returned
@@ -346,9 +345,24 @@
    */
   uint32_t CopyData (uint8_t *buffer, uint32_t size) const;
 
+  /**
+   * \param os pointer to output stream in which we want
+   *        to write the packet data.
+   * \param size the maximum number of bytes we want to write
+   *        in the output stream.
+   */
   void CopyData(std::ostream *os, uint32_t size) const;
 
   /**
+   * \returns a COW copy of the packet.
+   *
+   * The returns packet will behave like an independent copy of
+   * the original packet, even though they both share the
+   * same datasets internally.
+   */
+  Ptr<Packet> Copy (void) const;
+
+  /**
    * A packet is allocated a new uid when it is created
    * empty or with zero-filled payload.
    *
@@ -377,6 +391,14 @@
    */
   void Print (std::ostream &os) const;
 
+  /**
+   * \returns an iterator which points to the first 'item'
+   * stored in this buffer. Note that this iterator will point
+   * to an empty array of items if you don't call EnablePrinting
+   * or EnableChecking before.
+   *
+   * \sa EnablePrinting EnableChecking
+   */
   PacketMetadata::ItemIterator BeginItem (void) const;
 
   /**
--- a/src/common/pcap-file-test-suite.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/common/pcap-file-test-suite.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -1013,7 +1013,7 @@
 };
 
 PcapFileTestSuite::PcapFileTestSuite ()
-  : TestSuite ("pcap-file-object", UNIT)
+  : TestSuite ("pcap-file", UNIT)
 {
   AddTestCase (new WriteModeCreateTestCase);
   AddTestCase (new ReadModeCreateTestCase);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/pcap-file-wrapper.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,183 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * 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
+ */
+
+#include "ns3/log.h"
+#include "ns3/uinteger.h"
+
+#include "buffer.h"
+#include "header.h"
+#include "pcap-file-wrapper.h"
+
+NS_LOG_COMPONENT_DEFINE ("PcapFileWrapper");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (PcapFileWrapper);
+
+TypeId 
+PcapFileWrapper::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::PcapFileWrapper")
+    .SetParent<Object> ()
+    .AddConstructor<PcapFileWrapper> ()
+    .AddAttribute ("CaptureSize",
+                   "Maximum length of captured packets (cf. pcap snaplen)",
+                   UintegerValue (PcapFile::SNAPLEN_DEFAULT),
+                   MakeUintegerAccessor (&PcapFileWrapper::m_snapLen),
+                   MakeUintegerChecker<uint32_t> (0, PcapFile::SNAPLEN_DEFAULT))
+    ;
+  return tid;
+}
+
+
+PcapFileWrapper::PcapFileWrapper ()
+{
+}
+
+PcapFileWrapper::~PcapFileWrapper ()
+{
+  Close ();
+}
+
+void
+PcapFileWrapper::Close (void)
+{
+  m_file.Close ();
+}
+
+bool
+PcapFileWrapper::Open (std::string const &filename, std::string const &mode)
+{
+  return m_file.Open (filename, mode);
+}
+
+bool
+PcapFileWrapper::Init (uint32_t dataLinkType, uint32_t snapLen, int32_t tzCorrection)
+{
+  //
+  // If the user doesn't provide a snaplen, the default value will come in.  If
+  // this happens, we use the "CaptureSize" Attribute.  If the user does provide
+  // a snaplen, we use the one provided.
+  //
+  if (snapLen != std::numeric_limits<uint32_t>::max ())
+    {
+      return m_file.Init (dataLinkType, snapLen, tzCorrection);
+    } 
+  else
+    {
+      return m_file.Init (dataLinkType, m_snapLen, tzCorrection);
+    } 
+
+  //
+  // Quiet the compiler
+  //
+  return true;
+}
+
+bool
+PcapFileWrapper::Write (Time t, Ptr<const Packet> p)
+{
+  uint8_t buffer[PcapFile::SNAPLEN_DEFAULT];
+
+  uint64_t current = t.GetMicroSeconds ();
+  uint64_t s = current / 1000000;
+  uint64_t us = current % 1000000;
+
+  uint32_t bufferSize = p->GetSize ();
+  p->CopyData (buffer, bufferSize);
+  bool rc = m_file.Write (s, us, buffer, bufferSize);
+  return rc;
+}
+
+bool
+PcapFileWrapper::Write (Time t, Header &header, Ptr<const Packet> p)
+{
+  uint8_t buffer[PcapFile::SNAPLEN_DEFAULT];
+
+  uint64_t current = t.GetMicroSeconds ();
+  uint64_t s = current / 1000000;
+  uint64_t us = current % 1000000;
+
+  Buffer headerBuffer;
+  uint32_t headerSize = header.GetSerializedSize ();
+  uint32_t packetSize = p->GetSize ();
+  uint32_t bufferSize = headerSize + packetSize;
+
+  headerBuffer.AddAtStart (headerSize);
+  header.Serialize (headerBuffer.Begin ());
+
+  headerBuffer.Begin ().Read (buffer, headerSize);
+  p->CopyData (&buffer[headerSize], packetSize);
+  bool rc = m_file.Write (s, us, buffer, bufferSize);
+
+  return rc;
+}
+
+bool
+PcapFileWrapper::Write (Time t, uint8_t const *buffer, uint32_t length)
+{
+  uint64_t current = t.GetMicroSeconds ();
+  uint64_t s = current / 1000000;
+  uint64_t us = current % 1000000;
+
+  return m_file.Write (s, us, buffer, length);
+}
+
+uint32_t
+PcapFileWrapper::GetMagic (void)
+{
+  return m_file.GetMagic ();
+}
+
+uint16_t
+PcapFileWrapper::GetVersionMajor (void)
+{
+  return m_file.GetVersionMajor ();
+}
+
+uint16_t
+PcapFileWrapper::GetVersionMinor (void)
+{
+  return m_file.GetVersionMinor ();
+}
+
+int32_t
+PcapFileWrapper::GetTimeZoneOffset (void)
+{
+  return m_file.GetTimeZoneOffset ();
+}
+
+uint32_t
+PcapFileWrapper::GetSigFigs (void)
+{
+  return m_file.GetSigFigs ();
+}
+
+uint32_t
+PcapFileWrapper::GetSnapLen (void)
+{
+  return m_file.GetSnapLen ();
+}
+
+uint32_t
+PcapFileWrapper::GetDataLinkType (void)
+{
+  return m_file.GetDataLinkType ();
+}
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/pcap-file-wrapper.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,235 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * 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
+ */
+
+#ifndef PCAP_FILE_WRAPPER_H
+#define PCAP_FILE_WRAPPER_H
+
+#include <string.h>
+#include <limits>
+#include "ns3/ptr.h"
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+#include "pcap-file.h"
+
+namespace ns3 {
+
+/*
+ * A class representing a pcap file tailored for use in model code.
+ */
+
+class PcapFileWrapper : public Object
+{
+public:
+  static TypeId GetTypeId (void);
+
+  PcapFileWrapper ();
+  ~PcapFileWrapper ();
+
+  /**
+   * Create a new pcap file wrapper representing a new or existing pcap file.
+   * Semantics are similar to the C standard library function \c fopen
+   *
+   * Possible modes are:
+   *
+   * \verbatim
+   * "r":   Open a file for reading.  The file must exist.  The pcap header
+   *        is assumed to exist in the file and will be read and checked.
+   *        The file seek position indicator is set to point to the first 
+   *        packet on exit.
+   *
+   * "w":   Create an empty file for writing. If a file with the same name 
+   *        already exists its content is erased and the file is treated as a 
+   *        new empty pcap file.  The file is assumed not to have a pcap 
+   *        header and the caller is responsible for calling Init before saving
+   *        any packet data.  The file seek position indicator is set to point 
+   *        to the beginning of the file on exit since there will be no pcap
+   *        header.
+   *
+   * "a":   Append to an existing file. This mode allows for adding packet data
+   *        to the end of an existing pcap file.  The file must exist and have a
+   *        valid pcap header written (N.B. this is different from standard fopen
+   *        semantics).  The file seek position indicator is set to point 
+   *        to the end of the file on exit.
+   *
+   * "r+":  Open a file for update -- both reading and writing. The file must 
+   *        exist.  The pcap header is assumed to have been written to the 
+   *        file and will be read and checked.  The file seek position indicator
+   *        is set to point to the first packet on exit.
+   *
+   * "w+":  Create an empty file for both reading and writing.  If a file with
+   *        the same name already exists, its content is erased and the file is 
+   *        treated as a new empty pcap file.  Since this new file will not have
+   *        a pcap header, the caller is responsible for calling Init before 
+   *        saving any packet data.  On exit, the file seek position indicator is
+   *        set to point to the beginning of the file.
+   *
+   * "a+"   Open a file for reading and appending.  The file must exist and have a
+   *        valid pcap header written (N.B. this is different from standard fopen
+   *        semantics).  The file seek position indicator is set to point 
+   *        to the end of the file on exit.  Existing content is preserved.
+   * \endverbatim
+   *
+   * Since a pcap file is always a binary file, the file type is automatically 
+   * selected as a binary file.  For example, providing a mode string "a+" 
+   * results in the underlying OS file being opened in "a+b" mode.
+   *
+   * \param filename String containing the name of the file.
+   *
+   * \param mode String containing the access mode for the file.
+   *
+   * \returns Error indication that should be interpreted as, "did an error 
+   * happen"?  That is, the method returns false if the open succeeds, true 
+   * otherwise.  The errno variable will be set by the OS to to provide a 
+   * more descriptive failure indication.
+   */
+  bool Open (std::string const &filename, std::string const &mode);
+
+  /**
+   * Close the underlying pcap file.
+   */
+  void Close (void);
+
+  /**
+   * Initialize the pcap file associated with this wrapper.  This file must have
+   * been previously opened with write permissions.
+   *
+   * \param dataLinkType A data link type as defined in the pcap library.  If
+   * you want to make resulting pcap files visible in existing tools, the 
+   * data link type must match existing definitions, such as PCAP_ETHERNET,
+   * PCAP_PPP, PCAP_80211, etc.  If you are storing different kinds of packet
+   * data, such as naked TCP headers, you are at liberty to locally define your
+   * own data link types.  According to the pcap-linktype man page, "well-known"
+   * pcap linktypes range from 0 to 177.  If you use a large random number for
+   * your type, chances are small for a collision.
+   *
+   * \param snapLen An optional maximum size for packets written to the file.
+   * Defaults to 65535.  If packets exceed this length they are truncated.
+   *
+   * \param tzCorrection An integer describing the offset of your local
+   * time zone from UTC/GMT.  For example, Pacific Standard Time in the US is
+   * GMT-8, so one would enter -8 for that correction.  Defaults to 0 (UTC).
+   *
+   * \return false if the open succeeds, true otherwise.
+   *
+   * \warning Calling this method on an existing file will result in the loss
+   * any existing data.
+   */
+  bool Init (uint32_t dataLinkType, 
+             uint32_t snapLen = std::numeric_limits<uint32_t>::max (), 
+             int32_t tzCorrection = PcapFile::ZONE_DEFAULT);
+
+  /**
+   * \brief Write the next packet to file
+   * 
+   * \param t Packet timestamp as ns3::Time.
+   * \param p Packet to write to the pcap file.
+   * 
+   * \return true on error, false otherwise
+   */
+  bool Write (Time t, Ptr<const Packet> p);
+
+  /**
+   * \brief Write the provided header along with the packet to the pcap file.
+   *
+   * It is the case that adding a header to a packet prior to writing it to a
+   * file must trigger a deep copy in the Packet.  By providing the header
+   * separately, we can avoid that copy.
+   * 
+   * \param t Packet timestamp as ns3::Time.
+   * \param header The Header to prepend to the packet.
+   * \param p Packet to write to the pcap file.
+   * 
+   * \return true on error, false otherwise
+   */
+  bool Write (Time t, Header &header, Ptr<const Packet> p);
+
+  /**
+   * \brief Write the provided data buffer to the pcap file.
+   *
+   * \param t Packet timestamp as ns3::Time.
+   * \param buffer The buffer to write.
+   * \param length The size of the buffer.
+   * 
+   * \return true on error, false otherwise
+   */
+  bool Write (Time t, uint8_t const *buffer, uint32_t length);
+
+  /*
+   * \brief Returns the magic number of the pcap file as defined by the magic_number
+   * field in the pcap global header.
+   *
+   * See http://wiki.wireshark.org/Development/LibpcapFileFormat
+   */ 
+  uint32_t GetMagic (void);
+
+  /*
+   * \brief Returns the major version of the pcap file as defined by the version_major
+   * field in the pcap global header.
+   *
+   * See http://wiki.wireshark.org/Development/LibpcapFileFormat
+   */ 
+  uint16_t GetVersionMajor (void);
+
+  /*
+   * \brief Returns the minor version of the pcap file as defined by the version_minor
+   * field in the pcap global header.
+   *
+   * See http://wiki.wireshark.org/Development/LibpcapFileFormat
+   */ 
+  uint16_t GetVersionMinor (void);
+
+  /*
+   * \brief Returns the time zone offset of the pcap file as defined by the thiszone
+   * field in the pcap global header.
+   *
+   * See http://wiki.wireshark.org/Development/LibpcapFileFormat
+   */ 
+  int32_t GetTimeZoneOffset (void);
+
+  /*
+   * \brief Returns the accuracy of timestamps field of the pcap file as defined
+   * by the sigfigs field in the pcap global header.
+   *
+   * See http://wiki.wireshark.org/Development/LibpcapFileFormat
+   */ 
+  uint32_t GetSigFigs (void);
+
+  /*
+   * \brief Returns the max length of saved packets field of the pcap file as 
+   * defined by the snaplen field in the pcap global header.
+   *
+   * See http://wiki.wireshark.org/Development/LibpcapFileFormat
+   */ 
+  uint32_t GetSnapLen (void);
+
+  /*
+   * \brief Returns the data link type field of the pcap file as defined by the 
+   * network field in the pcap global header.
+   *
+   * See http://wiki.wireshark.org/Development/LibpcapFileFormat
+   */ 
+  uint32_t GetDataLinkType (void);
+  
+private:
+  PcapFile m_file;
+  uint32_t m_snapLen;
+};
+
+} //namespace ns3
+
+#endif // PCAP_FILE_WRAPPER_H
--- a/src/common/pcap-file.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/common/pcap-file.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -398,7 +398,33 @@
   m_fileHeader.m_type = dataLinkType;
 
   m_haveFileHeader = true;
-  m_swapMode = swapMode;
+
+  //
+  // We use pcap files for regression testing.  We do byte-for-byte comparisons
+  // in those tests to determine pass or fail.  If we allow big endian systems
+  // to write big endian headers, they will end up byte-swapped and the
+  // regression tests will fail.  Until we get rid of the regression tests, we
+  // have to pick an endianness and stick with it.  The precedent is little
+  // endian, so we set swap mode if required to pick little endian.
+  //
+  // We do want to allow a user or test suite to enable swapmode irrespective
+  // of what we decide here, so we allow setting swapmode from formal parameter
+  // as well.
+  //
+  // So, determine the endianness of the running system.
+  //
+  union {
+    uint32_t a;
+    uint8_t  b[4];
+  } u;
+
+  u.a = 1;
+  bool bigEndian = u.b[3];
+
+  //
+  // And set swap mode if requested or we are on a big-endian system.
+  //
+  m_swapMode = swapMode | bigEndian;
 
   return WriteFileHeader ();
 }
--- a/src/common/pcap-file.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/common/pcap-file.h	Thu Feb 25 14:17:21 2010 +0100
@@ -105,6 +105,9 @@
    */
   bool Open (std::string const &filename, std::string const &mode);
 
+  /**
+   * Close the underlying file.
+   */
   void Close (void);
 
   /**
@@ -127,6 +130,9 @@
    * time zone from UTC/GMT.  For example, Pacific Standard Time in the US is
    * GMT-8, so one would enter -8 for that correction.  Defaults to 0 (UTC).
    *
+   * \param swapMode Flag indicating a difference in endianness of the 
+   * writing system. Defaults to false.
+   *
    * \return false if the open succeeds, true otherwise.
    *
    * \warning Calling this method on an existing file will result in the loss
@@ -253,7 +259,7 @@
    * \param  f1         First PCAP file name
    * \param  f2         Second PCAP file name
    * \param  sec        [out] Time stamp of first different packet, seconds. Undefined if files doesn't differ.
-   * \param  uses       [out] Time stamp of first different packet, microseconds. Undefined if files doesn't differ.
+   * \param  usec       [out] Time stamp of first different packet, microseconds. Undefined if files doesn't differ.
    * \param  snapLen    Snap length (if used)
    */
   static bool Diff (std::string const & f1, std::string const & f2, 
--- a/src/common/pcap-writer.cc	Thu Feb 25 13:51:59 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,562 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-/*
- * Documentation kindly pointed out by Tom Henderson:
- * http://wiki.ethereal.com/Development/LibpcapFileFormat
- */
-
-#include <fstream>
-
-#include "ns3/log.h"
-#include "ns3/assert.h"
-#include "ns3/abort.h"
-#include "ns3/simulator.h"
-#include "ns3/uinteger.h"
-#include "pcap-writer.h"
-#include "packet.h"
-
-NS_LOG_COMPONENT_DEFINE ("PcapWriter");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (PcapWriter);
-
-enum {
-  PCAP_ETHERNET = 1,
-  PCAP_PPP      = 9,
-  PCAP_RAW_IP   = 101,
-  PCAP_80211    = 105,
-  PCAP_80211_PRISM = 119,
-  PCAP_80211_RADIOTAP  = 127,
-};
-
-TypeId 
-PcapWriter::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::PcapWriter")
-    .SetParent<Object> ()
-    .AddConstructor<PcapWriter> ()
-    .AddAttribute ("CaptureSize",
-                   "Number of bytes to capture at the start of each packet written in the pcap file. Zero means capture all bytes.",
-                   UintegerValue (0),
-                   MakeUintegerAccessor (&PcapWriter::m_captureSize),
-                   MakeUintegerChecker<uint32_t> ())
-    ;
-  return tid;
-}
-
-PcapWriter::PcapWriter ()
-{
-  NS_LOG_FUNCTION (this);
-  NS_LOG_LOGIC ("m_writer = 0");
-  m_writer = 0;
-}
-
-PcapWriter::~PcapWriter ()
-{
-  NS_LOG_FUNCTION (this);
-
-  if (m_writer != 0)
-    {
-      NS_LOG_LOGIC ("m_writer nonzero " << m_writer);
-      if (m_writer->is_open ())
-        {
-          NS_LOG_LOGIC ("m_writer open.  Closing " << m_writer);
-          m_writer->close ();
-        }
-
-      NS_LOG_LOGIC ("Deleting writer " << m_writer);
-      delete m_writer;
-
-      NS_LOG_LOGIC ("m_writer = 0");
-      m_writer = 0;
-    }
-  else
-    {
-      NS_LOG_LOGIC ("m_writer == 0");
-    }
-}
-
-void
-PcapWriter::Open (std::string const &name)
-{
-  NS_LOG_FUNCTION (this << name);
-  NS_ABORT_MSG_UNLESS (m_writer == 0, "PcapWriter::Open(): m_writer already allocated (std::ofstream leak detected)");
-
-  m_writer = new std::ofstream ();
-  NS_ABORT_MSG_UNLESS (m_writer, "PcapWriter::Open(): Cannot allocate m_writer");
-
-  NS_LOG_LOGIC ("Created writer " << m_writer);
-
-  m_writer->open (name.c_str (), std::ios_base::binary | std::ios_base::out);
-  NS_ABORT_MSG_IF (m_writer->fail (), "PcapWriter::Open(): m_writer->open(" << name.c_str () << ") failed");
-
-  NS_ASSERT_MSG (m_writer->is_open (), "PcapWriter::Open(): m_writer not open");
-
-  NS_LOG_LOGIC ("Writer opened successfully");
-}
-
-void 
-PcapWriter::WriteEthernetHeader (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  WriteHeader (PCAP_ETHERNET);
-}
-
-void 
-PcapWriter::WriteIpHeader (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  WriteHeader (PCAP_RAW_IP);
-}
-
-void
-PcapWriter::WriteWifiHeader (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  WriteHeader (PCAP_80211);
-}
-
-void
-PcapWriter::WriteWifiRadiotapHeader (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  WriteHeader (PCAP_80211_RADIOTAP);
-}
-
-void
-PcapWriter::WriteWifiPrismHeader (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  WriteHeader (PCAP_80211_PRISM);
-}
-
-void 
-PcapWriter::WritePppHeader (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  WriteHeader (PCAP_PPP);
-}
-
-void 
-PcapWriter::WriteHeader (uint32_t network)
-{
-  NS_LOG_FUNCTION (this << network);
-  Write32 (0xa1b2c3d4);
-  Write16 (2);
-  Write16 (4);
-  Write32 (0);
-  Write32 (0);
-  Write32 (0xffff);
-  Write32 (network);
-  m_pcapMode = network;
-}
-
-void 
-PcapWriter::WritePacket (Ptr<const Packet> packet)
-{
-  if (m_writer != 0) 
-    {
-      uint64_t current = Simulator::Now ().GetMicroSeconds ();
-      uint64_t s = current / 1000000;
-      uint64_t us = current % 1000000;
-      Write32 (s & 0xffffffff);
-      Write32 (us & 0xffffffff);
-      uint32_t thisCaptureSize;
-      if (m_captureSize == 0)
-        {
-          thisCaptureSize = packet->GetSize ();
-        }
-      else
-        {
-          thisCaptureSize = std::min (m_captureSize, packet->GetSize ());         
-        }          
-      Write32 (thisCaptureSize); 
-      Write32 (packet->GetSize ()); // actual packet size
-      packet->CopyData (m_writer, thisCaptureSize);
-    }
-}
-
-
-void PcapWriter::WriteWifiMonitorPacket(Ptr<const Packet> packet, uint16_t channelFreqMhz, uint16_t channelNumber,                                        
-                                        uint32_t rate, bool isShortPreamble, bool isTx, 
-                                        double signalDbm, double noiseDbm)
-{  
-  NS_LOG_FUNCTION (this << packet->GetSize() << channelFreqMhz << rate << isShortPreamble << isTx << signalDbm << noiseDbm);
-
-  if (m_writer == 0) 
-    {
-      return;
-    }
-
-  if (m_pcapMode == PCAP_80211)
-    {
-      WritePacket (packet);    
-      return;
-    }
-  
-  /* the following is common between PRISM and RADIOTAP */
-  
-  uint64_t current = Simulator::Now ().GetMicroSeconds ();
-  uint64_t s = current / 1000000;
-  uint64_t us = current % 1000000;
-  Write32 (s & 0xffffffff);
-  Write32 (us & 0xffffffff);
-    
-
-  // MAC timestamp. Actually according to radiotap specifications
-  // (http://www.radiotap.org/defined-fields/TSFT) this should be
-  // the time "when the first bit of the MPDU arrived at the
-  // MAC". This is not exactly what we're doing here, but to handle
-  // this properly we would need to first of all investigate how
-  // real devices (e.g. madwifi) handle this case, especially for TX
-  // packets (radiotap specs says TSFT is not used for TX packets,
-  // but madwifi actually uses it).
-  uint64_t tsft = current;    
-
-  
-  uint32_t wifiMonitorHeaderSize;  
-    
-  if (m_pcapMode == PCAP_80211_PRISM)
-    {
-      
-#define PRISM_MSG_CODE		 0x00000044
-#define PRISM_MSG_LENGTH         144
-#define PRISM_DID_HOSTTIME	 0x00010044
-#define PRISM_DID_MACTIME	 0x00020044
-#define PRISM_DID_CHANNEL	 0x00030044
-#define PRISM_DID_RSSI	         0x00040044
-#define PRISM_DID_SQ		 0x00050044
-#define PRISM_DID_SIGNAL	 0x00060044
-#define PRISM_DID_NOISE	         0x00070044
-#define PRISM_DID_RATE	         0x00080044
-#define PRISM_DID_ISTX	         0x00090044
-#define PRISM_DID_FRMLEN	 0x000A0044
-
-#define PRISM_STATUS_PRESENT    0
-#define PRISM_STATUS_ABSENT     1
-#define PRISM_ITEM_LENGTH       4
-
-
-      wifiMonitorHeaderSize = PRISM_MSG_LENGTH;
-      if (m_captureSize == 0)
-        {
-          Write32 (packet->GetSize () + wifiMonitorHeaderSize); // captured size == actual packet size
-        }
-      else
-        {
-          uint32_t thisCaptureSize = std::min (m_captureSize, packet->GetSize () + wifiMonitorHeaderSize);         
-          Write32 (thisCaptureSize); 
-        }
-      Write32 (packet->GetSize () + wifiMonitorHeaderSize); // actual packet size
-
-      Write32(PRISM_MSG_CODE);
-      Write32(PRISM_MSG_LENGTH);
-      WriteData((const uint8_t *)"unknown wifi device!!!!!!!!", 16);
-    
-      Write32(PRISM_DID_HOSTTIME);
-      Write16(PRISM_STATUS_PRESENT);
-      Write16(PRISM_ITEM_LENGTH); 
-      // madwifi reports hosttime in jiffies. 
-      // We calculate jiffies assuming HZ = 10
-      Write32((uint32_t) (Now ().GetMilliSeconds () / 10 ) ); 
-
-      Write32(PRISM_DID_MACTIME);
-      Write16(PRISM_STATUS_PRESENT);
-      Write16(PRISM_ITEM_LENGTH); 
-      // This looses precision, which is a well-known issue of the prism
-      // header format.
-      Write32((uint32_t) tsft);
-
-      Write32(PRISM_DID_CHANNEL);
-      Write16(PRISM_STATUS_PRESENT);
-      Write16(PRISM_ITEM_LENGTH);             
-      Write32((uint32_t) channelNumber);
-
-      Write32(PRISM_DID_RSSI);
-      Write16(PRISM_STATUS_PRESENT);
-      Write16(PRISM_ITEM_LENGTH); 
-      // madwifi here reports a value which is said to be "the value in
-      // dBm above noise". Apart from the fact that this is incorrect
-      // (if it is relative to a value in dBm, then it must be in dB,
-      // not in dBm again), this means that in fact it is not a RSSI
-      // (which stands for Received Signal Strength Indicator) but it is
-      // rather a Signal to Noise Ratio (SNR), of course in dB.
-      // Anyway, in the end we calculate the value exactly as madwifi does.
-      Write32((uint32_t)round(signalDbm - noiseDbm));
-
-      // SQ field not used. I would expect a PRISM_STATUS_ABSENT to be
-      // needed here, but if you look at the prism header that madwifi
-      // produces you'll just see that the whole field structure is
-      // zeroed. 
-      Write32(0);
-      Write16(0);
-      Write16(0); 
-      Write32(0);
-
-      Write32(PRISM_DID_SIGNAL);
-      Write16(PRISM_STATUS_PRESENT);
-      Write16(PRISM_ITEM_LENGTH); 
-      Write32((uint32_t)round(signalDbm));
-
-      Write32(PRISM_DID_NOISE);
-      Write16(PRISM_STATUS_PRESENT);
-      Write16(PRISM_ITEM_LENGTH); 
-      Write32((uint32_t)round(noiseDbm));
-            
-      Write32(PRISM_DID_RATE);    
-      Write16(PRISM_STATUS_PRESENT);
-      Write16(PRISM_ITEM_LENGTH); 
-      Write32(rate);
- 
-      Write32(PRISM_DID_ISTX);
-      Write16(PRISM_STATUS_PRESENT);
-      Write16(PRISM_ITEM_LENGTH); 
-      Write32(isTx ? 1 : 0);
-
-      Write32(PRISM_DID_FRMLEN);
-      Write16(PRISM_STATUS_PRESENT);
-      Write16(PRISM_ITEM_LENGTH); 
-      Write32(packet->GetSize ());    
-      
-    
-
-    } // PCAP_80211_PRISM
-
-  else if (m_pcapMode == PCAP_80211_RADIOTAP)
-    {      
-      NS_LOG_LOGIC("writing radiotap packet");
-      
-#define	RADIOTAP_TSFT               0x00000001
-#define	RADIOTAP_FLAGS              0x00000002
-#define	RADIOTAP_RATE               0x00000004
-#define RADIOTAP_CHANNEL            0x00000008
-#define	RADIOTAP_FHSS               0x00000010
-#define RADIOTAP_DBM_ANTSIGNAL      0x00000020
-#define RADIOTAP_DBM_ANTNOISE       0x00000040
-#define RADIOTAP_LOCK_QUALITY       0x00000080
-#define RADIOTAP_TX_ATTENUATION     0x00000100    
-#define RADIOTAP_DB_TX_ATTENUATION  0x00000200
-#define RADIOTAP_DBM_TX_POWER       0x00000200
-#define RADIOTAP_ANTENNA            0x00000400
-#define RADIOTAP_DB_ANTSIGNAL       0x00000800
-#define RADIOTAP_DB_ANTNOISE        0x00001000
-#define RADIOTAP_EXT                0x10000000
-
-#define	RADIOTAP_FLAG_NONE	   0x00	
-#define	RADIOTAP_FLAG_CFP	   0x01	
-#define	RADIOTAP_FLAG_SHORTPRE	   0x02	
-#define	RADIOTAP_FLAG_WEP	   0x04	
-#define	RADIOTAP_FLAG_FRAG	   0x08	
-#define	RADIOTAP_FLAG_FCS	   0x10	
-#define	RADIOTAP_FLAG_DATAPAD	   0x20	
-#define	RADIOTAP_FLAG_BADFCS	   0x40	
-
-#define	RADIOTAP_CHANNEL_TURBO	         0x0010
-#define	RADIOTAP_CHANNEL_CCK	         0x0020
-#define	RADIOTAP_CHANNEL_OFDM	         0x0040
-#define	RADIOTAP_CHANNEL_2GHZ	         0x0080
-#define	RADIOTAP_CHANNEL_5GHZ	         0x0100
-#define	RADIOTAP_CHANNEL_PASSIVE         0x0200
-#define	RADIOTAP_CHANNEL_DYN_CCK_OFDM    0x0400
-#define	RADIOTAP_CHANNEL_GFSK	         0x0800
-#define	RADIOTAP_CHANNEL_GSM             0x1000
-#define	RADIOTAP_CHANNEL_STATIC_TURBO    0x2000
-#define	RADIOTAP_CHANNEL_HALF_RATE       0x4000
-#define	RADIOTAP_CHANNEL_QUARTER_RATE    0x8000
-
-#define RADIOTAP_RX_PRESENT (RADIOTAP_TSFT | RADIOTAP_FLAGS | RADIOTAP_RATE | RADIOTAP_CHANNEL | RADIOTAP_DBM_ANTSIGNAL | RADIOTAP_DBM_ANTNOISE)
-#define RADIOTAP_RX_LENGTH (8+8+1+1+2+2+1+1)
-
-#define RADIOTAP_TX_PRESENT (RADIOTAP_TSFT | RADIOTAP_FLAGS  | RADIOTAP_RATE | RADIOTAP_CHANNEL)
-#define RADIOTAP_TX_LENGTH (8+8+1+1+2+2)
-      
-      if (isTx)
-        {
-          wifiMonitorHeaderSize = RADIOTAP_TX_LENGTH;
-        }
-      else
-        {
-          wifiMonitorHeaderSize = RADIOTAP_RX_LENGTH;
-        }      
-
-      if (m_captureSize == 0)
-        {
-          Write32 (packet->GetSize () + wifiMonitorHeaderSize); // captured size == actual packet size
-        }
-      else
-        {
-          uint32_t thisCaptureSize = std::min (m_captureSize, packet->GetSize () + wifiMonitorHeaderSize);         
-          Write32 (thisCaptureSize); 
-        }
-      Write32 (packet->GetSize () + wifiMonitorHeaderSize); // actual packet size
-
-      Write8(0); // radiotap version
-      Write8(0); // padding
-
-      if (isTx)
-        {
-          Write16(RADIOTAP_TX_LENGTH); 
-          Write32(RADIOTAP_TX_PRESENT); 
-        }
-      else
-        {
-          Write16(RADIOTAP_RX_LENGTH); 
-          Write32(RADIOTAP_RX_PRESENT); 
-        }
-
-      Write64(tsft); 
-      
-      uint8_t flags = RADIOTAP_FLAG_NONE;
-      if (isShortPreamble)
-        {
-          flags |= RADIOTAP_FLAG_SHORTPRE; 
-        }
-      Write8(flags);
-      
-
-      Write8(rate); 
-
-      Write16(channelFreqMhz); 
-      
-      uint16_t channelFlags;
-      if (channelFreqMhz < 2500)
-        {
-          // TODO: when 802.11g WifiModes will be implemented
-          // we will need to check dinamically whether channelFlags
-          // needs to be set to RADIOTAP_CHANNEL_CCK,
-          // RADIOTAP_CHANNEL_DYN or RADIOTAP_CHANNEL_OFDM.          
-          channelFlags = RADIOTAP_CHANNEL_2GHZ | RADIOTAP_CHANNEL_CCK;
-        }
-      else
-        {
-          // TODO: we should handle correctly the case of half rate
-          // (10 MHz channel) and quarter rate (5 Mhz channel). 
-          channelFlags = RADIOTAP_CHANNEL_5GHZ | RADIOTAP_CHANNEL_OFDM;
-        }                
-      Write16(channelFlags); 
-    
-      if (!isTx)
-        {
-          
-          Write8 (RoundToInt8 (signalDbm)); 
-          Write8 (RoundToInt8 (noiseDbm)); 
-        }
-
-    } // PCAP_80211_RADIOTAP
-
-    
-  else
-    {
-      NS_LOG_ERROR("unknown PCAP mode");      
-      return;
-    }    
-
-  // finally, write rest of packet
-  if (m_captureSize == 0)
-    {
-      packet->CopyData (m_writer, packet->GetSize ());
-    }
-  else
-    {
-      packet->CopyData (m_writer, m_captureSize - wifiMonitorHeaderSize);      
-    }
-
-}
-    
-  
-void 
-PcapWriter::SetCaptureSize (uint32_t size)
-{
-  m_captureSize = size;
-}
-
-int8_t 
-PcapWriter::RoundToInt8 (double value)
-{
-  if (value < -128)
-    {
-      return -128;
-    }
-  if (value > 127)
-    {
-      return 127;
-    }
-  return ((int8_t) round(value));
-}
-
-
-
-
-
-
-void
-PcapWriter::WriteData (uint8_t const*buffer, uint32_t size)
-{
-  NS_LOG_FUNCTION(this << size);
-  m_writer->write ((char const *)buffer, size);
-}
-
-
-void
-PcapWriter::Write64 (uint64_t data)
-{
-  uint8_t buffer[8];
-  buffer[0] = (data >> 0) & 0xff;
-  buffer[1] = (data >> 8) & 0xff;
-  buffer[2] = (data >> 16) & 0xff;
-  buffer[3] = (data >> 24) & 0xff;
-  buffer[4] = (data >> 32) & 0xff;
-  buffer[5] = (data >> 40) & 0xff;
-  buffer[6] = (data >> 48) & 0xff;
-  buffer[7] = (data >> 56) & 0xff;
-  WriteData (buffer, 8);
-}
-
-void
-PcapWriter::Write32 (uint32_t data)
-{
-  uint8_t buffer[4];
-  buffer[0] = (data >> 0) & 0xff;
-  buffer[1] = (data >> 8) & 0xff;
-  buffer[2] = (data >> 16) & 0xff;
-  buffer[3] = (data >> 24) & 0xff;
-  WriteData (buffer, 4);
-}
-
-void
-PcapWriter::Write16 (uint16_t data)
-{
-  uint8_t buffer[2];
-  buffer[0] = (data >> 0) & 0xff;
-  buffer[1] = (data >> 8) & 0xff;
-  WriteData (buffer, 2);
-}
-
-void
-PcapWriter::Write8 (uint8_t data)
-{
-  WriteData (&data, 1);
-}
-
-
-
-} // namespace ns3
--- a/src/common/pcap-writer.h	Thu Feb 25 13:51:59 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,159 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef PCAP_WRITER_H
-#define PCAP_WRITER_H
-
-#include <stdint.h>
-#include "ns3/object.h"
-
-namespace ns3 {
-
-class Packet;
-
-/**
- * \ingroup common
- *
- * \brief Pcap output for Packet logger
- *
- * Log Packets to a file in pcap format which can be
- * read by pcap readers.
- */
-class PcapWriter : public Object
-{
-public:
-  static TypeId GetTypeId (void);
-  PcapWriter ();
-  ~PcapWriter ();
-
-  /**
-   * \param name the name of the file to store packet log into.
-   * This method creates the file if it does not exist. If it
-   * exists, the file is emptied.
-   */
-  void Open (std::string const &name);
-
-  /**
-   * Write a pcap header in the output file which specifies
-   * that the content of the file will be Packets with
-   * Ethernet/LLC/SNAP encapsulation. This method should
-   * be invoked before ns3::PcapWriter::writePacket and after
-   * ns3::PcapWriter::open.
-   */
-  void WriteEthernetHeader (void);
-
-  /**
-   * Write a pcap header in the output file which specifies
-   * that the content of the file will be IPv4 Packets. This 
-   * method should be invoked before ns3::PcapWriter::WritePacket 
-   * and after ns3::PcapWriter::Open.
-   */
-  void WriteIpHeader (void);
-
-  /**
-   * Write a pcap header in the output file which specifies
-   * that the content of the file will be 802.11 Packets. This 
-   * method should be invoked before ns3::PcapWriter::WritePacket 
-   * and after ns3::PcapWriter::Open.
-   */
-  void WriteWifiHeader (void);
-
-  /**
-   * Write a pcap header in the output file which specifies
-   * that the content of the file will be 802.11 Packets preceded by a
-   * radiotap header providing PHY layer info. This method should be
-   * invoked before ns3::PcapWriter::WritePacket and after
-   * ns3::PcapWriter::Open. 
-   */
-  void WriteWifiRadiotapHeader (void);
-
-  /**
-   * Write a pcap header in the output file which specifies
-   * that the content of the file will be 802.11 Packets preceded by a
-   * prism header providing PHY layer info. This method should be
-   * invoked before ns3::PcapWriter::WritePacket and after
-   * ns3::PcapWriter::Open. 
-   */
-  void WriteWifiPrismHeader (void);
-
-  /**
-   * Write a pcap header in the output file which specifies
-   * that the content of the file will be ppp Packets. This 
-   * method should be invoked before ns3::PcapWriter::WritePacket 
-   * and after ns3::PcapWriter::Open.
-   */
-  void WritePppHeader (void);
-
-  /**
-   * \param packet packet to write to output file
-   */
-  void WritePacket (Ptr<const Packet> packet);
-
-  /** 
-   * Write a Packet, possibly adding wifi PHY layer information to it
-   *
-   * @param packet the packet being received
-   * @param channelFreqMhz the frequency in MHz at which the packet is
-   * received. Note that in real devices this is normally the
-   * frequency to which  the receiver is tuned, and this can be
-   * different than the frequency at which the packet was originally
-   * transmitted. This is because it is possible to have the receiver
-   * tuned on a given channel and still to be able to receive packets
-   * on a nearby channel.
-   * @param channelNumber the channel number, as defined by the
-   * IEEE 802.11 standard. 
-   * @param rate the PHY data rate in units of 500kbps (i.e., the same
-   * units used both for the radiotap and for the prism header) 
-   * @param isShortPreamble true if short preamble is used, false otherwise
-   * @param isTx true if packet is being transmitted, false when
-   * packet is being received
-   * @param signalDbm signal power in dBm
-   * @param noiseDbm  noise power in dBm
-   */
-  void WriteWifiMonitorPacket(Ptr<const Packet> packet, uint16_t channelFreqMhz,  uint16_t channelNumber,
-                              uint32_t rate, bool isShortPreamble, bool isTx, 
-                              double signalDbm, double noiseDbm);
-
-  /** 
-   * Set the maximum number of bytes to be captured for each packet. 
-   * 
-   * @param size the maximum number of bytes to be captured. If zero
-   * (default), the whole packet will be captured. 
-   */
-  void SetCaptureSize (uint32_t size);
-
-
-private:
-  void WriteData (uint8_t const*buffer, uint32_t size);
-  void Write64 (uint64_t data);
-  void Write32 (uint32_t data);
-  void Write16 (uint16_t data);
-  void Write8 (uint8_t data);
-  void WriteHeader (uint32_t network);
-  int8_t RoundToInt8 (double value);
-  std::ofstream *m_writer;
-  uint32_t m_pcapMode;
-  uint32_t m_captureSize;
-  
-};
-
-} // namespace ns3
-
-#endif /* PCAP_WRITER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/propagation-delay-model.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,104 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "propagation-delay-model.h"
+#include "ns3/random-variable.h"
+#include "ns3/mobility-model.h"
+#include "ns3/double.h"
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (PropagationDelayModel);
+
+TypeId 
+PropagationDelayModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::PropagationDelayModel")
+    .SetParent<Object> ()
+    ;
+  return tid;
+}
+
+PropagationDelayModel::~PropagationDelayModel ()
+{}
+
+NS_OBJECT_ENSURE_REGISTERED (RandomPropagationDelayModel);
+
+TypeId 
+RandomPropagationDelayModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::RandomPropagationDelayModel")
+    .SetParent<PropagationDelayModel> ()
+    .AddConstructor<RandomPropagationDelayModel> ()
+    .AddAttribute ("Variable",
+                   "The random variable which generates random delays (s).",
+                   RandomVariableValue (UniformVariable (0.0, 1.0)),
+                   MakeRandomVariableAccessor (&RandomPropagationDelayModel::m_variable),
+                   MakeRandomVariableChecker ())
+    ;
+  return tid;
+}
+
+RandomPropagationDelayModel::RandomPropagationDelayModel ()
+{}
+RandomPropagationDelayModel::~RandomPropagationDelayModel ()
+{}
+Time 
+RandomPropagationDelayModel::GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const
+{
+  return Seconds (m_variable.GetValue ());
+}
+
+NS_OBJECT_ENSURE_REGISTERED (ConstantSpeedPropagationDelayModel);
+
+TypeId
+ConstantSpeedPropagationDelayModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::ConstantSpeedPropagationDelayModel")
+    .SetParent<PropagationDelayModel> ()
+    .AddConstructor<ConstantSpeedPropagationDelayModel> ()
+    .AddAttribute ("Speed", "The speed (m/s)",
+                   DoubleValue (300000000.0),
+                   MakeDoubleAccessor (&ConstantSpeedPropagationDelayModel::m_speed),
+                   MakeDoubleChecker<double> ())
+    ;
+  return tid;
+}
+
+ConstantSpeedPropagationDelayModel::ConstantSpeedPropagationDelayModel ()
+{}
+Time 
+ConstantSpeedPropagationDelayModel::GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const
+{
+  double distance = a->GetDistanceFrom (b);
+  double seconds = distance / m_speed;
+  return Seconds (seconds);
+}
+void 
+ConstantSpeedPropagationDelayModel::SetSpeed (double speed)
+{
+  m_speed = speed;
+}
+double 
+ConstantSpeedPropagationDelayModel::GetSpeed (void) const
+{
+  return m_speed;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/propagation-delay-model.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,96 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef PROPAGATION_DELAY_MODEL_H
+#define PROPAGATION_DELAY_MODEL_H
+
+#include "ns3/ptr.h"
+#include "ns3/object.h"
+#include "ns3/nstime.h"
+#include "ns3/random-variable.h"
+
+namespace ns3 {
+
+class MobilityModel;
+
+/**
+ * \brief calculate a propagation delay.
+ */
+class PropagationDelayModel : public Object
+{
+public:
+  static TypeId GetTypeId (void);
+  virtual ~PropagationDelayModel ();
+  /**
+   * \param a the source
+   * \param b the destination
+   * \returns the calculated propagation delay
+   *
+   * Calculate the propagation delay between the specified
+   * source and destination.
+   */
+  virtual Time GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const = 0;
+};
+
+/**
+ * \brief the propagation delay is random
+ */
+class RandomPropagationDelayModel : public PropagationDelayModel
+{
+public:
+  static TypeId GetTypeId (void);
+
+  /**
+   * Use the default parameters from PropagationDelayRandomDistribution.
+   */
+  RandomPropagationDelayModel ();
+  virtual ~RandomPropagationDelayModel ();
+  virtual Time GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const;
+private:
+  RandomVariable m_variable;
+};
+
+/**
+ * \brief the propagation speed is constant
+ */
+class ConstantSpeedPropagationDelayModel : public PropagationDelayModel
+{
+public:
+  static TypeId GetTypeId (void);
+
+  /**
+   * Use the default parameters from PropagationDelayConstantSpeed.
+   */
+  ConstantSpeedPropagationDelayModel ();
+  virtual Time GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const;
+  /**
+   * \param speed the new speed (m/s)
+   */
+  void SetSpeed (double speed);
+  /**
+   * \returns the current propagation speed (m/s).
+   */
+  double GetSpeed (void) const;
+private:
+  double m_speed;
+};
+
+} // namespace ns3
+
+#endif /* PROPAGATION_DELAY_MODEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/propagation-loss-model-test-suite.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,384 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 The Boeing Company
+ *
+ * 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
+ */
+
+#include "ns3/log.h"
+#include "ns3/abort.h"
+#include "ns3/test.h"
+#include "ns3/pcap-file.h"
+#include "ns3/config.h"
+#include "ns3/string.h"
+#include "ns3/uinteger.h"
+#include "ns3/double.h"
+#include "ns3/data-rate.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/internet-stack-helper.h"
+#include "ns3/ipv4-address-helper.h"
+#include "ns3/tcp-socket-factory.h"
+#include "ns3/yans-wifi-helper.h"
+#include "ns3/propagation-loss-model.h"
+#include "ns3/propagation-delay-model.h"
+#include "ns3/yans-wifi-channel.h"
+#include "ns3/yans-wifi-phy.h"
+#include "ns3/wifi-net-device.h"
+#include "ns3/mobility-helper.h"
+#include "ns3/constant-position-mobility-model.h"
+#include "ns3/nqos-wifi-mac-helper.h"
+#include "ns3/simulator.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("PropagationLossModelsTest");
+
+// ===========================================================================
+// This is a simple test to validate propagation loss models of ns-3 wifi.
+// See the chapter in the ns-3 testing and validation guide for more detail
+// ===========================================================================
+//
+class FriisPropagationLossModelTestCase : public TestCase
+{
+public:
+  FriisPropagationLossModelTestCase ();
+  virtual ~FriisPropagationLossModelTestCase ();
+
+private:
+  virtual bool DoRun (void);
+
+  typedef struct {
+    Vector m_position;
+    double m_pt;  // dBm
+    double m_pr;  // W
+    double m_tolerance;
+  } TestVector;
+
+  TestVectors<TestVector> m_testVectors;
+};
+
+FriisPropagationLossModelTestCase::FriisPropagationLossModelTestCase ()
+  : TestCase ("Check to see that the ns-3 Friis propagation loss model provides correct received power"), m_testVectors ()
+{
+}
+
+FriisPropagationLossModelTestCase::~FriisPropagationLossModelTestCase ()
+{
+}
+
+bool
+FriisPropagationLossModelTestCase::DoRun (void)
+{
+  // The ns-3 testing manual gives more background on the values selected
+  // for this test.  First, set a few defaults. 
+
+  // wavelength at 2.4 GHz is 0.125m
+  Config::SetDefault ("ns3::FriisPropagationLossModel::Lambda", DoubleValue (0.125));
+  Config::SetDefault ("ns3::FriisPropagationLossModel::SystemLoss", DoubleValue (1.0));
+
+  // Select a reference transmit power
+  // Pt = 10^(17.0206/10)/10^3 = .05035702 W
+  double txPowerW = 0.05035702;
+  double txPowerdBm = 10 * log10 (txPowerW) + 30;
+
+  //
+  // We want to test the propagation loss model calculations at a few chosen 
+  // distances and compare the results to those we have manually calculated
+  // according to the model documentation.  The model reference specifies, 
+  // for instance, that the received power at 100m according to the provided
+  // input power will be 4.98265e-10 W.  Since this value specifies the power
+  // to 1e-15 significance, we test the ns-3 calculated value for agreement 
+  // within 5e-16.
+  //
+  TestVector testVector;
+
+  testVector.m_position = Vector (100, 0, 0);
+  testVector.m_pt = txPowerdBm;
+  testVector.m_pr = 4.98265e-10;
+  testVector.m_tolerance = 5e-16;
+  m_testVectors.Add (testVector);
+
+  testVector.m_position = Vector (500, 0, 0);
+  testVector.m_pt = txPowerdBm;
+  testVector.m_pr = 1.99306e-11;
+  testVector.m_tolerance = 5e-17;
+  m_testVectors.Add (testVector);
+
+  testVector.m_position = Vector (1000, 0, 0);
+  testVector.m_pt = txPowerdBm;
+  testVector.m_pr = 4.98265e-12;
+  testVector.m_tolerance = 5e-18;
+  m_testVectors.Add (testVector);
+
+  testVector.m_position = Vector (2000, 0, 0);
+  testVector.m_pt = txPowerdBm;
+  testVector.m_pr = 1.24566e-12;
+  testVector.m_tolerance = 5e-18;
+  m_testVectors.Add (testVector);
+
+  // Now, check that the received power values are expected
+
+  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> (); 
+  a->SetPosition (Vector (0,0,0));
+  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> (); 
+
+  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> (); 
+  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
+    {
+      testVector = m_testVectors.Get (i);
+      b->SetPosition (testVector.m_position);
+      double resultdBm = lossModel->CalcRxPower (testVector.m_pt, a, b);
+      double resultW =   pow (10.0, resultdBm/10.0)/1000;
+      NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power");
+    }
+	
+  return GetErrorStatus ();
+}
+
+// Added for Two-Ray Ground Model - tomhewer@mac.com
+
+class TwoRayGroundPropagationLossModelTestCase : public TestCase
+{
+public:
+  TwoRayGroundPropagationLossModelTestCase ();
+  virtual ~TwoRayGroundPropagationLossModelTestCase ();
+  
+private:
+  virtual bool DoRun (void);
+  
+  typedef struct
+  {
+    Vector m_position;
+    double m_pt;  // dBm
+    double m_pr;  // W
+    double m_tolerance;
+  } TestVector;
+  
+  TestVectors<TestVector> m_testVectors;
+};
+
+TwoRayGroundPropagationLossModelTestCase::TwoRayGroundPropagationLossModelTestCase ()
+: TestCase ("Check to see that the ns-3 TwoRayGround propagation loss model provides correct received power"),
+m_testVectors ()
+{
+}
+
+TwoRayGroundPropagationLossModelTestCase::~TwoRayGroundPropagationLossModelTestCase ()
+{
+}
+
+bool
+TwoRayGroundPropagationLossModelTestCase::DoRun (void)
+{
+  // wavelength at 2.4 GHz is 0.125m
+  Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::Lambda", DoubleValue (0.125));
+  Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::SystemLoss", DoubleValue (1.0));
+  
+  // set antenna height to 1.5m above z coordinate
+  Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::HeightAboveZ", DoubleValue (1.5));
+  
+  // Select a reference transmit power of 17.0206 dBm
+  // Pt = 10^(17.0206/10)/10^3 = .05035702 W
+  double txPowerW = 0.05035702;
+  double txPowerdBm = 10 * log10 (txPowerW) + 30;
+  
+  //
+  // As with the Friis tests above, we want to test the propagation loss 
+  // model calculations at a few chosen distances and compare the results 
+  // to those we can manually calculate. Let us test the ns-3 calculated 
+  // value for agreement to be within 5e-16, as above.
+  //
+  TestVector testVector;
+  
+  // Below the Crossover distance use Friis so this test should be the same as that above
+  // Crossover = (4 * PI * TxAntennaHeight * RxAntennaHeight) / Lamdba
+  // Crossover = (4 * PI * 1.5 * 1.5) / 0.125 = 226.1946m
+  
+  testVector.m_position = Vector (100, 0, 0);
+  testVector.m_pt = txPowerdBm;
+  testVector.m_pr = 4.98265e-10;
+  testVector.m_tolerance = 5e-16;
+  m_testVectors.Add (testVector);
+  
+  // These values are above the crossover distance and therefore use the Two Ray calculation
+  
+  testVector.m_position = Vector (500, 0, 0);
+  testVector.m_pt = txPowerdBm;
+  testVector.m_pr = 4.07891862e-12;
+  testVector.m_tolerance = 5e-16;
+  m_testVectors.Add (testVector);
+  
+  testVector.m_position = Vector (1000, 0, 0);
+  testVector.m_pt = txPowerdBm;
+  testVector.m_pr = 2.5493241375e-13;
+  testVector.m_tolerance = 5e-16;
+  m_testVectors.Add (testVector);
+  
+  testVector.m_position = Vector (2000, 0, 0);
+  testVector.m_pt = txPowerdBm;
+  testVector.m_pr = 1.593327585938e-14;
+  testVector.m_tolerance = 5e-16;
+  m_testVectors.Add (testVector);
+  
+  // Repeat the tests for non-zero z coordinates
+  
+  // Pr = (0.05035702 * (1.5*1.5) * (2.5*2.5)) / (500*500*500*500) = 1.13303295e-11
+  // dCross = (4 * pi * 1.5 * 2.5) / 0.125 = 376.99m
+  testVector.m_position = Vector (500, 0, 1);
+  testVector.m_pt = txPowerdBm;
+  testVector.m_pr = 1.13303295e-11;
+  testVector.m_tolerance = 5e-16;
+  m_testVectors.Add (testVector);
+  
+  // Pr = (0.05035702 * (1.5*1.5) * (5.5*5.5)) / (1000*1000*1000*1000) = 3.42742467375e-12
+  // dCross = (4 * pi * 1.5 * 5.5) / 0.125 = 829.38m
+  testVector.m_position = Vector (1000, 0, 4);
+  testVector.m_pt = txPowerdBm;
+  testVector.m_pr = 3.42742467375e-12;
+  testVector.m_tolerance = 5e-16;
+  m_testVectors.Add (testVector);
+  
+  // Pr = (0.05035702 * (1.5*1.5) * (11.5*11.5)) / (2000*2000*2000*2000) = 9.36522547734e-13
+  // dCross = (4 * pi * 1.5 * 11.5) / 0.125 = 1734.15m
+  testVector.m_position = Vector (2000, 0, 10);
+  testVector.m_pt = txPowerdBm;
+  testVector.m_pr = 9.36522547734e-13;
+  testVector.m_tolerance = 5e-16;
+  m_testVectors.Add (testVector);
+  
+  
+  // Now, check that the received power values are expected
+  
+  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> (); 
+  a->SetPosition (Vector (0,0,0));
+  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> (); 
+  
+  Ptr<TwoRayGroundPropagationLossModel> lossModel = CreateObject<TwoRayGroundPropagationLossModel> (); 
+  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
+  {
+    testVector = m_testVectors.Get (i);
+    b->SetPosition (testVector.m_position);
+    double resultdBm = lossModel->CalcRxPower (testVector.m_pt, a, b);
+    double resultW =   pow (10.0, resultdBm / 10.0) / 1000;
+    NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power");
+  }
+  
+  return GetErrorStatus ();
+}
+
+
+class LogDistancePropagationLossModelTestCase : public TestCase
+{
+public:
+  LogDistancePropagationLossModelTestCase ();
+  virtual ~LogDistancePropagationLossModelTestCase ();
+
+private:
+  virtual bool DoRun (void);
+
+  typedef struct {
+    Vector m_position;
+    double m_pt;  // dBm
+    double m_pr;  // W
+    double m_tolerance;
+  } TestVector;
+
+  TestVectors<TestVector> m_testVectors;
+};
+
+LogDistancePropagationLossModelTestCase::LogDistancePropagationLossModelTestCase ()
+  : TestCase ("Check to see that the ns-3 Log Distance propagation loss model provides correct received power"), m_testVectors ()
+{
+}
+
+LogDistancePropagationLossModelTestCase::~LogDistancePropagationLossModelTestCase ()
+{
+}
+
+bool
+LogDistancePropagationLossModelTestCase::DoRun (void)
+{
+  // reference loss at 2.4 GHz is 40.045997
+  Config::SetDefault ("ns3::LogDistancePropagationLossModel::ReferenceLoss", DoubleValue (40.045997));
+  Config::SetDefault ("ns3::LogDistancePropagationLossModel::Exponent", DoubleValue (3));
+
+  // Select a reference transmit power
+  // Pt = 10^(17.0206/10)/10^3 = .05035702 W
+  double txPowerW = 0.05035702;
+  double txPowerdBm = 10 * log10 (txPowerW) + 30;
+
+  //
+  // We want to test the propagation loss model calculations at a few chosen 
+  // distances and compare the results to those we have manually calculated
+  // according to the model documentation.  The following "TestVector" objects
+  // will drive the test.
+  //
+  TestVector testVector;
+
+  testVector.m_position = Vector (10, 0, 0);
+  testVector.m_pt = txPowerdBm;
+  testVector.m_pr = 4.98265e-9;
+  testVector.m_tolerance = 5e-15; 
+  m_testVectors.Add (testVector);
+
+  testVector.m_position = Vector (20, 0, 0);
+  testVector.m_pt = txPowerdBm;
+  testVector.m_pr = 6.22831e-10;
+  testVector.m_tolerance = 5e-16;
+  m_testVectors.Add (testVector);
+
+  testVector.m_position = Vector (40, 0, 0);
+  testVector.m_pt = txPowerdBm;
+  testVector.m_pr = 7.78539e-11;
+  testVector.m_tolerance = 5e-17;
+  m_testVectors.Add (testVector);
+
+  testVector.m_position = Vector (80, 0, 0);
+  testVector.m_pt = txPowerdBm;
+  testVector.m_pr = 9.73173e-12;
+  testVector.m_tolerance = 5e-17;
+  m_testVectors.Add (testVector);
+
+  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> (); 
+  a->SetPosition (Vector (0,0,0));
+  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> (); 
+
+  Ptr<LogDistancePropagationLossModel> lossModel = CreateObject<LogDistancePropagationLossModel> (); 
+  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
+    {
+      testVector = m_testVectors.Get (i);
+      b->SetPosition (testVector.m_position);
+      double resultdBm = lossModel->CalcRxPower (testVector.m_pt, a, b);
+      double resultW =   pow (10.0, resultdBm/10.0)/1000;
+      NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power");
+    }
+	
+  return GetErrorStatus ();
+}
+
+class PropagationLossModelsTestSuite : public TestSuite
+{
+public:
+  PropagationLossModelsTestSuite ();
+};
+
+PropagationLossModelsTestSuite::PropagationLossModelsTestSuite ()
+  : TestSuite ("propagation-loss-model", UNIT)
+{
+  AddTestCase (new FriisPropagationLossModelTestCase);
+  AddTestCase (new TwoRayGroundPropagationLossModelTestCase);
+  AddTestCase (new LogDistancePropagationLossModelTestCase);
+}
+
+PropagationLossModelsTestSuite WifiPropagationLossModelsTestSuite;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/propagation-loss-model.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,717 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
+ * Contributions: Tom Hewer <tomhewer@mac.com> for Two Ray Ground Model
+ */
+
+#include "propagation-loss-model.h"
+#include "ns3/log.h"
+#include "ns3/mobility-model.h"
+#include "ns3/boolean.h"
+#include "ns3/double.h"
+#include <math.h>
+
+NS_LOG_COMPONENT_DEFINE ("PropagationLossModel");
+
+namespace ns3 {
+
+// ------------------------------------------------------------------------- //
+
+NS_OBJECT_ENSURE_REGISTERED (PropagationLossModel);
+
+TypeId 
+PropagationLossModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::PropagationLossModel")
+    .SetParent<Object> ()
+    ;
+  return tid;
+}
+
+PropagationLossModel::PropagationLossModel ()
+  : m_next (0)
+{}
+
+PropagationLossModel::~PropagationLossModel ()
+{}
+
+void 
+PropagationLossModel::SetNext (Ptr<PropagationLossModel> next)
+{
+  m_next = next;
+}
+
+double 
+PropagationLossModel::CalcRxPower (double txPowerDbm,
+                                   Ptr<MobilityModel> a,
+                                   Ptr<MobilityModel> b) const
+{
+  double self = DoCalcRxPower (txPowerDbm, a, b);
+  if (m_next != 0)
+    {
+      self = m_next->CalcRxPower (self, a, b);
+    }
+  return self;
+}
+
+// ------------------------------------------------------------------------- //
+
+NS_OBJECT_ENSURE_REGISTERED (RandomPropagationLossModel);
+
+TypeId 
+RandomPropagationLossModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::RandomPropagationLossModel")
+    .SetParent<PropagationLossModel> ()
+    .AddConstructor<RandomPropagationLossModel> ()
+    .AddAttribute ("Variable", "The random variable used to pick a loss everytime CalcRxPower is invoked.",
+                   RandomVariableValue (ConstantVariable (1.0)),
+                   MakeRandomVariableAccessor (&RandomPropagationLossModel::m_variable),
+                   MakeRandomVariableChecker ())
+    ;
+  return tid;
+}
+RandomPropagationLossModel::RandomPropagationLossModel ()
+  : PropagationLossModel ()
+{}
+
+RandomPropagationLossModel::~RandomPropagationLossModel ()
+{}
+
+double 
+RandomPropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                           Ptr<MobilityModel> a,
+                                           Ptr<MobilityModel> b) const
+{
+  double rxc = -m_variable.GetValue ();
+  NS_LOG_DEBUG ("attenuation coefficent="<<rxc<<"Db");
+  return txPowerDbm + rxc;
+}
+
+// ------------------------------------------------------------------------- //
+
+NS_OBJECT_ENSURE_REGISTERED (FriisPropagationLossModel);
+
+const double FriisPropagationLossModel::PI = 3.14159265358979323846;
+
+TypeId 
+FriisPropagationLossModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::FriisPropagationLossModel")
+    .SetParent<PropagationLossModel> ()
+    .AddConstructor<FriisPropagationLossModel> ()
+    .AddAttribute ("Lambda", 
+                   "The wavelength  (default is 5.15 GHz at 300 000 km/s).",
+                   DoubleValue (300000000.0 / 5.150e9),
+                   MakeDoubleAccessor (&FriisPropagationLossModel::m_lambda),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("SystemLoss", "The system loss",
+                   DoubleValue (1.0),
+                   MakeDoubleAccessor (&FriisPropagationLossModel::m_systemLoss),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("MinDistance", 
+                   "The distance under which the propagation model refuses to give results (m)",
+                   DoubleValue (0.5),
+                   MakeDoubleAccessor (&FriisPropagationLossModel::SetMinDistance,
+                                       &FriisPropagationLossModel::GetMinDistance),
+                   MakeDoubleChecker<double> ())
+    ;
+  return tid;
+}
+
+FriisPropagationLossModel::FriisPropagationLossModel ()
+{}
+void 
+FriisPropagationLossModel::SetSystemLoss (double systemLoss)
+{
+  m_systemLoss = systemLoss;
+}
+double 
+FriisPropagationLossModel::GetSystemLoss (void) const
+{
+  return m_systemLoss;
+}
+void 
+FriisPropagationLossModel::SetMinDistance (double minDistance)
+{
+  m_minDistance = minDistance;
+}
+double 
+FriisPropagationLossModel::GetMinDistance (void) const
+{
+  return m_minDistance;
+}
+void 
+FriisPropagationLossModel::SetLambda (double frequency, double speed)
+{
+  m_lambda = speed / frequency;
+}
+void 
+FriisPropagationLossModel::SetLambda (double lambda)
+{
+  m_lambda = lambda;
+}
+double 
+FriisPropagationLossModel::GetLambda (void) const
+{
+  return m_lambda;
+}
+
+double 
+FriisPropagationLossModel::DbmToW (double dbm) const
+{
+  double mw = pow(10.0,dbm/10.0);
+  return mw / 1000.0;
+}
+
+double
+FriisPropagationLossModel::DbmFromW (double w) const
+{
+  double dbm = log10 (w * 1000.0) * 10.0;
+  return dbm;
+}
+
+double 
+FriisPropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                          Ptr<MobilityModel> a,
+                                          Ptr<MobilityModel> b) const
+{
+  /*
+   * Friis free space equation:
+   * where Pt, Gr, Gr and P are in Watt units
+   * L is in meter units.
+   *
+   *    P     Gt * Gr * (lambda^2)
+   *   --- = ---------------------
+   *    Pt     (4 * pi * d)^2 * L
+   *
+   * Gt: tx gain (unit-less)
+   * Gr: rx gain (unit-less)
+   * Pt: tx power (W)
+   * d: distance (m)
+   * L: system loss
+   * lambda: wavelength (m)
+   *
+   * Here, we ignore tx and rx gain and the input and output values 
+   * are in dB or dBm:
+   *
+   *                           lambda^2
+   * rx = tx +  10 log10 (-------------------)
+   *                       (4 * pi * d)^2 * L
+   *
+   * rx: rx power (dB)
+   * tx: tx power (dB)
+   * d: distance (m)
+   * L: system loss (unit-less)
+   * lambda: wavelength (m)
+   */
+  double distance = a->GetDistanceFrom (b);
+  if (distance <= m_minDistance)
+    {
+      return txPowerDbm;
+    }
+  double numerator = m_lambda * m_lambda;
+  double denominator = 16 * PI * PI * distance * distance * m_systemLoss;
+  double pr = 10 * log10 (numerator / denominator);
+  NS_LOG_DEBUG ("distance="<<distance<<"m, attenuation coefficient="<<pr<<"dB");
+  return txPowerDbm + pr;
+}
+
+// ------------------------------------------------------------------------- //
+// -- Two-Ray Ground Model ported from NS-2 -- tomhewer@mac.com -- Nov09 //
+
+NS_OBJECT_ENSURE_REGISTERED (TwoRayGroundPropagationLossModel);
+
+const double TwoRayGroundPropagationLossModel::PI = 3.14159265358979323846;
+
+TypeId 
+TwoRayGroundPropagationLossModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::TwoRayGroundPropagationLossModel")
+    .SetParent<PropagationLossModel> ()
+    .AddConstructor<TwoRayGroundPropagationLossModel> ()
+    .AddAttribute ("Lambda",
+                   "The wavelength  (default is 5.15 GHz at 300 000 km/s).",
+                   DoubleValue (300000000.0 / 5.150e9),
+                   MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::m_lambda),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("SystemLoss", "The system loss",
+                   DoubleValue (1.0),
+                   MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::m_systemLoss),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("MinDistance",
+                   "The distance under which the propagation model refuses to give results (m)",
+                   DoubleValue (0.5),
+                   MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::SetMinDistance,
+                                       &TwoRayGroundPropagationLossModel::GetMinDistance),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("HeightAboveZ",
+                   "The height of the antenna (m) above the node's Z coordinate",
+                   DoubleValue (0),
+                   MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::m_heightAboveZ),
+                   MakeDoubleChecker<double> ())
+  ;
+  return tid;
+}
+
+TwoRayGroundPropagationLossModel::TwoRayGroundPropagationLossModel ()
+{
+}
+void
+TwoRayGroundPropagationLossModel::SetSystemLoss (double systemLoss)
+{
+  m_systemLoss = systemLoss;
+}
+double
+TwoRayGroundPropagationLossModel::GetSystemLoss (void) const
+{
+  return m_systemLoss;
+}
+void
+TwoRayGroundPropagationLossModel::SetMinDistance (double minDistance)
+{
+  m_minDistance = minDistance;
+}
+double
+TwoRayGroundPropagationLossModel::GetMinDistance (void) const
+{
+  return m_minDistance;
+}
+void
+TwoRayGroundPropagationLossModel::SetHeightAboveZ (double heightAboveZ)
+{
+  m_heightAboveZ = heightAboveZ;
+}
+void 
+TwoRayGroundPropagationLossModel::SetLambda (double frequency, double speed)
+{
+  m_lambda = speed / frequency;
+}
+void 
+TwoRayGroundPropagationLossModel::SetLambda (double lambda)
+{
+  m_lambda = lambda;
+}
+double 
+TwoRayGroundPropagationLossModel::GetLambda (void) const
+{
+  return m_lambda;
+}
+
+double 
+TwoRayGroundPropagationLossModel::DbmToW (double dbm) const
+{
+  double mw = pow (10.0,dbm / 10.0);
+  return mw / 1000.0;
+}
+
+double
+TwoRayGroundPropagationLossModel::DbmFromW (double w) const
+{
+  double dbm = log10 (w * 1000.0) * 10.0;
+  return dbm;
+}
+
+double 
+TwoRayGroundPropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                                 Ptr<MobilityModel> a,
+                                                 Ptr<MobilityModel> b) const
+{
+  /*
+   * Two-Ray Ground equation:
+   *
+   * where Pt, Gt and Gr are in dBm units
+   * L, Ht and Hr are in meter units.
+   *
+   *   Pr      Gt * Gr * (Ht^2 * Hr^2)
+   *   -- =  (-------------------------)
+   *   Pt            d^4 * L
+   *
+   * Gt: tx gain (unit-less)
+   * Gr: rx gain (unit-less)
+   * Pt: tx power (dBm)
+   * d: distance (m)
+   * L: system loss
+   * Ht: Tx antenna height (m)
+   * Hr: Rx antenna height (m)
+   * lambda: wavelength (m)
+   *
+   * As with the Friis model we ignore tx and rx gain and output values
+   * are in dB or dBm
+   *
+   *                      (Ht * Ht) * (Hr * Hr)
+   * rx = tx + 10 log10 (-----------------------)
+   *                      (d * d * d * d) * L
+   */
+  double distance = a->GetDistanceFrom (b);
+  if (distance <= m_minDistance)
+    {
+      return txPowerDbm;
+    }
+
+  // Set the height of the Tx and Rx antennae
+  double txAntHeight = a->GetPosition ().z + m_heightAboveZ;
+  double rxAntHeight = b->GetPosition ().z + m_heightAboveZ;
+
+  // Calculate a crossover distance, under which we use Friis
+  /*
+   * 
+   * dCross = (4 * pi * Ht * Hr) / lambda
+   *
+   */
+
+  double dCross = (4 * PI * txAntHeight * rxAntHeight) / GetLambda ();
+  double tmp = 0;
+  if (distance <= dCross)
+    {
+      // We use Friis
+      double numerator = m_lambda * m_lambda;
+      tmp = PI * distance;
+      double denominator = 16 * tmp * tmp * m_systemLoss;
+      double pr = 10 * log10 (numerator / denominator);
+      NS_LOG_DEBUG ("Receiver within crossover (" << dCross << "m) for Two_ray path; using Friis");
+      NS_LOG_DEBUG ("distance=" << distance << "m, attenuation coefficient=" << pr << "dB");
+      return txPowerDbm + pr;
+    }
+  else   // Use Two-Ray Pathloss
+    {
+      tmp = txAntHeight * rxAntHeight;
+      double rayNumerator = tmp * tmp;
+      tmp = distance * distance;
+      double rayDenominator = tmp * tmp * m_systemLoss;
+      double rayPr = 10 * log10 (rayNumerator / rayDenominator);
+      NS_LOG_DEBUG ("distance=" << distance << "m, attenuation coefficient=" << rayPr << "dB");
+      return txPowerDbm + rayPr;
+
+    }
+}
+
+
+// ------------------------------------------------------------------------- //
+
+NS_OBJECT_ENSURE_REGISTERED (LogDistancePropagationLossModel);
+
+TypeId
+LogDistancePropagationLossModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::LogDistancePropagationLossModel")
+    .SetParent<PropagationLossModel> ()
+    .AddConstructor<LogDistancePropagationLossModel> ()
+    .AddAttribute ("Exponent",
+                   "The exponent of the Path Loss propagation model",
+                   DoubleValue (3.0),
+                   MakeDoubleAccessor (&LogDistancePropagationLossModel::m_exponent),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("ReferenceDistance",
+                   "The distance at which the reference loss is calculated (m)",
+                   DoubleValue (1.0),
+                   MakeDoubleAccessor (&LogDistancePropagationLossModel::m_referenceDistance),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("ReferenceLoss",
+                   "The reference loss at reference distance (dB). (Default is Friis at 1m with 5.15 GHz)",
+                   DoubleValue (46.6777),
+                   MakeDoubleAccessor (&LogDistancePropagationLossModel::m_referenceLoss),
+                   MakeDoubleChecker<double> ())
+    ;
+  return tid;
+                   
+}
+
+LogDistancePropagationLossModel::LogDistancePropagationLossModel ()
+{}
+
+void 
+LogDistancePropagationLossModel::SetPathLossExponent (double n)
+{
+  m_exponent = n;
+}
+void 
+LogDistancePropagationLossModel::SetReference (double referenceDistance, double referenceLoss)
+{
+  m_referenceDistance = referenceDistance;
+  m_referenceLoss = referenceLoss;
+}
+double 
+LogDistancePropagationLossModel::GetPathLossExponent (void) const
+{
+  return m_exponent;
+}
+  
+double 
+LogDistancePropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                                Ptr<MobilityModel> a,
+                                                Ptr<MobilityModel> b) const
+{
+  double distance = a->GetDistanceFrom (b);
+  if (distance <= m_referenceDistance)
+    {
+      return txPowerDbm;
+    }
+  /**
+   * The formula is:
+   * rx = 10 * log (Pr0(tx)) - n * 10 * log (d/d0)
+   *
+   * Pr0: rx power at reference distance d0 (W)
+   * d0: reference distance: 1.0 (m)
+   * d: distance (m)
+   * tx: tx power (dB)
+   * rx: dB
+   *
+   * Which, in our case is:
+   *
+   * rx = rx0(tx) - 10 * n * log (d/d0)
+   */
+  double pathLossDb = 10 * m_exponent * log10 (distance / m_referenceDistance);
+  double rxc = -m_referenceLoss - pathLossDb;
+  NS_LOG_DEBUG ("distance="<<distance<<"m, reference-attenuation="<<-m_referenceLoss<<"dB, "<<
+		"attenuation coefficient="<<rxc<<"db");
+  return txPowerDbm + rxc;
+}
+
+// ------------------------------------------------------------------------- //
+
+NS_OBJECT_ENSURE_REGISTERED (ThreeLogDistancePropagationLossModel);
+
+TypeId
+ThreeLogDistancePropagationLossModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::ThreeLogDistancePropagationLossModel")
+    .SetParent<PropagationLossModel> ()
+    .AddConstructor<ThreeLogDistancePropagationLossModel> ()
+    .AddAttribute ("Distance0",
+                   "Beginning of the first (near) distance field",
+                   DoubleValue (1.0),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance0),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Distance1",
+                   "Beginning of the second (middle) distance field.",
+                   DoubleValue (200.0),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance1),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Distance2",
+                   "Beginning of the third (far) distance field.",
+                   DoubleValue (500.0),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance2),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Exponent0",
+                   "The exponent for the first field.",
+                   DoubleValue (1.9),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent0),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Exponent1",
+                   "The exponent for the second field.",
+                   DoubleValue (3.8),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent1),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Exponent2",
+                   "The exponent for the third field.",
+                   DoubleValue (3.8),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent2),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("ReferenceLoss",
+                   "The reference loss at distance d0 (dB). (Default is Friis at 1m with 5.15 GHz)",
+                   DoubleValue (46.6777),
+                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_referenceLoss),
+                   MakeDoubleChecker<double> ())
+    ;
+  return tid;
+                   
+}
+
+ThreeLogDistancePropagationLossModel::ThreeLogDistancePropagationLossModel ()
+{
+}
+
+double 
+ThreeLogDistancePropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                                     Ptr<MobilityModel> a,
+                                                     Ptr<MobilityModel> b) const
+{
+  double distance = a->GetDistanceFrom (b);
+  NS_ASSERT(distance >= 0);
+
+  // See doxygen comments for the formula and explanation
+
+  double pathLossDb;
+
+  if (distance < m_distance0)
+    {
+      pathLossDb = 0;
+    }
+  else if (distance < m_distance1)
+    {
+      pathLossDb = m_referenceLoss
+        + 10 * m_exponent0 * log10(distance / m_distance0);
+    }
+  else if (distance < m_distance2)
+    {
+      pathLossDb = m_referenceLoss
+        + 10 * m_exponent0 * log10(m_distance1 / m_distance0)
+        + 10 * m_exponent1 * log10(distance / m_distance1);
+    }
+  else
+    {
+      pathLossDb = m_referenceLoss
+        + 10 * m_exponent0 * log10(m_distance1 / m_distance0)
+        + 10 * m_exponent1 * log10(m_distance2 / m_distance1)
+        + 10 * m_exponent2 * log10(distance / m_distance2);
+    }
+
+  NS_LOG_DEBUG ("ThreeLogDistance distance=" << distance << "m, " <<
+                "attenuation=" << pathLossDb << "dB");
+
+  return txPowerDbm - pathLossDb;
+}
+
+// ------------------------------------------------------------------------- //
+
+NS_OBJECT_ENSURE_REGISTERED (NakagamiPropagationLossModel);
+
+TypeId
+NakagamiPropagationLossModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::NakagamiPropagationLossModel")
+    .SetParent<PropagationLossModel> ()
+    .AddConstructor<NakagamiPropagationLossModel> ()
+    .AddAttribute ("Distance1",
+                   "Beginning of the second distance field. Default is 80m.",
+                   DoubleValue (80.0),
+                   MakeDoubleAccessor (&NakagamiPropagationLossModel::m_distance1),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Distance2",
+                   "Beginning of the third distance field. Default is 200m.",
+                   DoubleValue (200.0),
+                   MakeDoubleAccessor (&NakagamiPropagationLossModel::m_distance2),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("m0",
+                   "m0 for distances smaller than Distance1. Default is 1.5.",
+                   DoubleValue (1.5),
+                   MakeDoubleAccessor (&NakagamiPropagationLossModel::m_m0),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("m1",
+                   "m1 for distances smaller than Distance2. Default is 0.75.",
+                   DoubleValue (0.75),
+                   MakeDoubleAccessor (&NakagamiPropagationLossModel::m_m1),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("m2",
+                   "m2 for distances greater than Distance2. Default is 0.75.",
+                   DoubleValue (0.75),
+                   MakeDoubleAccessor (&NakagamiPropagationLossModel::m_m2),
+                   MakeDoubleChecker<double> ())
+    ;
+  return tid;
+                   
+}
+
+NakagamiPropagationLossModel::NakagamiPropagationLossModel ()
+{}
+
+double 
+NakagamiPropagationLossModel::DoCalcRxPower (double txPowerDbm,
+                                             Ptr<MobilityModel> a,
+                                             Ptr<MobilityModel> b) const
+{
+  // select m parameter
+
+  double distance = a->GetDistanceFrom (b);
+  NS_ASSERT(distance >= 0);
+
+  double m;
+  if (distance < m_distance1)
+    {
+      m = m_m0;
+    }
+  else if (distance < m_distance2)
+    {
+      m = m_m1;
+    }
+  else
+    {
+      m = m_m2;
+    }
+  
+  // the current power unit is dBm, but Watt is put into the Nakagami /
+  // Rayleigh distribution.
+  double powerW = pow(10, (txPowerDbm - 30) / 10);
+
+  double resultPowerW;
+
+  // switch between Erlang- and Gamma distributions: this is only for
+  // speed. (Gamma is equal to Erlang for any positive integer m.)
+  unsigned int int_m = static_cast<unsigned int>(floor(m));
+
+  if (int_m == m)
+    {
+      resultPowerW = m_erlangRandomVariable.GetValue(int_m, powerW / m);
+    }
+  else
+    {
+      resultPowerW = m_gammaRandomVariable.GetValue(m, powerW / m);
+    }
+
+  double resultPowerDbm = 10 * log10(resultPowerW) + 30;
+
+  NS_LOG_DEBUG ("Nakagami distance=" << distance << "m, " <<
+                "power=" << powerW <<"W, " <<
+                "resultPower=" << resultPowerW << "W=" << resultPowerDbm << "dBm");
+
+  return resultPowerDbm;
+}
+
+// ------------------------------------------------------------------------- //
+
+NS_OBJECT_ENSURE_REGISTERED (FixedRssLossModel);
+
+TypeId 
+FixedRssLossModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::FixedRssLossModel")
+    .SetParent<PropagationLossModel> ()
+    .AddConstructor<FixedRssLossModel> ()
+    .AddAttribute ("Rss", "The fixed receiver Rss.",
+                   DoubleValue (-150.0),
+                   MakeDoubleAccessor (&FixedRssLossModel::m_rss),
+                   MakeDoubleChecker<double> ())
+    ;
+  return tid;
+}
+FixedRssLossModel::FixedRssLossModel ()
+  : PropagationLossModel ()
+{}
+
+FixedRssLossModel::~FixedRssLossModel ()
+{}
+
+void 
+FixedRssLossModel::SetRss (double rss)
+{
+  m_rss = rss;
+}
+
+double 
+FixedRssLossModel::DoCalcRxPower (double txPowerDbm,
+                                           Ptr<MobilityModel> a,
+                                           Ptr<MobilityModel> b) const
+{
+  return m_rss;
+}
+
+// ------------------------------------------------------------------------- //
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/propagation-loss-model.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,467 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
+ * Contributions: Gary Pei <guangyu.pei@boeing.com> for fixed RSS
+ * Contributions: Tom Hewer <tomhewer@mac.com> for two ray ground model
+ */
+
+#ifndef PROPAGATION_LOSS_MODEL_H
+#define PROPAGATION_LOSS_MODEL_H
+
+#include "ns3/object.h"
+#include "ns3/random-variable.h"
+
+namespace ns3 {
+
+class MobilityModel;
+
+/**
+ * \brief Modelize the propagation loss through a transmission medium
+ *
+ * Calculate the receive power (dbm) from a transmit power (dbm)
+ * and a mobility model for the source and destination positions.
+ */
+class PropagationLossModel : public Object
+{
+public:
+  static TypeId GetTypeId (void);
+
+  PropagationLossModel ();
+  virtual ~PropagationLossModel ();
+
+  void SetNext (Ptr<PropagationLossModel> next);
+
+  /**
+   * \param txPowerDbm current transmission power (in dBm)
+   * \param a the mobility model of the source
+   * \param b the mobility model of the destination
+   * \returns the reception power after adding/multiplying propagation loss (in dBm)
+   */
+  double CalcRxPower (double txPowerDbm,
+                      Ptr<MobilityModel> a,
+                      Ptr<MobilityModel> b) const;
+private:
+  PropagationLossModel (const PropagationLossModel &o);
+  PropagationLossModel &operator = (const PropagationLossModel &o);
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const = 0;
+
+  Ptr<PropagationLossModel> m_next;
+};
+
+/**
+ * \brief The propagation loss follows a random distribution.
+ */ 
+class RandomPropagationLossModel : public PropagationLossModel
+{
+public:
+  static TypeId GetTypeId (void);
+
+  RandomPropagationLossModel ();
+  virtual ~RandomPropagationLossModel ();
+
+private:
+  RandomPropagationLossModel (const RandomPropagationLossModel &o);
+  RandomPropagationLossModel & operator = (const RandomPropagationLossModel &o);
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
+  RandomVariable m_variable;
+};
+
+/**
+ * \brief a Friis propagation loss model
+ *
+ * The Friis propagation loss model was first described in
+ * "A Note on a Simple Transmission Formula", by 
+ * "Harald T. Friis".
+ * 
+ * The original equation was described as:
+ *  \f$ \frac{P_r}{P_t} = \frac{A_r A_t}{d^2\lambda^2} \f$
+ *  with the following equation for the case of an
+ *  isotropic antenna with no heat loss:
+ *  \f$ A_{isotr.} = \frac{\lambda^2}{4\pi} \f$
+ *
+ * The final equation becomes:
+ * \f$ \frac{P_r}{P_t} = \frac{\lambda^2}{(4 \pi d)^2} \f$
+ *
+ * Modern extensions to this original equation are:
+ * \f$ P_r = \frac{P_t G_t G_r \lambda^2}{(4 \pi d)^2 L}\f$
+ *
+ * With:
+ *  - \f$ P_r \f$ : reception power (W)
+ *  - \f$ P_t \f$ : transmission power (W)
+ *  - \f$ G_t \f$ : transmission gain (unit-less)
+ *  - \f$ G_r \f$ : reception gain (unit-less)
+ *  - \f$ \lambda \f$ : wavelength (m)
+ *  - \f$ d \f$ : distance (m)
+ *  - \f$ L \f$ : system loss (unit-less)
+ *
+ *
+ * This model is invalid for small distance values.
+ * The current implementation returns the txpower as the rxpower
+ * for any distance smaller than MinDistance.
+ */
+class FriisPropagationLossModel : public PropagationLossModel
+{
+public:
+  static TypeId GetTypeId (void);
+  FriisPropagationLossModel ();
+  /**
+   * \param frequency (Hz)
+   * \param speed (m/s)
+   *
+   * Set the main wavelength used in the Friis model 
+   * calculation.
+   */
+  void SetLambda (double frequency, double speed);
+  /**
+   * \param lambda (m) the wavelength
+   *
+   * Set the main wavelength used in the Friis model 
+   * calculation.
+   */
+  void SetLambda (double lambda);
+  /**
+   * \param systemLoss (dimension-less)
+   *
+   * Set the system loss used by the Friis propagation model.
+   */
+  void SetSystemLoss (double systemLoss);
+
+  /**
+   * \param minDistance the minimum distance
+   *
+   * Below this distance, the txpower is returned
+   * unmodified as the rxpower.
+   */
+  void SetMinDistance (double minDistance);
+
+  /**
+   * \returns the minimum distance.
+   */
+  double GetMinDistance (void) const;
+
+  /**
+   * \returns the current wavelength (m)
+   */
+  double GetLambda (void) const;
+  /**
+   * \returns the current system loss (dimention-less)
+   */
+  double GetSystemLoss (void) const;
+
+private:
+  FriisPropagationLossModel (const FriisPropagationLossModel &o);
+  FriisPropagationLossModel & operator = (const FriisPropagationLossModel &o);
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
+  double DbmToW (double dbm) const;
+  double DbmFromW (double w) const;
+
+  static const double PI;
+  double m_lambda;
+  double m_systemLoss;
+  double m_minDistance;
+};
+
+/*
+ *
+ * \brief a Two-Ray Ground propagation loss model ported from NS2
+ *
+ * Two-ray ground reflection model.
+ *
+ * \f$ Pr = \frac{Pt * Gt * Gr * (ht^2 * hr^2)}{d^4 * L} \f$
+ *
+ * The original equation in Rappaport's book assumes L = 1.
+ * To be consistent with the free space equation, L is added here.
+ *
+ * Ht and Hr are set at the respective nodes z coordinate plus a model parameter
+ * set via SetHeightAboveZ.
+ *
+ * The two-ray model does not give a good result for short distances, due to the
+ * oscillation caused by constructive and destructive combination of the two
+ * rays. Instead the Friis free-space model is used for small distances. 
+ *
+ * The crossover distance, below which Friis is used, is calculated as follows:
+ *
+ * \f$ dCross = \frac{(4 * pi * Ht * Hr)}{lambda} \f$
+ */
+
+class TwoRayGroundPropagationLossModel : public PropagationLossModel
+{
+public:
+  static TypeId GetTypeId (void);
+  TwoRayGroundPropagationLossModel ();
+  /**
+   * \param frequency (Hz)
+   * \param speed (m/s)
+   *
+   * Set the main wavelength used in the TwoRayGround model 
+   * calculation.
+   */
+  void SetLambda (double frequency, double speed);
+  /**
+   * \param lambda (m) the wavelength
+   *
+   * Set the main wavelength used in the TwoRayGround model 
+   * calculation.
+   */
+  void SetLambda (double lambda);
+  /**
+   * \param systemLoss (dimension-less)
+   *
+   * Set the system loss used by the TwoRayGround propagation model.
+   */
+  void SetSystemLoss (double systemLoss);
+  /**
+   * \param minDistance the minimum distance
+   *
+   * Below this distance, the txpower is returned
+   * unmodified as the rxpower.
+   */
+  void SetMinDistance (double minDistance);
+  /**
+   * \returns the minimum distance.
+   */
+  double GetMinDistance (void) const;
+  /**
+   * \returns the current wavelength (m)
+   */
+  double GetLambda (void) const;
+  /**
+   * \returns the current system loss (dimention-less)
+   */
+  double GetSystemLoss (void) const;
+  /**
+   * \param heightAboveZ the model antenna height above the node's Z coordinate
+   *
+   * Set the model antenna height above the node's Z coordinate
+   */
+  void SetHeightAboveZ (double heightAboveZ);
+
+private:
+  TwoRayGroundPropagationLossModel (const TwoRayGroundPropagationLossModel &o);
+  TwoRayGroundPropagationLossModel & operator = (const TwoRayGroundPropagationLossModel &o);
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
+  double DbmToW (double dbm) const;
+  double DbmFromW (double w) const;
+
+  static const double PI;
+  double m_lambda;
+  double m_systemLoss;
+  double m_minDistance;
+  double m_heightAboveZ;
+};
+
+/**
+ * \brief a log distance propagation model.
+ *
+ * This model calculates the reception power with a so-called
+ * log-distance propagation model:
+ * \f$ L = L_0 + 10 n log_{10}(\frac{d}{d_0})\f$
+ *
+ * where:
+ *  - \f$ n \f$ : the path loss distance exponent
+ *  - \f$ d_0 \f$ : reference distance (m)
+ *  - \f$ L_0 \f$ : path loss at reference distance (dB)
+ *  - \f$ d \f$ : distance (m)
+ *  - \f$ L \f$ : path loss (dB)
+ *
+ * When the path loss is requested at a distance smaller than
+ * the reference distance, the tx power is returned.
+ *
+ */
+class LogDistancePropagationLossModel : public PropagationLossModel
+{
+public:
+  static TypeId GetTypeId (void);
+  LogDistancePropagationLossModel ();
+
+  /**
+   * \param n the path loss exponent.
+   * Set the path loss exponent.
+   */
+  void SetPathLossExponent (double n);
+  /** 
+   * \returns the current path loss exponent.
+   */
+  double GetPathLossExponent (void) const;
+
+  void SetReference (double referenceDistance, double referenceLoss);
+  
+private:
+  LogDistancePropagationLossModel (const LogDistancePropagationLossModel &o);
+  LogDistancePropagationLossModel & operator = (const LogDistancePropagationLossModel &o);
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
+  static Ptr<PropagationLossModel> CreateDefaultReference (void);
+
+  double m_exponent;
+  double m_referenceDistance;
+  double m_referenceLoss;
+};
+
+/**
+ * \brief A log distance path loss propagation model with three distance
+ * fields. This model is the same as ns3::LogDistancePropagationLossModel
+ * except that it has three distance fields: near, middle and far with
+ * different exponents.
+ *
+ * Within each field the reception power is calculated using the log-distance
+ * propagation equation:
+ * \f[ L = L_0 + 10 \cdot n_0 log_{10}(\frac{d}{d_0})\f]
+ * Each field begins where the previous ends and all together form a continuous function.
+ *
+ * There are three valid distance fields: near, middle, far. Actually four: the
+ * first from 0 to the reference distance is invalid and returns txPowerDbm.
+ *
+ * \f[ \underbrace{0 \cdots\cdots}_{=0} \underbrace{d_0 \cdots\cdots}_{n_0} \underbrace{d_1 \cdots\cdots}_{n_1} \underbrace{d_2 \cdots\cdots}_{n_2} \infty \f]
+ *
+ * Complete formula for the path loss in dB:
+ *
+ * \f[\displaystyle L =
+\begin{cases}
+0 & d < d_0 \\
+L_0 + 10 \cdot n_0 \log_{10}(\frac{d}{d_0}) & d_0 \leq d < d_1 \\
+L_0 + 10 \cdot n_0 \log_{10}(\frac{d_1}{d_0}) + 10 \cdot n_1 \log_{10}(\frac{d}{d_1}) & d_1 \leq d < d_2 \\
+L_0 + 10 \cdot n_0 \log_{10}(\frac{d_1}{d_0}) + 10 \cdot n_1 \log_{10}(\frac{d_2}{d_1}) + 10 \cdot n_2 \log_{10}(\frac{d}{d_2})& d_2 \leq d
+\end{cases}\f]
+ *
+ * where:
+ *  - \f$ L \f$ : resulting path loss (dB)
+ *  - \f$ d \f$ : distance (m)
+ *  - \f$ d_0, d_1, d_2 \f$ : three distance fields (m)
+ *  - \f$ n_0, n_1, n_2 \f$ : path loss distance exponent for each field (unitless)
+ *  - \f$ L_0 \f$ : path loss at reference distance (dB)
+ *
+ * When the path loss is requested at a distance smaller than the reference
+ * distance \f$ d_0 \f$, the tx power (with no path loss) is returned. The
+ * reference distance defaults to 1m and reference loss defaults to
+ * ns3::FriisPropagationLossModel with 5.15 GHz and is thus \f$ L_0 \f$ = 46.67 dB.
+ */
+
+class ThreeLogDistancePropagationLossModel : public PropagationLossModel
+{
+public:
+  static TypeId GetTypeId (void);
+  ThreeLogDistancePropagationLossModel ();
+
+  // Parameters are all accessible via attributes.
+
+private:
+  ThreeLogDistancePropagationLossModel (const ThreeLogDistancePropagationLossModel& o);
+  ThreeLogDistancePropagationLossModel& operator= (const ThreeLogDistancePropagationLossModel& o);
+
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
+
+  double m_distance0;
+  double m_distance1;
+  double m_distance2;
+
+  double m_exponent0;
+  double m_exponent1;
+  double m_exponent2;
+
+  double m_referenceLoss;
+};
+
+/**
+ * \brief Nakagami-m fast fading propagation loss model.
+ *
+ * The Nakagami-m distribution is applied to the power level. The probability
+ * density function is defined as
+ * \f[ p(x; m, \omega) = \frac{2 m^m}{\Gamma(m) \omega^m} x^{2m - 1} e^{-\frac{m}{\omega} x^2} = 2 x \cdot p_{\text{Gamma}}(x^2, m, \frac{m}{\omega}) \f]
+ * with \f$ m \f$ the fading depth parameter and \f$ \omega \f$ the average received power.
+ *
+ * It is implemented by either a ns3::GammaVariable or a ns3::ErlangVariable
+ * random variable.
+ *
+ * Like in ns3::ThreeLogDistancePropagationLossModel, the m parameter is varied
+ * over three distance fields:
+ * \f[ \underbrace{0 \cdots\cdots}_{m_0} \underbrace{d_1 \cdots\cdots}_{m_1} \underbrace{d_2 \cdots\cdots}_{m_2} \infty \f]
+ *
+ * For m = 1 the Nakagami-m distribution equals the Rayleigh distribution. Thus
+ * this model also implements Rayleigh distribution based fast fading.
+ */
+
+class NakagamiPropagationLossModel : public PropagationLossModel
+{
+public:
+  static TypeId GetTypeId (void);
+
+  NakagamiPropagationLossModel ();
+
+  // Parameters are all accessible via attributes.
+
+private:
+  NakagamiPropagationLossModel (const NakagamiPropagationLossModel& o);
+  NakagamiPropagationLossModel& operator= (const NakagamiPropagationLossModel& o);
+
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
+
+  double m_distance1;
+  double m_distance2;
+
+  double m_m0;
+  double m_m1;
+  double m_m2;
+
+  ErlangVariable        m_erlangRandomVariable;
+  GammaVariable         m_gammaRandomVariable;
+};
+
+/**
+ * \brief The propagation loss is fixed. The user can set received power level.
+ */ 
+class FixedRssLossModel : public PropagationLossModel
+{
+public:
+  static TypeId GetTypeId (void);
+
+  FixedRssLossModel ();
+  virtual ~FixedRssLossModel ();
+  /**
+   * \param rss (dBm) the received signal strength
+   *
+   * Set the RSS.
+   */
+  void SetRss (double rss);
+
+private:
+  FixedRssLossModel (const FixedRssLossModel &o);
+  FixedRssLossModel & operator = (const FixedRssLossModel &o);
+  virtual double DoCalcRxPower (double txPowerDbm,
+                                Ptr<MobilityModel> a,
+                                Ptr<MobilityModel> b) const;
+  double m_rss;
+};
+
+} // namespace ns3
+
+#endif /* PROPAGATION_LOSS_MODEL_H */
--- a/src/common/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/common/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -10,7 +10,6 @@
         'chunk.cc',
         'header.cc',
         'trailer.cc',
-        'pcap-writer.cc',
         'data-rate.cc',
         'error-model.cc',
         'tag.cc',
@@ -18,9 +17,14 @@
         'tag-buffer.cc',
         'packet-tag-list.cc',
         'nix-vector.cc',
-        'ascii-writer.cc',
         'pcap-file.cc',
         'pcap-file-test-suite.cc',
+        'pcap-file-wrapper.cc',
+        'output-stream-wrapper.cc',
+        'propagation-delay-model.cc',
+        'propagation-loss-model.cc',
+        'propagation-loss-model-test-suite.cc',
+        'jakes-propagation-loss-model.cc',
         ]
 
     headers = bld.new_task_gen('ns3header')
@@ -32,7 +36,6 @@
         'trailer.h',
         'packet.h',
         'packet-metadata.h',
-        'pcap-writer.h',
         'data-rate.h',
         'error-model.h',
         'tag.h',
@@ -40,7 +43,11 @@
         'tag-buffer.h',
         'packet-tag-list.h',
         'nix-vector.h',
-        'ascii-writer.h',
         'sgi-hashmap.h',
         'pcap-file.h',
+        'pcap-file-wrapper.h',
+        'output-stream-wrapper.h',
+        'propagation-delay-model.h',
+        'propagation-loss-model.h',
+        'jakes-propagation-loss-model.h',
         ]
--- a/src/contrib/attribute-default-iterator.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/contrib/attribute-default-iterator.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -1,15 +1,35 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  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: Faker Moatamri <faker.moatamri@sophia.inria.fr>
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+ 
 #include "attribute-default-iterator.h"
-#include "ns3/type-id.h"
 #include "ns3/attribute.h"
 #include "ns3/object-vector.h"
 #include "ns3/pointer.h"
 #include "ns3/global-value.h"
 #include "ns3/string.h"
 
-namespace ns3 {
+namespace ns3
+{
 
 AttributeDefaultIterator::~AttributeDefaultIterator ()
-{}
+{
+}
 void 
 AttributeDefaultIterator::Iterate (void)
 {
@@ -17,72 +37,87 @@
     {
       TypeId tid = TypeId::GetRegistered (i);
       if (tid.MustHideFromDocumentation ())
-	{
-	  continue;
-	}
+        {
+          continue;
+        }
       bool calledStart = false;
       for (uint32_t j = 0; j < tid.GetAttributeN (); j++)
-	{
-	  uint32_t flags = tid.GetAttributeFlags (j);
-	  if (!(flags & TypeId::ATTR_CONSTRUCT))
-	    {
-	      // we can't construct the attribute, so, there is no
-	      // initial value for the attribute
-	      continue;
-	    }
-	  Ptr<const AttributeAccessor> accessor = tid.GetAttributeAccessor (j);
-	  if (accessor == 0)
-	    {
-	      continue;
-	    }
-	  if (!accessor->HasSetter ())
-	    {
-	      continue;
-	    }
-	  Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (j);
-	  if (checker == 0)
-	    {
-	      continue;
-	    }
-	  Ptr<const AttributeValue> value = tid.GetAttributeInitialValue (j);
-	  if (value == 0)
-	    {
-	      continue;
-	    }
-	  Ptr<const ObjectVectorValue> vector = DynamicCast<const ObjectVectorValue> (value);
-	  if (vector != 0)
-	    {
-	      continue;
-	    }
-	  Ptr<const PointerValue> pointer = DynamicCast<const PointerValue> (value);
-	  if (pointer != 0)
-	    {
-	      continue;
-	    }
-	  if (!calledStart)
-	    {
-	      StartVisitTypeId (tid.GetName ());
-	    }
-	  VisitAttribute (tid.GetAttributeName (j),
-			  value->SerializeToString (checker));
-	  calledStart = true;
-	}
+        {
+          uint32_t flags = tid.GetAttributeFlags (j);
+          if (!(flags & TypeId::ATTR_CONSTRUCT))
+            {
+              // we can't construct the attribute, so, there is no
+              // initial value for the attribute
+              continue;
+            }
+          Ptr<const AttributeAccessor> accessor = tid.GetAttributeAccessor (j);
+          //No accessor, go to next attribute
+          if (accessor == 0)
+            {
+              continue;
+            }
+          if (!accessor->HasSetter ())
+            {
+              //skip this attribute it doesn't have an setter
+              continue;
+            }
+          Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (j);
+          if (checker == 0)
+            {
+              //skip, it doesn't have a checker
+              continue;
+            }
+          Ptr<const AttributeValue> value = tid.GetAttributeInitialValue (j);
+          if (value == 0)
+            {
+              //No value, check next attribute
+              continue;
+            }
+          Ptr<const ObjectVectorValue> vector = DynamicCast<const ObjectVectorValue> (value);
+          if (vector != 0)
+            {
+              //a vector value, won't take it
+              continue;
+            }
+          Ptr<const PointerValue> pointer = DynamicCast<const PointerValue> (value);
+          if (pointer != 0)
+            {
+              //pointer value, won't take it
+              continue;
+            }
+          //We take only values, no pointers or vectors
+          if (!calledStart)
+            {
+              StartVisitTypeId (tid.GetName ());
+            }
+          VisitAttribute (tid, tid.GetAttributeName (j), value->SerializeToString (checker), j);
+          calledStart = true;
+        }
       if (calledStart)
-	{
-	  EndVisitTypeId ();
-	}
+        {
+          EndVisitTypeId ();
+        }
     }
 }
 
 void 
 AttributeDefaultIterator::StartVisitTypeId (std::string name)
-{}
+{
+}
 void 
 AttributeDefaultIterator::EndVisitTypeId (void)
-{}
+{
+}
+
 void 
-AttributeDefaultIterator::VisitAttribute (std::string name, std::string defaultValue)
-{}
+AttributeDefaultIterator::DoVisitAttribute (std::string name, std::string defaultValue)
+{
+}
 
+void 
+AttributeDefaultIterator::VisitAttribute (TypeId tid, std::string name, std::string defaultValue, uint32_t index)
+{
+  DoVisitAttribute (name, defaultValue);
+}
 
 } // namespace ns3
--- a/src/contrib/attribute-default-iterator.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/contrib/attribute-default-iterator.h	Thu Feb 25 14:17:21 2010 +0100
@@ -1,6 +1,26 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  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: Faker Moatamri <faker.moatamri@sophia.inria.fr>
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+ 
 #ifndef ATTRIBUTE_DEFAULT_ITERATOR_H
 #define ATTRIBUTE_DEFAULT_ITERATOR_H
 
+#include "ns3/type-id.h"
 #include <string>
 
 namespace ns3 {
@@ -9,11 +29,30 @@
 {
 public:
   virtual ~AttributeDefaultIterator () = 0;
+  /**
+   * \brief This function will go through all the TypeIds and get only the attributes which are
+   * explicit values (not vectors or pointer or arrays) and apply StartVisitTypeId
+   * and VisitAttribute on the attributes in one TypeId. At the end of each TypeId
+   * EndVisitTypeId is called.
+   */
   void Iterate (void);
 private:
+  /**
+   * \brief Just an interface that needs to be implemented
+   */
   virtual void StartVisitTypeId (std::string name);
+  /**
+   * \brief Just an interface that needs to be implemented
+   */
   virtual void EndVisitTypeId (void);
-  virtual void VisitAttribute (std::string name, std::string defaultValue);
+  /**
+   * \brief This method can be implemented, otherwise, it will call DoVisitAttribute
+   */
+  virtual void VisitAttribute (TypeId tid, std::string name, std::string defaultValue, uint32_t index);
+  /**
+   * \brief This method is just an interface and needs to be implemented
+   */
+  virtual void DoVisitAttribute (std::string name, std::string defaultValue);
 };
 
 } // namespace ns3
--- a/src/contrib/attribute-iterator.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/contrib/attribute-iterator.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -1,3 +1,21 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  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@sophia.inria.fr>
+ */
+ 
 #include "attribute-iterator.h"
 #include "ns3/config.h"
 #include "ns3/log.h"
@@ -13,10 +31,12 @@
 
 
 AttributeIterator::AttributeIterator ()
-{}
+{
+}
 
 AttributeIterator::~AttributeIterator ()
-{}
+{
+}
 
 void 
 AttributeIterator::Iterate (void)
@@ -38,9 +58,9 @@
   for (uint32_t i = 0; i < m_examined.size (); ++i)
     {
       if (object == m_examined[i])
-	{
-	  return true;
-	}
+        {
+          return true;
+        }
     }
   return false;
 }
@@ -74,28 +94,36 @@
 
 void 
 AttributeIterator::DoStartVisitObject (Ptr<Object> object)
-{}
+{
+}
 void 
 AttributeIterator::DoEndVisitObject (void)
-{}
+{
+}
 void 
 AttributeIterator::DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> item)
-{}
+{
+}
 void 
 AttributeIterator::DoEndVisitPointerAttribute (void)
-{}
+{
+}
 void 
 AttributeIterator::DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector)
-{}
+{
+}
 void 
 AttributeIterator::DoEndVisitArrayAttribute (void)
-{}
+{
+}
 void 
 AttributeIterator::DoStartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item)
-{}
+{
+}
 void 
 AttributeIterator::DoEndVisitArrayItem (void)
-{}
+{
+}
 
 void 
 AttributeIterator::VisitAttribute (Ptr<Object> object, std::string name)
@@ -174,58 +202,59 @@
     {
       NS_LOG_DEBUG ("store " << tid.GetName ());
       for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
-	{
-	  Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (i);
-	  const PointerChecker *ptrChecker = dynamic_cast<const PointerChecker *> (PeekPointer (checker));
-	  if (ptrChecker != 0)
-	    {
-	      NS_LOG_DEBUG ("pointer attribute " << tid.GetAttributeName (i));
-	      PointerValue ptr;
-	      object->GetAttribute (tid.GetAttributeName (i), ptr);
-	      Ptr<Object> tmp = ptr.Get<Object> ();
-	      if (tmp != 0)
-		{
-		  StartVisitPointerAttribute (object, tid.GetAttributeName (i), tmp);
-		  m_examined.push_back (object);
-		  DoIterate (tmp);
-		  m_examined.pop_back ();
-		  EndVisitPointerAttribute ();
-		}
-	      continue;
-	    }
-	  // attempt to cast to an object vector.
-	  const ObjectVectorChecker *vectorChecker = dynamic_cast<const ObjectVectorChecker *> (PeekPointer (checker));
-	  if (vectorChecker != 0)
-	    {
-	      NS_LOG_DEBUG ("vector attribute " << tid.GetAttributeName (i));
-	      ObjectVectorValue vector;
-	      object->GetAttribute (tid.GetAttributeName (i), vector);
-	      StartVisitArrayAttribute (object, tid.GetAttributeName (i), vector);
-	      for (uint32_t j = 0; j < vector.GetN (); ++j)
-		{
-		  NS_LOG_DEBUG ("vector attribute item " << j);
-		  Ptr<Object> tmp = vector.Get (j);
-		  StartVisitArrayItem (vector, j, tmp);
-		  m_examined.push_back (object);
-		  DoIterate (tmp);
-		  m_examined.pop_back ();
-		  EndVisitArrayItem ();
-		}
-	      EndVisitArrayAttribute ();
-	      continue;
-	    }
-	  uint32_t flags = tid.GetAttributeFlags (i);
-	  Ptr<const AttributeAccessor> accessor = tid.GetAttributeAccessor (i);
-	  if ((flags & TypeId::ATTR_GET) && accessor->HasGetter () &&
-	      (flags & TypeId::ATTR_SET) && accessor->HasSetter ())
-	    {
-	      VisitAttribute (object, tid.GetAttributeName (i));
-	    }
-	  else
-	    {
-	      NS_LOG_DEBUG ("could not store " << tid.GetAttributeName (i));
-	    }
-	}
+        {
+          Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (i);
+          const PointerChecker *ptrChecker = dynamic_cast<const PointerChecker *> (PeekPointer (checker));
+          if (ptrChecker != 0)
+            {
+              NS_LOG_DEBUG ("pointer attribute " << tid.GetAttributeName (i));
+              PointerValue ptr;
+              object->GetAttribute (tid.GetAttributeName (i), ptr);
+              Ptr<Object> tmp = ptr.Get<Object> ();
+              if (tmp != 0)
+                {
+                  StartVisitPointerAttribute (object, tid.GetAttributeName (i),
+                                              tmp);
+                  m_examined.push_back (object);
+                  DoIterate (tmp);
+                  m_examined.pop_back ();
+                  EndVisitPointerAttribute ();
+                }
+              continue;
+            }
+          // attempt to cast to an object vector.
+          const ObjectVectorChecker *vectorChecker = dynamic_cast<const ObjectVectorChecker *> (PeekPointer (checker));
+          if (vectorChecker != 0)
+            {
+              NS_LOG_DEBUG ("vector attribute " << tid.GetAttributeName (i));
+              ObjectVectorValue vector;
+              object->GetAttribute (tid.GetAttributeName (i), vector);
+              StartVisitArrayAttribute (object, tid.GetAttributeName (i), vector);
+              for (uint32_t j = 0; j < vector.GetN (); ++j)
+                {
+                  NS_LOG_DEBUG ("vector attribute item " << j);
+                  Ptr<Object> tmp = vector.Get (j);
+                  StartVisitArrayItem (vector, j, tmp);
+                  m_examined.push_back (object);
+                  DoIterate (tmp);
+                  m_examined.pop_back ();
+                  EndVisitArrayItem ();
+                }
+              EndVisitArrayAttribute ();
+              continue;
+            }
+          uint32_t flags = tid.GetAttributeFlags (i);
+          Ptr<const AttributeAccessor> accessor = tid.GetAttributeAccessor (i);
+          if ((flags & TypeId::ATTR_GET) && accessor->HasGetter () && 
+              (flags & TypeId::ATTR_SET) && accessor->HasSetter ())
+            {
+              VisitAttribute (object, tid.GetAttributeName (i));
+            }
+          else
+            {
+              NS_LOG_DEBUG ("could not store " << tid.GetAttributeName (i));
+            }
+        }
     }
   Object::AggregateIterator iter = object->GetAggregateIterator ();
   bool recursiveAggregate = false;
@@ -233,22 +262,22 @@
     {
       Ptr<const Object> tmp = iter.Next ();
       if (IsExamined (tmp))
-	{
-	  recursiveAggregate = true;
-	}
+        {
+          recursiveAggregate = true;
+        }
     }
   if (!recursiveAggregate)
     {
       iter = object->GetAggregateIterator ();
       while (iter.HasNext ())
-	{
-	  Ptr<Object> tmp = const_cast<Object *> (PeekPointer (iter.Next ()));
-	  StartVisitObject (tmp);
-	  m_examined.push_back (object);
-	  DoIterate (tmp);
-	  m_examined.pop_back ();
-	  EndVisitObject ();
-	}
+        {
+          Ptr<Object> tmp = const_cast<Object *> (PeekPointer (iter.Next ()));
+          StartVisitObject (tmp);
+          m_examined.push_back (object);
+          DoIterate (tmp);
+          m_examined.pop_back ();
+          EndVisitObject ();
+        }
     }
 }
 
--- a/src/contrib/attribute-iterator.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/contrib/attribute-iterator.h	Thu Feb 25 14:17:21 2010 +0100
@@ -1,3 +1,21 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  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@sophia.inria.fr>
+ */
+ 
 #ifndef ATTRIBUTE_ITERATOR_H
 #define ATTRIBUTE_ITERATOR_H
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/display-functions.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,594 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  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: Faker Moatamri <faker.moatamri@sophia.inria.fr>
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "display-functions.h"
+#include "raw-text-config.h"
+#include "ns3/config.h"
+#include "ns3/string.h"
+#include "ns3/pointer.h"
+
+namespace ns3 {
+/**
+ * This function includes the name of the attribute or the editable value
+ * in the second column 
+ */
+void
+cell_data_function_col_1 (GtkTreeViewColumn *col, GtkCellRenderer *renderer,
+                          GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
+{
+  ModelNode *node;
+  gtk_tree_model_get (model, iter, COL_NODE, &node, -1);
+  if (node->type == ModelNode::NODE_ATTRIBUTE)
+    {
+      StringValue str;
+      node->object->GetAttribute (node->name, str);
+      g_object_set (renderer, "text", str.Get ().c_str (), (char*) 0);
+      g_object_set (renderer, "editable", TRUE, (char*) 0);
+    }
+  else
+    {
+      g_object_set (renderer, "text", "", (char*) 0);
+      g_object_set (renderer, "editable", FALSE, (char*) 0);
+    }
+}
+/**
+ * This function includes the name of the object, pointer, vector or vector item
+ * in the first column
+ */
+void
+cell_data_function_col_0 (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model,
+                          GtkTreeIter *iter, gpointer user_data)
+{
+  ModelNode *node;
+  gtk_tree_model_get (model, iter, COL_NODE, &node, -1);
+  g_object_set (renderer, "editable", FALSE, (char*) 0);
+  switch (node->type)
+    {
+    case ModelNode::NODE_OBJECT:
+      g_object_set (renderer, "text", node->object->GetInstanceTypeId ().GetName ().c_str (), (char*) 0);
+      break;
+    case ModelNode::NODE_POINTER:
+      g_object_set (renderer, "text", node->name.c_str (), (char*) 0);
+      break;
+    case ModelNode::NODE_VECTOR:
+      g_object_set (renderer, "text", node->name.c_str (), (char*) 0);
+      break;
+    case ModelNode::NODE_VECTOR_ITEM:
+      {
+        std::stringstream oss;
+        oss << node->index;
+        g_object_set (renderer, "text", oss.str ().c_str (), (char*) 0);
+      }
+      break;
+    case ModelNode::NODE_ATTRIBUTE:
+      g_object_set (renderer, "text", node->name.c_str (), (char*) 0);
+      break;
+    }
+}
+
+/**
+ * This is the callback called when the value of an attribute is changed
+ */
+void
+cell_edited_callback (GtkCellRendererText *cell, gchar *path_string,
+                      gchar *new_text, gpointer user_data)
+{
+  GtkTreeModel *model = GTK_TREE_MODEL (user_data);
+  GtkTreeIter iter;
+  gtk_tree_model_get_iter_from_string (model, &iter, path_string);
+  ModelNode *node;
+  gtk_tree_model_get (model, &iter, COL_NODE, &node, -1);
+  NS_ASSERT (node->type == ModelNode::NODE_ATTRIBUTE);
+  node->object->SetAttribute (node->name, StringValue (new_text));
+}
+
+/**
+ * This function gets the column number 0 or 1 from the mouse
+ * click
+ */
+int
+get_col_number_from_tree_view_column (GtkTreeViewColumn *col)
+{
+  GList *cols;
+  int num;
+  g_return_val_if_fail (col != 0, -1);
+  g_return_val_if_fail (col->tree_view != 0, -1);
+  cols = gtk_tree_view_get_columns (GTK_TREE_VIEW (col->tree_view));
+  num = g_list_index (cols, (gpointer) col);
+  g_list_free (cols);
+  return num;
+}
+
+/**
+ * This function displays the tooltip for an object, pointer, vector
+ * item or an attribute
+ */
+gboolean
+cell_tooltip_callback (GtkWidget *widget, gint x, gint y, gboolean keyboard_tip, 
+                       GtkTooltip *tooltip, gpointer user_data)
+{
+  GtkTreeModel *model;
+  GtkTreeIter iter;
+  GtkTreeViewColumn * column;
+  if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (widget), &x, &y,
+                                          keyboard_tip, &model, 0, &iter))
+    {
+      return FALSE;
+    }
+  if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), x, y, 0, &column, 0, 0))
+    {
+      return FALSE;
+    }
+  int col = get_col_number_from_tree_view_column (column);
+
+  ModelNode *node;
+  gtk_tree_model_get (model, &iter, COL_NODE, &node, -1);
+
+  switch (node->type)
+    {
+    case ModelNode::NODE_OBJECT:
+      if (col == 0)
+        {
+          std::string tip = "This object is of type "
+            + node->object->GetInstanceTypeId ().GetName ();
+          gtk_tooltip_set_text (tooltip, tip.c_str ());
+          return TRUE;
+        }
+      break;
+    case ModelNode::NODE_POINTER:
+      if (col == 0)
+        {
+          PointerValue ptr;
+          node->object->GetAttribute (node->name, ptr);
+          std::string tip = "This object is of type "
+            + ptr.GetObject ()->GetInstanceTypeId ().GetName ();
+          gtk_tooltip_set_text (tooltip, tip.c_str ());
+          return TRUE;
+        }
+      break;
+    case ModelNode::NODE_VECTOR:
+      break;
+    case ModelNode::NODE_VECTOR_ITEM:
+      if (col == 0)
+        {
+          std::string tip = "This object is of type "
+            + node->object->GetInstanceTypeId ().GetName ();
+          gtk_tooltip_set_text (tooltip, tip.c_str ());
+          return TRUE;
+        }
+      break;
+    case ModelNode::NODE_ATTRIBUTE:
+      {
+        uint32_t attrIndex = 0;
+        TypeId tid;
+        for (tid = node->object->GetInstanceTypeId (); tid.HasParent (); tid
+               = tid.GetParent ())
+          {
+            for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
+              {
+                if (tid.GetAttributeName (i) == node->name)
+                  {
+                    attrIndex = i;
+                    goto out;
+                  }
+              }
+          }
+out: if (col == 0)
+          {
+            std::string tip = tid.GetAttributeHelp (attrIndex);
+            gtk_tooltip_set_text (tooltip, tip.c_str ());
+          }
+        else
+          {
+            Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (
+                attrIndex);
+            std::string tip;
+            tip = "This attribute is of type " + checker->GetValueTypeName ();
+            if (checker->HasUnderlyingTypeInformation ())
+              {
+                tip += " " + checker->GetUnderlyingTypeInformation ();
+              }
+            gtk_tooltip_set_text (tooltip, tip.c_str ());
+          }
+        return TRUE;
+      }
+      break;
+    }
+  return FALSE;
+}
+
+/**
+ * This is the main view opening the widget, getting tooltips and drawing the 
+ * tree of attributes...
+ */
+GtkWidget *
+create_view (GtkTreeStore *model)
+{
+  GtkTreeViewColumn *col;
+  GtkCellRenderer *renderer;
+  GtkWidget *view;
+
+  view = gtk_tree_view_new ();
+  g_object_set (view, "has-tooltip", TRUE, (char*) 0);
+  g_signal_connect (view, "query-tooltip", (GCallback) cell_tooltip_callback, 0);
+
+  gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_BOTH);
+  gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
+
+  col = gtk_tree_view_column_new ();
+  gtk_tree_view_column_set_title (col, "Object Attributes");
+  gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_tree_view_column_pack_start (col, renderer, TRUE);
+  gtk_tree_view_column_set_cell_data_func (col, renderer, cell_data_function_col_0, 0, 0);
+  g_object_set (renderer, "editable", FALSE, (char*) 0);
+
+  col = gtk_tree_view_column_new ();
+  gtk_tree_view_column_set_title (col, "Attribute Value");
+  gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
+  renderer = gtk_cell_renderer_text_new ();
+  g_signal_connect (renderer, "edited", (GCallback) cell_edited_callback, model);
+  gtk_tree_view_column_pack_start (col, renderer, TRUE);
+  gtk_tree_view_column_set_cell_data_func (col, renderer, cell_data_function_col_1, 0, 0);
+
+  gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (model));
+
+  g_object_unref (model); /* destroy model automatically with view */
+
+  return view;
+}
+
+/**
+ * This is the action done when the user presses on the save button.
+ * It will save the config to a file.
+ */
+void
+save_clicked (GtkButton *button, gpointer user_data)
+{
+  GtkWidget *parent_window = GTK_WIDGET (user_data);
+  GtkWidget *dialog;
+
+  dialog = gtk_file_chooser_dialog_new ("Save File", GTK_WINDOW (parent_window), GTK_FILE_CHOOSER_ACTION_SAVE,
+                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE,
+                                        GTK_RESPONSE_ACCEPT, (char *) 0);
+  gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
+                                                  TRUE);
+
+  gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "config.txt");
+
+  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+    {
+      char *filename;
+
+      filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+      RawTextConfigSave config;
+      config.SetFilename (filename);
+      config.Attributes ();
+      g_free (filename);
+    }
+
+  gtk_widget_destroy (dialog);
+}
+
+/**
+ * If the user presses the button load, it will load the config file into memory.
+ */
+void
+load_clicked (GtkButton *button, gpointer user_data)
+{
+  GtkWidget *parent_window = GTK_WIDGET (user_data);
+  GtkWidget *dialog;
+
+  dialog = gtk_file_chooser_dialog_new ("Open File", GTK_WINDOW (parent_window), GTK_FILE_CHOOSER_ACTION_OPEN,
+                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN,
+                                        GTK_RESPONSE_ACCEPT, (char *) 0);
+
+  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+    {
+      char *filename;
+
+      filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+      RawTextConfigLoad config;
+      config.SetFilename (filename);
+      config.Attributes ();
+    }
+
+  gtk_widget_destroy (dialog);
+}
+
+/**
+ * Exit the window when exit button is pressed
+ */
+void
+exit_clicked_callback (GtkButton *button, gpointer user_data)
+{
+  gtk_main_quit ();
+  gtk_widget_hide (GTK_WIDGET (user_data));
+}
+
+/**
+ * Exit the application
+ */
+gboolean
+delete_event_callback (GtkWidget *widget, GdkEvent *event, gpointer user_data)
+{
+  gtk_main_quit ();
+  gtk_widget_hide (GTK_WIDGET (user_data));
+  return TRUE;
+}
+
+/**
+ * Delete the tree model contents
+ */
+gboolean
+clean_model_callback (GtkTreeModel *model, GtkTreePath *path,
+                      GtkTreeIter *iter, gpointer data)
+{
+  ModelNode *node;
+  gtk_tree_model_get (GTK_TREE_MODEL (model), iter, COL_NODE, &node, -1);
+  delete node;
+  gtk_tree_store_set (GTK_TREE_STORE (model), iter, COL_NODE, (ModelNode*) 0,
+                      -1);
+  return FALSE;
+}
+
+/**************************     display functions used by default configurator **********************/
+/**
+ * This function writes data in the second column, this data is going to be editable
+ * if it is a NODE_ATTRIBUTE
+ */
+void
+cell_data_function_col_1_config_default (GtkTreeViewColumn *col, GtkCellRenderer *renderer, 
+                                         GtkTreeModel *model, GtkTreeIter *iter,
+                                         gpointer user_data)
+{
+  ModelTypeid *node;
+  gtk_tree_model_get (model, iter, COL_TYPEID, &node, -1);
+  if (node->type == ModelTypeid::NODE_ATTRIBUTE)
+    {
+      g_object_set (renderer, "text", node->defaultValue.c_str (), (char*) 0);
+      g_object_set (renderer, "editable", TRUE, (char*) 0);
+    }
+  else
+    {
+      g_object_set (renderer, "text", "", (char*) 0);
+      g_object_set (renderer, "editable", FALSE, (char*) 0);
+    }
+}
+/**
+ * This function writes the attribute or typeid name in the column 0
+ */
+void
+cell_data_function_col_0_config_default (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, 
+                                         GtkTreeIter *iter, gpointer user_data)
+{
+  ModelTypeid *node;
+  gtk_tree_model_get (model, iter, COL_NODE, &node, -1);
+  g_object_set (renderer, "editable", FALSE, (char*) 0);
+  switch (node->type)
+    {
+    case ModelTypeid::NODE_TYPEID:
+      g_object_set (renderer, "text", node->tid.GetName ().c_str (), (char*) 0);
+      break;
+    case ModelTypeid::NODE_ATTRIBUTE:
+      g_object_set (renderer, "text", node->name.c_str (), (char*) 0);
+      break;
+    }
+}
+
+
+/**
+ *  This functions is called whenever there is a change in the value of an attribute
+ *  If the input value is ok, it will be updated in the default value and in the
+ *  gui, otherwise, it won't be updated in both.
+ */
+void
+cell_edited_callback_config_default (GtkCellRendererText *cell, gchar *path_string,
+                                     gchar *new_text, gpointer user_data)
+{
+  GtkTreeModel *model = GTK_TREE_MODEL (user_data);
+  GtkTreeIter iter;
+  gtk_tree_model_get_iter_from_string (model, &iter, path_string);
+  ModelTypeid *node;
+  gtk_tree_model_get (model, &iter, COL_NODE, &node, -1);
+  NS_ASSERT (node->type == ModelTypeid::NODE_ATTRIBUTE);
+  if (Config::SetDefaultFailSafe (node->tid.GetAttributeFullName (node->index),StringValue (new_text)))
+    {
+      node->defaultValue = new_text;
+    }
+}
+
+/**
+ * This function is used to display a tooltip whenever the user puts the mouse
+ * over a type ID or an attribute. It will give the type and the possible values of
+ * an attribute value and the type of the object for an attribute object or a 
+ * typeID object 
+ */
+gboolean
+cell_tooltip_callback_config_default (GtkWidget *widget, gint x, gint y,
+                                      gboolean keyboard_tip, GtkTooltip *tooltip, gpointer user_data)
+{
+  GtkTreeModel *model;
+  GtkTreeIter iter;
+  GtkTreeViewColumn * column;
+  if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (widget), &x, &y,
+                                          keyboard_tip, &model, 0, &iter))
+    {
+      return FALSE;
+    }
+  if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), x, y, 0, &column, 0, 0))
+    {
+      return FALSE;
+    }
+  int col = get_col_number_from_tree_view_column (column);
+
+  ModelTypeid *node;
+  gtk_tree_model_get (model, &iter, COL_NODE, &node, -1);
+
+  switch (node->type)
+    {
+    case ModelTypeid::NODE_TYPEID:
+      if (col == 0)
+        {
+          std::string tip = "This object is of type " + node->tid.GetName ();
+          gtk_tooltip_set_text (tooltip, tip.c_str ());
+          return TRUE;
+        }
+      break;
+    case ModelTypeid::NODE_ATTRIBUTE:
+      {
+        uint32_t attrIndex = node->index;
+        if (col == 0)
+          {
+            std::string tip = node->tid.GetAttributeHelp (attrIndex);
+            gtk_tooltip_set_text (tooltip, tip.c_str ());
+          }
+        else
+          {
+            Ptr<const AttributeChecker> checker = node->tid.GetAttributeChecker (attrIndex);
+            std::string tip;
+            tip = "This attribute is of type " + checker->GetValueTypeName ();
+            if (checker->HasUnderlyingTypeInformation ())
+              {
+                tip += " " + checker->GetUnderlyingTypeInformation ();
+              }
+            gtk_tooltip_set_text (tooltip, tip.c_str ());
+          }
+        return TRUE;
+      }
+      break;
+    }
+  return FALSE;
+}
+
+/**
+ * This is the action done when the user presses on the save button.
+ * It will save the config to a file.
+ */
+void
+save_clicked_default (GtkButton *button, gpointer user_data)
+{
+  GtkWidget *parent_window = GTK_WIDGET (user_data);
+  GtkWidget *dialog;
+
+  dialog = gtk_file_chooser_dialog_new ("Save File", GTK_WINDOW (parent_window), GTK_FILE_CHOOSER_ACTION_SAVE,
+                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE,
+                                        GTK_RESPONSE_ACCEPT, (char *) 0);
+  gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
+                                                  TRUE);
+
+  gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "config.txt");
+
+  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+    {
+      char *filename;
+
+      filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+      RawTextConfigSave config;
+      config.SetFilename (filename);
+      config.Default ();
+      g_free (filename);
+    }
+
+  gtk_widget_destroy (dialog);
+}
+
+/**
+ * If the user presses the button load, it will load the config file into memory.
+ */
+void
+load_clicked_default (GtkButton *button, gpointer user_data)
+{
+  GtkWidget *parent_window = GTK_WIDGET (user_data);
+  GtkWidget *dialog;
+
+  dialog = gtk_file_chooser_dialog_new ("Open File", GTK_WINDOW (parent_window), GTK_FILE_CHOOSER_ACTION_OPEN,
+                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN,
+                                        GTK_RESPONSE_ACCEPT, (char *) 0);
+
+  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+    {
+      char *filename;
+
+      filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+      RawTextConfigLoad config;
+      config.SetFilename (filename);
+      config.Default ();
+    }
+
+  gtk_widget_destroy (dialog);
+}
+
+/**
+ * This is the main view opening the widget, getting tooltips and drawing the 
+ * tree of attributes
+ */
+GtkWidget *
+create_view_config_default (GtkTreeStore *model)
+{
+  GtkTreeViewColumn *col;
+  GtkCellRenderer *renderer;
+  GtkWidget *view;
+
+  view = gtk_tree_view_new ();
+  g_object_set (view, "has-tooltip", TRUE, (char*) 0);
+  g_signal_connect (view, "query-tooltip", (GCallback) cell_tooltip_callback_config_default, 0);
+
+  gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_BOTH);
+  gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
+
+  col = gtk_tree_view_column_new ();
+  gtk_tree_view_column_set_title (col, "Object Attributes");
+  gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_tree_view_column_pack_start (col, renderer, TRUE);
+  gtk_tree_view_column_set_cell_data_func (col, renderer, cell_data_function_col_0_config_default, 0, 0);
+  g_object_set (renderer, "editable", FALSE, (char*) 0);
+
+  col = gtk_tree_view_column_new ();
+  gtk_tree_view_column_set_title (col, "Attribute Value");
+  gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
+  renderer = gtk_cell_renderer_text_new ();
+  g_signal_connect (renderer, "edited", (GCallback) cell_edited_callback_config_default, model);
+  gtk_tree_view_column_pack_start (col, renderer, TRUE);
+  gtk_tree_view_column_set_cell_data_func (col, renderer, cell_data_function_col_1_config_default, 0, 0);
+
+  gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (model));
+
+  g_object_unref (model); /* destroy model automatically with view */
+
+  return view;
+}
+
+/**
+ * Delete the tree model contents
+ */
+gboolean
+clean_model_callback_config_default (GtkTreeModel *model, GtkTreePath *path,
+                                     GtkTreeIter *iter, gpointer data)
+{
+  ModelTypeid *node;
+  gtk_tree_model_get (GTK_TREE_MODEL (model), iter, COL_TYPEID, &node, -1);
+  delete node;
+  gtk_tree_store_set (GTK_TREE_STORE (model), iter, COL_TYPEID, (ModelTypeid*) 0, -1);
+  return FALSE;
+}
+
+
+}//end ns3 namespace
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/display-functions.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,150 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  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: Faker Moatamri <faker.moatamri@sophia.inria.fr>
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef DISPLAY_FUNCTIONS_H
+#define DISPLAY_FUNCTIONS_H
+
+#include "model-node-creator.h"
+#include "model-typeid-creator.h"
+#include <gtk/gtk.h>
+
+namespace ns3 {
+/**
+ * This function includes the name of the attribute or the editable value
+ * in the second column 
+ */
+void
+cell_data_function_col_1 (GtkTreeViewColumn *col, GtkCellRenderer *renderer,
+                          GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data);
+/**
+ * This function includes the name of the object, pointer, vector or vector item
+ * in the first column
+ */
+void
+cell_data_function_col_0 (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model,
+                          GtkTreeIter *iter, gpointer user_data);
+/**
+ * This is the callback called when the value of an attribute is changed
+ */
+void
+cell_edited_callback (GtkCellRendererText *cell, gchar *path_string,
+                      gchar *new_text, gpointer user_data);
+/**
+ * This function gets the column number 0 or 1 from the mouse
+ * click
+ */
+int
+get_col_number_from_tree_view_column (GtkTreeViewColumn *col);
+/**
+ * This function displays the tooltip for an object, pointer, vector
+ * item or an attribute
+ */
+gboolean
+cell_tooltip_callback (GtkWidget *widget, gint x, gint y, gboolean keyboard_tip, 
+                       GtkTooltip *tooltip, gpointer user_data);
+/**
+ * This is the main view opening the widget, getting tooltips and drawing the 
+ * tree of attributes...
+ */
+GtkWidget *
+create_view (GtkTreeStore *model);
+/**
+ * This is the action done when the user presses on the save button.
+ * It will save the config to a file.
+ */
+void
+save_clicked (GtkButton *button, gpointer user_data);
+/**
+ * If the user presses the button load, it will load the config file into memory.
+ */
+void
+load_clicked (GtkButton *button, gpointer user_data);
+/**
+ * Exit the window when exit button is pressed
+ */
+void
+exit_clicked_callback (GtkButton *button, gpointer user_data);
+/**
+ * Exit the application
+ */
+gboolean
+delete_event_callback (GtkWidget *widget, GdkEvent *event, gpointer user_data);
+/**
+ * Delete the tree model contents
+ */
+gboolean
+clean_model_callback (GtkTreeModel *model, GtkTreePath *path,
+                      GtkTreeIter *iter, gpointer data);
+/**************************     display functions used by default configurator **********************/
+/**
+ * This function writes data in the second column, this data is going to be editable
+ * if it is a NODE_ATTRIBUTE
+ */
+void
+cell_data_function_col_1_config_default (GtkTreeViewColumn *col, GtkCellRenderer *renderer, 
+                                         GtkTreeModel *model, GtkTreeIter *iter,
+                                         gpointer user_data);
+/**
+ * This function writes the attribute or typeid name in the column 0
+ */
+void
+cell_data_function_col_0_config_default (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, 
+                                         GtkTreeIter *iter, gpointer user_data);
+/**
+ * This is the action done when the user presses on the save button.
+ * It will save the config to a file.
+ */
+void
+save_clicked_default (GtkButton *button, gpointer user_data);
+/**
+ * If the user presses the button load, it will load the config file into memory.
+ */
+void
+load_clicked_default (GtkButton *button, gpointer user_data);
+/**
+ *  This functions is called whenever there is a change in the value of an attribute
+ *  If the input value is ok, it will be updated in the default value and in the
+ *  gui, otherwise, it won't be updated in both.
+ */
+void
+cell_edited_callback_config_default (GtkCellRendererText *cell, gchar *path_string,
+                                     gchar *new_text, gpointer user_data);
+/**
+ * This function is used to display a tooltip whenever the user puts the mouse
+ * over a type ID or an attribute. It will give the type and the possible values of
+ * an attribute value and the type of the object for an attribute object or a 
+ * typeID object 
+ */
+gboolean
+cell_tooltip_callback_config_default (GtkWidget *widget, gint x, gint y,
+                                      gboolean keyboard_tip, GtkTooltip *tooltip, gpointer user_data);
+/**
+ * This is the main view opening the widget, getting tooltips and drawing the 
+ * tree of attributes
+ */
+GtkWidget *
+create_view_config_default (GtkTreeStore *model);
+/**
+ * Delete the tree model contents
+ */
+gboolean
+clean_model_callback_config_default (GtkTreeModel *model, GtkTreePath *path,
+                                     GtkTreeIter *iter, gpointer data);
+}//end namespace ns3
+
+#endif
--- a/src/contrib/event-garbage-collector.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/contrib/event-garbage-collector.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -138,7 +138,7 @@
   Simulator::Run ();
   NS_TEST_EXPECT_MSG_EQ (m_events, 0, "");
   NS_TEST_EXPECT_MSG_EQ (m_counter, 50, "");
-
+  Simulator::Destroy ();
   return false;
 }
 
--- a/src/contrib/gtk-config-store.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/contrib/gtk-config-store.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -1,11 +1,26 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  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: Faker Moatamri <faker.moatamri@sophia.inria.fr>
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
 #include "gtk-config-store.h"
-#include "attribute-iterator.h"
 #include "raw-text-config.h"
-#include "ns3/config.h"
-#include "ns3/string.h"
-#include "ns3/pointer.h"
+#include "display-functions.h"
 #include "ns3/log.h"
-#include <gtk/gtk.h>
 #include <fstream>
 
 
@@ -13,475 +28,62 @@
 
 NS_LOG_COMPONENT_DEFINE ("GtkconfigStore");
 
-enum {
-  COL_NODE = 0,
-  COL_LAST
-};
 
-struct ModelNode
-{
-  enum {
-    // store object + attribute name
-    NODE_ATTRIBUTE,
-    // store object + attribute name
-    NODE_POINTER,
-    // store object + attribute name
-    NODE_VECTOR,
-    // store index + value (object)
-    NODE_VECTOR_ITEM,
-    // store object
-    NODE_OBJECT
-  } type;
-  std::string name;
-  Ptr<Object> object;
-  uint32_t index;
-};
-
-class ModelCreator : public AttributeIterator
-{
-public:
-  ModelCreator ();
-
-  void Build (GtkTreeStore *treestore);
-private:
-  virtual void DoVisitAttribute (Ptr<Object> object, std::string name);
-  virtual void DoStartVisitObject (Ptr<Object> object);
-  virtual void DoEndVisitObject (void);
-  virtual void DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> value);
-  virtual void DoEndVisitPointerAttribute (void);
-  virtual void DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector);
-  virtual void DoEndVisitArrayAttribute (void);
-  virtual void DoStartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item);
-  virtual void DoEndVisitArrayItem (void);
-  void Add (ModelNode *node);
-  void Remove (void);
-
-  GtkTreeStore *m_treestore;
-  std::vector<GtkTreeIter *> m_iters;
-};
-
-ModelCreator::ModelCreator ()
-{}
-void 
-ModelCreator::Build (GtkTreeStore *treestore)
-{
-  m_treestore = treestore;
-  m_iters.push_back (0);
-  Iterate ();
-  NS_ASSERT (m_iters.size () == 1);
-}
-
-
-void
-ModelCreator::Add (ModelNode *node)
-{
-  GtkTreeIter *parent = m_iters.back ();
-  GtkTreeIter *current = g_new (GtkTreeIter, 1);
-  gtk_tree_store_append (m_treestore, current, parent);
-  gtk_tree_store_set (m_treestore, current,
-		      COL_NODE, node,
-                     -1);
-  m_iters.push_back (current);
-}
-void
-ModelCreator::Remove (void)
-{
-  GtkTreeIter *iter = m_iters.back ();
-  g_free (iter);
-  m_iters.pop_back ();
-}
-
-void 
-ModelCreator::DoVisitAttribute (Ptr<Object> object, std::string name)
-{
-  ModelNode *node = new ModelNode ();
-  node->type = ModelNode::NODE_ATTRIBUTE;
-  node->object = object;
-  node->name = name;
-  Add (node);
-  Remove ();
-}
-void 
-ModelCreator::DoStartVisitObject (Ptr<Object> object)
-{
-  ModelNode *node = new ModelNode ();
-  node->type = ModelNode::NODE_OBJECT;
-  node->object = object;
-  Add (node);
-}
-void 
-ModelCreator::DoEndVisitObject (void)
-{
-  Remove ();
-}
-void 
-ModelCreator::DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> value)
+GtkConfigStore::GtkConfigStore ()
 {
-  ModelNode *node = new ModelNode ();
-  node->type = ModelNode::NODE_POINTER;
-  node->object = object;
-  node->name = name;
-  Add (node);
-}
-void 
-ModelCreator::DoEndVisitPointerAttribute (void)
-{
-  Remove ();
-}
-void 
-ModelCreator::DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector)
-{
-  ModelNode *node = new ModelNode ();
-  node->type = ModelNode::NODE_VECTOR;
-  node->object = object;
-  node->name = name;
-  Add (node);
-}
-void 
-ModelCreator::DoEndVisitArrayAttribute (void)
-{
-  Remove ();
-}
-void 
-ModelCreator::DoStartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item)
-{
-  GtkTreeIter *parent = m_iters.back ();
-  GtkTreeIter *current = g_new (GtkTreeIter, 1);
-  ModelNode *node = new ModelNode ();
-  node->type = ModelNode::NODE_VECTOR_ITEM;
-  node->object = item;
-  node->index = index;
-  gtk_tree_store_append (m_treestore, current, parent);
-  gtk_tree_store_set (m_treestore, current,
-		      COL_NODE, node,
-                     -1);
-  m_iters.push_back (current);
-}
-void 
-ModelCreator::DoEndVisitArrayItem (void)
-{
-  GtkTreeIter *iter = m_iters.back ();
-  g_free (iter);
-  m_iters.pop_back ();  
-}
-
-static void
-cell_data_function_col_1 (GtkTreeViewColumn *col,
-			  GtkCellRenderer   *renderer,
-			  GtkTreeModel      *model,
-			  GtkTreeIter       *iter,
-			  gpointer           user_data)
-{
-  ModelNode *node;
-  gtk_tree_model_get (model, iter, COL_NODE, &node, -1);
-  if (node->type == ModelNode::NODE_ATTRIBUTE)
-    {
-      StringValue str;
-      node->object->GetAttribute (node->name, str);
-      g_object_set(renderer, "text", str.Get ().c_str (), (char*)0);
-      g_object_set(renderer, "editable", TRUE, (char*)0);
-    }
-  else
-    {
-      g_object_set(renderer, "text", "", (char*)0);
-      g_object_set(renderer, "editable", FALSE, (char*)0);
-    }
-}
-
-static void
-cell_data_function_col_0 (GtkTreeViewColumn *col,
-			  GtkCellRenderer   *renderer,
-			  GtkTreeModel      *model,
-			  GtkTreeIter       *iter,
-			  gpointer           user_data)
-{
-  ModelNode *node;
-  gtk_tree_model_get (model, iter, COL_NODE, &node, -1);
-  g_object_set (renderer, "editable", FALSE, (char*)0);
-  switch (node->type) {
-  case ModelNode::NODE_OBJECT:
-    g_object_set(renderer, "text", node->object->GetInstanceTypeId ().GetName ().c_str (), (char*)0);
-    break;
-  case ModelNode::NODE_POINTER:
-    g_object_set(renderer, "text", node->name.c_str (), (char*)0);
-    break;
-  case ModelNode::NODE_VECTOR:
-    g_object_set(renderer, "text", node->name.c_str (), (char*)0);
-    break;
-  case ModelNode::NODE_VECTOR_ITEM: {
-    std::stringstream oss;
-    oss << node->index;
-    g_object_set(renderer, "text", oss.str ().c_str (), (char*)0);
-  } break;
-  case ModelNode::NODE_ATTRIBUTE:
-    g_object_set(renderer, "text", node->name.c_str (), (char*)0);
-    break;
-  }
-}
-
-
-static void
-cell_edited_callback (GtkCellRendererText *cell,
-		      gchar               *path_string,
-		      gchar               *new_text,
-		      gpointer             user_data)
-{
-  GtkTreeModel *model = GTK_TREE_MODEL (user_data);
-  GtkTreeIter iter;
-  gtk_tree_model_get_iter_from_string (model, &iter, path_string);
-  ModelNode *node;
-  gtk_tree_model_get (model, &iter, COL_NODE, &node, -1);
-  NS_ASSERT (node->type == ModelNode::NODE_ATTRIBUTE);
-  node->object->SetAttribute (node->name, StringValue (new_text));
 }
 
-static int
-get_col_number_from_tree_view_column (GtkTreeViewColumn *col)
+void
+GtkConfigStore::ConfigureDefaults (void)
 {
-  GList *cols;
-  int   num;
-  g_return_val_if_fail ( col != 0, -1 );
-  g_return_val_if_fail ( col->tree_view != 0, -1 );
-  cols = gtk_tree_view_get_columns(GTK_TREE_VIEW(col->tree_view));
-  num = g_list_index(cols, (gpointer) col);
-  g_list_free(cols);
-  return num;
-}
-
-static gboolean
-cell_tooltip_callback (GtkWidget  *widget,
-		       gint        x,
-		       gint        y,
-		       gboolean    keyboard_tip,
-		       GtkTooltip *tooltip,
-		       gpointer    user_data)
-{
-  GtkTreeModel *model;
-  GtkTreeIter iter;
-  GtkTreeViewColumn * column;
-  if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (widget), 
-					  &x, &y, keyboard_tip,
-					  &model, 0, &iter))
-    {
-      return FALSE;
-    }
-  if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
-				      x, y, 0, &column, 0, 0))
-    {
-      return FALSE;
-    }  
-  int col = get_col_number_from_tree_view_column (column);
-
-  ModelNode *node;
-  gtk_tree_model_get (model, &iter, COL_NODE, &node, -1);
+  //this function should be called before running the script to enable the user
+  //to configure the default values for the objects he wants to use
+  GtkWidget *window;
+  GtkWidget *view;
+  GtkWidget *scroll;
 
-  switch (node->type) {
-  case ModelNode::NODE_OBJECT:
-    if (col == 0)
-      {
-	std::string tip = "This object is of type " + node->object->GetInstanceTypeId ().GetName ();
-	gtk_tooltip_set_text (tooltip, tip.c_str ());
-	return TRUE;
-      }
-    break;
-  case ModelNode::NODE_POINTER:
-    if (col == 0)
-      {
-	PointerValue ptr;
-	node->object->GetAttribute (node->name, ptr);
-	std::string tip = "This object is of type " + ptr.GetObject ()->GetInstanceTypeId ().GetName ();
-	gtk_tooltip_set_text (tooltip, tip.c_str ());
-	return TRUE;
-      }
-    break;
-  case ModelNode::NODE_VECTOR:
-    break;
-  case ModelNode::NODE_VECTOR_ITEM:
-    if (col == 0)
-      {
-	std::string tip = "This object is of type " + node->object->GetInstanceTypeId ().GetName ();
-	gtk_tooltip_set_text (tooltip, tip.c_str ());
-	return TRUE;
-      }
-    break;
-  case ModelNode::NODE_ATTRIBUTE: {
-    uint32_t attrIndex = 0;
-    TypeId tid;
-    for (tid = node->object->GetInstanceTypeId (); tid.HasParent (); tid = tid.GetParent ())
-      {
-	for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
-	  {
-	    if (tid.GetAttributeName (i) == node->name)
-	      {
-		attrIndex = i;
-		goto out;
-	      }
-	  }
-      }
-    out:
-    if (col == 0)
-      {
-	std::string tip = tid.GetAttributeHelp (attrIndex);
-	gtk_tooltip_set_text (tooltip, tip.c_str ());
-      }
-    else
-      {
-	Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (attrIndex);
-	std::string tip;
-	tip = "This attribute is of type " + checker->GetValueTypeName ();
-	if (checker->HasUnderlyingTypeInformation ())
-	  {
-	    tip += " " + checker->GetUnderlyingTypeInformation ();
-	  }
-	gtk_tooltip_set_text (tooltip, tip.c_str ());
-      }
-    return TRUE;
-  } break;
-  }
-  return FALSE;
-}
+  gtk_init (0, 0);
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), "ns-3 Default attributes.");
+  gtk_window_set_default_size (GTK_WINDOW (window), 600, 600);
 
+  g_signal_connect (window, "delete_event", (GCallback)delete_event_callback, window);
+  GtkTreeStore *model = gtk_tree_store_new (COL_LAST, G_TYPE_POINTER);
+  ModelTypeidCreator creator;
+  creator.Build (model);
 
-static GtkWidget *
-create_view (GtkTreeStore *model)
-{
-  GtkTreeViewColumn   *col;
-  GtkCellRenderer     *renderer;
-  GtkWidget           *view;
-
-  view = gtk_tree_view_new();
-  g_object_set (view, "has-tooltip", TRUE, (char*)0);
-  g_signal_connect (view, "query-tooltip", (GCallback) cell_tooltip_callback, 0);
-  
-  gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_BOTH);
-  gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
+  view = create_view_config_default (model);
+  scroll = gtk_scrolled_window_new (0, 0);
+  gtk_container_add (GTK_CONTAINER (scroll), view);
 
-  col = gtk_tree_view_column_new();
-  gtk_tree_view_column_set_title(col, "Object Attributes");
-  gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
-  renderer = gtk_cell_renderer_text_new ();
-  gtk_tree_view_column_pack_start(col, renderer, TRUE);
-  gtk_tree_view_column_set_cell_data_func(col, renderer, cell_data_function_col_0, 0, 0);
-  g_object_set(renderer, "editable", FALSE, (char*)0);
-
-  col = gtk_tree_view_column_new();
-  gtk_tree_view_column_set_title(col, "Attribute Value");
-  gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
-  renderer = gtk_cell_renderer_text_new();
-  g_signal_connect(renderer, "edited", (GCallback) cell_edited_callback, model);
-  gtk_tree_view_column_pack_start(col, renderer, TRUE);
-  gtk_tree_view_column_set_cell_data_func(col, renderer, cell_data_function_col_1, 0, 0);
-
-
-  gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL (model));
-
-  g_object_unref(model); /* destroy model automatically with view */
-
-
-  return view;
-}
-
-static void
-save_clicked (GtkButton *button,
-	      gpointer   user_data)
-{
-  GtkWidget *parent_window = GTK_WIDGET (user_data);
-  GtkWidget *dialog;
-
-  dialog = gtk_file_chooser_dialog_new ("Save File",
-					GTK_WINDOW (parent_window),
-					GTK_FILE_CHOOSER_ACTION_SAVE,
-					GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-					GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
-					(char *)0);
-  gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
-
-  gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "config.txt");
-
-
-  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
-    {
-      char *filename;
-
-      filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
-      RawTextConfigSave config;
-      config.SetFilename (filename);
-      config.Attributes ();
-      g_free (filename);
-    }
-
-  gtk_widget_destroy (dialog);
-}
+  GtkWidget *vbox = gtk_vbox_new (FALSE, 5);
+  gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 0);
+  gtk_box_pack_end (GTK_BOX (vbox), gtk_hseparator_new (), FALSE, FALSE, 0);
+  GtkWidget *hbox = gtk_hbox_new (FALSE, 5);
+  gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+  GtkWidget *save = gtk_button_new_with_label ("Save");
+  g_signal_connect (save, "clicked",  (GCallback) save_clicked_default, window);
+  gtk_box_pack_end (GTK_BOX (hbox), save, FALSE, FALSE, 0);
+  GtkWidget *load = gtk_button_new_with_label ("Load");
+  g_signal_connect (load, "clicked",  (GCallback) load_clicked_default, window);
+  gtk_box_pack_end (GTK_BOX (hbox), load, FALSE, FALSE, 0);
+  GtkWidget *exit = gtk_button_new_with_label ("Run Simulation");
+  g_signal_connect (exit, "clicked",  (GCallback) exit_clicked_callback, window);
+  gtk_box_pack_end (GTK_BOX (hbox), exit, FALSE, FALSE, 0);
 
-static void
-load_clicked (GtkButton *button,
-	      gpointer   user_data)
-{
-  GtkWidget *parent_window = GTK_WIDGET (user_data);
-  GtkWidget *dialog;
+  gtk_container_add (GTK_CONTAINER (window), vbox);
 
-  dialog = gtk_file_chooser_dialog_new ("Open File",
-					GTK_WINDOW (parent_window),
-					GTK_FILE_CHOOSER_ACTION_OPEN,
-					GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-					GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
-					(char *)0);
+  gtk_widget_show_all (window);
+
+  gtk_main ();
 
-  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
-    {
-      char *filename;
-
-      filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
-      RawTextConfigLoad config;
-      config.SetFilename (filename);
-      config.Attributes ();
-    }
+  gtk_tree_model_foreach (GTK_TREE_MODEL (model), 
+                          clean_model_callback_config_default,
+                          0);
 
-  gtk_widget_destroy (dialog);
-}
-
-static void 
-exit_clicked_callback (GtkButton *button,
-		       gpointer   user_data)
-{
-  gtk_main_quit ();
-  gtk_widget_hide (GTK_WIDGET (user_data));
+  gtk_widget_destroy (window); 
 }
 
-static gboolean
-delete_event_callback (GtkWidget *widget,
-		       GdkEvent  *event,
-		       gpointer   user_data)
-{
-  gtk_main_quit ();
-  gtk_widget_hide (GTK_WIDGET (user_data));
-  return TRUE;
-}
-
-static gboolean 
-clean_model_callback (GtkTreeModel *model,
-		      GtkTreePath *path,
-		      GtkTreeIter *iter,
-		      gpointer data)
-{
-  ModelNode *node;
-  gtk_tree_model_get (GTK_TREE_MODEL (model), iter, 
-		      COL_NODE, &node, 
-		      -1);
-  delete node;
-  gtk_tree_store_set (GTK_TREE_STORE (model), iter,
-		      COL_NODE, (ModelNode*)0,
-		      -1);
-  return FALSE;
-}
-
-GtkConfigStore::GtkConfigStore ()
-{}
-
-void 
-GtkConfigStore::ConfigureDefaults (void)
-{}
-
 void 
 GtkConfigStore::ConfigureAttributes (void)
 {
@@ -494,7 +96,7 @@
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   gtk_window_set_title (GTK_WINDOW (window), "ns-3 Object attributes.");
   gtk_window_set_default_size (GTK_WINDOW (window), 600, 600);
-  
+
   g_signal_connect (window, "delete_event", (GCallback)delete_event_callback, window);
 
 
@@ -528,8 +130,8 @@
   gtk_main ();
 
   gtk_tree_model_foreach (GTK_TREE_MODEL (model), 
-			  clean_model_callback, 
-			  0);
+                          clean_model_callback,
+                          0);
 
   gtk_widget_destroy (window);
 }
--- a/src/contrib/gtk-config-store.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/contrib/gtk-config-store.h	Thu Feb 25 14:17:21 2010 +0100
@@ -1,3 +1,22 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  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: Faker Moatamri <faker.moatamri@sophia.inria.fr>
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
 #ifndef GTK_CONFIG_STORE_H
 #define GTK_CONFIG_STORE_H
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/model-node-creator.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,130 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  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: Faker Moatamri <faker.moatamri@sophia.inria.fr>
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+ 
+#include "model-node-creator.h"
+namespace ns3 {
+
+ModelCreator::ModelCreator ()
+{
+}
+void
+
+ModelCreator::Build (GtkTreeStore *treestore)
+{
+  m_treestore = treestore;
+  m_iters.push_back (0);
+  //this function will go through all the objects and call on them
+  //DoStartVisitObject, DoIterate and DoEndVisitObject
+  Iterate ();
+  NS_ASSERT (m_iters.size () == 1);
+}
+
+
+void
+ModelCreator::Add (ModelNode *node)
+{
+  GtkTreeIter *parent = m_iters.back ();
+  GtkTreeIter *current = g_new (GtkTreeIter, 1);
+  gtk_tree_store_append (m_treestore, current, parent);
+  gtk_tree_store_set (m_treestore, current,
+                      COL_NODE, node, -1);
+  m_iters.push_back (current);
+}
+void
+ModelCreator::Remove (void)
+{
+  GtkTreeIter *iter = m_iters.back ();
+  g_free (iter);
+  m_iters.pop_back ();
+}
+
+void 
+ModelCreator::DoVisitAttribute (Ptr<Object> object, std::string name)
+{
+  ModelNode *node = new ModelNode ();
+  node->type = ModelNode::NODE_ATTRIBUTE;
+  node->object = object;
+  node->name = name;
+  Add (node);
+  Remove ();
+}
+void 
+ModelCreator::DoStartVisitObject (Ptr<Object> object)
+{
+  ModelNode *node = new ModelNode ();
+  node->type = ModelNode::NODE_OBJECT;
+  node->object = object;
+  Add (node);
+}
+void 
+ModelCreator::DoEndVisitObject (void)
+{
+  Remove ();
+}
+void 
+ModelCreator::DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> value)
+{
+  ModelNode *node = new ModelNode ();
+  node->type = ModelNode::NODE_POINTER;
+  node->object = object;
+  node->name = name;
+  Add (node);
+}
+void 
+ModelCreator::DoEndVisitPointerAttribute (void)
+{
+  Remove ();
+}
+void 
+ModelCreator::DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector)
+{
+  ModelNode *node = new ModelNode ();
+  node->type = ModelNode::NODE_VECTOR;
+  node->object = object;
+  node->name = name;
+  Add (node);
+}
+void 
+ModelCreator::DoEndVisitArrayAttribute (void)
+{
+  Remove ();
+}
+void 
+ModelCreator::DoStartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item)
+{
+  GtkTreeIter *parent = m_iters.back ();
+  GtkTreeIter *current = g_new (GtkTreeIter, 1);
+  ModelNode *node = new ModelNode ();
+  node->type = ModelNode::NODE_VECTOR_ITEM;
+  node->object = item;
+  node->index = index;
+  gtk_tree_store_append (m_treestore, current, parent);
+  gtk_tree_store_set (m_treestore, current,
+              COL_NODE, node,
+                     -1);
+  m_iters.push_back (current);
+}
+void 
+ModelCreator::DoEndVisitArrayItem (void)
+{
+  GtkTreeIter *iter = m_iters.back ();
+  g_free (iter);
+  m_iters.pop_back ();  
+}
+}//end namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/model-node-creator.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,73 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  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: Faker Moatamri <faker.moatamri@sophia.inria.fr>
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "attribute-iterator.h"
+#include <gtk/gtk.h>
+
+namespace ns3
+{
+
+enum
+{
+  COL_NODE = 0, COL_LAST
+};
+
+struct ModelNode
+{
+  enum
+  {
+    // store object + attribute name
+    NODE_ATTRIBUTE,
+    // store object + attribute name
+    NODE_POINTER,
+    // store object + attribute name
+    NODE_VECTOR,
+    // store index + value (object)
+    NODE_VECTOR_ITEM,
+    // store object
+    NODE_OBJECT
+  } type;
+  std::string name;
+  Ptr<Object> object;
+  uint32_t index;
+};
+class ModelCreator : public AttributeIterator
+{
+public:
+  ModelCreator ();
+
+  void Build (GtkTreeStore *treestore);
+private:
+  virtual void DoVisitAttribute (Ptr<Object> object, std::string name);
+  virtual void DoStartVisitObject (Ptr<Object> object);
+  virtual void DoEndVisitObject (void);
+  virtual void DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> value);
+  virtual void DoEndVisitPointerAttribute (void);
+  virtual void DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector);
+  virtual void DoEndVisitArrayAttribute (void);
+  virtual void DoStartVisitArrayItem (const ObjectVectorValue &vector,
+                                      uint32_t index, Ptr<Object> item);
+  virtual void DoEndVisitArrayItem (void);
+  void Add (ModelNode *node);
+  void Remove (void);
+
+  GtkTreeStore *m_treestore;
+  std::vector<GtkTreeIter *> m_iters;
+};
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/model-typeid-creator.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,81 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  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: Faker Moatamri <faker.moatamri@sophia.inria.fr>
+ */
+
+#include "model-typeid-creator.h"
+
+namespace ns3 {
+
+ModelTypeidCreator::ModelTypeidCreator ()
+{
+}
+void
+
+ModelTypeidCreator::Build (GtkTreeStore *treestore)
+{
+  m_treestore = treestore;
+  m_iters.push_back (0);
+  Iterate ();
+  NS_ASSERT (m_iters.size () == 1);
+}
+
+void
+ModelTypeidCreator::Add (ModelTypeid *node)
+{
+  GtkTreeIter *parent = m_iters.back ();
+  GtkTreeIter *current = g_new (GtkTreeIter, 1);
+  gtk_tree_store_append (m_treestore, current, parent);
+  gtk_tree_store_set (m_treestore, current, COL_TYPEID, node, -1);
+  m_iters.push_back (current);
+}
+
+void
+ModelTypeidCreator::Remove (void)
+{
+  GtkTreeIter *iter = m_iters.back ();
+  g_free (iter);
+  m_iters.pop_back ();
+}
+
+void 
+ModelTypeidCreator::VisitAttribute (TypeId tid, std::string name, std::string defaultValue, uint32_t index)
+{
+  ModelTypeid *node = new ModelTypeid ();
+  node->type = ModelTypeid::NODE_ATTRIBUTE;
+  node->tid = tid;
+  node->name = name;
+  node->defaultValue = defaultValue;
+  node->index = index;
+  Add (node);
+  Remove ();
+}
+
+void 
+ModelTypeidCreator::StartVisitTypeId (std::string name)
+{
+  ModelTypeid *node = new ModelTypeid ();
+  node->type = ModelTypeid::NODE_TYPEID;
+  node->tid = TypeId::LookupByName (name);
+  Add (node);
+}
+
+void 
+ModelTypeidCreator::EndVisitTypeId (void)
+{
+  Remove ();
+}
+}//end namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/model-typeid-creator.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,82 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  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: Moatamri Faker <faker.moatamri@sophia.inria.fr>
+ */
+
+#include "attribute-default-iterator.h"
+#include "ns3/type-id.h"
+#include <gtk/gtk.h>
+#include <vector>
+
+namespace ns3 {
+
+enum
+{
+  COL_TYPEID = 0, COL_LASTID
+};
+
+struct ModelTypeid
+{
+  enum
+  {
+    // store TypeId + attribute name +defaultValue and index
+    NODE_ATTRIBUTE,
+    // store TypeId
+    NODE_TYPEID
+  } type;
+  std::string name;
+  std::string defaultValue;
+  //The TypeId object and if it is an attribute, it's the TypeId object of the attribute
+  TypeId tid;
+  //stores the index of the attribute in list of attributes for a given TypeId
+  uint32_t index;
+};
+class ModelTypeidCreator : public AttributeDefaultIterator
+{
+public:
+  ModelTypeidCreator ();
+  /**
+   * \brief This method will iterate on typeIds having default attributes and create a model
+   * for them, this model will be used by the view.
+   */
+  void Build (GtkTreeStore *treestore);
+private:
+  /**
+   * \brief This method will add a ModelTypeid to the GtkTreeIterator
+   */
+  virtual void VisitAttribute (TypeId tid, std::string name, std::string defaultValue, uint32_t index);
+  /**
+   * \brief Add a node for the new TypeId object
+   */
+  virtual void StartVisitTypeId (std::string name);
+  /**
+   * \brief Remove the last gtk tree iterator
+   */
+  virtual void EndVisitTypeId (void);
+  /**
+   * \brief Adds a treestore iterator to m_treestore model
+   */
+  void Add (ModelTypeid *node);
+  /**
+   * Removes the last GtkTreeIterator from m_iters
+   */
+  void Remove (void);
+  //this is the TreeStore model corresponding to the view
+  GtkTreeStore *m_treestore;
+  //This contains a vector of iterators used to build the TreeStore
+  std::vector<GtkTreeIter *> m_iters;
+};
+}
--- a/src/contrib/raw-text-config.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/contrib/raw-text-config.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -41,7 +41,7 @@
     virtual void StartVisitTypeId (std::string name) {
       m_typeId = name;
     }
-    virtual void VisitAttribute (std::string name, std::string defaultValue) {
+    virtual void DoVisitAttribute (std::string name, std::string defaultValue) {
       *m_os << "default " << m_typeId << "::" << name << " \"" << defaultValue << "\"" << std::endl;
     }
     std::string m_typeId;
--- a/src/contrib/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/contrib/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -47,7 +47,11 @@
 
     if bld.env['ENABLE_GTK_CONFIG_STORE']:
         headers.source.append ('gtk-config-store.h')
-        module.source.append ('gtk-config-store.cc')
+        module.source.extend (['gtk-config-store.cc',
+                               'model-node-creator.cc',
+                               'model-typeid-creator.cc',
+                               'display-functions.cc',
+                               ])
         module.uselib = 'GTK_CONFIG_STORE'
 
     if bld.env['ENABLE_LIBXML2']:
--- a/src/contrib/xml-config.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/contrib/xml-config.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -90,7 +90,7 @@
     virtual void StartVisitTypeId (std::string name) {
       m_typeid = name;
     }
-    virtual void VisitAttribute (std::string name, std::string defaultValue) {
+    virtual void DoVisitAttribute (std::string name, std::string defaultValue) {
       int rc;
       rc = xmlTextWriterStartElement(m_writer, BAD_CAST "default");
        if (rc < 0) 
--- a/src/core/random-variable.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/core/random-variable.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -23,12 +23,12 @@
 
 #include <math.h>
 #include <stdlib.h>
-#include <sys/time.h>			// for gettimeofday
+#include <sys/time.h>                   // for gettimeofday
 #include <unistd.h>
 #include <iostream>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <fcntl.h>       
+#include <fcntl.h>
 #include <sstream>
 #include <vector>
 
@@ -42,100 +42,103 @@
 
 using namespace std;
 
-namespace ns3{
+namespace ns3 {
 
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // Seed Manager
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 
-uint32_t SeedManager::GetSeed()
+uint32_t SeedManager::GetSeed ()
 {
   uint32_t s[6];
   RngStream::GetPackageSeed (s);
-  NS_ASSERT(
-              s[0] == s[1] &&
-              s[0] == s[2] &&
-              s[0] == s[3] &&
-              s[0] == s[4] &&
-              s[0] == s[5]    
-            );
+  NS_ASSERT (
+    s[0] == s[1]
+    && s[0] == s[2]
+    && s[0] == s[3]
+    && s[0] == s[4]
+    && s[0] == s[5]
+    );
   return s[0];
 }
 
-void SeedManager::SetSeed(uint32_t seed)
+void SeedManager::SetSeed (uint32_t seed)
 {
-  Config::SetGlobal("RngSeed", IntegerValue(seed));
+  Config::SetGlobal ("RngSeed", IntegerValue (seed));
 }
 
-void SeedManager::SetRun(uint32_t run)
+void SeedManager::SetRun (uint32_t run)
 {
-  Config::SetGlobal("RngRun", IntegerValue(run));
+  Config::SetGlobal ("RngRun", IntegerValue (run));
 }
 
-uint32_t SeedManager::GetRun()
+uint32_t SeedManager::GetRun ()
 {
   return RngStream::GetPackageRun ();
 }
 
 bool SeedManager::CheckSeed (uint32_t seed)
 {
-  return RngStream::CheckSeed(seed);
+  return RngStream::CheckSeed (seed);
 }
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // RandomVariableBase methods
 
 
-class RandomVariableBase 
+class RandomVariableBase
 {
 public:
   RandomVariableBase ();
   RandomVariableBase (const RandomVariableBase &o);
-  virtual ~RandomVariableBase();
-  virtual double  GetValue() = 0;
-  virtual uint32_t GetInteger();
-  virtual RandomVariableBase*   Copy(void) const = 0;
+  virtual ~RandomVariableBase ();
+  virtual double  GetValue () = 0;
+  virtual uint32_t GetInteger ();
+  virtual RandomVariableBase*   Copy (void) const = 0;
 
 protected:
-  RngStream* m_generator;  //underlying generator being wrapped
+  RngStream* m_generator;  // underlying generator being wrapped
 };
 
-RandomVariableBase::RandomVariableBase() 
-  : m_generator(NULL)
+RandomVariableBase::RandomVariableBase ()
+  : m_generator (NULL)
 {
 }
 
-RandomVariableBase::RandomVariableBase(const RandomVariableBase& r)
-  :m_generator(0)
+RandomVariableBase::RandomVariableBase (const RandomVariableBase& r)
+  : m_generator (0)
 {
   if (r.m_generator)
     {
-      m_generator = new RngStream(*r.m_generator);
+      m_generator = new RngStream (*r.m_generator);
     }
 }
 
-RandomVariableBase::~RandomVariableBase()
+RandomVariableBase::~RandomVariableBase ()
 {
   delete m_generator;
 }
 
-uint32_t RandomVariableBase::GetInteger() 
+uint32_t RandomVariableBase::GetInteger ()
 {
-  return (uint32_t)GetValue();
+  return (uint32_t)GetValue ();
 }
 
-//-------------------------------------------------------
+// -------------------------------------------------------
 
-RandomVariable::RandomVariable()
+RandomVariable::RandomVariable ()
   : m_variable (0)
-{}
-RandomVariable::RandomVariable(const RandomVariable&o)
+{
+}
+RandomVariable::RandomVariable (const RandomVariable&o)
   : m_variable (o.m_variable->Copy ())
-{}
+{
+}
 RandomVariable::RandomVariable (const RandomVariableBase &variable)
   : m_variable (variable.Copy ())
-{}
+{
+}
 RandomVariable &
 RandomVariable::operator = (const RandomVariable &o)
 {
@@ -147,17 +150,17 @@
   m_variable = o.m_variable->Copy ();
   return *this;
 }
-RandomVariable::~RandomVariable()
+RandomVariable::~RandomVariable ()
 {
   delete m_variable;
 }
-double  
+double
 RandomVariable::GetValue (void) const
 {
   return m_variable->GetValue ();
 }
 
-uint32_t 
+uint32_t
 RandomVariable::GetInteger (void) const
 {
   return m_variable->GetInteger ();
@@ -173,197 +176,223 @@
 ATTRIBUTE_VALUE_IMPLEMENT (RandomVariable);
 ATTRIBUTE_CHECKER_IMPLEMENT (RandomVariable);
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // UniformVariableImpl
 
-class UniformVariableImpl : public RandomVariableBase {
+class UniformVariableImpl : public RandomVariableBase
+{
 public:
   /**
    * Creates a uniform random number generator in the
    * range [0.0 .. 1.0).
    */
-  UniformVariableImpl();
+  UniformVariableImpl ();
 
   /**
    * Creates a uniform random number generator with the specified range
    * \param s Low end of the range
    * \param l High end of the range
    */
-  UniformVariableImpl(double s, double l);
+  UniformVariableImpl (double s, double l);
 
-  UniformVariableImpl(const UniformVariableImpl& c);
+  UniformVariableImpl (const UniformVariableImpl& c);
 
   double GetMin (void) const;
   double GetMax (void) const;
-  
+
   /**
    * \return A value between low and high values specified by the constructor
    */
-  virtual double GetValue();
+  virtual double GetValue ();
 
   /**
    * \return A value between low and high values specified by parameters
    */
-  virtual double GetValue(double s, double l);
-  
-  virtual RandomVariableBase*  Copy(void) const;
+  virtual double GetValue (double s, double l);
+
+  virtual RandomVariableBase*  Copy (void) const;
 
 private:
   double m_min;
   double m_max;
 };
 
-UniformVariableImpl::UniformVariableImpl() 
-  : m_min(0), m_max(1.0) { }
-  
-UniformVariableImpl::UniformVariableImpl(double s, double l) 
-  : m_min(s), m_max(l) { }
+UniformVariableImpl::UniformVariableImpl ()
+  : m_min (0),
+    m_max (1.0)
+{
+}
 
-UniformVariableImpl::UniformVariableImpl(const UniformVariableImpl& c) 
-  : RandomVariableBase(c), m_min(c.m_min), m_max(c.m_max) { }
+UniformVariableImpl::UniformVariableImpl (double s, double l)
+  : m_min (s),
+    m_max (l)
+{
+}
 
-double 
+UniformVariableImpl::UniformVariableImpl (const UniformVariableImpl& c)
+  : RandomVariableBase (c),
+    m_min (c.m_min),
+    m_max (c.m_max)
+{
+}
+
+double
 UniformVariableImpl::GetMin (void) const
 {
   return m_min;
 }
-double 
+double
 UniformVariableImpl::GetMax (void) const
 {
   return m_max;
 }
 
 
-double UniformVariableImpl::GetValue()
+double UniformVariableImpl::GetValue ()
 {
-  if(!m_generator)
+  if (!m_generator)
     {
-      m_generator = new RngStream();
+      m_generator = new RngStream ();
     }
-  return m_min + m_generator->RandU01() * (m_max - m_min);
+  return m_min + m_generator->RandU01 () * (m_max - m_min);
 }
 
-double UniformVariableImpl::GetValue(double s, double l) 
+double UniformVariableImpl::GetValue (double s, double l)
 {
-  if(!m_generator)
+  if (!m_generator)
     {
-      m_generator = new RngStream();
+      m_generator = new RngStream ();
     }
-    return s + m_generator->RandU01() * (l-s); 
+  return s + m_generator->RandU01 () * (l - s);
 }
 
-RandomVariableBase* UniformVariableImpl::Copy() const
+RandomVariableBase* UniformVariableImpl::Copy () const
 {
-  return new UniformVariableImpl(*this);
+  return new UniformVariableImpl (*this);
 }
 
-UniformVariable::UniformVariable()
+UniformVariable::UniformVariable ()
   : RandomVariable (UniformVariableImpl ())
-{}
-UniformVariable::UniformVariable(double s, double l)
+{
+}
+UniformVariable::UniformVariable (double s, double l)
   : RandomVariable (UniformVariableImpl (s, l))
-{}
+{
+}
 
-double UniformVariable::GetValue(void) const
+double UniformVariable::GetValue (void) const
 {
   return this->RandomVariable::GetValue ();
 }
 
-double UniformVariable::GetValue(double s, double l)
+double UniformVariable::GetValue (double s, double l)
 {
-  return ((UniformVariableImpl*)Peek())->GetValue(s,l);
+  return ((UniformVariableImpl*)Peek ())->GetValue (s,l);
 }
 
 uint32_t UniformVariable::GetInteger (uint32_t s, uint32_t l)
 {
-  NS_ASSERT(s <= l);
-  return static_cast<uint32_t>( GetValue(s, l+1) );
+  NS_ASSERT (s <= l);
+  return static_cast<uint32_t> ( GetValue (s, l + 1) );
 }
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // ConstantVariableImpl methods
 
-class ConstantVariableImpl : public RandomVariableBase { 
+class ConstantVariableImpl : public RandomVariableBase
+{
 
 public:
   /**
    * Construct a ConstantVariableImpl RNG that returns zero every sample
    */
-  ConstantVariableImpl();
-  
+  ConstantVariableImpl ();
+
   /**
    * Construct a ConstantVariableImpl RNG that returns the specified value
    * every sample.
    * \param c Unchanging value for this RNG.
    */
-  ConstantVariableImpl(double c);
+  ConstantVariableImpl (double c);
 
 
-  ConstantVariableImpl(const ConstantVariableImpl& c) ;
+  ConstantVariableImpl (const ConstantVariableImpl& c);
 
   /**
    * \brief Specify a new constant RNG for this generator.
    * \param c New constant value for this RNG.
    */
-  void    NewConstant(double c);
+  void    NewConstant (double c);
 
   /**
    * \return The constant value specified
    */
-  virtual double  GetValue();
-  virtual uint32_t GetInteger();
-  virtual RandomVariableBase*   Copy(void) const;
+  virtual double  GetValue ();
+  virtual uint32_t GetInteger ();
+  virtual RandomVariableBase*   Copy (void) const;
 private:
   double m_const;
 };
 
-ConstantVariableImpl::ConstantVariableImpl() 
-  : m_const(0) { }
+ConstantVariableImpl::ConstantVariableImpl ()
+  : m_const (0)
+{
+}
+
+ConstantVariableImpl::ConstantVariableImpl (double c)
+  : m_const (c)
+{
+}
 
-ConstantVariableImpl::ConstantVariableImpl(double c) 
-  : m_const(c) { };
-  
-ConstantVariableImpl::ConstantVariableImpl(const ConstantVariableImpl& c) 
-  : RandomVariableBase(c), m_const(c.m_const) { }
+ConstantVariableImpl::ConstantVariableImpl (const ConstantVariableImpl& c)
+  : RandomVariableBase (c),
+    m_const (c.m_const)
+{
+}
 
-void ConstantVariableImpl::NewConstant(double c) 
-  { m_const = c;}
-  
-double ConstantVariableImpl::GetValue()
+void ConstantVariableImpl::NewConstant (double c)
+{
+  m_const = c;
+}
+
+double ConstantVariableImpl::GetValue ()
 {
   return m_const;
 }
 
-uint32_t ConstantVariableImpl::GetInteger()
+uint32_t ConstantVariableImpl::GetInteger ()
 {
   return (uint32_t)m_const;
 }
 
-RandomVariableBase* ConstantVariableImpl::Copy() const
+RandomVariableBase* ConstantVariableImpl::Copy () const
 {
-  return new ConstantVariableImpl(*this);
+  return new ConstantVariableImpl (*this);
 }
 
-ConstantVariable::ConstantVariable()
+ConstantVariable::ConstantVariable ()
   : RandomVariable (ConstantVariableImpl ())
-{}
-ConstantVariable::ConstantVariable(double c)
+{
+}
+ConstantVariable::ConstantVariable (double c)
   : RandomVariable (ConstantVariableImpl (c))
-{}
-void 
-ConstantVariable::SetConstant(double c)
+{
+}
+void
+ConstantVariable::SetConstant (double c)
 {
   *this = ConstantVariable (c);
 }
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // SequentialVariableImpl methods
 
 
-class SequentialVariableImpl : public RandomVariableBase {
+class SequentialVariableImpl : public RandomVariableBase
+{
 
 public:
   /**
@@ -377,7 +406,7 @@
    * \param i Increment between sequence values
    * \param c Number of times each member of the sequence is repeated
    */
-  SequentialVariableImpl(double f, double l, double i = 1, uint32_t c = 1);
+  SequentialVariableImpl (double f, double l, double i = 1, uint32_t c = 1);
 
   /**
    * \brief Constructor for the SequentialVariableImpl RNG.
@@ -389,16 +418,16 @@
    * \param i Reference to a RandomVariableBase for the sequence increment
    * \param c Number of times each member of the sequence is repeated
    */
-  SequentialVariableImpl(double f, double l, const RandomVariable& i, uint32_t c = 1);
+  SequentialVariableImpl (double f, double l, const RandomVariable& i, uint32_t c = 1);
 
-  SequentialVariableImpl(const SequentialVariableImpl& c);
-  
-  ~SequentialVariableImpl();
+  SequentialVariableImpl (const SequentialVariableImpl& c);
+
+  ~SequentialVariableImpl ();
   /**
    * \return The next value in the Sequence
    */
-  virtual double GetValue();
-  virtual RandomVariableBase*  Copy(void) const;
+  virtual double GetValue ();
+  virtual RandomVariableBase*  Copy (void) const;
 private:
   double m_min;
   double m_max;
@@ -408,152 +437,193 @@
   uint32_t  m_currentConsecutive;
 };
 
-SequentialVariableImpl::SequentialVariableImpl(double f, double l, double i, uint32_t c)
-  : m_min(f), m_max(l), m_increment(ConstantVariable(i)), m_consecutive(c),
-    m_current(f), m_currentConsecutive(0)
-{}
-
-SequentialVariableImpl::SequentialVariableImpl(double f, double l, const RandomVariable& i, uint32_t c)
-  : m_min(f), m_max(l), m_increment(i), m_consecutive(c),
-    m_current(f), m_currentConsecutive(0)
-{}
+SequentialVariableImpl::SequentialVariableImpl (double f, double l, double i, uint32_t c)
+  : m_min (f),
+    m_max (l),
+    m_increment (ConstantVariable (i)),
+    m_consecutive (c),
+    m_current (f),
+    m_currentConsecutive (0)
+{
+}
 
-SequentialVariableImpl::SequentialVariableImpl(const SequentialVariableImpl& c)
-  : RandomVariableBase(c), m_min(c.m_min), m_max(c.m_max),
-    m_increment(c.m_increment), m_consecutive(c.m_consecutive),
-    m_current(c.m_current), m_currentConsecutive(c.m_currentConsecutive)
-{}
+SequentialVariableImpl::SequentialVariableImpl (double f, double l, const RandomVariable& i, uint32_t c)
+  : m_min (f),
+    m_max (l),
+    m_increment (i),
+    m_consecutive (c),
+    m_current (f),
+    m_currentConsecutive (0)
+{
+}
 
-SequentialVariableImpl::~SequentialVariableImpl()
-{}
+SequentialVariableImpl::SequentialVariableImpl (const SequentialVariableImpl& c)
+  : RandomVariableBase (c),
+    m_min (c.m_min),
+    m_max (c.m_max),
+    m_increment (c.m_increment),
+    m_consecutive (c.m_consecutive),
+    m_current (c.m_current),
+    m_currentConsecutive (c.m_currentConsecutive)
+{
+}
 
-double SequentialVariableImpl::GetValue()
+SequentialVariableImpl::~SequentialVariableImpl ()
+{
+}
+
+double SequentialVariableImpl::GetValue ()
 { // Return a sequential series of values
   double r = m_current;
   if (++m_currentConsecutive == m_consecutive)
     { // Time to advance to next
       m_currentConsecutive = 0;
-      m_current += m_increment.GetValue();
+      m_current += m_increment.GetValue ();
       if (m_current >= m_max)
-        m_current = m_min + (m_current - m_max);
+        {
+          m_current = m_min + (m_current - m_max);
+        }
     }
   return r;
 }
 
-RandomVariableBase* SequentialVariableImpl::Copy() const
+RandomVariableBase* SequentialVariableImpl::Copy () const
 {
-  return new SequentialVariableImpl(*this);
+  return new SequentialVariableImpl (*this);
 }
 
-SequentialVariable::SequentialVariable(double f, double l, double i, uint32_t c)
+SequentialVariable::SequentialVariable (double f, double l, double i, uint32_t c)
   : RandomVariable (SequentialVariableImpl (f, l, i, c))
-{}
-SequentialVariable::SequentialVariable(double f, double l, const RandomVariable& i, uint32_t c)
+{
+}
+SequentialVariable::SequentialVariable (double f, double l, const RandomVariable& i, uint32_t c)
   : RandomVariable (SequentialVariableImpl (f, l, i, c))
-{}
+{
+}
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // ExponentialVariableImpl methods
 
-class ExponentialVariableImpl : public RandomVariableBase { 
+class ExponentialVariableImpl : public RandomVariableBase
+{
 public:
   /**
    * Constructs an exponential random variable  with a mean
    * value of 1.0.
    */
-  ExponentialVariableImpl();
+  ExponentialVariableImpl ();
 
   /**
    * \brief Constructs an exponential random variable with a specified mean
    * \param m Mean value for the random variable
    */
-  explicit ExponentialVariableImpl(double m);
+  explicit ExponentialVariableImpl (double m);
 
   /**
-   * \brief Constructs an exponential random variable with spefified
-   * \brief mean and upper limit.
+   * \brief Constructs an exponential random variable with specified
+   * mean and upper limit.
    *
    * Since exponential distributions can theoretically return unbounded values,
    * it is sometimes useful to specify a fixed upper limit.  Note however when
-   * the upper limit is specified, the true mean of the distribution is 
-   * slightly smaller than the mean value specified.
+   * the upper limit is specified, the true mean of the distribution is
+   * slightly smaller than the mean value specified: \f$ m - b/(e^{b/m}-1) \f$.
    * \param m Mean value of the random variable
    * \param b Upper bound on returned values
    */
-  ExponentialVariableImpl(double m, double b);
+  ExponentialVariableImpl (double m, double b);
 
-  ExponentialVariableImpl(const ExponentialVariableImpl& c);
-  
+  ExponentialVariableImpl (const ExponentialVariableImpl& c);
+
   /**
    * \return A random value from this exponential distribution
    */
-  virtual double GetValue();
-  virtual RandomVariableBase* Copy(void) const;
+  virtual double GetValue ();
+  virtual RandomVariableBase* Copy (void) const;
 
 private:
   double m_mean;  // Mean value of RV
   double m_bound; // Upper bound on value (if non-zero)
 };
 
-ExponentialVariableImpl::ExponentialVariableImpl() 
-  : m_mean(1.0), m_bound(0) { }
-  
-ExponentialVariableImpl::ExponentialVariableImpl(double m) 
-  : m_mean(m), m_bound(0) { }
-  
-ExponentialVariableImpl::ExponentialVariableImpl(double m, double b) 
-  : m_mean(m), m_bound(b) { }
-  
-ExponentialVariableImpl::ExponentialVariableImpl(const ExponentialVariableImpl& c) 
-  : RandomVariableBase(c), m_mean(c.m_mean), m_bound(c.m_bound) { }
+ExponentialVariableImpl::ExponentialVariableImpl ()
+  : m_mean (1.0),
+    m_bound (0)
+{
+}
+
+ExponentialVariableImpl::ExponentialVariableImpl (double m)
+  : m_mean (m),
+    m_bound (0)
+{
+}
+
+ExponentialVariableImpl::ExponentialVariableImpl (double m, double b)
+  : m_mean (m),
+    m_bound (b)
+{
+}
 
-double ExponentialVariableImpl::GetValue()
+ExponentialVariableImpl::ExponentialVariableImpl (const ExponentialVariableImpl& c)
+  : RandomVariableBase (c),
+    m_mean (c.m_mean),
+    m_bound (c.m_bound)
 {
-  if(!m_generator)
+}
+
+double ExponentialVariableImpl::GetValue ()
+{
+  if (!m_generator)
     {
-      m_generator = new RngStream();
+      m_generator = new RngStream ();
     }
-  while(1)
+  while (1)
     {
-      double r = -m_mean*log(m_generator->RandU01());
-      if (m_bound == 0 || r <= m_bound) return r;
-      //otherwise, try again
+      double r = -m_mean*log (m_generator->RandU01 ());
+      if (m_bound == 0 || r <= m_bound)
+        {
+          return r;
+        }
+      // otherwise, try again
     }
 }
 
-RandomVariableBase* ExponentialVariableImpl::Copy() const
+RandomVariableBase* ExponentialVariableImpl::Copy () const
 {
-  return new ExponentialVariableImpl(*this);
+  return new ExponentialVariableImpl (*this);
 }
 
-ExponentialVariable::ExponentialVariable()
+ExponentialVariable::ExponentialVariable ()
   : RandomVariable (ExponentialVariableImpl ())
-{}
-ExponentialVariable::ExponentialVariable(double m)
+{
+}
+ExponentialVariable::ExponentialVariable (double m)
   : RandomVariable (ExponentialVariableImpl (m))
-{}
-ExponentialVariable::ExponentialVariable(double m, double b)
+{
+}
+ExponentialVariable::ExponentialVariable (double m, double b)
   : RandomVariable (ExponentialVariableImpl (m, b))
-{}
+{
+}
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // ParetoVariableImpl methods
-class ParetoVariableImpl : public RandomVariableBase {
+class ParetoVariableImpl : public RandomVariableBase
+{
 public:
   /**
    * Constructs a pareto random variable with a mean of 1 and a shape
    * parameter of 1.5
    */
-  ParetoVariableImpl();
+  ParetoVariableImpl ();
 
   /**
    * Constructs a pareto random variable with specified mean and shape
    * parameter of 1.5
    * \param m Mean value of the distribution
    */
-  explicit ParetoVariableImpl(double m);
+  explicit ParetoVariableImpl (double m);
 
   /**
    * Constructs a pareto random variable with the specified mean value and
@@ -561,7 +631,7 @@
    * \param m Mean value of the distribution
    * \param s Shape parameter for the distribution
    */
-  ParetoVariableImpl(double m, double s);
+  ParetoVariableImpl (double m, double s);
 
   /**
    * \brief Constructs a pareto random variable with the specified mean
@@ -575,15 +645,15 @@
    * \param s Shape parameter
    * \param b Upper limit on returned values
    */
-  ParetoVariableImpl(double m, double s, double b);
+  ParetoVariableImpl (double m, double s, double b);
 
-  ParetoVariableImpl(const ParetoVariableImpl& c);
-  
+  ParetoVariableImpl (const ParetoVariableImpl& c);
+
   /**
    * \return A random value from this Pareto distribution
    */
-  virtual double GetValue();
-  virtual RandomVariableBase* Copy() const;
+  virtual double GetValue ();
+  virtual RandomVariableBase* Copy () const;
 
 private:
   double m_mean;  // Mean value of RV
@@ -591,66 +661,94 @@
   double m_bound; // Upper bound on value (if non-zero)
 };
 
-ParetoVariableImpl::ParetoVariableImpl() 
-  : m_mean(1.0), m_shape(1.5), m_bound(0) { }
+ParetoVariableImpl::ParetoVariableImpl ()
+  : m_mean (1.0),
+    m_shape (1.5),
+    m_bound (0)
+{
+}
 
-ParetoVariableImpl::ParetoVariableImpl(double m) 
-  : m_mean(m), m_shape(1.5), m_bound(0) { }
+ParetoVariableImpl::ParetoVariableImpl (double m)
+  : m_mean (m),
+    m_shape (1.5),
+    m_bound (0)
+{
+}
 
-ParetoVariableImpl::ParetoVariableImpl(double m, double s) 
-    : m_mean(m), m_shape(s), m_bound(0) { }
+ParetoVariableImpl::ParetoVariableImpl (double m, double s)
+  : m_mean (m),
+    m_shape (s),
+    m_bound (0)
+{
+}
 
-ParetoVariableImpl::ParetoVariableImpl(double m, double s, double b) 
-  : m_mean(m), m_shape(s), m_bound(b) { }
+ParetoVariableImpl::ParetoVariableImpl (double m, double s, double b)
+  : m_mean (m),
+    m_shape (s),
+    m_bound (b)
+{
+}
 
-ParetoVariableImpl::ParetoVariableImpl(const ParetoVariableImpl& c) 
-  : RandomVariableBase(c), m_mean(c.m_mean), m_shape(c.m_shape), 
-    m_bound(c.m_bound) { }
+ParetoVariableImpl::ParetoVariableImpl (const ParetoVariableImpl& c)
+  : RandomVariableBase (c),
+    m_mean (c.m_mean),
+    m_shape (c.m_shape),
+    m_bound (c.m_bound)
+{
+}
 
-double ParetoVariableImpl::GetValue()
+double ParetoVariableImpl::GetValue ()
 {
-  if(!m_generator)
+  if (!m_generator)
     {
-      m_generator = new RngStream();
+      m_generator = new RngStream ();
     }
   double scale = m_mean * ( m_shape - 1.0) / m_shape;
-  while(1)
+  while (1)
     {
-      double r = (scale * ( 1.0 / pow(m_generator->RandU01(), 1.0 / m_shape)));
-      if (m_bound == 0 || r <= m_bound) return r;
-      //otherwise, try again
+      double r = (scale * ( 1.0 / pow (m_generator->RandU01 (), 1.0 / m_shape)));
+      if (m_bound == 0 || r <= m_bound)
+        {
+          return r;
+        }
+      // otherwise, try again
     }
 }
 
-RandomVariableBase* ParetoVariableImpl::Copy() const
+RandomVariableBase* ParetoVariableImpl::Copy () const
 {
-  return new ParetoVariableImpl(*this);
+  return new ParetoVariableImpl (*this);
 }
 
 ParetoVariable::ParetoVariable ()
   : RandomVariable (ParetoVariableImpl ())
-{}
-ParetoVariable::ParetoVariable(double m)
+{
+}
+ParetoVariable::ParetoVariable (double m)
   : RandomVariable (ParetoVariableImpl (m))
-{}
-ParetoVariable::ParetoVariable(double m, double s)
+{
+}
+ParetoVariable::ParetoVariable (double m, double s)
   : RandomVariable (ParetoVariableImpl (m, s))
-{}
-ParetoVariable::ParetoVariable(double m, double s, double b)
+{
+}
+ParetoVariable::ParetoVariable (double m, double s, double b)
   : RandomVariable (ParetoVariableImpl (m, s, b))
-{}
+{
+}
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // WeibullVariableImpl methods
 
-class WeibullVariableImpl : public RandomVariableBase {
+class WeibullVariableImpl : public RandomVariableBase
+{
 public:
   /**
    * Constructs a weibull random variable  with a mean
    * value of 1.0 and a shape (alpha) parameter of 1
    */
-  WeibullVariableImpl();
+  WeibullVariableImpl ();
 
 
   /**
@@ -658,7 +756,7 @@
    * value and a shape (alpha) parameter of 1.5.
    * \param m mean value of the distribution
    */
-   WeibullVariableImpl(double m) ;
+  WeibullVariableImpl (double m);
 
   /**
    * Constructs a weibull random variable with the specified mean
@@ -666,28 +764,28 @@
    * \param m Mean value for the distribution.
    * \param s Shape (alpha) parameter for the distribution.
    */
-  WeibullVariableImpl(double m, double s);
+  WeibullVariableImpl (double m, double s);
 
-   /**
-   * \brief Constructs a weibull random variable with the specified mean
-   * \brief value, shape (alpha), and upper bound.
-   * Since WeibullVariableImpl distributions can theoretically return unbounded values,
-   * it is sometimes usefull to specify a fixed upper limit.  Note however
-   * that when the upper limit is specified, the true mean of the distribution
-   * is slightly smaller than the mean value specified.
-   * \param m Mean value for the distribution.
-   * \param s Shape (alpha) parameter for the distribution.
-   * \param b Upper limit on returned values
-   */
-  WeibullVariableImpl(double m, double s, double b);
+  /**
+  * \brief Constructs a weibull random variable with the specified mean
+  * \brief value, shape (alpha), and upper bound.
+  * Since WeibullVariableImpl distributions can theoretically return unbounded values,
+  * it is sometimes usefull to specify a fixed upper limit.  Note however
+  * that when the upper limit is specified, the true mean of the distribution
+  * is slightly smaller than the mean value specified.
+  * \param m Mean value for the distribution.
+  * \param s Shape (alpha) parameter for the distribution.
+  * \param b Upper limit on returned values
+  */
+  WeibullVariableImpl (double m, double s, double b);
 
-  WeibullVariableImpl(const WeibullVariableImpl& c);
-  
+  WeibullVariableImpl (const WeibullVariableImpl& c);
+
   /**
    * \return A random value from this Weibull distribution
    */
-  virtual double GetValue();
-  virtual RandomVariableBase* Copy(void) const;
+  virtual double GetValue ();
+  virtual RandomVariableBase* Copy (void) const;
 
 private:
   double m_mean;  // Mean value of RV
@@ -695,79 +793,107 @@
   double m_bound; // Upper bound on value (if non-zero)
 };
 
-WeibullVariableImpl::WeibullVariableImpl() : m_mean(1.0), m_alpha(1), m_bound(0) { }
-WeibullVariableImpl::WeibullVariableImpl(double m) 
-  : m_mean(m), m_alpha(1), m_bound(0) { }
-WeibullVariableImpl::WeibullVariableImpl(double m, double s) 
-  : m_mean(m), m_alpha(s), m_bound(0) { }
-WeibullVariableImpl::WeibullVariableImpl(double m, double s, double b) 
-  : m_mean(m), m_alpha(s), m_bound(b) { };
-WeibullVariableImpl::WeibullVariableImpl(const WeibullVariableImpl& c) 
-  : RandomVariableBase(c), m_mean(c.m_mean), m_alpha(c.m_alpha),
-    m_bound(c.m_bound) { }
+WeibullVariableImpl::WeibullVariableImpl () : m_mean (1.0),
+                                              m_alpha (1),
+                                              m_bound (0)
+{
+}
+WeibullVariableImpl::WeibullVariableImpl (double m)
+  : m_mean (m),
+    m_alpha (1),
+    m_bound (0)
+{
+}
+WeibullVariableImpl::WeibullVariableImpl (double m, double s)
+  : m_mean (m),
+    m_alpha (s),
+    m_bound (0)
+{
+}
+WeibullVariableImpl::WeibullVariableImpl (double m, double s, double b)
+  : m_mean (m),
+    m_alpha (s),
+    m_bound (b)
+{
+}
+WeibullVariableImpl::WeibullVariableImpl (const WeibullVariableImpl& c)
+  : RandomVariableBase (c),
+    m_mean (c.m_mean),
+    m_alpha (c.m_alpha),
+    m_bound (c.m_bound)
+{
+}
 
-double WeibullVariableImpl::GetValue()
+double WeibullVariableImpl::GetValue ()
 {
-  if(!m_generator)
+  if (!m_generator)
     {
-      m_generator = new RngStream();
+      m_generator = new RngStream ();
     }
   double exponent = 1.0 / m_alpha;
-  while(1)
+  while (1)
     {
-      double r = m_mean * pow( -log(m_generator->RandU01()), exponent);
-      if (m_bound == 0 || r <= m_bound) return r;
-      //otherwise, try again
+      double r = m_mean * pow ( -log (m_generator->RandU01 ()), exponent);
+      if (m_bound == 0 || r <= m_bound)
+        {
+          return r;
+        }
+      // otherwise, try again
     }
 }
 
-RandomVariableBase* WeibullVariableImpl::Copy() const
+RandomVariableBase* WeibullVariableImpl::Copy () const
 {
-  return new WeibullVariableImpl(*this);
+  return new WeibullVariableImpl (*this);
 }
 
-WeibullVariable::WeibullVariable()
+WeibullVariable::WeibullVariable ()
   : RandomVariable (WeibullVariableImpl ())
-{}
-WeibullVariable::WeibullVariable(double m)
+{
+}
+WeibullVariable::WeibullVariable (double m)
   : RandomVariable (WeibullVariableImpl (m))
-{}
-WeibullVariable::WeibullVariable(double m, double s)
+{
+}
+WeibullVariable::WeibullVariable (double m, double s)
   : RandomVariable (WeibullVariableImpl (m, s))
-{}
-WeibullVariable::WeibullVariable(double m, double s, double b)
+{
+}
+WeibullVariable::WeibullVariable (double m, double s, double b)
   : RandomVariable (WeibullVariableImpl (m, s, b))
-{}
+{
+}
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // NormalVariableImpl methods
 
-class NormalVariableImpl : public RandomVariableBase { // Normally Distributed random var
+class NormalVariableImpl : public RandomVariableBase   // Normally Distributed random var
 
+{
 public:
-   static const double INFINITE_VALUE;
+  static const double INFINITE_VALUE;
   /**
    * Constructs an normal random variable  with a mean
    * value of 0 and variance of 1.
-   */ 
-  NormalVariableImpl();
+   */
+  NormalVariableImpl ();
 
   /**
    * \brief Construct a normal random variable with specified mean and variance
    * \param m Mean value
    * \param v Variance
    * \param b Bound.  The NormalVariableImpl is bounded within +-bound of the mean.
-   */ 
-  NormalVariableImpl(double m, double v, double b = INFINITE_VALUE);
+   */
+  NormalVariableImpl (double m, double v, double b = INFINITE_VALUE);
 
-  NormalVariableImpl(const NormalVariableImpl& c);
-  
+  NormalVariableImpl (const NormalVariableImpl& c);
+
   /**
    * \return A value from this normal distribution
    */
-  virtual double GetValue();
-  virtual RandomVariableBase* Copy(void) const;
+  virtual double GetValue ();
+  virtual RandomVariableBase* Copy (void) const;
 
   double GetMean (void) const;
   double GetVariance (void) const;
@@ -783,62 +909,77 @@
 
 const double NormalVariableImpl::INFINITE_VALUE = 1e307;
 
-NormalVariableImpl::NormalVariableImpl() 
-  : m_mean(0.0), m_variance(1.0), m_bound(INFINITE_VALUE), m_nextValid(false){}
-
-NormalVariableImpl::NormalVariableImpl(double m, double v, double b)
-  : m_mean(m), m_variance(v), m_bound(b), m_nextValid(false) { }
+NormalVariableImpl::NormalVariableImpl ()
+  : m_mean (0.0),
+    m_variance (1.0),
+    m_bound (INFINITE_VALUE),
+    m_nextValid (false)
+{
+}
 
-NormalVariableImpl::NormalVariableImpl(const NormalVariableImpl& c)
-  : RandomVariableBase(c), m_mean(c.m_mean), m_variance(c.m_variance),
-    m_bound(c.m_bound), m_nextValid(false) { }
+NormalVariableImpl::NormalVariableImpl (double m, double v, double b)
+  : m_mean (m),
+    m_variance (v),
+    m_bound (b),
+    m_nextValid (false)
+{
+}
 
-double NormalVariableImpl::GetValue()
+NormalVariableImpl::NormalVariableImpl (const NormalVariableImpl& c)
+  : RandomVariableBase (c),
+    m_mean (c.m_mean),
+    m_variance (c.m_variance),
+    m_bound (c.m_bound),
+    m_nextValid (false)
 {
-  if(!m_generator)
+}
+
+double NormalVariableImpl::GetValue ()
+{
+  if (!m_generator)
     {
-      m_generator = new RngStream();
+      m_generator = new RngStream ();
     }
   if (m_nextValid)
     { // use previously generated
       m_nextValid = false;
       return m_next;
     }
-  while(1)
+  while (1)
     { // See Simulation Modeling and Analysis p. 466 (Averill Law)
       // for algorithm; basically a Box-Muller transform:
       // http://en.wikipedia.org/wiki/Box-Muller_transform
-      double u1 = m_generator->RandU01();
-      double u2 = m_generator->RandU01();;
+      double u1 = m_generator->RandU01 ();
+      double u2 = m_generator->RandU01 ();
       double v1 = 2 * u1 - 1;
       double v2 = 2 * u2 - 1;
       double w = v1 * v1 + v2 * v2;
       if (w <= 1.0)
         { // Got good pair
-          double y = sqrt((-2 * log(w))/w);
-          m_next = m_mean + v2 * y * sqrt(m_variance);
-          //if next is in bounds, it is valid
-          m_nextValid = fabs(m_next-m_mean) <= m_bound;
-          double x1 = m_mean + v1 * y * sqrt(m_variance);
-          //if x1 is in bounds, return it
-          if (fabs(x1-m_mean) <= m_bound)
+          double y = sqrt ((-2 * log (w)) / w);
+          m_next = m_mean + v2 * y * sqrt (m_variance);
+          // if next is in bounds, it is valid
+          m_nextValid = fabs (m_next - m_mean) <= m_bound;
+          double x1 = m_mean + v1 * y * sqrt (m_variance);
+          // if x1 is in bounds, return it
+          if (fabs (x1 - m_mean) <= m_bound)
             {
               return x1;
             }
-          //otherwise try and return m_next if it is valid
+          // otherwise try and return m_next if it is valid
           else if (m_nextValid)
-	    {
-	      m_nextValid = false;
-	      return m_next;
-	    }
-          //otherwise, just run this loop again
+            {
+              m_nextValid = false;
+              return m_next;
+            }
+          // otherwise, just run this loop again
         }
     }
 }
 
-RandomVariableBase* NormalVariableImpl::Copy() const
+RandomVariableBase* NormalVariableImpl::Copy () const
 {
-  return new NormalVariableImpl(*this);
+  return new NormalVariableImpl (*this);
 }
 
 double
@@ -859,109 +1000,131 @@
   return m_bound;
 }
 
-NormalVariable::NormalVariable()
+NormalVariable::NormalVariable ()
   : RandomVariable (NormalVariableImpl ())
-{}
-NormalVariable::NormalVariable(double m, double v)
+{
+}
+NormalVariable::NormalVariable (double m, double v)
   : RandomVariable (NormalVariableImpl (m, v))
-{}
-NormalVariable::NormalVariable(double m, double v, double b)
+{
+}
+NormalVariable::NormalVariable (double m, double v, double b)
   : RandomVariable (NormalVariableImpl (m, v, b))
-{}
+{
+}
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-class EmpiricalVariableImpl : public RandomVariableBase {
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+class EmpiricalVariableImpl : public RandomVariableBase
+{
 public:
   /**
    * Constructor for the EmpiricalVariableImpl random variables.
    */
-  explicit EmpiricalVariableImpl();
+  explicit EmpiricalVariableImpl ();
 
-  virtual ~EmpiricalVariableImpl();
-  EmpiricalVariableImpl(const EmpiricalVariableImpl& c);
+  virtual ~EmpiricalVariableImpl ();
+  EmpiricalVariableImpl (const EmpiricalVariableImpl& c);
   /**
    * \return A value from this empirical distribution
    */
-  virtual double GetValue();
-  virtual RandomVariableBase* Copy(void) const;
+  virtual double GetValue ();
+  virtual RandomVariableBase* Copy (void) const;
   /**
    * \brief Specifies a point in the empirical distribution
    * \param v The function value for this point
    * \param c Probability that the function is less than or equal to v
    */
-  virtual void CDF(double v, double c);  // Value, prob <= Value
+  virtual void CDF (double v, double c);  // Value, prob <= Value
 
 private:
-  class ValueCDF {
-  public:
-    ValueCDF();
-    ValueCDF(double v, double c);
-    ValueCDF(const ValueCDF& c);
+  class ValueCDF
+  {
+public:
+    ValueCDF ();
+    ValueCDF (double v, double c);
+    ValueCDF (const ValueCDF& c);
     double value;
     double    cdf;
   };
-  virtual void Validate();  // Insure non-decreasing emiprical values
-  virtual double Interpolate(double, double, double, double, double);
+  virtual void Validate ();  // Insure non-decreasing emiprical values
+  virtual double Interpolate (double, double, double, double, double);
   bool validated; // True if non-decreasing validated
   std::vector<ValueCDF> emp;       // Empicical CDF
 };
 
 
 // ValueCDF methods
-EmpiricalVariableImpl::ValueCDF::ValueCDF() 
-  : value(0.0), cdf(0.0){ }
-EmpiricalVariableImpl::ValueCDF::ValueCDF(double v, double c) 
-  : value(v), cdf(c) { }
-EmpiricalVariableImpl::ValueCDF::ValueCDF(const ValueCDF& c) 
-  : value(c.value), cdf(c.cdf) { }
+EmpiricalVariableImpl::ValueCDF::ValueCDF ()
+  : value (0.0),
+    cdf (0.0)
+{
+}
+EmpiricalVariableImpl::ValueCDF::ValueCDF (double v, double c)
+  : value (v),
+    cdf (c)
+{
+}
+EmpiricalVariableImpl::ValueCDF::ValueCDF (const ValueCDF& c)
+  : value (c.value),
+    cdf (c.cdf)
+{
+}
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // EmpiricalVariableImpl methods
-EmpiricalVariableImpl::EmpiricalVariableImpl() 
-  : validated(false) { }
+EmpiricalVariableImpl::EmpiricalVariableImpl ()
+  : validated (false)
+{
+}
 
-EmpiricalVariableImpl::EmpiricalVariableImpl(const EmpiricalVariableImpl& c)
-  : RandomVariableBase(c), validated(c.validated), emp(c.emp) { }
+EmpiricalVariableImpl::EmpiricalVariableImpl (const EmpiricalVariableImpl& c)
+  : RandomVariableBase (c),
+    validated (c.validated),
+    emp (c.emp)
+{
+}
 
-EmpiricalVariableImpl::~EmpiricalVariableImpl() { }
+EmpiricalVariableImpl::~EmpiricalVariableImpl ()
+{
+}
 
-double EmpiricalVariableImpl::GetValue()
+double EmpiricalVariableImpl::GetValue ()
 { // Return a value from the empirical distribution
   // This code based (loosely) on code by Bruce Mah (Thanks Bruce!)
-  if(!m_generator)
+  if (!m_generator)
     {
-      m_generator = new RngStream();
+      m_generator = new RngStream ();
     }
-  if (emp.size() == 0) 
+  if (emp.size () == 0)
     {
       return 0.0; // HuH? No empirical data
     }
-  if (!validated) 
+  if (!validated)
     {
-      Validate();      // Insure in non-decreasing
+      Validate ();      // Insure in non-decreasing
     }
-  double r = m_generator->RandU01();
-  if (r <= emp.front().cdf)
+  double r = m_generator->RandU01 ();
+  if (r <= emp.front ().cdf)
     {
-      return emp.front().value; // Less than first
+      return emp.front ().value; // Less than first
     }
-  if (r >= emp.back().cdf) 
-    { 
-      return emp.back().value;  // Greater than last
+  if (r >= emp.back ().cdf)
+    {
+      return emp.back ().value;  // Greater than last
     }
   // Binary search
   std::vector<ValueCDF>::size_type bottom = 0;
-  std::vector<ValueCDF>::size_type top = emp.size() - 1;
-  while(1)
+  std::vector<ValueCDF>::size_type top = emp.size () - 1;
+  while (1)
     {
       std::vector<ValueCDF>::size_type c = (top + bottom) / 2;
-      if (r >= emp[c].cdf && r < emp[c+1].cdf)
+      if (r >= emp[c].cdf && r < emp[c + 1].cdf)
         { // Found it
-          return Interpolate(emp[c].cdf, emp[c+1].cdf,
-                             emp[c].value, emp[c+1].value,
-                             r);
+          return Interpolate (emp[c].cdf, emp[c + 1].cdf,
+                              emp[c].value, emp[c + 1].value,
+                              r);
         }
       // Not here, adjust bounds
       if (r < emp[c].cdf)
@@ -975,21 +1138,21 @@
     }
 }
 
-RandomVariableBase* EmpiricalVariableImpl::Copy() const
+RandomVariableBase* EmpiricalVariableImpl::Copy () const
 {
-  return new EmpiricalVariableImpl(*this);
+  return new EmpiricalVariableImpl (*this);
 }
 
-void EmpiricalVariableImpl::CDF(double v, double c)
+void EmpiricalVariableImpl::CDF (double v, double c)
 { // Add a new empirical datapoint to the empirical cdf
   // NOTE.   These MUST be inserted in non-decreasing order
-  emp.push_back(ValueCDF(v, c));
+  emp.push_back (ValueCDF (v, c));
 }
 
-void EmpiricalVariableImpl::Validate()
+void EmpiricalVariableImpl::Validate ()
 {
   ValueCDF prior;
-  for (std::vector<ValueCDF>::size_type i = 0; i < emp.size(); ++i)
+  for (std::vector<ValueCDF>::size_type i = 0; i < emp.size (); ++i)
     {
       ValueCDF& current = emp[i];
       if (current.value < prior.value || current.cdf < prior.cdf)
@@ -999,27 +1162,29 @@
                << " prior value "   << prior.value
                << " current cdf "   << current.cdf
                << " prior cdf "     << prior.cdf << endl;
-          NS_FATAL_ERROR("Empirical Dist error");
+          NS_FATAL_ERROR ("Empirical Dist error");
         }
       prior = current;
     }
   validated = true;
 }
 
-double EmpiricalVariableImpl::Interpolate(double c1, double c2,
-                                double v1, double v2, double r)
+double EmpiricalVariableImpl::Interpolate (double c1, double c2,
+                                           double v1, double v2, double r)
 { // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
   return (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
 }
 
-EmpiricalVariable::EmpiricalVariable()
+EmpiricalVariable::EmpiricalVariable ()
   : RandomVariable (EmpiricalVariableImpl ())
-{}
+{
+}
 EmpiricalVariable::EmpiricalVariable (const RandomVariableBase &variable)
   : RandomVariable (variable)
-{}
-void 
-EmpiricalVariable::CDF(double v, double c)
+{
+}
+void
+EmpiricalVariable::CDF (double v, double c)
 {
   EmpiricalVariableImpl *impl = dynamic_cast<EmpiricalVariableImpl *> (Peek ());
   NS_ASSERT (impl);
@@ -1027,50 +1192,53 @@
 }
 
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // IntegerValue EmpiricalVariableImpl methods
-class IntEmpiricalVariableImpl : public EmpiricalVariableImpl {
+class IntEmpiricalVariableImpl : public EmpiricalVariableImpl
+{
 public:
+  IntEmpiricalVariableImpl ();
 
-  IntEmpiricalVariableImpl();
-  
-  virtual RandomVariableBase* Copy(void) const;
+  virtual RandomVariableBase* Copy (void) const;
   /**
    * \return An integer value from this empirical distribution
    */
-  virtual uint32_t GetInteger();
+  virtual uint32_t GetInteger ();
 private:
-  virtual double Interpolate(double, double, double, double, double);
+  virtual double Interpolate (double, double, double, double, double);
 };
 
 
-IntEmpiricalVariableImpl::IntEmpiricalVariableImpl() { }
-
-uint32_t IntEmpiricalVariableImpl::GetInteger()
+IntEmpiricalVariableImpl::IntEmpiricalVariableImpl ()
 {
-  return (uint32_t)GetValue();
 }
 
-RandomVariableBase* IntEmpiricalVariableImpl::Copy() const
+uint32_t IntEmpiricalVariableImpl::GetInteger ()
 {
-  return new IntEmpiricalVariableImpl(*this);
+  return (uint32_t)GetValue ();
+}
+
+RandomVariableBase* IntEmpiricalVariableImpl::Copy () const
+{
+  return new IntEmpiricalVariableImpl (*this);
 }
 
-double IntEmpiricalVariableImpl::Interpolate(double c1, double c2,
-                                   double v1, double v2, double r)
+double IntEmpiricalVariableImpl::Interpolate (double c1, double c2,
+                                              double v1, double v2, double r)
 { // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
-  return ceil(v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
+  return ceil (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
 }
 
-IntEmpiricalVariable::IntEmpiricalVariable()
+IntEmpiricalVariable::IntEmpiricalVariable ()
   : EmpiricalVariable (IntEmpiricalVariableImpl ())
-{}
+{
+}
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // DeterministicVariableImpl
-class DeterministicVariableImpl : public RandomVariableBase 
+class DeterministicVariableImpl : public RandomVariableBase
 {
 
 public:
@@ -1079,55 +1247,61 @@
    *
    * Creates a generator that returns successive elements of the d array
    * on successive calls to ::Value().  Note that the d pointer is copied
-   * for use by the generator (shallow-copy), not its contents, so the 
-   * contents of the array d points to have to remain unchanged for the use 
+   * for use by the generator (shallow-copy), not its contents, so the
+   * contents of the array d points to have to remain unchanged for the use
    * of DeterministicVariableImpl to be meaningful.
    * \param d Pointer to array of random values to return in sequence
    * \param c Number of values in the array
    */
-  explicit DeterministicVariableImpl(double* d, uint32_t c);
+  explicit DeterministicVariableImpl (double* d, uint32_t c);
 
-  virtual ~DeterministicVariableImpl();
+  virtual ~DeterministicVariableImpl ();
   /**
    * \return The next value in the deterministic sequence
    */
-  virtual double GetValue();
-  virtual RandomVariableBase* Copy(void) const;
+  virtual double GetValue ();
+  virtual RandomVariableBase* Copy (void) const;
 private:
   uint32_t   count;
   uint32_t   next;
   double* data;
 };
 
-DeterministicVariableImpl::DeterministicVariableImpl(double* d, uint32_t c)
-    : count(c), next(c), data(d)
+DeterministicVariableImpl::DeterministicVariableImpl (double* d, uint32_t c)
+  : count (c),
+    next (c),
+    data (d)
 { // Nothing else needed
 }
 
-DeterministicVariableImpl::~DeterministicVariableImpl() { }
-  
-double DeterministicVariableImpl::GetValue()
+DeterministicVariableImpl::~DeterministicVariableImpl ()
 {
-  if (next == count) 
+}
+
+double DeterministicVariableImpl::GetValue ()
+{
+  if (next == count)
     {
       next = 0;
     }
   return data[next++];
 }
 
-RandomVariableBase* DeterministicVariableImpl::Copy() const
+RandomVariableBase* DeterministicVariableImpl::Copy () const
 {
-  return new DeterministicVariableImpl(*this);
+  return new DeterministicVariableImpl (*this);
 }
 
-DeterministicVariable::DeterministicVariable(double* d, uint32_t c)
+DeterministicVariable::DeterministicVariable (double* d, uint32_t c)
   : RandomVariable (DeterministicVariableImpl (d, c))
-{}
+{
+}
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // LogNormalVariableImpl
-class LogNormalVariableImpl : public RandomVariableBase { 
+class LogNormalVariableImpl : public RandomVariableBase
+{
 public:
   /**
    * \param mu mu parameter of the lognormal distribution
@@ -1139,7 +1313,7 @@
    * \return A random value from this distribution
    */
   virtual double GetValue ();
-  virtual RandomVariableBase* Copy(void) const;
+  virtual RandomVariableBase* Copy (void) const;
 
 private:
   double m_mu;
@@ -1153,31 +1327,32 @@
 }
 
 LogNormalVariableImpl::LogNormalVariableImpl (double mu, double sigma)
-    :m_mu(mu), m_sigma(sigma) 
+  : m_mu (mu),
+    m_sigma (sigma)
 {
 }
 
 // The code from this function was adapted from the GNU Scientific
 // Library 1.8:
 /* randist/lognormal.c
- * 
+ *
  * Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or (at
  * your option) any later version.
- * 
+ *
  * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
-/* The lognormal distribution has the form 
+/* The lognormal distribution has the form
 
    p(x) dx = 1/(x * sqrt(2 pi sigma^2)) exp(-(ln(x) - zeta)^2/2 sigma^2) dx
 
@@ -1186,9 +1361,9 @@
 double
 LogNormalVariableImpl::GetValue ()
 {
-  if(!m_generator)
+  if (!m_generator)
     {
-      m_generator = new RngStream();
+      m_generator = new RngStream ();
     }
   double u, v, r2, normal, z;
 
@@ -1213,10 +1388,11 @@
 
 LogNormalVariable::LogNormalVariable (double mu, double sigma)
   : RandomVariable (LogNormalVariableImpl (mu, sigma))
-{}
+{
+}
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // GammaVariableImpl
 class GammaVariableImpl : public RandomVariableBase
 {
@@ -1236,9 +1412,9 @@
    * \return A random value from the gamma distribution with parameters alpha
    * and beta
    */
-  double GetValue(double alpha, double beta);
+  double GetValue (double alpha, double beta);
 
-  virtual RandomVariableBase* Copy(void) const;
+  virtual RandomVariableBase* Copy (void) const;
 
 private:
   double m_alpha;
@@ -1253,14 +1429,15 @@
 }
 
 GammaVariableImpl::GammaVariableImpl (double alpha, double beta)
-  : m_alpha(alpha), m_beta(beta) 
+  : m_alpha (alpha),
+    m_beta (beta)
 {
 }
 
 double
 GammaVariableImpl::GetValue ()
 {
-  return GetValue(m_alpha, m_beta);
+  return GetValue (m_alpha, m_beta);
 }
 
 /*
@@ -1271,10 +1448,10 @@
   G. Marsaglia, W. W. Tsang: A simple method for gereating Gamma variables
   ACM Transactions on mathematical software, Vol. 26, No. 3, Sept. 2000
 
-  The Gamma distribution density function has the form 
+  The Gamma distribution density function has the form
 
-	                     x^(alpha-1) * exp(-x/beta)
-	p(x; alpha, beta) = ----------------------------
+                             x^(alpha-1) * exp(-x/beta)
+        p(x; alpha, beta) = ----------------------------
                              beta^alpha * Gamma(alpha)
 
   for x > 0.
@@ -1282,17 +1459,17 @@
 double
 GammaVariableImpl::GetValue (double alpha, double beta)
 {
-  if(!m_generator)
+  if (!m_generator)
     {
-      m_generator = new RngStream();
+      m_generator = new RngStream ();
     }
 
   if (alpha < 1)
     {
       double u = m_generator->RandU01 ();
-      return GetValue(1.0 + alpha, beta) * pow (u, 1.0 / alpha);
+      return GetValue (1.0 + alpha, beta) * pow (u, 1.0 / alpha);
     }
-	
+
   double x, v, u;
   double d = alpha - 1.0 / 3.0;
   double c = (1.0 / 3.0) / sqrt (d);
@@ -1303,7 +1480,8 @@
         {
           x = m_normal.GetValue ();
           v = 1.0 + c * x;
-        } while (v <= 0);
+        }
+      while (v <= 0);
 
       v = v * v * v;
       u = m_generator->RandU01 ();
@@ -1330,18 +1508,18 @@
 {
 }
 
-double GammaVariable::GetValue(void) const
+double GammaVariable::GetValue (void) const
 {
   return this->RandomVariable::GetValue ();
 }
 
-double GammaVariable::GetValue(double alpha, double beta) const
+double GammaVariable::GetValue (double alpha, double beta) const
 {
-  return ((GammaVariableImpl*)Peek())->GetValue(alpha, beta);
+  return ((GammaVariableImpl*)Peek ())->GetValue (alpha, beta);
 }
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // ErlangVariableImpl
 
 class ErlangVariableImpl : public RandomVariableBase
@@ -1362,9 +1540,9 @@
    * \return A random value from the Erlang distribution with parameters k and
    * lambda.
    */
-  double GetValue(unsigned int k, double lambda);
+  double GetValue (unsigned int k, double lambda);
 
-  virtual RandomVariableBase* Copy(void) const;
+  virtual RandomVariableBase* Copy (void) const;
 
 private:
   unsigned int m_k;
@@ -1378,24 +1556,25 @@
 }
 
 ErlangVariableImpl::ErlangVariableImpl (unsigned int k, double lambda)
-  : m_k(k), m_lambda(lambda)
+  : m_k (k),
+    m_lambda (lambda)
 {
 }
 
 double
 ErlangVariableImpl::GetValue ()
 {
-  return GetValue(m_k, m_lambda);
+  return GetValue (m_k, m_lambda);
 }
 
 /*
   The code for the following generator functions was adapted from ns-2
   tools/ranvar.cc
 
-  The Erlang distribution density function has the form 
+  The Erlang distribution density function has the form
 
-	                   x^(k-1) * exp(-x/lambda)
-	p(x; k, lambda) = ---------------------------
+                           x^(k-1) * exp(-x/lambda)
+        p(x; k, lambda) = ---------------------------
                              lambda^k * (k-1)!
 
   for x > 0.
@@ -1403,17 +1582,17 @@
 double
 ErlangVariableImpl::GetValue (unsigned int k, double lambda)
 {
-  if(!m_generator)
+  if (!m_generator)
     {
-      m_generator = new RngStream();
+      m_generator = new RngStream ();
     }
 
-  ExponentialVariable exponential(lambda);
+  ExponentialVariable exponential (lambda);
 
   double result = 0;
   for (unsigned int i = 0; i < k; ++i)
     {
-      result += exponential.GetValue();
+      result += exponential.GetValue ();
     }
 
   return result;
@@ -1429,26 +1608,27 @@
 {
 }
 
-double ErlangVariable::GetValue(void) const
+double ErlangVariable::GetValue (void) const
 {
   return this->RandomVariable::GetValue ();
 }
 
-double ErlangVariable::GetValue(unsigned int k, double lambda) const
+double ErlangVariable::GetValue (unsigned int k, double lambda) const
 {
-  return ((ErlangVariableImpl*)Peek())->GetValue(k, lambda);
+  return ((ErlangVariableImpl*)Peek ())->GetValue (k, lambda);
 }
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // TriangularVariableImpl methods
-class TriangularVariableImpl : public RandomVariableBase {
+class TriangularVariableImpl : public RandomVariableBase
+{
 public:
   /**
    * Creates a triangle distribution random number generator in the
    * range [0.0 .. 1.0), with mean of 0.5
    */
-  TriangularVariableImpl();
+  TriangularVariableImpl ();
 
   /**
    * Creates a triangle distribution random number generator with the specified
@@ -1457,65 +1637,81 @@
    * \param l High end of the range
    * \param mean mean of the distribution
    */
-  TriangularVariableImpl(double s, double l, double mean);
+  TriangularVariableImpl (double s, double l, double mean);
 
-  TriangularVariableImpl(const TriangularVariableImpl& c);
-  
+  TriangularVariableImpl (const TriangularVariableImpl& c);
+
   /**
    * \return A value from this distribution
    */
-  virtual double GetValue();
-  virtual RandomVariableBase*  Copy(void) const;
+  virtual double GetValue ();
+  virtual RandomVariableBase*  Copy (void) const;
 
 private:
   double m_min;
   double m_max;
-  double m_mode;  //easier to work with the mode internally instead of the mean
-                  //they are related by the simple: mean = (min+max+mode)/3
+  double m_mode;  // easier to work with the mode internally instead of the mean
+                  // they are related by the simple: mean = (min+max+mode)/3
 };
 
-TriangularVariableImpl::TriangularVariableImpl() 
-  : m_min(0), m_max(1), m_mode(0.5) { }
-  
-TriangularVariableImpl::TriangularVariableImpl(double s, double l, double mean) 
-  : m_min(s), m_max(l), m_mode(3.0*mean-s-l) { }
-  
-TriangularVariableImpl::TriangularVariableImpl(const TriangularVariableImpl& c) 
-  : RandomVariableBase(c), m_min(c.m_min), m_max(c.m_max), m_mode(c.m_mode) { }
+TriangularVariableImpl::TriangularVariableImpl ()
+  : m_min (0),
+    m_max (1),
+    m_mode (0.5)
+{
+}
+
+TriangularVariableImpl::TriangularVariableImpl (double s, double l, double mean)
+  : m_min (s),
+    m_max (l),
+    m_mode (3.0 * mean - s - l)
+{
+}
 
-double TriangularVariableImpl::GetValue()
+TriangularVariableImpl::TriangularVariableImpl (const TriangularVariableImpl& c)
+  : RandomVariableBase (c),
+    m_min (c.m_min),
+    m_max (c.m_max),
+    m_mode (c.m_mode)
 {
-  if(!m_generator)
+}
+
+double TriangularVariableImpl::GetValue ()
+{
+  if (!m_generator)
     {
-      m_generator = new RngStream();
+      m_generator = new RngStream ();
     }
-  double u = m_generator->RandU01();
-  if(u <= (m_mode - m_min) / (m_max - m_min) )
+  double u = m_generator->RandU01 ();
+  if (u <= (m_mode - m_min) / (m_max - m_min) )
     {
-      return m_min + sqrt(u * (m_max - m_min) * (m_mode - m_min) );
+      return m_min + sqrt (u * (m_max - m_min) * (m_mode - m_min) );
     }
   else
     {
-      return m_max - sqrt( (1-u) * (m_max - m_min) * (m_max - m_mode) );
+      return m_max - sqrt ( (1 - u) * (m_max - m_min) * (m_max - m_mode) );
     }
 }
 
-RandomVariableBase* TriangularVariableImpl::Copy() const
+RandomVariableBase* TriangularVariableImpl::Copy () const
 {
-  return new TriangularVariableImpl(*this);
+  return new TriangularVariableImpl (*this);
 }
 
-TriangularVariable::TriangularVariable()
+TriangularVariable::TriangularVariable ()
   : RandomVariable (TriangularVariableImpl ())
-{}
-TriangularVariable::TriangularVariable(double s, double l, double mean)
+{
+}
+TriangularVariable::TriangularVariable (double s, double l, double mean)
   : RandomVariable (TriangularVariableImpl (s,l,mean))
-{}
+{
+}
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
 // ZipfVariableImpl
-class ZipfVariableImpl : public RandomVariableBase { 
+class ZipfVariableImpl : public RandomVariableBase
+{
 public:
   /**
    * \param n the number of possible items
@@ -1532,12 +1728,12 @@
    * \return A random value from this distribution
    */
   virtual double GetValue ();
-  virtual RandomVariableBase* Copy(void) const;
+  virtual RandomVariableBase* Copy (void) const;
 
 private:
   long m_n;
   double m_alpha;
-  double m_c; //the normalization constant
+  double m_c; // the normalization constant
 };
 
 
@@ -1547,38 +1743,42 @@
 }
 
 ZipfVariableImpl::ZipfVariableImpl ()
-    :m_n(1), m_alpha(0), m_c(1)
+  : m_n (1),
+    m_alpha (0),
+    m_c (1)
 {
 }
 
 
 ZipfVariableImpl::ZipfVariableImpl (long n, double alpha)
-    :m_n(n), m_alpha(alpha), m_c(0)
+  : m_n (n),
+    m_alpha (alpha),
+    m_c (0)
 {
-  //calculate the normalization constant c
-  for(int i=1;i<=n;i++)
+  // calculate the normalization constant c
+  for (int i = 1; i <= n; i++)
     {
-      m_c+=(1.0/pow((double)i,alpha));
+      m_c += (1.0 / pow ((double)i,alpha));
     }
-  m_c=1.0/m_c;
+  m_c = 1.0 / m_c;
 }
 
 double
 ZipfVariableImpl::GetValue ()
 {
-  if(!m_generator)
+  if (!m_generator)
     {
-      m_generator = new RngStream();
+      m_generator = new RngStream ();
     }
 
-  double u = m_generator->RandU01();
-  double sum_prob=0,zipf_value=0;
-  for(int i=1;i<=m_n;i++)
+  double u = m_generator->RandU01 ();
+  double sum_prob = 0,zipf_value = 0;
+  for (int i = 1; i <= m_n; i++)
     {
-      sum_prob+=m_c/pow((double)i,m_alpha);
-      if(sum_prob>u)
+      sum_prob += m_c / pow ((double)i,m_alpha);
+      if (sum_prob > u)
         {
-          zipf_value=i;
+          zipf_value = i;
           break;
         }
     }
@@ -1587,14 +1787,103 @@
 
 ZipfVariable::ZipfVariable ()
   : RandomVariable (ZipfVariableImpl ())
-{}
+{
+}
 
 ZipfVariable::ZipfVariable (long n, double alpha)
   : RandomVariable (ZipfVariableImpl (n, alpha))
-{}
+{
+}
+
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// ZetaVariableImpl
+class ZetaVariableImpl : public RandomVariableBase
+{
+public:
+  /**
+   * \param alpha the alpha parameter
+   */
+  ZetaVariableImpl (double alpha);
+
+  /**
+   * \A zipf variable with alpha=1.1
+   */
+  ZetaVariableImpl ();
+
+  /**
+   * \return A random value from this distribution
+   */
+  virtual double GetValue ();
+  virtual RandomVariableBase* Copy (void) const;
+
+private:
+  double m_alpha;
+  double m_b; // just for calculus simplifications
+};
+
+
+RandomVariableBase* ZetaVariableImpl::Copy () const
+{
+  return new ZetaVariableImpl (m_alpha);
+}
+
+ZetaVariableImpl::ZetaVariableImpl ()
+  : m_alpha (3.14),
+    m_b (pow (2.0, 2.14))
+{
+}
 
 
-std::ostream &operator << (std::ostream &os, const RandomVariable &var)
+ZetaVariableImpl::ZetaVariableImpl (double alpha)
+  : m_alpha (alpha),
+    m_b (pow (2.0, alpha - 1.0))
+{
+}
+
+/*
+ The code for the following generator functions is borrowed from:
+ L. Devroye: Non-Uniform Random Variate Generation, Springer-Verlag, New York, 1986.
+ page 551
+ */
+double
+ZetaVariableImpl::GetValue ()
+{
+  if (!m_generator)
+    {
+      m_generator = new RngStream ();
+    }
+
+  double u, v;
+  double X, T;
+  double test;
+
+  do
+    {
+      u = m_generator->RandU01 ();
+      v = m_generator->RandU01 ();
+      X = floor (pow (u, -1.0 / (m_alpha - 1.0)));
+      T = pow (1.0 + 1.0 / X, m_alpha - 1.0);
+      test = v * X * (T - 1.0) / (m_b - 1.0);
+    }
+  while ( test > (T / m_b) );
+
+  return X;
+}
+
+ZetaVariable::ZetaVariable ()
+  : RandomVariable (ZetaVariableImpl ())
+{
+}
+
+ZetaVariable::ZetaVariable (double alpha)
+  : RandomVariable (ZetaVariableImpl (alpha))
+{
+}
+
+
+std::ostream & operator << (std::ostream &os, const RandomVariable &var)
 {
   RandomVariableBase *base = var.Peek ();
   ConstantVariableImpl *constant = dynamic_cast<ConstantVariableImpl *> (base);
@@ -1624,7 +1913,7 @@
   os.setstate (std::ios_base::badbit);
   return os;
 }
-std::istream &operator >> (std::istream &is, RandomVariable &var)
+std::istream & operator >> (std::istream &is, RandomVariable &var)
 {
   std::string value;
   is >> value;
@@ -1715,7 +2004,9 @@
 {
 public:
   BasicRandomNumberTestCase ();
-  virtual ~BasicRandomNumberTestCase () {}
+  virtual ~BasicRandomNumberTestCase ()
+  {
+  }
 
 private:
   virtual bool DoRun (void);
@@ -1744,7 +2035,7 @@
   vector<double> samples;
   const int NSAMPLES = 10000;
   double sum = 0;
-  
+
   //
   // Get and store a bunch of samples.  As we go along sum them and then find
   // the mean value of the samples.
@@ -1757,7 +2048,7 @@
     }
   double obtainedMean = sum / NSAMPLES;
   NS_TEST_EXPECT_MSG_EQ_TOL (obtainedMean, desiredMean, 0.1, "Got unexpected mean value from LogNormalVariable");
-  
+
   //
   // Wander back through the saved stamples and find their standard deviation
   //
@@ -1777,7 +2068,9 @@
 {
 public:
   RandomNumberSerializationTestCase ();
-  virtual ~RandomNumberSerializationTestCase () {}
+  virtual ~RandomNumberSerializationTestCase ()
+  {
+  }
 
 private:
   virtual bool DoRun (void);
@@ -1794,7 +2087,7 @@
   RandomVariableValue val;
   val.DeserializeFromString ("Uniform:0.1:0.2", MakeRandomVariableChecker ());
   RandomVariable rng = val.Get ();
-  NS_TEST_ASSERT_MSG_EQ (val.SerializeToString (MakeRandomVariableChecker ()), "Uniform:0.1:0.2", 
+  NS_TEST_ASSERT_MSG_EQ (val.SerializeToString (MakeRandomVariableChecker ()), "Uniform:0.1:0.2",
                          "Deserialize and Serialize \"Uniform:0.1:0.2\" mismatch");
 
   val.DeserializeFromString ("Normal:0.1:0.2", MakeRandomVariableChecker ());
@@ -1825,4 +2118,4 @@
 
 BasicRandomNumberTestSuite BasicRandomNumberTestSuite;
 
-}//namespace ns3
+} // namespace ns3
--- a/src/core/random-variable.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/core/random-variable.h	Thu Feb 25 14:17:21 2010 +0100
@@ -43,7 +43,6 @@
 class SeedManager
 {
 public:
-	  
   /**
    * \brief set the seed
    * it will duplicate the seed value 6 times
@@ -57,45 +56,45 @@
    * Note, while the underlying RNG takes six integer values as a seed;
    * it is sufficient to set these all to the same integer, so we provide
    * a simpler interface here that just takes one integer.
-   */ 
+   */
   static void SetSeed (uint32_t seed);
- 
+
   /**
    * \brief Get the seed value
    * \return the seed value
    *
    * Note:  returns the first of the six seed values used in the underlying RNG
    */
-   static uint32_t GetSeed ();
- 
-   /**
-    * \brief Set the run number of simulation
-    *
-    * \code
-    * SeedManager::SetSeed(12);
-    * int N = atol(argv[1]); //read in run number from command line
-    * SeedManager::SetRun(N);
-    * UniformVariable x(0,10);
-    * ExponentialVariable y(2902);
-    * \endcode
-    * In this example, N could successivly be equal to 1,2,3, etc. and the user
-    * would continue to get independent runs out of the single simulation.  For
-    * this simple example, the following might work:
-    * \code
-    * ./simulation 0
-    * ...Results for run 0:...
-    *
-    * ./simulation 1
-    * ...Results for run 1:...
-    * \endcode
-    */
+  static uint32_t GetSeed ();
+
+  /**
+   * \brief Set the run number of simulation
+   *
+   * \code
+   * SeedManager::SetSeed(12);
+   * int N = atol(argv[1]); //read in run number from command line
+   * SeedManager::SetRun(N);
+   * UniformVariable x(0,10);
+   * ExponentialVariable y(2902);
+   * \endcode
+   * In this example, N could successivly be equal to 1,2,3, etc. and the user
+   * would continue to get independent runs out of the single simulation.  For
+   * this simple example, the following might work:
+   * \code
+   * ./simulation 0
+   * ...Results for run 0:...
+   *
+   * ./simulation 1
+   * ...Results for run 1:...
+   * \endcode
+   */
   static void SetRun (uint32_t run);
   /**
    * \returns the current run number
    * @sa SetRun
    */
   static uint32_t GetRun (void);
-  
+
   /**
    * \brief Check if seed value is valid if wanted to be used as seed
    * \return true if valid and false if invalid
@@ -111,7 +110,7 @@
  * Note: The underlying random number generation method used
  * by NS-3 is the RngStream code by Pierre L'Ecuyer at
  * the University of Montreal.
- * 
+ *
  * NS-3 has a rich set of  random number generators.
  * Class RandomVariable defines the base class functionalty
  * required for all random number generators.  By default, the underlying
@@ -119,13 +118,13 @@
  * coming from the ns3::GlobalValue \ref GlobalValueRngSeed "RngSeed" and \ref GlobalValueRngRun "RngRun".
  */
 class RandomVariable
-{ 
+{
 public:
-  RandomVariable();
-  RandomVariable(const RandomVariable&o);
+  RandomVariable ();
+  RandomVariable (const RandomVariable&o);
   RandomVariable &operator = (const RandomVariable &o);
-  ~RandomVariable();
-  
+  ~RandomVariable ();
+
   /**
    * \brief Returns a random double from the underlying distribution
    * \return A floating point random value
@@ -139,13 +138,13 @@
   uint32_t GetInteger (void) const;
 
 private:
-  friend std::ostream &operator << (std::ostream &os, const RandomVariable &var);
-  friend std::istream &operator >> (std::istream &os, RandomVariable &var);
+  friend std::ostream & operator << (std::ostream &os, const RandomVariable &var);
+  friend std::istream & operator >> (std::istream &os, RandomVariable &var);
 
   RandomVariableBase *m_variable;
 protected:
   RandomVariable (const RandomVariableBase &variable);
-  RandomVariableBase *Peek (void) const;
+  RandomVariableBase * Peek (void) const;
 };
 
 /**
@@ -153,7 +152,7 @@
  * \ingroup randomvariable
  *
  * This class supports the creation of objects that return random numbers
- * from a fixed uniform distribution.  It also supports the generation of 
+ * from a fixed uniform distribution.  It also supports the generation of
  * single random numbers from various uniform distributions.
  *
  * The low end of the range is always included and the high end
@@ -164,40 +163,40 @@
  * UniformVariable::GetSingleValue(100,1000); //returns a value [100,1000)
  * \endcode
  */
-class UniformVariable : public RandomVariable 
+class UniformVariable : public RandomVariable
 {
 public:
   /**
    * Creates a uniform random number generator in the
    * range [0.0 .. 1.0).
    */
-  UniformVariable();
+  UniformVariable ();
 
   /**
    * Creates a uniform random number generator with the specified range
    * \param s Low end of the range
    * \param l High end of the range
    */
-  UniformVariable(double s, double l);
+  UniformVariable (double s, double l);
 
   /**
   * \brief call RandomVariable::GetValue
   * \return A floating point random value
   *
-  * Note: we have to re-implement this method here because the method is 
+  * Note: we have to re-implement this method here because the method is
   * overloaded below for the two-argument variant and the c++ name resolution
-  * rules don't work well with overloads split between parent and child 
+  * rules don't work well with overloads split between parent and child
   * classes.
   */
   double GetValue (void) const;
-  
+
   /**
   * \brief Returns a random double with the specified range
   * \param s Low end of the range
   * \param l High end of the range
   * \return A floating point random value
   */
-  double GetValue(double s, double l);
+  double GetValue (double s, double l);
 
   /**
    * \brief Returns a random unsigned integer from the interval [s,l] including both ends.
@@ -215,26 +214,27 @@
  * Class ConstantVariable defines a random number generator that
  * returns the same value every sample.
  */
-class ConstantVariable : public RandomVariable { 
+class ConstantVariable : public RandomVariable
+{
 
 public:
   /**
    * Construct a ConstantVariable RNG that returns zero every sample
    */
-  ConstantVariable();
-  
+  ConstantVariable ();
+
   /**
    * Construct a ConstantVariable RNG that returns the specified value
    * every sample.
    * \param c Unchanging value for this RNG.
    */
-  ConstantVariable(double c);
+  ConstantVariable (double c);
 
   /**
    * \brief Specify a new constant RNG for this generator.
    * \param c New constant value for this RNG.
    */
-  void SetConstant(double c);
+  void SetConstant (double c);
 
 };
 
@@ -244,10 +244,10 @@
  *
  * Class SequentialVariable defines a random number generator that
  * returns a sequential sequence.  The sequence monotonically
- * increases for a period, then wraps around to the low value 
+ * increases for a period, then wraps around to the low value
  * and begins monotonicaly increasing again.
  */
-class SequentialVariable : public RandomVariable 
+class SequentialVariable : public RandomVariable
 {
 public:
   /**
@@ -261,7 +261,7 @@
    * \param i Increment between sequence values
    * \param c Number of times each member of the sequence is repeated
    */
-  SequentialVariable(double f, double l, double i = 1, uint32_t c = 1);
+  SequentialVariable (double f, double l, double i = 1, uint32_t c = 1);
 
   /**
    * \brief Constructor for the SequentialVariable RNG.
@@ -273,7 +273,7 @@
    * \param i Reference to a RandomVariable for the sequence increment
    * \param c Number of times each member of the sequence is repeated
    */
-  SequentialVariable(double f, double l, const RandomVariable& i, uint32_t c = 1);
+  SequentialVariable (double f, double l, const RandomVariable& i, uint32_t c = 1);
 
 };
 
@@ -282,17 +282,18 @@
  * \ingroup randomvariable
  *
  * This class supports the creation of objects that return random numbers
- * from a fixed exponential distribution.  It also supports the generation of 
+ * from a fixed exponential distribution.  It also supports the generation of
  * single random numbers from various exponential distributions.
  *
- * The probability density function of an exponential variable 
+ * The probability density function of an exponential variable
  * is defined over the interval [0, +inf) as:
  * \f$ \alpha  e^{-\alpha x} \f$
- * where \f$ \alpha = \frac{1}{mean} \f$ 
+ * where \f$ \alpha = \frac{1}{mean} \f$
  *
- * The bounded version is defined over the internal [0,+inf) as:
- * \f$ \left\{ \begin{array}{cl} \alpha  e^{-\alpha x} & x < bound \\ bound & x > bound \end{array}\right. \f$
- * 
+ * The bounded version is defined over the interval [0,b] as:
+ * \f$ \alpha  e^{-\alpha x} \quad x \in [0,b] \f$.
+ * Note that in this case the true mean is \f$ 1/\alpha - b/(e^{\alpha \, b}-1) \f$
+ *
  * \code
  * ExponentialVariable x(3.14);
  * x.GetValue();  //will always return with mean 3.14
@@ -301,33 +302,33 @@
  * \endcode
  *
  */
-class ExponentialVariable : public RandomVariable 
-{ 
+class ExponentialVariable : public RandomVariable
+{
 public:
   /**
    * Constructs an exponential random variable  with a mean
    * value of 1.0.
    */
-  ExponentialVariable();
+  ExponentialVariable ();
 
   /**
    * \brief Constructs an exponential random variable with a specified mean
    * \param m Mean value for the random variable
    */
-  explicit ExponentialVariable(double m);
+  explicit ExponentialVariable (double m);
 
   /**
-   * \brief Constructs an exponential random variable with spefified
-   * \brief mean and upper limit.
+   * \brief Constructs an exponential random variable with specified
+   * mean and upper limit.
    *
    * Since exponential distributions can theoretically return unbounded values,
    * it is sometimes useful to specify a fixed upper limit.  Note however when
-   * the upper limit is specified, the true mean of the distribution is 
-   * slightly smaller than the mean value specified.
+   * the upper limit is specified, the true mean of the distribution is
+   * slightly smaller than the mean value specified: \f$ m - b/(e^{b/m}-1) \f$.
    * \param m Mean value of the random variable
    * \param b Upper bound on returned values
    */
-  ExponentialVariable(double m, double b);
+  ExponentialVariable (double m, double b);
 
 };
 
@@ -336,13 +337,13 @@
  * \ingroup randomvariable
  *
  * This class supports the creation of objects that return random numbers
- * from a fixed pareto distribution.  It also supports the generation of 
+ * from a fixed pareto distribution.  It also supports the generation of
  * single random numbers from various pareto distributions.
  *
  * The probability density function is defined over the range [\f$x_m\f$,+inf) as:
- * \f$ k \frac{x_m^k}{x^{k+1}}\f$ where \f$x_m > 0\f$ is called the location 
+ * \f$ k \frac{x_m^k}{x^{k+1}}\f$ where \f$x_m > 0\f$ is called the location
  * parameter and \f$ k > 0\f$ is called the pareto index or shape.
- * 
+ *
  * The parameter \f$ x_m \f$ can be infered from the mean and the parameter \f$ k \f$
  * with the equation \f$ x_m = mean \frac{k-1}{k},  k > 1\f$.
  *
@@ -367,7 +368,7 @@
    * parameter of 1.5
    * \param m Mean value of the distribution
    */
-  explicit ParetoVariable(double m);
+  explicit ParetoVariable (double m);
 
   /**
    * Constructs a pareto random variable with the specified mean value and
@@ -375,7 +376,7 @@
    * \param m Mean value of the distribution
    * \param s Shape parameter for the distribution
    */
-  ParetoVariable(double m, double s);
+  ParetoVariable (double m, double s);
 
   /**
    * \brief Constructs a pareto random variable with the specified mean
@@ -389,7 +390,7 @@
    * \param s Shape parameter
    * \param b Upper limit on returned values
    */
-  ParetoVariable(double m, double s, double b);
+  ParetoVariable (double m, double s, double b);
 
 };
 
@@ -398,7 +399,7 @@
  * \ingroup randomvariable
  *
  * This class supports the creation of objects that return random numbers
- * from a fixed weibull distribution.  It also supports the generation of 
+ * from a fixed weibull distribution.  It also supports the generation of
  * single random numbers from various weibull distributions.
  *
  * The probability density function is defined over the interval [0, +inf]
@@ -407,13 +408,14 @@
  * specified mean is related to the scale and shape parameters by the following relation:
  * \f$ mean = \lambda\Gamma\left(1+\frac{1}{k}\right) \f$ where \f$ \Gamma \f$ is the Gamma function.
  */
-class WeibullVariable : public RandomVariable {
+class WeibullVariable : public RandomVariable
+{
 public:
   /**
    * Constructs a weibull random variable  with a mean
    * value of 1.0 and a shape (alpha) parameter of 1
    */
-  WeibullVariable();
+  WeibullVariable ();
 
 
   /**
@@ -421,7 +423,7 @@
    * value and a shape (alpha) parameter of 1.5.
    * \param m mean value of the distribution
    */
-  WeibullVariable(double m) ;
+  WeibullVariable (double m);
 
   /**
    * Constructs a weibull random variable with the specified mean
@@ -429,20 +431,20 @@
    * \param m Mean value for the distribution.
    * \param s Shape (alpha) parameter for the distribution.
    */
-  WeibullVariable(double m, double s);
+  WeibullVariable (double m, double s);
 
-   /**
-   * \brief Constructs a weibull random variable with the specified mean
-   * \brief value, shape (alpha), and upper bound.
-   * Since WeibullVariable distributions can theoretically return unbounded values,
-   * it is sometimes usefull to specify a fixed upper limit.  Note however
-   * that when the upper limit is specified, the true mean of the distribution
-   * is slightly smaller than the mean value specified.
-   * \param m Mean value for the distribution.
-   * \param s Shape (alpha) parameter for the distribution.
-   * \param b Upper limit on returned values
-   */
-  WeibullVariable(double m, double s, double b);
+  /**
+  * \brief Constructs a weibull random variable with the specified mean
+  * \brief value, shape (alpha), and upper bound.
+  * Since WeibullVariable distributions can theoretically return unbounded values,
+  * it is sometimes usefull to specify a fixed upper limit.  Note however
+  * that when the upper limit is specified, the true mean of the distribution
+  * is slightly smaller than the mean value specified.
+  * \param m Mean value for the distribution.
+  * \param s Shape (alpha) parameter for the distribution.
+  * \param b Upper limit on returned values
+  */
+  WeibullVariable (double m, double s, double b);
 
 };
 
@@ -450,9 +452,9 @@
  * \brief Class NormalVariable defines a random variable with a
  * normal (Gaussian) distribution.
  * \ingroup randomvariable
- * 
+ *
  * This class supports the creation of objects that return random numbers
- * from a fixed normal distribution.  It also supports the generation of 
+ * from a fixed normal distribution.  It also supports the generation of
  * single random numbers from various normal distributions.
  *
  * The density probability function is defined over the interval (-inf,+inf)
@@ -466,15 +468,15 @@
   /**
    * Constructs an normal random variable  with a mean
    * value of 0 and variance of 1.
-   */ 
-  NormalVariable();
+   */
+  NormalVariable ();
 
   /**
    * \brief Construct a normal random variable with specified mean and variance.
    * \param m Mean value
    * \param v Variance
-   */ 
-  NormalVariable(double m, double v);
+   */
+  NormalVariable (double m, double v);
 
   /**
    * \brief Construct a normal random variable with specified mean and variance
@@ -482,15 +484,15 @@
    * \param v Variance
    * \param b Bound.  The NormalVariable is bounded symetrically about the mean
    * [mean-bound,mean+bound]
-   */ 
-  NormalVariable(double m, double v, double b);
+   */
+  NormalVariable (double m, double v, double b);
 };
 
 /**
  * \brief EmpiricalVariable distribution random var
  * \ingroup randomvariable
  *
- * Defines a random variable  that has a specified, empirical 
+ * Defines a random variable  that has a specified, empirical
  * distribution.  The distribution is specified by a
  * series of calls to the CDF member function, specifying a
  * value and the probability that the function value is less than
@@ -501,19 +503,20 @@
  * as inverse transform sampling:
  * (http://en.wikipedia.org/wiki/Inverse_transform_sampling).
  */
-class EmpiricalVariable : public RandomVariable {
+class EmpiricalVariable : public RandomVariable
+{
 public:
   /**
    * Constructor for the EmpiricalVariable random variables.
    */
-  explicit EmpiricalVariable();
+  explicit EmpiricalVariable ();
 
   /**
    * \brief Specifies a point in the empirical distribution
    * \param v The function value for this point
    * \param c Probability that the function is less than or equal to v
    */
-  void CDF(double v, double c);  // Value, prob <= Value
+  void CDF (double v, double c);  // Value, prob <= Value
 protected:
   EmpiricalVariable (const RandomVariableBase &variable);
 };
@@ -527,10 +530,10 @@
  * sampling interpolation described in the EmpiricalVariable documentation
  * is modified to only return integers.
  */
-class IntEmpiricalVariable : public EmpiricalVariable 
+class IntEmpiricalVariable : public EmpiricalVariable
 {
 public:
-  IntEmpiricalVariable();
+  IntEmpiricalVariable ();
 };
 
 /**
@@ -550,13 +553,13 @@
    *
    * Creates a generator that returns successive elements of the d array
    * on successive calls to ::Value().  Note that the d pointer is copied
-   * for use by the generator (shallow-copy), not its contents, so the 
-   * contents of the array d points to have to remain unchanged for the use 
+   * for use by the generator (shallow-copy), not its contents, so the
+   * contents of the array d points to have to remain unchanged for the use
    * of DeterministicVariable to be meaningful.
    * \param d Pointer to array of random values to return in sequence
    * \param c Number of values in the array
    */
-  explicit DeterministicVariable(double* d, uint32_t c);
+  explicit DeterministicVariable (double* d, uint32_t c);
 };
 
 /**
@@ -573,7 +576,7 @@
  *
  * The probability density function is defined over the interval [0,+inf) as:
  * \f$ \frac{1}{x\sigma\sqrt{2\pi}} e^{-\frac{(ln(x) - \mu)^2}{2\sigma^2}}\f$
- * where \f$ mean = e^{\mu+\frac{\sigma^2}{2}} \f$ and 
+ * where \f$ mean = e^{\mu+\frac{\sigma^2}{2}} \f$ and
  * \f$ variance = (e^{\sigma^2}-1)e^{2\mu+\sigma^2}\f$
  *
  * The \f$ \mu \f$ and \f$ \sigma \f$ parameters can be calculated from the mean
@@ -581,7 +584,7 @@
  * \f$ \mu = ln(mean) - \frac{1}{2}ln\left(1+\frac{stddev}{mean^2}\right)\f$, and,
  * \f$ \sigma = \sqrt{ln\left(1+\frac{stddev}{mean^2}\right)}\f$
  */
-class LogNormalVariable : public RandomVariable 
+class LogNormalVariable : public RandomVariable
 {
 public:
   /**
@@ -595,18 +598,18 @@
  * \brief Gamma Distributed Random Variable
  * \ingroup randomvariable
  *
- * GammaVariable defines a random variable with gamma distribution. 
+ * GammaVariable defines a random variable with gamma distribution.
  *
  * This class supports the creation of objects that return random numbers
- * from a fixed gamma distribution. It also supports the generation of 
+ * from a fixed gamma distribution. It also supports the generation of
  * single random numbers from various gamma distributions.
  *
  * The probability density function is defined over the interval [0,+inf) as:
  * \f$ x^{\alpha-1} \frac{e^{-\frac{x}{\beta}}}{\beta^\alpha \Gamma(\alpha)}\f$
- * where \f$ mean = \alpha\beta \f$ and 
+ * where \f$ mean = \alpha\beta \f$ and
  * \f$ variance = \alpha \beta^2\f$
  */
-class GammaVariable : public RandomVariable 
+class GammaVariable : public RandomVariable
 {
 public:
   /**
@@ -622,7 +625,7 @@
 
   /**
    * \brief call RandomVariable::GetValue
-   * \return A floating point random value 
+   * \return A floating point random value
    *
    * Note: we have to re-implement this method here because the method is
    * overloaded below for the two-argument variant and the c++ name resolution
@@ -630,14 +633,14 @@
    * classes.
    */
   double GetValue (void) const;
-  
+
   /**
    * \brief Returns a gamma random distributed double with parameters alpha and beta.
    * \param alpha alpha parameter of the gamma distribution
    * \param beta beta parameter of the gamma distribution
    * \return A floating point random value
    */
-  double GetValue(double alpha, double beta) const;
+  double GetValue (double alpha, double beta) const;
 };
 
 /**
@@ -656,10 +659,10 @@
  *
  * The probability density function is defined over the interval [0,+inf) as:
  * \f$ \frac{x^{k-1} e^{-\frac{x}{\lambda}}}{\lambda^k (k-1)!}\f$
- * where \f$ mean = k \lambda \f$ and 
+ * where \f$ mean = k \lambda \f$ and
  * \f$ variance = k \lambda^2\f$
  */
-class ErlangVariable : public RandomVariable 
+class ErlangVariable : public RandomVariable
 {
 public:
   /**
@@ -675,7 +678,7 @@
 
   /**
    * \brief call RandomVariable::GetValue
-   * \return A floating point random value 
+   * \return A floating point random value
    *
    * Note: we have to re-implement this method here because the method is
    * overloaded below for the two-argument variant and the c++ name resolution
@@ -683,50 +686,87 @@
    * classes.
    */
   double GetValue (void) const;
-  
+
   /**
    * \brief Returns an Erlang random distributed double with parameters k and lambda.
    * \param k k parameter of the Erlang distribution. Must be a non-negative integer.
    * \param lambda lambda parameter of the Erlang distribution
    * \return A floating point random value
    */
-  double GetValue(unsigned int k, double lambda) const;
+  double GetValue (unsigned int k, double lambda) const;
 };
 
 /**
- * \brief Zipf Distributed random var (between 1 and n included)
+ * \brief Zipf Distributed Random Variable
  * \ingroup randomvariable
  *
+ * ZipfVariable defines a discrete random variable with Zipf distribution.
+ *
+ * The Zipf's law states that given some corpus of natural language
+ * utterances, the frequency of any word is inversely proportional
+ * to its rank in the frequency table.
+ *
+ * Zipf's distribution have two parameters, alpha and N, where:
+ * \f$ \alpha > 0 \f$ (real) and \f$ N \in \{1,2,3 \dots\}\f$ (integer).
+ * Probability Mass Function is \f$ f(k; \alpha, N) = k^{-\alpha}/ H_{N,\alpha} \f$
+ * where \f$ H_{N,\alpha} = \sum_{n=1}^N n^{-\alpha} \f$
  */
-class ZipfVariable : public RandomVariable 
+class ZipfVariable : public RandomVariable
 {
 public:
   /**
-   * \param n the number of possible items
-   * \param alpha the alpha parameter
+   * \brief Returns a Zipf random variable with parameters N and alpha.
+   * \param N the number of possible items. Must be a positive integer.
+   * \param alpha the alpha parameter. Must be a strictly positive real.
    */
-  ZipfVariable (long n, double alpha);
+  ZipfVariable (long N, double alpha);
   /**
-   * A zipf variable with N=1 and alpha=0
+   * Constructs a Zipf random variable with N=1 and alpha=0.
    */
   ZipfVariable ();
 };
 
 /**
+ * \brief Zeta Distributed Distributed Random Variable
+ * \ingroup randomvariable
+ *
+ * ZetaVariable defines a discrete random variable with Zeta distribution.
+ *
+ * The Zeta distribution is closely related to Zipf distribution when N goes to infinity.
+ *
+ * Zeta distribution has one parameter, alpha, \f$ \alpha > 1 \f$ (real).
+ * Probability Mass Function is \f$ f(k; \alpha) = k^{-\alpha}/\zeta(\alpha) \f$
+ * where \f$ \zeta(\alpha) \f$ is the Riemann zeta function ( \f$ \sum_{n=1}^\infty n^{-\alpha} ) \f$
+ */
+class ZetaVariable : public RandomVariable
+{
+public:
+  /**
+   * \brief Returns a Zeta random variable with parameter alpha.
+   * \param alpha the alpha parameter. Must be a strictly greater than 1, real.
+   */
+  ZetaVariable (double alpha);
+  /**
+   * Constructs a Zeta random variable with alpha=3.14
+   */
+  ZetaVariable ();
+};
+
+/**
  * \brief Triangularly Distributed random var
  * \ingroup randomvariable
- * 
+ *
  * This distribution is a triangular distribution.  The probablility density
  * is in the shape of a triangle.
  */
-class TriangularVariable : public RandomVariable 
+class TriangularVariable : public RandomVariable
 {
 public:
   /**
    * Creates a triangle distribution random number generator in the
    * range [0.0 .. 1.0), with mean of 0.5
    */
-  TriangularVariable();
+  TriangularVariable ();
 
   /**
    * Creates a triangle distribution random number generator with the specified
@@ -735,12 +775,12 @@
    * \param l High end of the range
    * \param mean mean of the distribution
    */
-  TriangularVariable(double s, double l, double mean);
+  TriangularVariable (double s, double l, double mean);
 
 };
 
-std::ostream &operator << (std::ostream &os, const RandomVariable &var);
-std::istream &operator >> (std::istream &os, RandomVariable &var);
+std::ostream & operator << (std::ostream &os, const RandomVariable &var);
+std::istream & operator >> (std::istream &os, RandomVariable &var);
 
 /**
  * \class ns3::RandomVariableValue
@@ -751,7 +791,7 @@
 ATTRIBUTE_CHECKER_DEFINE (RandomVariable);
 ATTRIBUTE_ACCESSOR_DEFINE (RandomVariable);
 
-}//namespace ns3
+} // namespace ns3
 
 
 #endif
--- a/src/devices/csma/csma-net-device.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/csma/csma-net-device.h	Thu Feb 25 14:17:21 2010 +0100
@@ -125,6 +125,13 @@
   void SetQueue (Ptr<Queue> queue);
 
   /**
+   * Get a copy of the attached Queue.
+   *
+   * \return a pointer to the queue.
+   */
+  Ptr<Queue> GetQueue (void) const; 
+
+  /**
    * Attach a receive ErrorModel to the CsmaNetDevice.
    *
    * The CsmaNetDevice may optionally include an ErrorModel in
@@ -414,16 +421,6 @@
   virtual void DoDispose (void);
 
   /**
-   * Get a copy of the attached Queue.
-   *
-   * This method is provided for any derived class that may need to get
-   * direct access to the underlying queue.
-   *
-   * \return a pointer to the queue.
-   */
-  Ptr<Queue> GetQueue (void) const; 
-
-  /**
    * Adds the necessary headers and trailers to a packet of data in order to
    * respect the packet type
    *
--- a/src/devices/emu/emu-net-device.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/emu/emu-net-device.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -272,6 +272,14 @@
   Ptr<RealtimeSimulatorImpl> impl = DynamicCast<RealtimeSimulatorImpl> (Simulator::GetImplementation ());
   m_rtImpl = GetPointer (impl);
 
+  //
+  // A similar story exists for the node ID.  We can't just naively do a
+  // GetNode ()->GetId () since GetNode is going to give us a Ptr<Node> which
+  // is reference counted.  We need to stash away the node ID for use in the
+  // read thread.
+  //
+  m_nodeId = GetNode ()->GetId ();
+
   NS_LOG_LOGIC ("Creating socket");
 
   //
@@ -444,16 +452,16 @@
       //
       // Execute the socket creation process image.
       //
-      status = ::execl (FindCreator ("emu-sock-creator").c_str (), 
+      status = ::execlp ("emu-sock-creator", 
                         "emu-sock-creator",                             // argv[0] (filename)
                         oss.str ().c_str (),                            // argv[1] (-p<path?
                         (char *)NULL);
 
       //
-      // If the execl successfully completes, it never returns.  If it returns it failed or the OS is
+      // If the execlp successfully completes, it never returns.  If it returns it failed or the OS is
       // broken.  In either case, we bail.
       //
-      NS_FATAL_ERROR ("EmuNetDevice::CreateSocket(): Back from execl(), errno = " << ::strerror (errno));
+      NS_FATAL_ERROR ("EmuNetDevice::CreateSocket(): Back from execlp(), errno = " << ::strerror (errno));
     }
   else
     {
@@ -581,52 +589,6 @@
     }
 }
 
-std::string
-EmuNetDevice::FindCreator (std::string creatorName)
-{
-  NS_LOG_FUNCTION (creatorName);
-
-  std::list<std::string> locations;
-
-  // The path to the bits if we're sitting there with them
-  locations.push_back ("./");
-  locations.push_back ("./");
-
-  // The path to the bits if we're sitting in the root of the repo
-  locations.push_back ("./build/optimized/src/devices/emu/");
-  locations.push_back ("./build/debug/src/devices/emu/");
-
-  // if at the level of src (or build)
-  locations.push_back ("../build/optimized/src/devices/emu/");
-  locations.push_back ("../build/debug/src/devices/emu/");
-
-  // src/devices (or build/debug)
-  locations.push_back ("../../build/optimized/src/devices/emu/");
-  locations.push_back ("../../build/debug/src/devices/emu/");
-
-  // src/devices/emu (or build/debug/examples)
-  locations.push_back ("../../../build/optimized/src/devices/emu/");
-  locations.push_back ("../../../build/debug/src/devices/emu/");
-
-  // src/devices/emu (or build/debug/examples/emulation)
-  locations.push_back ("../../../../build/optimized/src/devices/emu/");
-  locations.push_back ("../../../../build/debug/src/devices/emu/");
-
-  for (std::list<std::string>::const_iterator i = locations.begin (); i != locations.end (); ++i)
-    {
-      struct stat st;
-
-      if (::stat ((*i + creatorName).c_str (), &st) == 0)
-	{
-          NS_LOG_INFO ("Found Creator " << *i + creatorName);                  
-	  return *i + creatorName;
-	}
-    }
-
-  NS_FATAL_ERROR ("EmuNetDevice::FindCreator(): Couldn't find creator");
-  return ""; // quiet compiler
-}
-
 void
 EmuNetDevice::StopDevice (void)
 {
@@ -803,10 +765,10 @@
           return;
         }
 
-      NS_LOG_INFO ("EmuNetDevice::ReadThread(): Received packet");
+      NS_LOG_INFO ("EmuNetDevice::EmuNetDevice(): Received packet on node " << m_nodeId);
       NS_LOG_INFO ("EmuNetDevice::ReadThread(): Scheduling handler");
       NS_ASSERT_MSG (m_rtImpl, "EmuNetDevice::ReadThread(): Realtime simulator implementation pointer not set");
-      m_rtImpl->ScheduleRealtimeNowWithContext (GetNode ()->GetId (), MakeEvent (&EmuNetDevice::ForwardUp, this, buf, len));
+      m_rtImpl->ScheduleRealtimeNowWithContext (m_nodeId, MakeEvent (&EmuNetDevice::ForwardUp, this, buf, len));
       buf = 0;
     }
 }
--- a/src/devices/emu/emu-net-device.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/emu/emu-net-device.h	Thu Feb 25 14:17:21 2010 +0100
@@ -104,6 +104,14 @@
    */
   void SetQueue (Ptr<Queue> queue);
 
+  /**
+   * Get a copy of the attached Queue.
+   *
+   * @returns Ptr to the queue.
+   */
+  Ptr<Queue> GetQueue(void) const; 
+
+
 //
 // Pure virtual methods inherited from NetDevice we must implement.
 //
@@ -219,16 +227,6 @@
   std::string FindCreator (std::string creatorName);
 
   /**
-   * Get a copy of the attached Queue.
-   *
-   * This method is provided for any derived class that may need to get
-   * direct access to the underlying queue.
-   *
-   * @returns Ptr to the queue.
-   */
-  Ptr<Queue> GetQueue(void) const; 
-
-  /**
    * Spin up the device
    */
   void StartDevice (void);
@@ -515,6 +513,13 @@
    * Never free this pointer!
    */
   RealtimeSimulatorImpl *m_rtImpl;
+
+  /*
+   * a copy of the node id so the read thread doesn't have to GetNode() in
+   * in order to find the node ID.  Thread unsafe reference counting in 
+   * multithreaded apps is not a good thing.
+   */
+  uint32_t m_nodeId;
 };
 
 } // namespace ns3
--- a/src/devices/emu/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/emu/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -1,5 +1,7 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
+import os.path
+
 def configure(conf):
     if conf.env['ENABLE_THREADING']:
         conf.env['ENABLE_EMU'] = conf.check(header_name='netpacket/packet.h',
@@ -12,6 +14,11 @@
                                      False,
                                      "needs threading support which is not available")
 
+    if conf.env['ENABLE_EMU']:
+        blddir = os.path.abspath(os.path.join(conf.blddir, conf.env.variant()))
+        emucreatordir = os.path.abspath(os.path.join(blddir, "src/devices/emu"))
+        conf.env.append_value('NS3_EXECUTABLE_PATH', emucreatordir)
+
 def build(bld):
     module = bld.create_ns3_module('emu', ['node'])
     module.source = [
--- a/src/devices/point-to-point/point-to-point-net-device.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/point-to-point/point-to-point-net-device.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -511,11 +511,19 @@
       // Even if the transmitter is immediately available, we still enqueue and
       // dequeue the packet to hit the tracing hooks.
       //
-      m_queue->Enqueue (packet);
-      packet = m_queue->Dequeue ();
-      m_snifferTrace (packet);
-      m_promiscSnifferTrace (packet);
-      return TransmitStart (packet);
+      if (m_queue->Enqueue (packet) == true)
+        {
+          packet = m_queue->Dequeue ();
+          m_snifferTrace (packet);
+          m_promiscSnifferTrace (packet);
+          return TransmitStart (packet);
+        }
+      else
+        {
+          // Enqueue may fail (overflow)
+          m_macTxDropTrace (packet);
+          return false;
+        }
     }
   else
     {
--- a/src/devices/point-to-point/point-to-point-net-device.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/point-to-point/point-to-point-net-device.h	Thu Feb 25 14:17:21 2010 +0100
@@ -108,6 +108,13 @@
   void SetQueue (Ptr<Queue> queue);
 
   /**
+   * Get a copy of the attached Queue.
+   *
+   * @returns Ptr to the queue.
+   */
+  Ptr<Queue> GetQueue(void) const; 
+
+  /**
    * Attach a receive ErrorModel to the PointToPointNetDevice.
    *
    * The PointToPointNetDevice may optionally include an ErrorModel in
@@ -261,16 +268,6 @@
 
   virtual void DoDispose (void);
 
-  /**
-   * Get a copy of the attached Queue.
-   *
-   * This method is provided for any derived class that may need to get
-   * direct access to the underlying queue.
-   *
-   * @returns Ptr to the queue.
-   */
-  Ptr<Queue> GetQueue(void) const; 
-
 private:
   /**
    * Calculate the value for the MTU that would result from 
--- a/src/devices/tap-bridge/tap-bridge.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/tap-bridge/tap-bridge.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -206,6 +206,14 @@
   m_rtImpl = GetPointer (impl);
 
   //
+  // A similar story exists for the node ID.  We can't just naively do a
+  // GetNode ()->GetId () since GetNode is going to give us a Ptr<Node> which
+  // is reference counted.  We need to stash away the node ID for use in the
+  // read thread.
+  //
+  m_nodeId = GetNode ()->GetId ();
+
+  //
   // Spin up the tap bridge and start receiving packets.
   //
   NS_LOG_LOGIC ("Creating tap device");
@@ -477,8 +485,8 @@
       //
       // Execute the socket creation process image.
       //
-      status = ::execl (FindCreator ("tap-creator").c_str (), 
-                        FindCreator ("tap-creator").c_str (), // argv[0] (filename)
+      status = ::execlp ("tap-creator", 
+                        "tap-creator",                        // argv[0] (filename)
                         ossDeviceName.str ().c_str (),        // argv[1] (-d<device name>)
                         ossGateway.str ().c_str (),           // argv[2] (-g<gateway>)
                         ossIp.str ().c_str (),                // argv[3] (-i<IP address>)
@@ -489,10 +497,10 @@
                         (char *)NULL);
 
       //
-      // If the execl successfully completes, it never returns.  If it returns it failed or the OS is
+      // If the execlp successfully completes, it never returns.  If it returns it failed or the OS is
       // broken.  In either case, we bail.
       //
-      NS_FATAL_ERROR ("TapBridge::CreateTap(): Back from execl(), errno = " << ::strerror (errno));
+      NS_FATAL_ERROR ("TapBridge::CreateTap(): Back from execlp(), errno = " << ::strerror (errno));
     }
   else
     {
@@ -614,44 +622,6 @@
     }
 }
 
-std::string
-TapBridge::FindCreator (std::string creatorName)
-{
-  NS_LOG_FUNCTION (creatorName);
-
-  std::list<std::string> locations;
-
-  // The path to the bits if we're sitting in the root of the repo
-  locations.push_back ("./build/optimized/src/devices/tap-bridge/");
-  locations.push_back ("./build/debug/src/devices/tap-bridge/");
-
-  // if in src
-  locations.push_back ("../build/optimized/src/devices/tap-bridge/");
-  locations.push_back ("../build/debug/src/devices/tap-bridge/");
-
-  // if in src/devices
-  locations.push_back ("../../build/optimized/src/devices/tap-bridge/");
-  locations.push_back ("../../build/debug/src/devices/tap-bridge/");
-
-  // if in src/devices/tap-bridge
-  locations.push_back ("../../../build/optimized/src/devices/tap-bridge/");
-  locations.push_back ("../../../build/debug/src/devices/tap-bridge/");
-
-  for (std::list<std::string>::const_iterator i = locations.begin (); i != locations.end (); ++i)
-    {
-      struct stat st;
-
-      if (::stat ((*i + creatorName).c_str (), &st) == 0)
-	{
-          NS_LOG_INFO ("Found Creator " << *i + creatorName);                  
-	  return *i + creatorName;
-	}
-    }
-
-  NS_FATAL_ERROR ("TapBridge::FindCreator(): Couldn't find creator");
-  return ""; // quiet compiler
-}
-
 void
 TapBridge::ReadThread (void)
 {
@@ -686,11 +656,10 @@
           return;
         }
 
-      NS_LOG_INFO ("TapBridge::ReadThread(): Received packet on node " << m_node->GetId ());
+      NS_LOG_INFO ("TapBridge::ReadThread(): Received packet on node " << m_nodeId);
       NS_LOG_INFO ("TapBridge::ReadThread(): Scheduling handler");
       NS_ASSERT_MSG (m_rtImpl, "EmuNetDevice::ReadThread(): Realtime simulator implementation pointer not set");
-      m_rtImpl->ScheduleRealtimeNowWithContext (GetNode ()->GetId (),
-        MakeEvent (&TapBridge::ForwardToBridgedDevice, this, buf, len));
+      m_rtImpl->ScheduleRealtimeNowWithContext (m_nodeId, MakeEvent (&TapBridge::ForwardToBridgedDevice, this, buf, len));
       buf = 0;
     }
 }
--- a/src/devices/tap-bridge/tap-bridge.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/tap-bridge/tap-bridge.h	Thu Feb 25 14:17:21 2010 +0100
@@ -234,16 +234,6 @@
   /**
    * \internal
    *
-   * Figure out where the tap creation program lives on the system.
-   *
-   * \param creatorName The name of the program used to create the Tap.
-   * \returns A path name to use when you want to create a Tap.
-   */
-  std::string FindCreator (std::string creatorName);
-
-  /**
-   * \internal
-   *
    * Spin up the device
    */
   void StartTapDevice (void);
@@ -467,6 +457,13 @@
    * Never free this pointer!
    */
   RealtimeSimulatorImpl *m_rtImpl;
+
+  /*
+   * a copy of the node id so the read thread doesn't have to GetNode() in
+   * in order to find the node ID.  Thread unsafe reference counting in 
+   * multithreaded apps is not a good thing.
+   */
+  uint32_t m_nodeId;
 };
 
 } // namespace ns3
--- a/src/devices/tap-bridge/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/tap-bridge/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -1,5 +1,7 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
+import os.path
+
 def configure(conf):
     if conf.env['ENABLE_THREADING']:
         conf.env['ENABLE_TAP'] = conf.check(header_name='linux/if_tun.h',
@@ -12,6 +14,11 @@
                                      False,
                                      "needs threading support which is not available")
 
+    if conf.env['ENABLE_TAP']:
+        blddir = os.path.abspath(os.path.join(conf.blddir, conf.env.variant()))
+        tapcreatordir = os.path.abspath(os.path.join(blddir, "src/devices/tap-bridge"))
+        conf.env.append_value('NS3_EXECUTABLE_PATH', tapcreatordir)
+
 def build(bld):
     module = bld.create_ns3_module('tap-bridge', ['node'])
     module.source = [
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/block-ack-agreement.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,119 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * 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: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#include "block-ack-agreement.h"
+
+namespace ns3 {
+
+BlockAckAgreement::BlockAckAgreement ()
+ : m_amsduSupported (0),
+   m_blockAckPolicy (1),
+   m_inactivityEvent ()
+{}
+
+BlockAckAgreement::BlockAckAgreement (Mac48Address peer, uint8_t tid)
+ : m_amsduSupported (0),
+   m_blockAckPolicy (1),
+   m_inactivityEvent ()
+{
+  m_tid = tid;
+  m_peer = peer;
+}
+
+BlockAckAgreement::~BlockAckAgreement ()
+{
+  m_inactivityEvent.Cancel ();
+}
+
+void
+BlockAckAgreement::SetBufferSize (uint16_t bufferSize)
+{
+  NS_ASSERT (bufferSize <= 1024);
+  m_bufferSize = bufferSize;
+}
+void
+BlockAckAgreement::SetTimeout (uint16_t timeout)
+{
+  m_timeout = timeout;
+}
+void
+BlockAckAgreement::SetStartingSequence (uint16_t seq)
+{
+  NS_ASSERT (seq < 4096);
+  m_startingSeq = seq;
+}
+void
+BlockAckAgreement::SetImmediateBlockAck (void)
+{
+  m_blockAckPolicy = 1;
+}
+void
+BlockAckAgreement::SetDelayedBlockAck (void)
+{
+  m_blockAckPolicy = 0;
+}
+void
+BlockAckAgreement::SetAmsduSupport (bool supported)
+{
+  m_amsduSupported = supported;
+}
+
+uint8_t
+BlockAckAgreement::GetTid (void) const
+{
+  return m_tid;
+}
+Mac48Address
+BlockAckAgreement::GetPeer (void) const
+{
+  return m_peer;
+}
+uint16_t
+BlockAckAgreement::GetBufferSize (void) const
+{
+  return m_bufferSize;
+}
+uint16_t
+BlockAckAgreement::GetTimeout (void) const
+{
+  return m_timeout;
+}
+uint16_t
+BlockAckAgreement::GetStartingSequence (void) const
+{
+  return m_startingSeq;
+}
+uint16_t
+BlockAckAgreement::GetStartingSequenceControl (void) const
+{
+  uint16_t seqControl = (m_startingSeq<<4) | 0xfff0;
+  return seqControl;
+}
+bool
+BlockAckAgreement::IsImmediateBlockAck (void) const
+{
+  return (m_blockAckPolicy == 1);
+}
+bool
+BlockAckAgreement::IsAmsduSupported (void) const
+{
+  return (m_amsduSupported == 1)?true:false;
+}
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/block-ack-agreement.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,68 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * 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: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#ifndef BLOCK_ACK_AGREEMENT_H
+#define BLOCK_ACK_AGREEMENT_H
+
+#include "ns3/mac48-address.h"
+#include "ns3/event-id.h"
+
+namespace ns3 {
+/**
+ * \brief Maintains information for a block ack agreement.
+ */
+class BlockAckAgreement 
+{
+  friend class MacLow;
+public:
+  BlockAckAgreement ();
+  BlockAckAgreement (Mac48Address peer, uint8_t tid);
+  ~BlockAckAgreement ();
+  void SetBufferSize (uint16_t bufferSize);
+  void SetTimeout (uint16_t timeout);
+  void SetStartingSequence (uint16_t seq);
+  void SetImmediateBlockAck (void);
+  void SetDelayedBlockAck (void);
+  void SetAmsduSupport (bool supported);
+
+  uint8_t GetTid (void) const;
+  Mac48Address GetPeer (void) const;
+  uint16_t GetBufferSize (void) const;
+  uint16_t GetTimeout (void) const;
+  uint16_t GetStartingSequence (void) const;
+  uint16_t GetStartingSequenceControl (void) const;
+  bool IsImmediateBlockAck (void) const;
+  bool IsAmsduSupported (void) const;
+
+protected:
+ 
+  Mac48Address m_peer;
+  uint8_t m_amsduSupported;
+  uint8_t m_blockAckPolicy; /* represents type of block ack: immediate or delayed */
+  uint8_t m_tid;
+  uint16_t m_bufferSize;
+  uint16_t m_timeout;
+  uint16_t m_startingSeq;
+  
+  EventId m_inactivityEvent;
+};
+
+} //namespace ns3
+
+#endif /* BLOCK_ACK_AGREEMENT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/block-ack-manager.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,617 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * 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: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/simulator.h"
+#include "ns3/fatal-error.h"
+
+#include "block-ack-manager.h"
+#include "mgt-headers.h"
+#include "ctrl-headers.h"
+#include "wifi-mac-header.h"
+#include "edca-txop-n.h"
+#include "mac-low.h"
+#include "wifi-mac-queue.h"
+#include "mac-tx-middle.h"
+
+NS_LOG_COMPONENT_DEFINE ("BlockAckManager");
+
+namespace ns3 {
+
+BlockAckManager::Item::Item ()
+{}
+
+BlockAckManager::Item::Item (Ptr<const Packet> packet, const WifiMacHeader &hdr, Time tStamp)
+  : packet (packet), hdr (hdr), timestamp (tStamp)
+{}
+
+Bar::Bar ()
+{}
+
+Bar::Bar (Ptr<const Packet> bar, Mac48Address recipient, uint8_t tid, bool immediate)
+  : bar (bar), recipient (recipient), tid (tid), immediate (immediate)
+{}
+
+BlockAckManager::BlockAckManager ()
+{}
+
+BlockAckManager::~BlockAckManager ()
+{
+  m_queue = 0;
+  m_agreements.clear ();
+  m_retryPackets.clear ();
+}
+
+bool
+BlockAckManager::ExistsAgreement (Mac48Address recipient, uint8_t tid) const
+{
+  return (m_agreements.find (std::make_pair (recipient, tid)) != m_agreements.end ());
+}
+
+bool
+BlockAckManager::ExistsAgreementInState (Mac48Address recipient, uint8_t tid, 
+                                         enum OriginatorBlockAckAgreement::State state) const
+{
+  AgreementsCI it;
+  it = m_agreements.find (std::make_pair (recipient, tid));
+  if (it != m_agreements.end ())
+    {
+      switch (state) {
+        case OriginatorBlockAckAgreement::INACTIVE:
+          return it->second.first.IsInactive ();
+        case OriginatorBlockAckAgreement::ESTABLISHED:
+          return it->second.first.IsEstablished ();
+        case OriginatorBlockAckAgreement::PENDING:
+          return it->second.first.IsPending ();
+        case OriginatorBlockAckAgreement::UNSUCCESSFUL:
+          return it->second.first.IsUnsuccessful ();
+        default:
+          NS_FATAL_ERROR ("Invalid state for block ack agreement");
+      }
+    }
+  return false;
+}
+
+void
+BlockAckManager::CreateAgreement (const MgtAddBaRequestHeader *reqHdr, Mac48Address recipient)
+{
+  pair<Mac48Address, uint8_t> key (recipient, reqHdr->GetTid ());
+  OriginatorBlockAckAgreement agreement (recipient, reqHdr->GetTid ());
+  agreement.SetStartingSequence (reqHdr->GetStartingSequence ());
+  /* for now we assume that originator doesn't use this field. Use of this field 
+     is mandatory only for recipient */
+  agreement.SetBufferSize (0);
+  agreement.SetTimeout (reqHdr->GetTimeout ());
+  agreement.SetAmsduSupport (reqHdr->IsAmsduSupported ());
+  if (reqHdr->IsImmediateBlockAck ())
+    {
+      agreement.SetImmediateBlockAck ();
+    }                         
+  else
+    {
+      agreement.SetDelayedBlockAck ();
+    }
+  agreement.SetState (OriginatorBlockAckAgreement::PENDING);
+  PacketQueue queue(0);
+  pair<OriginatorBlockAckAgreement, PacketQueue> value (agreement, queue);
+  m_agreements.insert (make_pair (key, value));
+  m_blockPackets (recipient, reqHdr->GetTid ());
+}
+
+void
+BlockAckManager::DestroyAgreement (Mac48Address recipient, uint8_t tid)
+{
+  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
+  if (it != m_agreements.end ())
+    {
+      for (list<PacketQueueI>::iterator i = m_retryPackets.begin (); i != m_retryPackets.end ();)
+        {
+          if ((*i)->hdr.GetAddr1 () == recipient && (*i)->hdr.GetQosTid () == tid)
+            {
+              i = m_retryPackets.erase (i);
+            }
+          else
+            {
+              i++;
+            }
+        }
+      m_agreements.erase (it);
+      //remove scheduled bar
+      for (list<Bar>::iterator i = m_bars.begin (); i != m_bars.end ();)
+        {
+          if (i->recipient == recipient && i->tid == tid)
+            {
+              i = m_bars.erase (i);
+            }
+          else
+            {
+              i++;
+            }
+        }
+    }
+}
+
+void
+BlockAckManager::UpdateAgreement (const MgtAddBaResponseHeader *respHdr, Mac48Address recipient)
+{
+  uint8_t tid = respHdr->GetTid ();
+  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
+  if (it != m_agreements.end ())
+    {
+      OriginatorBlockAckAgreement& agreement = it->second.first;
+      agreement.SetBufferSize (respHdr->GetBufferSize () + 1);
+      agreement.SetTimeout (respHdr->GetTimeout ());
+      agreement.SetAmsduSupport (respHdr->IsAmsduSupported ());
+      if (respHdr->IsImmediateBlockAck ())
+        {
+          agreement.SetImmediateBlockAck ();
+        }                         
+      else
+        {
+          agreement.SetDelayedBlockAck ();
+        }
+      agreement.SetState (OriginatorBlockAckAgreement::ESTABLISHED);
+      if (agreement.GetTimeout () != 0)
+        {
+          Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
+          agreement.m_inactivityEvent = Simulator::Schedule (timeout, 
+                                                             &BlockAckManager::InactivityTimeout, 
+                                                             this,
+                                                             recipient, tid);
+        }
+    }
+  m_unblockPackets (recipient, tid);
+}
+
+void
+BlockAckManager::StorePacket (Ptr<const Packet> packet, const WifiMacHeader &hdr, Time tStamp)
+{
+  NS_LOG_FUNCTION (this);
+  NS_ASSERT (hdr.IsQosData ());
+
+  uint8_t tid = hdr.GetQosTid ();
+  Mac48Address recipient = hdr.GetAddr1 ();
+
+  Item item (packet, hdr, tStamp);
+  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
+  NS_ASSERT (it != m_agreements.end ());
+  it->second.second.push_back (item);
+}
+
+Ptr<const Packet>
+BlockAckManager::GetNextPacket (WifiMacHeader &hdr)
+{
+  NS_LOG_FUNCTION (this);
+  Ptr<const Packet> packet = 0;
+  if (m_retryPackets.size () > 0)
+    {
+      CleanupBuffers ();
+      PacketQueueI queueIt = m_retryPackets.front ();
+      m_retryPackets.pop_front ();
+      packet = queueIt->packet;
+      hdr = queueIt->hdr;
+      hdr.SetRetry ();
+      NS_LOG_INFO ("Retry packet seq="<<hdr.GetSequenceNumber ());
+      uint8_t tid = hdr.GetQosTid ();
+      Mac48Address recipient = hdr.GetAddr1 ();
+
+      if (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED) ||
+          SwitchToBlockAckIfNeeded (recipient, tid, hdr.GetSequenceNumber ()))
+        {
+          hdr.SetQosAckPolicy (WifiMacHeader::BLOCK_ACK);
+        }
+      else
+        {
+          /* From section 9.10.3 in IEEE802.11e standard:
+           * In order to improve efficiency, originators using the Block Ack facility
+           * may send MPDU frames with the Ack Policy subfield in QoS control frames
+           * set to Normal Ack if only a few MPDUs are available for transmission.[...]
+           * When there are sufficient number of MPDUs, the originator may switch back to 
+           * the use of Block Ack.
+           */
+          hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
+          AgreementsI i = m_agreements.find (std::make_pair (recipient, tid));
+          i->second.second.erase (queueIt);
+        }
+    }
+  return packet;
+}
+
+bool
+BlockAckManager::HasBar (struct Bar &bar)
+{
+  if (m_bars.size () > 0)
+    {
+      bar = m_bars.front ();
+      m_bars.pop_front ();
+      return true;
+    }
+  return false;
+}
+
+bool
+BlockAckManager::HasPackets (void) const
+{
+  return (m_retryPackets.size () > 0 || m_bars.size () > 0);
+}
+
+uint32_t
+BlockAckManager::GetNBufferedPackets (Mac48Address recipient, uint8_t tid) const
+{
+  uint32_t nPackets = 0;
+  if (ExistsAgreement (recipient, tid))
+    {
+      AgreementsCI it = m_agreements.find (std::make_pair (recipient, tid));
+      PacketQueueCI queueIt = (*it).second.second.begin ();
+      uint16_t currentSeq = 0;
+      while (queueIt != (*it).second.second.end ())
+        {
+          currentSeq = (*queueIt).hdr.GetSequenceNumber ();
+          nPackets++;
+          /* a fragmented packet must be counted as one packet */
+          while (queueIt != (*it).second.second.end () && (*queueIt).hdr.GetSequenceNumber () == currentSeq)
+            {
+              queueIt++;
+            }
+        }
+      return nPackets;
+    }
+  return 0;
+}
+
+uint32_t
+BlockAckManager::GetNRetryNeededPackets (Mac48Address recipient, uint8_t tid) const
+{
+  uint32_t nPackets = 0;
+  uint16_t currentSeq = 0;
+  if (ExistsAgreement (recipient, tid))
+    {
+      list<PacketQueueI>::const_iterator it = m_retryPackets.begin ();
+      while (it != m_retryPackets.end ())
+        {
+          if ((*it)->hdr.GetAddr1 () == recipient && (*it)->hdr.GetQosTid () == tid)
+            {
+              currentSeq = (*it)->hdr.GetSequenceNumber ();
+              nPackets++;
+              /* a fragmented packet must be counted as one packet */
+              while (it != m_retryPackets.end () && (*it)->hdr.GetSequenceNumber () == currentSeq)
+                {
+                  it++;
+                }
+            }
+        }
+    }
+  return nPackets;
+}
+
+void
+BlockAckManager::SetBlockAckThreshold (uint8_t nPackets)
+{
+  m_blockAckThreshold = nPackets;
+}
+
+void
+BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recipient)
+{
+  NS_LOG_FUNCTION (this);
+  uint16_t sequenceFirstLost = 0;
+  if (!blockAck->IsMultiTid ())
+    {
+      uint8_t tid = blockAck->GetTidInfo ();
+      if (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED))
+        {
+          bool foundFirstLost = false;
+          AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
+          PacketQueueI queueEnd = it->second.second.end ();
+
+          if (it->second.first.m_inactivityEvent.IsRunning ())
+            {
+              /* Upon reception of a block ack frame, the inactivity timer at the 
+                 originator must be reset. 
+                 For more details see section 11.5.3 in IEEE802.11e standard */
+              it->second.first.m_inactivityEvent.Cancel ();
+              Time timeout = MicroSeconds (1024 * it->second.first.GetTimeout ());
+              it->second.first.m_inactivityEvent = Simulator::Schedule (timeout,
+                                                                        &BlockAckManager::InactivityTimeout, 
+                                                                        this,
+                                                                        recipient, tid);
+            }
+          if (blockAck->IsBasic ())
+            {
+              for (PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd;)
+                {
+                  if (blockAck->IsFragmentReceived ((*queueIt).hdr.GetSequenceNumber (),
+                                                    (*queueIt).hdr.GetFragmentNumber ()))
+                    {
+                      queueIt = it->second.second.erase (queueIt);
+                    }
+                  else
+                    {
+                      if (!foundFirstLost)
+                        {
+                          foundFirstLost = true;
+                          sequenceFirstLost = (*queueIt).hdr.GetSequenceNumber ();
+                          (*it).second.first.SetStartingSequence (sequenceFirstLost);
+                        }
+                      m_retryPackets.push_back (queueIt);
+                      queueIt++;
+                    }
+                }
+            }
+          else if (blockAck->IsCompressed ())
+            {
+              for (PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd;)
+                {
+                  if (blockAck->IsPacketReceived ((*queueIt).hdr.GetSequenceNumber ()))
+                    {
+                      uint16_t currentSeq = (*queueIt).hdr.GetSequenceNumber ();
+                      while (queueIt != queueEnd &&
+                             (*queueIt).hdr.GetSequenceNumber () == currentSeq)
+                        {
+                          queueIt = it->second.second.erase (queueIt);
+                        }
+                    }
+                  else
+                    {
+                      if (!foundFirstLost)
+                        {
+                          foundFirstLost = true;
+                          sequenceFirstLost = (*queueIt).hdr.GetSequenceNumber ();
+                          (*it).second.first.SetStartingSequence (sequenceFirstLost);
+                        }
+                      m_retryPackets.push_back (queueIt);
+                      queueIt++;
+                    }
+                }
+            }
+          uint16_t newSeq = m_txMiddle->GetNextSeqNumberByTidAndAddress (tid, recipient);
+          if ((foundFirstLost && !SwitchToBlockAckIfNeeded (recipient, tid, sequenceFirstLost)) ||
+              (!foundFirstLost && !SwitchToBlockAckIfNeeded (recipient, tid, newSeq)))
+            {
+              it->second.first.SetState (OriginatorBlockAckAgreement::INACTIVE);
+            }
+        }
+    }
+  else
+    {
+      //NOT SUPPORTED FOR NOW
+      NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+    }
+}
+
+void
+BlockAckManager::SetBlockAckType (enum BlockAckType bAckType)
+{
+  m_blockAckType = bAckType;
+}
+
+Ptr<Packet>
+BlockAckManager::ScheduleBlockAckReqIfNeeded (Mac48Address recipient, uint8_t tid)
+{
+  /* This method checks if a BlockAckRequest frame should be send to the recipient station.
+     Number of packets under block ack is specified in OriginatorBlockAckAgreement object but sometimes
+     this number could be incorrect. In fact is possible that a block ack agreement exists for n
+     packets but some of these packets are dropped due to MSDU lifetime expiration.
+   */
+  NS_LOG_FUNCTION (this);
+  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
+  NS_ASSERT (it != m_agreements.end ());
+
+  if ((*it).second.first.NeedBlockAckRequest () ||
+      (GetNRetryNeededPackets (recipient, tid) == 0 &&
+       m_queue->GetNPacketsByTidAndAddress (tid, WifiMacHeader::ADDR1, recipient) == 0))
+    {
+      OriginatorBlockAckAgreement &agreement = (*it).second.first;
+      agreement.CompleteExchange ();
+
+      CtrlBAckRequestHeader reqHdr;
+      if (m_blockAckType == BASIC_BLOCK_ACK || m_blockAckType == COMPRESSED_BLOCK_ACK)
+        {
+          reqHdr.SetType (m_blockAckType);
+          reqHdr.SetTidInfo (agreement.GetTid ());
+          reqHdr.SetStartingSequence (agreement.GetStartingSequence ());
+        }
+      else if (m_blockAckType == MULTI_TID_BLOCK_ACK)
+        {
+          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+        }
+      else
+        {
+          NS_FATAL_ERROR ("Invalid block ack type.");
+        }
+      Ptr<Packet> bar = Create<Packet> ();
+      bar->AddHeader (reqHdr);
+      return bar;
+    }
+  return 0;
+}
+
+void
+BlockAckManager::InactivityTimeout (Mac48Address recipient, uint8_t tid)
+{
+  m_blockAckInactivityTimeout (recipient, tid, true);
+}
+
+void
+BlockAckManager::NotifyAgreementEstablished (Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
+{
+  NS_LOG_FUNCTION (this);
+  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
+  NS_ASSERT (it != m_agreements.end ());
+    
+  it->second.first.SetState (OriginatorBlockAckAgreement::ESTABLISHED);
+  it->second.first.SetStartingSequence (startingSeq);
+}
+
+void
+BlockAckManager::NotifyAgreementUnsuccessful (Mac48Address recipient, uint8_t tid)
+{
+  NS_LOG_FUNCTION (this);
+  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
+  NS_ASSERT (it != m_agreements.end ());
+  if (it != m_agreements.end ())
+    {
+      it->second.first.SetState (OriginatorBlockAckAgreement::UNSUCCESSFUL);
+    }
+}
+
+void
+BlockAckManager::NotifyMpduTransmission (Mac48Address recipient, uint8_t tid)
+{
+  NS_LOG_FUNCTION (this);
+  Ptr<Packet> bar = 0;
+  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
+  NS_ASSERT (it != m_agreements.end ());
+  it->second.first.NotifyMpduTransmission ();
+  bar = ScheduleBlockAckReqIfNeeded (recipient, tid);
+  if (bar != 0)
+    {
+      Bar request (bar, recipient, tid, it->second.first.IsImmediateBlockAck ());
+      m_bars.push_back (request);
+    }
+}
+
+void
+BlockAckManager::SetQueue (Ptr<WifiMacQueue> queue)
+{
+  m_queue = queue;
+}
+
+bool
+BlockAckManager::SwitchToBlockAckIfNeeded (Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
+{
+  NS_LOG_FUNCTION (this);
+  NS_ASSERT (!ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::PENDING));
+  if (!ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::UNSUCCESSFUL) && ExistsAgreement (recipient, tid))
+    {
+      uint32_t packets = m_queue->GetNPacketsByTidAndAddress (tid, WifiMacHeader::ADDR1, recipient) +
+                         GetNBufferedPackets (recipient, tid);
+      if (packets >= m_blockAckThreshold)
+        {
+          NotifyAgreementEstablished (recipient, tid, startingSeq);
+          return true;
+        }
+    }
+  return false;
+}
+
+void
+BlockAckManager::TearDownBlockAck (Mac48Address recipient, uint8_t tid)
+{
+  NS_LOG_FUNCTION (this);
+  DestroyAgreement (recipient, tid);
+}
+
+bool
+BlockAckManager::HasOtherFragments (uint16_t sequenceNumber) const
+{
+  bool retVal = false;
+  if (m_retryPackets.size () > 0)
+    {
+      Item next = *(m_retryPackets.front ());
+      if (next.hdr.GetSequenceNumber () == sequenceNumber)
+        {
+          retVal = true;
+        }
+    }
+  return retVal;
+}
+
+uint32_t
+BlockAckManager::GetNextPacketSize (void) const
+{
+  uint32_t size = 0;
+  if (m_retryPackets.size () > 0)
+    {
+      Item next = *(m_retryPackets.front ());
+      size = next.packet->GetSize ();
+    }
+  return size;
+}
+
+void
+BlockAckManager::CleanupBuffers (void)
+{
+  for (AgreementsI j = m_agreements.begin(); j != m_agreements.end (); j++)
+    {
+      if (j->second.second.empty ()) 
+        {
+          continue;
+        }
+      Time now = Simulator::Now ();
+      PacketQueueI end = j->second.second.begin ();
+      for (PacketQueueI i = j->second.second.begin (); i != j->second.second.end (); i++) 
+        {
+          if (i->timestamp + m_maxDelay > now) 
+            {
+              end = i;
+              break;
+            }
+          else
+            {
+              /* remove retry packet iterator if it's present in retry queue */
+              for (list<PacketQueueI>::iterator it = m_retryPackets.begin (); it != m_retryPackets.end (); it++)
+                {
+                  if ((*it)->hdr.GetAddr1 () == j->second.first.GetPeer () &&
+                      (*it)->hdr.GetQosTid () == j->second.first.GetTid () &&
+                      (*it)->hdr.GetSequenceNumber () == i->hdr.GetSequenceNumber ())
+                    {
+                      m_retryPackets.erase (it);
+                    }
+                }
+            }
+        }
+      j->second.second.erase (j->second.second.begin (), end);
+      j->second.first.SetStartingSequence (end->hdr.GetSequenceNumber ());
+    }
+}
+
+void
+BlockAckManager::SetMaxPacketDelay (Time maxDelay)
+{
+  NS_LOG_FUNCTION (this);
+  m_maxDelay = maxDelay;
+}
+
+void
+BlockAckManager::SetBlockAckInactivityCallback (Callback<void, Mac48Address, uint8_t, bool> callback)
+{
+  m_blockAckInactivityTimeout = callback;
+}
+
+void
+BlockAckManager::SetBlockDestinationCallback (Callback<void, Mac48Address, uint8_t> callback)
+{
+  m_blockPackets = callback;
+}
+
+void
+BlockAckManager::SetUnblockDestinationCallback (Callback<void, Mac48Address, uint8_t> callback)
+{
+  m_unblockPackets = callback;
+}
+
+void
+BlockAckManager::SetTxMiddle (MacTxMiddle* txMiddle)
+{
+  m_txMiddle = txMiddle;
+}
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/block-ack-manager.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,304 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * 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: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#ifndef BLOCK_ACK_MANAGER_H
+#define BLOCK_ACK_MANAGER_H
+
+#include <map>
+#include <list>
+#include <deque>
+
+#include "ns3/packet.h"
+
+#include "wifi-mac-header.h"
+#include "originator-block-ack-agreement.h"
+#include "ctrl-headers.h"
+#include "qos-utils.h"
+
+using namespace std;
+
+namespace ns3 {
+
+class MgtAddBaResponseHeader;
+class MgtAddBaRequestHeader;
+class MgtDelBaHeader;
+class MacTxMiddle;
+class WifiMacQueue;
+
+struct Bar {
+    Bar ();
+    Bar (Ptr<const Packet> packet,
+         Mac48Address recipient,
+         uint8_t tid,
+         bool immediate);
+    Ptr<const Packet> bar;
+    Mac48Address recipient;
+    uint8_t tid;
+    bool immediate;
+};
+
+/**
+ * \brief Manages all block ack agreements for an originator station.
+ */
+class BlockAckManager
+{
+private:
+  BlockAckManager (const BlockAckManager&);
+  BlockAckManager& operator= (const BlockAckManager&);
+
+public:
+  BlockAckManager ();
+  ~BlockAckManager ();
+  /**
+   * \param recipient Address of peer station involved in block ack mechanism.
+   * \param tid Traffic ID.
+   *
+   * Checks if a block ack agreement exists with station addressed by 
+   * <i>recipient</i> for tid <i>tid</i>.
+   */
+  bool ExistsAgreement (Mac48Address recipient, uint8_t tid) const;
+  /**
+   * \param recipient Address of peer station involved in block ack mechanism.
+   * \param tid Traffic ID.
+   * \param state The state for block ack agreement
+
+   * Checks if a block ack agreement with a state equals to <i>state</i> exists with
+   * station addressed by <i>recipient</i> for tid <i>tid</i>.
+   */
+  bool ExistsAgreementInState (Mac48Address recipient, uint8_t tid, 
+                               enum OriginatorBlockAckAgreement::State state) const;
+  /** 
+   * \param reqHdr Relative Add block ack request (action frame).
+   * \param recipient Address of peer station involved in block ack mechanism.
+   *
+   * Creates a new block ack agreement in pending state. When a ADDBA response 
+   * with a successful status code is received, the relative agreement becomes established. 
+   */
+  void CreateAgreement (const MgtAddBaRequestHeader *reqHdr, Mac48Address recipient);
+  /** 
+   * \param recipient Address of peer station involved in block ack mechanism.
+   * \param tid Tid Traffic id of transmitted packet.
+   *
+   * Invoked when a recipient reject a block ack agreement or when a Delba frame
+   * is Received/Trasmitted.
+   */
+  void DestroyAgreement (Mac48Address recipient, uint8_t tid);
+  /**
+   * \param respHdr Relative Add block ack response (action frame).
+   * \param recipient Address of peer station involved in block ack mechanism.
+   *
+   * Invoked upon receipt of a ADDBA response frame from <i>recipient</i>.
+   */
+  void UpdateAgreement (const MgtAddBaResponseHeader *respHdr, Mac48Address recipient);
+  /**
+   * \param packet Packet to store.
+   * \param hdr 802.11 header for packet.
+   * \param tStamp time stamp for packet
+   *
+   * Stores <i>packet</i> for a possible future retransmission. Retransmission occurs
+   * if the packet, in a block ack frame, is indicated by recipient as not received.
+   */
+  void StorePacket (Ptr<const Packet> packet, const WifiMacHeader &hdr, Time tStamp);
+  /**
+   * \param hdr 802.11 header of returned packet (if exists).
+   *
+   * This methods returns a packet (if exists) indicated as not received in
+   * corresponding block ack bitmap.
+   */
+  Ptr<const Packet> GetNextPacket (WifiMacHeader &hdr);
+  bool HasBar (struct Bar &bar);
+  /**
+   * Returns true if there are packets that need of retransmission or at least a
+   * BAR is sheduled. Returns false othewise.
+   */
+  bool HasPackets (void) const;
+  /**
+   * \param blockAck The received block ack frame.
+   * \param recipient Sender of block ack frame.
+   *
+   * Invoked upon receipt of a block ack frame. Typically, this function, is called
+   * by ns3::EdcaTxopN object. Performs a check on which MPDUs, previously sent
+   * with ack policy set to Block Ack, were correctly received by the recipient. 
+   * An acknowldeged MPDU is removed from the buffer, retransmitted otherwise.  
+   */
+  void NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recipient);
+  /**
+   * \param recipient Address of peer station involved in block ack mechanism.
+   * \param tid Traffic ID.
+   *
+   * Returns number of packets buffered for a specified agreement. This methods doesn't return 
+   * number of buffered MPDUs but number of buffered MSDUs.
+   */
+  uint32_t GetNBufferedPackets (Mac48Address recipient, uint8_t tid) const;
+  /**
+   * \param recipient Address of peer station involved in block ack mechanism.
+   * \param tid Traffic ID.
+   *
+   * Returns number of packets for a specific agreeemnt that need retransmission.
+   * This methods doesn't return number of MPDUs that need retransmission but number MSDUs.
+   */
+  uint32_t GetNRetryNeededPackets (Mac48Address recipient, uint8_t tid) const;
+  /**
+   * \param recipient Address of peer station involved in block ack mechanism.
+   * \param tid Traffic ID of transmitted packet.
+   * \param startingSeq starting sequence field
+   *
+   * Puts corresponding agreement in established state and updates number of packets
+   * and starting sequence field. Invoked typically after a block ack refresh.  
+   */
+  void NotifyAgreementEstablished (Mac48Address recipient, uint8_t tid, uint16_t startingSeq);
+  /**
+   * \param recipient Address of peer station involved in block ack mechanism.
+   * \param tid Traffic ID of transmitted packet.
+   *
+   * Marks an agreement as unsuccessful. This happens if <i>recipient</i> station reject block ack setup
+   * by an ADDBAResponse frame with a failure status code. FOr now we assume that every QoS station accepts
+   * a block ack setup.
+   */
+  void NotifyAgreementUnsuccessful (Mac48Address recipient, uint8_t tid);
+  /**
+   * \param recipient Address of peer station involved in block ack mechanism.
+   * \param tid Traffic ID of transmitted packet.
+   *
+   * This methods is typically invoked by ns3::EdcaTxopN object every time that a MPDU
+   * with ack policy subfield in Qos Control field set to Block Ack is transmitted.
+   */
+  void NotifyMpduTransmission (Mac48Address recipient, uint8_t tid);
+  /**
+   * \param nPackets Minimum number of packets for use of block ack.
+   *
+   * Upon receipt of a block ack frame, if total number of packets (packets in WifiMacQueue
+   * and buffered packets) is greater of <i>nPackets</i>, they are transmitted using block ack mechanism.   
+   */
+  void SetBlockAckThreshold (uint8_t nPackets);
+  /**
+   * \param queue The WifiMacQueue object.
+   */
+  void SetQueue (Ptr<WifiMacQueue> queue);
+  void SetTxMiddle (MacTxMiddle* txMiddle);
+  /**
+   * \param bAckType Type of block ack
+   *
+   * See ctrl-headers.h for more details.
+   */
+  void SetBlockAckType (enum BlockAckType bAckType);
+  /**
+   * \param recipient Address of station involved in block ack mechanism.
+   * \param tid Traffic ID.
+   *
+   * This method is invoked by EdcaTxopN object upon receipt of a DELBA frame
+   * from recipient. The relative block ack agreement is destroied.
+   */
+  void TearDownBlockAck (Mac48Address recipient, uint8_t tid);
+  /**
+   * \param sequenceNumber Sequence number of the packet which fragment is 
+   * part of.
+   *
+   * Returns true if another fragment with sequence number <i>sequenceNumber</i> is scheduled
+   * for retransmission.
+   */
+  bool HasOtherFragments (uint16_t sequenceNumber) const;
+  /**
+   * Returns size of the next packet that needs retransmission.
+   */
+  uint32_t GetNextPacketSize (void) const;
+  /**
+   * \param maxDelay Max delay for a buffered packet.
+   * 
+   * This method is always called by ns3::WifiMacQueue object and sets max delay equals
+   * to ns3:WifiMacQueue delay value.
+   */
+  void SetMaxPacketDelay (Time maxDelay);
+  /**
+   */
+  void SetBlockAckInactivityCallback (Callback<void, Mac48Address, uint8_t, bool> callback);
+  void SetBlockDestinationCallback (Callback<void, Mac48Address, uint8_t> callback);
+  void SetUnblockDestinationCallback (Callback<void, Mac48Address, uint8_t> callback);
+  /**
+   * Checks if there are in the queue other packets that could be send under block ack.
+   * If yes adds these packets in current block ack exchange.
+   * However, number of packets exchanged in the current block ack, will not exceed 
+   * the value of BufferSize in the corresponding OriginatorBlockAckAgreement object.
+   */
+  bool SwitchToBlockAckIfNeeded (Mac48Address recipient, uint8_t tid, uint16_t startingSeq);
+private:
+  /**
+   * Checks if all packets, for which a block ack agreement was established or refreshed,
+   * have been transmitted. If yes, adds a pair in m_bAckReqs to indicate that 
+   * at next channel access a block ack request (for established agreement
+   * <i>recipient</i>,<i>tid</i>) is needed.
+   */
+  Ptr<Packet> ScheduleBlockAckReqIfNeeded (Mac48Address recipient, uint8_t tid);
+  /**
+   * This method removes packets whose lifetime was exceded.
+   */
+  void CleanupBuffers (void);
+  void InactivityTimeout (Mac48Address, uint8_t);
+
+  struct Item;
+  typedef std::list<Item> PacketQueue;
+  typedef std::list<Item>::iterator PacketQueueI;
+  typedef std::list<Item>::const_iterator PacketQueueCI;
+  
+  typedef std::map<std::pair<Mac48Address, uint8_t>, 
+              std::pair<OriginatorBlockAckAgreement, PacketQueue> > Agreements;
+  typedef std::map<std::pair<Mac48Address, uint8_t>, 
+              std::pair<OriginatorBlockAckAgreement, PacketQueue> >::iterator AgreementsI;
+  typedef std::map<std::pair<Mac48Address, uint8_t>, 
+              std::pair<OriginatorBlockAckAgreement, PacketQueue> >::const_iterator AgreementsCI;
+
+  struct Item {
+    Item ();
+    Item (Ptr<const Packet> packet,
+          const WifiMacHeader &hdr,
+          Time tStamp);
+    Ptr<const Packet> packet;
+    WifiMacHeader hdr;
+    Time timestamp;
+  };
+  
+  /**
+   * This data structure contains, for each block ack agreement (recipient, tid), a set of packets
+   * for which an ack by block ack is requested.
+   * Every packet or fragment indicated as correctly received in block ack frame is 
+   * erased from this data structure. Pushed back in retransmission queue otherwise.
+   */
+  Agreements m_agreements;
+  /**
+   * This list contains all iterators to stored packets that need to be retransmitted.
+   * A packet needs retransmission if it's indicated as not correctly recevied in a block ack
+   * frame.
+   */
+  std::list<PacketQueueI> m_retryPackets;
+  std::list<Bar> m_bars;
+  
+  uint8_t m_blockAckThreshold;
+  enum BlockAckType m_blockAckType;
+  Time m_maxDelay;
+  MacTxMiddle* m_txMiddle;
+  Mac48Address m_address;
+  Ptr<WifiMacQueue> m_queue;
+  Callback<void, Mac48Address, uint8_t, bool> m_blockAckInactivityTimeout;
+  Callback<void, Mac48Address, uint8_t> m_blockPackets;
+  Callback<void, Mac48Address, uint8_t> m_unblockPackets;
+};
+
+} //namespace ns3
+
+#endif /* BLOCK_ACK_MANAGER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/block-ack-test-suite.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,214 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * 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: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#include "ns3/test.h"
+#include "ns3/log.h"
+#include "qos-utils.h"
+#include <list>
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("BlockAckTest");
+/**
+ * This simple test verifies the correctness of buffering for packets received
+ * under block ack. In order to completely understand this example is important to cite
+ * section 9.10.3 in IEEE802.11 standard:
+ *
+ * "[...] The sequence number space is considered divided into two parts, one of which
+ * is “old” and one of which is “new” by means of a boundary created by adding half the
+ * sequence number range to the current start of receive window (modulo 2^12)."
+ */
+//-------------------------------------------------------------------------------------
+
+/* ----- = old packets
+ * +++++ = new packets
+ *  
+ *  CASE A: startSeq < endSeq  
+ *                        -  -   +
+ *  initial buffer state: 0 16 56000
+ *
+ * 
+ *    0                            4095
+ *    |------|++++++++++++++++|-----|
+ *           ^                ^
+ *           | startSeq       | endSeq = 4000
+ *
+ *  first received packet's sequence control = 64016 (seqNum = 4001, fragNum = 0) -
+ *  second received packet's sequence control = 63984 (seqNum = 3999, fragNum = 0) +
+ *  4001 is older seq number so this packet should be inserted at the buffer's begin.
+ *  3999 is previous element of older of new packets: it should be inserted at the end of buffer.
+ *  
+ *  expected buffer state: 64016 0 16 56000 63984
+ *
+ */
+class PacketBufferingCaseA : public TestCase
+{
+public:
+  PacketBufferingCaseA ();
+  virtual ~PacketBufferingCaseA ();
+private:
+  virtual bool DoRun (void);
+  std::list<uint16_t> m_expectedBuffer;
+};
+
+PacketBufferingCaseA::PacketBufferingCaseA ()
+  : TestCase ("Check correct order of buffering when startSequence < endSeq")
+{
+  m_expectedBuffer.push_back (64016);
+  m_expectedBuffer.push_back (0);
+  m_expectedBuffer.push_back (16);
+  m_expectedBuffer.push_back (56000);
+  m_expectedBuffer.push_back (63984);
+}
+
+PacketBufferingCaseA::~PacketBufferingCaseA ()
+{}
+
+bool
+PacketBufferingCaseA::DoRun (void)
+{
+  std::list<uint16_t> m_buffer;
+  std::list<uint16_t>::iterator i,j;
+  m_buffer.push_back (0);
+  m_buffer.push_back (16);
+  m_buffer.push_back (56000);
+
+  uint16_t endSeq = 4000;
+  
+  uint16_t receivedSeq = 4001 * 16;
+  uint32_t mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
+  for (i = m_buffer.begin (); i != m_buffer.end () && QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) < mappedSeq; i++);
+    {
+      m_buffer.insert (i, receivedSeq);
+    }
+  
+  receivedSeq = 3999 * 16;
+  mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
+  for (i = m_buffer.begin (); i != m_buffer.end () && QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) < mappedSeq; i++);
+    {
+      m_buffer.insert (i, receivedSeq);
+    }
+
+  for (i = m_buffer.begin (), j = m_expectedBuffer.begin (); i != m_buffer.end (); i++, j++)
+    {
+      NS_TEST_EXPECT_MSG_EQ (*i, *j, "error in buffer order");
+    }
+  return GetErrorStatus ();
+}
+
+/* ----- = old packets
+ * +++++ = new packets
+ *  
+ *  CASE B: startSeq > endSeq
+ *                         -    +    +
+ *  initial buffer state: 256 64000 16
+ *
+ *
+ *    0                            4095
+ *    |++++++|----------------|++++++|
+ *           ^                ^
+ *           | endSeq = 10    | startSeq
+ *
+ *  first received packet's sequence control = 240 (seqNum = 15, fragNum = 0)  -
+ *  second received packet's sequence control = 241 (seqNum = 15, fragNum = 1) -
+ *  third received packet's sequence control = 64800 (seqNum = 4050, fragNum = 0) +
+ *  240 is an old packet should be inserted at the buffer's begin.
+ *  241 is an old packet: second segment of the above packet.
+ *  4050 is a new packet: it should be inserted between 64000 and 16.
+ *  
+ *  expected buffer state: 240 241 256 64000 64800 16
+ *
+ */
+class PacketBufferingCaseB : public TestCase
+{
+public:
+  PacketBufferingCaseB ();
+  virtual ~PacketBufferingCaseB ();
+private:
+  virtual bool DoRun (void);
+  std::list<uint16_t> m_expectedBuffer;
+};
+
+PacketBufferingCaseB::PacketBufferingCaseB ()
+  : TestCase ("Check correct order of buffering when startSequence > endSeq")
+{
+  m_expectedBuffer.push_back (240);
+  m_expectedBuffer.push_back (241);
+  m_expectedBuffer.push_back (256);
+  m_expectedBuffer.push_back (64000);
+  m_expectedBuffer.push_back (64800);
+  m_expectedBuffer.push_back (16);
+}
+
+PacketBufferingCaseB::~PacketBufferingCaseB ()
+{}
+
+bool
+PacketBufferingCaseB::DoRun (void)
+{
+  std::list<uint16_t> m_buffer;
+  std::list<uint16_t>::iterator i,j;
+  m_buffer.push_back (256);
+  m_buffer.push_back (64000);
+  m_buffer.push_back (16);
+
+  uint16_t endSeq = 10;
+
+  uint16_t receivedSeq = 15 * 16;
+  uint32_t mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
+  for (i = m_buffer.begin (); i != m_buffer.end () && QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) < mappedSeq; i++);
+    {
+      m_buffer.insert (i, receivedSeq);
+    }
+
+  receivedSeq = 15 * 16 + 1;
+  mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
+  for (i = m_buffer.begin (); i != m_buffer.end () && QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) < mappedSeq; i++);
+    {
+      m_buffer.insert (i, receivedSeq);
+    }
+
+  receivedSeq = 4050 * 16;
+  mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
+  for (i = m_buffer.begin (); i != m_buffer.end () && QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) < mappedSeq; i++);
+    {
+      m_buffer.insert (i, receivedSeq);
+    }
+
+  for (i = m_buffer.begin (), j = m_expectedBuffer.begin (); i != m_buffer.end (); i++, j++)
+    {
+      NS_TEST_EXPECT_MSG_EQ (*i, *j, "error in buffer order");
+    }
+  return GetErrorStatus ();
+}
+
+class BlockAckTestSuite : public TestSuite
+{
+public:
+  BlockAckTestSuite ();
+};
+
+BlockAckTestSuite::BlockAckTestSuite ()
+  : TestSuite ("wifi-block-ack", UNIT)
+{
+  AddTestCase (new PacketBufferingCaseA);
+  AddTestCase (new PacketBufferingCaseB);
+}
+
+BlockAckTestSuite g_blockAckTestSuite;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/ctrl-headers.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,681 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * 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: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#include "ns3/fatal-error.h"
+
+#include "ctrl-headers.h"
+
+namespace ns3 {
+
+/***********************************
+ *       Block ack request
+ ***********************************/
+
+NS_OBJECT_ENSURE_REGISTERED (CtrlBAckRequestHeader);
+
+CtrlBAckRequestHeader::CtrlBAckRequestHeader ()
+  : m_barAckPolicy (false),
+    m_multiTid (false),
+    m_compressed (false)
+{}
+
+CtrlBAckRequestHeader::~CtrlBAckRequestHeader ()
+{}
+
+TypeId
+CtrlBAckRequestHeader::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::CtrlBAckRequestHeader")
+    .SetParent<Header> ()
+    .AddConstructor<CtrlBAckRequestHeader> ()
+  ;
+  return tid;
+}
+
+TypeId
+CtrlBAckRequestHeader::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+void
+CtrlBAckRequestHeader::Print (std::ostream &os) const
+{
+  os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq;
+}
+
+uint32_t
+CtrlBAckRequestHeader::GetSerializedSize () const
+{
+  uint32_t size = 0;
+  size += 2; //Bar control
+  if (!m_multiTid)
+    {
+      size += 2; //Starting sequence control
+    }
+  else
+    {
+      if (m_compressed)
+        {
+          size += (2 + 2) * (m_tidInfo + 1);  //Multi-tid block ack
+        }
+      else
+        {
+          NS_FATAL_ERROR ("Reserved configuration.");
+        }
+    }
+  return size;
+}
+
+void
+CtrlBAckRequestHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+  i.WriteHtolsbU16 (GetBarControl ());
+  if (!m_multiTid)
+    {
+      i.WriteHtolsbU16 (GetStartingSequenceControl ());
+    }
+  else
+    {
+      if (m_compressed)
+        {
+          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+        }
+      else
+        {
+          NS_FATAL_ERROR ("Reserved configuration.");
+        }
+    }
+}
+
+uint32_t
+CtrlBAckRequestHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  SetBarControl (i.ReadLsbtohU16 ());
+  if (!m_multiTid)
+    {
+      SetStartingSequenceControl (i.ReadLsbtohU16 ());
+    }
+  else
+    {
+      if (m_compressed)
+        {
+          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+        }
+      else
+        {
+          NS_FATAL_ERROR ("Reserved configuration.");
+        }
+    }
+  return i.GetDistanceFrom (start);
+} 
+
+uint16_t
+CtrlBAckRequestHeader::GetBarControl (void) const
+{
+  uint16_t res = 0;
+  if (m_barAckPolicy)
+    {
+      res |= 0x1;
+    }
+  if (m_multiTid)
+    {
+      res |= (0x1<<1);
+    }
+  if (m_compressed)
+    {
+      res |= (0x1<<2);
+    }
+  res |= (m_tidInfo << 12) & (0xf<<12);
+  return res;
+}
+
+void
+CtrlBAckRequestHeader::SetBarControl (uint16_t bar)
+{
+  m_barAckPolicy = ((bar & 0x01) == 1)?true:false;
+  m_multiTid = (((bar >> 1) & 0x01) == 1)?true:false;
+  m_compressed = (((bar >> 2) & 0x01) == 1)?true:false;
+  m_tidInfo = (bar >> 12) & 0x0f;
+}
+
+uint16_t
+CtrlBAckRequestHeader::GetStartingSequenceControl (void) const
+{
+  return (m_startingSeq << 4) & 0xfff0;
+}
+
+void
+CtrlBAckRequestHeader::SetStartingSequenceControl (uint16_t seqControl)
+{
+  m_startingSeq = (seqControl >> 4) & 0x0fff;
+}
+
+void
+CtrlBAckRequestHeader::SetHtImmediateAck (bool immediateAck)
+{
+  m_barAckPolicy = immediateAck;
+}
+
+void
+CtrlBAckRequestHeader::SetType (enum BlockAckType type)
+{
+  switch (type) {
+    case BASIC_BLOCK_ACK:
+      m_multiTid = false;
+      m_compressed = false;
+      break;
+    case COMPRESSED_BLOCK_ACK:
+      m_multiTid = false;
+      m_compressed = true;
+      break;
+    case MULTI_TID_BLOCK_ACK:
+      m_multiTid = true;
+      m_compressed = true;
+      break;
+    default:
+      NS_FATAL_ERROR ("Invalid variant type");
+      break;
+  }
+}
+
+void
+CtrlBAckRequestHeader::SetTidInfo (uint8_t tid)
+{
+  m_tidInfo = static_cast<uint16_t> (tid);
+}
+
+void
+CtrlBAckRequestHeader::SetStartingSequence (uint16_t seq)
+{
+  m_startingSeq = seq;
+}
+
+bool
+CtrlBAckRequestHeader::MustSendHtImmediateAck (void) const
+{
+  return m_barAckPolicy;
+}
+
+uint8_t
+CtrlBAckRequestHeader::GetTidInfo (void) const
+{
+  uint8_t tid = static_cast<uint8_t> (m_tidInfo);
+  return tid;
+}
+
+uint16_t
+CtrlBAckRequestHeader::GetStartingSequence (void) const
+{
+  return m_startingSeq;
+}
+
+bool
+CtrlBAckRequestHeader::IsBasic (void) const
+{
+  return (!m_multiTid && !m_compressed)?true:false;
+}
+
+bool
+CtrlBAckRequestHeader::IsCompressed (void) const
+{
+  return (!m_multiTid && m_compressed)?true:false;
+}
+
+bool
+CtrlBAckRequestHeader::IsMultiTid (void) const
+{
+  return (m_multiTid && m_compressed)?true:false;
+}
+
+/***********************************
+ *       Block ack response
+ ***********************************/
+
+NS_OBJECT_ENSURE_REGISTERED (CtrlBAckResponseHeader);
+
+CtrlBAckResponseHeader::CtrlBAckResponseHeader ()
+  : m_baAckPolicy (false),
+    m_multiTid (false),
+    m_compressed (false)
+{
+  memset (&bitmap, 0, sizeof (bitmap));
+}
+
+CtrlBAckResponseHeader::~CtrlBAckResponseHeader ()
+{}
+
+TypeId
+CtrlBAckResponseHeader::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::CtrlBAckResponseHeader")
+    .SetParent<Header> ()
+    .AddConstructor<CtrlBAckResponseHeader> ()
+  ;
+  return tid; 
+}
+
+TypeId
+CtrlBAckResponseHeader::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+void
+CtrlBAckResponseHeader::Print (std::ostream &os) const
+{
+  os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq;
+}
+
+uint32_t
+CtrlBAckResponseHeader::GetSerializedSize (void) const
+{
+  uint32_t size = 0;
+  size += 2; //Bar control
+  if (!m_multiTid)
+    {
+      if (!m_compressed)
+        {
+          size += (2 + 128); //Basic block ack
+        }
+      else
+        {
+          size += (2 + 8); //Compressed block ack
+        }
+    }
+  else
+    {
+      if (m_compressed)
+        {
+          size += (2 + 2 + 8) * (m_tidInfo + 1); //Multi-tid block ack
+        }
+      else
+        {
+          NS_FATAL_ERROR ("Reserved configuration.");
+        }
+    }
+  return size;
+}
+
+void
+CtrlBAckResponseHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+  i.WriteHtolsbU16 (GetBaControl ());
+  if (!m_multiTid)
+    {
+      i.WriteHtolsbU16 (GetStartingSequenceControl ());
+      i = SerializeBitmap (i);
+    }
+  else
+    {
+      if (m_compressed)
+        {
+          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+        }
+      else
+        {
+          NS_FATAL_ERROR ("Reserved configuration.");
+        }
+    }
+}
+
+uint32_t
+CtrlBAckResponseHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  SetBaControl (i.ReadLsbtohU16 ());
+  if (!m_multiTid)
+    {
+      SetStartingSequenceControl (i.ReadLsbtohU16 ());
+      i = DeserializeBitmap (i);
+    }
+  else
+    {
+      if (m_compressed)
+        {
+          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+        }
+      else
+        {
+          NS_FATAL_ERROR ("Reserved configuration.");
+        }
+    }
+  return i.GetDistanceFrom (start);
+}
+
+void
+CtrlBAckResponseHeader::SetHtImmediateAck (bool immediateAck)
+{
+  m_baAckPolicy = immediateAck;
+}
+
+void
+CtrlBAckResponseHeader::SetType (enum BlockAckType type)
+{
+  switch (type) {
+    case BASIC_BLOCK_ACK:
+      m_multiTid = false;
+      m_compressed = false;
+      break;
+    case COMPRESSED_BLOCK_ACK:
+      m_multiTid = false;
+      m_compressed = true;
+      break;
+    case MULTI_TID_BLOCK_ACK:
+      m_multiTid = true;
+      m_compressed = true;
+      break;
+    default:
+      NS_FATAL_ERROR ("Invalid variant type");
+      break;
+  }
+}
+
+void
+CtrlBAckResponseHeader::SetTidInfo (uint8_t tid)
+{
+  m_tidInfo = static_cast<uint16_t> (tid);
+}
+
+void
+CtrlBAckResponseHeader::SetStartingSequence (uint16_t seq)
+{
+  m_startingSeq = seq;
+}
+
+bool
+CtrlBAckResponseHeader::MustSendHtImmediateAck (void) const
+{
+  return (m_baAckPolicy)?true:false;
+}
+
+uint8_t
+CtrlBAckResponseHeader::GetTidInfo (void) const
+{
+  uint8_t tid = static_cast<uint8_t> (m_tidInfo);
+  return tid;
+}
+
+uint16_t
+CtrlBAckResponseHeader::GetStartingSequence (void) const
+{
+  return m_startingSeq;
+}
+
+bool
+CtrlBAckResponseHeader::IsBasic (void) const
+{
+  return (!m_multiTid && !m_compressed)?true:false;
+}
+
+bool
+CtrlBAckResponseHeader::IsCompressed (void) const
+{
+  return (!m_multiTid && m_compressed)?true:false;
+}
+
+bool
+CtrlBAckResponseHeader::IsMultiTid (void) const
+{
+  return (m_multiTid && m_compressed)?true:false;
+}
+
+uint16_t
+CtrlBAckResponseHeader::GetBaControl (void) const
+{
+  uint16_t res = 0;
+  if (m_baAckPolicy) 
+    {
+      res |= 0x1;
+    }
+  if (m_multiTid)
+    {
+      res |= (0x1<<1);
+    }
+  if (m_compressed)
+    {
+      res |= (0x1<<2);
+    }
+  res |= (m_tidInfo << 12) & (0xf<<12);
+  return res;
+}
+
+void
+CtrlBAckResponseHeader::SetBaControl (uint16_t ba)
+{
+  m_baAckPolicy = ((ba & 0x01) == 1)?true:false;
+  m_multiTid = (((ba >> 1) & 0x01) == 1)?true:false;
+  m_compressed = (((ba >> 2) & 0x01) == 1)?true:false;
+  m_tidInfo = (ba >> 12) & 0x0f;
+}
+
+uint16_t
+CtrlBAckResponseHeader::GetStartingSequenceControl (void) const
+{
+  return (m_startingSeq << 4) & 0xfff0;
+}
+
+void
+CtrlBAckResponseHeader::SetStartingSequenceControl (uint16_t seqControl)
+{
+  m_startingSeq = (seqControl >> 4) & 0x0fff;
+}
+
+Buffer::Iterator
+CtrlBAckResponseHeader::SerializeBitmap (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+  if (!m_multiTid)
+    {
+      if (!m_compressed)
+        {
+          for (uint32_t j = 0; j < 64; j++)
+            {
+              i.WriteHtolsbU16 (bitmap.m_bitmap[j]);
+            }
+        }
+      else
+        {
+          i.WriteHtolsbU64 (bitmap.m_compressedBitmap);
+        }
+    }
+  else
+    {
+      if (m_compressed)
+        {
+          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+        }
+      else
+        {
+          NS_FATAL_ERROR ("Reserved configuration.");
+        }
+    }
+  return i;
+}
+
+Buffer::Iterator
+CtrlBAckResponseHeader::DeserializeBitmap (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  if (!m_multiTid)
+    {
+      if (!m_compressed)
+        {
+          for (uint32_t j = 0; j < 64; j++)
+            {
+              bitmap.m_bitmap[j] = i.ReadLsbtohU16 ();
+            }
+        }
+      else
+        {
+          bitmap.m_compressedBitmap = i.ReadLsbtohU64 ();
+        }
+    }
+  else
+    {
+      if (m_compressed)
+        {
+          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+        }
+      else
+        {
+          NS_FATAL_ERROR ("Reserved configuration.");
+        }
+    }
+  return i;
+}
+
+void
+CtrlBAckResponseHeader::SetReceivedPacket (uint16_t seq)
+{
+  if (!m_multiTid)
+    {
+      if (!m_compressed)
+        {
+          /* To set correctly basic block ack bitmap we need fragment number too.
+             So if it's not specified, we consider packet not fragmented. */
+          bitmap.m_bitmap[IndexInBitmap (seq)] |= 0x0001;
+        }
+      else
+        {
+          bitmap.m_compressedBitmap |= (0x0000000000000001 << IndexInBitmap (seq));
+        }
+    }
+  else
+    {
+      if (m_compressed)
+        {
+          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+        }
+      else
+        {
+          NS_FATAL_ERROR ("Reserved configuration.");
+        }
+    }
+}
+
+void
+CtrlBAckResponseHeader::SetReceivedFragment (uint16_t seq, uint8_t frag)
+{
+  NS_ASSERT (frag < 16);
+  if (!m_multiTid)
+    {
+      if (!m_compressed)
+        {
+          bitmap.m_bitmap[IndexInBitmap (seq)] |= (0x0001<<frag);
+        }
+      else
+        {
+          /* We can ignore this...compressed block ack doesn't support
+             acknowledgement of single fragments */
+        }
+    }
+  else
+    {
+      if (m_compressed)
+        {
+          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+        }
+      else
+        {
+          NS_FATAL_ERROR ("Reserved configuration.");
+        }
+    }
+}
+
+bool
+CtrlBAckResponseHeader::IsPacketReceived (uint16_t seq) const
+{
+  if (!m_multiTid)
+    {
+      if (!m_compressed)
+        {
+          /*It's impossible to say if an entire packet was correctly received. */
+          return false; 
+        }
+      else
+        {
+          uint64_t mask = 0x0000000000000001;
+          return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1)?true:false;
+        }
+    }
+  else
+    {
+      if (m_compressed)
+        {
+          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+        }
+      else
+        {
+          NS_FATAL_ERROR ("Reserved configuration.");
+        }
+    }
+  return false;
+}
+
+bool
+CtrlBAckResponseHeader::IsFragmentReceived (uint16_t seq, uint8_t frag) const
+{
+  NS_ASSERT (frag < 16);
+  if (!m_multiTid)
+    {
+      if (!m_compressed)
+        {
+          return ((bitmap.m_bitmap[IndexInBitmap (seq)] & (0x0001<<frag)) != 0x0000)?true:false;
+        }
+      else
+        {
+          /* Although this could make no sense, if packet with sequence number
+             equal to <i>seq</i> was correctly received, also all of its fragments 
+             were correctly received. */
+          uint64_t mask = 0x0000000000000001;
+          return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1)?true:false;
+        }
+    }
+  else
+    {
+      if (m_compressed)
+        {
+          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+        }
+      else
+        {
+          NS_FATAL_ERROR ("Reserved configuration.");
+        }
+    }
+  return false;
+}
+
+uint8_t
+CtrlBAckResponseHeader::IndexInBitmap (uint16_t seq) const
+{
+  if (seq >= m_startingSeq)
+    {
+      return (seq - m_startingSeq);
+    }
+  else
+    {
+      return (4096 - m_startingSeq + seq);
+    }
+}
+
+}  //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/ctrl-headers.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,159 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * 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: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#ifndef CTRL_HEADERS_H
+#define CTRL_HEADERS_H
+
+#include "ns3/header.h"
+
+namespace ns3 {
+
+/** Headers for Block ack request and response.
+ *  802.11n standard includes three types of block ack:
+ *    - Basic block ack (unique type in 802.11e)
+ *    - Compressed block ack
+ *    - Multi-TID block ack
+ *  For now only basic block ack and compressed block ack 
+ *  are supported.
+ *  Basic block ack is also default variant.
+ */
+enum BlockAckType
+{
+  BASIC_BLOCK_ACK,
+  COMPRESSED_BLOCK_ACK,
+  MULTI_TID_BLOCK_ACK
+};
+
+class CtrlBAckRequestHeader : public Header {
+public:
+  CtrlBAckRequestHeader ();
+  ~CtrlBAckRequestHeader ();
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+  void SetHtImmediateAck (bool immediateAck);
+  void SetType (enum BlockAckType type);
+  void SetTidInfo (uint8_t tid);
+  void SetStartingSequence (uint16_t seq);
+
+  bool MustSendHtImmediateAck (void) const;
+  uint8_t GetTidInfo (void) const;
+  uint16_t GetStartingSequence (void) const;
+  bool IsBasic (void) const;
+  bool IsCompressed (void) const;
+  bool IsMultiTid (void) const;
+
+  uint16_t GetStartingSequenceControl (void) const;
+  
+private:
+  
+  void SetStartingSequenceControl (uint16_t seqControl);
+  uint16_t GetBarControl (void) const;
+  void SetBarControl (uint16_t bar);
+  
+  /**
+   * The lsb bit of the BAR control field is used only for the
+   * HT (High Throughput) delayed block ack configuration.
+   * For now only non HT immediate block ack is implemented so this field
+   * is here only for a future implementation of HT delayed variant.
+   */
+  bool m_barAckPolicy;
+  bool m_multiTid;
+  bool m_compressed;
+  uint16_t m_tidInfo;
+  uint16_t m_startingSeq;
+};
+
+class CtrlBAckResponseHeader : public Header {
+public:
+  CtrlBAckResponseHeader ();
+  ~CtrlBAckResponseHeader ();
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+  void SetHtImmediateAck (bool immeadiateAck);
+  void SetType (enum BlockAckType type);
+  void SetTidInfo (uint8_t tid);
+  void SetStartingSequence (uint16_t seq);
+
+  bool MustSendHtImmediateAck (void) const;
+  uint8_t GetTidInfo (void) const;
+  uint16_t GetStartingSequence (void) const;
+  bool IsBasic (void) const;
+  bool IsCompressed (void) const;
+  bool IsMultiTid (void) const;
+
+  void SetReceivedPacket (uint16_t seq);
+  void SetReceivedFragment (uint16_t seq, uint8_t frag);
+  bool IsPacketReceived (uint16_t seq) const;
+  bool IsFragmentReceived (uint16_t seq, uint8_t frag) const;
+
+  uint16_t GetStartingSequenceControl (void) const;
+  void SetStartingSequenceControl (uint16_t seqControl);
+  
+private:
+  
+  uint16_t GetBaControl (void) const;
+  void SetBaControl (uint16_t bar);
+  
+  Buffer::Iterator SerializeBitmap (Buffer::Iterator start) const;
+  Buffer::Iterator DeserializeBitmap (Buffer::Iterator start);
+
+  /**
+   * This function is used to correctly index in both bitmap
+   * and compressed bitmap, one bit or one block of 16 bits respectly.
+   * If we are using basic block ack, return value represents index of 
+   * block of 16 bits for packet having sequence number equals to <i>seq</i>.
+   * If we are using compressed block ack, return value represents bit 
+   * to set to 1 in the compressed bitmap to indicate that packet having 
+   * sequence number equals to <i>seq</i> was correctly received.
+   *
+   * for more details see 7.2.1.8 in IEEE 802.11n/D4.00
+   */
+  uint8_t IndexInBitmap (uint16_t seq) const;
+
+  /**
+   * The lsb bit of the BA control field is used only for the
+   * HT (High Throughput) delayed block ack configuration.
+   * For now only non HT immediate block ack is implemented so this field
+   * is here only for a future implementation of HT delayed variant.
+   */
+  bool m_baAckPolicy;
+  bool m_multiTid;
+  bool m_compressed;
+  uint16_t m_tidInfo;
+  uint16_t m_startingSeq;
+
+  union {
+    uint16_t m_bitmap[64];
+    uint64_t m_compressedBitmap;
+  } bitmap;
+};
+
+} //namespace ns3
+
+#endif /* CTRL_HEADERS_H */
--- a/src/devices/wifi/dca-txop.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/dca-txop.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -36,9 +36,8 @@
 
 NS_LOG_COMPONENT_DEFINE ("DcaTxop");
 
-#define MY_DEBUG(x) \
-  NS_LOG_DEBUG (m_low->GetAddress () << " " << x)
-
+#undef NS_LOG_APPEND_CONTEXT
+#define NS_LOG_APPEND_CONTEXT if (m_low != 0) {std::clog << "[mac=" << m_low->GetAddress () << "] ";}
 
 namespace ns3 {
 
@@ -263,10 +262,10 @@
 }
 
 bool
-DcaTxop::NeedRts (void)
+DcaTxop::NeedRts (Ptr<const Packet> packet, const WifiMacHeader *header)
 {
-  return m_stationManager->NeedRts (m_currentHdr.GetAddr1 (), &m_currentHdr,
-                                    m_currentPacket);
+  return m_stationManager->NeedRts (header->GetAddr1 (), header,
+                                    packet);
 }
 
 bool
@@ -355,7 +354,7 @@
     {
       if (m_queue->IsEmpty ()) 
         {
-          MY_DEBUG ("queue empty");
+          NS_LOG_DEBUG ("queue empty");
           return;
         }
       m_currentPacket = m_queue->Dequeue (&m_currentHdr);
@@ -366,7 +365,7 @@
       m_currentHdr.SetNoMoreFragments ();
       m_currentHdr.SetNoRetry ();
       m_fragmentNumber = 0;
-      MY_DEBUG ("dequeued size="<<m_currentPacket->GetSize ()<<
+      NS_LOG_DEBUG ("dequeued size="<<m_currentPacket->GetSize ()<<
                     ", to="<<m_currentHdr.GetAddr1 ()<<
                     ", seq="<<m_currentHdr.GetSequenceControl ()); 
     }
@@ -385,7 +384,7 @@
       m_dcf->ResetCw ();
       m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
       StartAccessIfNeeded ();
-      MY_DEBUG ("tx broadcast");
+      NS_LOG_DEBUG ("tx broadcast");
     } 
   else 
     {
@@ -393,17 +392,24 @@
       
       if (NeedFragmentation ()) 
         {
-          params.DisableRts ();
           WifiMacHeader hdr;
           Ptr<Packet> fragment = GetFragmentPacket (&hdr);
+          if (NeedRts (fragment, &hdr))
+            {
+              params.EnableRts ();
+            }
+          else
+            {
+              params.DisableRts ();
+            }
           if (IsLastFragment ()) 
             {
-              MY_DEBUG ("fragmenting last fragment size="<<fragment->GetSize ());
+              NS_LOG_DEBUG ("fragmenting last fragment size="<<fragment->GetSize ());
               params.DisableNextData ();
             } 
           else 
             {
-              MY_DEBUG ("fragmenting size="<<fragment->GetSize ());
+              NS_LOG_DEBUG ("fragmenting size="<<fragment->GetSize ());
               params.EnableNextData (GetNextFragmentSize ());
             }
           Low ()->StartTransmission (fragment, &hdr, params, 
@@ -411,15 +417,15 @@
         } 
       else 
         {
-          if (NeedRts ()) 
+          if (NeedRts (m_currentPacket, &m_currentHdr)) 
             {
               params.EnableRts ();
-              MY_DEBUG ("tx unicast rts");
+              NS_LOG_DEBUG ("tx unicast rts");
             } 
           else 
             {
               params.DisableRts ();
-              MY_DEBUG ("tx unicast");
+              NS_LOG_DEBUG ("tx unicast");
             }
           params.DisableNextData ();
           Low ()->StartTransmission (m_currentPacket, &m_currentHdr,
@@ -438,7 +444,7 @@
 DcaTxop::NotifyCollision (void)
 {
   NS_LOG_FUNCTION (this);
-  MY_DEBUG ("collision");
+  NS_LOG_DEBUG ("collision");
   m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
   RestartAccessIfNeeded ();
 }
@@ -454,16 +460,16 @@
 DcaTxop::GotCts (double snr, WifiMode txMode)
 {
   NS_LOG_FUNCTION (this << snr << txMode);
-  MY_DEBUG ("got cts");
+  NS_LOG_DEBUG ("got cts");
 }
 void 
 DcaTxop::MissedCts (void)
 {
   NS_LOG_FUNCTION (this);
-  MY_DEBUG ("missed cts");
+  NS_LOG_DEBUG ("missed cts");
   if (!NeedRtsRetransmission ())
     {
-      MY_DEBUG ("Cts Fail");
+      NS_LOG_DEBUG ("Cts Fail");
       m_stationManager->ReportFinalRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
       if (!m_txFailedCallback.IsNull ()) 
         {
@@ -487,7 +493,7 @@
   if (!NeedFragmentation () ||
       IsLastFragment ()) 
     {
-      MY_DEBUG ("got ack. tx done.");
+      NS_LOG_DEBUG ("got ack. tx done.");
       if (!m_txOkCallback.IsNull ()) 
         {
           m_txOkCallback (m_currentHdr);
@@ -503,17 +509,17 @@
     } 
   else 
     {
-      MY_DEBUG ("got ack. tx not done, size="<<m_currentPacket->GetSize ());
+      NS_LOG_DEBUG ("got ack. tx not done, size="<<m_currentPacket->GetSize ());
     }
 }
 void 
 DcaTxop::MissedAck (void)
 {
   NS_LOG_FUNCTION (this);
-  MY_DEBUG ("missed ack");
+  NS_LOG_DEBUG ("missed ack");
   if (!NeedDataRetransmission ()) 
     {
-      MY_DEBUG ("Ack Fail");
+      NS_LOG_DEBUG ("Ack Fail");
       m_stationManager->ReportFinalDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
       if (!m_txFailedCallback.IsNull ()) 
         {
@@ -525,7 +531,7 @@
     } 
   else 
     {
-      MY_DEBUG ("Retransmit");
+      NS_LOG_DEBUG ("Retransmit");
       m_currentHdr.SetRetry ();
       m_dcf->UpdateFailedCw ();
     }
@@ -536,7 +542,7 @@
 DcaTxop::StartNext (void)
 {
   NS_LOG_FUNCTION (this);
-  MY_DEBUG ("start next packet fragment");
+  NS_LOG_DEBUG ("start next packet fragment");
   /* this callback is used only for fragments. */
   NextFragment ();
   WifiMacHeader hdr;
@@ -560,7 +566,7 @@
 DcaTxop::Cancel (void)
 {
   NS_LOG_FUNCTION (this);
-  MY_DEBUG ("transmission cancelled");
+  NS_LOG_DEBUG ("transmission cancelled");
   /**
    * This happens in only one case: in an AP, you have two DcaTxop:
    *   - one is used exclusively for beacons and has a high priority.
--- a/src/devices/wifi/dca-txop.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/dca-txop.h	Thu Feb 25 14:17:21 2010 +0100
@@ -141,7 +141,7 @@
 
   void RestartAccessIfNeeded (void);
   void StartAccessIfNeeded (void);
-  bool NeedRts (void);
+  bool NeedRts (Ptr<const Packet> packet, const WifiMacHeader *header);
   bool NeedRtsRetransmission (void);
   bool NeedDataRetransmission (void);
   bool NeedFragmentation (void);
--- a/src/devices/wifi/edca-txop-n.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/edca-txop-n.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -31,11 +31,14 @@
 #include "random-stream.h"
 #include "wifi-mac-queue.h"
 #include "msdu-aggregator.h"
+#include "mgt-headers.h"
+#include "qos-blocked-destinations.h"
+#include "block-ack-manager.h"
 
 NS_LOG_COMPONENT_DEFINE ("EdcaTxopN");
 
-#define MY_DEBUG(x) \
-  NS_LOG_DEBUG (m_low->GetAddress () << " " << x)
+#undef NS_LOG_APPEND_CONTEXT
+#define NS_LOG_APPEND_CONTEXT if (m_low != 0) {std::clog << "[mac=" << m_low->GetAddress () << "] ";}
 
 namespace ns3 {
 
@@ -82,6 +85,12 @@
   virtual void MissedAck (void) {
     m_txop->MissedAck ();
   }
+  virtual void GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address source) {
+    m_txop->GotBlockAck (blockAck, source);
+  }
+  virtual void MissedBlockAck (void) {
+    m_txop->MissedBlockAck ();
+  }
   virtual void StartNext (void) {
     m_txop->StartNext ();
   }
@@ -93,6 +102,22 @@
   EdcaTxopN *m_txop;
 };
 
+class EdcaTxopN::BlockAckEventListener : public MacLowBlockAckEventListener
+{
+public:
+  BlockAckEventListener (EdcaTxopN *txop)
+    : MacLowBlockAckEventListener (),
+      m_txop (txop) {}
+  virtual ~BlockAckEventListener () {}
+
+  virtual void BlockAckInactivityTimeout (Mac48Address address, uint8_t tid) {
+    m_txop->SendDelbaFrame (address, tid, false);
+  }
+
+private:
+  EdcaTxopN *m_txop;
+};
+
 NS_OBJECT_ENSURE_REGISTERED (EdcaTxopN);
 
 TypeId
@@ -101,6 +126,19 @@
   static TypeId tid = TypeId ("ns3::EdcaTxopN")
     .SetParent<Object> ()
     .AddConstructor<EdcaTxopN> ()
+    .AddAttribute ("BlockAckThreshold", "If number of packets in this queue reaches this value,\
+                                         block ack mechanism is used. If this value is 0, block ack is never used.",
+                   UintegerValue(0),
+                   MakeUintegerAccessor (&EdcaTxopN::SetBlockAckThreshold,
+                                         &EdcaTxopN::GetBlockAckThreshold),
+                   MakeUintegerChecker<uint8_t> (0, 64))
+    .AddAttribute ("BlockAckInactivityTimeout", "Represents max time (blocks of 1024 micro seconds) allowed for block ack\
+                                                 inactivity. If this value isn't equal to 0 a timer start after that a\
+                                                 block ack setup is completed and will be reset every time that a block\
+                                                 ack frame is received. If this value is 0, block ack inactivity timeout won't be used.",
+                   UintegerValue(0),
+                   MakeUintegerAccessor (&EdcaTxopN::m_blockAckInactivityTimeout),
+                   MakeUintegerChecker<uint16_t> ())
     ;
   return tid;
 }
@@ -108,13 +146,22 @@
 EdcaTxopN::EdcaTxopN ()
   : m_manager (0),
     m_currentPacket(0),
-    m_aggregator (0)
+    m_aggregator (0),
+    m_blockAckType (COMPRESSED_BLOCK_ACK)
 {
   NS_LOG_FUNCTION (this);
   m_transmissionListener = new EdcaTxopN::TransmissionListener (this);
+  m_blockAckListener = new EdcaTxopN::BlockAckEventListener (this);
   m_dcf = new EdcaTxopN::Dcf (this);
   m_queue = CreateObject<WifiMacQueue> ();
   m_rng = new RealRandomStream ();
+  m_qosBlockedDestinations = new QosBlockedDestinations ();
+  m_baManager = new BlockAckManager ();
+  m_baManager->SetQueue (m_queue);
+  m_baManager->SetBlockAckType (m_blockAckType);
+  m_baManager->SetBlockDestinationCallback (MakeCallback (&QosBlockedDestinations::Block, m_qosBlockedDestinations));
+  m_baManager->SetUnblockDestinationCallback (MakeCallback (&QosBlockedDestinations::Unblock, m_qosBlockedDestinations));
+  m_baManager->SetMaxPacketDelay (m_queue->GetMaxDelay ());
 }
 
 EdcaTxopN::~EdcaTxopN ()
@@ -132,9 +179,15 @@
   delete m_transmissionListener;
   delete m_dcf;
   delete m_rng;
+  delete m_qosBlockedDestinations;
+  delete m_baManager;
+  delete m_blockAckListener;
   m_transmissionListener = 0;
   m_dcf = 0;
   m_rng = 0;
+  m_qosBlockedDestinations = 0;
+  m_baManager = 0;
+  m_blockAckListener = 0;
   m_txMiddle = 0;
   m_aggregator = 0;
 }
@@ -253,7 +306,7 @@
 bool
 EdcaTxopN::NeedsAccess (void) const
 {
-  return !m_queue->IsEmpty () || m_currentPacket != 0;
+  return !m_queue->IsEmpty () || m_currentPacket != 0 || m_baManager->HasPackets ();
 }
 
 void
@@ -262,23 +315,50 @@
   NS_LOG_FUNCTION (this);
   if (m_currentPacket == 0)
     {
-      if (m_queue->IsEmpty ())
+      if (m_queue->IsEmpty () && !m_baManager->HasPackets ())
         {
-          MY_DEBUG ("queue is empty");
+          NS_LOG_DEBUG ("queue is empty");
           return; 
         }
-      m_currentPacket = m_queue->Dequeue (&m_currentHdr);
-      NS_ASSERT (m_currentPacket != 0);
-      
-      uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr);
-      m_currentHdr.SetSequenceNumber (sequence);
-      m_currentHdr.SetFragmentNumber (0);
-      m_currentHdr.SetNoMoreFragments ();
-      m_currentHdr.SetNoRetry ();
-      m_fragmentNumber = 0;
-      MY_DEBUG ("dequeued size="<<m_currentPacket->GetSize ()<<
-                ", to="<<m_currentHdr.GetAddr1 ()<<
-                ", seq="<<m_currentHdr.GetSequenceControl ());
+      struct Bar bar;
+      if (m_baManager->HasBar (bar))
+        {
+          SendBlockAckRequest (bar);
+          return;
+        }
+      /* check if packets need retransmission are stored in BlockAckManager */
+      m_currentPacket = m_baManager->GetNextPacket (m_currentHdr);
+      if (m_currentPacket == 0)
+        {
+          if (m_queue->PeekFirstAvailable (&m_currentHdr, m_currentPacketTimestamp, m_qosBlockedDestinations) == 0)
+            {
+              NS_LOG_DEBUG ("no available packets in the queue");
+              return;
+            }
+          if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast () &&
+              m_blockAckThreshold > 0 &&
+              !m_baManager->ExistsAgreement (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ()) &&
+              SetupBlockAckIfNeeded ())
+            {
+              return;
+            }
+          m_currentPacket = m_queue->DequeueFirstAvailable (&m_currentHdr, m_currentPacketTimestamp, m_qosBlockedDestinations);
+          NS_ASSERT (m_currentPacket != 0);
+          
+          uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr);
+          m_currentHdr.SetSequenceNumber (sequence);
+          m_currentHdr.SetFragmentNumber (0);
+          m_currentHdr.SetNoMoreFragments ();
+          m_currentHdr.SetNoRetry ();
+          m_fragmentNumber = 0;
+          NS_LOG_DEBUG ("dequeued size="<<m_currentPacket->GetSize ()<<
+                    ", to="<<m_currentHdr.GetAddr1 ()<<
+                    ", seq="<<m_currentHdr.GetSequenceControl ());
+          if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast ())
+            {
+              VerifyBlockAck ();
+            }
+        }
     }
   MacLowTransmissionParameters params;
   params.DisableOverrideDurationId ();
@@ -288,38 +368,48 @@
       params.DisableAck ();
       params.DisableNextData ();
       m_low->StartTransmission (m_currentPacket,
-                                 &m_currentHdr,
-                                 params,
-                                 m_transmissionListener);
+                                &m_currentHdr,
+                                params,
+                                m_transmissionListener);
       
       m_currentPacket = 0;
       m_dcf->ResetCw ();
       m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
       StartAccessIfNeeded ();
-      MY_DEBUG ("tx broadcast");
+      NS_LOG_DEBUG ("tx broadcast");
     }
   else
     {
-      params.EnableAck ();
-      if (NeedFragmentation () && ((m_currentHdr.IsQosData () &&
-                                    !m_currentHdr.IsQosAmsdu ()) ||
-                                    m_currentHdr.IsData ()))
+      if (m_currentHdr.IsQosData () && m_currentHdr.IsQosBlockAck ())
+        {
+          params.DisableAck ();
+        }
+      else
         {
+          params.EnableAck ();
+        }
+      if (NeedFragmentation () && ((m_currentHdr.IsQosData () && 
+                                   !m_currentHdr.IsQosAmsdu ()) ||
+                                   m_currentHdr.IsData ()) &&
+                                  (m_blockAckThreshold == 0 ||
+                                   m_blockAckType == BASIC_BLOCK_ACK))
+        {
+          //With COMPRESSED_BLOCK_ACK fragmentation must be avoided.
           params.DisableRts ();
           WifiMacHeader hdr;
           Ptr<Packet> fragment = GetFragmentPacket (&hdr);
           if (IsLastFragment ()) 
             {
-              MY_DEBUG ("fragmenting last fragment size=" << fragment->GetSize ());
+              NS_LOG_DEBUG ("fragmenting last fragment size=" << fragment->GetSize ());
               params.DisableNextData ();
             } 
           else 
             {
-              MY_DEBUG ("fragmenting size=" << fragment->GetSize ());
+              NS_LOG_DEBUG ("fragmenting size=" << fragment->GetSize ());
               params.EnableNextData (GetNextFragmentSize ());
             }
           m_low->StartTransmission (fragment, &hdr, params, 
-                                     m_transmissionListener);
+                                    m_transmissionListener);
         }
       else
         {
@@ -328,7 +418,7 @@
               m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (), 
                                             WifiMacHeader::ADDR1, m_currentHdr.GetAddr1 ()) &&
               !m_currentHdr.GetAddr1 ().IsBroadcast () &&
-              m_aggregator != 0)
+              m_aggregator != 0 && !m_currentHdr.IsRetry ())
             {
               /* here is performed aggregation */
               Ptr<Packet> currentAggregatedPacket = Create<Packet> ();
@@ -338,8 +428,8 @@
               bool aggregated = false;
               bool isAmsdu = false;
               Ptr<const Packet> peekedPacket = m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (), 
-                                                                       WifiMacHeader::ADDR1, 
-                                                                       m_currentHdr.GetAddr1 ());
+                                                                             WifiMacHeader::ADDR1, 
+                                                                             m_currentHdr.GetAddr1 ());
               while (peekedPacket != 0)
                 {
                   aggregated = m_aggregator->Aggregate (peekedPacket, currentAggregatedPacket,
@@ -363,22 +453,23 @@
                   m_currentHdr.SetAddr3 (m_low->GetBssid ());
                   m_currentPacket = currentAggregatedPacket;
                   currentAggregatedPacket = 0;
-                  MY_DEBUG ("tx unicast A-MSDU");
+                  NS_LOG_DEBUG ("tx unicast A-MSDU");
                 }
             }
           if (NeedRts ())
             {
               params.EnableRts ();
-              MY_DEBUG ("tx unicast rts");
+              NS_LOG_DEBUG ("tx unicast rts");
             } 
           else 
             {
               params.DisableRts ();
-              MY_DEBUG ("tx unicast");
+              NS_LOG_DEBUG ("tx unicast");
             }
           params.DisableNextData ();
           m_low->StartTransmission (m_currentPacket, &m_currentHdr,
                                     params, m_transmissionListener);
+          CompleteTx ();
         }
     }
 }
@@ -401,17 +492,17 @@
 EdcaTxopN::GotCts (double snr, WifiMode txMode)
 {
   NS_LOG_FUNCTION (this << snr << txMode);
-  MY_DEBUG ("got cts");
+  NS_LOG_DEBUG ("got cts");
 }
 
 void 
 EdcaTxopN::MissedCts (void)
 {
   NS_LOG_FUNCTION (this);
-  MY_DEBUG ("missed cts");
+  NS_LOG_DEBUG ("missed cts");
   if (!NeedRtsRetransmission ())
     {
-      MY_DEBUG ("Cts Fail");
+      NS_LOG_DEBUG ("Cts Fail");
       m_stationManager->ReportFinalRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
       if (!m_txFailedCallback.IsNull ()) 
         {
@@ -456,11 +547,32 @@
       IsLastFragment () ||
       m_currentHdr.IsQosAmsdu ()) 
     {
-      MY_DEBUG ("got ack. tx done.");
+      NS_LOG_DEBUG ("got ack. tx done.");
       if (!m_txOkCallback.IsNull ())
         {
            m_txOkCallback (m_currentHdr);
         }
+      
+      if (m_currentHdr.IsAction ())
+        {
+          WifiActionHeader actionHdr;
+          Ptr<Packet> p = m_currentPacket->Copy ();
+          p->RemoveHeader (actionHdr);
+          if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
+              actionHdr.GetAction ().blockAck == WifiActionHeader::BLOCK_ACK_DELBA)
+            {
+              MgtDelBaHeader delBa;
+              p->PeekHeader (delBa);
+              if (delBa.IsByOriginator ())
+                {
+                  m_baManager->TearDownBlockAck (m_currentHdr.GetAddr1 (), delBa.GetTid ());
+                }
+              else
+                {
+                  m_low->DestroyBlockAckAgreement (m_currentHdr.GetAddr1 (), delBa.GetTid ());
+                }
+            }
+        }
       m_currentPacket = 0;
          
       m_dcf->ResetCw ();
@@ -469,7 +581,7 @@
     } 
   else 
     {
-      MY_DEBUG ("got ack. tx not done, size="<<m_currentPacket->GetSize ());
+      NS_LOG_DEBUG ("got ack. tx not done, size="<<m_currentPacket->GetSize ());
     }
 }
 
@@ -477,10 +589,10 @@
 EdcaTxopN::MissedAck (void)
 {
   NS_LOG_FUNCTION (this);
-  MY_DEBUG ("missed ack");
+  NS_LOG_DEBUG ("missed ack");
   if (!NeedDataRetransmission ()) 
     {
-      MY_DEBUG ("Ack Fail");
+      NS_LOG_DEBUG ("Ack Fail");
       m_stationManager->ReportFinalDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
       if (!m_txFailedCallback.IsNull ()) 
         {
@@ -492,7 +604,7 @@
     } 
   else 
     {
-      MY_DEBUG ("Retransmit");
+      NS_LOG_DEBUG ("Retransmit");
       m_currentHdr.SetRetry ();
       m_dcf->UpdateFailedCw ();
     }
@@ -500,6 +612,20 @@
   RestartAccessIfNeeded ();
 }
 
+void
+EdcaTxopN::MissedBlockAck (void)
+{
+  NS_LOG_FUNCTION (this);
+  NS_LOG_DEBUG ("missed block ack");
+  //should i report this to station addressed by ADDR1?
+  NS_LOG_DEBUG ("Retransmit block ack request");
+  m_currentHdr.SetRetry ();
+  m_dcf->UpdateFailedCw ();
+  
+  m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+  RestartAccessIfNeeded ();
+}
+
 Ptr<MsduAggregator>
 EdcaTxopN::GetMsduAggregator (void) const
 {
@@ -511,7 +637,7 @@
 {
   NS_LOG_FUNCTION (this);
   if ((m_currentPacket != 0 ||
-       !m_queue->IsEmpty ()) &&
+       !m_queue->IsEmpty () || m_baManager->HasPackets ()) &&
        !m_dcf->IsAccessRequested ())
     {
       m_manager->RequestAccess (m_dcf);
@@ -523,7 +649,7 @@
 {
   NS_LOG_FUNCTION (this);
   if (m_currentPacket == 0 &&
-      !m_queue->IsEmpty () &&
+      (!m_queue->IsEmpty () || m_baManager->HasPackets ()) &&
       !m_dcf->IsAccessRequested ())
     {
       m_manager->RequestAccess (m_dcf);
@@ -561,7 +687,7 @@
 EdcaTxopN::StartNext (void)
 {
   NS_LOG_FUNCTION (this);
-  MY_DEBUG ("start next packet fragment");
+  NS_LOG_DEBUG ("start next packet fragment");
   /* this callback is used only for fragments. */
   NextFragment ();
   WifiMacHeader hdr;
@@ -585,7 +711,7 @@
 EdcaTxopN::Cancel (void)
 {
   NS_LOG_FUNCTION (this);
-  MY_DEBUG ("transmission cancelled");
+  NS_LOG_DEBUG ("transmission cancelled");
 }
 
 bool
@@ -644,6 +770,12 @@
   return fragment;
 }
 
+void
+EdcaTxopN::SetAccessClass (enum AccessClass ac)
+{
+  m_ac = ac;
+}
+
 Mac48Address
 EdcaTxopN::MapSrcAddressForAggregation (const WifiMacHeader &hdr)
 {
@@ -680,4 +812,273 @@
   m_aggregator = aggr;
 }
 
+void
+EdcaTxopN::PushFront (Ptr<const Packet> packet, const WifiMacHeader &hdr)
+{
+  NS_LOG_FUNCTION (this << packet << &hdr);
+  WifiMacTrailer fcs;
+  uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.GetSerializedSize ();
+  m_stationManager->PrepareForQueue (hdr.GetAddr1 (), &hdr,
+                                     packet, fullPacketSize);
+  m_queue->PushFront (packet, hdr);
+  StartAccessIfNeeded ();
+}
+
+void
+EdcaTxopN::GotAddBaResponse (const MgtAddBaResponseHeader *respHdr, Mac48Address recipient)
+{
+  NS_LOG_FUNCTION (this);
+  NS_LOG_DEBUG ("received ADDBA response from "<<recipient);
+  uint8_t tid = respHdr->GetTid ();
+  if (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::PENDING))
+   {
+     if (respHdr->GetStatusCode ().IsSuccess ())
+       {
+         NS_LOG_DEBUG ("block ack agreement established with "<<recipient);
+         m_baManager->UpdateAgreement (respHdr, recipient);
+       }
+     else
+       {
+         NS_LOG_DEBUG ("discard ADDBA response"<<recipient);
+         m_baManager->NotifyAgreementUnsuccessful (recipient, tid);
+       }
+    }
+  RestartAccessIfNeeded ();
+}
+
+void
+EdcaTxopN::GotDelBaFrame (const MgtDelBaHeader *delBaHdr, Mac48Address recipient)
+{
+  NS_LOG_FUNCTION (this);
+  NS_LOG_DEBUG ("received DELBA frame from="<<recipient);
+  m_baManager->TearDownBlockAck (recipient, delBaHdr->GetTid ());
+}
+
+void
+EdcaTxopN::GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recipient)
+{
+  NS_LOG_DEBUG ("got block ack from="<<recipient);
+  m_baManager->NotifyGotBlockAck (blockAck, recipient);
+  m_currentPacket = 0;
+  m_dcf->ResetCw ();
+  m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+  RestartAccessIfNeeded ();
+}
+
+void
+EdcaTxopN::VerifyBlockAck (void)
+{
+  NS_LOG_FUNCTION (this);
+  uint8_t tid = m_currentHdr.GetQosTid ();
+  Mac48Address recipient = m_currentHdr.GetAddr1 ();
+  uint16_t sequence = m_currentHdr.GetSequenceNumber ();
+  if (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::INACTIVE))
+    {
+      m_baManager->SwitchToBlockAckIfNeeded (recipient, tid, sequence);
+    }
+  if (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED))
+    {
+      m_currentHdr.SetQosAckPolicy (WifiMacHeader::BLOCK_ACK);
+    }
+}
+
+void
+EdcaTxopN::CompleteTx (void)
+{
+  if (m_currentHdr.IsQosData () && m_currentHdr.IsQosBlockAck ())
+    {
+      if (!m_currentHdr.IsRetry ())
+        {
+          m_baManager->StorePacket (m_currentPacket, m_currentHdr, m_currentPacketTimestamp);
+        }
+      m_baManager->NotifyMpduTransmission (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ());
+      //we are not waiting for an ack: transmission is completed
+      m_currentPacket = 0;
+      m_dcf->ResetCw ();
+      m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+      StartAccessIfNeeded ();
+    }
+}
+
+bool
+EdcaTxopN::SetupBlockAckIfNeeded ()
+{
+  uint8_t tid = m_currentHdr.GetQosTid ();
+  Mac48Address recipient = m_currentHdr.GetAddr1 ();
+
+  uint32_t packets = m_queue->GetNPacketsByTidAndAddress (tid, WifiMacHeader::ADDR1, recipient);
+
+  if (packets >= m_blockAckThreshold)
+    {
+      /* Block ack setup */
+      uint16_t startingSequence = m_txMiddle->GetNextSeqNumberByTidAndAddress (tid, recipient);
+      SendAddBaRequest (recipient, tid, startingSequence, m_blockAckInactivityTimeout, true);
+      return true;
+    }
+  return false;
+}
+
+void
+EdcaTxopN::SendBlockAckRequest (const struct Bar &bar)
+{
+  NS_LOG_FUNCTION (this);
+  WifiMacHeader hdr;
+  hdr.SetType (WIFI_MAC_CTL_BACKREQ);
+  hdr.SetAddr1 (bar.recipient);
+  hdr.SetAddr2 (m_low->GetAddress ());
+  hdr.SetAddr3 (m_low->GetBssid ());
+  hdr.SetDsNotTo ();
+  hdr.SetDsNotFrom ();
+  hdr.SetNoRetry ();
+  hdr.SetNoMoreFragments ();
+
+  m_currentPacket = bar.bar;
+  m_currentHdr = hdr;
+
+  MacLowTransmissionParameters params;
+  params.DisableRts ();
+  params.DisableNextData ();
+  params.DisableOverrideDurationId ();
+  if (bar.immediate)
+    {
+      if (m_blockAckType == BASIC_BLOCK_ACK)
+        {
+          params.EnableBasicBlockAck ();
+        }
+      else if (m_blockAckType == COMPRESSED_BLOCK_ACK)
+        {
+          params.EnableCompressedBlockAck ();
+        }
+      else if (m_blockAckType == MULTI_TID_BLOCK_ACK)
+        {
+          NS_FATAL_ERROR ("Multi-tid block ack is not supported");
+        }
+    }
+  else
+    {
+      //Delayed block ack
+      params.EnableAck ();
+    }
+  m_low->StartTransmission (m_currentPacket, &m_currentHdr, params, m_transmissionListener);
+}
+
+void
+EdcaTxopN::CompleteConfig (void)
+{
+  NS_LOG_FUNCTION (this);
+  m_baManager->SetTxMiddle (m_txMiddle);
+  m_low->RegisterBlockAckListenerForAc (m_ac, m_blockAckListener);
+  m_baManager->SetBlockAckInactivityCallback (MakeCallback (&EdcaTxopN::SendDelbaFrame, this));
+}
+
+void
+EdcaTxopN::SetBlockAckThreshold (uint8_t threshold)
+{
+  m_blockAckThreshold = threshold;
+  m_baManager->SetBlockAckThreshold (threshold);
+}
+
+uint8_t
+EdcaTxopN::GetBlockAckThreshold (void) const
+{
+  return m_blockAckThreshold;
+}
+
+void
+EdcaTxopN::SendAddBaRequest (Mac48Address dest, uint8_t tid, uint16_t startSeq, 
+                             uint16_t timeout, bool immediateBAck)
+{
+  NS_LOG_FUNCTION (this);
+  NS_LOG_DEBUG ("sent ADDBA request to "<<dest);
+  WifiMacHeader hdr;
+  hdr.SetAction ();
+  hdr.SetAddr1 (dest);
+  hdr.SetAddr2 (m_low->GetAddress ());
+  hdr.SetAddr3 (m_low->GetAddress ());
+  hdr.SetDsNotTo ();
+  hdr.SetDsNotFrom ();
+  
+  WifiActionHeader actionHdr;
+  WifiActionHeader::ActionValue action;
+  action.blockAck = WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST;
+  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
+
+  Ptr<Packet> packet = Create<Packet> ();
+  /*Setting ADDBARequest header*/
+  MgtAddBaRequestHeader reqHdr;
+  reqHdr.SetAmsduSupport (true);
+  if (immediateBAck)
+    {
+      reqHdr.SetImmediateBlockAck ();
+    }
+  else
+    {
+      reqHdr.SetDelayedBlockAck ();
+    }
+  reqHdr.SetTid (tid);
+  /* For now we don't use buffer size field in the ADDBA request frame. The recipient
+   * will choose how many packets it can receive under block ack.
+   */
+  reqHdr.SetBufferSize (0);
+  reqHdr.SetTimeout (timeout);
+  reqHdr.SetStartingSequence (startSeq);
+
+  m_baManager->CreateAgreement (&reqHdr, dest);
+  
+  packet->AddHeader (reqHdr);
+  packet->AddHeader (actionHdr);
+  
+  m_currentPacket = packet;
+  m_currentHdr = hdr;
+
+  uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr);
+  m_currentHdr.SetSequenceNumber (sequence);
+  m_currentHdr.SetFragmentNumber (0);
+  m_currentHdr.SetNoMoreFragments ();
+  m_currentHdr.SetNoRetry ();
+  
+  MacLowTransmissionParameters params;
+  params.EnableAck ();
+  params.DisableRts ();
+  params.DisableNextData ();
+  params.DisableOverrideDurationId ();
+  
+  m_low->StartTransmission (m_currentPacket, &m_currentHdr, params, 
+                            m_transmissionListener);
+}
+
+void
+EdcaTxopN::SendDelbaFrame (Mac48Address addr, uint8_t tid, bool byOriginator)
+{
+  WifiMacHeader hdr;
+  hdr.SetAction ();
+  hdr.SetAddr1 (addr);
+  hdr.SetAddr2 (m_low->GetAddress ());
+  hdr.SetAddr3 (m_low->GetAddress ());
+  hdr.SetDsNotTo ();
+  hdr.SetDsNotFrom ();
+
+  MgtDelBaHeader delbaHdr;
+  delbaHdr.SetTid (tid);
+  if (byOriginator)
+    {
+      delbaHdr.SetByOriginator ();
+    }
+  else
+    {
+      delbaHdr.SetByRecipient ();
+    }
+
+  WifiActionHeader actionHdr;
+  WifiActionHeader::ActionValue action;
+  action.blockAck = WifiActionHeader::BLOCK_ACK_DELBA;
+  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
+  
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->AddHeader (delbaHdr);
+  packet->AddHeader (actionHdr);
+
+  PushFront (packet, hdr);
+}
+
 } //namespace ns3
--- a/src/devices/wifi/edca-txop-n.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/edca-txop-n.h	Thu Feb 25 14:17:21 2010 +0100
@@ -31,6 +31,7 @@
 #include "wifi-mac-header.h"
 #include "qos-utils.h"
 #include "dcf.h"
+#include "ctrl-headers.h"
 
 #include <map>
 #include <list>
@@ -44,7 +45,12 @@
 class WifiMacParameters;
 class WifiMacQueue;
 class RandomStream;
+class QosBlockedDestinations;
 class MsduAggregator;
+class MgtAddBaResponseHeader;
+class BlockAckManager;
+class MgtDelBaHeader;
+
 
 /* This queue contains packets for a particular access class.
  * possibles access classes are:
@@ -110,6 +116,10 @@
   void GotCts (double snr, WifiMode txMode);
   void MissedCts (void);
   void GotAck (double snr, WifiMode txMode);
+  void GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recipient);
+  void MissedBlockAck (void);
+  void GotAddBaResponse (const MgtAddBaResponseHeader *respHdr, Mac48Address recipient);
+  void GotDelBaFrame (const MgtDelBaHeader *delBaHdr, Mac48Address recipient);
   void MissedAck (void);
   void StartNext (void);
   void Cancel (void);
@@ -127,8 +137,14 @@
   void NextFragment (void);
   Ptr<Packet> GetFragmentPacket (WifiMacHeader *hdr);
   
+  void SetAccessClass (enum AccessClass ac);
   void Queue (Ptr<const Packet> packet, const WifiMacHeader &hdr);
   void SetMsduAggregator (Ptr<MsduAggregator> aggr);
+  void PushFront (Ptr<const Packet> packet, const WifiMacHeader &hdr);
+  void CompleteConfig (void);
+  void SetBlockAckThreshold (uint8_t threshold);
+  uint8_t GetBlockAckThreshold (void) const;
+  void SendDelbaFrame (Mac48Address addr, uint8_t tid, bool byOriginator);
 
 private:
   /**
@@ -144,9 +160,33 @@
   Mac48Address MapDestAddressForAggregation (const WifiMacHeader &hdr);
   EdcaTxopN &operator = (const EdcaTxopN &);
   EdcaTxopN (const EdcaTxopN &);
+
+  /* If number of packets in the queue reaches m_blockAckThreshold value, an ADDBARequest frame
+   * is sent to destination in order to setup a block ack.
+   */
+  bool SetupBlockAckIfNeeded ();
+  /* Sends an ADDBARequest to establish a block ack agreement with sta
+   * addressed by <i>recipient</i> for tid <i>tid</i>.
+   */
+  void SendAddBaRequest (Mac48Address recipient, uint8_t tid, uint16_t startSeq,
+                         uint16_t timeout, bool immediateBAck);
+  /* After that all packets, for which a block ack agreement was established, have been
+   * transmitted, we have to send a block ack request.
+   */
+  void SendBlockAckRequest (const struct Bar &bar);
+  /* For now is typically invoked to complete transmission of a packets sent with ack policy
+   * Block Ack: the packet is buffered and dcf is reset.
+   */
+  void CompleteTx (void);
+  /* Verifies if dequeued packet has to be transmitted with ack policy Block Ack. This happens
+   * if an established block ack agreement exists with the receiver.
+   */
+  void VerifyBlockAck (void);
   
+  AccessClass m_ac;
   class Dcf;
   class TransmissionListener;
+  class BlockAckEventListener;
   friend class Dcf;
   friend class TransmissionListener;
   Dcf *m_dcf;
@@ -157,6 +197,7 @@
   Ptr<MacLow> m_low;
   MacTxMiddle *m_txMiddle;
   TransmissionListener *m_transmissionListener;
+  BlockAckEventListener *m_blockAckListener;
   RandomStream *m_rng;
   Ptr<WifiRemoteStationManager> m_stationManager;
   uint8_t m_fragmentNumber;
@@ -169,6 +210,15 @@
   WifiMacHeader m_currentHdr;
   Ptr<MsduAggregator> m_aggregator;
   TypeOfStation m_typeOfStation;
+  QosBlockedDestinations *m_qosBlockedDestinations;
+  BlockAckManager *m_baManager;
+  /*
+   * Represents the minimun number of packets for use of block ack.
+   */
+  uint8_t m_blockAckThreshold;
+  enum BlockAckType m_blockAckType;
+  Time m_currentPacketTimestamp;
+  uint16_t m_blockAckInactivityTimeout;
 };
 
 }  //namespace ns3
--- a/src/devices/wifi/jakes-propagation-loss-model.cc	Thu Feb 25 13:51:59 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,259 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 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
- *
- * Author: Federico Maguolo <maguolof@dei.unipd.it>
- */
-
-#include "ns3/simulator.h"
-#include "ns3/uinteger.h"
-#include "ns3/double.h"
-#include "ns3/random-variable.h"
-#include "ns3/mobility-model.h"
-#include "ns3/log.h"
-#include "jakes-propagation-loss-model.h"
-#include <math.h>
-
-NS_LOG_COMPONENT_DEFINE ("Jakes");
-
-namespace ns3 {
-
-class JakesPropagationLossModel::PathCoefficients 
-{
-public:
-  PathCoefficients (Ptr<const JakesPropagationLossModel> jakes,
-                    Ptr<MobilityModel> receiver, 
-                    uint8_t nRays, 
-                    uint8_t nOscillators);
-  ~PathCoefficients ();
-  double GetLoss (void);
-  Ptr<MobilityModel> GetReceiver (void);
-private:
-  void DoConstruct (void);
-  Ptr<MobilityModel> m_receiver;
-  uint8_t m_nOscillators;
-  uint8_t m_nRays;
-  double **m_phases;
-  Time m_lastUpdate;
-  Ptr<const JakesPropagationLossModel> m_jakes;
-};
-
-
-JakesPropagationLossModel::PathCoefficients::PathCoefficients (Ptr<const JakesPropagationLossModel> jakes, 
-                                                           Ptr<MobilityModel> receiver, 
-                                                           uint8_t nRays, 
-							   uint8_t nOscillators)
-  : m_receiver (receiver),
-    m_nOscillators (nOscillators),
-    m_nRays (nRays),
-    m_jakes(jakes)
-{
-  DoConstruct ();
-}
-
-JakesPropagationLossModel::PathCoefficients::~PathCoefficients ()
-{
-  for (uint8_t i = 0; i < m_nRays; i++) 
-    {
-      delete [] m_phases[i];
-    }
-  delete [] m_phases;
-}
-
-void
-JakesPropagationLossModel::PathCoefficients::DoConstruct ()
-{
-  m_phases = new double*[m_nRays];
-  for (uint8_t i = 0; i < m_nRays; i++) 
-    {
-      m_phases[i] = new double[m_nOscillators + 1];
-      for (uint8_t j = 0; j <= m_nOscillators; j++) 
-        {
-          m_phases[i][j] = 2.0 * JakesPropagationLossModel::PI * m_jakes->m_variable.GetValue ();
-        }
-    }
-  m_lastUpdate = Simulator::Now ();
-}
-
-Ptr<MobilityModel>
-JakesPropagationLossModel::PathCoefficients::GetReceiver ()
-{
-  return m_receiver;
-}
-
-double
-JakesPropagationLossModel::PathCoefficients::GetLoss (void)
-{
-  uint16_t N = 4 * m_nOscillators + 2;
-  Time interval = Simulator::Now () - m_lastUpdate;
-  ComplexNumber coef= {0.0, 0.0};
-  ComplexNumber fading;
-  double norm = 0.0;
-  for (uint8_t i = 0; i < m_nRays; i++) 
-    {
-      fading.real = 0.0;
-      fading.imag = 0.0;
-      for (uint8_t j = 0; j <= m_nOscillators; j++) 
-        {
-          m_phases[i][j] += 2.0 * JakesPropagationLossModel::PI * 
-            cos (2.0 * JakesPropagationLossModel::PI * j / N) * m_jakes->m_fd * interval.GetSeconds ();
-          m_phases[i][j] -= 2.0 * JakesPropagationLossModel::PI * 
-            floor (m_phases[i][j] / 2.0 / JakesPropagationLossModel::PI);
-          fading.real += m_jakes->m_amp[j].real * cos (m_phases[i][j]);
-          fading.imag += m_jakes->m_amp[j].imag * cos (m_phases[i][j]);
-          norm += sqrt(pow (m_jakes->m_amp[j].real, 2) + pow(m_jakes->m_amp[j].imag, 2));
-        }
-    coef.real += fading.real;
-    coef.imag += fading.imag;
-    }
-  m_lastUpdate = Simulator::Now ();
-  double k = sqrt (pow (coef.real, 2) + pow (coef.imag, 2)) / norm;
-  NS_LOG_DEBUG ("Jakes coef "<< k << " (" << 10 * log10 (k) << "dB)");
-  return 10 * log10 (k);
-}
-
-NS_OBJECT_ENSURE_REGISTERED (JakesPropagationLossModel);
-
-const double JakesPropagationLossModel::PI = 3.14159265358979323846;
-
-TypeId
-JakesPropagationLossModel::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::JakesPropagationLossModel")
-    .SetParent<PropagationLossModel> ()
-    .AddConstructor<JakesPropagationLossModel> ()
-    .AddAttribute ("NumberOfRaysPerPath",
-                   "The number of rays to use by default for compute the fading coeficent for a given path (default is 1)",
-                   UintegerValue (1),
-		   MakeUintegerAccessor (&JakesPropagationLossModel::SetNRays,
-                                         &JakesPropagationLossModel::GetNRays),
-		   MakeUintegerChecker<uint8_t> ())
-    .AddAttribute ("NumberOfOscillatorsPerRay",
-                   "The number of oscillators to use by default for compute the coeficent for a given ray of a given "
-                   "path (default is 4)",
-                   UintegerValue (4),
-		   MakeUintegerAccessor (&JakesPropagationLossModel::SetNOscillators,
-                                         &JakesPropagationLossModel::GetNOscillators),
-		   MakeUintegerChecker<uint8_t> ())
-    .AddAttribute ("DopplerFreq",
-                   "The doppler frequency in Hz (f_d = v / lambda = v * f / c), the default is 0)",
-                   DoubleValue (0.0),
-		   MakeDoubleAccessor (&JakesPropagationLossModel::m_fd),
-		   MakeDoubleChecker<double> ())
-    .AddAttribute ("Distribution",
-                   "The distribution to choose the initial phases.",
-                   RandomVariableValue (ConstantVariable (1.0)),
-                   MakeRandomVariableAccessor (&JakesPropagationLossModel::m_variable),
-                   MakeRandomVariableChecker ())
-    ;
-  return tid;
-}
-
-JakesPropagationLossModel::JakesPropagationLossModel ()
-  : m_amp (0),
-    m_nRays (0),
-    m_nOscillators (0)
-{}
-
-JakesPropagationLossModel::~JakesPropagationLossModel ()
-{
-  delete [] m_amp;
-  for (PathsList::iterator i = m_paths.end (); i != m_paths.begin (); i--) 
-    {
-      PathsSet *ps = *i;
-      for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++) 
-        {
-          PathCoefficients *pc = *r;
-          delete pc;
-        }
-      delete ps;
-    }
-}
-
-void
-JakesPropagationLossModel::SetNRays (uint8_t nRays)
-{
-  m_nRays = nRays;
-}
-
-void
-JakesPropagationLossModel::SetNOscillators (uint8_t nOscillators)
-{
-  m_nOscillators = nOscillators;
-  delete [] m_amp;
-  uint16_t N = 4 * m_nOscillators + 2;
-  m_amp = new ComplexNumber[m_nOscillators + 1];
-  m_amp[0].real = 2.0 * sqrt(2.0 / N) * cos (PI / 4.0);
-  m_amp[0].imag = 2.0 * sqrt(2.0 / N) * sin (PI / 4.0);
-  for (uint8_t i = 1; i <= m_nOscillators; i++) 
-    {
-      double beta = PI * (double)i / m_nOscillators;
-      m_amp[i].real = 4.0 * cos (beta) / sqrt(N);
-      m_amp[i].imag = 4.0 * sin (beta) / sqrt(N);
-    }
-}
-
-uint8_t 
-JakesPropagationLossModel::GetNRays (void) const
-{
-  return m_nRays;
-}
-uint8_t 
-JakesPropagationLossModel::GetNOscillators (void) const
-{
-  return m_nOscillators;
-}
-
-
-double 
-JakesPropagationLossModel::DoCalcRxPower (double txPowerDbm,
-                                          Ptr<MobilityModel> a,
-                                          Ptr<MobilityModel> b) const
-{
-  PathsList::iterator i = m_paths.end ();
-  while (i != m_paths.begin ()) 
-    {
-      i--;
-      PathsSet *ps = *i;
-      if (ps->sender == a) 
-        {
-          m_paths.erase (i);
-          m_paths.push_back (ps);
-          for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++) 
-            {
-              PathCoefficients *pc = *r;
-              if (pc->GetReceiver () == b) 
-                {
-                  ps->receivers.erase (r);
-                  ps->receivers.push_back (pc);
-                  return txPowerDbm + pc->GetLoss ();
-                }
-            }
-          PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators);
-          ps->receivers.push_back (pc);
-          return txPowerDbm + pc->GetLoss ();
-        }
-    }
-  PathsSet *ps = new PathsSet;
-  ps->sender = a;
-  PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators);
-  ps->receivers.push_back (pc);
-  m_paths.push_back (ps);
-  return txPowerDbm + pc->GetLoss ();
-}
-
-} // namespace ns3
-
--- a/src/devices/wifi/jakes-propagation-loss-model.h	Thu Feb 25 13:51:59 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 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
- *
- * Author: Federico Maguolo <maguolof@dei.unipd.it>
- */
-#ifndef PROPAGATION_JAKES_MODEL_H
-#define PROPAGATION_JAKES_MODEL_H
-
-#include "ns3/nstime.h"
-#include "propagation-loss-model.h"
-
-namespace ns3 {
-
-
-/**
- * \brief a Jakes propagation loss model
- *
- * The Jakes propagation loss model implemented here is 
- * described in [1].
- * 
- *
- * We call path the set of rays that depart from a given 
- * transmitter and arrive to a given receiver. For each ray
- * The complex coefficient is compute as follow:
- * \f[ u(t)=u_c(t) + j u_s(t)\f]
- * \f[ u_c(t) = \frac{2}{\sqrt{N}}\sum_{n=0}^{M}a_n\cos(\omega_n t+\phi_n)\f]
- * \f[ u_s(t) = \frac{2}{\sqrt{N}}\sum_{n=0}^{M}b_n\cos(\omega_n t+\phi_n)\f]
- * where
- * \f[ a_n=\left \{ \begin{array}{ll}
- * \sqrt{2}\cos\beta_0 & n=0 \\
- * 2\cos\beta_n & n=1,2,\ldots,M
- * \end{array}
- * \right .\f]
- * \f[ b_n=\left \{ \begin{array}{ll}
- * \sqrt{2}\sin\beta_0 & n=0 \\
- * 2\sin\beta_n & n=1,2,\ldots,M
- * \end{array}
- * \right .\f]
- * \f[ \beta_n=\left \{ \begin{array}{ll}
- * \frac{\pi}{4} & n=0 \\
- * \frac{\pi n}{M} & n=1,2,\ldots,M
- * \end{array}
- * \right .\f]
- * \f[ \omega_n=\left \{ \begin{array}{ll}
- * 2\pi f_d & n=0 \\
- * 2\pi f_d \cos\frac{2\pi n}{N} & n=1,2,\ldots,M
- * \end{array}
- * \right .\f]
- *
- * The parameter \f$f_d\f$ is the doppler frequency and \f$N=4M+2\f$ where
- * \f$M\f$ is the number of oscillators per ray.
- *
- * The attenuation coefficent of the path is the magnitude of the sum of 
- * all the ray coefficients. This attenuation coefficient could be greater than
- * \f$1\f$, hence it is divide by \f$ \frac{2N_r}{\sqrt{N}} \sum_{n+0}^{M}\sqrt{a_n^2 +b_n^2}\f$
- * where \f$N_r\f$ is the number of rays.
- *
- * The initail phases \f$\phi_i\f$ are random and they are choosen according 
- * to a given distribution.
- * 
- * [1] Y. R. Zheng and C. Xiao, "Simulation Models With Correct 
- * Statistical Properties for Rayleigh Fading Channel", IEEE
- * Trans. on Communications, Vol. 51, pp 920-928, June 2003
- */
-class JakesPropagationLossModel : public PropagationLossModel
-{
-public:
-  static TypeId GetTypeId (void);
-  JakesPropagationLossModel ();
-  virtual ~JakesPropagationLossModel ();
-
-  /**
-   * \param nRays Number of rays per path
-   *
-   * Set the number of rays for each path
-   */
-  void SetNRays (uint8_t nRays);
-  /**
-   * \param nOscillators Number of oscillators
-   *
-   * Set the number of oscillators to use to compute the ray coefficient
-   */
-  void SetNOscillators (uint8_t nOscillators);
-
-  uint8_t GetNRays (void) const;
-  uint8_t GetNOscillators (void) const;
-
-private:
-  JakesPropagationLossModel (const JakesPropagationLossModel &o);
-  JakesPropagationLossModel & operator = (const JakesPropagationLossModel &o);
-  void DoConstruct (void);
-  virtual double DoCalcRxPower (double txPowerDbm,
-                                Ptr<MobilityModel> a,
-                                Ptr<MobilityModel> b) const;
-
-  class PathCoefficients;
-  struct ComplexNumber {
-    double real;
-    double imag;
-  };
-  friend class PathCoefficents;
-  typedef std::vector<PathCoefficients *> DestinationList;
-  struct PathsSet {
-    Ptr<MobilityModel> sender;
-    DestinationList receivers;
-  };
-  typedef std::vector<PathsSet *> PathsList;
-
-  
-  static const double PI;
-  ComplexNumber* m_amp;
-  RandomVariable m_variable;
-  double m_fd;  
-  mutable PathsList m_paths;
-  uint8_t m_nRays;
-  uint8_t m_nOscillators;
-};
-
-} // namespace ns3
-
-#endif /* PROPAGATION_JAKES_MODEL_H */
-
-
--- a/src/devices/wifi/mac-low.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/mac-low.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -1,6 +1,7 @@
 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
 /*
  * Copyright (c) 2005,2006 INRIA
+ * Copyright (c) 2009 MIRKO BANCHI
  *
  * 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 
@@ -16,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
  */
 
 #include "ns3/assert.h"
@@ -29,6 +31,8 @@
 #include "mac-low.h"
 #include "wifi-phy.h"
 #include "wifi-mac-trailer.h"
+#include "qos-utils.h"
+#include "edca-txop-n.h"
 
 NS_LOG_COMPONENT_DEFINE ("MacLow");
 
@@ -111,11 +115,23 @@
 {}
 MacLowTransmissionListener::~MacLowTransmissionListener ()
 {}
+void
+MacLowTransmissionListener::GotBlockAck (const CtrlBAckResponseHeader *blockAck,
+                                         Mac48Address source)
+{}
+void
+MacLowTransmissionListener::MissedBlockAck (void)
+{}
 MacLowDcfListener::MacLowDcfListener ()
 {}
 MacLowDcfListener::~MacLowDcfListener ()
 {}
 
+MacLowBlockAckEventListener::MacLowBlockAckEventListener ()
+{}
+MacLowBlockAckEventListener::~MacLowBlockAckEventListener ()
+{}
+
 MacLowTransmissionParameters::MacLowTransmissionParameters ()
   : m_nextSize (0),
     m_waitAck (ACK_NONE),
@@ -147,6 +163,21 @@
 {
   m_waitAck = ACK_SUPER_FAST;
 }
+void
+MacLowTransmissionParameters::EnableBasicBlockAck (void)
+{
+  m_waitAck = BLOCK_ACK_BASIC;
+}
+void
+MacLowTransmissionParameters::EnableCompressedBlockAck (void)
+{
+  m_waitAck = BLOCK_ACK_COMPRESSED;
+}
+void
+MacLowTransmissionParameters::EnableMultiTidBlockAck (void)
+{
+  m_waitAck = BLOCK_ACK_MULTI_TID;
+}
 void 
 MacLowTransmissionParameters::EnableFastAck (void)
 {
@@ -192,6 +223,21 @@
 {
   return (m_waitAck == ACK_SUPER_FAST);
 }
+bool
+MacLowTransmissionParameters::MustWaitBasicBlockAck (void) const
+{
+  return (m_waitAck == BLOCK_ACK_BASIC)?true:false;
+}
+bool
+MacLowTransmissionParameters::MustWaitCompressedBlockAck (void) const
+{
+  return (m_waitAck == BLOCK_ACK_COMPRESSED)?true:false;
+}
+bool
+MacLowTransmissionParameters::MustWaitMultiTidBlockAck (void) const
+{
+  return (m_waitAck == BLOCK_ACK_MULTI_TID)?true:false;
+}
 bool 
 MacLowTransmissionParameters::MustSendRts (void) const
 {
@@ -240,6 +286,15 @@
   case MacLowTransmissionParameters::ACK_SUPER_FAST:
     os << "super-fast";
     break;
+  case MacLowTransmissionParameters::BLOCK_ACK_BASIC:
+    os << "basic-block-ack";
+    break;
+  case MacLowTransmissionParameters::BLOCK_ACK_COMPRESSED:
+    os << "compressed-block-ack";
+    break;
+  case MacLowTransmissionParameters::BLOCK_ACK_MULTI_TID:
+    os << "multi-tid-block-ack";
+    break;
   }
   os << "]";
   return os;
@@ -274,6 +329,7 @@
     m_fastAckTimeoutEvent (),
     m_superFastAckTimeoutEvent (),
     m_fastAckFailedTimeoutEvent (),
+    m_blockAckTimeoutEvent (),
     m_ctsTimeoutEvent (),
     m_sendCtsEvent (),
     m_sendAckEvent (),
@@ -308,6 +364,7 @@
   m_fastAckTimeoutEvent.Cancel ();
   m_superFastAckTimeoutEvent.Cancel ();
   m_fastAckFailedTimeoutEvent.Cancel ();
+  m_blockAckTimeoutEvent.Cancel ();
   m_ctsTimeoutEvent.Cancel ();
   m_sendCtsEvent.Cancel ();
   m_sendAckEvent.Cancel ();
@@ -344,6 +401,11 @@
       m_fastAckFailedTimeoutEvent.Cancel ();
       oneRunning = true;
     }
+  if (m_blockAckTimeoutEvent.IsRunning ())
+    {
+      m_blockAckTimeoutEvent.Cancel ();
+      oneRunning = true;
+    }
   if (m_ctsTimeoutEvent.IsRunning ()) 
     {
       m_ctsTimeoutEvent.Cancel ();
@@ -400,6 +462,16 @@
 {
   m_ackTimeout = ackTimeout;
 }
+void
+MacLow::SetBasicBlockAckTimeout (Time blockAckTimeout)
+{
+  m_basicBlockAckTimeout = blockAckTimeout;
+}
+void
+MacLow::SetCompressedBlockAckTimeout (Time blockAckTimeout)
+{
+  m_compressedBlockAckTimeout = blockAckTimeout;
+}
 void 
 MacLow::SetCtsTimeout (Time ctsTimeout)
 {
@@ -435,6 +507,16 @@
 {
   return m_ackTimeout;
 }
+Time
+MacLow::GetBasicBlockAckTimeout () const
+{
+  return m_basicBlockAckTimeout;
+}
+Time
+MacLow::GetCompressedBlockAckTimeout () const
+{
+  return m_compressedBlockAckTimeout;
+}
 Time 
 MacLow::GetCtsTimeout (void) const
 {
@@ -652,6 +734,53 @@
                                                  &MacLow::WaitSifsAfterEndTx, this);
         }
     } 
+  else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self &&
+          (m_txParams.MustWaitBasicBlockAck () || m_txParams.MustWaitCompressedBlockAck ()) && 
+           m_blockAckTimeoutEvent.IsRunning ())
+    {
+      NS_LOG_DEBUG ("got block ack from "<<hdr.GetAddr2 ());
+      CtrlBAckResponseHeader blockAck;
+      packet->RemoveHeader (blockAck);
+      m_blockAckTimeoutEvent.Cancel ();
+      m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 ());
+    }
+  else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
+    {
+      CtrlBAckRequestHeader blockAckReq;
+      packet->RemoveHeader (blockAckReq);
+      if (!blockAckReq.IsMultiTid ())
+        {
+          AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), blockAckReq.GetTidInfo ()));
+          if (it != m_bAckAgreements.end ())
+            {
+              NS_ASSERT (m_sendAckEvent.IsExpired ());
+              /* See section 11.5.3 in IEEE802.11 for mean of this timer */
+              ResetBlockAckInactivityTimerIfNeeded (it->second.first);
+              if ((*it).second.first.IsImmediateBlockAck ())
+                {
+                  NS_LOG_DEBUG ("rx blockAckRequest/sendImmediateBlockAck from="<< hdr.GetAddr2 ());
+                  m_sendAckEvent = Simulator::Schedule (GetSifs (),
+                                                        &MacLow::SendBlockAckAfterBlockAckRequest, this,
+                                                        blockAckReq,
+                                                        hdr.GetAddr2 (), 
+                                                        hdr.GetDuration (),
+                                                        txMode);
+                }
+              else
+                {
+                  NS_FATAL_ERROR ("Delayed block ack not supported.");
+                }
+            }
+          else
+            {
+              NS_LOG_DEBUG ("There's not a valid agreement for this block ack request.");
+            }
+        }
+      else
+        {
+          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+        }
+    }
   else if (hdr.IsCtl ()) 
     {
       NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ());
@@ -661,7 +790,50 @@
       m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
                                     rxSnr, txMode);
       
-      if (hdr.IsQosData () && hdr.IsQosNoAck ()) 
+      if (hdr.IsQosData () && StoreMpduIfNeeded (packet, hdr)) 
+        {
+          /* From section 9.10.4 in IEEE802.11:
+             Upon the receipt of a QoS data frame from the originator for which
+             the Block Ack agreement exists, the recipient shall buffer the MSDU
+             regardless of the value of the Ack Policy subfield within the 
+             QoS Control field of the QoS data frame. */
+          if (hdr.IsQosAck ())
+            {
+              AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
+              RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (),
+                                                            hdr.GetAddr2 (), hdr.GetQosTid ());
+              RxCompleteBufferedPackets (hdr.GetAddr2 (), hdr.GetQosTid ());
+              NS_ASSERT (m_sendAckEvent.IsExpired ());
+              m_sendAckEvent = Simulator::Schedule (GetSifs (),
+                                                    &MacLow::SendAckAfterData, this,
+                                                    hdr.GetAddr2 (), 
+                                                    hdr.GetDuration (),
+                                                    txMode,
+                                                    rxSnr);
+            }
+          else if (hdr.IsQosBlockAck ())
+            {
+              AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
+              /* See section 11.5.3 in IEEE802.11 for mean of this timer */
+              ResetBlockAckInactivityTimerIfNeeded (it->second.first);
+            }
+          return;  
+        }
+      else if (hdr.IsQosData () && hdr.IsQosBlockAck ())
+        {
+          /* This happens if a packet with ack policy Block Ack is received and a block ack
+             agreement for that packet doesn't exist.
+
+             From section 11.5.3 in IEEE802.11e:
+             When a recipient does not have an active Block ack for a TID, but receives
+             data MPDUs with the Ack Policy subfield set to Block Ack, it shall discard
+             them and shall send a DELBA frame using the normal access 
+             mechanisms. */
+          AccessClass ac = QosUtilsMapTidToAc (hdr.GetQosTid ());
+          m_edcaListeners[ac]->BlockAckInactivityTimeout (hdr.GetAddr2 (), hdr.GetQosTid ());
+          return;
+        }
+      else if (hdr.IsQosData () && hdr.IsQosNoAck ()) 
         {
           NS_LOG_DEBUG ("rx unicast/noAck from="<<hdr.GetAddr2 ());
         } 
@@ -709,6 +881,27 @@
   ack.SetType (WIFI_MAC_CTL_ACK);
   return ack.GetSize () + 4;
 }
+uint32_t
+MacLow::GetBlockAckSize (enum BlockAckType type) const
+{
+  WifiMacHeader hdr;
+  hdr.SetType (WIFI_MAC_CTL_BACKRESP);
+  CtrlBAckResponseHeader blockAck;
+  if (type == BASIC_BLOCK_ACK)
+    {
+      blockAck.SetType (BASIC_BLOCK_ACK);
+    }
+  else if (type == COMPRESSED_BLOCK_ACK)
+    {
+      blockAck.SetType (COMPRESSED_BLOCK_ACK);
+    }
+  else if (type == MULTI_TID_BLOCK_ACK)
+    {
+      //Not implemented
+      NS_ASSERT (false);  
+    }
+  return hdr.GetSize () + blockAck.GetSerializedSize () + 4; 
+}
 uint32_t 
 MacLow::GetRtsSize (void) const
 {
@@ -723,6 +916,19 @@
   return m_phy->CalculateTxDuration (GetAckSize (), ackMode, WIFI_PREAMBLE_LONG);
 }
 Time
+MacLow::GetBlockAckDuration (Mac48Address to, WifiMode blockAckReqTxMode, enum BlockAckType type) const
+{
+  /* 
+   * For immediate BlockAck we should transmit the frame with the same WifiMode
+   * as the BlockAckReq.
+   *
+   * from section 9.6 in IEEE802.11e:
+   * The BlockAck control frame shall be sent at the same rate and modulation class as
+   * the BlockAckReq frame if it is sent in response to a BlockAckReq frame.
+   */
+  return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxMode, WIFI_PREAMBLE_LONG);
+}
+Time
 MacLow::GetCtsDuration (Mac48Address to, WifiMode rtsTxMode) const
 {
   WifiMode ctsMode = GetCtsTxModeForRts (to, rtsTxMode);
@@ -977,6 +1183,17 @@
     }
 }
 void
+MacLow::BlockAckTimeout (void)
+{
+  NS_LOG_FUNCTION (this);
+  NS_LOG_DEBUG ("block ack timeout");
+  
+  m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
+  MacLowTransmissionListener *listener = m_listener;
+  m_listener = 0;
+  listener->MissedBlockAck ();
+}
+void
 MacLow::SuperFastAckTimeout ()
 {
   NS_LOG_FUNCTION (this);
@@ -1068,7 +1285,19 @@
       NotifyAckTimeoutStartNow (timerDelay);
       m_superFastAckTimeoutEvent = Simulator::Schedule (timerDelay, 
                                                         &MacLow::SuperFastAckTimeout, this);
-    } 
+    }
+  else if (m_txParams.MustWaitBasicBlockAck ())
+    {
+      Time timerDelay = txDuration + GetBasicBlockAckTimeout ();
+      NS_ASSERT (m_blockAckTimeoutEvent.IsExpired ());
+      m_blockAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::BlockAckTimeout, this);
+    }
+  else if (m_txParams.MustWaitCompressedBlockAck ())
+    {
+      Time timerDelay = txDuration + GetCompressedBlockAckTimeout ();
+      NS_ASSERT (m_blockAckTimeoutEvent.IsExpired ());
+      m_blockAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::BlockAckTimeout, this);
+    }
   else if (m_txParams.HasNextPacket ()) 
     {
       Time delay = txDuration + GetSifs ();
@@ -1097,7 +1326,17 @@
     } 
   else 
     {
-      if (m_txParams.MustWaitAck ()) 
+      if (m_txParams.MustWaitBasicBlockAck ())
+        {
+          duration += GetSifs ();
+          duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, BASIC_BLOCK_ACK);
+        }
+      else if (m_txParams.MustWaitCompressedBlockAck ())
+        {
+          duration += GetSifs ();
+          duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, COMPRESSED_BLOCK_ACK);
+        }
+      else if (m_txParams.MustWaitAck ()) 
         {
           duration += GetSifs ();
           duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
@@ -1248,4 +1487,365 @@
   ForwardDown (packet, &ack, ackTxMode);
 }
 
+bool
+MacLow::StoreMpduIfNeeded (Ptr<Packet> packet, WifiMacHeader hdr)
+{
+  AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
+  if (it != m_bAckAgreements.end ())
+   {
+     WifiMacTrailer fcs;
+     packet->RemoveTrailer (fcs);
+     BufferedPacket bufferedPacket (packet, hdr);
+
+     uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
+     uint16_t mappedSeqControl = QosUtilsMapSeqControlToUniqueInteger (hdr.GetSequenceControl () ,endSequence);
+
+     BufferedPacketI i = (*it).second.second.begin ();
+     for (; i != (*it).second.second.end () &&
+            QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceControl (), endSequence) < mappedSeqControl; i++);
+     (*it).second.second.insert (i, bufferedPacket);
+     return true;
+   }
+  return false;
+}
+
+void
+MacLow::CreateBlockAckAgreement (const MgtAddBaResponseHeader *respHdr, Mac48Address originator,
+                                 uint16_t startingSeq)
+{
+  uint8_t tid = respHdr->GetTid ();
+  BlockAckAgreement agreement (originator, tid);
+  if (respHdr->IsImmediateBlockAck ())
+    {
+      agreement.SetImmediateBlockAck ();
+    }
+  else
+    {
+      agreement.SetDelayedBlockAck ();
+    }
+  agreement.SetAmsduSupport (respHdr->IsAmsduSupported ());
+  agreement.SetBufferSize (respHdr->GetBufferSize ());
+  agreement.SetTimeout (respHdr->GetTimeout ());
+  agreement.SetStartingSequence (startingSeq);
+  
+  std::list<BufferedPacket> buffer (0);
+  AgreementKey key (originator, respHdr->GetTid ());
+  AgreementValue value (agreement, buffer);
+  m_bAckAgreements.insert (std::make_pair (key, value));
+  
+  if (respHdr->GetTimeout () != 0)
+    {
+      AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, respHdr->GetTid ()));
+      Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
+ 
+      AccessClass ac = QosUtilsMapTidToAc (agreement.GetTid ());
+      
+      it->second.first.m_inactivityEvent = Simulator::Schedule (timeout,
+                                                                &MacLowBlockAckEventListener::BlockAckInactivityTimeout,
+                                                                m_edcaListeners[ac],
+                                                                originator, tid);
+    }
+}
+
+void
+MacLow::DestroyBlockAckAgreement (Mac48Address originator, uint8_t tid)
+{
+  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
+  if (it != m_bAckAgreements.end ())
+    {
+      RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (), originator, tid);
+      RxCompleteBufferedPackets (originator, tid);
+      m_bAckAgreements.erase (it);
+    }
+}
+
+void
+MacLow::RxCompleteBufferedPacketsWithSmallerSequence (uint16_t seq, Mac48Address originator, uint8_t tid)
+{
+  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
+  if (it != m_bAckAgreements.end ())
+    {
+      BufferedPacketI i = (*it).second.second.begin ();
+      uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
+      uint16_t mappedStart = QosUtilsMapSeqControlToUniqueInteger (seq, endSequence);
+      uint16_t guard = (*it).second.first.GetStartingSequence ();
+      BufferedPacketI last = (*it).second.second.begin ();
+
+      for (; i != (*it).second.second.end () &&
+             QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceNumber (), endSequence) < mappedStart;)
+        {
+          while (i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl ())
+            {
+              if (!(*i).second.IsMoreFragments ())
+                {
+                  while (last != i)
+                    {
+                      m_rxCallback ((*last).first, &(*last).second);
+                      last++;
+                    }
+                  m_rxCallback ((*last).first, &(*last).second);
+                  last++;
+                }
+              guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
+            }
+          /* go to next packet */
+          while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
+            {
+              i++;
+            }
+          if (i != (*it).second.second.end ())
+            {
+              guard = (*i).second.GetSequenceControl () & 0xfff0;
+              last = i;
+            }
+        }
+      (*it).second.second.erase ((*it).second.second.begin (), i);
+    }
+}
+
+void
+MacLow::RxCompleteBufferedPackets (Mac48Address originator, uint8_t tid)
+{
+  AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
+  if (it != m_bAckAgreements.end ())
+    {
+      uint16_t startingSeqCtrl = ((*it).second.first.GetStartingSequence ()<<4) & 0xfff0;
+      uint16_t guard = startingSeqCtrl;
+
+      BufferedPacketI lastComplete = (*it).second.second.begin ();
+      BufferedPacketI i = (*it).second.second.begin ();
+      for (;i != (*it).second.second.end() && guard == (*i).second.GetSequenceControl (); i++)
+        {
+          if (!(*i).second.IsMoreFragments ())
+            {
+              while (lastComplete != i)
+                {
+                  m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
+                  lastComplete++;
+                }
+               m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
+               lastComplete++;
+            }
+          guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
+        }
+      (*it).second.first.SetStartingSequence ((guard>>4)&0x0fff);
+      /* All packets already forwarded to WifiMac must be removed from buffer: 
+      [begin (), lastComplete) */
+      (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
+    }
+}
+
+void
+MacLow::SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Address originator, bool immediate,
+                              Time duration, WifiMode blockAckReqTxMode)
+{
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->AddHeader (*blockAck);
+
+  WifiMacHeader hdr;
+  hdr.SetType (WIFI_MAC_CTL_BACKRESP);
+  hdr.SetAddr1 (originator);
+  hdr.SetAddr2 (GetAddress ());
+  hdr.SetDsNotFrom ();
+  hdr.SetDsNotTo ();
+  hdr.SetNoRetry ();
+  hdr.SetNoMoreFragments ();
+
+  m_currentPacket = packet;
+  m_currentHdr = hdr;
+  if (immediate)
+    {
+      m_txParams.DisableAck ();
+      duration -= GetSifs ();
+      if (blockAck->IsBasic ())
+        {
+          duration -= GetBlockAckDuration (originator, blockAckReqTxMode, BASIC_BLOCK_ACK);
+        }
+      else if (blockAck->IsCompressed ())
+        {
+          duration -= GetBlockAckDuration (originator, blockAckReqTxMode, COMPRESSED_BLOCK_ACK);
+        }
+      else if (blockAck->IsMultiTid ())
+        {
+          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+        }
+    }
+  else
+    {
+      m_txParams.EnableAck ();
+      duration += GetSifs ();
+      duration += GetAckDuration (originator, blockAckReqTxMode);
+    }
+  m_txParams.DisableNextData ();
+
+  StartDataTxTimers ();
+
+  NS_ASSERT (duration >= MicroSeconds (0));
+  hdr.SetDuration (duration);
+  //here should be present a control about immediate or delayed block ack
+  //for now we assume immediate
+  packet->AddHeader (hdr);
+  WifiMacTrailer fcs;
+  packet->AddTrailer (fcs);
+  ForwardDown (packet, &hdr, blockAckReqTxMode);
+  m_currentPacket = 0;
+}
+
+void
+MacLow::SendBlockAckAfterBlockAckRequest (const CtrlBAckRequestHeader reqHdr, Mac48Address originator,
+                                          Time duration, WifiMode blockAckReqTxMode)
+{
+  NS_LOG_FUNCTION (this);
+  CtrlBAckResponseHeader blockAck;
+  uint8_t tid;
+  bool immediate = false;
+  if (!reqHdr.IsMultiTid ())
+    {
+      blockAck.SetStartingSequence (reqHdr.GetStartingSequence ());
+      blockAck.SetTidInfo (reqHdr.GetTidInfo ());
+      
+      tid = reqHdr.GetTidInfo ();
+      AgreementsI it;
+      it = m_bAckAgreements.find (std::make_pair (originator, tid));
+      if (it != m_bAckAgreements.end ())
+        {
+          immediate = (*it).second.first.IsImmediateBlockAck ();
+          uint16_t startingSeqCtrl = reqHdr.GetStartingSequenceControl ();
+
+          /* All packets with smaller sequence than starting sequence control must be passed up to Wifimac 
+           * See 9.10.3 in IEEE8022.11e standard.
+           */
+          RxCompleteBufferedPacketsWithSmallerSequence ((startingSeqCtrl>>4)&0xfff0, originator, tid);
+
+          std::list<BufferedPacket>::iterator i = (*it).second.second.begin ();
+
+          /* For more details about next operations see section 9.10.4 of IEEE802.11e standard */
+          if (reqHdr.IsBasic ())
+            {
+              blockAck.SetType (BASIC_BLOCK_ACK);
+              uint16_t guard = startingSeqCtrl;
+              std::list<BufferedPacket>::iterator lastComplete = (*it).second.second.begin ();
+              for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
+                {
+                  blockAck.SetReceivedFragment ((*i).second.GetSequenceNumber (),
+                                                (*i).second.GetFragmentNumber ());
+                   /* Section 9.10.4 in IEEE802.11n: the recipient shall pass up to WifiMac the 
+                    * MSDUs and A-MSDUs starting with the starting sequence number 
+                    * sequentially until there is an incomplete MSDU or A-MSDU in the buffer */
+                  if (!(*i).second.IsMoreFragments ())
+                    {
+                      while (lastComplete != i)
+                        {
+                          m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
+                          lastComplete++;
+                        }
+                      m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
+                      lastComplete++;
+                    }
+                  guard = (*i).second.IsMoreFragments () ? (guard + 1) : (guard + 16) & 0xfff0;
+                }
+              (*it).second.first.SetStartingSequence ((guard>>4)&0x0fff);
+              /* All packets already forwarded to WifiMac must be removed from buffer: 
+                 [begin (), lastComplete) */
+              (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
+              for (i = lastComplete; i != (*it).second.second.end (); i++)
+                { 
+                  blockAck.SetReceivedFragment ((*i).second.GetSequenceNumber (),
+                                                (*i).second.GetFragmentNumber ());  
+                }
+            }
+          else if (reqHdr.IsCompressed ())
+            {
+              blockAck.SetType (COMPRESSED_BLOCK_ACK);
+              uint16_t guard = startingSeqCtrl;
+              std::list<BufferedPacket>::iterator lastComplete = (*it).second.second.begin ();
+              for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
+                {
+                  if (!(*i).second.IsMoreFragments ())
+                    {
+                      blockAck.SetReceivedPacket ((*i).second.GetSequenceNumber ());
+                      while (lastComplete != i)
+                        {
+                          m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
+                          lastComplete++;
+                        }
+                      m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
+                      lastComplete++;
+                    }
+                  guard = (*i).second.IsMoreFragments () ? (guard + 1) : (guard + 16) & 0xfff0;
+                }
+              (*it).second.first.SetStartingSequence ((guard>>4)&0x0fff);
+              /* All packets already forwarded to WifiMac must be removed from buffer:
+                 [begin (), lastcomplete) */
+              (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
+              i = lastComplete;
+              if (i != (*it).second.second.end ())
+                {
+                  guard = (*i).second.GetSequenceControl () & 0xfff0;
+                }
+              for (; i != (*it).second.second.end ();)
+                {
+                  for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
+                    {
+                      if (!(*i).second.IsMoreFragments ())
+                        {
+                          guard = (guard + 16) & 0xfff0;
+                          blockAck.SetReceivedPacket ((*i).second.GetSequenceNumber ());
+                        }
+                      else
+                        {
+                          guard += 1;
+                        }
+                    }
+                  while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
+                    {
+                      i++;
+                    }
+                  if (i != (*it).second.second.end ())
+                    {
+                      guard = (*i).second.GetSequenceControl () & 0xfff0;
+                    }
+                }
+            }
+        }
+      else
+        {
+          NS_LOG_DEBUG ("there's not a valid block ack agreement with "<<originator);
+        }
+    }
+  else
+    {
+      NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
+    }
+
+  SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckReqTxMode);
+}
+
+void
+MacLow::ResetBlockAckInactivityTimerIfNeeded (BlockAckAgreement &agreement)
+{
+  if (agreement.GetTimeout () != 0)
+    {
+      NS_ASSERT (agreement.m_inactivityEvent.IsRunning ());
+      agreement.m_inactivityEvent.Cancel ();
+      Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
+
+      AccessClass ac = QosUtilsMapTidToAc (agreement.GetTid ());
+      //std::map<AccessClass, MacLowTransmissionListener*>::iterator it = m_edcaListeners.find (ac);
+      //NS_ASSERT (it != m_edcaListeners.end ());
+
+      agreement.m_inactivityEvent = Simulator::Schedule (timeout, 
+                                                         &MacLowBlockAckEventListener::BlockAckInactivityTimeout, 
+                                                         m_edcaListeners[ac],
+                                                         agreement.GetPeer (),
+                                                         agreement.GetTid ());
+    }
+}
+
+void
+MacLow::RegisterBlockAckListenerForAc (enum AccessClass ac, MacLowBlockAckEventListener *listener)
+{
+  m_edcaListeners.insert (std::make_pair (ac, listener));
+}
+
 } // namespace ns3
--- a/src/devices/wifi/mac-low.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/mac-low.h	Thu Feb 25 14:17:21 2010 +0100
@@ -1,6 +1,7 @@
 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
 /*
  * Copyright (c) 2005, 2006 INRIA
+ * Copyright (c) 2009 MIRKO BANCHI
  *
  * 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 
@@ -16,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
  */
 #ifndef MAC_LOW_H
 #define MAC_LOW_H
@@ -23,21 +25,27 @@
 #include <vector>
 #include <stdint.h>
 #include <ostream>
+#include <map>
 
 #include "wifi-mac-header.h"
 #include "wifi-mode.h"
 #include "wifi-preamble.h"
 #include "wifi-remote-station-manager.h"
+#include "ctrl-headers.h"
+#include "mgt-headers.h"
+#include "block-ack-agreement.h"
 #include "ns3/mac48-address.h"
 #include "ns3/callback.h"
 #include "ns3/event-id.h"
 #include "ns3/packet.h"
 #include "ns3/nstime.h"
+#include "qos-utils.h"
 
 namespace ns3 {
 
 class WifiPhy;
 class WifiMac;
+class EdcaTxopN;
 
 /**
  * \brief listen to events coming from ns3::MacLow.
@@ -76,6 +84,29 @@
    */
   virtual void MissedAck (void) = 0;
   /**
+   * \param blockAck Block ack response header
+   * \param source Address of block ack sender
+   *
+   * Invoked when ns3::MacLow receives a block ack frame.
+   * Block ack frame is received after a block ack request
+   * and contains information about the correct reception 
+   * of a set of packet for which a normal ack wasn't send.
+   * Default implementation for this method is empty. Every
+   * queue that intends to be notified by MacLow of reception
+   * of a block ack must redefine this function.
+   */
+  virtual void GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address source);
+  /**
+   * ns3::MacLow did not receive an expected BLOCK_ACK within
+   * BlockAckTimeout. This method is used only for immediate 
+   * block ack variant. With delayed block ack, the MissedAck method will be
+   * called instead: upon receipt of a block ack request, the rx station will
+   * reply with a normal ack frame. Later, when the rx station gets a txop, it
+   * will send the block ack back to the tx station which will reply with a
+   * normal ack to the rx station.
+   */
+  virtual void MissedBlockAck (void);
+  /**
    * Invoked when ns3::MacLow wants to start a new transmission
    * as configured by MacLowTransmissionParameters::EnableNextData.
    * The listener is expected to call again MacLow::StartTransmission
@@ -119,6 +150,25 @@
 };
 
 /**
+ * \brief listen for block ack events.
+ */
+class MacLowBlockAckEventListener {
+public:
+  MacLowBlockAckEventListener ();
+  virtual ~MacLowBlockAckEventListener ();
+  /**
+   * Typically is called in order to notify EdcaTxopN that a block ack inactivity
+   * timeout occurs for the block ack agreement identified by the pair <i>originator</i>, <i>tid</i>.
+   * 
+   * Rx station maintains an inactivity timer for each block ack
+   * agreement. Timer is reset when a frame with ack policy block ack
+   * or a block ack request are received. When this timer reaches zero
+   * this method is called and a delba frame is scheduled for transmission.
+   */
+  virtual void BlockAckInactivityTimeout (Mac48Address originator, uint8_t tid) = 0;
+};
+
+/**
  * \brief control how a packet is transmitted.
  *
  * The ns3::MacLow::StartTransmission method expects
@@ -157,6 +207,18 @@
    */
   void EnableSuperFastAck (void);
   /**
+   * Wait BASICBLOCKACKTimeout for a Basic Block Ack Response frame.
+   */
+  void EnableBasicBlockAck (void);
+  /**
+   * Wait COMPRESSEDBLOCKACKTimeout for a Compressed Block Ack Response frame.
+   */
+  void EnableCompressedBlockAck (void);
+  /**
+   * NOT IMPLEMENTED FOR NOW
+   */
+  void EnableMultiTidBlockAck (void);
+  /**
    * Send a RTS, and wait CTSTimeout for a CTS. If we get a 
    * CTS on time, call MacLowTransmissionListener::GotCts
    * and send data. Otherwise, call MacLowTransmissionListener::MissedCts
@@ -233,6 +295,24 @@
    */
   bool MustWaitSuperFastAck (void) const;
   /**
+   * \returns true if block ack mechanism is used, false otherwise.
+   *
+   * \sa EnableBlockAck
+   */
+  bool MustWaitBasicBlockAck (void) const;
+  /**
+   * \returns true if compressed block ack mechanism is used, false otherwise.
+   *
+   * \sa EnableCompressedBlockAck
+   */
+  bool MustWaitCompressedBlockAck (void) const;
+  /**
+   * \returns true if multi-tid block ack mechanism is used, false otherwise.
+   *
+   * \sa EnableMultiTidBlockAck
+   */
+  bool MustWaitMultiTidBlockAck (void) const;
+  /**
    * \returns true if RTS should be sent and CTS waited for before 
    *          sending data, false otherwise.
    */
@@ -262,7 +342,10 @@
     ACK_NONE,
     ACK_NORMAL,
     ACK_FAST,
-    ACK_SUPER_FAST
+    ACK_SUPER_FAST,
+    BLOCK_ACK_BASIC,
+    BLOCK_ACK_COMPRESSED,
+    BLOCK_ACK_MULTI_TID
   } m_waitAck;
   bool m_sendRts;
   Time m_overrideDurationId;
@@ -286,6 +369,8 @@
 
   void SetAddress (Mac48Address ad);
   void SetAckTimeout (Time ackTimeout);
+  void SetBasicBlockAckTimeout (Time blockAckTimeout);
+  void SetCompressedBlockAckTimeout (Time blockAckTimeout);
   void SetCtsTimeout (Time ctsTimeout);
   void SetSifs (Time sifs);
   void SetSlotTime (Time slotTime);
@@ -293,6 +378,8 @@
   void SetBssid (Mac48Address ad);
   Mac48Address GetAddress (void) const;
   Time GetAckTimeout (void) const;
+  Time GetBasicBlockAckTimeout () const;
+  Time GetCompressedBlockAckTimeout () const;
   Time GetCtsTimeout (void) const;
   Time GetSifs (void) const;
   Time GetSlotTime (void) const;
@@ -364,9 +451,39 @@
    * occurs, pending MAC transmissions (RTS, CTS, DATA and ACK) are cancelled.
    */
   void NotifySwitchingStartNow (Time duration); 
+  /**
+   * \param respHdr Add block ack response from originator (action frame).
+   * \param originator Address of peer station involved in block ack mechanism.
+   * \param startingSeq Sequence number of the first MPDU of all packets for which block ack was negotiated.
+   * 
+   * This function is typically invoked only by ns3::QapWifiMac and ns3::QstaWifiMac.
+   * If we are transmitting an Add block ack response, MacLow must allocate buffers to collect
+   * all correctly received packets belonging to category for which block ack was negotiated.
+   * It's needed in order to send a Block ack after corresponding originator's Block ack request.
+   */
+  void CreateBlockAckAgreement (const MgtAddBaResponseHeader *respHdr, Mac48Address originator,
+                                uint16_t startingSeq);
+  /**
+   * \param originator Address of peer partecipating in Block Ack mechanism.
+   * \param tid TID for which Block Ack was created.
+   *
+   * Checks if exists an established block ack agreement with <i>originator</i>
+   * for tid <i>tid</i>. If the agreement exists, tears down it. This function is typically
+   * invoked when a DELBA frame is received from <i>originator</i>.
+   */
+  void DestroyBlockAckAgreement (Mac48Address originator, uint8_t tid);
+  /**
+   * \param ac Access class managed by the queue.
+   * \param listener The listener for the queue.
+   *
+   * The lifetime of the registered listener is typically equal to the lifetime of the queue
+   * associated to this AC.
+   */
+  void RegisterBlockAckListenerForAc (enum AccessClass ac, MacLowBlockAckEventListener *listener);
 private:
   void CancelAllEvents (void);
   uint32_t GetAckSize (void) const;
+  uint32_t GetBlockAckSize (enum BlockAckType type) const;
   uint32_t GetRtsSize (void) const;
   uint32_t GetCtsSize (void) const;
   uint32_t GetSize (Ptr<const Packet> packet, const WifiMacHeader *hdr) const;
@@ -380,8 +497,10 @@
   WifiMode GetDataTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const;
   WifiMode GetCtsTxModeForRts (Mac48Address to, WifiMode rtsTxMode) const;
   WifiMode GetAckTxModeForData (Mac48Address to, WifiMode dataTxMode) const;
+
   Time GetCtsDuration (Mac48Address to, WifiMode rtsTxMode) const;
   Time GetAckDuration (Mac48Address to, WifiMode dataTxMode) const;
+  Time GetBlockAckDuration (Mac48Address to, WifiMode blockAckReqTxMode, enum BlockAckType type) const;
   void NotifyNav (const WifiMacHeader &hdr, WifiMode txMode, WifiPreamble preamble);
   void DoNavResetNow (Time duration);
   bool DoNavStartNow (Time duration);
@@ -397,6 +516,7 @@
   void FastAckTimeout (void);
   void SuperFastAckTimeout (void);
   void FastAckFailedTimeout (void);
+  void BlockAckTimeout (void);
   void CtsTimeout (void);
   void SendCtsAfterRts (Mac48Address source, Time duration, WifiMode txMode, double rtsSnr);
   void SendAckAfterData (Mac48Address source, Time duration, WifiMode txMode, double rtsSnr);
@@ -408,6 +528,53 @@
   void SendCurrentTxPacket (void);
   void StartDataTxTimers (void);
   virtual void DoDispose (void);
+  /**
+   * \param originator Address of peer partecipating in Block Ack mechanism.
+   * \param tid TID for which Block Ack was created.
+   * \param seq Starting sequence
+   *
+   * This function forward up all completed "old" packets with sequence number
+   * smaller than <i>seq</i>. All comparison are performed circularly mod 4096.
+   */
+  void RxCompleteBufferedPacketsWithSmallerSequence (uint16_t seq, Mac48Address originator, uint8_t tid);
+  /**
+   * \param originator Address of peer partecipating in Block Ack mechanism.
+   * \param tid TID for which Block Ack was created.
+   *
+   * This method is typically invoked when a MPDU with ack policy
+   * subfield set to Normal Ack is received and a block ack agreement
+   * for that packet exists.
+   * This happens when the originator of block ack has only few MPDUs to send.
+   * All completed MSDUs starting with starting sequence number of block ack
+   * agreement are forward up to WifiMac until there is an incomplete MSDU.
+   * See section 9.10.4 in IEEE802.11 standard for more details.
+   */
+  void RxCompleteBufferedPackets (Mac48Address originator, uint8_t tid);
+  /* 
+   * This method checks if exists a valid established block ack agreement. 
+   * If there is, store the packet without pass it up to WifiMac. The packet is buffered
+   * in order of increasing sequence control field. All comparison are performed
+   * circularly modulo 2^12.
+   */
+  bool StoreMpduIfNeeded (Ptr<Packet> packet, WifiMacHeader hdr);
+  /*
+   * Invoked after that a block ack request has been received. Looks for corresponding
+   * block ack agreement and creates block ack bitmap on a received packets basis.
+   */
+  void SendBlockAckAfterBlockAckRequest (const CtrlBAckRequestHeader reqHdr, Mac48Address originator,
+                                         Time duration, WifiMode blockAckReqTxMode);
+  /*
+   * This method creates block ack frame with header equals to <i>blockAck</i> and start its transmission.
+   */
+  void SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Address originator, bool immediate,
+                             Time duration, WifiMode blockAckReqTxMode);
+  /*
+   * Every time that a block ack request or a packet with ack policy equals to <i>block ack</i>
+   * are received, if a relative block ack agreement exists and the value of inactivity timeout
+   * is not 0, the timer is reset.
+   * see section 11.5.3 in IEEE802.11e for more details.
+   */
+  void ResetBlockAckInactivityTimerIfNeeded (BlockAckAgreement &agreement);
 
   void SetupPhyMacLowListener (Ptr<WifiPhy> phy); 
 
@@ -422,6 +589,7 @@
   EventId m_fastAckTimeoutEvent;
   EventId m_superFastAckTimeoutEvent;
   EventId m_fastAckFailedTimeoutEvent;
+  EventId m_blockAckTimeoutEvent;
   EventId m_ctsTimeoutEvent;
   EventId m_sendCtsEvent;
   EventId m_sendAckEvent;
@@ -436,6 +604,8 @@
   Mac48Address m_self;
   Mac48Address m_bssid;
   Time m_ackTimeout;
+  Time m_basicBlockAckTimeout;
+  Time m_compressedBlockAckTimeout;
   Time m_ctsTimeout;
   Time m_sifs;
   Time m_slotTime;
@@ -446,6 +616,23 @@
 
   // Listerner needed to monitor when a channel switching occurs. 
   class PhyMacLowListener *m_phyMacLowListener; 
+
+  /*
+   * BlockAck data structures.
+   */
+  typedef std::pair<Ptr<Packet>, WifiMacHeader> BufferedPacket;
+  typedef std::list<BufferedPacket>::iterator BufferedPacketI;
+
+  typedef std::pair<Mac48Address, uint8_t> AgreementKey;
+  typedef std::pair<BlockAckAgreement, std::list<BufferedPacket> > AgreementValue;
+
+  typedef std::map<AgreementKey, AgreementValue> Agreements;
+  typedef std::map<AgreementKey, AgreementValue>::iterator AgreementsI;
+
+  Agreements m_bAckAgreements;
+  
+  typedef std::map<AccessClass, MacLowBlockAckEventListener*> QueueListeners;
+  QueueListeners m_edcaListeners;
 };
 
 } // namespace ns3
--- a/src/devices/wifi/mac-tx-middle.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/mac-tx-middle.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -77,4 +77,17 @@
   return retval;
 }
 
+uint16_t
+MacTxMiddle::GetNextSeqNumberByTidAndAddress (uint8_t tid, Mac48Address addr) const
+{
+  NS_ASSERT (tid < 16);
+  uint16_t seq = 0;
+  std::map <Mac48Address,uint16_t*>::const_iterator it = m_qosSequences.find (addr);
+  if (it != m_qosSequences.end ())
+    {
+      return it->second[tid];
+    }
+  return seq;
+}
+
 } // namespace ns3
--- a/src/devices/wifi/mac-tx-middle.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/mac-tx-middle.h	Thu Feb 25 14:17:21 2010 +0100
@@ -37,6 +37,7 @@
   ~MacTxMiddle ();
 
   uint16_t GetNextSequenceNumberfor (const WifiMacHeader *hdr);
+  uint16_t GetNextSeqNumberByTidAndAddress (uint8_t tid, Mac48Address addr) const;
 
 private:
   std::map <Mac48Address,uint16_t*> m_qosSequences;
--- a/src/devices/wifi/mgt-headers.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/mgt-headers.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -1,6 +1,7 @@
 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
 /*
  * Copyright (c) 2006 INRIA
+ * Copyright (c) 2009 MIRKO BANCHI
  *
  * 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 
@@ -16,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
  */
 #include "mgt-headers.h"
 #include "ns3/simulator.h"
@@ -405,6 +407,11 @@
 
   switch (type)
     {
+  case BLOCK_ACK:
+    {
+      m_actionValue = action.blockAck;
+      break;
+    }
   case MESH_PEERING_MGT:
     {
       m_actionValue = action.peerLink;
@@ -427,6 +434,8 @@
 {
   switch (m_category)
     {
+  case BLOCK_ACK:
+    return BLOCK_ACK;
   case MESH_PEERING_MGT:
     return MESH_PEERING_MGT;
   case MESH_LINK_METRIC:
@@ -451,6 +460,19 @@
   retval.peerLink = PEER_LINK_OPEN; // Needs to be initialized to something to quiet valgrind in default cases
   switch (m_category)
     {
+  case BLOCK_ACK:
+    switch (m_actionValue)
+      {
+    case BLOCK_ACK_ADDBA_REQUEST:
+      retval.blockAck = BLOCK_ACK_ADDBA_REQUEST;
+      return retval;
+    case BLOCK_ACK_ADDBA_RESPONSE:
+      retval.blockAck = BLOCK_ACK_ADDBA_RESPONSE;
+      return retval;
+    case BLOCK_ACK_DELBA:
+      retval.blockAck = BLOCK_ACK_DELBA;
+      return retval;
+      }
   case MESH_PEERING_MGT:
     switch (m_actionValue)
       {
@@ -528,4 +550,449 @@
   return i.GetDistanceFrom (start);
 }
 
+/***************************************************
+*                 ADDBARequest
+****************************************************/
+
+NS_OBJECT_ENSURE_REGISTERED (MgtAddBaRequestHeader);
+
+MgtAddBaRequestHeader::MgtAddBaRequestHeader ()
+ : m_dialogToken (1),
+   m_amsduSupport (1),
+   m_bufferSize (0)
+{}
+
+TypeId
+MgtAddBaRequestHeader::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::MgtAddBaRequestHeader")
+    .SetParent<Header> ()
+    .AddConstructor<MgtAddBaRequestHeader> ();
+  ;
+  return tid;
+}
+
+TypeId
+MgtAddBaRequestHeader::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+void
+MgtAddBaRequestHeader::Print (std::ostream &os) const
+{}
+
+uint32_t
+MgtAddBaRequestHeader::GetSerializedSize (void) const
+{
+  uint32_t size = 0;
+  size += 1; //Dialog token
+  size += 2; //Block ack parameter set
+  size += 2; //Block ack timeout value
+  size += 2; //Starting sequence control
+  return size;
+}
+
+void
+MgtAddBaRequestHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+  i.WriteU8 (m_dialogToken);
+  i.WriteHtolsbU16 (GetParameterSet ());
+  i.WriteHtolsbU16 (m_timeoutValue);
+  i.WriteHtolsbU16 (GetStartingSequenceControl ());
+}
+
+uint32_t
+MgtAddBaRequestHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  m_dialogToken = i.ReadU8 ();
+  SetParameterSet (i.ReadLsbtohU16 ());
+  m_timeoutValue = i.ReadLsbtohU16 ();
+  SetStartingSequenceControl (i.ReadLsbtohU16 ());
+  return i.GetDistanceFrom (start);
+}
+
+void
+MgtAddBaRequestHeader::SetDelayedBlockAck ()
+{
+  m_policy = 0;
+}
+
+void
+MgtAddBaRequestHeader::SetImmediateBlockAck ()
+{
+  m_policy = 1;
+}
+  
+void
+MgtAddBaRequestHeader::SetTid (uint8_t tid)
+{
+  NS_ASSERT (tid < 16);
+  m_tid = tid;
+}
+
+void
+MgtAddBaRequestHeader::SetTimeout (uint16_t timeout)
+{
+  m_timeoutValue = timeout;
+}
+
+void
+MgtAddBaRequestHeader::SetBufferSize (uint16_t size)
+{
+  m_bufferSize = size;
+}
+
+void
+MgtAddBaRequestHeader::SetStartingSequence (uint16_t seq)
+{
+  m_startingSeq = seq;
+}
+
+void
+MgtAddBaRequestHeader::SetAmsduSupport (bool supported)
+{
+  m_amsduSupport = supported;
+}
+
+uint8_t
+MgtAddBaRequestHeader::GetTid (void) const
+{
+  return m_tid;
+}
+
+bool
+MgtAddBaRequestHeader::IsImmediateBlockAck (void) const
+{
+  return (m_policy == 1)?true:false;
+}
+
+uint16_t
+MgtAddBaRequestHeader::GetTimeout (void) const
+{
+  return m_timeoutValue;
+}
+
+uint16_t
+MgtAddBaRequestHeader::GetBufferSize (void) const
+{
+  return m_bufferSize;
+}
+
+bool
+MgtAddBaRequestHeader::IsAmsduSupported (void) const
+{
+  return (m_amsduSupport == 1)?true:false;
+}
+
+uint16_t
+MgtAddBaRequestHeader::GetStartingSequence (void) const
+{
+  return m_startingSeq;
+}
+
+uint16_t
+MgtAddBaRequestHeader::GetStartingSequenceControl (void) const
+{
+  return (m_startingSeq << 4) & 0xfff0;
+}
+
+void
+MgtAddBaRequestHeader::SetStartingSequenceControl (uint16_t seqControl)
+{
+  m_startingSeq = (seqControl >> 4) & 0x0fff;
+}
+
+uint16_t
+MgtAddBaRequestHeader::GetParameterSet (void) const
+{
+  uint16_t res = 0;
+  res |= m_amsduSupport;
+  res |= m_policy << 1;
+  res |= m_tid << 2;
+  res |= m_bufferSize << 6;
+  return res;
+}
+
+void
+MgtAddBaRequestHeader::SetParameterSet (uint16_t params)
+{
+  m_amsduSupport = (params) & 0x01;
+  m_policy = (params >> 1) & 0x01;
+  m_tid = (params >> 2) & 0x0f;
+  m_bufferSize = (params >> 6) & 0x03ff;
+}
+
+/***************************************************
+*                 ADDBAResponse
+****************************************************/
+
+NS_OBJECT_ENSURE_REGISTERED (MgtAddBaResponseHeader);
+
+MgtAddBaResponseHeader::MgtAddBaResponseHeader ()
+  : m_dialogToken (1),
+    m_amsduSupport (1),
+    m_bufferSize (0)
+{}
+
+TypeId
+MgtAddBaResponseHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::MgtAddBaResponseHeader")
+    .SetParent<Header> ()
+    .AddConstructor<MgtAddBaResponseHeader> ()
+  ;
+  return tid;
+}
+
+TypeId
+MgtAddBaResponseHeader::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+void
+MgtAddBaResponseHeader::Print (std::ostream &os) const
+{
+  os <<"status code="<<m_code;
+}
+
+uint32_t
+MgtAddBaResponseHeader::GetSerializedSize (void) const
+{
+  uint32_t size = 0;
+  size += 1; //Dialog token
+  size += m_code.GetSerializedSize (); //Status code
+  size += 2; //Block ack parameter set
+  size += 2; //Block ack timeout value
+  return size;
+}
+
+void
+MgtAddBaResponseHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+  i.WriteU8 (m_dialogToken);
+  i = m_code.Serialize (i);
+  i.WriteHtolsbU16 (GetParameterSet ());
+  i.WriteHtolsbU16 (m_timeoutValue);
+}
+
+uint32_t
+MgtAddBaResponseHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  m_dialogToken = i.ReadU8 ();
+  i = m_code.Deserialize (i);
+  SetParameterSet (i.ReadLsbtohU16 ());
+  m_timeoutValue = i.ReadLsbtohU16 ();
+  return i.GetDistanceFrom (start);
+}
+
+void
+MgtAddBaResponseHeader::SetDelayedBlockAck ()
+{
+  m_policy = 0;
+}
+
+void
+MgtAddBaResponseHeader::SetImmediateBlockAck ()
+{
+  m_policy = 1;
+}
+
+void
+MgtAddBaResponseHeader::SetTid (uint8_t tid)
+{
+  NS_ASSERT (tid < 16);
+  m_tid = tid;
+}
+
+void
+MgtAddBaResponseHeader::SetTimeout (uint16_t timeout)
+{
+  m_timeoutValue = timeout;
+}
+
+void
+MgtAddBaResponseHeader::SetBufferSize (uint16_t size)
+{
+  m_bufferSize = size;
+}
+
+void
+MgtAddBaResponseHeader::SetStatusCode (StatusCode code)
+{
+  m_code = code;
+}
+
+void
+MgtAddBaResponseHeader::SetAmsduSupport (bool supported)
+{
+  m_amsduSupport = supported;
+}
+
+StatusCode
+MgtAddBaResponseHeader::GetStatusCode (void) const
+{
+  return m_code;
+}
+
+uint8_t
+MgtAddBaResponseHeader::GetTid (void) const
+{
+  return m_tid;
+}
+
+bool
+MgtAddBaResponseHeader::IsImmediateBlockAck (void) const
+{
+  return (m_policy == 1)?true:false;
+}
+
+uint16_t
+MgtAddBaResponseHeader::GetTimeout (void) const
+{
+  return m_timeoutValue;
+}
+
+uint16_t
+MgtAddBaResponseHeader::GetBufferSize (void) const
+{
+  return m_bufferSize;
+}
+
+bool
+MgtAddBaResponseHeader::IsAmsduSupported (void) const
+{
+  return (m_amsduSupport == 1)?true:false; 
+}
+
+uint16_t
+MgtAddBaResponseHeader::GetParameterSet (void) const
+{
+  uint16_t res = 0;
+  res |= m_amsduSupport;
+  res |= m_policy << 1;
+  res |= m_tid << 2;
+  res |= m_bufferSize << 6;
+  return res;
+}
+
+void
+MgtAddBaResponseHeader::SetParameterSet (uint16_t params)
+{
+  m_amsduSupport = (params) & 0x01;
+  m_policy = (params >> 1) & 0x01;
+  m_tid = (params >> 2) & 0x0f;
+  m_bufferSize = (params >> 6) & 0x03ff;
+}
+
+/***************************************************
+*                     DelBa
+****************************************************/
+
+NS_OBJECT_ENSURE_REGISTERED (MgtDelBaHeader);
+
+MgtDelBaHeader::MgtDelBaHeader ()
+  : m_reasonCode (1)
+{}
+
+TypeId
+MgtDelBaHeader::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::MgtDelBaHeader")
+    .SetParent<Header> ()
+    .AddConstructor<MgtDelBaHeader> ()
+  ;
+  return tid;
+}
+
+TypeId
+MgtDelBaHeader::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+void
+MgtDelBaHeader::Print (std::ostream &os) const
+{}
+
+uint32_t
+MgtDelBaHeader::GetSerializedSize (void) const
+{
+  uint32_t size = 0;
+  size += 2; //DelBa parameter set
+  size += 2; //Reason code
+  return size;
+}
+
+void
+MgtDelBaHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+  i.WriteHtolsbU16 (GetParameterSet ());
+  i.WriteHtolsbU16 (m_reasonCode);
+}
+
+uint32_t
+MgtDelBaHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  SetParameterSet (i.ReadLsbtohU16 ());
+  m_reasonCode = i.ReadLsbtohU16 ();
+  return i.GetDistanceFrom (start);
+}
+
+bool
+MgtDelBaHeader::IsByOriginator (void) const
+{
+  return (m_initiator == 1)?true:false;
+}
+
+uint8_t
+MgtDelBaHeader::GetTid (void) const
+{
+  NS_ASSERT (m_tid < 16);
+  uint8_t tid = static_cast<uint8_t> (m_tid);
+  return tid;
+}
+
+void
+MgtDelBaHeader::SetByOriginator (void)
+{
+  m_initiator = 1;
+}
+
+void
+MgtDelBaHeader::SetByRecipient (void)
+{
+  m_initiator = 0;
+}
+
+void
+MgtDelBaHeader::SetTid (uint8_t tid)
+{
+  NS_ASSERT (tid < 16);
+  m_tid = static_cast<uint16_t> (tid);
+}
+
+uint16_t
+MgtDelBaHeader::GetParameterSet (void) const
+{
+  uint16_t res = 0;
+  res |= m_initiator << 11;
+  res |= m_tid << 12;
+  return res;
+}
+
+void
+MgtDelBaHeader::SetParameterSet (uint16_t params)
+{
+  m_initiator = (params >> 11) & 0x01;
+  m_tid = (params >> 12) & 0x0f;
+}
+
 } // namespace ns3
--- a/src/devices/wifi/mgt-headers.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/mgt-headers.h	Thu Feb 25 14:17:21 2010 +0100
@@ -1,6 +1,7 @@
 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
 /*
  * Copyright (c) 2006 INRIA
+ * Copyright (c) 2009 MIRKO BANCHI
  *
  * 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 
@@ -16,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
  */
 #ifndef MGT_HEADERS_H
 #define MGT_HEADERS_H
@@ -134,6 +136,10 @@
 
 class MgtBeaconHeader : public MgtProbeResponseHeader {};
 
+/****************************
+*     Action frames
+*****************************/
+
 /**
  * \brief See IEEE 802.11 chapter 7.3.1.11
  *
@@ -148,6 +154,7 @@
   /* Compatible with open80211s implementation */
   enum CategoryValue //table 7-24 staring from 4
   {
+    BLOCK_ACK = 3,
     MESH_PEERING_MGT = 30,
     MESH_LINK_METRIC = 31,
     MESH_PATH_SELECTION = 32,
@@ -189,6 +196,12 @@
     TBTT_ADJUSTMENT_REQUEST,
     MESH_CHANNEL_SWITCH_ANNOUNCEMENT,
   };
+  enum BlockAckActionValue
+  {
+    BLOCK_ACK_ADDBA_REQUEST = 0,
+    BLOCK_ACK_ADDBA_RESPONSE = 1,
+    BLOCK_ACK_DELBA = 2
+  };
   typedef union
   {
     enum PeerLinkMgtActionValue peerLink;
@@ -196,6 +209,7 @@
     enum PathSelectionActionValue pathSelection;
     enum InterworkActionValue interwork;
     enum ResourceCoordinationActionValue resourceCoordination;
+    enum BlockAckActionValue blockAck;
   } ActionValue;
   void   SetAction (enum CategoryValue type,ActionValue action);
 
@@ -212,6 +226,115 @@
   uint8_t m_actionValue;
 };
 
+class MgtAddBaRequestHeader : public Header {
+public:
+  
+  MgtAddBaRequestHeader ();
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+  void SetDelayedBlockAck ();
+  void SetImmediateBlockAck ();
+  void SetTid (uint8_t tid);
+  void SetTimeout (uint16_t timeout);
+  void SetBufferSize (uint16_t size);
+  void SetStartingSequence (uint16_t seq);
+  void SetAmsduSupport (bool supported);
+  
+  uint16_t GetStartingSequence (void) const;
+  uint8_t GetTid (void) const;
+  bool IsImmediateBlockAck (void) const;
+  uint16_t GetTimeout (void) const;
+  uint16_t GetBufferSize (void) const;
+  bool IsAmsduSupported (void) const;
+  
+private:
+  uint16_t GetParameterSet (void) const;
+  void SetParameterSet (uint16_t params);
+  uint16_t GetStartingSequenceControl (void) const;
+  void SetStartingSequenceControl (uint16_t seqControl);
+  
+  uint8_t m_dialogToken; /* Not used for now */
+  uint8_t m_amsduSupport;
+  uint8_t m_policy;
+  uint8_t m_tid;
+  uint16_t m_bufferSize;
+  uint16_t m_timeoutValue;
+  uint16_t m_startingSeq;
+};
+ 
+class MgtAddBaResponseHeader : public Header {
+public:
+
+  MgtAddBaResponseHeader ();
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+  void SetDelayedBlockAck ();
+  void SetImmediateBlockAck ();
+  void SetTid (uint8_t tid);
+  void SetTimeout (uint16_t timeout);
+  void SetBufferSize (uint16_t size);
+  void SetStatusCode (StatusCode code);
+  void SetAmsduSupport (bool supported);
+
+  StatusCode GetStatusCode (void) const;
+  uint8_t GetTid (void) const;
+  bool IsImmediateBlockAck (void) const;
+  uint16_t GetTimeout (void) const;
+  uint16_t GetBufferSize (void) const;
+  bool IsAmsduSupported (void) const;
+
+private:
+  uint16_t GetParameterSet (void) const;
+  void SetParameterSet (uint16_t params);
+  
+  uint8_t m_dialogToken; /* Not used for now */
+  StatusCode m_code;
+  uint8_t m_amsduSupport;
+  uint8_t m_policy;
+  uint8_t m_tid;
+  uint16_t m_bufferSize;
+  uint16_t m_timeoutValue;
+};
+
+class MgtDelBaHeader : public Header {
+public:
+  MgtDelBaHeader ();
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+  bool IsByOriginator (void) const;
+  uint8_t GetTid (void) const;
+  void SetTid (uint8_t);
+  void SetByOriginator (void);
+  void SetByRecipient (void);
+
+private:
+  uint16_t GetParameterSet (void) const;
+  void SetParameterSet (uint16_t params);
+
+  uint16_t m_initiator;
+  uint16_t m_tid;
+  /* Not used for now.
+     Always set to 1: "Unspecified reason" */
+  uint16_t m_reasonCode;
+};
 
 } // namespace ns3
 
--- a/src/devices/wifi/msdu-standard-aggregator.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/msdu-standard-aggregator.h	Thu Feb 25 14:17:21 2010 +0100
@@ -32,7 +32,7 @@
   MsduStandardAggregator ();
   ~MsduStandardAggregator ();
   /**
-   * \param packet Packet we have to insert into </i>aggregatedPacket</i>.
+   * \param packet Packet we have to insert into <i>aggregatedPacket</i>.
    * \param aggregatedPacket Packet that will contain <i>packet</i>, if aggregation is possible, 
    * \param src Source address of <i>packet</i>.
    * \param dest Destination address of <i>packet</i>.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/originator-block-ack-agreement.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,82 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * 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: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#include "originator-block-ack-agreement.h"
+
+namespace ns3 {
+
+OriginatorBlockAckAgreement::OriginatorBlockAckAgreement ()
+  : BlockAckAgreement (),
+    m_state (PENDING),
+    m_sentMpdus (0)
+{}
+OriginatorBlockAckAgreement::OriginatorBlockAckAgreement (Mac48Address recipient, uint8_t tid)
+  : BlockAckAgreement (recipient, tid),
+    m_state (PENDING),
+    m_sentMpdus (0)
+{}
+OriginatorBlockAckAgreement::~OriginatorBlockAckAgreement ()
+{}
+void
+OriginatorBlockAckAgreement::SetState (enum State state)
+{
+  m_state = state;
+  if (state == INACTIVE)
+    {
+      m_sentMpdus = 0;
+    }
+}
+bool
+OriginatorBlockAckAgreement::IsPending (void) const
+{
+  return (m_state == PENDING)?true:false;
+}
+bool
+OriginatorBlockAckAgreement::IsEstablished (void) const
+{
+  return (m_state == ESTABLISHED)?true:false;
+}
+bool
+OriginatorBlockAckAgreement::IsInactive (void) const
+{
+  return (m_state == INACTIVE)?true:false;
+}
+bool
+OriginatorBlockAckAgreement::IsUnsuccessful (void) const
+{
+  return (m_state == UNSUCCESSFUL)?true:false;
+}
+void
+OriginatorBlockAckAgreement::NotifyMpduTransmission (void)
+{
+  NS_ASSERT (m_sentMpdus < m_bufferSize);
+  m_sentMpdus++;
+}
+bool
+OriginatorBlockAckAgreement::NeedBlockAckRequest (void) const
+{
+  return (m_sentMpdus == m_bufferSize/2)?true:false;
+}
+void
+OriginatorBlockAckAgreement::CompleteExchange (void)
+{
+  m_sentMpdus = 0;
+}
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/originator-block-ack-agreement.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,115 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * 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: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#ifndef ORIGINATOR_BLOCK_ACK_AGREEMENT_H
+#define ORIGINATOR_BLOCK_ACK_AGREEMENT_H
+
+#include "block-ack-agreement.h"
+
+namespace ns3 {
+
+/* \brief Maintains the state and information about trasmitted MPDUs with ack policy block ack
+ *        for an originator station.
+ */
+class OriginatorBlockAckAgreement : public BlockAckAgreement
+{
+  friend class BlockAckManager;
+public:
+  OriginatorBlockAckAgreement ();
+  OriginatorBlockAckAgreement (Mac48Address recipient, uint8_t tid);
+  ~OriginatorBlockAckAgreement ();
+  /*                                      receive ADDBAResponse
+   *  send ADDBARequest ---------------   status code = success  ---------------
+   *  ----------------->|   PENDING    |------------------------>|  ESTABLISHED |-----
+   *                    ---------------                          ---------------      |
+   *                          |                                    /   ^    ^         |
+   *   receive ADDBAResponse  |                receive BlockAck   /    |    |         | receive BlockAck
+   *   status code = failure  |           retryPkts + queuePkts  /     |    |         | retryPkts + queuePkts
+   *                          v                     <           /      |    |         |           >=
+   *                   ---------------     blockAckThreshold   /       |    |         | blockAckThreshold
+   *                   | UNSUCCESSFUL |                       /        |    |         |
+   *                   ---------------                       v         |    ----------|
+   *                                            --------------         |      
+   *                                            |  INACTIVE   |        |  
+   *                                            --------------         |
+   *                        send a MPDU (Normal Ack)   |               |
+   *                        retryPkts + queuePkts      |               |
+   *                                  >=               |               |
+   *                         blockAckThreshold         |----------------
+   */                    
+   /**
+   * Represents the state for this agreement.
+   *
+   *  PENDING:
+   *    If an agreement is in PENDING state it means that an ADDBARequest frame was sent to
+   *    recipient in order to setup the block ack and the originator is waiting for the relative
+   *    ADDBAResponse frame.
+   *  
+   *  ESTABLISHED:
+   *    The block ack is active and all packets relative to this agreement are trasmitted
+   *    with ack policy set to block ack.
+   *  
+   *  INACTIVE:
+   *    In our implementation, block ack tear-down happens only if an inactivity timeout occurs
+   *    so we could have an active block ack but a number of packets that doesn't reach the value of
+   *    m_blockAckThreshold (see ns3::BlocAckManager). In these conditions the agreement becomes
+   *    INACTIVE until that the number of packets reaches the value of m_blockAckThreshold again.
+   *
+   *  UNSUCCESSFUL (not used for now):
+   *    The agremeent's state becomes UNSUCCESSFUL if:
+   *     
+   *    - its previous state was PENDING and an ADDBAResponse frame wasn't received from
+   *      recipient station within an interval of time defined by m_bAckSetupTimeout attribute
+   *      in ns3::WifiMac.
+   *    - an ADDBAResponse frame is received from recipient and the Status Code field is set
+   *      to failure.
+   *    
+   *    In both cases for station addressed by BlockAckAgreement::m_peer and for
+   *    TID BlockAckAgreement::m_tid block ack mechanism won't be used.
+   */
+  enum State {
+    PENDING,
+    ESTABLISHED,
+    INACTIVE,
+    UNSUCCESSFUL
+  };
+  void SetState (enum State state);
+  bool IsPending (void) const;
+  bool IsEstablished (void) const;
+  bool IsInactive (void) const;
+  bool IsUnsuccessful (void) const;
+  /**
+   * Notifies a packet's transmission with ack policy Block Ack.
+   */
+  void NotifyMpduTransmission (void);
+  /**
+   * Returns true if all packets for which a block ack was negotiated have been transmitted so
+   * a block ack request is needed in order to acknowledge them.
+   */
+  bool NeedBlockAckRequest (void) const;
+  void CompleteExchange (void);
+
+private:
+  enum State m_state;
+  uint8_t m_sentMpdus;
+};
+
+} //namespace ns3
+
+#endif /* ORIGINATOR_BLOCK_ACK_AGREEMENT_H */
--- a/src/devices/wifi/propagation-delay-model.cc	Thu Feb 25 13:51:59 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "propagation-delay-model.h"
-#include "ns3/random-variable.h"
-#include "ns3/mobility-model.h"
-#include "ns3/double.h"
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (PropagationDelayModel);
-
-TypeId 
-PropagationDelayModel::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::PropagationDelayModel")
-    .SetParent<Object> ()
-    ;
-  return tid;
-}
-
-PropagationDelayModel::~PropagationDelayModel ()
-{}
-
-NS_OBJECT_ENSURE_REGISTERED (RandomPropagationDelayModel);
-
-TypeId 
-RandomPropagationDelayModel::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::RandomPropagationDelayModel")
-    .SetParent<PropagationDelayModel> ()
-    .AddConstructor<RandomPropagationDelayModel> ()
-    .AddAttribute ("Variable",
-                   "The random variable which generates random delays (s).",
-                   RandomVariableValue (UniformVariable (0.0, 1.0)),
-                   MakeRandomVariableAccessor (&RandomPropagationDelayModel::m_variable),
-                   MakeRandomVariableChecker ())
-    ;
-  return tid;
-}
-
-RandomPropagationDelayModel::RandomPropagationDelayModel ()
-{}
-RandomPropagationDelayModel::~RandomPropagationDelayModel ()
-{}
-Time 
-RandomPropagationDelayModel::GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const
-{
-  return Seconds (m_variable.GetValue ());
-}
-
-NS_OBJECT_ENSURE_REGISTERED (ConstantSpeedPropagationDelayModel);
-
-TypeId
-ConstantSpeedPropagationDelayModel::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::ConstantSpeedPropagationDelayModel")
-    .SetParent<PropagationDelayModel> ()
-    .AddConstructor<ConstantSpeedPropagationDelayModel> ()
-    .AddAttribute ("Speed", "The speed (m/s)",
-                   DoubleValue (300000000.0),
-                   MakeDoubleAccessor (&ConstantSpeedPropagationDelayModel::m_speed),
-                   MakeDoubleChecker<double> ())
-    ;
-  return tid;
-}
-
-ConstantSpeedPropagationDelayModel::ConstantSpeedPropagationDelayModel ()
-{}
-Time 
-ConstantSpeedPropagationDelayModel::GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const
-{
-  double distance = a->GetDistanceFrom (b);
-  double seconds = distance / m_speed;
-  return Seconds (seconds);
-}
-void 
-ConstantSpeedPropagationDelayModel::SetSpeed (double speed)
-{
-  m_speed = speed;
-}
-double 
-ConstantSpeedPropagationDelayModel::GetSpeed (void) const
-{
-  return m_speed;
-}
-
-} // namespace ns3
--- a/src/devices/wifi/propagation-delay-model.h	Thu Feb 25 13:51:59 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef PROPAGATION_DELAY_MODEL_H
-#define PROPAGATION_DELAY_MODEL_H
-
-#include "ns3/ptr.h"
-#include "ns3/object.h"
-#include "ns3/nstime.h"
-#include "ns3/random-variable.h"
-
-namespace ns3 {
-
-class MobilityModel;
-
-/**
- * \brief calculate a propagation delay.
- */
-class PropagationDelayModel : public Object
-{
-public:
-  static TypeId GetTypeId (void);
-  virtual ~PropagationDelayModel ();
-  /**
-   * \param a the source
-   * \param b the destination
-   * \returns the calculated propagation delay
-   *
-   * Calculate the propagation delay between the specified
-   * source and destination.
-   */
-  virtual Time GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const = 0;
-};
-
-/**
- * \brief the propagation delay is random
- */
-class RandomPropagationDelayModel : public PropagationDelayModel
-{
-public:
-  static TypeId GetTypeId (void);
-
-  /**
-   * Use the default parameters from PropagationDelayRandomDistribution.
-   */
-  RandomPropagationDelayModel ();
-  virtual ~RandomPropagationDelayModel ();
-  virtual Time GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const;
-private:
-  RandomVariable m_variable;
-};
-
-/**
- * \brief the propagation speed is constant
- */
-class ConstantSpeedPropagationDelayModel : public PropagationDelayModel
-{
-public:
-  static TypeId GetTypeId (void);
-
-  /**
-   * Use the default parameters from PropagationDelayConstantSpeed.
-   */
-  ConstantSpeedPropagationDelayModel ();
-  virtual Time GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const;
-  /**
-   * \param speed the new speed (m/s)
-   */
-  void SetSpeed (double speed);
-  /**
-   * \returns the current propagation speed (m/s).
-   */
-  double GetSpeed (void) const;
-private:
-  double m_speed;
-};
-
-} // namespace ns3
-
-#endif /* PROPAGATION_DELAY_MODEL_H */
--- a/src/devices/wifi/propagation-loss-model-test-suite.cc	Thu Feb 25 13:51:59 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,251 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 The Boeing Company
- *
- * 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
- */
-
-#include "ns3/log.h"
-#include "ns3/abort.h"
-#include "ns3/test.h"
-#include "ns3/pcap-file.h"
-#include "ns3/config.h"
-#include "ns3/string.h"
-#include "ns3/uinteger.h"
-#include "ns3/double.h"
-#include "ns3/data-rate.h"
-#include "ns3/inet-socket-address.h"
-#include "ns3/internet-stack-helper.h"
-#include "ns3/ipv4-address-helper.h"
-#include "ns3/tcp-socket-factory.h"
-#include "ns3/yans-wifi-helper.h"
-#include "ns3/propagation-loss-model.h"
-#include "ns3/propagation-delay-model.h"
-#include "ns3/yans-wifi-channel.h"
-#include "ns3/yans-wifi-phy.h"
-#include "ns3/wifi-net-device.h"
-#include "ns3/mobility-helper.h"
-#include "ns3/constant-position-mobility-model.h"
-#include "ns3/nqos-wifi-mac-helper.h"
-#include "ns3/simulator.h"
-
-using namespace ns3;
-
-NS_LOG_COMPONENT_DEFINE ("PropagationLossModelsTest");
-
-// ===========================================================================
-// This is a simple test to validate propagation loss models of ns-3 wifi.
-// See the chapter in the ns-3 testing and validation guide for more detail
-// ===========================================================================
-//
-class FriisPropagationLossModelTestCase : public TestCase
-{
-public:
-  FriisPropagationLossModelTestCase ();
-  virtual ~FriisPropagationLossModelTestCase ();
-
-private:
-  virtual bool DoRun (void);
-
-  typedef struct {
-    Vector m_position;
-    double m_pt;  // dBm
-    double m_pr;  // W
-    double m_tolerance;
-  } TestVector;
-
-  TestVectors<TestVector> m_testVectors;
-};
-
-FriisPropagationLossModelTestCase::FriisPropagationLossModelTestCase ()
-  : TestCase ("Check to see that the ns-3 Friis propagation loss model provides correct received power"), m_testVectors ()
-{
-}
-
-FriisPropagationLossModelTestCase::~FriisPropagationLossModelTestCase ()
-{
-}
-
-bool
-FriisPropagationLossModelTestCase::DoRun (void)
-{
-  // The ns-3 testing manual gives more background on the values selected
-  // for this test.  First, set a few defaults. 
-
-  // wavelength at 2.4 GHz is 0.125m
-  Config::SetDefault ("ns3::FriisPropagationLossModel::Lambda", DoubleValue (0.125));
-  Config::SetDefault ("ns3::FriisPropagationLossModel::SystemLoss", DoubleValue (1.0));
-
-  // Select a reference transmit power
-  // Pt = 10^(17.0206/10)/10^3 = .05035702 W
-  double txPowerW = 0.05035702;
-  double txPowerdBm = 10 * log10 (txPowerW) + 30;
-
-  //
-  // We want to test the propagation loss model calculations at a few chosen 
-  // distances and compare the results to those we have manually calculated
-  // according to the model documentation.  The model reference specifies, 
-  // for instance, that the received power at 100m according to the provided
-  // input power will be 4.98265e-10 W.  Since this value specifies the power
-  // to 1e-15 significance, we test the ns-3 calculated value for agreement 
-  // within 5e-16.
-  //
-  TestVector testVector;
-
-  testVector.m_position = Vector (100, 0, 0);
-  testVector.m_pt = txPowerdBm;
-  testVector.m_pr = 4.98265e-10;
-  testVector.m_tolerance = 5e-16;
-  m_testVectors.Add (testVector);
-
-  testVector.m_position = Vector (500, 0, 0);
-  testVector.m_pt = txPowerdBm;
-  testVector.m_pr = 1.99306e-11;
-  testVector.m_tolerance = 5e-17;
-  m_testVectors.Add (testVector);
-
-  testVector.m_position = Vector (1000, 0, 0);
-  testVector.m_pt = txPowerdBm;
-  testVector.m_pr = 4.98265e-12;
-  testVector.m_tolerance = 5e-18;
-  m_testVectors.Add (testVector);
-
-  testVector.m_position = Vector (2000, 0, 0);
-  testVector.m_pt = txPowerdBm;
-  testVector.m_pr = 1.24566e-12;
-  testVector.m_tolerance = 5e-18;
-  m_testVectors.Add (testVector);
-
-  // Now, check that the received power values are expected
-
-  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> (); 
-  a->SetPosition (Vector (0,0,0));
-  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> (); 
-
-  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> (); 
-  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
-    {
-      testVector = m_testVectors.Get (i);
-      b->SetPosition (testVector.m_position);
-      double resultdBm = lossModel->CalcRxPower (testVector.m_pt, a, b);
-      double resultW =   pow (10.0, resultdBm/10.0)/1000;
-      NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power");
-    }
-	
-  return GetErrorStatus ();
-}
-
-class LogDistancePropagationLossModelTestCase : public TestCase
-{
-public:
-  LogDistancePropagationLossModelTestCase ();
-  virtual ~LogDistancePropagationLossModelTestCase ();
-
-private:
-  virtual bool DoRun (void);
-
-  typedef struct {
-    Vector m_position;
-    double m_pt;  // dBm
-    double m_pr;  // W
-    double m_tolerance;
-  } TestVector;
-
-  TestVectors<TestVector> m_testVectors;
-};
-
-LogDistancePropagationLossModelTestCase::LogDistancePropagationLossModelTestCase ()
-  : TestCase ("Check to see that the ns-3 Log Distance propagation loss model provides correct received power"), m_testVectors ()
-{
-}
-
-LogDistancePropagationLossModelTestCase::~LogDistancePropagationLossModelTestCase ()
-{
-}
-
-bool
-LogDistancePropagationLossModelTestCase::DoRun (void)
-{
-  // reference loss at 2.4 GHz is 40.045997
-  Config::SetDefault ("ns3::LogDistancePropagationLossModel::ReferenceLoss", DoubleValue (40.045997));
-  Config::SetDefault ("ns3::LogDistancePropagationLossModel::Exponent", DoubleValue (3));
-
-  // Select a reference transmit power
-  // Pt = 10^(17.0206/10)/10^3 = .05035702 W
-  double txPowerW = 0.05035702;
-  double txPowerdBm = 10 * log10 (txPowerW) + 30;
-
-  //
-  // We want to test the propagation loss model calculations at a few chosen 
-  // distances and compare the results to those we have manually calculated
-  // according to the model documentation.  The following "TestVector" objects
-  // will drive the test.
-  //
-  TestVector testVector;
-
-  testVector.m_position = Vector (10, 0, 0);
-  testVector.m_pt = txPowerdBm;
-  testVector.m_pr = 4.98265e-9;
-  testVector.m_tolerance = 5e-15; 
-  m_testVectors.Add (testVector);
-
-  testVector.m_position = Vector (20, 0, 0);
-  testVector.m_pt = txPowerdBm;
-  testVector.m_pr = 6.22831e-10;
-  testVector.m_tolerance = 5e-16;
-  m_testVectors.Add (testVector);
-
-  testVector.m_position = Vector (40, 0, 0);
-  testVector.m_pt = txPowerdBm;
-  testVector.m_pr = 7.78539e-11;
-  testVector.m_tolerance = 5e-17;
-  m_testVectors.Add (testVector);
-
-  testVector.m_position = Vector (80, 0, 0);
-  testVector.m_pt = txPowerdBm;
-  testVector.m_pr = 9.73173e-12;
-  testVector.m_tolerance = 5e-17;
-  m_testVectors.Add (testVector);
-
-  Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> (); 
-  a->SetPosition (Vector (0,0,0));
-  Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> (); 
-
-  Ptr<LogDistancePropagationLossModel> lossModel = CreateObject<LogDistancePropagationLossModel> (); 
-  for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
-    {
-      testVector = m_testVectors.Get (i);
-      b->SetPosition (testVector.m_position);
-      double resultdBm = lossModel->CalcRxPower (testVector.m_pt, a, b);
-      double resultW =   pow (10.0, resultdBm/10.0)/1000;
-      NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power");
-    }
-	
-  return GetErrorStatus ();
-}
-
-class PropagationLossModelsTestSuite : public TestSuite
-{
-public:
-  PropagationLossModelsTestSuite ();
-};
-
-PropagationLossModelsTestSuite::PropagationLossModelsTestSuite ()
-  : TestSuite ("propagation-loss-model", UNIT)
-{
-  AddTestCase (new FriisPropagationLossModelTestCase);
-  AddTestCase (new LogDistancePropagationLossModelTestCase);
-}
-
-PropagationLossModelsTestSuite WifiPropagationLossModelsTestSuite;
--- a/src/devices/wifi/propagation-loss-model.cc	Thu Feb 25 13:51:59 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,546 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- * Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
- */
-
-#include "propagation-loss-model.h"
-#include "ns3/log.h"
-#include "ns3/mobility-model.h"
-#include "ns3/boolean.h"
-#include "ns3/double.h"
-#include <math.h>
-
-NS_LOG_COMPONENT_DEFINE ("PropagationLossModel");
-
-namespace ns3 {
-
-// ------------------------------------------------------------------------- //
-
-NS_OBJECT_ENSURE_REGISTERED (PropagationLossModel);
-
-TypeId 
-PropagationLossModel::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::PropagationLossModel")
-    .SetParent<Object> ()
-    ;
-  return tid;
-}
-
-PropagationLossModel::PropagationLossModel ()
-  : m_next (0)
-{}
-
-PropagationLossModel::~PropagationLossModel ()
-{}
-
-void 
-PropagationLossModel::SetNext (Ptr<PropagationLossModel> next)
-{
-  m_next = next;
-}
-
-double 
-PropagationLossModel::CalcRxPower (double txPowerDbm,
-                                   Ptr<MobilityModel> a,
-                                   Ptr<MobilityModel> b) const
-{
-  double self = DoCalcRxPower (txPowerDbm, a, b);
-  if (m_next != 0)
-    {
-      self = m_next->CalcRxPower (self, a, b);
-    }
-  return self;
-}
-
-// ------------------------------------------------------------------------- //
-
-NS_OBJECT_ENSURE_REGISTERED (RandomPropagationLossModel);
-
-TypeId 
-RandomPropagationLossModel::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::RandomPropagationLossModel")
-    .SetParent<PropagationLossModel> ()
-    .AddConstructor<RandomPropagationLossModel> ()
-    .AddAttribute ("Variable", "The random variable used to pick a loss everytime CalcRxPower is invoked.",
-                   RandomVariableValue (ConstantVariable (1.0)),
-                   MakeRandomVariableAccessor (&RandomPropagationLossModel::m_variable),
-                   MakeRandomVariableChecker ())
-    ;
-  return tid;
-}
-RandomPropagationLossModel::RandomPropagationLossModel ()
-  : PropagationLossModel ()
-{}
-
-RandomPropagationLossModel::~RandomPropagationLossModel ()
-{}
-
-double 
-RandomPropagationLossModel::DoCalcRxPower (double txPowerDbm,
-                                           Ptr<MobilityModel> a,
-                                           Ptr<MobilityModel> b) const
-{
-  double rxc = -m_variable.GetValue ();
-  NS_LOG_DEBUG ("attenuation coefficent="<<rxc<<"Db");
-  return txPowerDbm + rxc;
-}
-
-// ------------------------------------------------------------------------- //
-
-NS_OBJECT_ENSURE_REGISTERED (FriisPropagationLossModel);
-
-const double FriisPropagationLossModel::PI = 3.14159265358979323846;
-
-TypeId 
-FriisPropagationLossModel::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::FriisPropagationLossModel")
-    .SetParent<PropagationLossModel> ()
-    .AddConstructor<FriisPropagationLossModel> ()
-    .AddAttribute ("Lambda", 
-                   "The wavelength  (default is 5.15 GHz at 300 000 km/s).",
-                   DoubleValue (300000000.0 / 5.150e9),
-                   MakeDoubleAccessor (&FriisPropagationLossModel::m_lambda),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("SystemLoss", "The system loss",
-                   DoubleValue (1.0),
-                   MakeDoubleAccessor (&FriisPropagationLossModel::m_systemLoss),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("MinDistance", 
-                   "The distance under which the propagation model refuses to give results (m)",
-                   DoubleValue (0.5),
-                   MakeDoubleAccessor (&FriisPropagationLossModel::SetMinDistance,
-                                       &FriisPropagationLossModel::GetMinDistance),
-                   MakeDoubleChecker<double> ())
-    ;
-  return tid;
-}
-
-FriisPropagationLossModel::FriisPropagationLossModel ()
-{}
-void 
-FriisPropagationLossModel::SetSystemLoss (double systemLoss)
-{
-  m_systemLoss = systemLoss;
-}
-double 
-FriisPropagationLossModel::GetSystemLoss (void) const
-{
-  return m_systemLoss;
-}
-void 
-FriisPropagationLossModel::SetMinDistance (double minDistance)
-{
-  m_minDistance = minDistance;
-}
-double 
-FriisPropagationLossModel::GetMinDistance (void) const
-{
-  return m_minDistance;
-}
-void 
-FriisPropagationLossModel::SetLambda (double frequency, double speed)
-{
-  m_lambda = speed / frequency;
-}
-void 
-FriisPropagationLossModel::SetLambda (double lambda)
-{
-  m_lambda = lambda;
-}
-double 
-FriisPropagationLossModel::GetLambda (void) const
-{
-  return m_lambda;
-}
-
-double 
-FriisPropagationLossModel::DbmToW (double dbm) const
-{
-  double mw = pow(10.0,dbm/10.0);
-  return mw / 1000.0;
-}
-
-double
-FriisPropagationLossModel::DbmFromW (double w) const
-{
-  double dbm = log10 (w * 1000.0) * 10.0;
-  return dbm;
-}
-
-double 
-FriisPropagationLossModel::DoCalcRxPower (double txPowerDbm,
-                                          Ptr<MobilityModel> a,
-                                          Ptr<MobilityModel> b) const
-{
-  /*
-   * Friis free space equation:
-   * where Pt, Gr, Gr and P are in Watt units
-   * L is in meter units.
-   *
-   *    P     Gt * Gr * (lambda^2)
-   *   --- = ---------------------
-   *    Pt     (4 * pi * d)^2 * L
-   *
-   * Gt: tx gain (unit-less)
-   * Gr: rx gain (unit-less)
-   * Pt: tx power (W)
-   * d: distance (m)
-   * L: system loss
-   * lambda: wavelength (m)
-   *
-   * Here, we ignore tx and rx gain and the input and output values 
-   * are in dB or dBm:
-   *
-   *                           lambda^2
-   * rx = tx +  10 log10 (-------------------)
-   *                       (4 * pi * d)^2 * L
-   *
-   * rx: rx power (dB)
-   * tx: tx power (dB)
-   * d: distance (m)
-   * L: system loss (unit-less)
-   * lambda: wavelength (m)
-   */
-  double distance = a->GetDistanceFrom (b);
-  if (distance <= m_minDistance)
-    {
-      return txPowerDbm;
-    }
-  double numerator = m_lambda * m_lambda;
-  double denominator = 16 * PI * PI * distance * distance * m_systemLoss;
-  double pr = 10 * log10 (numerator / denominator);
-  NS_LOG_DEBUG ("distance="<<distance<<"m, attenuation coefficient="<<pr<<"dB");
-  return txPowerDbm + pr;
-}
-
-// ------------------------------------------------------------------------- //
-
-NS_OBJECT_ENSURE_REGISTERED (LogDistancePropagationLossModel);
-
-TypeId
-LogDistancePropagationLossModel::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::LogDistancePropagationLossModel")
-    .SetParent<PropagationLossModel> ()
-    .AddConstructor<LogDistancePropagationLossModel> ()
-    .AddAttribute ("Exponent",
-                   "The exponent of the Path Loss propagation model",
-                   DoubleValue (3.0),
-                   MakeDoubleAccessor (&LogDistancePropagationLossModel::m_exponent),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("ReferenceDistance",
-                   "The distance at which the reference loss is calculated (m)",
-                   DoubleValue (1.0),
-                   MakeDoubleAccessor (&LogDistancePropagationLossModel::m_referenceDistance),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("ReferenceLoss",
-                   "The reference loss at reference distance (dB). (Default is Friis at 1m with 5.15 GHz)",
-                   DoubleValue (46.6777),
-                   MakeDoubleAccessor (&LogDistancePropagationLossModel::m_referenceLoss),
-                   MakeDoubleChecker<double> ())
-    ;
-  return tid;
-                   
-}
-
-LogDistancePropagationLossModel::LogDistancePropagationLossModel ()
-{}
-
-void 
-LogDistancePropagationLossModel::SetPathLossExponent (double n)
-{
-  m_exponent = n;
-}
-void 
-LogDistancePropagationLossModel::SetReference (double referenceDistance, double referenceLoss)
-{
-  m_referenceDistance = referenceDistance;
-  m_referenceLoss = referenceLoss;
-}
-double 
-LogDistancePropagationLossModel::GetPathLossExponent (void) const
-{
-  return m_exponent;
-}
-  
-double 
-LogDistancePropagationLossModel::DoCalcRxPower (double txPowerDbm,
-                                                Ptr<MobilityModel> a,
-                                                Ptr<MobilityModel> b) const
-{
-  double distance = a->GetDistanceFrom (b);
-  if (distance <= m_referenceDistance)
-    {
-      return txPowerDbm;
-    }
-  /**
-   * The formula is:
-   * rx = 10 * log (Pr0(tx)) - n * 10 * log (d/d0)
-   *
-   * Pr0: rx power at reference distance d0 (W)
-   * d0: reference distance: 1.0 (m)
-   * d: distance (m)
-   * tx: tx power (dB)
-   * rx: dB
-   *
-   * Which, in our case is:
-   *
-   * rx = rx0(tx) - 10 * n * log (d/d0)
-   */
-  double pathLossDb = 10 * m_exponent * log10 (distance / m_referenceDistance);
-  double rxc = -m_referenceLoss - pathLossDb;
-  NS_LOG_DEBUG ("distance="<<distance<<"m, reference-attenuation="<<-m_referenceLoss<<"dB, "<<
-		"attenuation coefficient="<<rxc<<"db");
-  return txPowerDbm + rxc;
-}
-
-// ------------------------------------------------------------------------- //
-
-NS_OBJECT_ENSURE_REGISTERED (ThreeLogDistancePropagationLossModel);
-
-TypeId
-ThreeLogDistancePropagationLossModel::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::ThreeLogDistancePropagationLossModel")
-    .SetParent<PropagationLossModel> ()
-    .AddConstructor<ThreeLogDistancePropagationLossModel> ()
-    .AddAttribute ("Distance0",
-                   "Beginning of the first (near) distance field",
-                   DoubleValue (1.0),
-                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance0),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("Distance1",
-                   "Beginning of the second (middle) distance field.",
-                   DoubleValue (200.0),
-                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance1),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("Distance2",
-                   "Beginning of the third (far) distance field.",
-                   DoubleValue (500.0),
-                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_distance2),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("Exponent0",
-                   "The exponent for the first field.",
-                   DoubleValue (1.9),
-                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent0),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("Exponent1",
-                   "The exponent for the second field.",
-                   DoubleValue (3.8),
-                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent1),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("Exponent2",
-                   "The exponent for the third field.",
-                   DoubleValue (3.8),
-                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_exponent2),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("ReferenceLoss",
-                   "The reference loss at distance d0 (dB). (Default is Friis at 1m with 5.15 GHz)",
-                   DoubleValue (46.6777),
-                   MakeDoubleAccessor (&ThreeLogDistancePropagationLossModel::m_referenceLoss),
-                   MakeDoubleChecker<double> ())
-    ;
-  return tid;
-                   
-}
-
-ThreeLogDistancePropagationLossModel::ThreeLogDistancePropagationLossModel ()
-{
-}
-
-double 
-ThreeLogDistancePropagationLossModel::DoCalcRxPower (double txPowerDbm,
-                                                     Ptr<MobilityModel> a,
-                                                     Ptr<MobilityModel> b) const
-{
-  double distance = a->GetDistanceFrom (b);
-  NS_ASSERT(distance >= 0);
-
-  // See doxygen comments for the formula and explanation
-
-  double pathLossDb;
-
-  if (distance < m_distance0)
-    {
-      pathLossDb = 0;
-    }
-  else if (distance < m_distance1)
-    {
-      pathLossDb = m_referenceLoss
-        + 10 * m_exponent0 * log10(distance / m_distance0);
-    }
-  else if (distance < m_distance2)
-    {
-      pathLossDb = m_referenceLoss
-        + 10 * m_exponent0 * log10(m_distance1 / m_distance0)
-        + 10 * m_exponent1 * log10(distance / m_distance1);
-    }
-  else
-    {
-      pathLossDb = m_referenceLoss
-        + 10 * m_exponent0 * log10(m_distance1 / m_distance0)
-        + 10 * m_exponent1 * log10(m_distance2 / m_distance1)
-        + 10 * m_exponent2 * log10(distance / m_distance2);
-    }
-
-  NS_LOG_DEBUG ("ThreeLogDistance distance=" << distance << "m, " <<
-                "attenuation=" << pathLossDb << "dB");
-
-  return txPowerDbm - pathLossDb;
-}
-
-// ------------------------------------------------------------------------- //
-
-NS_OBJECT_ENSURE_REGISTERED (NakagamiPropagationLossModel);
-
-TypeId
-NakagamiPropagationLossModel::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::NakagamiPropagationLossModel")
-    .SetParent<PropagationLossModel> ()
-    .AddConstructor<NakagamiPropagationLossModel> ()
-    .AddAttribute ("Distance1",
-                   "Beginning of the second distance field. Default is 80m.",
-                   DoubleValue (80.0),
-                   MakeDoubleAccessor (&NakagamiPropagationLossModel::m_distance1),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("Distance2",
-                   "Beginning of the third distance field. Default is 200m.",
-                   DoubleValue (200.0),
-                   MakeDoubleAccessor (&NakagamiPropagationLossModel::m_distance2),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("m0",
-                   "m0 for distances smaller than Distance1. Default is 1.5.",
-                   DoubleValue (1.5),
-                   MakeDoubleAccessor (&NakagamiPropagationLossModel::m_m0),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("m1",
-                   "m1 for distances smaller than Distance2. Default is 0.75.",
-                   DoubleValue (0.75),
-                   MakeDoubleAccessor (&NakagamiPropagationLossModel::m_m1),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("m2",
-                   "m2 for distances greater than Distance2. Default is 0.75.",
-                   DoubleValue (0.75),
-                   MakeDoubleAccessor (&NakagamiPropagationLossModel::m_m2),
-                   MakeDoubleChecker<double> ())
-    ;
-  return tid;
-                   
-}
-
-NakagamiPropagationLossModel::NakagamiPropagationLossModel ()
-{}
-
-double 
-NakagamiPropagationLossModel::DoCalcRxPower (double txPowerDbm,
-                                             Ptr<MobilityModel> a,
-                                             Ptr<MobilityModel> b) const
-{
-  // select m parameter
-
-  double distance = a->GetDistanceFrom (b);
-  NS_ASSERT(distance >= 0);
-
-  double m;
-  if (distance < m_distance1)
-    {
-      m = m_m0;
-    }
-  else if (distance < m_distance2)
-    {
-      m = m_m1;
-    }
-  else
-    {
-      m = m_m2;
-    }
-  
-  // the current power unit is dBm, but Watt is put into the Nakagami /
-  // Rayleigh distribution.
-  double powerW = pow(10, (txPowerDbm - 30) / 10);
-
-  double resultPowerW;
-
-  // switch between Erlang- and Gamma distributions: this is only for
-  // speed. (Gamma is equal to Erlang for any positive integer m.)
-  unsigned int int_m = static_cast<unsigned int>(floor(m));
-
-  if (int_m == m)
-    {
-      resultPowerW = m_erlangRandomVariable.GetValue(int_m, powerW / m);
-    }
-  else
-    {
-      resultPowerW = m_gammaRandomVariable.GetValue(m, powerW / m);
-    }
-
-  double resultPowerDbm = 10 * log10(resultPowerW) + 30;
-
-  NS_LOG_DEBUG ("Nakagami distance=" << distance << "m, " <<
-                "power=" << powerW <<"W, " <<
-                "resultPower=" << resultPowerW << "W=" << resultPowerDbm << "dBm");
-
-  return resultPowerDbm;
-}
-
-// ------------------------------------------------------------------------- //
-
-NS_OBJECT_ENSURE_REGISTERED (FixedRssLossModel);
-
-TypeId 
-FixedRssLossModel::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::FixedRssLossModel")
-    .SetParent<PropagationLossModel> ()
-    .AddConstructor<FixedRssLossModel> ()
-    .AddAttribute ("Rss", "The fixed receiver Rss.",
-                   DoubleValue (-150.0),
-                   MakeDoubleAccessor (&FixedRssLossModel::m_rss),
-                   MakeDoubleChecker<double> ())
-    ;
-  return tid;
-}
-FixedRssLossModel::FixedRssLossModel ()
-  : PropagationLossModel ()
-{}
-
-FixedRssLossModel::~FixedRssLossModel ()
-{}
-
-void 
-FixedRssLossModel::SetRss (double rss)
-{
-  m_rss = rss;
-}
-
-double 
-FixedRssLossModel::DoCalcRxPower (double txPowerDbm,
-                                           Ptr<MobilityModel> a,
-                                           Ptr<MobilityModel> b) const
-{
-  return m_rss;
-}
-
-// ------------------------------------------------------------------------- //
-
-} // namespace ns3
--- a/src/devices/wifi/propagation-loss-model.h	Thu Feb 25 13:51:59 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,375 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- * Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
- * Contributions: Gary Pei <guangyu.pei@boeing.com> for fixed RSS
- */
-
-#ifndef PROPAGATION_LOSS_MODEL_H
-#define PROPAGATION_LOSS_MODEL_H
-
-#include "ns3/object.h"
-#include "ns3/random-variable.h"
-
-namespace ns3 {
-
-class MobilityModel;
-
-/**
- * \brief Modelize the propagation loss through a transmission medium
- *
- * Calculate the receive power (dbm) from a transmit power (dbm)
- * and a mobility model for the source and destination positions.
- */
-class PropagationLossModel : public Object
-{
-public:
-  static TypeId GetTypeId (void);
-
-  PropagationLossModel ();
-  virtual ~PropagationLossModel ();
-
-  void SetNext (Ptr<PropagationLossModel> next);
-
-  /**
-   * \param txPowerDbm current transmission power (in dBm)
-   * \param a the mobility model of the source
-   * \param b the mobility model of the destination
-   * \returns the reception power after adding/multiplying propagation loss (in dBm)
-   */
-  double CalcRxPower (double txPowerDbm,
-                      Ptr<MobilityModel> a,
-                      Ptr<MobilityModel> b) const;
-private:
-  PropagationLossModel (const PropagationLossModel &o);
-  PropagationLossModel &operator = (const PropagationLossModel &o);
-  virtual double DoCalcRxPower (double txPowerDbm,
-                                Ptr<MobilityModel> a,
-                                Ptr<MobilityModel> b) const = 0;
-
-  Ptr<PropagationLossModel> m_next;
-};
-
-/**
- * \brief The propagation loss follows a random distribution.
- */ 
-class RandomPropagationLossModel : public PropagationLossModel
-{
-public:
-  static TypeId GetTypeId (void);
-
-  RandomPropagationLossModel ();
-  virtual ~RandomPropagationLossModel ();
-
-private:
-  RandomPropagationLossModel (const RandomPropagationLossModel &o);
-  RandomPropagationLossModel & operator = (const RandomPropagationLossModel &o);
-  virtual double DoCalcRxPower (double txPowerDbm,
-                                Ptr<MobilityModel> a,
-                                Ptr<MobilityModel> b) const;
-  RandomVariable m_variable;
-};
-
-/**
- * \brief a Friis propagation loss model
- *
- * The Friis propagation loss model was first described in
- * "A Note on a Simple Transmission Formula", by 
- * "Harald T. Friis".
- * 
- * The original equation was described as:
- *  \f$ \frac{P_r}{P_t} = \frac{A_r A_t}{d^2\lambda^2} \f$
- *  with the following equation for the case of an
- *  isotropic antenna with no heat loss:
- *  \f$ A_{isotr.} = \frac{\lambda^2}{4\pi} \f$
- *
- * The final equation becomes:
- * \f$ \frac{P_r}{P_t} = \frac{\lambda^2}{(4 \pi d)^2} \f$
- *
- * Modern extensions to this original equation are:
- * \f$ P_r = \frac{P_t G_t G_r \lambda^2}{(4 \pi d)^2 L}\f$
- *
- * With:
- *  - \f$ P_r \f$ : reception power (W)
- *  - \f$ P_t \f$ : transmission power (W)
- *  - \f$ G_t \f$ : transmission gain (unit-less)
- *  - \f$ G_r \f$ : reception gain (unit-less)
- *  - \f$ \lambda \f$ : wavelength (m)
- *  - \f$ d \f$ : distance (m)
- *  - \f$ L \f$ : system loss (unit-less)
- *
- *
- * This model is invalid for small distance values.
- * The current implementation returns the txpower as the rxpower
- * for any distance smaller than MinDistance.
- */
-class FriisPropagationLossModel : public PropagationLossModel
-{
-public:
-  static TypeId GetTypeId (void);
-  FriisPropagationLossModel ();
-  /**
-   * \param frequency (Hz)
-   * \param speed (m/s)
-   *
-   * Set the main wavelength used in the Friis model 
-   * calculation.
-   */
-  void SetLambda (double frequency, double speed);
-  /**
-   * \param lambda (m) the wavelength
-   *
-   * Set the main wavelength used in the Friis model 
-   * calculation.
-   */
-  void SetLambda (double lambda);
-  /**
-   * \param systemLoss (dimension-less)
-   *
-   * Set the system loss used by the Friis propagation model.
-   */
-  void SetSystemLoss (double systemLoss);
-
-  /**
-   * \param minDistance the minimum distance
-   *
-   * Below this distance, the txpower is returned
-   * unmodified as the rxpower.
-   */
-  void SetMinDistance (double minDistance);
-
-  /**
-   * \returns the minimum distance.
-   */
-  double GetMinDistance (void) const;
-
-  /**
-   * \returns the current wavelength (m)
-   */
-  double GetLambda (void) const;
-  /**
-   * \returns the current system loss (dimention-less)
-   */
-  double GetSystemLoss (void) const;
-
-private:
-  FriisPropagationLossModel (const FriisPropagationLossModel &o);
-  FriisPropagationLossModel & operator = (const FriisPropagationLossModel &o);
-  virtual double DoCalcRxPower (double txPowerDbm,
-                                Ptr<MobilityModel> a,
-                                Ptr<MobilityModel> b) const;
-  double DbmToW (double dbm) const;
-  double DbmFromW (double w) const;
-
-  static const double PI;
-  double m_lambda;
-  double m_systemLoss;
-  double m_minDistance;
-};
-
-/**
- * \brief a log distance propagation model.
- *
- * This model calculates the reception power with a so-called
- * log-distance propagation model:
- * \f$ L = L_0 + 10 n log_{10}(\frac{d}{d_0})\f$
- *
- * where:
- *  - \f$ n \f$ : the path loss distance exponent
- *  - \f$ d_0 \f$ : reference distance (m)
- *  - \f$ L_0 \f$ : path loss at reference distance (dB)
- *  - \f$ d \f$ : distance (m)
- *  - \f$ L \f$ : path loss (dB)
- *
- * When the path loss is requested at a distance smaller than
- * the reference distance, the tx power is returned.
- *
- */
-class LogDistancePropagationLossModel : public PropagationLossModel
-{
-public:
-  static TypeId GetTypeId (void);
-  LogDistancePropagationLossModel ();
-
-  /**
-   * \param n the path loss exponent.
-   * Set the path loss exponent.
-   */
-  void SetPathLossExponent (double n);
-  /** 
-   * \returns the current path loss exponent.
-   */
-  double GetPathLossExponent (void) const;
-
-  void SetReference (double referenceDistance, double referenceLoss);
-  
-private:
-  LogDistancePropagationLossModel (const LogDistancePropagationLossModel &o);
-  LogDistancePropagationLossModel & operator = (const LogDistancePropagationLossModel &o);
-  virtual double DoCalcRxPower (double txPowerDbm,
-                                Ptr<MobilityModel> a,
-                                Ptr<MobilityModel> b) const;
-  static Ptr<PropagationLossModel> CreateDefaultReference (void);
-
-  double m_exponent;
-  double m_referenceDistance;
-  double m_referenceLoss;
-};
-
-/**
- * \brief A log distance path loss propagation model with three distance
- * fields. This model is the same as ns3::LogDistancePropagationLossModel
- * except that it has three distance fields: near, middle and far with
- * different exponents.
- *
- * Within each field the reception power is calculated using the log-distance
- * propagation equation:
- * \f[ L = L_0 + 10 \cdot n_0 log_{10}(\frac{d}{d_0})\f]
- * Each field begins where the previous ends and all together form a continuous function.
- *
- * There are three valid distance fields: near, middle, far. Actually four: the
- * first from 0 to the reference distance is invalid and returns txPowerDbm.
- *
- * \f[ \underbrace{0 \cdots\cdots}_{=0} \underbrace{d_0 \cdots\cdots}_{n_0} \underbrace{d_1 \cdots\cdots}_{n_1} \underbrace{d_2 \cdots\cdots}_{n_2} \infty \f]
- *
- * Complete formula for the path loss in dB:
- *
- * \f[\displaystyle L =
-\begin{cases}
-0 & d < d_0 \\
-L_0 + 10 \cdot n_0 \log_{10}(\frac{d}{d_0}) & d_0 \leq d < d_1 \\
-L_0 + 10 \cdot n_0 \log_{10}(\frac{d_1}{d_0}) + 10 \cdot n_1 \log_{10}(\frac{d}{d_1}) & d_1 \leq d < d_2 \\
-L_0 + 10 \cdot n_0 \log_{10}(\frac{d_1}{d_0}) + 10 \cdot n_1 \log_{10}(\frac{d_2}{d_1}) + 10 \cdot n_2 \log_{10}(\frac{d}{d_2})& d_2 \leq d
-\end{cases}\f]
- *
- * where:
- *  - \f$ L \f$ : resulting path loss (dB)
- *  - \f$ d \f$ : distance (m)
- *  - \f$ d_0, d_1, d_2 \f$ : three distance fields (m)
- *  - \f$ n_0, n_1, n_2 \f$ : path loss distance exponent for each field (unitless)
- *  - \f$ L_0 \f$ : path loss at reference distance (dB)
- *
- * When the path loss is requested at a distance smaller than the reference
- * distance \f$ d_0 \f$, the tx power (with no path loss) is returned. The
- * reference distance defaults to 1m and reference loss defaults to
- * ns3::FriisPropagationLossModel with 5.15 GHz and is thus \f$ L_0 \f$ = 46.67 dB.
- */
-
-class ThreeLogDistancePropagationLossModel : public PropagationLossModel
-{
-public:
-  static TypeId GetTypeId (void);
-  ThreeLogDistancePropagationLossModel ();
-
-  // Parameters are all accessible via attributes.
-
-private:
-  ThreeLogDistancePropagationLossModel (const ThreeLogDistancePropagationLossModel& o);
-  ThreeLogDistancePropagationLossModel& operator= (const ThreeLogDistancePropagationLossModel& o);
-
-  virtual double DoCalcRxPower (double txPowerDbm,
-                                Ptr<MobilityModel> a,
-                                Ptr<MobilityModel> b) const;
-
-  double m_distance0;
-  double m_distance1;
-  double m_distance2;
-
-  double m_exponent0;
-  double m_exponent1;
-  double m_exponent2;
-
-  double m_referenceLoss;
-};
-
-/**
- * \brief Nakagami-m fast fading propagation loss model.
- *
- * The Nakagami-m distribution is applied to the power level. The probability
- * density function is defined as
- * \f[ p(x; m, \omega) = \frac{2 m^m}{\Gamma(m) \omega^m} x^{2m - 1} e^{-\frac{m}{\omega} x^2} = 2 x \cdot p_{\text{Gamma}}(x^2, m, \frac{m}{\omega}) \f]
- * with \f$ m \f$ the fading depth parameter and \f$ \omega \f$ the average received power.
- *
- * It is implemented by either a ns3::GammaVariable or a ns3::ErlangVariable
- * random variable.
- *
- * Like in ns3::ThreeLogDistancePropagationLossModel, the m parameter is varied
- * over three distance fields:
- * \f[ \underbrace{0 \cdots\cdots}_{m_0} \underbrace{d_1 \cdots\cdots}_{m_1} \underbrace{d_2 \cdots\cdots}_{m_2} \infty \f]
- *
- * For m = 1 the Nakagami-m distribution equals the Rayleigh distribution. Thus
- * this model also implements Rayleigh distribution based fast fading.
- */
-
-class NakagamiPropagationLossModel : public PropagationLossModel
-{
-public:
-  static TypeId GetTypeId (void);
-
-  NakagamiPropagationLossModel ();
-
-  // Parameters are all accessible via attributes.
-
-private:
-  NakagamiPropagationLossModel (const NakagamiPropagationLossModel& o);
-  NakagamiPropagationLossModel& operator= (const NakagamiPropagationLossModel& o);
-
-  virtual double DoCalcRxPower (double txPowerDbm,
-                                Ptr<MobilityModel> a,
-                                Ptr<MobilityModel> b) const;
-
-  double m_distance1;
-  double m_distance2;
-
-  double m_m0;
-  double m_m1;
-  double m_m2;
-
-  ErlangVariable        m_erlangRandomVariable;
-  GammaVariable         m_gammaRandomVariable;
-};
-
-/**
- * \brief The propagation loss is fixed. The user can set received power level.
- */ 
-class FixedRssLossModel : public PropagationLossModel
-{
-public:
-  static TypeId GetTypeId (void);
-
-  FixedRssLossModel ();
-  virtual ~FixedRssLossModel ();
-  /**
-   * \param rss (dBm) the received signal strength
-   *
-   * Set the RSS.
-   */
-  void SetRss (double rss);
-
-private:
-  FixedRssLossModel (const FixedRssLossModel &o);
-  FixedRssLossModel & operator = (const FixedRssLossModel &o);
-  virtual double DoCalcRxPower (double txPowerDbm,
-                                Ptr<MobilityModel> a,
-                                Ptr<MobilityModel> b) const;
-  double m_rss;
-};
-
-} // namespace ns3
-
-#endif /* PROPAGATION_LOSS_MODEL_H */
--- a/src/devices/wifi/qadhoc-wifi-mac.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/qadhoc-wifi-mac.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -147,6 +147,18 @@
   m_low->SetAckTimeout (ackTimeout);
 }
 
+void 
+QadhocWifiMac::SetBasicBlockAckTimeout (Time blockAckTimeout)
+{
+  m_low->SetBasicBlockAckTimeout (blockAckTimeout);
+}
+
+void 
+QadhocWifiMac::SetCompressedBlockAckTimeout (Time blockAckTimeout)
+{
+  m_low->SetCompressedBlockAckTimeout (blockAckTimeout);
+}
+
 void
 QadhocWifiMac::SetCtsTimeout (Time ctsTimeout)
 {
@@ -183,6 +195,18 @@
   return m_low->GetAckTimeout ();
 }
 
+Time 
+QadhocWifiMac::GetBasicBlockAckTimeout (void) const
+{
+  return m_low->GetBasicBlockAckTimeout ();
+}
+
+Time 
+QadhocWifiMac::GetCompressedBlockAckTimeout (void) const
+{
+  return m_low->GetCompressedBlockAckTimeout ();
+}
+
 Time
 QadhocWifiMac::GetCtsTimeout (void) const
 {
@@ -353,7 +377,42 @@
     }
   else if (hdr->IsMgt ())
     {
-      //Handling action frames
+      if (hdr->IsAction ())
+        {
+          WifiActionHeader actionHdr;
+          packet->RemoveHeader (actionHdr);
+          if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
+              actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST)
+            {
+              MgtAddBaRequestHeader reqHdr;
+              packet->RemoveHeader (reqHdr);
+              SendAddBaResponse (&reqHdr, hdr->GetAddr2 ());
+            }
+          else if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
+                   actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST)
+            {
+              MgtAddBaResponseHeader respHdr;
+              packet->RemoveHeader (respHdr);
+              m_queues[QosUtilsMapTidToAc (respHdr.GetTid ())]->GotAddBaResponse (&respHdr, hdr->GetAddr2 ());
+            }
+          else if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
+                   actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_DELBA)
+            {
+              MgtDelBaHeader delBaHdr;
+              packet->RemoveHeader (delBaHdr);
+              if (delBaHdr.IsByOriginator ())
+                {
+                  /* Delba frame was sent by originator, this means that an ingoing established
+                     agreement exists in MacLow */
+                     m_low->DestroyBlockAckAgreement (hdr->GetAddr2 (), delBaHdr.GetTid ());                }
+              else
+                {
+                  /* We must notify correct queue tear down of agreement */
+                  AccessClass ac = QosUtilsMapTidToAc (delBaHdr.GetTid ());
+                  m_queues[ac]->GotDelBaFrame (&delBaHdr, hdr->GetAddr2 ());
+                }
+            }
+        }
     }
 }
 
@@ -401,6 +460,8 @@
   edca->SetManager (m_dcfManager);
   edca->SetTypeOfStation (ADHOC_STA);
   edca->SetTxMiddle (m_txMiddle);
+  edca->SetAccessClass (ac);
+  edca->CompleteConfig ();
   m_queues.insert (std::make_pair(ac, edca));
 }
 
@@ -445,4 +506,59 @@
     }
 }
 
+
+void
+QadhocWifiMac::SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr, Mac48Address originator)
+{
+  NS_LOG_FUNCTION (this);
+  WifiMacHeader hdr;
+  hdr.SetAction ();
+  hdr.SetAddr1 (originator);
+  hdr.SetAddr2 (m_low->GetAddress ());
+  hdr.SetAddr3 (m_low->GetAddress ());
+  hdr.SetDsNotFrom ();
+  hdr.SetDsNotTo ();
+
+  MgtAddBaResponseHeader respHdr;
+  StatusCode code;
+  code.SetSuccess ();
+  respHdr.SetStatusCode (code);
+  //Here a control about queues type?
+  respHdr.SetAmsduSupport (reqHdr->IsAmsduSupported ());
+
+  if (reqHdr->IsImmediateBlockAck ())
+    {
+      respHdr.SetImmediateBlockAck ();
+    }
+  else
+    {
+      respHdr.SetDelayedBlockAck ();
+    }
+  respHdr.SetTid (reqHdr->GetTid ());
+  /* For now there's not no control about limit of reception.
+     We assume that receiver has no limit on reception.
+     However we assume that a receiver sets a bufferSize in order to satisfy
+     next equation:
+     (bufferSize + 1) % 16 = 0
+     So if a recipient is able to buffer a packet, it should be also able to buffer
+     all possible packet's fragments.
+     See section 7.3.1.14 in IEEE802.11e for more details. */
+  respHdr.SetBufferSize (1023);
+  respHdr.SetTimeout (reqHdr->GetTimeout ());
+
+  WifiActionHeader actionHdr;
+  WifiActionHeader::ActionValue action;
+  action.blockAck = WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE;
+  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
+
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->AddHeader (respHdr);
+  packet->AddHeader (actionHdr);
+  
+  /* ns3::MacLow have to buffer all correctly received packet for this block ack session */
+  m_low->CreateBlockAckAgreement (&respHdr, originator, reqHdr->GetStartingSequence ());
+
+  //Better a management queue? 
+  m_queues[QosUtilsMapTidToAc (reqHdr->GetTid ())]->PushFront (packet, hdr);
+}
 } //namespace ns3
--- a/src/devices/wifi/qadhoc-wifi-mac.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/qadhoc-wifi-mac.h	Thu Feb 25 14:17:21 2010 +0100
@@ -38,6 +38,7 @@
 class DcfManager;
 class MacLow;
 class MacRxMiddle;
+class MgtAddBaRequestHeader;
 
 class QadhocWifiMac : public WifiMac
 {
@@ -73,6 +74,10 @@
   virtual void SetAddress (Mac48Address address);
   virtual void SetSsid (Ssid ssid);
   virtual Mac48Address GetBssid (void) const;
+  virtual void SetBasicBlockAckTimeout (Time blockAckTimeout);
+  virtual void SetCompressedBlockAckTimeout (Time blockAckTimeout);
+  virtual Time GetBasicBlockAckTimeout (void) const;
+  virtual Time GetCompressedBlockAckTimeout (void) const;
 
 
 private:
@@ -82,7 +87,8 @@
   void ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to);
   QadhocWifiMac &operator = (const QadhocWifiMac &);
   QadhocWifiMac (const QadhocWifiMac &);
-
+  void SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr, Mac48Address originator);
+  
   /**
   * When an A-MSDU is received, is deaggregated by this method and all extracted packets are
   * forwarded up.
--- a/src/devices/wifi/qap-wifi-mac.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/qap-wifi-mac.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -199,6 +199,18 @@
 }
 
 void 
+QapWifiMac::SetBasicBlockAckTimeout (Time blockAckTimeout)
+{
+  m_low->SetBasicBlockAckTimeout (blockAckTimeout);
+}
+
+void
+QapWifiMac::SetCompressedBlockAckTimeout (Time blockAckTimeout)
+{
+  m_low->SetCompressedBlockAckTimeout (blockAckTimeout);
+}
+
+void 
 QapWifiMac::SetCtsTimeout (Time ctsTimeout)
 {
   m_low->SetCtsTimeout (ctsTimeout);
@@ -235,6 +247,18 @@
 }
 
 Time 
+QapWifiMac::GetBasicBlockAckTimeout () const
+{
+  return m_low->GetBasicBlockAckTimeout ();
+}
+
+Time 
+QapWifiMac::GetCompressedBlockAckTimeout () const
+{
+  return m_low->GetCompressedBlockAckTimeout ();
+}
+
+Time 
 QapWifiMac::GetCtsTimeout (void) const
 {
   return m_low->GetCtsTimeout ();
@@ -670,7 +694,44 @@
           else if (hdr->IsReassocReq ()) 
             {
               /* we don't support reassoc frames for now */
-            } 
+            }
+          else if (hdr->IsAction ())
+            {
+              WifiActionHeader actionHdr;
+              packet->RemoveHeader (actionHdr);
+              if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
+                  actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST)
+                {
+                  MgtAddBaRequestHeader reqHdr;
+                  packet->RemoveHeader (reqHdr);
+                  SendAddBaResponse (&reqHdr, hdr->GetAddr2 ());
+                }
+              else if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
+                       actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE)
+                {
+                  MgtAddBaResponseHeader respHdr;
+                  packet->RemoveHeader (respHdr);
+                  m_queues[QosUtilsMapTidToAc (respHdr.GetTid ())]->GotAddBaResponse (&respHdr, hdr->GetAddr2 ());
+                }
+              else if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
+                       actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_DELBA)
+                {
+                  MgtDelBaHeader delBaHdr;
+                  packet->RemoveHeader (delBaHdr);
+                  if (delBaHdr.IsByOriginator ())
+                    {
+                      /* Delba frame was sent by originator, this means that an ingoing established
+                      agreement exists in MacLow */
+                      m_low->DestroyBlockAckAgreement (hdr->GetAddr2 (), delBaHdr.GetTid ());
+                    }
+                  else
+                    {
+                      /* We must notify correct queue tear down of agreement */
+                      AccessClass ac = QosUtilsMapTidToAc (delBaHdr.GetTid ());
+                      m_queues[ac]->GotDelBaFrame (&delBaHdr, hdr->GetAddr2 ());
+                    }
+                }
+            }
           else if (hdr->IsAuthentication () ||
                    hdr->IsDeauthentication ()) 
                  {
@@ -741,6 +802,8 @@
   edca->SetTxMiddle (m_txMiddle);
   edca->SetTxOkCallback (MakeCallback (&QapWifiMac::TxOk, this));
   edca->SetTxFailedCallback (MakeCallback (&QapWifiMac::TxFailed, this));
+  edca->SetAccessClass (ac);
+  edca->CompleteConfig ();
   m_queues.insert (std::make_pair(ac, edca));
 }
 
@@ -796,4 +859,59 @@
   WifiMac::DoStart ();
 }
 
+void
+QapWifiMac::SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr, Mac48Address originator)
+{
+  NS_LOG_FUNCTION (this);
+  WifiMacHeader hdr;
+  hdr.SetAction ();
+  hdr.SetAddr1 (originator);
+  hdr.SetAddr2 (m_low->GetAddress ());
+  hdr.SetAddr3 (m_low->GetAddress ());
+  hdr.SetDsNotFrom ();
+  hdr.SetDsNotTo ();
+
+  MgtAddBaResponseHeader respHdr;
+  StatusCode code;
+  code.SetSuccess ();
+  respHdr.SetStatusCode (code);
+  //Here a control about queues type?
+  respHdr.SetAmsduSupport (reqHdr->IsAmsduSupported ());
+  
+  if (reqHdr->IsImmediateBlockAck ())
+    {
+      respHdr.SetImmediateBlockAck ();
+    }
+  else
+    {
+      respHdr.SetDelayedBlockAck ();
+    }
+  respHdr.SetTid (reqHdr->GetTid ());
+  /* For now there's not no control about limit of reception.
+     We assume that receiver has no limit on reception.
+     However we assume that a receiver sets a bufferSize in order to satisfy
+     next equation:
+     (bufferSize + 1) % 16 = 0
+     So if a recipient is able to buffer a packet, it should be also able to buffer
+     all possible packet's fragments.
+     See section 7.3.1.14 in IEEE802.11e for more details. */
+  respHdr.SetBufferSize (1023);
+  respHdr.SetTimeout (reqHdr->GetTimeout ());
+
+  WifiActionHeader actionHdr;
+  WifiActionHeader::ActionValue action;
+  action.blockAck = WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE;
+  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
+
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->AddHeader (respHdr);
+  packet->AddHeader (actionHdr);
+  
+  /* ns3::MacLow have to buffer all correctly received packet for this block ack session */
+  m_low->CreateBlockAckAgreement (&respHdr, originator, reqHdr->GetStartingSequence ());
+
+  //Better a management queue? 
+  m_queues[QosUtilsMapTidToAc (reqHdr->GetTid ())]->PushFront (packet, hdr);
+}
+
 }  //namespace ns3
--- a/src/devices/wifi/qap-wifi-mac.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/qap-wifi-mac.h	Thu Feb 25 14:17:21 2010 +0100
@@ -47,6 +47,7 @@
 class DcfManager;
 class AmsduSubframeHeader;
 class MsduAggregator;
+class MgtAddBaRequestHeader;
 
 class QapWifiMac : public WifiMac
 {
@@ -81,6 +82,10 @@
   virtual void SetAddress (Mac48Address address);
   virtual void SetSsid (Ssid ssid);
   virtual Mac48Address GetBssid (void) const;
+  virtual void SetBasicBlockAckTimeout (Time blockAckTimeout);
+  virtual void SetCompressedBlockAckTimeout (Time blockAckTimeout);
+  virtual Time GetBasicBlockAckTimeout (void) const;
+  virtual Time GetCompressedBlockAckTimeout (void) const;
 
   void SetBeaconInterval (Time interval);
   Time GetBeaconInterval (void) const;
@@ -103,6 +108,7 @@
   void TxFailed (const WifiMacHeader& hdr);
   void SendProbeResp (Mac48Address to);
   void SendAssocResp (Mac48Address to, bool success);
+  void SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr, Mac48Address originator);
   void SendOneBeacon (void);
   SupportedRates GetSupportedRates (void) const;
   void SetBeaconGeneration (bool enable);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/qos-blocked-destinations.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,66 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005, 2009 INRIA
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * 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: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#include "qos-blocked-destinations.h"
+
+namespace ns3 {
+
+QosBlockedDestinations::QosBlockedDestinations ()
+{}
+
+QosBlockedDestinations::~QosBlockedDestinations ()
+{}
+
+bool
+QosBlockedDestinations::IsBlocked (Mac48Address dest, uint8_t tid) const
+{
+  for (BlockedPacketsCI i = m_blockedQosPackets.begin (); i != m_blockedQosPackets.end (); i++)
+    {
+      if (i->first == dest && i->second == tid)
+        {
+          return true;
+        }
+    }
+  return false;
+}
+
+void
+QosBlockedDestinations::Block (Mac48Address dest, uint8_t tid)
+{
+  if (!IsBlocked (dest, tid))
+    {
+      m_blockedQosPackets.push_back (std::make_pair (dest, tid));
+    }
+}
+
+void
+QosBlockedDestinations::Unblock (Mac48Address dest, uint8_t tid)
+{
+  for (BlockedPacketsI i = m_blockedQosPackets.begin (); i != m_blockedQosPackets.end (); i++)
+    {
+      if (i->first == dest && i->second == tid)
+        {
+          m_blockedQosPackets.erase (i);
+          break;
+        }
+    }
+}
+
+} //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/qos-blocked-destinations.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,48 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005, 2009 INRIA
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * 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: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#ifndef QOS_BLOCKED_DESTINATIONS_H
+#define QOS_BLOCKED_DESTINATIONS_H
+
+#include <list>
+#include "ns3/mac48-address.h"
+
+namespace ns3 {
+
+class QosBlockedDestinations
+{
+public:
+  QosBlockedDestinations ();
+  ~QosBlockedDestinations ();
+
+  void Block (Mac48Address dest, uint8_t tid);
+  void Unblock (Mac48Address dest, uint8_t tid);
+  bool IsBlocked (Mac48Address dest, uint8_t tid) const;
+
+private:
+  typedef std::list<std::pair<Mac48Address, uint8_t> > BlockedPackets;
+  typedef std::list<std::pair<Mac48Address, uint8_t> >::iterator BlockedPacketsI;
+  typedef std::list<std::pair<Mac48Address, uint8_t> >::const_iterator BlockedPacketsCI;
+  BlockedPackets m_blockedQosPackets;
+};
+
+} //namespace ns3
+
+#endif /* QOS_BLOCKED_DESTINATIONS_H */
--- a/src/devices/wifi/qos-utils.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/qos-utils.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -16,6 +16,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mirko Banchi <mk.banchi@gmail.com>
+ * Author: Cecchi Niccolò <insa@igeek.it>
  */
 #include "qos-utils.h"
 #include "qos-tag.h"
@@ -69,4 +70,16 @@
   return tid;
 }
 
+uint32_t
+QosUtilsMapSeqControlToUniqueInteger (uint16_t seqControl, uint16_t endSequence)
+{
+  uint32_t integer = 0;
+  uint16_t numberSeq = (seqControl>>4) & 0x0fff;
+  integer = (4096 - (endSequence + 1) + numberSeq) % 4096;
+  integer *= 16;
+  integer += (seqControl & 0x000f);
+  return integer; 
+}
+
+
 } //namespace ns3
--- a/src/devices/wifi/qos-utils.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/qos-utils.h	Thu Feb 25 14:17:21 2010 +0100
@@ -45,6 +45,13 @@
  */
 uint8_t QosUtilsGetTidForPacket (Ptr<const Packet> packet);
 
+/*
+ * Next function is useful to correctly sort buffered packets under block ack.
+ * When an BAR is received from originator station, completed "old"
+ * (see section 9.10.3 in IEEE802.11e) packets must be forwarded up before "new" packets.
+ */
+uint32_t QosUtilsMapSeqControlToUniqueInteger (uint16_t seqControl, uint16_t endSequence);
+
 } //namespace ns3
 
 #endif /* QOS_UTILS_H */
--- a/src/devices/wifi/qsta-wifi-mac.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/qsta-wifi-mac.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -170,6 +170,18 @@
   m_low->SetAckTimeout (ackTimeout);
 }
 
+void 
+QstaWifiMac::SetBasicBlockAckTimeout (Time blockAckTimeout)
+{
+  m_low->SetBasicBlockAckTimeout (blockAckTimeout);
+}
+
+void 
+QstaWifiMac::SetCompressedBlockAckTimeout (Time blockAckTimeout)
+{
+  m_low->SetCompressedBlockAckTimeout (blockAckTimeout);
+}
+
 void
 QstaWifiMac::SetCtsTimeout (Time ctsTimeout)
 {
@@ -206,6 +218,18 @@
  return m_low->GetAckTimeout ();
 }
 
+Time 
+QstaWifiMac::GetBasicBlockAckTimeout (void) const
+{
+  return m_low->GetBasicBlockAckTimeout ();
+}
+
+Time 
+QstaWifiMac::GetCompressedBlockAckTimeout (void) const
+{
+  return m_low->GetCompressedBlockAckTimeout ();
+}
+
 Time
 QstaWifiMac::GetCtsTimeout (void) const
 {
@@ -674,6 +698,43 @@
             }
         }
     }
+  else if (hdr->IsAction ())
+    {
+      WifiActionHeader actionHdr;
+      packet->RemoveHeader (actionHdr);
+      if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
+          actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST)
+        {
+          MgtAddBaRequestHeader reqHdr;
+          packet->RemoveHeader (reqHdr);
+          SendAddBaResponse (&reqHdr, hdr->GetAddr2 ());
+        }
+      else if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
+               actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE)
+        {
+          MgtAddBaResponseHeader respHdr;
+          packet->RemoveHeader (respHdr);
+          m_queues[QosUtilsMapTidToAc (respHdr.GetTid ())]->GotAddBaResponse (&respHdr, hdr->GetAddr2 ());
+        }
+      else if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
+               actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_DELBA)
+        {
+          MgtDelBaHeader delBaHdr;
+          packet->RemoveHeader (delBaHdr);
+          if (delBaHdr.IsByOriginator ())
+            {
+              /* Delba frame was sent by originator, this means that an ingoing established
+                 agreement exists in MacLow */
+              m_low->DestroyBlockAckAgreement (hdr->GetAddr2 (), delBaHdr.GetTid ());
+            }
+          else
+            {
+              /* We must notify correct queue tear down of agreement */
+              AccessClass ac = QosUtilsMapTidToAc (delBaHdr.GetTid ());
+              m_queues[ac]->GotDelBaFrame (&delBaHdr, hdr->GetAddr2 ());
+            }
+        }
+    }
 }
 
 SupportedRates
@@ -731,6 +792,8 @@
   edca->SetManager (m_dcfManager);
   edca->SetTypeOfStation (STA);
   edca->SetTxMiddle (m_txMiddle);
+  edca->SetAccessClass (ac);
+  edca->CompleteConfig ();
   m_queues.insert (std::make_pair(ac, edca));
 }
 
@@ -775,5 +838,59 @@
     }
 }
 
+void
+QstaWifiMac::SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr, Mac48Address originator)
+{
+  NS_LOG_FUNCTION (this);
+  WifiMacHeader hdr;
+  hdr.SetAction ();
+  hdr.SetAddr1 (originator);
+  hdr.SetAddr2 (m_low->GetAddress ());
+  hdr.SetAddr3 (m_low->GetAddress ());
+  hdr.SetDsNotFrom ();
+  hdr.SetDsNotTo ();
+
+  MgtAddBaResponseHeader respHdr;
+  StatusCode code;
+  code.SetSuccess ();
+  respHdr.SetStatusCode (code);
+  //Here a control about queues type?
+  respHdr.SetAmsduSupport (reqHdr->IsAmsduSupported ());
+
+  if (reqHdr->IsImmediateBlockAck ())
+    {
+      respHdr.SetImmediateBlockAck ();
+    }
+  else
+    {
+      respHdr.SetDelayedBlockAck ();
+    }
+  respHdr.SetTid (reqHdr->GetTid ());
+  /* For now there's not no control about limit of reception.
+     We assume that receiver has no limit on reception.
+     However we assume that a receiver sets a bufferSize in order to satisfy
+     next equation:
+     (bufferSize + 1) % 16 = 0
+     So if a recipient is able to buffer a packet, it should be also able to buffer
+     all possible packet's fragments.
+     See section 7.3.1.14 in IEEE802.11e for more details. */
+  respHdr.SetBufferSize (1023);
+  respHdr.SetTimeout (reqHdr->GetTimeout ());
+
+  WifiActionHeader actionHdr;
+  WifiActionHeader::ActionValue action;
+  action.blockAck = WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE;
+  actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
+
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->AddHeader (respHdr);
+  packet->AddHeader (actionHdr);
+  
+  /* ns3::MacLow have to buffer all correctly received packet for this block ack session */
+  m_low->CreateBlockAckAgreement (&respHdr, originator, reqHdr->GetStartingSequence ());
+
+  //Better a management queue? 
+  m_queues[QosUtilsMapTidToAc (reqHdr->GetTid ())]->PushFront (packet, hdr);
+}
 
 }  //namespace ns3
--- a/src/devices/wifi/qsta-wifi-mac.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/qsta-wifi-mac.h	Thu Feb 25 14:17:21 2010 +0100
@@ -45,6 +45,7 @@
 class WifiMacHeader;
 class AmsduSubframeHeader;
 class MsduAggregator;
+class MgtAddBaRequestHeader;
 
 class QstaWifiMac : public WifiMac
 {
@@ -80,6 +81,10 @@
   virtual void SetAddress (Mac48Address address);
   virtual void SetSsid (Ssid ssid);
   virtual Mac48Address GetBssid (void) const;
+  virtual void SetBasicBlockAckTimeout (Time blockAckTimeout);
+  virtual void SetCompressedBlockAckTimeout (Time blockAckTimeout);
+  virtual Time GetBasicBlockAckTimeout (void) const;
+  virtual Time GetCompressedBlockAckTimeout (void) const;
 
   void SetMaxMissedBeacons (uint32_t missed);
   void SetProbeRequestTimeout (Time timeout);
@@ -100,6 +105,7 @@
   void ProbeRequestTimeout (void);
   void SendAssociationRequest (void);
   void SendProbeRequest (void);
+  void SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr, Mac48Address originator);
   void TryToEnsureAssociated (void);
   bool IsAssociated (void) const;
   bool IsWaitAssocResp (void) const;
--- a/src/devices/wifi/wifi-channel.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/wifi-channel.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -28,8 +28,8 @@
 #include "wifi-channel.h"
 #include "wifi-net-device.h"
 #include "yans-wifi-phy.h"
-#include "propagation-loss-model.h"
-#include "propagation-delay-model.h"
+#include "ns3/propagation-loss-model.h"
+#include "ns3/propagation-delay-model.h"
 
 NS_LOG_COMPONENT_DEFINE ("WifiChannel");
 
--- a/src/devices/wifi/wifi-mac-header.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/wifi-mac-header.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -122,6 +122,19 @@
   m_ctrlType = TYPE_MGT;
   m_ctrlSubtype = 8;
 }
+void
+WifiMacHeader::SetBlockAckReq (void)
+{
+  m_ctrlType = TYPE_CTL;
+  m_ctrlSubtype = 8;
+}
+void
+WifiMacHeader::SetBlockAck (void)
+{
+  m_ctrlType = TYPE_CTL;
+  m_ctrlSubtype = 9;
+}
+
 void 
 WifiMacHeader::SetTypeData (void)
 {
@@ -348,6 +361,21 @@
     break;
   }
 }
+void
+WifiMacHeader::SetQosNormalAck ()
+{
+  m_qosAckPolicy = 0;
+}
+void
+WifiMacHeader::SetQosBlockAck ()
+{
+  m_qosAckPolicy = 3;
+}
+void
+WifiMacHeader::SetQosNoAck ()
+{
+  m_qosAckPolicy = 1;
+}
 void WifiMacHeader::SetQosAmsdu (void)
 {
   m_amsduPresent = 1;
@@ -630,6 +658,16 @@
 {
   return (GetType () == WIFI_MAC_MGT_MULTIHOP_ACTION);
 }
+bool
+WifiMacHeader::IsBlockAckReq (void) const
+{
+  return (GetType () == WIFI_MAC_CTL_BACKREQ)?true:false;
+}
+bool
+WifiMacHeader::IsBlockAck (void) const
+{
+  return (GetType () == WIFI_MAC_CTL_BACKRESP)?true:false;
+}
 
 
 uint16_t 
@@ -808,8 +846,7 @@
       break;
     case SUBTYPE_CTL_BACKREQ:
     case SUBTYPE_CTL_BACKRESP:
-      // NOT IMPLEMENTED
-      NS_ASSERT (false);
+      size = 2+2+6+6;
       break;
     }
     break;
@@ -1018,8 +1055,7 @@
       break;
     case SUBTYPE_CTL_BACKREQ:
     case SUBTYPE_CTL_BACKRESP:
-      // NOT IMPLEMENTED
-      NS_ASSERT (false);
+      WriteTo (i, m_addr2);
       break;
     default:
       //NOTREACHED
@@ -1068,8 +1104,7 @@
       break;
     case SUBTYPE_CTL_BACKREQ:
     case SUBTYPE_CTL_BACKRESP:
-      // NOT IMPLEMENTED
-      NS_ASSERT (false);
+      ReadFrom (i, m_addr2);
       break;
     }
     break;
--- a/src/devices/wifi/wifi-mac-header.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/wifi-mac-header.h	Thu Feb 25 14:17:21 2010 +0100
@@ -102,6 +102,8 @@
   void SetBeacon (void);
   void SetTypeData (void);
   void SetAction ();
+  void SetBlockAckReq (void);
+  void SetBlockAck (void);
   void SetMultihopAction();
   void SetDsFrom (void);
   void SetDsNotFrom (void);
@@ -125,6 +127,9 @@
   void SetQosEosp ();
   void SetQosNoEosp ();
   void SetQosAckPolicy (enum QosAckPolicy);
+  void SetQosNormalAck (void);
+  void SetQosBlockAck (void);
+  void SetQosNoAck (void);
   void SetQosAmsdu (void);
   void SetQosNoAmsdu (void);
   void SetQosTxopLimit (uint8_t txop);
@@ -145,6 +150,8 @@
   bool IsRts (void) const;
   bool IsCts (void) const;
   bool IsAck (void) const;
+  bool IsBlockAckReq (void) const;
+  bool IsBlockAck (void) const;
   bool IsAssocReq (void) const;
   bool IsAssocResp (void) const;
   bool IsReassocReq (void) const;
--- a/src/devices/wifi/wifi-mac-queue.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/wifi-mac-queue.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -24,6 +24,7 @@
 #include "ns3/uinteger.h"
 
 #include "wifi-mac-queue.h"
+#include "qos-blocked-destinations.h"
 
 using namespace std;
 
@@ -111,18 +112,19 @@
 
   Time now = Simulator::Now ();
   uint32_t n = 0;
-  PacketQueueI end = m_queue.begin ();
-  for (PacketQueueI i = m_queue.begin (); i != m_queue.end (); i++) 
+  for (PacketQueueI i = m_queue.begin (); i != m_queue.end ();) 
     {
       if (i->tstamp + m_maxDelay > now) 
         {
-          end = i;
-          break;
+          i++;
         }
-      n++;
+      else
+        {
+          i = m_queue.erase (i);
+          n++;
+        }
     }
   m_size -= n;
-  m_queue.erase (m_queue.begin (), end);
 }
 
 Ptr<const Packet>
@@ -260,4 +262,81 @@
   return false;
 }
 
+void
+WifiMacQueue::PushFront (Ptr<const Packet> packet, const WifiMacHeader &hdr)
+{
+  Cleanup ();
+  if (m_size == m_maxSize)
+    {
+      return;
+    }
+  Time now = Simulator::Now ();
+  m_queue.push_front (Item (packet, hdr, now));
+  m_size++;
+}
+
+uint32_t
+WifiMacQueue::GetNPacketsByTidAndAddress (uint8_t tid, WifiMacHeader::AddressType type,
+                                          Mac48Address addr)
+{
+  Cleanup ();
+  uint32_t nPackets = 0;
+  if (!m_queue.empty ())
+    {
+      PacketQueueI it;
+      NS_ASSERT (type <= 4);
+      for (it = m_queue.begin (); it != m_queue.end (); it++)
+        {
+          if (GetAddressForPacket (type, it) == addr)
+            {
+              if (it->hdr.IsQosData () && it->hdr.GetQosTid () == tid)
+                {
+                  nPackets++;
+                }
+            }
+        }
+    }
+  return nPackets;
+}
+
+Ptr<const Packet>
+WifiMacQueue::DequeueFirstAvailable (WifiMacHeader *hdr, Time &timestamp,
+                                     const QosBlockedDestinations *blockedPackets)
+{
+  Cleanup ();
+  Ptr<const Packet> packet = 0;
+  for (PacketQueueI it = m_queue.begin (); it != m_queue.end (); it++)
+    {
+      if (!it->hdr.IsQosData () ||
+          !blockedPackets->IsBlocked (it->hdr.GetAddr1 (), it->hdr.GetQosTid ()))
+        {
+          *hdr = it->hdr;
+          timestamp = it->tstamp;
+          packet = it->packet;
+          m_queue.erase (it);
+          m_size--;
+          return packet;
+        }
+    }
+  return packet;
+}
+
+Ptr<const Packet>
+WifiMacQueue::PeekFirstAvailable (WifiMacHeader *hdr, Time &timestamp,
+                                  const QosBlockedDestinations *blockedPackets)
+{
+  Cleanup ();
+  for (PacketQueueI it = m_queue.begin (); it != m_queue.end (); it++)
+    {
+      if (!it->hdr.IsQosData () ||
+          !blockedPackets->IsBlocked (it->hdr.GetAddr1 (), it->hdr.GetQosTid ()))
+        {
+          *hdr = it->hdr;
+          timestamp = it->tstamp;
+          return it->packet;
+        }
+    }
+  return 0;
+}
+
 } // namespace ns3
--- a/src/devices/wifi/wifi-mac-queue.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/wifi-mac-queue.h	Thu Feb 25 14:17:21 2010 +0100
@@ -32,6 +32,7 @@
 namespace ns3 {
 
 class WifiMacParameters;
+class QosBlockedDestinations;
 
 /**
  * \brief a 802.11e-specific queue.
@@ -61,6 +62,7 @@
   Time GetMaxDelay (void) const;
 
   void Enqueue (Ptr<const Packet> packet, const WifiMacHeader &hdr);
+  void PushFront (Ptr<const Packet> packet, const WifiMacHeader &hdr);
   Ptr<const Packet> Dequeue (WifiMacHeader *hdr);
   Ptr<const Packet> Peek (WifiMacHeader *hdr);
   /**
@@ -91,12 +93,33 @@
    * performed in linear time (O(n)).  
    */
   bool Remove (Ptr<const Packet> packet);
-  
+  /**
+   * Returns number of QoS packets having tid equals to <i>tid</i> and address
+   * specified by <i>type</i> equals to <i>addr</i>.
+   */
+  uint32_t GetNPacketsByTidAndAddress (uint8_t tid,
+                                       WifiMacHeader::AddressType type,
+                                       Mac48Address addr);
+  /**
+   * Returns first available packet for transmission. A packet could be no available
+   * if it's a QoS packet with a tid and an address1 fields equal to <i>tid</i> and <i>addr</i>
+   * respectively that index a pending agreement in the BlockAckManager object.
+   * So that packet must not be transmitted until reception of an ADDBA response frame from station
+   * addressed by <i>addr</i>. This method removes the packet from queue. 
+   */
+  Ptr<const Packet> DequeueFirstAvailable (WifiMacHeader *hdr,
+                                           Time &tStamp,
+                                           const QosBlockedDestinations *blockedPackets);
+  /**
+   * Returns first available packet for transmission. The packet isn't removed from queue.
+   */
+  Ptr<const Packet> PeekFirstAvailable (WifiMacHeader *hdr,
+                                        Time &tStamp,
+                                        const QosBlockedDestinations *blockedPackets);
   void Flush (void);
 
   bool IsEmpty (void);
   uint32_t GetSize (void);
-
 private:
   struct Item;
   
--- a/src/devices/wifi/wifi-mac.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/wifi-mac.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -69,6 +69,63 @@
   return ctsTimeout;
 }
 
+Time
+WifiMac::GetDefaultBasicBlockAckDelay (void)
+{
+  // This value must be rivisited
+  return MicroSeconds (250);
+}
+Time
+WifiMac::GetDefaultCompressedBlockAckDelay (void)
+{
+  // This value must be rivisited
+  return MicroSeconds (68);
+}
+Time
+WifiMac::GetDefaultBasicBlockAckTimeout (void)
+{
+  Time blockAckTimeout = GetDefaultSifs ();
+  blockAckTimeout += GetDefaultBasicBlockAckDelay ();
+  blockAckTimeout += MicroSeconds (GetDefaultMaxPropagationDelay ().GetMicroSeconds () * 2);
+  blockAckTimeout += GetDefaultSlot ();
+  return blockAckTimeout;
+}
+Time
+WifiMac::GetDefaultCompressedBlockAckTimeout (void)
+{
+  Time blockAckTimeout = GetDefaultSifs ();
+  blockAckTimeout += GetDefaultCompressedBlockAckDelay ();
+  blockAckTimeout += MicroSeconds (GetDefaultMaxPropagationDelay ().GetMicroSeconds () * 2);
+  blockAckTimeout += GetDefaultSlot ();
+  return blockAckTimeout;
+}
+
+void
+WifiMac::SetBasicBlockAckTimeout (Time blockAckTimeout)
+{
+  //this method must be implemented by QoS WifiMacs
+}
+
+Time
+WifiMac::GetBasicBlockAckTimeout (void) const
+{
+  //this method must be implemented by QoS WifiMacs
+  return MicroSeconds (0);
+}
+
+void
+WifiMac::SetCompressedBlockAckTimeout (Time blockAckTimeout)
+{
+  //this methos must be implemented by QoS WifiMacs
+}
+
+Time
+WifiMac::GetCompressedBlockAckTimeout (void) const
+{
+  //this method must be implemented by QoS WifiMacs
+  return MicroSeconds (0);
+}
+
 TypeId 
 WifiMac::GetTypeId (void)
 {
@@ -84,6 +141,16 @@
                    MakeTimeAccessor (&WifiMac::GetAckTimeout,
                                      &WifiMac::SetAckTimeout),
                    MakeTimeChecker ())
+    .AddAttribute ("BasicBlockAckTimeout", "When this timeout expires, the BASIC_BLOCK_ACK_REQ/BASIC_BLOCK_ACK handshake has failed.",
+                   TimeValue (GetDefaultBasicBlockAckTimeout ()),
+                   MakeTimeAccessor (&WifiMac::GetBasicBlockAckTimeout,
+                                     &WifiMac::SetBasicBlockAckTimeout),
+                   MakeTimeChecker ())
+    .AddAttribute ("CompressedBlockAckTimeout", "When this timeout expires, the COMPRESSED_BLOCK_ACK_REQ/COMPRESSED_BLOCK_ACK handshake has failed.",
+                   TimeValue (GetDefaultCompressedBlockAckTimeout ()),
+                   MakeTimeAccessor (&WifiMac::GetCompressedBlockAckTimeout,
+                                     &WifiMac::SetCompressedBlockAckTimeout),
+                   MakeTimeChecker ())
     .AddAttribute ("Sifs", "The value of the SIFS constant.",
                    TimeValue (GetDefaultSifs ()),
                    MakeTimeAccessor (&WifiMac::SetSifs,
--- a/src/devices/wifi/wifi-mac.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/wifi-mac.h	Thu Feb 25 14:17:21 2010 +0100
@@ -179,6 +179,13 @@
    * \param linkDown the callback to invoke when the link becomes down.
    */
   virtual void SetLinkDownCallback (Callback<void> linkDown) = 0;
+  /* Next functions are not pure vitual so non Qos WifiMacs are not
+   * forced to implement them.
+   */
+  virtual void SetBasicBlockAckTimeout (Time blockAckTimeout);
+  virtual Time GetBasicBlockAckTimeout (void) const;
+  virtual void SetCompressedBlockAckTimeout (Time blockAckTimeout);
+  virtual Time GetCompressedBlockAckTimeout (void) const;
 
   /**
    * Public method used to fire a MacTx trace.  Implemented for encapsulation 
@@ -224,6 +231,10 @@
   static Time GetDefaultEifsNoDifs (void);
   static Time GetDefaultCtsAckDelay (void);
   static Time GetDefaultCtsAckTimeout (void);
+  static Time GetDefaultBasicBlockAckDelay (void);
+  static Time GetDefaultBasicBlockAckTimeout (void);
+  static Time GetDefaultCompressedBlockAckDelay (void);
+  static Time GetDefaultCompressedBlockAckTimeout (void);
   /**
    * \param standard the phy standard to be used
    *
--- a/src/devices/wifi/wifi-mode.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/wifi-mode.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -148,9 +148,32 @@
   item->standard = standard;
   return WifiMode (uid);
 }
+
+WifiMode 
+WifiModeFactory::CreateQpsk (std::string uniqueName,
+			     bool isMandatory,
+			     uint32_t bandwidth,
+			     uint32_t dataRate,
+			     uint32_t phyRate,
+                             enum WifiPhyStandard standard)
+{
+  WifiModeFactory *factory = GetFactory ();
+  uint32_t uid = factory->AllocateUid (uniqueName);
+  WifiModeItem *item = factory->Get (uid);
+  item->uniqueUid = uniqueName;
+  item->bandwidth = bandwidth;
+  item->dataRate = dataRate;
+  item->phyRate = phyRate;
+  item->modulation = WifiMode::QPSK;
+  item->constellationSize = 4;
+  item->isMandatory = isMandatory;
+  item->standard = standard;
+  return WifiMode (uid);
+}
+
 WifiMode 
 WifiModeFactory::CreateQam (std::string uniqueName,
-			     bool isMandatory,
+                            bool isMandatory,
 			    uint32_t bandwidth,
 			    uint32_t dataRate,
 			    uint32_t phyRate,
--- a/src/devices/wifi/wifi-mode.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/wifi-mode.h	Thu Feb 25 14:17:21 2010 +0100
@@ -42,6 +42,7 @@
  public:
   enum ModulationType {
     BPSK,
+    QPSK,
     DBPSK,
     DQPSK,
     QAM,
@@ -170,6 +171,25 @@
    *        associated WifiMode is used.
    * \param dataRate the rate (bits/second) at which the user data is transmitted
    * \param phyRate the rate (bits/second) at which the encoded user data is transmitted
+   * \param standard the Wifi Phy standard to apply
+   *        The phyRate includes FEC so, is typically higher than the dataRate.
+   *
+   * Create a QPSK WifiMode.
+   */
+  static WifiMode CreateQpsk (std::string uniqueName,
+			      bool isMandatory,
+			      uint32_t bandwidth,
+			      uint32_t dataRate,
+			      uint32_t phyRate,
+                              enum WifiPhyStandard standard);
+  /**
+   * \param uniqueName the name of the associated WifiMode. This name
+   *        must be unique accross _all_ instances.
+   * \param isMandatory true if this WifiMode is mandatory, false otherwise.
+   * \param bandwidth the bandwidth (Hz) of the signal generated when the
+   *        associated WifiMode is used.
+   * \param dataRate the rate (bits/second) at which the user data is transmitted
+   * \param phyRate the rate (bits/second) at which the encoded user data is transmitted
    *        The phyRate includes FEC so, is typically higher than the dataRate.
    * \param constellationSize the number of elements included in the QAM constellation. 
    * \param standard the Wifi Phy standard to apply
--- a/src/devices/wifi/wifi-phy-test.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/wifi-phy-test.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -20,8 +20,8 @@
 #include "wifi-net-device.h"
 #include "yans-wifi-channel.h"
 #include "yans-wifi-phy.h"
-#include "propagation-loss-model.h"
-#include "propagation-delay-model.h"
+#include "ns3/propagation-loss-model.h"
+#include "ns3/propagation-delay-model.h"
 #include "error-rate-model.h"
 #include "yans-error-rate-model.h"
 #include "ns3/ptr.h"
--- a/src/devices/wifi/wifi-phy.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/wifi-phy.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -114,7 +114,7 @@
 WifiMode 
 WifiPhy::Get12mba (void)
 {
-  static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-12mbs",
+  static WifiMode mode = WifiModeFactory::CreateQpsk ("wifia-12mbs",
                                                       true,
                                                       20000000, 12000000, 24000000,
                                                       WIFI_PHY_STANDARD_80211a);
@@ -123,7 +123,7 @@
 WifiMode 
 WifiPhy::Get18mba (void)
 {
-  static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-18mbs",
+  static WifiMode mode = WifiModeFactory::CreateQpsk ("wifia-18mbs",
                                                       false,
                                                       20000000, 18000000, 24000000,
                                                       WIFI_PHY_STANDARD_80211a);
@@ -132,39 +132,43 @@
 WifiMode 
 WifiPhy::Get24mba (void)
 {
-  static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-24mbs",
-                                                      true,
-                                                      20000000, 24000000, 48000000,
-                                                      WIFI_PHY_STANDARD_80211a);
+  static WifiMode mode = WifiModeFactory::CreateQam ("wifia-24mbs",
+                                                     true,
+                                                     20000000, 24000000, 48000000,
+                                                     16,
+                                                     WIFI_PHY_STANDARD_80211a);
   return mode;
 }
 WifiMode 
 WifiPhy::Get36mba (void)
 {
-  static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-36mbs",
-                                                      false,
-                                                      20000000, 36000000, 48000000,
-                                                      WIFI_PHY_STANDARD_80211a);
+  static WifiMode mode = WifiModeFactory::CreateQam ("wifia-36mbs",
+                                                     false,
+                                                     20000000, 36000000, 48000000,
+                                                     16,
+                                                     WIFI_PHY_STANDARD_80211a);
   return mode;
 }
 
 WifiMode 
 WifiPhy::Get48mba (void)
 {
-  static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-48mbs",
-                                                      false,
-                                                      20000000, 48000000, 72000000,
-                                                      WIFI_PHY_STANDARD_80211a);
+  static WifiMode mode = WifiModeFactory::CreateQam ("wifia-48mbs",
+                                                     false,
+                                                     20000000, 48000000, 72000000,
+                                                     64,
+                                                     WIFI_PHY_STANDARD_80211a);
   return mode;
 }
 
 WifiMode 
 WifiPhy::Get54mba (void)
 {
-  static WifiMode mode = WifiModeFactory::CreateBpsk ("wifia-54mbs",
-                                                      false,
-                                                      20000000, 54000000, 72000000,
-                                                      WIFI_PHY_STANDARD_80211a);
+  static WifiMode mode = WifiModeFactory::CreateQam ("wifia-54mbs",
+                                                     false,
+                                                     20000000, 54000000, 72000000,
+                                                     64,
+                                                     WIFI_PHY_STANDARD_80211a);
   return mode;
 }
 
--- a/src/devices/wifi/wifi-test.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/wifi-test.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -23,8 +23,8 @@
 #include "adhoc-wifi-mac.h"
 #include "yans-wifi-phy.h"
 #include "arf-wifi-manager.h"
-#include "propagation-delay-model.h"
-#include "propagation-loss-model.h"
+#include "ns3/propagation-delay-model.h"
+#include "ns3/propagation-loss-model.h"
 #include "error-rate-model.h"
 #include "yans-error-rate-model.h"
 #include "ns3/constant-position-mobility-model.h"
@@ -143,7 +143,7 @@
   m_propDelay.SetTypeId ("ns3::RandomPropagationDelayModel");
   m_mac.SetTypeId ("ns3::AdhocWifiMac");
   RunOne ();
-
+  Simulator::Destroy ();
   return false;
 }
 
--- a/src/devices/wifi/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -3,10 +3,6 @@
 def build(bld):
     obj = bld.create_ns3_module('wifi', ['node'])
     obj.source = [
-        'propagation-delay-model.cc',
-        'propagation-loss-model.cc',
-        'propagation-loss-model-test-suite.cc',
-        'jakes-propagation-loss-model.cc',
         'wifi-channel.cc',
         'wifi-mode.cc',
         'ssid.cc',
@@ -58,14 +54,17 @@
         'msdu-aggregator.cc',
         'amsdu-subframe-header.cc',
         'msdu-standard-aggregator.cc',
+        'originator-block-ack-agreement.cc',
         'dcf.cc',
+        'ctrl-headers.cc',
+        'qos-blocked-destinations.cc',
+        'block-ack-agreement.cc',
+        'block-ack-manager.cc',
+        'block-ack-test-suite.cc',
         ]
     headers = bld.new_task_gen('ns3header')
     headers.module = 'wifi'
     headers.source = [
-        'propagation-delay-model.h',
-        'propagation-loss-model.h',
-        'jakes-propagation-loss-model.h',
         'wifi-net-device.h',
         'wifi-channel.h',
         'wifi-mode.h',
@@ -111,7 +110,11 @@
         'dcf-manager.h',
         'mac-rx-middle.h', 
         'mac-low.h',
+        'originator-block-ack-agreement.h',
         'dcf.h',
+        'ctrl-headers.h',
+        'block-ack-agreement.h',
+        'block-ack-manager.h',
         ]
 
     if bld.env['ENABLE_GSL']:
--- a/src/devices/wifi/yans-wifi-channel.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/yans-wifi-channel.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -27,8 +27,8 @@
 #include "ns3/object-factory.h"
 #include "yans-wifi-channel.h"
 #include "yans-wifi-phy.h"
-#include "propagation-loss-model.h"
-#include "propagation-delay-model.h"
+#include "ns3/propagation-loss-model.h"
+#include "ns3/propagation-delay-model.h"
 
 NS_LOG_COMPONENT_DEFINE ("YansWifiChannel");
 
--- a/src/helper/csma-helper.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/csma-helper.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -17,7 +17,9 @@
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
-#include "csma-helper.h"
+
+#include "ns3/abort.h"
+#include "ns3/log.h"
 #include "ns3/simulator.h"
 #include "ns3/object-factory.h"
 #include "ns3/queue.h"
@@ -26,10 +28,14 @@
 #include "ns3/config.h"
 #include "ns3/packet.h"
 #include "ns3/names.h"
-#include "ns3/pcap-writer.h"
-#include "ns3/ascii-writer.h"
+
+#include "trace-helper.h"
+#include "csma-helper.h"
+
 #include <string>
 
+NS_LOG_COMPONENT_DEFINE ("CsmaHelper");
+
 namespace ns3 {
 
 CsmaHelper::CsmaHelper ()
@@ -66,123 +72,118 @@
 }
 
 void 
-CsmaHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid, bool promiscuous)
+CsmaHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous)
 {
-  std::ostringstream oss;
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/";
-  Config::MatchContainer matches = Config::LookupMatches (oss.str ());
-  if (matches.GetN () == 0)
+  //
+  // All of the Pcap enable functions vector through here including the ones
+  // that are wandering through all of devices on perhaps all of the nodes in
+  // the system.  We can only deal with devices of type CsmaNetDevice.
+  //
+  Ptr<CsmaNetDevice> device = nd->GetObject<CsmaNetDevice> ();
+  if (device == 0)
     {
+      NS_LOG_INFO ("CsmaHelper::EnablePcapInternal(): Device " << device << " not of type ns3::CsmaNetDevice");
       return;
     }
-  oss.str ("");
-  oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
-  Ptr<PcapWriter> pcap = CreateObject<PcapWriter> ();
-  pcap->Open (oss.str ());
-  pcap->WriteEthernetHeader ();
-  oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
+
+  PcapHelper pcapHelper;
+  std::string filename = pcapHelper.GetFilenameFromDevice (prefix, device);
+  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_EN10MB);
   if (promiscuous)
     {
-      oss << "/$ns3::CsmaNetDevice/PromiscSniffer";
+      pcapHelper.HookDefaultSink<CsmaNetDevice> (device, "PromiscSniffer", file);
     }
   else
     {
-      oss << "/$ns3::CsmaNetDevice/Sniffer";
-    }
-  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&CsmaHelper::SniffEvent, pcap));
-}
-
-void 
-CsmaHelper::EnablePcap (std::string filename, NetDeviceContainer d, bool promiscuous)
-{
-  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
-    {
-      Ptr<NetDevice> dev = *i;
-      EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex (), promiscuous);
+      pcapHelper.HookDefaultSink<CsmaNetDevice> (device, "Sniffer", file);
     }
 }
 
 void 
-CsmaHelper::EnablePcap (std::string filename, Ptr<NetDevice> nd, bool promiscuous)
-{
-  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex (), promiscuous);
-}
-
-void 
-CsmaHelper::EnablePcap (std::string filename, std::string ndName, bool promiscuous)
+CsmaHelper::EnableAsciiInternal (Ptr<OutputStreamWrapper> stream, std::string prefix, Ptr<NetDevice> nd)
 {
-  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
-  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex (), promiscuous);
-}
+  //
+  // All of the ascii enable functions vector through here including the ones
+  // that are wandering through all of devices on perhaps all of the nodes in
+  // the system.  We can only deal with devices of type CsmaNetDevice.
+  //
+  Ptr<CsmaNetDevice> device = nd->GetObject<CsmaNetDevice> ();
+  if (device == 0)
+    {
+      NS_LOG_INFO ("CsmaHelper::EnableAsciiInternal(): Device " << device << " not of type ns3::CsmaNetDevice");
+      return;
+    }
 
-void
-CsmaHelper::EnablePcap (std::string filename, NodeContainer n, bool promiscuous)
-{
-  NetDeviceContainer devs;
-  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+  //
+  // Our default trace sinks are going to use packet printing, so we have to 
+  // make sure that is turned on.
+  //
+  Packet::EnablePrinting ();
+
+  //
+  // If we are not provided an OutputStreamWrapper, we are expected to create 
+  // one using the usual trace filename conventions and do a Hook*WithoutContext
+  // since there will be one file per context and therefore the context would
+  // be redundant.
+  //
+  if (stream == 0)
     {
-      Ptr<Node> node = *i;
-      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-        {
-          devs.Add (node->GetDevice (j));
-        }
-    }
-  EnablePcap (filename, devs, promiscuous);
-}
+      //
+      // Set up an output stream object to deal with private ofstream copy 
+      // constructor and lifetime issues.  Let the helper decide the actual
+      // name of the file given the prefix.
+      //
+      AsciiTraceHelper asciiTraceHelper;
+      std::string filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
+      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename, "w");
+
+      //
+      // The MacRx trace source provides our "r" event.
+      //
+      asciiTraceHelper.HookDefaultReceiveSinkWithoutContext<CsmaNetDevice> (device, "MacRx", theStream);
+
+      //
+      // The "+", '-', and 'd' events are driven by trace sources actually in the
+      // transmit queue.
+      //
+      Ptr<Queue> queue = device->GetQueue ();
+      asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext<Queue> (queue, "Enqueue", theStream);
+      asciiTraceHelper.HookDefaultDropSinkWithoutContext<Queue> (queue, "Drop", theStream);
+      asciiTraceHelper.HookDefaultDequeueSinkWithoutContext<Queue> (queue, "Dequeue", theStream);
 
-void
-CsmaHelper::EnablePcapAll (std::string filename, bool promiscuous)
-{
-  EnablePcap (filename, NodeContainer::GetGlobal (), promiscuous);
-}
+      return;
+    }
 
-void 
-CsmaHelper::EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid)
-{
-  Ptr<AsciiWriter> writer = AsciiWriter::Get (os);
-  Packet::EnablePrinting ();
+  //
+  // If we are provided an OutputStreamWrapper, we are expected to use it, and
+  // to providd a context.  We are free to come up with our own context if we
+  // want, and use the AsciiTraceHelper Hook*WithContext functions, but for 
+  // compatibility and simplicity, we just use Config::Connect and let it deal
+  // with the context.
+  //
+  // Note that we are going to use the default trace sinks provided by the 
+  // ascii trace helper.  There is actually no AsciiTraceHelper in sight here,
+  // but the default trace sinks are actually publicly available static 
+  // functions that are always there waiting for just such a case.
+  //
+  uint32_t nodeid = nd->GetNode ()->GetId ();
+  uint32_t deviceid = nd->GetIfIndex ();
   std::ostringstream oss;
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/MacRx";
-  Config::Connect (oss.str (), MakeBoundCallback (&CsmaHelper::AsciiRxEvent, writer));
+
+  oss << "/NodeList/" << nd->GetNode ()->GetId () << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/MacRx";
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultReceiveSinkWithContext, stream));
+
   oss.str ("");
   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/TxQueue/Enqueue";
-  Config::Connect (oss.str (), MakeBoundCallback (&CsmaHelper::AsciiEnqueueEvent, writer));
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultEnqueueSinkWithContext, stream));
+
   oss.str ("");
   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/TxQueue/Dequeue";
-  Config::Connect (oss.str (), MakeBoundCallback (&CsmaHelper::AsciiDequeueEvent, writer));
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDequeueSinkWithContext, stream));
+
   oss.str ("");
   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/TxQueue/Drop";
-  Config::Connect (oss.str (), MakeBoundCallback (&CsmaHelper::AsciiDropEvent, writer));
-}
-void 
-CsmaHelper::EnableAscii (std::ostream &os, NetDeviceContainer d)
-{
-  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
-    {
-      Ptr<NetDevice> dev = *i;
-      EnableAscii (os, dev->GetNode ()->GetId (), dev->GetIfIndex ());
-    }
-}
-void
-CsmaHelper::EnableAscii (std::ostream &os, NodeContainer n)
-{
-  NetDeviceContainer devs;
-  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
-    {
-      Ptr<Node> node = *i;
-      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-        {
-          devs.Add (node->GetDevice (j));
-        }
-    }
-  EnableAscii (os, devs);
-}
-
-void
-CsmaHelper::EnableAsciiAll (std::ostream &os)
-{
-  EnableAscii (os, NodeContainer::GetGlobal ());
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDropSinkWithContext, stream));
 }
 
 NetDeviceContainer
@@ -268,34 +269,4 @@
   return device;
 }
 
-void 
-CsmaHelper::SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
-{
-  writer->WritePacket (packet);
-}
-
-void 
-CsmaHelper::AsciiEnqueueEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet)
-{
-  writer->WritePacket (AsciiWriter::ENQUEUE, path, packet);
-}
-
-void 
-CsmaHelper::AsciiDequeueEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet)
-{
-  writer->WritePacket (AsciiWriter::DEQUEUE, path, packet);
-}
-
-void 
-CsmaHelper::AsciiDropEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet)
-{
-  writer->WritePacket (AsciiWriter::DROP, path, packet);
-}
-
-void 
-CsmaHelper::AsciiRxEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet)
-{
-  writer->WritePacket (AsciiWriter::RX, path, packet);
-}
-
 } // namespace ns3
--- a/src/helper/csma-helper.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/csma-helper.h	Thu Feb 25 14:17:21 2010 +0100
@@ -21,29 +21,36 @@
 #define CSMA_HELPER_H
 
 #include <string>
+
 #include "ns3/attribute.h"
 #include "ns3/object-factory.h"
 #include "ns3/net-device-container.h"
 #include "ns3/node-container.h"
 #include "ns3/csma-channel.h"
 #include "ns3/deprecated.h"
+#include "trace-helper.h"
 
 namespace ns3 {
 
 class Packet;
-class PcapWriter;
-class AsciiWriter;
 
 /**
  * \brief build a set of CsmaNetDevice objects
+ *
+ * Normally we eschew multiple inheritance, however, the classes 
+ * PcapUserHelperForDevice and AsciiTraceUserHelperForDevice are
+ * treated as "mixins".  A mixin is a self-contained class that
+ * encapsulates a general attribute or a set of functionality that
+ * may be of interest to many other classes.
  */
-class CsmaHelper
+class CsmaHelper : public PcapHelperForDevice, public AsciiTraceHelperForDevice
 {
 public:
   /**
    * Construct a CsmaHelper.
    */
   CsmaHelper ();
+  virtual ~CsmaHelper () {}
 
   /**
    * \param type the type of queue
@@ -84,106 +91,6 @@
   void SetChannelAttribute (std::string n1, const AttributeValue &v1);
 
   /**
-   * \param filename filename prefix to use for pcap files.
-   * \param nodeid the id of the node to generate pcap output for.
-   * \param deviceid the id of the device to generate pcap output for.
-   * \param promiscuous If true capture all possible packets available at the device.
-   *
-   * Generate a pcap file which contains the link-level data observed
-   * by the specified deviceid within the specified nodeid. The pcap
-   * data is stored in the file prefix-nodeid-deviceid.pcap.
-   *
-   * This method should be invoked after the network topology has 
-   * been fully constructed.
-   */
-  static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid, bool promiscuous);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param nd Net device in which you want to enable tracing.
-   * \param promiscuous If true capture all possible packets available at the device.
-   *
-   * Enable pcap output the indicated net device.
-   */
-  static void EnablePcap (std::string filename, Ptr<NetDevice> nd, bool promiscuous);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param ndName The name of the net device in which you want to enable tracing.
-   * \param promiscuous If true capture all possible packets available at the device.
-   *
-   * Enable pcap output the indicated net device.
-   */
-  static void EnablePcap (std::string filename, std::string ndName, bool promiscuous);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param d container of devices of type ns3::CsmaNetDevice
-   * \param promiscuous If true capture all possible packets available at the device.
-   *
-   * Enable pcap output on each input device which is of the ns3::CsmaNetDevice type.
-   */
-  static void EnablePcap (std::string filename, NetDeviceContainer d, bool promiscuous);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param n container of nodes.
-   * \param promiscuous If true capture all possible packets available at the device.
-   *
-   * Enable pcap output on each device which is of the
-   * ns3::CsmaNetDevice type and which is located in one of the 
-   * input nodes.
-   */
-  static void EnablePcap (std::string filename, NodeContainer n, bool promiscuous);
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param promiscuous If true capture all possible packets available at the device.
-   *
-   * Enable pcap output on each device which is of the
-   * ns3::CsmaNetDevice type
-   */
-  static void EnablePcapAll (std::string filename, bool promiscuous);
-
-  /**
-   * \param os output stream
-   * \param nodeid the id of the node to generate ascii output for.
-   * \param deviceid the id of the device to generate ascii output for.
-   *
-   * Enable ascii output on the specified deviceid within the
-   * specified nodeid if it is of type ns3::CsmaNetDevice and dump 
-   * that to the specified stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid);
-  /**
-   * \param os output stream
-   * \param d device container
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::CsmaNetDevice type and which is located in the input
-   * device container and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, NetDeviceContainer d);
-  /**
-   * \param os output stream
-   * \param n node container
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::CsmaNetDevice type and which is located in one
-   * of the input node and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, NodeContainer n);
-  /**
-   * \param os output stream
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::CsmaNetDevice type and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAsciiAll (std::ostream &os);
-
-  /**
    * This method creates an ns3::CsmaChannel with the attributes configured by
    * CsmaHelper::SetChannelAttribute, an ns3::CsmaNetDevice with the attributes
    * configured by CsmaHelper::SetDeviceAttribute and then adds the device
@@ -291,26 +198,31 @@
    */
   Ptr<NetDevice> InstallPriv (Ptr<Node> node, Ptr<CsmaChannel> channel) const;
 
-  /*
+  /**
+   * \brief Enable pcap output on the indicated net device.
    * \internal
-   */
-  static void SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
-
-  static void AsciiRxEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet);
-  /*
-   * \internal
+   *
+   * NetDevice-specific implementation mechanism for hooking the trace and
+   * writing to the trace file.
+   *
+   * \param prefix Filename prefix to use for pcap files.
+   * \param nd Net device for which you want to enable tracing.
+   * \param promiscuous If true capture all possible packets available at the device.
    */
-  static void AsciiEnqueueEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet);
+  virtual void EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous = false);
 
-  /*
+  /**
+   * \brief Enable ascii trace output on the indicated net device.
    * \internal
+   *
+   * NetDevice-specific implementation mechanism for hooking the trace and
+   * writing to the trace file.
+   *
+   * \param stream The output stream object to use when logging ascii traces.
+   * \param prefix Filename prefix to use for ascii trace files.
+   * \param nd Net device for which you want to enable tracing.
    */
-  static void AsciiDequeueEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet);
-
-  /*
-   * \internal
-   */
-  static void AsciiDropEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet);
+  virtual void EnableAsciiInternal (Ptr<OutputStreamWrapper> stream, std::string prefix, Ptr<NetDevice> nd);
 
   ObjectFactory m_queueFactory;
   ObjectFactory m_deviceFactory;
--- a/src/helper/emu-helper.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/emu-helper.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -24,11 +24,10 @@
 #include "ns3/names.h"
 #include "ns3/queue.h"
 #include "ns3/emu-net-device.h"
-#include "ns3/pcap-writer.h"
-#include "ns3/ascii-writer.h"
 #include "ns3/config.h"
 #include "ns3/packet.h"
 
+#include "trace-helper.h"
 #include "emu-helper.h"
 
 NS_LOG_COMPONENT_DEFINE ("EmuHelper");
@@ -66,133 +65,118 @@
 }
 
 void 
-EmuHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid, bool promiscuous)
+EmuHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous)
 {
-  NS_LOG_FUNCTION (filename << nodeid << deviceid << promiscuous);
-  std::ostringstream oss;
-  oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
-  Ptr<PcapWriter> pcap = CreateObject<PcapWriter> ();
-  pcap->Open (oss.str ());
-  pcap->WriteEthernetHeader ();
+  //
+  // All of the Pcap enable functions vector through here including the ones
+  // that are wandering through all of devices on perhaps all of the nodes in
+  // the system.  We can only deal with devices of type EmuNetDevice.
+  //
+  Ptr<EmuNetDevice> device = nd->GetObject<EmuNetDevice> ();
+  if (device == 0)
+    {
+      NS_LOG_INFO ("EmuHelper::EnablePcapInternal(): Device " << device << " not of type ns3::EmuNetDevice");
+      return;
+    }
 
-  oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
+  PcapHelper pcapHelper;
+  std::string filename = pcapHelper.GetFilenameFromDevice (prefix, device);
+  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_EN10MB);
   if (promiscuous)
     {
-      oss << "/$ns3::EmuNetDevice/PromiscSniffer";
+      pcapHelper.HookDefaultSink<EmuNetDevice> (device, "PromiscSniffer", file);
     }
   else
     {
-      oss << "/$ns3::EmuNetDevice/Sniffer";
-    }
-  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&EmuHelper::SniffEvent, pcap));
-}
-
-void 
-EmuHelper::EnablePcap (std::string filename, Ptr<NetDevice> nd, bool promiscuous)
-{
-  NS_LOG_FUNCTION (filename << &nd << promiscuous);
-  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex (), promiscuous);
-}
-
-void 
-EmuHelper::EnablePcap (std::string filename, std::string ndName, bool promiscuous)
-{
-  NS_LOG_FUNCTION (filename << ndName << promiscuous);
-  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
-  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex (), promiscuous);
-}
-
-void 
-EmuHelper::EnablePcap (std::string filename, NetDeviceContainer d, bool promiscuous)
-{
-  NS_LOG_FUNCTION (filename << &d << promiscuous);
-  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
-    {
-      Ptr<NetDevice> dev = *i;
-      EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex (), promiscuous);
+      pcapHelper.HookDefaultSink<EmuNetDevice> (device, "Sniffer", file);
     }
 }
 
-void
-EmuHelper::EnablePcap (std::string filename, NodeContainer n, bool promiscuous)
+void 
+EmuHelper::EnableAsciiInternal (Ptr<OutputStreamWrapper> stream, std::string prefix, Ptr<NetDevice> nd)
 {
-  NS_LOG_FUNCTION (filename << &n << promiscuous);
-  NetDeviceContainer devs;
-  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+  //
+  // All of the ascii enable functions vector through here including the ones
+  // that are wandering through all of devices on perhaps all of the nodes in
+  // the system.  We can only deal with devices of type EmuNetDevice.
+  //
+  Ptr<EmuNetDevice> device = nd->GetObject<EmuNetDevice> ();
+  if (device == 0)
     {
-      Ptr<Node> node = *i;
-      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-	{
-	  devs.Add (node->GetDevice (j));
-	}
+      NS_LOG_INFO ("EmuHelper::EnableAsciiInternal(): Device " << device << " not of type ns3::EmuNetDevice");
+      return;
     }
-  EnablePcap (filename, devs, promiscuous);
-}
+
+  //
+  // Our default trace sinks are going to use packet printing, so we have to 
+  // make sure that is turned on.
+  //
+  Packet::EnablePrinting ();
+
+  //
+  // If we are not provided an OutputStreamWrapper, we are expected to create 
+  // one using the usual trace filename conventions and do a Hook*WithoutContext
+  // since there will be one file per context and therefore the context would
+  // be redundant.
+  //
+  if (stream == 0)
+    {
+      //
+      // Set up an output stream object to deal with private ofstream copy 
+      // constructor and lifetime issues.  Let the helper decide the actual
+      // name of the file given the prefix.
+      //
+      AsciiTraceHelper asciiTraceHelper;
+      std::string filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
+      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename, "w");
 
-void
-EmuHelper::EnablePcapAll (std::string filename, bool promiscuous)
-{
-  NS_LOG_FUNCTION (filename << promiscuous);
-  EnablePcap (filename, NodeContainer::GetGlobal (), promiscuous);
-}
+      //
+      // The MacRx trace source provides our "r" event.
+      //
+      asciiTraceHelper.HookDefaultReceiveSinkWithoutContext<EmuNetDevice> (device, "MacRx", theStream);
+
+      //
+      // The "+", '-', and 'd' events are driven by trace sources actually in the
+      // transmit queue.
+      //
+      Ptr<Queue> queue = device->GetQueue ();
+      asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext<Queue> (queue, "Enqueue", theStream);
+      asciiTraceHelper.HookDefaultDropSinkWithoutContext<Queue> (queue, "Drop", theStream);
+      asciiTraceHelper.HookDefaultDequeueSinkWithoutContext<Queue> (queue, "Dequeue", theStream);
 
-void 
-EmuHelper::EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid)
-{
-  NS_LOG_FUNCTION (&os << nodeid << deviceid);
-  Ptr<AsciiWriter> writer = AsciiWriter::Get (os);
-  Packet::EnablePrinting ();
+      return;
+    }
+
+  //
+  // If we are provided an OutputStreamWrapper, we are expected to use it, and
+  // to providd a context.  We are free to come up with our own context if we
+  // want, and use the AsciiTraceHelper Hook*WithContext functions, but for 
+  // compatibility and simplicity, we just use Config::Connect and let it deal
+  // with the context.
+  //
+  // Note that we are going to use the default trace sinks provided by the 
+  // ascii trace helper.  There is actually no AsciiTraceHelper in sight here,
+  // but the default trace sinks are actually publicly available static 
+  // functions that are always there waiting for just such a case.
+  //
+  uint32_t nodeid = nd->GetNode ()->GetId ();
+  uint32_t deviceid = nd->GetIfIndex ();
   std::ostringstream oss;
 
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::EmuNetDevice/MacRx";
-  Config::Connect (oss.str (), MakeBoundCallback (&EmuHelper::AsciiRxEvent, writer));
+  oss << "/NodeList/" << nd->GetNode ()->GetId () << "/DeviceList/" << deviceid << "/$ns3::EmuNetDevice/MacRx";
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultReceiveSinkWithContext, stream));
 
   oss.str ("");
   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::EmuNetDevice/TxQueue/Enqueue";
-  Config::Connect (oss.str (), MakeBoundCallback (&EmuHelper::AsciiEnqueueEvent, writer));
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultEnqueueSinkWithContext, stream));
 
   oss.str ("");
   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::EmuNetDevice/TxQueue/Dequeue";
-  Config::Connect (oss.str (), MakeBoundCallback (&EmuHelper::AsciiDequeueEvent, writer));
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDequeueSinkWithContext, stream));
 
   oss.str ("");
   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::EmuNetDevice/TxQueue/Drop";
-  Config::Connect (oss.str (), MakeBoundCallback (&EmuHelper::AsciiDropEvent, writer));
-}
-
-void 
-EmuHelper::EnableAscii (std::ostream &os, NetDeviceContainer d)
-{
-  NS_LOG_FUNCTION (&os << &d);
-  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
-    {
-      Ptr<NetDevice> dev = *i;
-      EnableAscii (os, dev->GetNode ()->GetId (), dev->GetIfIndex ());
-    }
-}
-
-void
-EmuHelper::EnableAscii (std::ostream &os, NodeContainer n)
-{
-  NS_LOG_FUNCTION (&os << &n);
-  NetDeviceContainer devs;
-  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
-    {
-      Ptr<Node> node = *i;
-      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-	{
-	  devs.Add (node->GetDevice (j));
-	}
-    }
-  EnableAscii (os, devs);
-}
-
-void
-EmuHelper::EnableAsciiAll (std::ostream &os)
-{
-  NS_LOG_FUNCTION (&os);
-  EnableAscii (os, NodeContainer::GetGlobal ());
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDropSinkWithContext, stream));
 }
 
 NetDeviceContainer
@@ -233,47 +217,4 @@
   return device;
 }
 
-void 
-EmuHelper::SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
-{
-  NS_LOG_FUNCTION (writer << packet);
-  writer->WritePacket (packet);
-}
-
-void
-EmuHelper::AsciiEnqueueEvent (Ptr<AsciiWriter> writer,
-                              std::string path,
-                              Ptr<const Packet> packet)
-{
-  NS_LOG_FUNCTION (writer << path << packet);
-  writer->WritePacket (AsciiWriter::ENQUEUE, path, packet);
-}
-
-void
-EmuHelper::AsciiDequeueEvent (Ptr<AsciiWriter> writer,
-                              std::string path,
-                              Ptr<const Packet> packet)
-{
-  NS_LOG_FUNCTION (writer << path << packet);
-  writer->WritePacket (AsciiWriter::DEQUEUE, path, packet);
-}
-
-void
-EmuHelper::AsciiDropEvent (Ptr<AsciiWriter> writer,
-                           std::string path,
-                           Ptr<const Packet> packet)
-{
-  NS_LOG_FUNCTION (writer << path << packet);
-  writer->WritePacket (AsciiWriter::DROP, path, packet);
-}
-
-void
-EmuHelper::AsciiRxEvent (Ptr<AsciiWriter> writer,
-                         std::string path,
-                         Ptr<const Packet> packet)
-{
-  NS_LOG_FUNCTION (writer << path << packet);
-  writer->WritePacket (AsciiWriter::RX, path, packet);
-}
-
 } // namespace ns3
--- a/src/helper/emu-helper.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/emu-helper.h	Thu Feb 25 14:17:21 2010 +0100
@@ -21,22 +21,29 @@
 
 #include <string>
 #include <ostream>
+
 #include "ns3/attribute.h"
 #include "ns3/object-factory.h"
 #include "ns3/net-device-container.h"
 #include "ns3/node-container.h"
 #include "ns3/emu-net-device.h"
 
+#include "trace-helper.h"
+
 namespace ns3 {
 
 class Packet;
-class PcapWriter;
-class AsciiWriter;
 
 /**
  * \brief build a set of EmuNetDevice objects
+ *
+ * Normally we eschew multiple inheritance, however, the classes 
+ * PcapUserHelperForDevice and AsciiTraceUserHelperForDevice are
+ * treated as "mixins".  A mixin is a self-contained class that
+ * encapsulates a general attribute or a set of functionality that
+ * may be of interest to many other classes.
  */
-class EmuHelper
+  class EmuHelper : public PcapHelperForDevice, public AsciiTraceHelperForDevice
 {
 public:
   /*
@@ -75,113 +82,6 @@
   void SetAttribute (std::string n1, const AttributeValue &v1);
 
   /**
-   * \param filename filename prefix to use for pcap files.
-   * \param nodeid the id of the node to generate pcap output for.
-   * \param deviceid the id of the device to generate pcap output for.
-   * \param promiscuous If true capture all possible packets available at the device.
-   *
-   * Generate a pcap file which contains the link-level data observed
-   * by the specified deviceid within the specified nodeid. The pcap
-   * data is stored in the file prefix-nodeid-deviceid.pcap.
-   *
-   * This method should be invoked after the network topology has 
-   * been fully constructed.
-   */
-  static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid, bool promiscuous);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param nd Indicates net device on which you want to enable tracing.
-   * \param promiscuous If true capture all possible packets available at the device.
-   *
-   * Enable pcap output on each input device which is of the
-   * ns3::EmuNetDevice type.
-   */
-  static void EnablePcap (std::string filename, Ptr<NetDevice> nd, bool promiscuous);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param ndName Name of net device on which you want to enable tracing.
-   * \param promiscuous If true capture all possible packets available at the device.
-   *
-   * Enable pcap output on each input device which is of the
-   * ns3::EmuNetDevice type.
-   */
-  static void EnablePcap (std::string filename, std::string ndName, bool promiscuous);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param d container of devices of type ns3::EmuNetDevice
-   * \param promiscuous If true capture all possible packets available at the device.
-   *
-   * Enable pcap output on each input device which is of the
-   * ns3::EmuNetDevice type.
-   */
-  static void EnablePcap (std::string filename, NetDeviceContainer d, bool promiscuous);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param n container of nodes.
-   * \param promiscuous If true capture all possible packets available at the device.
-   *
-   * Enable pcap output on each device which is of the
-   * ns3::EmuNetDevice type and which is located in one of the 
-   * input nodes.
-   */
-  static void EnablePcap (std::string filename, NodeContainer n, bool promiscuous);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param promiscuous If true capture all possible packets available at the device.
-   *
-   * Enable pcap output on each device which is of the
-   * ns3::EmuNetDevice type
-   */
-  static void EnablePcapAll (std::string filename, bool promiscuous);
-
-  /**
-   * \param os output stream
-   * \param nodeid the id of the node to generate ascii output for.
-   * \param deviceid the id of the device to generate ascii output for.
-   *
-   * Enable ascii output on the specified deviceid within the
-   * specified nodeid if it is of type ns3::EmuNetDevice and dump 
-   * that to the specified stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid);
-
-  /**
-   * \param os output stream
-   * \param d device container
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::EmuNetDevice type and which is located in the input
-   * device container and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, NetDeviceContainer d);
-
-  /**
-   * \param os output stream
-   * \param n node container
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::EmuNetDevice type and which is located in one
-   * of the input node and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, NodeContainer n);
-
-  /**
-   * \param os output stream
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::EmuNetDevice type and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAsciiAll (std::ostream &os);
-
-  /**
    * This method creates an ns3::EmuNetDevice with the attributes configured by 
    * EmuHelper::SetDeviceAttribute and then adds the device to the node.
    *
@@ -215,30 +115,30 @@
    */
   Ptr<NetDevice> InstallPriv (Ptr<Node> node) const;
 
-  /*
-   * \internal
+  /**
+   * \brief Enable pcap output the indicated net device.
+   *
+   * NetDevice-specific implementation mechanism for hooking the trace and
+   * writing to the trace file.
+   *
+   * \param prefix Filename prefix to use for pcap files.
+   * \param nd Net device for which you want to enable tracing.
+   * \param promiscuous If true capture all possible packets available at the device.
    */
-  static void SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+  virtual void EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous = false);
 
-  /*
-   * \internal
-   */
-  static void AsciiRxEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet);
-
-  /*
+  /**
+   * \brief Enable ascii trace output on the indicated net device.
    * \internal
-   */
-  static void AsciiEnqueueEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet);
-
-  /*
-   * \internal
+   *
+   * NetDevice-specific implementation mechanism for hooking the trace and
+   * writing to the trace file.
+   *
+   * \param stream The output stream object to use when logging ascii traces.
+   * \param prefix Filename prefix to use for ascii trace files.
+   * \param nd Net device for which you want to enable tracing.
    */
-  static void AsciiDequeueEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet);
-
-  /*
-   * \internal
-   */
-  static void AsciiDropEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet);
+  virtual void EnableAsciiInternal (Ptr<OutputStreamWrapper> stream, std::string prefix, Ptr<NetDevice> nd);
 
   ObjectFactory m_queueFactory;
   ObjectFactory m_deviceFactory;
--- a/src/helper/internet-stack-helper.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/internet-stack-helper.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -162,20 +162,67 @@
 #include "ns3/callback.h"
 #include "ns3/node.h"
 #include "ns3/core-config.h"
-#include "ns3/pcap-writer.h"
-#include "ns3/ascii-writer.h"
+#include "ns3/arp-l3-protocol.h"
 #include "internet-stack-helper.h"
 #include "ipv4-list-routing-helper.h"
 #include "ipv4-static-routing-helper.h"
 #include "ipv4-global-routing-helper.h"
 #include "ipv6-list-routing-helper.h"
 #include "ipv6-static-routing-helper.h"
+#include "trace-helper.h"
 #include <limits>
+#include <map>
+
+NS_LOG_COMPONENT_DEFINE ("InternetStackHelper");
 
 namespace ns3 {
 
-std::vector<InternetStackHelper::Trace> InternetStackHelper::m_traces;
-std::string InternetStackHelper::m_pcapBaseFilename;
+//
+// Historically, the only context written to ascii traces was the protocol.
+// Traces from the protocols include the interface, though.  It is not 
+// possible to really determine where an event originated without including
+// this.  If you want the additional context information, define 
+// INTERFACE_CONTEXT.  If you want compatibility with the old-style traces
+// comment it out.
+//
+#define INTERFACE_CONTEXT
+
+//
+// Things are going to work differently here with respect to trace file handling
+// than in most places because the Tx and Rx trace sources we are interested in
+// are going to multiplex receive and transmit callbacks for all Ipv4 and 
+// interface pairs through one callback.  We want packets to or from each 
+// distinct pair to go to an individual file, so we have got to demultiplex the
+// Ipv4 and interface pair into a corresponding Ptr<PcapFileWrapper> at the 
+// callback.
+//
+// A complication in this situation is that the trace sources are hooked on 
+// a protocol basis.  There is no trace source hooked by an Ipv4 and interface
+// pair.  This means that if we naively proceed to hook, say, a drop trace
+// for a given Ipv4 with interface 0, and then hook for Ipv4 with interface 1
+// we will hook the drop trace twice and get two callbacks per event.  What
+// we need to do is to hook the event once, and that will result in a single
+// callback per drop event, and the trace source will provide the interface
+// which we filter on in the trace sink.
+// 
+// This has got to continue to work properly after the helper has been 
+// destroyed; but must be cleaned up at the end of time to avoid leaks. 
+// Global maps of protocol/interface pairs to file objects seems to fit the 
+// bill.
+//
+typedef std::pair<Ptr<Ipv4>, uint32_t> InterfacePairIpv4; 
+typedef std::map<InterfacePairIpv4, Ptr<PcapFileWrapper> > InterfaceFileMapIpv4;  
+typedef std::map<InterfacePairIpv4, Ptr<OutputStreamWrapper> > InterfaceStreamMapIpv4;  
+
+static InterfaceFileMapIpv4 g_interfaceFileMapIpv4; /**< A mapping of Ipv4/interface pairs to pcap files */
+static InterfaceStreamMapIpv4 g_interfaceStreamMapIpv4; /**< A mapping of Ipv4/interface pairs to ascii streams */
+
+typedef std::pair<Ptr<Ipv6>, uint32_t> InterfacePairIpv6;
+typedef std::map<InterfacePairIpv6, Ptr<PcapFileWrapper> > InterfaceFileMapIpv6;
+typedef std::map<InterfacePairIpv6, Ptr<OutputStreamWrapper> > InterfaceStreamMapIpv6;
+
+static InterfaceFileMapIpv6 g_interfaceFileMapIpv6; /**< A mapping of Ipv6/interface pairs to pcap files */
+static InterfaceStreamMapIpv6 g_interfaceStreamMapIpv6; /**< A mapping of Ipv6/interface pairs to pcap files */
 
 InternetStackHelper::InternetStackHelper ()
   : m_routing (0),
@@ -268,21 +315,6 @@
 }
 
 void
-InternetStackHelper::Cleanup (void)
-{
-  uint32_t illegal = std::numeric_limits<uint32_t>::max ();
-
-  for (std::vector<Trace>::iterator i = m_traces.begin ();
-       i != m_traces.end (); i++)
-  {
-    i->nodeId = illegal;
-    i->interfaceId = illegal;
-    i->writer = 0;
-  }
-  m_traces.clear ();
-}
-
-void
 InternetStackHelper::SetTcp (const std::string tid)
 {
   m_tcpFactory.SetTypeId (tid);
@@ -373,129 +405,515 @@
   Ptr<Node> node = Names::Find<Node> (nodeName);
   Install (node);
 }
-void
-InternetStackHelper::EnableAscii (std::ostream &os, NodeContainer n)
+
+static void
+Ipv4L3ProtocolRxTxSink (Ptr<const Packet> p, Ptr<Ipv4> ipv4, uint32_t interface)
 {
-  Ptr<AsciiWriter> writer = AsciiWriter::Get (os);
-  Packet::EnablePrinting ();
-  std::ostringstream oss;
-  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+  NS_LOG_FUNCTION (p << ipv4 << interface);
+
+  //
+  // Since trace sources are independent of interface, if we hook a source
+  // on a particular protocol we will get traces for all of its interfaces.
+  // We need to filter this to only report interfaces for which the user 
+  // has expressed interest.
+  //
+  InterfacePairIpv4 pair = std::make_pair (ipv4, interface);
+  if (g_interfaceFileMapIpv4.find (pair) == g_interfaceFileMapIpv4.end ())
     {
-      Ptr<Node> node = *i;
-      oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv4L3Protocol/Drop";
-      Config::Connect (oss.str (), MakeBoundCallback (&InternetStackHelper::AsciiDropEventIpv4, writer));
-      oss.str ("");
-      oss << "/NodeList/" << node->GetId () << "/$ns3::ArpL3Protocol/Drop";
-      Config::Connect (oss.str (), MakeBoundCallback (&InternetStackHelper::AsciiDropEventArp, writer));
-      oss.str ("");
-      oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv6L3Protocol/Drop";
-      Config::Connect (oss.str (), MakeBoundCallback (&InternetStackHelper::AsciiDropEventIpv6, writer));
-      oss.str ("");
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
     }
+
+  Ptr<PcapFileWrapper> file = g_interfaceFileMapIpv4[pair];
+  file->Write(Simulator::Now(), p);
+}
+
+bool
+InternetStackHelper::PcapHooked (Ptr<Ipv4> ipv4)
+{
+  for (  InterfaceFileMapIpv4::const_iterator i = g_interfaceFileMapIpv4.begin (); 
+         i != g_interfaceFileMapIpv4.end (); 
+         ++i)  
+    {
+      if ((*i).first.first == ipv4)
+        {
+          return true;
+        }
+    }
+  return false;
 }
 
-void
-InternetStackHelper::EnableAsciiAll (std::ostream &os)
+void 
+InternetStackHelper::EnablePcapIpv4Internal (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface)
 {
-  EnableAscii (os, NodeContainer::GetGlobal ());
+  NS_LOG_FUNCTION (prefix << ipv4 << interface);
+
+  if (!m_ipv4Enabled)
+    {
+      NS_LOG_INFO ("Call to enable Ipv4 pcap tracing but Ipv4 not enabled");
+      return;
+    }
+
+  //
+  // We have to create a file and a mapping from protocol/interface to file 
+  // irrespective of how many times we want to trace a particular protocol.
+  //
+  PcapHelper pcapHelper;
+  std::string filename = pcapHelper.GetFilenameFromInterfacePair (prefix, ipv4, interface);
+  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_RAW);
+
+  //
+  // However, we only hook the trace source once to avoid multiple trace sink
+  // calls per event (connect is independent of interface).
+  //
+  if (!PcapHooked (ipv4))
+    {
+      //
+      // Ptr<Ipv4> is aggregated to node and Ipv4L3Protocol is aggregated to 
+      // node so we can get to Ipv4L3Protocol through Ipv4.
+      //
+      Ptr<Ipv4L3Protocol> ipv4L3Protocol = ipv4->GetObject<Ipv4L3Protocol> ();
+      NS_ASSERT_MSG (ipv4L3Protocol, "InternetStackHelper::EnablePcapIpv4Internal(): "
+                     "m_ipv4Enabled and ipv4L3Protocol inconsistent");
+
+      bool result = ipv4L3Protocol->TraceConnectWithoutContext ("Tx", MakeCallback (&Ipv4L3ProtocolRxTxSink));
+      NS_ASSERT_MSG (result == true, "InternetStackHelper::EnablePcapIpv4Internal():  "
+                     "Unable to connect ipv4L3Protocol \"Tx\"");
+
+      result = ipv4L3Protocol->TraceConnectWithoutContext ("Rx", MakeCallback (&Ipv4L3ProtocolRxTxSink));
+      NS_ASSERT_MSG (result == true, "InternetStackHelper::EnablePcapIpv4Internal():  "
+                     "Unable to connect ipv4L3Protocol \"Rx\"");
+    }
+
+  g_interfaceFileMapIpv4[std::make_pair (ipv4, interface)] = file;
+}
+
+static void
+Ipv6L3ProtocolRxTxSink (Ptr<const Packet> p, Ptr<Ipv6> ipv6, uint32_t interface)
+{
+  NS_LOG_FUNCTION (p << ipv6 << interface);
+
+  //
+  // Since trace sources are independent of interface, if we hook a source
+  // on a particular protocol we will get traces for all of its interfaces.
+  // We need to filter this to only report interfaces for which the user 
+  // has expressed interest.
+  //
+  InterfacePairIpv6 pair = std::make_pair (ipv6, interface);
+  if (g_interfaceFileMapIpv6.find (pair) == g_interfaceFileMapIpv6.end ())
+    {
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
+    }
+
+  Ptr<PcapFileWrapper> file = g_interfaceFileMapIpv6[pair];
+  file->Write(Simulator::Now(), p);
 }
 
-void
-InternetStackHelper::EnablePcapAll (std::string filename)
+bool
+InternetStackHelper::PcapHooked (Ptr<Ipv6> ipv6)
 {
-  Simulator::ScheduleDestroy (&InternetStackHelper::Cleanup);
+  for (  InterfaceFileMapIpv6::const_iterator i = g_interfaceFileMapIpv6.begin (); 
+         i != g_interfaceFileMapIpv6.end (); 
+         ++i)  
+    {
+      if ((*i).first.first == ipv6)
+        {
+          return true;
+        }
+    }
+  return false;
+}
+
+void 
+InternetStackHelper::EnablePcapIpv6Internal (std::string prefix, Ptr<Ipv6> ipv6, uint32_t interface)
+{
+  NS_LOG_FUNCTION (prefix << ipv6 << interface);
+
+  if (!m_ipv6Enabled)
+    {
+      NS_LOG_INFO ("Call to enable Ipv6 pcap tracing but Ipv6 not enabled");
+      return;
+    }
 
-  InternetStackHelper::m_pcapBaseFilename = filename;
-  Config::Connect ("/NodeList/*/$ns3::Ipv4L3Protocol/Tx",
-                   MakeCallback (&InternetStackHelper::LogTxIp));
-  Config::Connect ("/NodeList/*/$ns3::Ipv4L3Protocol/Rx",
-                   MakeCallback (&InternetStackHelper::LogRxIp));
+  //
+  // We have to create a file and a mapping from protocol/interface to file 
+  // irrespective of how many times we want to trace a particular protocol.
+  //
+  PcapHelper pcapHelper;
+  std::string filename = pcapHelper.GetFilenameFromInterfacePair (prefix, ipv6, interface);
+  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_RAW);
 
-  /* IPv6 */
-  Config::Connect ("/NodeList/*/$ns3::Ipv6L3Protocol/Tx",
-                   MakeCallback (&InternetStackHelper::LogTxIp));
-  Config::Connect ("/NodeList/*/$ns3::Ipv6L3Protocol/Rx",
-                   MakeCallback (&InternetStackHelper::LogRxIp));
+  //
+  // However, we only hook the trace source once to avoid multiple trace sink
+  // calls per event (connect is independent of interface).
+  //
+  if (!PcapHooked (ipv6))
+    {
+      //
+      // Ptr<Ipv6> is aggregated to node and Ipv6L3Protocol is aggregated to 
+      // node so we can get to Ipv6L3Protocol through Ipv6.
+      //
+      Ptr<Ipv6L3Protocol> ipv6L3Protocol = ipv6->GetObject<Ipv6L3Protocol> ();
+      NS_ASSERT_MSG (ipv6L3Protocol, "InternetStackHelper::EnablePcapIpv6Internal(): "
+                     "m_ipv6Enabled and ipv6L3Protocol inconsistent");
+
+      bool result = ipv6L3Protocol->TraceConnectWithoutContext ("Tx", MakeCallback (&Ipv6L3ProtocolRxTxSink));
+      NS_ASSERT_MSG (result == true, "InternetStackHelper::EnablePcapIpv6Internal():  "
+                     "Unable to connect ipv6L3Protocol \"Tx\"");
+
+      result = ipv6L3Protocol->TraceConnectWithoutContext ("Rx", MakeCallback (&Ipv6L3ProtocolRxTxSink));
+      NS_ASSERT_MSG (result == true, "InternetStackHelper::EnablePcapIpv6Internal():  "
+                     "Unable to connect ipv6L3Protocol \"Rx\"");
+    }
+
+  g_interfaceFileMapIpv6[std::make_pair (ipv6, interface)] = file;
 }
 
-uint32_t
-InternetStackHelper::GetNodeIndex (std::string context)
+static void
+Ipv4L3ProtocolDropSinkWithoutContext (
+  Ptr<OutputStreamWrapper> stream,
+  Ipv4Header const &header, 
+  Ptr<const Packet> packet,
+  Ipv4L3Protocol::DropReason reason, 
+  Ptr<Ipv4> ipv4, 
+  uint32_t interface)
+{
+  //
+  // Since trace sources are independent of interface, if we hook a source
+  // on a particular protocol we will get traces for all of its interfaces.
+  // We need to filter this to only report interfaces for which the user 
+  // has expressed interest.
+  //
+  InterfacePairIpv4 pair = std::make_pair (ipv4, interface);
+  if (g_interfaceStreamMapIpv4.find (pair) == g_interfaceStreamMapIpv4.end ())
+    {
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
+    }
+
+  Ptr<Packet> p = packet->Copy ();
+  p->AddHeader (header);
+  *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
+}
+
+static void
+Ipv4L3ProtocolDropSinkWithContext (
+  Ptr<OutputStreamWrapper> stream,
+  std::string context,
+  Ipv4Header const &header, 
+  Ptr<const Packet> packet,
+  Ipv4L3Protocol::DropReason reason, 
+  Ptr<Ipv4> ipv4, 
+  uint32_t interface)
 {
-  std::string::size_type pos;
-  pos = context.find ("/NodeList/");
-  NS_ASSERT (pos == 0);
-  std::string::size_type afterNodeIndex = context.find ("/", 11);
-  NS_ASSERT (afterNodeIndex != std::string::npos);
-  std::string index = context.substr (10, afterNodeIndex - 10);
-  std::istringstream iss;
-  iss.str (index);
-  uint32_t nodeIndex;
-  iss >> nodeIndex;
-  return nodeIndex;
+  //
+  // Since trace sources are independent of interface, if we hook a source
+  // on a particular protocol we will get traces for all of its interfaces.
+  // We need to filter this to only report interfaces for which the user 
+  // has expressed interest.
+  //
+  InterfacePairIpv4 pair = std::make_pair (ipv4, interface);
+  if (g_interfaceStreamMapIpv4.find (pair) == g_interfaceStreamMapIpv4.end ())
+    {
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
+    }
+
+  Ptr<Packet> p = packet->Copy ();
+  p->AddHeader (header);
+#ifdef INTERFACE_CONTEXT
+  *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << context << "(" << interface << ") " 
+    << *p << std::endl;
+#else
+  *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << context << " "  << *p << std::endl;
+#endif
+}
+
+bool
+InternetStackHelper::AsciiHooked (Ptr<Ipv4> ipv4)
+{
+  for (  InterfaceStreamMapIpv4::const_iterator i = g_interfaceStreamMapIpv4.begin (); 
+         i != g_interfaceStreamMapIpv4.end (); 
+         ++i)  
+    {
+      if ((*i).first.first == ipv4)
+        {
+          return true;
+        }
+    }
+  return false;
 }
 
-void
-InternetStackHelper::LogTxIp (std::string context, Ptr<const Packet> packet, uint32_t interfaceIndex)
+void 
+InternetStackHelper::EnableAsciiIpv4Internal (
+  Ptr<OutputStreamWrapper> stream, 
+  std::string prefix, 
+  Ptr<Ipv4> ipv4, 
+  uint32_t interface)
 {
-  Ptr<PcapWriter> writer = InternetStackHelper::GetStream (GetNodeIndex (context), interfaceIndex);
-  writer->WritePacket (packet);
-}
+  if (!m_ipv4Enabled)
+    {
+      NS_LOG_INFO ("Call to enable Ipv4 ascii tracing but Ipv4 not enabled");
+      return;
+    }
+
+  //
+  // Our trace sinks are going to use packet printing, so we have to 
+  // make sure that is turned on.
+  //
+  Packet::EnablePrinting ();
+
+  //
+  // If we are not provided an OutputStreamWrapper, we are expected to create 
+  // one using the usual trace filename conventions and hook WithoutContext
+  // since there will be one file per context and therefore the context would
+  // be redundant.
+  //
+  if (stream == 0)
+    {
+      //
+      // Set up an output stream object to deal with private ofstream copy 
+      // constructor and lifetime issues.  Let the helper decide the actual
+      // name of the file given the prefix.
+      //
+      // We have to create a stream and a mapping from protocol/interface to 
+      // stream irrespective of how many times we want to trace a particular 
+      // protocol.
+      //
+      AsciiTraceHelper asciiTraceHelper;
+      std::string filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ipv4, interface);
+      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename, "w");
 
-void
-InternetStackHelper::LogRxIp (std::string context, Ptr<const Packet> packet, uint32_t interfaceIndex)
-{
-  Ptr<PcapWriter> writer = InternetStackHelper::GetStream (GetNodeIndex (context), interfaceIndex);
-  writer->WritePacket (packet);
+      //
+      // However, we only hook the trace sources once to avoid multiple trace sink
+      // calls per event (connect is independent of interface).
+      //
+      if (!AsciiHooked (ipv4))
+        {
+          //
+          // We can use the default drop sink for the ArpL3Protocol since it has
+          // the usual signature.  We can get to the Ptr<ArpL3Protocol> through
+          // our Ptr<Ipv4> since they must both be aggregated to the same node.
+          //
+          Ptr<ArpL3Protocol> arpL3Protocol = ipv4->GetObject<ArpL3Protocol> ();
+          asciiTraceHelper.HookDefaultDropSinkWithoutContext<ArpL3Protocol> (arpL3Protocol, "Drop", theStream);
+          
+          //
+          // The drop sink for the Ipv4L3Protocol uses a different signature than
+          // the default sink, so we have to cook one up for ourselves.  We can get
+          // to the Ptr<Ipv4L3Protocol> through our Ptr<Ipv4> since they must both 
+          // be aggregated to the same node.
+          //
+          Ptr<Ipv4L3Protocol> ipv4L3Protocol = ipv4->GetObject<Ipv4L3Protocol> ();
+          bool __attribute__ ((unused)) result = ipv4L3Protocol->TraceConnectWithoutContext ("Drop", 
+            MakeBoundCallback (&Ipv4L3ProtocolDropSinkWithoutContext, theStream));
+          NS_ASSERT_MSG (result == true, "InternetStackHelper::EanableAsciiIpv4Internal():  "
+                         "Unable to connect ipv4L3Protocol \"Drop\"");
+        }
+
+      g_interfaceStreamMapIpv4[std::make_pair (ipv4, interface)] = theStream;
+      return;
+    }
+
+  //
+  // If we are provided an OutputStreamWrapper, we are expected to use it, and
+  // to provide a context.  We are free to come up with our own context if we
+  // want, and use the AsciiTraceHelper Hook*WithContext functions, but for 
+  // compatibility and simplicity, we just use Config::Connect and let it deal
+  // with the context.
+  //
+  // We need to associate the ipv4/interface with a stream to express interest
+  // in tracing events on that pair, however, we only hook the trace sources 
+  // once to avoid multiple trace sink calls per event (connect is independent
+  // of interface).
+  //
+  if (!AsciiHooked (ipv4))
+    {
+      Ptr<Node> node = ipv4->GetObject<Node> ();
+      std::ostringstream oss;
+
+      //
+      // For the ARP Drop, we are going to use the default trace sink provided by 
+      // the ascii trace helper.  There is actually no AsciiTraceHelper in sight 
+      // here, but the default trace sinks are actually publicly available static 
+      // functions that are always there waiting for just such a case.
+      //
+      oss << "/NodeList/" << node->GetId () << "/$ns3::ArpL3Protocol/Drop";
+      Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDropSinkWithContext, stream));
+      
+      //
+      // This has all kinds of parameters coming with, so we have to cook up our
+      // own sink.
+      //
+      oss.str ("");
+      oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv4L3Protocol/Drop";
+      Config::Connect (oss.str (), MakeBoundCallback (&Ipv4L3ProtocolDropSinkWithContext, stream));
+    }
+
+  g_interfaceStreamMapIpv4[std::make_pair (ipv4, interface)] = stream;
 }
 
-Ptr<PcapWriter>
-InternetStackHelper::GetStream (uint32_t nodeId, uint32_t interfaceId)
+static void
+Ipv6L3ProtocolDropSinkWithoutContext (
+  Ptr<OutputStreamWrapper> stream,
+  Ipv6Header const &header, 
+  Ptr<const Packet> packet,
+  Ipv6L3Protocol::DropReason reason, 
+  Ptr<Ipv6> ipv6, 
+  uint32_t interface)
 {
-  for (std::vector<Trace>::iterator i = m_traces.begin ();
-       i != m_traces.end (); i++)
-  {
-    if (i->nodeId == nodeId &&
-        i->interfaceId == interfaceId)
+  //
+  // Since trace sources are independent of interface, if we hook a source
+  // on a particular protocol we will get traces for all of its interfaces.
+  // We need to filter this to only report interfaces for which the user 
+  // has expressed interest.
+  //
+  InterfacePairIpv6 pair = std::make_pair (ipv6, interface);
+  if (g_interfaceStreamMapIpv6.find (pair) == g_interfaceStreamMapIpv6.end ())
     {
-      return i->writer;
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
     }
-  }
-  InternetStackHelper::Trace trace;
-  trace.nodeId = nodeId;
-  trace.interfaceId = interfaceId;
-  trace.writer = CreateObject<PcapWriter> ();
-  std::ostringstream oss;
-  oss << m_pcapBaseFilename << "-" << nodeId << "-" << interfaceId << ".pcap";
-  trace.writer->Open (oss.str ());
-  trace.writer->WriteIpHeader ();
-  m_traces.push_back (trace);
-  return trace.writer;
+
+  Ptr<Packet> p = packet->Copy ();
+  p->AddHeader (header);
+  *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
+}
+
+static void
+Ipv6L3ProtocolDropSinkWithContext (
+  Ptr<OutputStreamWrapper> stream,
+  std::string context,
+  Ipv6Header const &header, 
+  Ptr<const Packet> packet,
+  Ipv6L3Protocol::DropReason reason, 
+  Ptr<Ipv6> ipv6, 
+  uint32_t interface)
+{
+  //
+  // Since trace sources are independent of interface, if we hook a source
+  // on a particular protocol we will get traces for all of its interfaces.
+  // We need to filter this to only report interfaces for which the user 
+  // has expressed interest.
+  //
+  InterfacePairIpv6 pair = std::make_pair (ipv6, interface);
+  if (g_interfaceStreamMapIpv6.find (pair) == g_interfaceStreamMapIpv6.end ())
+    {
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
+    }
+
+  Ptr<Packet> p = packet->Copy ();
+  p->AddHeader (header);
+#ifdef INTERFACE_CONTEXT
+  *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << context << "(" << interface << ") " 
+    << *p << std::endl;
+#else
+  *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
+#endif
+}
+
+bool
+InternetStackHelper::AsciiHooked (Ptr<Ipv6> ipv6)
+{
+  for (  InterfaceStreamMapIpv6::const_iterator i = g_interfaceStreamMapIpv6.begin (); 
+         i != g_interfaceStreamMapIpv6.end (); 
+         ++i)  
+    {
+      if ((*i).first.first == ipv6)
+        {
+          return true;
+        }
+    }
+  return false;
 }
 
-void
-InternetStackHelper::AsciiDropEventArp (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet)
-{
-  writer->WritePacket (AsciiWriter::DROP, path, packet);
-}
-
-void
-InternetStackHelper::AsciiDropEventIpv4 (Ptr<AsciiWriter> writer, std::string path,
-                                         Ipv4Header const &header, Ptr<const Packet> packet,
-                                         Ipv4L3Protocol::DropReason reason, uint32_t interface)
+void 
+InternetStackHelper::EnableAsciiIpv6Internal (
+  Ptr<OutputStreamWrapper> stream, 
+  std::string prefix, 
+  Ptr<Ipv6> ipv6, 
+  uint32_t interface)
 {
-  Ptr<Packet> p = packet->Copy ();
-  p->AddHeader (header);
-  writer->WritePacket (AsciiWriter::DROP, path, p);
-}
+  if (!m_ipv6Enabled)
+    {
+      NS_LOG_INFO ("Call to enable Ipv6 ascii tracing but Ipv6 not enabled");
+      return;
+    }
+
+  //
+  // Our trace sinks are going to use packet printing, so we have to 
+  // make sure that is turned on.
+  //
+  Packet::EnablePrinting ();
+
+  //
+  // If we are not provided an OutputStreamWrapper, we are expected to create 
+  // one using the usual trace filename conventions and do a hook WithoutContext
+  // since there will be one file per context and therefore the context would
+  // be redundant.
+  //
+  if (stream == 0)
+    {
+      //
+      // Set up an output stream object to deal with private ofstream copy 
+      // constructor and lifetime issues.  Let the helper decide the actual
+      // name of the file given the prefix.
+      //
+      // We have to create a stream and a mapping from protocol/interface to 
+      // stream irrespective of how many times we want to trace a particular 
+      // protocol.
+      //
+      AsciiTraceHelper asciiTraceHelper;
+      std::string filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ipv6, interface);
+      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename, "w");
 
-void
-InternetStackHelper::AsciiDropEventIpv6 (Ptr<AsciiWriter> writer, std::string path,
-                                         Ipv6Header const &header, Ptr<const Packet> packet,
-                                         Ipv6L3Protocol::DropReason reason, uint32_t interface)
-{
-  Ptr<Packet> p = packet->Copy ();
-  p->AddHeader (header);
-  writer->WritePacket (AsciiWriter::DROP, path, p);
+      //
+      // However, we only hook the trace sources once to avoid multiple trace sink
+      // calls per event (connect is independent of interface).
+      //
+      if (!AsciiHooked (ipv6))
+        {
+          //
+          // The drop sink for the Ipv6L3Protocol uses a different signature than
+          // the default sink, so we have to cook one up for ourselves.  We can get
+          // to the Ptr<Ipv6L3Protocol> through our Ptr<Ipv6> since they must both 
+          // be aggregated to the same node.
+          //
+          Ptr<Ipv6L3Protocol> ipv6L3Protocol = ipv6->GetObject<Ipv6L3Protocol> ();
+          bool __attribute__ ((unused)) result = ipv6L3Protocol->TraceConnectWithoutContext ("Drop", 
+            MakeBoundCallback (&Ipv6L3ProtocolDropSinkWithoutContext, theStream));
+          NS_ASSERT_MSG (result == true, "InternetStackHelper::EnableAsciiIpv6Internal():  "
+                         "Unable to connect ipv6L3Protocol \"Drop\"");
+        }
+
+      g_interfaceStreamMapIpv6[std::make_pair (ipv6, interface)] = theStream;
+      return;
+    }
+
+  //
+  // If we are provided an OutputStreamWrapper, we are expected to use it, and
+  // to provide a context.  We are free to come up with our own context if we
+  // want, and use the AsciiTraceHelper Hook*WithContext functions, but for 
+  // compatibility and simplicity, we just use Config::Connect and let it deal
+  // with the context.
+  //
+  // We need to associate the ipv4/interface with a stream to express interest
+  // in tracing events on that pair, however, we only hook the trace sources 
+  // once to avoid multiple trace sink calls per event (connect is independent
+  // of interface).
+  //
+  if (!AsciiHooked (ipv6))
+    {
+      Ptr<Node> node = ipv6->GetObject<Node> ();
+      std::ostringstream oss;
+      
+      oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv6L3Protocol/Drop";
+      Config::Connect (oss.str (), MakeBoundCallback (&Ipv6L3ProtocolDropSinkWithContext, stream));
+    }
+
+  g_interfaceStreamMapIpv6[std::make_pair (ipv6, interface)] = stream;
 }
 
 } // namespace ns3
--- a/src/helper/internet-stack-helper.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/internet-stack-helper.h	Thu Feb 25 14:17:21 2010 +0100
@@ -26,10 +26,9 @@
 #include "ns3/packet.h"
 #include "ns3/ptr.h"
 #include "ns3/object-factory.h"
-#include "ns3/pcap-writer.h"
-#include "ns3/ascii-writer.h"
 #include "ns3/ipv4-l3-protocol.h"
 #include "ns3/ipv6-l3-protocol.h"
+#include "trace-helper.h"
 
 namespace ns3 {
 
@@ -39,8 +38,22 @@
 
 /**
  * \brief aggregate IP/TCP/UDP functionality to existing Nodes.
+ *
+ * This helper enables pcap and ascii tracing of events in the internet stack
+ * associated with a node.  This is substantially similar to the tracing
+ * that happens in device helpers, but the important difference is that, well,
+ * there is no device.  This means that the creation of output file names will
+ * change, and also the user-visible methods will not reference devices and
+ * therefore the number of trace enable methods is reduced.
+ *
+ * Normally we eschew multiple inheritance, however, the classes 
+ * PcapUserHelperForIpv4 and AsciiTraceUserHelperForIpv4 are
+ * treated as "mixins".  A mixin is a self-contained class that
+ * encapsulates a general attribute or a set of functionality that
+ * may be of interest to many other classes.
  */
-class InternetStackHelper
+class InternetStackHelper : public PcapHelperForIpv4, public PcapHelperForIpv6, 
+                              public AsciiTraceHelperForIpv4, public AsciiTraceHelperForIpv6
 {
 public:
   /**
@@ -145,43 +158,6 @@
   void SetTcp (std::string tid, std::string attr, const AttributeValue &val); 
 
   /**
-   * \param os output stream
-   * \param n node container
-   *
-   * Enable ascii output on these drop traces, for each node in the NodeContainer..
-   * /NodeList/[i]/$ns3ArpL3Protocol/Drop 
-   * /NodeList/[i]/$ns3Ipv4L3Protocol/Drop 
-   * /NodeList/[i]/$ns3Ipv6L3Protocol/Drop 
-   */
-  static void EnableAscii (std::ostream &os, NodeContainer n);
-
-  /**
-   * \param os output stream
-   *
-   * Enable ascii output on these drop traces, for all nodes.
-   * /NodeList/[i]/$ns3ArpL3Protocol/Drop 
-   * /NodeList/[i]/$ns3Ipv4L3Protocol/Drop 
-   * /NodeList/[i]/$ns3Ipv6L3Protocol/Drop 
-   */
-  static void EnableAsciiAll (std::ostream &os);
-
-  /**
-   * Enable pcap output on each protocol instance which is of the
-   * ns3::Ipv4L3Protocol or ns3::Ipv6L3Protocol type.  Both Tx and 
-   * Rx events will be logged.
-   *
-   * \param filename filename prefix to use for pcap files.
-   *
-   * \warning If you perform multiple simulations in a single script,
-   * each iteration of the simulation will result in the trace files
-   * being overwritten.  We don't attempt to anticipate what a user
-   * might actually want to do, so we leave it up to them.  If you want
-   * to save any particular data, do so manually at inter-simulation 
-   * time.
-   */
-  static void EnablePcapAll (std::string filename);
-
-  /**
    * \brief Enable/disable IPv4 stack install.
    * \param enable enable state
    */
@@ -194,6 +170,54 @@
   void SetIpv6StackInstall (bool enable);
 
 private:
+  /**
+   * @brief Enable pcap output the indicated Ipv4 and interface pair.
+   * @internal
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   * @param ipv4 Ptr to the Ipv4 interface on which you want to enable tracing.
+   * @param interface Interface ID on the Ipv4 on which you want to enable tracing.
+   */
+  virtual void EnablePcapIpv4Internal (std::string prefix, 
+                                       Ptr<Ipv4> ipv4, uint32_t interface);
+
+  /**
+   * @brief Enable ascii trace output on the indicated Ipv4 and interface pair.
+   * @internal
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param prefix Filename prefix to use for ascii trace files.
+   * @param ipv4 Ptr to the Ipv4 interface on which you want to enable tracing.
+   * @param interface Interface ID on the Ipv4 on which you want to enable tracing.
+   */
+  virtual void EnableAsciiIpv4Internal (Ptr<OutputStreamWrapper> stream, std::string prefix, 
+                                        Ptr<Ipv4> ipv4, uint32_t interface);
+
+  /**
+   * @brief Enable pcap output the indicated Ipv4 and interface pair.
+   * @internal
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   * @param ipv4 Ptr to the Ipv4 interface on which you want to enable tracing.
+   * @param interface Interface ID on the Ipv4 on which you want to enable tracing.
+   */
+  virtual void EnablePcapIpv6Internal (std::string prefix, 
+                                       Ptr<Ipv6> ipv6, uint32_t interface);
+
+  /**
+   * @brief Enable ascii trace output on the indicated Ipv4 and interface pair.
+   * @internal
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param prefix Filename prefix to use for ascii trace files.
+   * @param ipv4 Ptr to the Ipv4 interface on which you want to enable tracing.
+   * @param interface Interface ID on the Ipv4 on which you want to enable tracing.
+   */
+  virtual void EnableAsciiIpv6Internal (Ptr<OutputStreamWrapper> stream, std::string prefix, 
+                                        Ptr<Ipv6> ipv6, uint32_t interface);
+
   void Initialize (void);
   ObjectFactory m_tcpFactory;
   const Ipv4RoutingHelper *m_routing;
@@ -217,50 +241,22 @@
   /**
    * \internal
    */
-  static void LogRxIp (std::string context, Ptr<const Packet> packet, uint32_t deviceId);
-
-  /**
-   * \internal
-   */
-  static void LogTxIp (std::string context, Ptr<const Packet> packet, uint32_t deviceId);
-
-  /**
-   * \internal
-   */
-  static Ptr<PcapWriter> GetStream (uint32_t nodeId, uint32_t interfaceId);
-
-  struct Trace {
-    uint32_t nodeId;
-    uint32_t interfaceId;
-    Ptr<PcapWriter> writer;
-  };
+  bool PcapHooked (Ptr<Ipv4> ipv4);
 
   /**
    * \internal
    */
-  static void AsciiDropEventIpv4 (Ptr<AsciiWriter> writer, std::string path,
-                                  Ipv4Header const &header, Ptr<const Packet> packet,
-                                  Ipv4L3Protocol::DropReason reason, uint32_t interface);
-  /**
-   * \internal
-   */
-  static void AsciiDropEventArp (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet);
+  bool AsciiHooked (Ptr<Ipv4> ipv4);
 
   /**
    * \internal
    */
-  static void AsciiDropEventIpv6 (Ptr<AsciiWriter> writer, std::string path,
-                                  Ipv6Header const &header, Ptr<const Packet> packet,
-                                  Ipv6L3Protocol::DropReason reason, uint32_t interface);
-
-  static std::string m_pcapBaseFilename;
+  bool PcapHooked (Ptr<Ipv6> ipv6);
 
   /**
    * \internal
    */
-  static uint32_t GetNodeIndex (std::string context);
-
-  static std::vector<Trace> m_traces;
+  bool AsciiHooked (Ptr<Ipv6> ipv6);
 
   /**
    * \brief IPv4 install state (enabled/disabled) ?
--- a/src/helper/ipv4-address-helper.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/ipv4-address-helper.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -23,6 +23,7 @@
 #include "ns3/net-device.h"
 #include "ns3/ipv4.h"
 #include "ns3/ipv4-address-generator.h"
+#include "ns3/simulator.h"
 #include "ipv4-address-helper.h"
 
 NS_LOG_COMPONENT_DEFINE("Ipv4AddressHelper");
@@ -200,6 +201,7 @@
 NetworkAllocatorHelperTestCase::DoTeardown (void)
 {
   Ipv4AddressGenerator::Reset ();
+  Simulator::Destroy ();
 }
 bool
 NetworkAllocatorHelperTestCase::DoRun (void)
@@ -246,6 +248,7 @@
 AddressAllocatorHelperTestCase::DoTeardown (void)
 {
   Ipv4AddressGenerator::Reset ();
+  Simulator::Destroy ();
 }
 
 bool
@@ -337,6 +340,7 @@
 ResetAllocatorHelperTestCase::DoTeardown (void)
 {
   Ipv4AddressGenerator::Reset ();
+  Simulator::Destroy ();
 }
 
 static class Ipv4AddressHelperTestSuite : public TestSuite
--- a/src/helper/ipv4-interface-container.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/ipv4-interface-container.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -16,6 +16,18 @@
     }
 }
 
+Ipv4InterfaceContainer::Iterator 
+Ipv4InterfaceContainer::Begin (void) const
+{
+  return m_interfaces.begin ();
+}
+
+Ipv4InterfaceContainer::Iterator 
+Ipv4InterfaceContainer::End (void) const
+{
+  return m_interfaces.end ();
+}
+
 uint32_t 
 Ipv4InterfaceContainer::GetN (void) const
 {
--- a/src/helper/ipv4-interface-container.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/ipv4-interface-container.h	Thu Feb 25 14:17:21 2010 +0100
@@ -32,6 +32,8 @@
 class Ipv4InterfaceContainer
 {
 public:
+  typedef std::vector<std::pair<Ptr<Ipv4>, uint32_t> >::const_iterator Iterator;
+
   /**
    * Create an empty Ipv4InterfaceContainer.
    */
@@ -44,8 +46,69 @@
   void Add (Ipv4InterfaceContainer other);
 
   /**
+   * \brief Get an iterator which refers to the first pair in the 
+   * container.
+   *
+   * Pairs can be retrieved from the container in two ways.  First,
+   * directly by an index into the container, and second, using an iterator.
+   * This method is used in the iterator method and is typically used in a 
+   * for-loop to run through the pairs
+   *
+   * \code
+   *   Ipv4InterfaceContainer::Iterator i;
+   *   for (i = container.Begin (); i != container.End (); ++i)
+   *     {
+   *       std::pair<Ptr<Ipv4>, uint32_t> pair = *i;
+   *       method (pair.first, pair.second);  // use the pair
+   *     }
+   * \endcode
+   *
+   * \returns an iterator which refers to the first pair in the container.
+   */
+  Iterator Begin (void) const;
+
+  /**
+   * \brief Get an iterator which indicates past-the-last Node in the 
+   * container.
+   *
+   * Nodes can be retrieved from the container in two ways.  First,
+   * directly by an index into the container, and second, using an iterator.
+   * This method is used in the iterator method and is typically used in a 
+   * for-loop to run through the Nodes
+   *
+   * \code
+   *   NodeContainer::Iterator i;
+   *   for (i = container.Begin (); i != container.End (); ++i)
+   *     {
+   *       std::pair<Ptr<Ipv4>, uint32_t> pair = *i;
+   *       method (pair.first, pair.second);  // use the pair
+   *     }
+   * \endcode
+   *
+   * \returns an iterator which indicates an ending condition for a loop.
+   */
+  Iterator End (void) const;
+
+  /**
    * \returns the number of Ptr<Ipv4> and interface pairs stored in this 
    * Ipv4InterfaceContainer.
+   *
+   * Pairs can be retrieved from the container in two ways.  First,
+   * directly by an index into the container, and second, using an iterator.
+   * This method is used in the direct method and is typically used to
+   * define an ending condition in a for-loop that runs through the stored
+   * Nodes
+   *
+   * \code
+   *   uint32_t nNodes = container.GetN ();
+   *   for (uint32_t i = 0 i < nNodes; ++i)
+   *     {
+   *       std::pair<Ptr<Ipv4>, uint32_t> pair = container.Get (i);
+   *       method (pair.first, pair.second);  // use the pair
+   *     }
+   * \endcode
+   *
+   * \returns the number of Ptr<Node> stored in this container.
    */
   uint32_t GetN (void) const;
 
@@ -61,7 +124,6 @@
    */
   Ipv4Address GetAddress (uint32_t i, uint32_t j = 0) const;
 
-
   void SetMetric (uint32_t i, uint16_t metric);
 
   /**
--- a/src/helper/ipv6-interface-container.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/ipv6-interface-container.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -31,6 +31,18 @@
 {
 }
 
+Ipv6InterfaceContainer::Iterator 
+Ipv6InterfaceContainer::Begin (void) const
+{
+  return m_interfaces.begin ();
+}
+
+Ipv6InterfaceContainer::Iterator 
+Ipv6InterfaceContainer::End (void) const
+{
+  return m_interfaces.end ();
+}
+
 uint32_t Ipv6InterfaceContainer::GetN () const
 {
   return m_interfaces.size ();
--- a/src/helper/ipv6-interface-container.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/ipv6-interface-container.h	Thu Feb 25 14:17:21 2010 +0100
@@ -38,14 +38,30 @@
 class Ipv6InterfaceContainer
 {
 public:
+  typedef std::vector<std::pair<Ptr<Ipv6>, uint32_t> >::const_iterator Iterator;
   /**
    * \brief Constructor.
    */
   Ipv6InterfaceContainer ();
 
   /**
-   * \brief Get the number of interfaces.
-   * \return the number of interfaces stored in this Ipv6InterfaceContainer.
+   * \returns the number of Ptr<Ipv6> and interface pairs stored in this 
+   * Ipv4InterfaceContainer.
+   *
+   * Pairs can be retrieved from the container in two ways.  First,
+   * directly by an index into the container, and second, using an iterator.
+   * This method is used in the direct method and is typically used to
+   * define an ending condition in a for-loop that runs through the stored
+   * Nodes
+   *
+   * \code
+   *   uint32_t nNodes = container.GetN ();
+   *   for (uint32_t i = 0 i < nNodes; ++i)
+   *     {
+   *       std::pair<Ptr<Ipv6>, uint32_t> pair = container.Get (i);
+   *       method (pair.first, pair.second);  // use the pair
+   *     }
+   * \endcode
    */
   uint32_t GetN (void) const;
 
@@ -72,6 +88,50 @@
   void Add (Ptr<Ipv6> ipv6, uint32_t interface);
 
   /**
+   * \brief Get an iterator which refers to the first pair in the 
+   * container.
+   *
+   * Pairs can be retrieved from the container in two ways.  First,
+   * directly by an index into the container, and second, using an iterator.
+   * This method is used in the iterator method and is typically used in a 
+   * for-loop to run through the pairs
+   *
+   * \code
+   *   Ipv4InterfaceContainer::Iterator i;
+   *   for (i = container.Begin (); i != container.End (); ++i)
+   *     {
+   *       std::pair<Ptr<Ipv6>, uint32_t> pair = *i;
+   *       method (pair.first, pair.second);  // use the pair
+   *     }
+   * \endcode
+   *
+   * \returns an iterator which refers to the first pair in the container.
+   */
+  Iterator Begin (void) const;
+
+  /**
+   * \brief Get an iterator which indicates past-the-last Node in the 
+   * container.
+   *
+   * Nodes can be retrieved from the container in two ways.  First,
+   * directly by an index into the container, and second, using an iterator.
+   * This method is used in the iterator method and is typically used in a 
+   * for-loop to run through the Nodes
+   *
+   * \code
+   *   NodeContainer::Iterator i;
+   *   for (i = container.Begin (); i != container.End (); ++i)
+   *     {
+   *       std::pair<Ptr<Ipv6>, uint32_t> pair = *i;
+   *       method (pair.first, pair.second);  // use the pair
+   *     }
+   * \endcode
+   *
+   * \returns an iterator which indicates an ending condition for a loop.
+   */
+  Iterator End (void) const;
+
+  /**
    * \brief Fusion with another Ipv6InterfaceContainer.
    * \param c container
    */
--- a/src/helper/node-container.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/node-container.h	Thu Feb 25 14:17:21 2010 +0100
@@ -189,10 +189,10 @@
    * Nodes
    *
    * \code
-   *   uint32_t nNodes = continer.GetN ();
+   *   uint32_t nNodes = container.GetN ();
    *   for (uint32_t i = 0 i < nNodes; ++i)
    *     {
-   *       Ptr<Node> p = continer.Get (i)
+   *       Ptr<Node> p = container.Get (i)
    *       i->method ();  // some Node method
    *     }
    * \endcode
--- a/src/helper/point-to-point-dumbbell-helper.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/point-to-point-dumbbell-helper.h	Thu Feb 25 14:17:21 2010 +0100
@@ -137,7 +137,7 @@
    * \param lrx lower right x value
    * \param lry lower right y value
    */
-  void      BoundingBox (double, double, double, double);
+  void      BoundingBox (double ulx, double uly, double lrx, double lry);
   
 private:
   NodeContainer          m_leftLeaf;
--- a/src/helper/point-to-point-helper.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/point-to-point-helper.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -17,7 +17,9 @@
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
-#include "point-to-point-helper.h"
+
+#include "ns3/abort.h"
+#include "ns3/log.h"
 #include "ns3/simulator.h"
 #include "ns3/point-to-point-net-device.h"
 #include "ns3/point-to-point-channel.h"
@@ -25,12 +27,14 @@
 #include "ns3/config.h"
 #include "ns3/packet.h"
 #include "ns3/names.h"
-#include "ns3/pcap-writer.h"
-#include "ns3/ascii-writer.h"
+
+#include "trace-helper.h"
+#include "point-to-point-helper.h"
+
+NS_LOG_COMPONENT_DEFINE ("PointToPointHelper");
 
 namespace ns3 {
 
-
 PointToPointHelper::PointToPointHelper ()
 {
   m_queueFactory.SetTypeId ("ns3::DropTailQueue");
@@ -65,118 +69,112 @@
 }
 
 void 
-PointToPointHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
+PointToPointHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous)
 {
-  std::ostringstream oss;
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/";
-  Config::MatchContainer matches = Config::LookupMatches (oss.str ());
-  if (matches.GetN () == 0)
+  //
+  // All of the Pcap enable functions vector through here including the ones
+  // that are wandering through all of devices on perhaps all of the nodes in
+  // the system.  We can only deal with devices of type PointToPointNetDevice.
+  //
+  Ptr<PointToPointNetDevice> device = nd->GetObject<PointToPointNetDevice> ();
+  if (device == 0)
     {
+      NS_LOG_INFO ("PointToPointHelper::EnablePcapInternal(): Device " << device << " not of type ns3::PointToPointNetDevice");
       return;
     }
-  oss.str ("");
-  oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
-  Ptr<PcapWriter> pcap = CreateObject<PcapWriter> ();
-  pcap->Open (oss.str ());
-  pcap->WritePppHeader ();
-  oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
-  oss << "/$ns3::PointToPointNetDevice/PromiscSniffer";
-  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PointToPointHelper::SniffEvent, pcap));
-}
 
-void 
-PointToPointHelper::EnablePcap (std::string filename, Ptr<NetDevice> nd)
-{
-  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ());
-}
-
-void 
-PointToPointHelper::EnablePcap (std::string filename, std::string ndName)
-{
-  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
-  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ());
+  PcapHelper pcapHelper;
+  std::string filename = pcapHelper.GetFilenameFromDevice (prefix, device);
+  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_PPP);
+  pcapHelper.HookDefaultSink<PointToPointNetDevice> (device, "PromiscSniffer", file);
 }
 
 void 
-PointToPointHelper::EnablePcap (std::string filename, NetDeviceContainer d)
+PointToPointHelper::EnableAsciiInternal (Ptr<OutputStreamWrapper> stream, std::string prefix, Ptr<NetDevice> nd)
 {
-  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
+  //
+  // All of the ascii enable functions vector through here including the ones
+  // that are wandering through all of devices on perhaps all of the nodes in
+  // the system.  We can only deal with devices of type PointToPointNetDevice.
+  //
+  Ptr<PointToPointNetDevice> device = nd->GetObject<PointToPointNetDevice> ();
+  if (device == 0)
     {
-      Ptr<NetDevice> dev = *i;
-      EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
+      NS_LOG_INFO ("PointToPointHelper::EnableAsciiInternal(): Device " << device << 
+                   " not of type ns3::PointToPointNetDevice");
+      return;
     }
-}
+
+  //
+  // Our default trace sinks are going to use packet printing, so we have to 
+  // make sure that is turned on.
+  //
+  Packet::EnablePrinting ();
 
-void
-PointToPointHelper::EnablePcap (std::string filename, NodeContainer n)
-{
-  NetDeviceContainer devs;
-  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+  //
+  // If we are not provided an OutputStreamWrapper, we are expected to create 
+  // one using the usual trace filename conventions and do a Hook*WithoutContext
+  // since there will be one file per context and therefore the context would
+  // be redundant.
+  //
+  if (stream == 0)
     {
-      Ptr<Node> node = *i;
-      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-        {
-          devs.Add (node->GetDevice (j));
-        }
-    }
-  EnablePcap (filename, devs);
-}
+      //
+      // Set up an output stream object to deal with private ofstream copy 
+      // constructor and lifetime issues.  Let the helper decide the actual
+      // name of the file given the prefix.
+      //
+      AsciiTraceHelper asciiTraceHelper;
+      std::string filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
+      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename, "w");
+
+      //
+      // The MacRx trace source provides our "r" event.
+      //
+      asciiTraceHelper.HookDefaultReceiveSinkWithoutContext<PointToPointNetDevice> (device, "MacRx", theStream);
+
+      //
+      // The "+", '-', and 'd' events are driven by trace sources actually in the
+      // transmit queue.
+      //
+      Ptr<Queue> queue = device->GetQueue ();
+      asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext<Queue> (queue, "Enqueue", theStream);
+      asciiTraceHelper.HookDefaultDropSinkWithoutContext<Queue> (queue, "Drop", theStream);
+      asciiTraceHelper.HookDefaultDequeueSinkWithoutContext<Queue> (queue, "Dequeue", theStream);
 
-void
-PointToPointHelper::EnablePcapAll (std::string filename)
-{
-  EnablePcap (filename, NodeContainer::GetGlobal ());
-}
+      return;
+    }
 
-void 
-PointToPointHelper::EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid)
-{
-  Ptr<AsciiWriter> writer = AsciiWriter::Get (os);
-  Packet::EnablePrinting ();
+  //
+  // If we are provided an OutputStreamWrapper, we are expected to use it, and
+  // to providd a context.  We are free to come up with our own context if we
+  // want, and use the AsciiTraceHelper Hook*WithContext functions, but for 
+  // compatibility and simplicity, we just use Config::Connect and let it deal
+  // with the context.
+  //
+  // Note that we are going to use the default trace sinks provided by the 
+  // ascii trace helper.  There is actually no AsciiTraceHelper in sight here,
+  // but the default trace sinks are actually publicly available static 
+  // functions that are always there waiting for just such a case.
+  //
+  uint32_t nodeid = nd->GetNode ()->GetId ();
+  uint32_t deviceid = nd->GetIfIndex ();
   std::ostringstream oss;
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/MacRx";
-  Config::Connect (oss.str (), MakeBoundCallback (&PointToPointHelper::AsciiRxEvent, writer));
+
+  oss << "/NodeList/" << nd->GetNode ()->GetId () << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/MacRx";
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultReceiveSinkWithContext, stream));
+
   oss.str ("");
   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Enqueue";
-  Config::Connect (oss.str (), MakeBoundCallback (&PointToPointHelper::AsciiEnqueueEvent, writer));
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultEnqueueSinkWithContext, stream));
+
   oss.str ("");
   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Dequeue";
-  Config::Connect (oss.str (), MakeBoundCallback (&PointToPointHelper::AsciiDequeueEvent, writer));
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDequeueSinkWithContext, stream));
+
   oss.str ("");
   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Drop";
-  Config::Connect (oss.str (), MakeBoundCallback (&PointToPointHelper::AsciiDropEvent, writer));
-}
-
-void 
-PointToPointHelper::EnableAscii (std::ostream &os, NetDeviceContainer d)
-{
-  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
-    {
-      Ptr<NetDevice> dev = *i;
-      EnableAscii (os, dev->GetNode ()->GetId (), dev->GetIfIndex ());
-    }
-}
-
-void
-PointToPointHelper::EnableAscii (std::ostream &os, NodeContainer n)
-{
-  NetDeviceContainer devs;
-  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
-    {
-      Ptr<Node> node = *i;
-      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-        {
-          devs.Add (node->GetDevice (j));
-        }
-    }
-  EnableAscii (os, devs);
-}
-
-void
-PointToPointHelper::EnableAsciiAll (std::ostream &os)
-{
-  EnableAscii (os, NodeContainer::GetGlobal ());
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDropSinkWithContext, stream));
 }
 
 NetDeviceContainer 
@@ -232,35 +230,4 @@
   return Install (a, b);
 }
 
-void 
-PointToPointHelper::SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
-{
-  writer->WritePacket (packet);
-}
-
-void
-PointToPointHelper::AsciiEnqueueEvent (Ptr<AsciiWriter> writer, std::string path,
-                                       Ptr<const Packet> packet)
-{
-  writer->WritePacket (AsciiWriter::ENQUEUE, path, packet);
-}
-
-void
-PointToPointHelper::AsciiDequeueEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet)
-{
-  writer->WritePacket (AsciiWriter::DEQUEUE, path, packet);
-}
-
-void
-PointToPointHelper::AsciiDropEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet)
-{
-  writer->WritePacket (AsciiWriter::DROP, path, packet);
-}
-
-void
-PointToPointHelper::AsciiRxEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet)
-{
-  writer->WritePacket (AsciiWriter::RX, path, packet);
-}
-
 } // namespace ns3
--- a/src/helper/point-to-point-helper.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/point-to-point-helper.h	Thu Feb 25 14:17:21 2010 +0100
@@ -20,24 +20,29 @@
 #ifndef POINT_TO_POINT_HELPER_H
 #define POINT_TO_POINT_HELPER_H
 
+#include <string>
+
 #include "ns3/object-factory.h"
 #include "ns3/net-device-container.h"
 #include "ns3/node-container.h"
 #include "ns3/deprecated.h"
-#include <string>
+
+#include "trace-helper.h"
 
 namespace ns3 {
 
 class Queue;
 class NetDevice;
 class Node;
-class PcapWriter;
-class AsciiWriter;
 
 /**
  * \brief Build a set of PointToPointNetDevice objects
+ *
+ * Normally we eschew multiple inheritance, however, the classes 
+ * PcapUserHelperForDevice and AsciiTraceUserHelperForDevice are
+ * "mixins".
  */
-class PointToPointHelper
+class PointToPointHelper : public PcapHelperForDevice, public AsciiTraceHelperForDevice
 {
 public:
   /**
@@ -45,6 +50,7 @@
    * point networks.
    */
   PointToPointHelper ();
+  virtual ~PointToPointHelper () {}
 
   /**
    * Each point to point net device must have a queue to pass packets through.
@@ -95,108 +101,6 @@
   void SetChannelAttribute (std::string name, const AttributeValue &value);
 
   /**
-   * \param filename filename prefix to use for pcap files.
-   * \param nodeid the id of the node to generate pcap output for.
-   * \param deviceid the id of the device to generate pcap output for.
-   *
-   * Generate a pcap file which contains the link-level data observed
-   * by the specified deviceid within the specified nodeid. The pcap
-   * data is stored in the file prefix-nodeid-deviceid.pcap.
-   *
-   * This method should be invoked after the network topology has 
-   * been fully constructed.
-   */
-  static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param nd Net device on which you want to enable tracing.
-   *
-   * Enable pcap output on each input device which is of the
-   * ns3::PointToPointNetDevice type.
-   */
-  static void EnablePcap (std::string filename, Ptr<NetDevice> nd);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param ndName Name of net device on which you want to enable tracing.
-   *
-   * Enable pcap output on each input device which is of the
-   * ns3::PointToPointNetDevice type.
-   */
-  static void EnablePcap (std::string filename, std::string ndName);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param d container of devices of type ns3::PointToPointNetDevice
-   *
-   * Enable pcap output on each input device which is of the
-   * ns3::PointToPointNetDevice type.
-   */
-  static void EnablePcap (std::string filename, NetDeviceContainer d);
-
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param n container of nodes.
-   *
-   * Enable pcap output on each device which is of the
-   * ns3::PointToPointNetDevice type and which is located in one of the 
-   * input nodes.
-   */
-  static void EnablePcap (std::string filename, NodeContainer n);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   *
-   * Enable pcap output on each device which is of the
-   * ns3::PointToPointNetDevice type
-   */
-  static void EnablePcapAll (std::string filename);
-
-  /**
-   * \param os output stream
-   * \param nodeid the id of the node to generate ascii output for.
-   * \param deviceid the id of the device to generate ascii output for.
-   *
-   * Enable ascii output on the specified deviceid within the
-   * specified nodeid if it is of type ns3::PointToPointNetDevice and dump 
-   * that to the specified stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid);
-
-  /**
-   * \param os output stream
-   * \param d device container
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::PointToPointNetDevice type and which is located in the input
-   * device container and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, NetDeviceContainer d);
-
-  /**
-   * \param os output stream
-   * \param n node container
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::PointToPointNetDevice type and which is located in one
-   * of the input node and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, NodeContainer n);
-
-  /**
-   * \param os output stream
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::PointToPointNetDevice type and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAsciiAll (std::ostream &os);
-
-  /**
    * \param c a set of nodes
    *
    * This method creates a ns3::PointToPointChannel with the
@@ -241,14 +145,30 @@
   NetDeviceContainer Install (std::string aNode, std::string bNode);
 
 private:
-  void EnablePcap (Ptr<Node> node, Ptr<NetDevice> device, Ptr<Queue> queue);
-  static void SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+  /**
+   * \brief Enable pcap output the indicated net device.
+   *
+   * NetDevice-specific implementation mechanism for hooking the trace and
+   * writing to the trace file.
+   *
+   * \param prefix Filename prefix to use for pcap files.
+   * \param nd Net device for which you want to enable tracing.
+   * \param promiscuous If true capture all possible packets available at the device.
+   */
+  virtual void EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous = false);
 
-  void EnableAscii (Ptr<Node> node, Ptr<NetDevice> device);
-  static void AsciiRxEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet);
-  static void AsciiEnqueueEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet);
-  static void AsciiDequeueEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet);
-  static void AsciiDropEvent (Ptr<AsciiWriter> writer, std::string path, Ptr<const Packet> packet);
+  /**
+   * \brief Enable ascii trace output on the indicated net device.
+   * \internal
+   *
+   * NetDevice-specific implementation mechanism for hooking the trace and
+   * writing to the trace file.
+   *
+   * \param stream The output stream object to use when logging ascii traces.
+   * \param prefix Filename prefix to use for ascii trace files.
+   * \param nd Net device for which you want to enable tracing.
+   */
+  virtual void EnableAsciiInternal (Ptr<OutputStreamWrapper> stream, std::string prefix, Ptr<NetDevice> nd);
 
   ObjectFactory m_queueFactory;
   ObjectFactory m_channelFactory;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/trace-helper.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,1165 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 University of Washington
+ *
+ * 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
+ */
+
+#include <stdint.h>
+#include <string>
+#include <fstream>
+
+#include "ns3/abort.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/ptr.h"
+#include "ns3/node.h"
+#include "ns3/names.h"
+#include "ns3/net-device.h"
+#include "ns3/pcap-file-wrapper.h"
+
+#include "trace-helper.h"
+
+NS_LOG_COMPONENT_DEFINE("TraceHelper");
+
+namespace ns3 {
+
+PcapHelper::PcapHelper ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+PcapHelper::~PcapHelper ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ptr<PcapFileWrapper>
+PcapHelper::CreateFile (
+  std::string filename, 
+  std::string filemode,  
+  uint32_t    dataLinkType, 
+  uint32_t    snapLen, 
+  int32_t     tzCorrection)
+{
+  NS_LOG_FUNCTION (filename << filemode << dataLinkType << snapLen << tzCorrection);
+
+  Ptr<PcapFileWrapper> file = CreateObject<PcapFileWrapper> ();
+  bool err = file->Open (filename, filemode);
+  NS_ABORT_MSG_IF (err, "Unable to Open " << filename << " for mode " << filemode);
+
+  err = file->Init (dataLinkType, snapLen, tzCorrection);
+  NS_ABORT_MSG_IF (err, "Unable to Init " << filename);
+
+  //
+  // Note that the pcap helper promptly forgets all about the pcap file.  We
+  // rely on the reference count of the file object which will soon be owned
+  // by the caller to keep the object alive.  If the caller uses the file 
+  // object to hook a trace source, ownership of the file object will be
+  // implicitly transferred to the callback which keeps the object alive.
+  // When the callback is destroyed (when either the trace is disconnected or
+  // the object with the trace source is deleted) the callback will be destroyed
+  // and the file object will be destroyed, releasing the pointer and closing
+  // the file.
+  //
+  return file;
+}
+
+std::string
+PcapHelper::GetFilenameFromDevice (std::string prefix, Ptr<NetDevice> device, bool useObjectNames)
+{
+  NS_LOG_FUNCTION (prefix << device << useObjectNames);
+  NS_ABORT_MSG_UNLESS (prefix.size (), "Empty prefix string");
+
+  std::ostringstream oss;
+  oss << prefix << "-";
+
+  std::string nodename;
+  std::string devicename;
+
+  Ptr<Node> node = device->GetNode ();
+
+  if (useObjectNames)
+    {
+      nodename = Names::FindName (node);
+      devicename = Names::FindName (device);
+    }
+
+  if (nodename.size ())
+    {
+      oss << nodename;
+    }
+  else
+    {
+      oss << node->GetId ();
+    }
+
+  oss << "-";
+
+  if (devicename.size ())
+    {
+      oss << devicename;
+    }
+  else
+    {
+      oss << device->GetIfIndex ();
+    }
+
+  oss << ".pcap";
+
+  return oss.str ();
+}
+
+std::string
+PcapHelper::GetFilenameFromInterfacePair (std::string prefix, Ptr<Object> object, uint32_t interface, bool useObjectNames)
+{
+  NS_LOG_FUNCTION (prefix << object << interface << useObjectNames);
+  NS_ABORT_MSG_UNLESS (prefix.size (), "Empty prefix string");
+
+  std::ostringstream oss;
+  oss << prefix << "-";
+
+  std::string objname;
+  std::string nodename;
+
+  Ptr<Node> node = object->GetObject<Node> ();
+
+  if (useObjectNames)
+    {
+      objname = Names::FindName (object);
+      nodename = Names::FindName (node);
+    }
+
+  if (objname.size ())
+    {
+      oss << objname;
+    }
+  else if (nodename.size ())
+    {
+      oss << nodename;
+    }
+  else
+    {
+      oss << "n" << node->GetId ();
+    }
+
+  oss << "-i" << interface << ".pcap";
+
+  return oss.str ();
+}
+
+//
+// The basic default trace sink.  This one just writes the packet to the pcap
+// file which is good enough for most kinds of captures.
+//
+void
+PcapHelper::DefaultSink (Ptr<PcapFileWrapper> file, Ptr<const Packet> p)
+{
+  NS_LOG_FUNCTION (file << p);
+  file->Write(Simulator::Now(), p);
+}
+
+AsciiTraceHelper::AsciiTraceHelper ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+AsciiTraceHelper::~AsciiTraceHelper ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ptr<OutputStreamWrapper>
+AsciiTraceHelper::CreateFileStream (std::string filename, std::string filemode)
+{
+  NS_LOG_FUNCTION (filename << filemode);
+
+  std::ofstream *ofstream = new std::ofstream;
+  std::ios_base::openmode mode = std::ios_base::out | std::ios_base::trunc;
+
+  if (filemode == "a")
+    {
+      mode = std::ios_base::out | std::ios_base::app;
+    }
+  else if (filemode == "w")
+    {
+      mode = std::ios_base::out | std::ios_base::trunc;
+    }
+  else
+    {
+      NS_ABORT_MSG ("AsciiTraceHelper::CreateFileStream(): Unexpected file mode");
+    }
+
+  ofstream->open (filename.c_str (), mode);
+  NS_ABORT_MSG_UNLESS (ofstream->is_open (), "AsciiTraceHelper::CreateFileStream():  Unable to Open " << 
+                       filename << " for mode " << filemode);
+  
+  Ptr<OutputStreamWrapper> StreamWrapper = Create<OutputStreamWrapper> ();
+  StreamWrapper->SetStream (ofstream);
+
+  //
+  // Note that the ascii trace helper promptly forgets all about the trace file.
+  // We rely on the reference count of the file object which will soon be owned
+  // by the caller to keep the object alive.  If the caller uses the stream 
+  // object to hook a trace source, ownership of the stream object will be
+  // implicitly transferred to the callback which keeps the object alive.
+  // When the callback is destroyed (when either the trace is disconnected or
+  // the object with the trace source is deleted) the callback will be destroyed
+  // and the stream object will be destroyed, releasing the pointer and closing
+  // the underlying file.
+  //
+  return StreamWrapper;
+}
+
+std::string
+AsciiTraceHelper::GetFilenameFromDevice (std::string prefix, Ptr<NetDevice> device, bool useObjectNames)
+{
+  NS_LOG_FUNCTION (prefix << device << useObjectNames);
+  NS_ABORT_MSG_UNLESS (prefix.size (), "Empty prefix string");
+
+  std::ostringstream oss;
+  oss << prefix << "-";
+
+  std::string nodename;
+  std::string devicename;
+
+  Ptr<Node> node = device->GetNode ();
+
+  if (useObjectNames)
+    {
+      nodename = Names::FindName (node);
+      devicename = Names::FindName (device);
+    }
+
+  if (nodename.size ())
+    {
+      oss << nodename;
+    }
+  else
+    {
+      oss << node->GetId ();
+    }
+
+  oss << "-";
+
+  if (devicename.size ())
+    {
+      oss << devicename;
+    }
+  else
+    {
+      oss << device->GetIfIndex ();
+    }
+
+  oss << ".tr";
+
+  return oss.str ();
+}
+
+std::string
+AsciiTraceHelper::GetFilenameFromInterfacePair (
+  std::string prefix, 
+  Ptr<Object> object, 
+  uint32_t interface, 
+  bool useObjectNames)
+{
+  NS_LOG_FUNCTION (prefix << object << interface << useObjectNames);
+  NS_ABORT_MSG_UNLESS (prefix.size (), "Empty prefix string");
+
+  std::ostringstream oss;
+  oss << prefix << "-";
+
+  std::string objname;
+  std::string nodename;
+
+  Ptr<Node> node = object->GetObject<Node> ();
+
+  if (useObjectNames)
+    {
+      objname = Names::FindName (object);
+      nodename = Names::FindName (node);
+    }
+
+  if (objname.size ())
+    {
+      oss << objname;
+    }
+  else if (nodename.size ())
+    {
+      oss << nodename;
+    }
+  else
+    {
+      oss << "n" << node->GetId ();
+    }
+
+  oss << "-i" << interface << ".tr";
+
+  return oss.str ();
+}
+
+//
+// One of the basic default trace sink sets.  Enqueue:
+//
+//   When a packet has been sent to a device for transmission, the device is
+//   expected to place the packet onto a transmit queue even if it does not
+//   have to delay the packet at all, if only to trigger this event.  This 
+//   event will eventually translate into a '+' operation in the trace file.
+//
+//   This is typically implemented by hooking the "TxQueue/Enqueue" trace hook
+//   in the device (actually the Queue in the device).
+//
+void
+AsciiTraceHelper::DefaultEnqueueSinkWithoutContext (Ptr<OutputStreamWrapper> stream, Ptr<const Packet> p)
+{
+  NS_LOG_FUNCTION (stream << p);
+  *stream->GetStream () << "+ " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
+}
+
+void
+AsciiTraceHelper::DefaultEnqueueSinkWithContext (Ptr<OutputStreamWrapper> stream, std::string context, Ptr<const Packet> p)
+{
+  NS_LOG_FUNCTION (stream << p);
+  *stream->GetStream () << "+ " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
+}
+
+//
+// One of the basic default trace sink sets.  Drop:
+//
+//   When a packet has been sent to a device for transmission, the device is
+//   expected to place the packet onto a transmit queue.  If this queue is 
+//   full the packet will be dropped.  The device is expected to trigger an
+//   event to indicate that an outbound packet is being dropped.  This event
+//   will eventually translate into a 'd' operation in the trace file.
+//
+//   This is typically implemented by hooking the "TxQueue/Drop" trace hook
+//   in the device (actually the Queue in the device).
+//
+void
+AsciiTraceHelper::DefaultDropSinkWithoutContext (Ptr<OutputStreamWrapper> stream, Ptr<const Packet> p)
+{
+  NS_LOG_FUNCTION (stream << p);
+  *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
+}
+
+void
+AsciiTraceHelper::DefaultDropSinkWithContext (Ptr<OutputStreamWrapper> stream, std::string context, Ptr<const Packet> p)
+{
+  NS_LOG_FUNCTION (stream << p);
+  *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
+}
+
+//
+// One of the basic default trace sink sets.  Dequeue:
+//
+//   When a packet has been sent to a device for transmission, the device is
+//   expected to place the packet onto a transmit queue even if it does not
+//   have to delay the packet at all.  The device removes the packet from the
+//   transmit queue when the packet is ready to send, and this dequeue will 
+//   fire a corresponding event.  This event will eventually translate into a 
+//   '-' operation in the trace file.
+//
+//   This is typically implemented by hooking the "TxQueue/Dequeue" trace hook
+//   in the device (actually the Queue in the device).
+//
+void
+AsciiTraceHelper::DefaultDequeueSinkWithoutContext (Ptr<OutputStreamWrapper> stream, Ptr<const Packet> p)
+{
+  NS_LOG_FUNCTION (stream << p);
+  *stream->GetStream () << "- " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
+}
+
+void
+AsciiTraceHelper::DefaultDequeueSinkWithContext (Ptr<OutputStreamWrapper> stream, std::string context, Ptr<const Packet> p)
+{
+  NS_LOG_FUNCTION (stream << p);
+  *stream->GetStream () << "- " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
+}
+
+//
+// One of the basic default trace sink sets.  Receive:
+//
+//   When a packet is received by a device for transmission, the device is
+//   expected to trigger this event to indicate the reception has occurred.
+//   This event will eventually translate into an 'r' operation in the trace 
+//   file.
+//
+//   This is typically implemented by hooking the "MacRx" trace hook in the
+//   device.
+void
+AsciiTraceHelper::DefaultReceiveSinkWithoutContext (Ptr<OutputStreamWrapper> stream, Ptr<const Packet> p)
+{
+  NS_LOG_FUNCTION (stream << p);
+  *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
+}
+
+void
+AsciiTraceHelper::DefaultReceiveSinkWithContext (Ptr<OutputStreamWrapper> stream, std::string context, Ptr<const Packet> p)
+{
+  NS_LOG_FUNCTION (stream << p);
+  *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
+}
+
+void 
+PcapHelperForDevice::EnablePcap (std::string prefix, Ptr<NetDevice> nd, bool promiscuous)
+{
+  EnablePcapInternal (prefix, nd, promiscuous);
+}
+
+void 
+PcapHelperForDevice::EnablePcap (std::string prefix, std::string ndName, bool promiscuous)
+{
+  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+  EnablePcap (prefix, nd, promiscuous);
+}
+
+void 
+PcapHelperForDevice::EnablePcap (std::string prefix, NetDeviceContainer d, bool promiscuous)
+{
+  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
+    {
+      Ptr<NetDevice> dev = *i;
+      EnablePcap (prefix, dev, promiscuous);
+    }
+}
+
+void
+PcapHelperForDevice::EnablePcap (std::string prefix, NodeContainer n, bool promiscuous)
+{
+  NetDeviceContainer devs;
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
+        {
+          devs.Add (node->GetDevice (j));
+        }
+    }
+  EnablePcap (prefix, devs, promiscuous);
+}
+
+void
+PcapHelperForDevice::EnablePcapAll (std::string prefix, bool promiscuous)
+{
+  EnablePcap (prefix, NodeContainer::GetGlobal (), promiscuous);
+}
+
+void 
+PcapHelperForDevice::EnablePcap (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool promiscuous)
+{
+  NodeContainer n = NodeContainer::GetGlobal ();
+
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      if (node->GetId () != nodeid) 
+        {
+          continue;
+        }
+      
+      NS_ABORT_MSG_IF (deviceid >= node->GetNDevices (), "PcapHelperForDevice::EnablePcap(): Unknown deviceid = " 
+                       << deviceid);
+      Ptr<NetDevice> nd = node->GetDevice (deviceid);
+      EnablePcap (prefix, nd, promiscuous);
+      return;
+    }
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForDevice::EnableAscii (std::string prefix, Ptr<NetDevice> nd)
+{
+  EnableAsciiInternal (Ptr<OutputStreamWrapper> (), prefix, nd);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForDevice::EnableAscii (Ptr<OutputStreamWrapper> stream, Ptr<NetDevice> nd)
+{
+  EnableAsciiInternal (stream, std::string (), nd);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForDevice::EnableAscii (std::string prefix, std::string ndName)
+{
+  EnableAsciiImpl (Ptr<OutputStreamWrapper> (), prefix, ndName);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForDevice::EnableAscii (Ptr<OutputStreamWrapper> stream, std::string ndName)
+{
+  EnableAsciiImpl (stream, std::string (), ndName);
+}
+
+//
+// Private API
+//
+void 
+AsciiTraceHelperForDevice::EnableAsciiImpl (Ptr<OutputStreamWrapper> stream, std::string prefix, std::string ndName)
+{
+  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+  EnableAsciiInternal (stream, prefix, nd);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForDevice::EnableAscii (std::string prefix, NetDeviceContainer d)
+{
+  EnableAsciiImpl (Ptr<OutputStreamWrapper> (), prefix, d);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForDevice::EnableAscii (Ptr<OutputStreamWrapper> stream, NetDeviceContainer d)
+{
+  EnableAsciiImpl (stream, std::string (), d);
+}
+
+//
+// Private API
+//
+void 
+AsciiTraceHelperForDevice::EnableAsciiImpl (Ptr<OutputStreamWrapper> stream, std::string prefix, NetDeviceContainer d)
+{
+  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
+    {
+      Ptr<NetDevice> dev = *i;
+      EnableAsciiInternal (stream, prefix, dev);
+    }
+}
+
+//
+// Public API
+//
+void
+AsciiTraceHelperForDevice::EnableAscii (std::string prefix, NodeContainer n)
+{
+  EnableAsciiImpl (Ptr<OutputStreamWrapper> (), prefix, n);
+}
+
+//
+// Public API
+//
+void
+AsciiTraceHelperForDevice::EnableAscii (Ptr<OutputStreamWrapper> stream, NodeContainer n)
+{
+  EnableAsciiImpl (stream, std::string (), n);
+}
+
+//
+// Private API
+//
+void
+AsciiTraceHelperForDevice::EnableAsciiImpl (Ptr<OutputStreamWrapper> stream, std::string prefix, NodeContainer n)
+{
+  NetDeviceContainer devs;
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
+        {
+          devs.Add (node->GetDevice (j));
+        }
+    }
+  EnableAsciiImpl (stream, prefix, devs);
+}
+
+//
+// Public API
+//
+void
+AsciiTraceHelperForDevice::EnableAsciiAll (std::string prefix)
+{
+  EnableAsciiImpl (Ptr<OutputStreamWrapper> (), prefix, NodeContainer::GetGlobal ());
+}
+
+//
+// Public API
+//
+void
+AsciiTraceHelperForDevice::EnableAsciiAll (Ptr<OutputStreamWrapper> stream)
+{
+  EnableAsciiImpl (stream, std::string (), NodeContainer::GetGlobal ());
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForDevice::EnableAscii (Ptr<OutputStreamWrapper> stream, uint32_t nodeid, uint32_t deviceid)
+{
+  EnableAsciiImpl (stream, std::string (), nodeid, deviceid);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForDevice::EnableAscii (std::string prefix, uint32_t nodeid, uint32_t deviceid)
+{
+  EnableAsciiImpl (Ptr<OutputStreamWrapper> (), prefix, nodeid, deviceid);
+}
+
+//
+// Private API
+//
+void 
+AsciiTraceHelperForDevice::EnableAsciiImpl (
+  Ptr<OutputStreamWrapper> stream, 
+  std::string prefix, 
+  uint32_t nodeid, 
+  uint32_t deviceid)
+{
+  NodeContainer n = NodeContainer::GetGlobal ();
+
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      if (node->GetId () != nodeid) 
+        {
+          continue;
+        }
+      
+      NS_ABORT_MSG_IF (deviceid >= node->GetNDevices (), 
+                       "AsciiTraceHelperForDevice::EnableAscii(): Unknown deviceid = " << deviceid);
+
+      Ptr<NetDevice> nd = node->GetDevice (deviceid);
+
+      EnableAsciiInternal (stream, prefix, nd);
+      return;
+    }
+}
+
+void 
+PcapHelperForIpv4::EnablePcapIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface)
+{
+  EnablePcapIpv4Internal (prefix, ipv4, interface);
+}
+
+void 
+PcapHelperForIpv4::EnablePcapIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface)
+{
+  Ptr<Ipv4> ipv4 = Names::Find<Ipv4> (ipv4Name);
+  EnablePcapIpv4 (prefix, ipv4, interface);
+}
+
+void 
+PcapHelperForIpv4::EnablePcapIpv4 (std::string prefix, Ipv4InterfaceContainer c)
+{
+  for (Ipv4InterfaceContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      std::pair<Ptr<Ipv4>, uint32_t> pair = *i;
+      EnablePcapIpv4 (prefix, pair.first, pair.second);
+    }
+}
+
+void
+PcapHelperForIpv4::EnablePcapIpv4 (std::string prefix, NodeContainer n)
+{
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+      if (ipv4)
+        {
+          for (uint32_t j = 0; j < ipv4->GetNInterfaces (); ++j)
+            {
+              EnablePcapIpv4 (prefix, ipv4, j);
+            }
+        }
+    }
+}
+
+void
+PcapHelperForIpv4::EnablePcapIpv4All (std::string prefix)
+{
+  EnablePcapIpv4 (prefix, NodeContainer::GetGlobal ());
+}
+
+void 
+PcapHelperForIpv4::EnablePcapIpv4 (std::string prefix, uint32_t nodeid, uint32_t interface)
+{
+  NodeContainer n = NodeContainer::GetGlobal ();
+
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      if (node->GetId () != nodeid) 
+        {
+          continue;
+        }
+      
+      Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+      if (ipv4)
+        {
+          EnablePcapIpv4 (prefix, ipv4, interface);
+        }
+      return;
+    }
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv4::EnableAsciiIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface)
+{
+  EnableAsciiIpv4Internal (Ptr<OutputStreamWrapper> (), prefix, ipv4, interface);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv4::EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, Ptr<Ipv4> ipv4, uint32_t interface)
+{
+  EnableAsciiIpv4Internal (stream, std::string (), ipv4, interface);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv4::EnableAsciiIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface)
+{
+  EnableAsciiIpv4Impl (Ptr<OutputStreamWrapper> (), prefix, ipv4Name, interface);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv4::EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, std::string ipv4Name, uint32_t interface)
+{
+  EnableAsciiIpv4Impl (stream, std::string (), ipv4Name, interface);
+}
+
+//
+// Private API
+//
+void 
+AsciiTraceHelperForIpv4::EnableAsciiIpv4Impl (
+  Ptr<OutputStreamWrapper> stream, 
+  std::string prefix, 
+  std::string ipv4Name, 
+  uint32_t interface)
+{
+  Ptr<Ipv4> ipv4 = Names::Find<Ipv4> (ipv4Name);
+  EnableAsciiIpv4Internal (stream, prefix, ipv4, interface);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv4::EnableAsciiIpv4 (std::string prefix, Ipv4InterfaceContainer c)
+{
+  EnableAsciiIpv4Impl (Ptr<OutputStreamWrapper> (), prefix, c);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv4::EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, Ipv4InterfaceContainer c)
+{
+  EnableAsciiIpv4Impl (stream, std::string (), c);
+}
+
+//
+// Private API
+//
+void 
+AsciiTraceHelperForIpv4::EnableAsciiIpv4Impl (Ptr<OutputStreamWrapper> stream, std::string prefix, Ipv4InterfaceContainer c)
+{
+  for (Ipv4InterfaceContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      std::pair<Ptr<Ipv4>, uint32_t> pair = *i;
+      EnableAsciiIpv4Internal (stream, prefix, pair.first, pair.second);
+    }
+}
+
+//
+// Public API
+//
+void
+AsciiTraceHelperForIpv4::EnableAsciiIpv4 (std::string prefix, NodeContainer n)
+{
+  EnableAsciiIpv4Impl (Ptr<OutputStreamWrapper> (), prefix, n);
+}
+
+//
+// Public API
+//
+void
+AsciiTraceHelperForIpv4::EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, NodeContainer n)
+{
+  EnableAsciiIpv4Impl (stream, std::string (), n);
+}
+
+//
+// Private API
+//
+void
+AsciiTraceHelperForIpv4::EnableAsciiIpv4Impl (Ptr<OutputStreamWrapper> stream, std::string prefix, NodeContainer n)
+{
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+      if (ipv4)
+        {
+          for (uint32_t j = 0; j < ipv4->GetNInterfaces (); ++j)
+            {
+              EnableAsciiIpv4Internal (stream, prefix, ipv4, j);
+            }
+        }
+    }
+}
+
+//
+// Public API
+//
+void
+AsciiTraceHelperForIpv4::EnableAsciiIpv4All (std::string prefix)
+{
+  EnableAsciiIpv4Impl (Ptr<OutputStreamWrapper> (), prefix, NodeContainer::GetGlobal ());
+}
+
+//
+// Public API
+//
+void
+AsciiTraceHelperForIpv4::EnableAsciiIpv4All (Ptr<OutputStreamWrapper> stream)
+{
+  EnableAsciiIpv4Impl (stream, std::string (), NodeContainer::GetGlobal ());
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv4::EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, uint32_t nodeid, uint32_t interface)
+{
+  EnableAsciiIpv4Impl (stream, std::string (), nodeid, interface);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv4::EnableAsciiIpv4 (std::string prefix, uint32_t nodeid, uint32_t interface)
+{
+  EnableAsciiIpv4Impl (Ptr<OutputStreamWrapper> (), prefix, nodeid, interface);
+}
+
+//
+// Private API
+//
+void 
+AsciiTraceHelperForIpv4::EnableAsciiIpv4Impl (
+  Ptr<OutputStreamWrapper> stream, 
+  std::string prefix, 
+  uint32_t nodeid, 
+  uint32_t interface)
+{
+  NodeContainer n = NodeContainer::GetGlobal ();
+
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      if (node->GetId () != nodeid) 
+        {
+          continue;
+        }
+
+      Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+      if (ipv4)
+        {
+          EnableAsciiIpv4Internal (stream, prefix, ipv4, interface);
+        }
+
+      return;
+    }
+}
+
+void 
+PcapHelperForIpv6::EnablePcapIpv6 (std::string prefix, Ptr<Ipv6> ipv6, uint32_t interface)
+{
+  EnablePcapIpv6Internal (prefix, ipv6, interface);
+}
+
+void 
+PcapHelperForIpv6::EnablePcapIpv6 (std::string prefix, std::string ipv6Name, uint32_t interface)
+{
+  Ptr<Ipv6> ipv6 = Names::Find<Ipv6> (ipv6Name);
+  EnablePcapIpv6 (prefix, ipv6, interface);
+}
+
+void 
+PcapHelperForIpv6::EnablePcapIpv6 (std::string prefix, Ipv6InterfaceContainer c)
+{
+  for (Ipv6InterfaceContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      std::pair<Ptr<Ipv6>, uint32_t> pair = *i;
+      EnablePcapIpv6 (prefix, pair.first, pair.second);
+    }
+}
+
+void
+PcapHelperForIpv6::EnablePcapIpv6 (std::string prefix, NodeContainer n)
+{
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
+      if (ipv6)
+        {
+          for (uint32_t j = 0; j < ipv6->GetNInterfaces (); ++j)
+            {
+              EnablePcapIpv6 (prefix, ipv6, j);
+            }
+        }
+    }
+}
+
+void
+PcapHelperForIpv6::EnablePcapIpv6All (std::string prefix)
+{
+  EnablePcapIpv6 (prefix, NodeContainer::GetGlobal ());
+}
+
+void 
+PcapHelperForIpv6::EnablePcapIpv6 (std::string prefix, uint32_t nodeid, uint32_t interface)
+{
+  NodeContainer n = NodeContainer::GetGlobal ();
+
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      if (node->GetId () != nodeid) 
+        {
+          continue;
+        }
+      
+      Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
+      if (ipv6)
+        {
+          EnablePcapIpv6 (prefix, ipv6, interface);
+        }
+      return;
+    }
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv6::EnableAsciiIpv6 (std::string prefix, Ptr<Ipv6> ipv6, uint32_t interface)
+{
+  EnableAsciiIpv6Internal (Ptr<OutputStreamWrapper> (), prefix, ipv6, interface);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv6::EnableAsciiIpv6 (Ptr<OutputStreamWrapper> stream, Ptr<Ipv6> ipv6, uint32_t interface)
+{
+  EnableAsciiIpv6Internal (stream, std::string (), ipv6, interface);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv6::EnableAsciiIpv6 (std::string prefix, std::string ipv6Name, uint32_t interface)
+{
+  EnableAsciiIpv6Impl (Ptr<OutputStreamWrapper> (), prefix, ipv6Name, interface);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv6::EnableAsciiIpv6 (Ptr<OutputStreamWrapper> stream, std::string ipv6Name, uint32_t interface)
+{
+  EnableAsciiIpv6Impl (stream, std::string (), ipv6Name, interface);
+}
+
+//
+// Private API
+//
+void 
+AsciiTraceHelperForIpv6::EnableAsciiIpv6Impl (
+  Ptr<OutputStreamWrapper> stream, 
+  std::string prefix, 
+  std::string ipv6Name, 
+  uint32_t interface)
+{
+  Ptr<Ipv6> ipv6 = Names::Find<Ipv6> (ipv6Name);
+  EnableAsciiIpv6Internal (stream, prefix, ipv6, interface);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv6::EnableAsciiIpv6 (std::string prefix, Ipv6InterfaceContainer c)
+{
+  EnableAsciiIpv6Impl (Ptr<OutputStreamWrapper> (), prefix, c);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv6::EnableAsciiIpv6 (Ptr<OutputStreamWrapper> stream, Ipv6InterfaceContainer c)
+{
+  EnableAsciiIpv6Impl (stream, std::string (), c);
+}
+
+//
+// Private API
+//
+void 
+AsciiTraceHelperForIpv6::EnableAsciiIpv6Impl (Ptr<OutputStreamWrapper> stream, std::string prefix, Ipv6InterfaceContainer c)
+{
+  for (Ipv6InterfaceContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      std::pair<Ptr<Ipv6>, uint32_t> pair = *i;
+      EnableAsciiIpv6Internal (stream, prefix, pair.first, pair.second);
+    }
+}
+
+//
+// Public API
+//
+void
+AsciiTraceHelperForIpv6::EnableAsciiIpv6 (std::string prefix, NodeContainer n)
+{
+  EnableAsciiIpv6Impl (Ptr<OutputStreamWrapper> (), prefix, n);
+}
+
+//
+// Public API
+//
+void
+AsciiTraceHelperForIpv6::EnableAsciiIpv6 (Ptr<OutputStreamWrapper> stream, NodeContainer n)
+{
+  EnableAsciiIpv6Impl (stream, std::string (), n);
+}
+
+//
+// Private API
+//
+void
+AsciiTraceHelperForIpv6::EnableAsciiIpv6Impl (Ptr<OutputStreamWrapper> stream, std::string prefix, NodeContainer n)
+{
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
+      if (ipv6)
+        {
+          for (uint32_t j = 0; j < ipv6->GetNInterfaces (); ++j)
+            {
+              EnableAsciiIpv6Internal (stream, prefix, ipv6, j);
+            }
+        }
+    }
+}
+
+//
+// Public API
+//
+void
+AsciiTraceHelperForIpv6::EnableAsciiIpv6All (std::string prefix)
+{
+  EnableAsciiIpv6Impl (Ptr<OutputStreamWrapper> (), prefix, NodeContainer::GetGlobal ());
+}
+
+//
+// Public API
+//
+void
+AsciiTraceHelperForIpv6::EnableAsciiIpv6All (Ptr<OutputStreamWrapper> stream)
+{
+  EnableAsciiIpv6Impl (stream, std::string (), NodeContainer::GetGlobal ());
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv6::EnableAsciiIpv6 (Ptr<OutputStreamWrapper> stream, uint32_t nodeid, uint32_t interface)
+{
+  EnableAsciiIpv6Impl (stream, std::string (), nodeid, interface);
+}
+
+//
+// Public API
+//
+void 
+AsciiTraceHelperForIpv6::EnableAsciiIpv6 (std::string prefix, uint32_t nodeid, uint32_t interface)
+{
+  EnableAsciiIpv6Impl (Ptr<OutputStreamWrapper> (), prefix, nodeid, interface);
+}
+
+//
+// Private API
+//
+void 
+AsciiTraceHelperForIpv6::EnableAsciiIpv6Impl (
+  Ptr<OutputStreamWrapper> stream, 
+  std::string prefix, 
+  uint32_t nodeid, 
+  uint32_t interface)
+{
+  NodeContainer n = NodeContainer::GetGlobal ();
+
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      if (node->GetId () != nodeid) 
+        {
+          continue;
+        }
+
+      Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
+      if (ipv6)
+        {
+          EnableAsciiIpv6Internal (stream, prefix, ipv6, interface);
+        }
+
+      return;
+    }
+}
+
+} // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/trace-helper.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,1158 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 University of Washington
+ *
+ * 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
+ */
+
+#ifndef TRACE_HELPER_H
+#define TRACE_HELPER_H
+
+#include "ns3/assert.h"
+#include "ns3/net-device-container.h"
+#include "ns3/ipv4-interface-container.h"
+#include "ns3/ipv6-interface-container.h"
+#include "ns3/node-container.h"
+#include "ns3/simulator.h"
+#include "ns3/pcap-file-wrapper.h"
+#include "ns3/output-stream-wrapper.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv6.h"
+
+namespace ns3 {
+
+/**
+ * \brief Manage pcap files for device models
+ *
+ * Handling pcap files is a common operation for ns-3 devices.  It is useful to
+ * provide a common base class for dealing with these ops.
+ */
+
+class PcapHelper
+{
+public:
+  //
+  // These are the data link types that will be written to the pcap file.  We
+  // don't include pcap-bpf.h to avoid an explicit dependency on the real pcap
+  // and we don't make an enumeration of all of the values to make it easy to
+  // pass new values in.
+  //
+  enum {
+    DLT_NULL = 0,
+    DLT_EN10MB = 1,
+    DLT_PPP = 9,
+    DLT_RAW = 101,
+    DLT_IEEE802_11 = 105,
+    DLT_PRISM_HEADER = 119,
+    DLT_IEEE802_11_RADIO = 127
+  };
+
+  /**
+   * @brief Create a pcap helper.
+   */
+  PcapHelper ();
+
+  /**
+   * @brief Destroy a pcap helper.
+   */
+  ~PcapHelper ();
+
+  /**
+   * @brief Let the pcap helper figure out a reasonable filename to use for a
+   * pcap file associated with a device.
+   */
+  std::string GetFilenameFromDevice (std::string prefix, Ptr<NetDevice> device, bool useObjectNames = true);
+
+  /**
+   * @brief Let the pcap helper figure out a reasonable filename to use for the
+   * pcap file associated with a node.
+   */
+  std::string GetFilenameFromInterfacePair (std::string prefix, Ptr<Object> object, 
+                                            uint32_t interface, bool useObjectNames = true);
+
+  /**
+   * @brief Create and initialize a pcap file.
+   */
+  Ptr<PcapFileWrapper> CreateFile (std::string filename, std::string filemode,
+                                  uint32_t dataLinkType,  uint32_t snapLen = 65535, int32_t tzCorrection = 0);
+  /**
+   * @brief Hook a trace source to the default trace sink
+   */
+  template <typename T> void HookDefaultSink (Ptr<T> object, std::string traceName, Ptr<PcapFileWrapper> file);
+
+private:
+  static void DefaultSink (Ptr<PcapFileWrapper> file, Ptr<const Packet> p);
+};
+
+template <typename T> void
+PcapHelper::HookDefaultSink (Ptr<T> object, std::string tracename, Ptr<PcapFileWrapper> file)
+{
+  bool __attribute__ ((unused)) result = 
+    object->TraceConnectWithoutContext (tracename.c_str (), MakeBoundCallback (&DefaultSink, file));
+  NS_ASSERT_MSG (result == true, "PcapHelper::HookDefaultSink():  Unable to hook \"" << tracename << "\"");
+}
+
+/**
+ * \brief Manage ASCII trace files for device models
+ *
+ * Handling ascii trace files is a common operation for ns-3 devices.  It is 
+ * useful to provide a common base class for dealing with these ops.
+ */
+
+class AsciiTraceHelper
+{
+public:
+  /**
+   * @brief Create an ascii trace helper.
+   */
+  AsciiTraceHelper ();
+
+  /**
+   * @brief Destroy an ascii trace helper.
+   */
+  ~AsciiTraceHelper ();
+
+  /**
+   * @brief Let the ascii trace helper figure out a reasonable filename to use
+   * for an ascii trace file associated with a device.
+   */
+  std::string GetFilenameFromDevice (std::string prefix, Ptr<NetDevice> device, bool useObjectNames = true);
+
+  /**
+   * @brief Let the ascii trace helper figure out a reasonable filename to use
+   * for an ascii trace file associated with a node.
+   */
+  std::string GetFilenameFromInterfacePair (std::string prefix, Ptr<Object> object, 
+                                            uint32_t interface, bool useObjectNames = true);
+
+  /**
+   * @brief Create and initialize an output stream object we'll use to write the 
+   * traced bits.
+   *
+   * One of the common issues users run into when trying to use tracing in ns-3
+   * is actually a design decision made in the C++ stream library.  It is not 
+   * widely known that copy and assignment of iostreams is forbidden by 
+   * std::basic_ios<>.  This is because it is not possible to predict the 
+   * semantics of the stream desired by a user.
+   *
+   * The tempting ns-3 idiom when tracing to a file is to create a bound callback
+   * with an ofstream as the bound object.  Unfortunately, this implies a copy 
+   * construction in order to get the ofstream object into the callback.  This 
+   * operation, as mentioned above, is forbidden by the STL.  You could use a 
+   * global ostream and pass a pointer to it, but that is pretty ugly.  You 
+   * could create an ostream on the stack and pass a pointer to it, but you may
+   * run into object lifetime issues.  Ns-3 has a nice reference counted object
+   * that can solve the problem so we use one of those to carry the stream
+   * around and deal with the lifetime issues.
+   */
+  Ptr<OutputStreamWrapper> CreateFileStream (std::string filename, std::string filemode = "w");
+
+  /**
+   * @brief Hook a trace source to the default enqueue operation trace sink that
+   * does not accept nor log a trace context.
+   */
+  template <typename T> 
+  void HookDefaultEnqueueSinkWithoutContext (Ptr<T> object, std::string traceName, Ptr<OutputStreamWrapper> stream);
+
+  /**
+   * @brief Hook a trace source to the default enqueue operation trace sink that
+   * does accept and log a trace context.
+   */
+  template <typename T> 
+  void HookDefaultEnqueueSinkWithContext (Ptr<T> object, 
+                                          std::string context, std::string traceName, Ptr<OutputStreamWrapper> stream);
+
+  /**
+   * @brief Hook a trace source to the default drop operation trace sink that 
+   * does not accept nor log a trace context.
+   */
+  template <typename T> 
+  void HookDefaultDropSinkWithoutContext (Ptr<T> object, std::string traceName, Ptr<OutputStreamWrapper> stream);
+
+  /**
+   * @brief Hook a trace source to the default drop operation trace sink that 
+   * does accept and log a trace context.
+   */
+  template <typename T> 
+  void HookDefaultDropSinkWithContext (Ptr<T> object, 
+                                       std::string context, std::string traceName, Ptr<OutputStreamWrapper> stream);
+
+  /**
+   * @brief Hook a trace source to the default dequeue operation trace sink
+   * that does not accept nor log a trace context.
+   */
+  template <typename T> 
+  void HookDefaultDequeueSinkWithoutContext (Ptr<T> object, std::string traceName, Ptr<OutputStreamWrapper> stream);
+
+  /**
+   * @brief Hook a trace source to the default dequeue operation trace sink
+   * that does accept and log a trace context.
+   */
+  template <typename T> 
+  void HookDefaultDequeueSinkWithContext (Ptr<T> object, 
+                                          std::string context, std::string traceName, Ptr<OutputStreamWrapper> stream);
+
+  /**
+   * @brief Hook a trace source to the default receive operation trace sink
+   * that does not accept nor log a trace context.
+   */
+  template <typename T> 
+  void HookDefaultReceiveSinkWithoutContext (Ptr<T> object, std::string traceName, Ptr<OutputStreamWrapper> stream);
+
+  /**
+   * @brief Hook a trace source to the default receive operation trace sink
+   * that does accept and log a trace context.
+   */
+  template <typename T> 
+  void HookDefaultReceiveSinkWithContext (Ptr<T> object, 
+                                          std::string context, std::string traceName, Ptr<OutputStreamWrapper> stream);
+
+  static void DefaultEnqueueSinkWithoutContext (Ptr<OutputStreamWrapper> file, Ptr<const Packet> p);
+  static void DefaultEnqueueSinkWithContext (Ptr<OutputStreamWrapper> file, std::string context, Ptr<const Packet> p);
+
+  static void DefaultDropSinkWithoutContext (Ptr<OutputStreamWrapper> file, Ptr<const Packet> p);
+  static void DefaultDropSinkWithContext (Ptr<OutputStreamWrapper> file, std::string context, Ptr<const Packet> p);
+
+  static void DefaultDequeueSinkWithoutContext (Ptr<OutputStreamWrapper> file, Ptr<const Packet> p);
+  static void DefaultDequeueSinkWithContext (Ptr<OutputStreamWrapper> file, std::string context, Ptr<const Packet> p);
+
+  static void DefaultReceiveSinkWithoutContext (Ptr<OutputStreamWrapper> file, Ptr<const Packet> p);
+  static void DefaultReceiveSinkWithContext (Ptr<OutputStreamWrapper> file, std::string context, Ptr<const Packet> p);
+};
+
+template <typename T> void
+AsciiTraceHelper::HookDefaultEnqueueSinkWithoutContext (Ptr<T> object, std::string tracename, Ptr<OutputStreamWrapper> file)
+{
+  bool __attribute__ ((unused)) result = 
+    object->TraceConnectWithoutContext (tracename, MakeBoundCallback (&DefaultEnqueueSinkWithoutContext, file));
+  NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultEnqueueSinkWithoutContext():  Unable to hook \"" 
+                 << tracename << "\"");
+}
+
+template <typename T> void
+AsciiTraceHelper::HookDefaultEnqueueSinkWithContext (
+  Ptr<T> object, 
+  std::string context, 
+  std::string tracename, 
+  Ptr<OutputStreamWrapper> stream)
+{
+  bool __attribute__ ((unused)) result = 
+    object->TraceConnect (tracename, context, MakeBoundCallback (&DefaultEnqueueSinkWithContext, stream));
+  NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultEnqueueSinkWithContext():  Unable to hook \"" 
+                 << tracename << "\"");
+}
+
+template <typename T> void
+AsciiTraceHelper::HookDefaultDropSinkWithoutContext (Ptr<T> object, std::string tracename, Ptr<OutputStreamWrapper> file)
+{
+  bool __attribute__ ((unused)) result = 
+    object->TraceConnectWithoutContext (tracename, MakeBoundCallback (&DefaultDropSinkWithoutContext, file));
+  NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultDropSinkWithoutContext():  Unable to hook \"" 
+                 << tracename << "\"");
+}
+
+template <typename T> void
+AsciiTraceHelper::HookDefaultDropSinkWithContext (
+  Ptr<T> object, 
+  std::string context,
+  std::string tracename, 
+  Ptr<OutputStreamWrapper> stream)
+{
+  bool __attribute__ ((unused)) result = 
+    object->TraceConnect (tracename, context, MakeBoundCallback (&DefaultDropSinkWithContext, stream));
+  NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultDropSinkWithContext():  Unable to hook \"" 
+                 << tracename << "\"");
+}
+
+template <typename T> void
+AsciiTraceHelper::HookDefaultDequeueSinkWithoutContext (Ptr<T> object, std::string tracename, Ptr<OutputStreamWrapper> file)
+{
+  bool __attribute__ ((unused)) result = 
+    object->TraceConnectWithoutContext (tracename, MakeBoundCallback (&DefaultDequeueSinkWithoutContext, file));
+  NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultDequeueSinkWithoutContext():  Unable to hook \"" 
+                 << tracename << "\"");
+}
+
+template <typename T> void
+AsciiTraceHelper::HookDefaultDequeueSinkWithContext (
+  Ptr<T> object, 
+  std::string context,
+  std::string tracename, 
+  Ptr<OutputStreamWrapper> stream)
+{
+  bool __attribute__ ((unused)) result = 
+    object->TraceConnect (tracename, context, MakeBoundCallback (&DefaultDequeueSinkWithContext, stream));
+  NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultDequeueSinkWithContext():  Unable to hook \"" 
+                 << tracename << "\"");
+}
+
+template <typename T> void
+AsciiTraceHelper::HookDefaultReceiveSinkWithoutContext (Ptr<T> object, std::string tracename, Ptr<OutputStreamWrapper> file)
+{
+  bool __attribute__ ((unused)) result = 
+    object->TraceConnectWithoutContext (tracename, MakeBoundCallback (&DefaultReceiveSinkWithoutContext, file));
+  NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultReceiveSinkWithoutContext():  Unable to hook \"" 
+                 << tracename << "\"");
+}
+
+template <typename T> void
+AsciiTraceHelper::HookDefaultReceiveSinkWithContext (
+  Ptr<T> object, 
+  std::string context,
+  std::string tracename, 
+  Ptr<OutputStreamWrapper> stream)
+{
+  bool __attribute__ ((unused)) result = 
+    object->TraceConnect (tracename, context, MakeBoundCallback (&DefaultReceiveSinkWithContext, stream));
+  NS_ASSERT_MSG (result == true, "AsciiTraceHelper::HookDefaultReceiveSinkWithContext():  Unable to hook \"" 
+                 << tracename << "\"");
+}
+
+/**
+ * \brief Base class providing common user-level pcap operations for helpers
+ * representing net devices.
+ */
+class PcapHelperForDevice
+{
+public:
+  /**
+   * @brief Construct a PcapHelperForDevice
+   */
+  PcapHelperForDevice () {}
+
+  /**
+   * @brief Destroy a PcapHelperForDevice
+   */
+  virtual ~PcapHelperForDevice () {}
+
+  /**
+   * @brief Enable pcap output the indicated net device.
+   * @internal
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   * @param nd Net device for which you want to enable tracing.
+   * @param promiscuous If true capture all possible packets available at the device.
+   */
+  virtual void EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous) = 0;
+
+  /**
+   * @brief Enable pcap output the indicated net device.
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   * @param nd Net device for which you want to enable tracing.
+   * @param promiscuous If true capture all possible packets available at the device.
+   */
+  void EnablePcap (std::string prefix, Ptr<NetDevice> nd, bool promiscuous = false);
+
+  /**
+   * @brief Enable pcap output the indicated net device using a device previously
+   * named using the ns-3 object name service.
+   *
+   * @param filename filename prefix to use for pcap files.
+   * @param ndName The name of the net device in which you want to enable tracing.
+   * @param promiscuous If true capture all possible packets available at the device.
+   */
+  void EnablePcap (std::string prefix, std::string ndName, bool promiscuous = false);
+
+  /**
+   * @brief Enable pcap output on each device in the container which is of the 
+   * appropriate type.
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   * @param d container of devices of type ns3::CsmaNetDevice
+   * @param promiscuous If true capture all possible packets available at the device.
+   */
+  void EnablePcap (std::string prefix, NetDeviceContainer d, bool promiscuous = false);
+
+  /**
+   * @brief Enable pcap output on each device (which is of the appropriate type)
+   * in the nodes provided in the container.
+   *
+   * \param prefix Filename prefix to use for pcap files.
+   * \param n container of nodes.
+   * \param promiscuous If true capture all possible packets available at the device.
+   */
+  void EnablePcap (std::string prefix, NodeContainer n, bool promiscuous = false);
+
+  /**
+   * @brief Enable pcap output on the device specified by a global node-id (of
+   * a previously created node) and associated device-id.
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   * @param promiscuous If true capture all possible packets available at the device.
+   */
+  void EnablePcap (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool promiscuous = false);
+
+  /**
+   * @brief Enable pcap output on each device (which is of the appropriate type)
+   * in the set of all nodes created in the simulation.
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   * @param promiscuous If true capture all possible packets available at the device.
+   */
+  void EnablePcapAll (std::string prefix, bool promiscuous = false);
+};
+
+/**
+ * \brief Base class providing common user-level ascii trace operations for helpers
+ * representing net devices.
+ */
+class AsciiTraceHelperForDevice
+{
+public:
+  /**
+   * @brief Construct an AsciiTraceHelperForDevice.
+   */
+  AsciiTraceHelperForDevice () {}
+
+  /**
+   * @brief Destroy an AsciiTraceHelperForDevice.
+   */
+  virtual ~AsciiTraceHelperForDevice () {}
+
+  /**
+   * @brief Enable ascii trace output on the indicated net device.
+   * @internal
+   *
+   * The implementation is expected to use a provided Ptr<OutputStreamWrapper>
+   * if it is non-null.  If the OutputStreamWrapper is null, the implementation
+   * is expected to use a provided prefix to construct a new file name for
+   * each net device using the rules described in the class overview.
+   *
+   * If the prefix is provided, there will be one file per net device created.
+   * In this case, adding a trace context to the file would be pointless, so
+   * the device implementation is expected to TraceConnectWithoutContext.
+   *
+   * If the output stream object is provided, there may be many different 
+   * devices writing to a single file.  In this case, the device adding a 
+   * trace context could be important, so the device implementation is 
+   * expected to TraceConnect.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param prefix Filename prefix to use for ascii trace files.
+   * @param nd Net device for which you want to enable tracing.
+   */
+  virtual void EnableAsciiInternal (Ptr<OutputStreamWrapper> stream, std::string prefix, Ptr<NetDevice> nd) = 0;
+
+  /**
+   * @brief Enable ascii trace output on the indicated net device.
+   *
+   * @param prefix Filename prefix to use for ascii files.
+   * @param nd Net device for which you want to enable tracing.
+   */
+  void EnableAscii (std::string prefix, Ptr<NetDevice> nd);
+
+  /**
+   * @brief Enable ascii trace output on the indicated net device.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param nd Net device for which you want to enable tracing.
+   */
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, Ptr<NetDevice> nd);
+
+  /**
+   * @brief Enable ascii trace output the indicated net device using a device 
+   * previously named using the ns-3 object name service.
+   *
+   * @param filename filename prefix to use for ascii files.
+   * @param ndName The name of the net device in which you want to enable tracing.
+   */
+  void EnableAscii (std::string prefix, std::string ndName);
+
+  /**
+   * @brief Enable ascii trace output the indicated net device using a device 
+   * previously named using the ns-3 object name service.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param ndName The name of the net device in which you want to enable tracing.
+   */
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, std::string ndName);
+
+  /**
+   * @brief Enable ascii trace output on each device in the container which is
+   * of the appropriate type.
+   *
+   * @param prefix Filename prefix to use for ascii files.
+   * @param d container of devices of type ns3::CsmaNetDevice
+   */
+  void EnableAscii (std::string prefix, NetDeviceContainer d);
+
+  /**
+   * @brief Enable ascii trace output on each device in the container which is
+   * of the appropriate type.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param d container of devices of type ns3::CsmaNetDevice
+   */
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, NetDeviceContainer d);
+
+  /**
+   * @brief Enable ascii trace output on each device (which is of the 
+   * appropriate type) in the nodes provided in the container.
+   *
+   * \param prefix Filename prefix to use for ascii files.
+   * \param n container of nodes.
+   */
+  void EnableAscii (std::string prefix, NodeContainer n);
+
+  /**
+   * @brief Enable ascii trace output on each device (which is of the 
+   * appropriate type) in the nodes provided in the container.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * \param n container of nodes.
+   */
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, NodeContainer n);
+
+  /**
+   * @brief Enable ascii trace output on each device (which is of the
+   * appropriate type) in the set of all nodes created in the simulation.
+   *
+   * @param prefix Filename prefix to use for ascii files.
+   */
+  void EnableAsciiAll (std::string prefix);
+
+  /**
+   * @brief Enable ascii trace output on each device (which is of the
+   * appropriate type) in the set of all nodes created in the simulation.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   */
+  void EnableAsciiAll (Ptr<OutputStreamWrapper> stream);
+
+  /**
+   * @brief Enable ascii trace output on the device specified by a global 
+   * node-id (of a previously created node) and associated device-id.
+   *
+   * @param prefix Filename prefix to use when creating ascii trace files
+   * @param nodeid The node identifier/number of the node on which to enable
+   *               ascii tracing
+   * @param deviceid The device identifier/index of the device on which to enable
+   *               ascii tracing
+   */
+  void EnableAscii (std::string prefix, uint32_t nodeid, uint32_t deviceid);
+
+  /**
+   * @brief Enable ascii trace output on the device specified by a global 
+   * node-id (of a previously created node) and associated device-id.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param nodeid The node identifier/number of the node on which to enable
+   *               ascii tracing
+   * @param deviceid The device identifier/index of the device on which to enable
+   *               ascii tracing
+   */
+  void EnableAscii (Ptr<OutputStreamWrapper> stream, uint32_t nodeid, uint32_t deviceid);
+
+private:
+  /**
+   * @internal Avoid code duplication.
+   */
+  void EnableAsciiImpl (Ptr<OutputStreamWrapper> stream, std::string prefix, uint32_t nodeid, uint32_t deviceid);
+
+  /**
+   * @internal Avoid code duplication.
+   */
+  void EnableAsciiImpl (Ptr<OutputStreamWrapper> stream, std::string prefix, NodeContainer n);
+
+  /**
+   * @internal Avoid code duplication.
+   */
+  void EnableAsciiImpl (Ptr<OutputStreamWrapper> stream, std::string prefix, NetDeviceContainer d);
+
+  /**
+   * @internal Avoid code duplication.
+   */
+  void EnableAsciiImpl (Ptr<OutputStreamWrapper> stream, std::string prefix, std::string ndName);
+
+  /**
+   * @internal Avoid code duplication.
+   */
+  void EnableAsciiImpl (Ptr<OutputStreamWrapper> stream, std::string prefix, Ptr<NetDevice> nd);
+
+};
+
+/**
+ * @brief Base class providing common user-level pcap operations for helpers
+ * representing IPv4 protocols .
+ */
+class PcapHelperForIpv4
+{
+public:
+  /**
+   * @brief Construct a PcapHelperForIpv4.
+   */
+  PcapHelperForIpv4 () {}
+
+  /**
+   * @brief Destroy a PcapHelperForIpv4.
+   */
+  virtual ~PcapHelperForIpv4 () {}
+
+  /**
+   * @brief Enable pcap output the indicated Ipv4 and interface pair.
+   * @internal
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   * @param ipv4 Ptr<Ipv4> on which you want to enable tracing.
+   * @param interface Interface on ipv4 on which you want to enable tracing.
+   */
+  virtual void EnablePcapIpv4Internal (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface) = 0;
+
+  /**
+   * @brief Enable pcap output the indicated Ipv4 and interface pair.
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   * @param ipv4 Ptr<Ipv4> on which you want to enable tracing.
+   * @param interface Interface on ipv4 on which you want to enable tracing.
+   */
+  void EnablePcapIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface);
+
+  /**
+   * @brief Enable pcap output the indicated Ipv4 and interface pair using a
+   * Ptr<Ipv4> previously named using the ns-3 object name service.
+   *
+   * @param filename filename prefix to use for pcap files.
+   * @param ipv4Name Name of the Ptr<Ipv4> on which you want to enable tracing.
+   * @param interface Interface on ipv4 on which you want to enable tracing.
+   */
+  void EnablePcapIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface);
+
+  /**
+   * @brief Enable pcap output on each Ipv4 and interface pair in the container.
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   * @param c Ipv4InterfaceContainer of Ipv4 and interface pairs
+   */
+  void EnablePcapIpv4 (std::string prefix, Ipv4InterfaceContainer c);
+
+  /**
+   * @brief Enable pcap output on all Ipv4 and interface pairs existing in the
+   * nodes provided in the container.
+   *
+   * \param prefix Filename prefix to use for pcap files.
+   * \param n container of nodes.
+   */
+  void EnablePcapIpv4 (std::string prefix, NodeContainer n);
+
+  /**
+   * @brief Enable pcap output on the Ipv4 and interface pair specified by a 
+   * global node-id (of a previously created node) and interface.  Since there
+   * can be only one Ipv4 aggregated to a node, the node-id unambiguously 
+   * determines the Ipv4.
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   */
+  void EnablePcapIpv4 (std::string prefix, uint32_t nodeid, uint32_t interface);
+
+  /**
+   * @brief Enable pcap output on all Ipv4 and interface pairs existing in the 
+   * set of all nodes created in the simulation.
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   */
+  void EnablePcapIpv4All (std::string prefix);
+
+};
+
+/**
+ * @brief Base class providing common user-level ascii trace operations for 
+ * helpers representing IPv4 protocols .
+ */
+class AsciiTraceHelperForIpv4
+{
+public:
+  /**
+   * @brief Construct an AsciiTraceHelperForIpv4.
+   */
+  AsciiTraceHelperForIpv4 () {}
+
+  /**
+   * @brief Destroy an AsciiTraceHelperForIpv4
+   */
+  virtual ~AsciiTraceHelperForIpv4 () {}
+
+  /**
+   * @brief Enable ascii trace output on the indicated Ipv4 and interface pair.
+   * @internal
+   *
+   * The implementation is expected to use a provided Ptr<OutputStreamWrapper>
+   * if it is non-null.  If the OutputStreamWrapper is null, the implementation
+   * is expected to use a provided prefix to construct a new file name for
+   * each net device using the rules described in the class overview.
+   *
+   * If the prefix is provided, there will be one file per Ipv4 and interface pair
+   * created.  In this case, adding a trace context to the file would be pointless,
+   * so the helper implementation is expected to TraceConnectWithoutContext.
+   *
+   * If the output stream object is provided, there may be many different Ipv4 
+   * and interface pairs writing to a single file.  In this case, the trace 
+   * context could be important, so the helper implementation is expected to 
+   * TraceConnect.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param prefix Filename prefix to use for ascii trace files.
+   * @param ipv4 Ptr<Ipv4> on which you want to enable tracing.
+   * @param interface The interface on which you want to enable tracing.
+   */
+  virtual void EnableAsciiIpv4Internal (Ptr<OutputStreamWrapper> stream, std::string prefix, 
+                                    Ptr<Ipv4> ipv4, uint32_t interface) = 0;
+
+  /**
+   * @brief Enable ascii trace output on the indicated Ipv4 and interface pair.
+   *
+   * @param prefix Filename prefix to use for ascii files.
+   * @param ipv4 Ptr<Ipv4> on which you want to enable tracing.
+   * @param interface The interface on which you want to enable tracing.
+   */
+  void EnableAsciiIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface);
+
+  /**
+   * @brief Enable ascii trace output on the indicated Ipv4 and interface pair.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param ipv4 Ptr<Ipv4> on which you want to enable tracing.
+   * @param interface The interface on which you want to enable tracing.
+   */
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, Ptr<Ipv4> ipv4, uint32_t interface);
+
+  /**
+   * @brief Enable ascii trace output the indicated Ipv4 and interface pair
+   * using an Ipv4 previously named using the ns-3 object name service.
+   *
+   * @param filename filename prefix to use for ascii files.
+   * @param ipv4Name The name of the Ipv4 on which you want to enable tracing.
+   * @param interface The interface on which you want to enable tracing.
+   */
+  void EnableAsciiIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface);
+
+  /**
+   * @brief Enable ascii trace output the indicated net device using a device 
+   * previously named using the ns-3 object name service.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param ipv4Name The name of the Ipv4 on which you want to enable tracing.
+   * @param interface The interface on which you want to enable tracing.
+   */
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, std::string ipv4Name, uint32_t interface);
+
+  /**
+   * @brief Enable ascii trace output on each Ipv4 and interface pair in the 
+   * container
+   *
+   * @param prefix Filename prefix to use for ascii files.
+   * @param c Ipv4InterfaceContainer of Ipv4 and interface pairs on which to 
+   *          enable tracing.
+   */
+  void EnableAsciiIpv4 (std::string prefix, Ipv4InterfaceContainer c);
+
+  /**
+   * @brief Enable ascii trace output on each device in the container which is
+   * of the appropriate type.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param c Ipv4InterfaceContainer of Ipv4 and interface pairs on which to 
+   *          enable tracing.
+   */
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, Ipv4InterfaceContainer c);
+
+  /**
+   * @brief Enable ascii trace output on all Ipv4 and interface pairs existing
+   * in the nodes provided in the container.
+   *
+   * \param prefix Filename prefix to use for ascii files.
+   * \param n container of nodes.
+   */
+  void EnableAsciiIpv4 (std::string prefix, NodeContainer n);
+
+  /**
+   * @brief Enable ascii trace output on all Ipv4 and interface pairs existing
+   * in the nodes provided in the container.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * \param n container of nodes.
+   */
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, NodeContainer n);
+
+  /**
+   * @brief Enable ascii trace output on all Ipv4 and interface pairs existing
+   * in the set of all nodes created in the simulation.
+   *
+   * @param prefix Filename prefix to use for ascii files.
+   */
+  void EnableAsciiIpv4All (std::string prefix);
+
+  /**
+   * @brief Enable ascii trace output on each device (which is of the
+   * appropriate type) in the set of all nodes created in the simulation.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   */
+  void EnableAsciiIpv4All (Ptr<OutputStreamWrapper> stream);
+
+  /**
+   * @brief Enable pcap output on the Ipv4 and interface pair specified by a 
+   * global node-id (of a previously created node) and interface.  Since there
+   * can be only one Ipv4 aggregated to a node, the node-id unambiguously 
+   * determines the Ipv4.
+   *
+   * @param prefix Filename prefix to use when creating ascii trace files
+   * @param nodeid The node identifier/number of the node on which to enable
+   *               ascii tracing
+   * @param interface The device identifier/index of the device on which to enable
+   *               ascii tracing
+   */
+  void EnableAsciiIpv4 (std::string prefix, uint32_t nodeid, uint32_t deviceid);
+
+  /**
+   * @brief Enable pcap output on the Ipv4 and interface pair specified by a 
+   * global node-id (of a previously created node) and interface.  Since there
+   * can be only one Ipv4 aggregated to a node, the node-id unambiguously 
+   * determines the Ipv4.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param nodeid The node identifier/number of the node on which to enable
+   *               ascii tracing
+   * @param interface The interface on which you want to enable tracing.
+   */
+  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, uint32_t nodeid, uint32_t interface);
+
+private:
+  /**
+   * @internal Avoid code duplication.
+   */
+  void EnableAsciiIpv4Impl (Ptr<OutputStreamWrapper> stream, std::string prefix, uint32_t nodeid, uint32_t interface);
+
+  /**
+   * @internal Avoid code duplication.
+   */
+  void EnableAsciiIpv4Impl (Ptr<OutputStreamWrapper> stream, std::string prefix, NodeContainer n);
+
+  /**
+   * @internal Avoid code duplication.
+   */
+  void EnableAsciiIpv4Impl (Ptr<OutputStreamWrapper> stream, std::string prefix, Ipv4InterfaceContainer c);
+
+  /**
+   * @internal Avoid code duplication.
+   */
+  void EnableAsciiIpv4Impl (Ptr<OutputStreamWrapper> stream, std::string prefix, std::string ipv4Name, uint32_t interface);
+
+  /**
+   * @internal Avoid code duplication.
+   */
+  void EnableAsciiIpv4Impl (Ptr<OutputStreamWrapper> stream, std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface);
+
+};
+
+/**
+ * @brief Base class providing common user-level pcap operations for helpers
+ * representing IPv6 protocols .
+ */
+class PcapHelperForIpv6
+{
+public:
+  /**
+   * @brief Construct a PcapHelperForIpv6.
+   */
+  PcapHelperForIpv6 () {}
+
+  /**
+   * @brief Destroy a PcapHelperForIpv6
+   */
+  virtual ~PcapHelperForIpv6 () {}
+
+  /**
+   * @brief Enable pcap output the indicated Ipv6 and interface pair.
+   * @internal
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   * @param ipv6 Ptr<Ipv6> on which you want to enable tracing.
+   * @param interface Interface on ipv6 on which you want to enable tracing.
+   */
+  virtual void EnablePcapIpv6Internal (std::string prefix, Ptr<Ipv6> ipv6, uint32_t interface) = 0;
+
+  /**
+   * @brief Enable pcap output the indicated Ipv6 and interface pair.
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   * @param ipv6 Ptr<Ipv6> on which you want to enable tracing.
+   * @param interface Interface on ipv6 on which you want to enable tracing.
+   */
+  void EnablePcapIpv6 (std::string prefix, Ptr<Ipv6> ipv6, uint32_t interface);
+
+  /**
+   * @brief Enable pcap output the indicated Ipv6 and interface pair using a
+   * Ptr<Ipv6> previously named using the ns-3 object name service.
+   *
+   * @param filename filename prefix to use for pcap files.
+   * @param ipv6Name Name of the Ptr<Ipv6> on which you want to enable tracing.
+   * @param interface Interface on ipv6 on which you want to enable tracing.
+   */
+  void EnablePcapIpv6 (std::string prefix, std::string ipv6Name, uint32_t interface);
+
+  /**
+   * @brief Enable pcap output on each Ipv6 and interface pair in the container.
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   * @param c Ipv6InterfaceContainer of Ipv6 and interface pairs
+   */
+  void EnablePcapIpv6 (std::string prefix, Ipv6InterfaceContainer c);
+
+  /**
+   * @brief Enable pcap output on all Ipv6 and interface pairs existing in the
+   * nodes provided in the container.
+   *
+   * \param prefix Filename prefix to use for pcap files.
+   * \param n container of nodes.
+   */
+  void EnablePcapIpv6 (std::string prefix, NodeContainer n);
+
+  /**
+   * @brief Enable pcap output on the Ipv6 and interface pair specified by a 
+   * global node-id (of a previously created node) and interface.  Since there
+   * can be only one Ipv6 aggregated to a node, the node-id unambiguously 
+   * determines the Ipv6.
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   */
+  void EnablePcapIpv6 (std::string prefix, uint32_t nodeid, uint32_t interface);
+
+  /**
+   * @brief Enable pcap output on all Ipv6 and interface pairs existing in the 
+   * set of all nodes created in the simulation.
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   */
+  void EnablePcapIpv6All (std::string prefix);
+};
+
+/**
+ * @brief Base class providing common user-level ascii trace operations for
+ * helpers representing IPv6 protocols .
+ */
+class AsciiTraceHelperForIpv6
+{
+public:
+  /**
+   * @brief Construct an AsciiTraceHelperForIpv6.
+   */
+  AsciiTraceHelperForIpv6 () {}
+
+  /**
+   * @brief Destroy an AsciiTraceHelperForIpv6
+   */
+  virtual ~AsciiTraceHelperForIpv6 () {}
+
+  /**
+   * @brief Enable ascii trace output on the indicated Ipv6 and interface pair.
+   * @internal
+   *
+   * The implementation is expected to use a provided Ptr<OutputStreamWrapper>
+   * if it is non-null.  If the OutputStreamWrapper is null, the implementation
+   * is expected to use a provided prefix to construct a new file name for
+   * each net device using the rules described in the class overview.
+   *
+   * If the prefix is provided, there will be one file per Ipv6 and interface pair
+   * created.  In this case, adding a trace context to the file would be pointless,
+   * so the helper implementation is expected to TraceConnectWithoutContext.
+   *
+   * If the output stream object is provided, there may be many different Ipv6 
+   * and interface pairs writing to a single file.  In this case, the trace 
+   * context could be important, so the helper implementation is expected to 
+   * TraceConnect.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param prefix Filename prefix to use for ascii trace files.
+   * @param ipv6 Ptr<Ipv6> on which you want to enable tracing.
+   * @param interface The interface on which you want to enable tracing.
+   */
+  virtual void EnableAsciiIpv6Internal (Ptr<OutputStreamWrapper> stream, std::string prefix, 
+                                        Ptr<Ipv6> ipv6, uint32_t interface) = 0;
+
+  /**
+   * @brief Enable ascii trace output on the indicated Ipv6 and interface pair.
+   *
+   * @param prefix Filename prefix to use for ascii files.
+   * @param ipv6 Ptr<Ipv6> on which you want to enable tracing.
+   * @param interface The interface on which you want to enable tracing.
+   */
+  void EnableAsciiIpv6 (std::string prefix, 
+                        Ptr<Ipv6> ipv6, uint32_t interface);
+
+  /**
+   * @brief Enable ascii trace output on the indicated Ipv6 and interface pair.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param ipv6 Ptr<Ipv6> on which you want to enable tracing.
+   * @param interface The interface on which you want to enable tracing.
+   */
+  void EnableAsciiIpv6 (Ptr<OutputStreamWrapper> stream, 
+                        Ptr<Ipv6> ipv6, uint32_t interface);
+
+  /**
+   * @brief Enable ascii trace output the indicated Ipv6 and interface pair
+   * using an Ipv6 previously named using the ns-3 object name service.
+   *
+   * @param filename filename prefix to use for ascii files.
+   * @param ipv6Name The name of the Ipv6 on which you want to enable tracing.
+   * @param interface The interface on which you want to enable tracing.
+   */
+  void EnableAsciiIpv6 (std::string prefix, 
+                        std::string ipv6Name, uint32_t interface);
+
+  /**
+   * @brief Enable ascii trace output the indicated net device using a device 
+   * previously named using the ns-3 object name service.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param ipv6Name The name of the Ipv6 on which you want to enable tracing.
+   * @param interface The interface on which you want to enable tracing.
+   */
+  void EnableAsciiIpv6 (Ptr<OutputStreamWrapper> stream, 
+                        std::string ipv6Name, uint32_t interface);
+
+  /**
+   * @brief Enable ascii trace output on each Ipv6 and interface pair in the 
+   * container
+   *
+   * @param prefix Filename prefix to use for ascii files.
+   * @param c Ipv6InterfaceContainer of Ipv6 and interface pairs on which to 
+   *          enable tracing.
+   */
+  void EnableAsciiIpv6 (std::string prefix, Ipv6InterfaceContainer c);
+
+  /**
+   * @brief Enable ascii trace output on each device in the container which is
+   * of the appropriate type.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param c Ipv6InterfaceContainer of Ipv6 and interface pairs on which to 
+   *          enable tracing.
+   */
+  void EnableAsciiIpv6 (Ptr<OutputStreamWrapper> stream, Ipv6InterfaceContainer c);
+
+  /**
+   * @brief Enable ascii trace output on all Ipv6 and interface pairs existing
+   * in the nodes provided in the container.
+   *
+   * \param prefix Filename prefix to use for ascii files.
+   * \param n container of nodes.
+   */
+  void EnableAsciiIpv6 (std::string prefix, NodeContainer n);
+
+  /**
+   * @brief Enable ascii trace output on all Ipv6 and interface pairs existing
+   * in the nodes provided in the container.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * \param n container of nodes.
+   */
+  void EnableAsciiIpv6 (Ptr<OutputStreamWrapper> stream, NodeContainer n);
+
+  /**
+   * @brief Enable pcap output on the Ipv6 and interface pair specified by a 
+   * global node-id (of a previously created node) and interface.  Since there
+   * can be only one Ipv6 aggregated to a node, the node-id unambiguously 
+   * determines the Ipv6.
+   *
+   * @param prefix Filename prefix to use when creating ascii trace files
+   * @param nodeid The node identifier/number of the node on which to enable
+   *               ascii tracing
+   * @param interface The device identifier/index of the device on which to enable
+   *               ascii tracing
+   */
+  void EnableAsciiIpv6 (std::string prefix, uint32_t nodeid, uint32_t deviceid);
+
+  /**
+   * @brief Enable pcap output on the Ipv6 and interface pair specified by a 
+   * global node-id (of a previously created node) and interface.  Since there
+   * can be only one Ipv6 aggregated to a node, the node-id unambiguously 
+   * determines the Ipv6.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param nodeid The node identifier/number of the node on which to enable
+   *               ascii tracing
+   * @param interface The interface on which you want to enable tracing.
+   */
+  void EnableAsciiIpv6 (Ptr<OutputStreamWrapper> stream, uint32_t nodeid, uint32_t interface);
+
+  /**
+   * @brief Enable ascii trace output on all Ipv6 and interface pairs existing
+   * in the set of all nodes created in the simulation.
+   *
+   * @param prefix Filename prefix to use for ascii files.
+   */
+  void EnableAsciiIpv6All (std::string prefix);
+
+  /**
+   * @brief Enable ascii trace output on each device (which is of the
+   * appropriate type) in the set of all nodes created in the simulation.
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   */
+  void EnableAsciiIpv6All (Ptr<OutputStreamWrapper> stream);
+
+private:
+  /**
+   * @internal Avoid code duplication.
+   */
+  void EnableAsciiIpv6Impl (Ptr<OutputStreamWrapper> stream, std::string prefix, uint32_t nodeid, uint32_t interface);
+
+  /**
+   * @internal Avoid code duplication.
+   */
+  void EnableAsciiIpv6Impl (Ptr<OutputStreamWrapper> stream, std::string prefix, NodeContainer n);
+
+  /**
+   * @internal Avoid code duplication.
+   */
+  void EnableAsciiIpv6Impl (Ptr<OutputStreamWrapper> stream, std::string prefix, Ipv6InterfaceContainer c);
+
+  /**
+   * @internal Avoid code duplication.
+   */
+  void EnableAsciiIpv6Impl (Ptr<OutputStreamWrapper> stream, std::string prefix, std::string ipv6Name, uint32_t interface);
+
+  /**
+   * @internal Avoid code duplication.
+   */
+  void EnableAsciiIpv6Impl (Ptr<OutputStreamWrapper> stream, std::string prefix, Ptr<Ipv6> ipv6, uint32_t interface);
+
+};
+
+} // namespace ns3
+
+#endif /* TRACE_HELPER_H */
--- a/src/helper/wifi-helper.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/wifi-helper.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -30,7 +30,6 @@
 #include "ns3/propagation-loss-model.h"
 #include "ns3/mobility-model.h"
 #include "ns3/log.h"
-#include "ns3/pcap-writer.h"
 #include "ns3/config.h"
 #include "ns3/simulator.h"
 #include "ns3/names.h"
--- a/src/helper/wifi-helper.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/wifi-helper.h	Thu Feb 25 14:17:21 2010 +0100
@@ -28,6 +28,7 @@
 #include "ns3/node-container.h"
 #include "ns3/net-device-container.h"
 #include "ns3/wifi-phy-standard.h"
+#include "trace-helper.h"
 
 namespace ns3 {
 
@@ -46,6 +47,7 @@
 {
 public:
   virtual ~WifiPhyHelper ();
+
   /**
    * \param node the node on which the PHY object will reside
    * \param device the device within which the PHY object will reside
--- a/src/helper/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -48,6 +48,7 @@
         'point-to-point-star-helper.cc',
         'csma-star-helper.cc',
         'udp-client-server-helper.cc',
+        'trace-helper.cc',
         ]
 
     headers = bld.new_task_gen('ns3header')
@@ -99,6 +100,7 @@
         'point-to-point-star-helper.h',
         'csma-star-helper.h',
         'udp-client-server-helper.h',
+        'trace-helper.h',
         ]
 
     env = bld.env_of_name('default')
--- a/src/helper/yans-wifi-helper.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/yans-wifi-helper.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -17,6 +17,8 @@
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
+
+#include "trace-helper.h"
 #include "yans-wifi-helper.h"
 #include "ns3/error-rate-model.h"
 #include "ns3/propagation-loss-model.h"
@@ -24,45 +26,68 @@
 #include "ns3/yans-wifi-channel.h"
 #include "ns3/yans-wifi-phy.h"
 #include "ns3/wifi-net-device.h"
-#include "ns3/pcap-writer.h"
-#include "ns3/ascii-writer.h"
+#include "ns3/radiotap-header.h"
+#include "ns3/pcap-file-wrapper.h"
 #include "ns3/simulator.h"
 #include "ns3/config.h"
 #include "ns3/names.h"
+#include "ns3/abort.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("YansWifiHelper");
 
 namespace ns3 {
 
-static void PcapSniffTxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet, uint16_t channelFreqMhz,  uint16_t channelNumber, 
-                              uint32_t rate, bool isShortPreamble)
+static void 
+AsciiPhyTransmitSinkWithContext (
+  Ptr<OutputStreamWrapper> stream, 
+  std::string context, 
+  Ptr<const Packet> p,
+  WifiMode mode, 
+  WifiPreamble preamble,
+  uint8_t txLevel)
 {
-  const double unusedValue = 0;
-  writer->WriteWifiMonitorPacket(packet, channelFreqMhz, channelNumber, rate, isShortPreamble, true, unusedValue, unusedValue); 
+  NS_LOG_FUNCTION (stream << context << p << mode << preamble << txLevel);
+  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
 }
 
-
-static void PcapSniffRxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet, uint16_t channelFreqMhz,  uint16_t channelNumber,
-                              uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm)
+static void 
+AsciiPhyTransmitSinkWithoutContext (
+  Ptr<OutputStreamWrapper> stream, 
+  Ptr<const Packet> p,
+  WifiMode mode, 
+  WifiPreamble preamble,
+  uint8_t txLevel)
 {
-  writer->WriteWifiMonitorPacket(packet, channelFreqMhz, channelNumber, rate, isShortPreamble, false, signalDbm, noiseDbm); 
+  NS_LOG_FUNCTION (stream << p << mode << preamble << txLevel);
+  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
 }
 
-
-static void AsciiPhyTxEvent (Ptr<AsciiWriter> writer, std::string path,
-                             Ptr<const Packet> packet,
-                             WifiMode mode, WifiPreamble preamble,
-                             uint8_t txLevel)
+static void 
+AsciiPhyReceiveSinkWithContext (
+  Ptr<OutputStreamWrapper> stream,
+  std::string context,
+  Ptr<const Packet> p, 
+  double snr, 
+  WifiMode mode,
+  enum WifiPreamble preamble)
 {
-  writer->WritePacket (AsciiWriter::TX, path, packet);
+  NS_LOG_FUNCTION (stream << context << p << snr << mode << preamble);
+  *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
 }
 
-static void AsciiPhyRxOkEvent (Ptr<AsciiWriter> writer, std::string path,
-                               Ptr<const Packet> packet, double snr, WifiMode mode,
-                               enum WifiPreamble preamble)
+static void 
+AsciiPhyReceiveSinkWithoutContext (
+  Ptr<OutputStreamWrapper> stream,
+  Ptr<const Packet> p, 
+  double snr, 
+  WifiMode mode,
+  enum WifiPreamble preamble)
 {
-  writer->WritePacket (AsciiWriter::RX, path, packet);
+  NS_LOG_FUNCTION (stream << p << snr << mode << preamble);
+  *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
 }
 
-
 YansWifiChannelHelper::YansWifiChannelHelper ()
 {}
 
@@ -149,8 +174,7 @@
 
 YansWifiPhyHelper::YansWifiPhyHelper ()
   : m_channel (0),
-    m_pcapFormat(PCAP_FORMAT_80211)
-    
+    m_pcapDlt(PcapHelper::DLT_IEEE802_11)
 {
   m_phy.SetTypeId ("ns3::YansWifiPhy");
 }
@@ -215,136 +239,246 @@
   return phy;
 }
 
+static void 
+PcapSniffTxEvent (
+  Ptr<PcapFileWrapper> file,
+  Ptr<const Packet>   packet,
+  uint16_t            channelFreqMhz,
+  uint16_t            channelNumber,
+  uint32_t            rate,
+  bool                isShortPreamble)
+{
+  uint32_t dlt = file->GetDataLinkType ();
 
-void 
-YansWifiPhyHelper::SetPcapFormat (enum PcapFormat format)
-{
-  m_pcapFormat = format;
+  switch (dlt)
+    {
+    case PcapHelper::DLT_IEEE802_11:
+      file->Write (Simulator::Now (), packet);
+      return;
+    case PcapHelper::DLT_PRISM_HEADER:
+      {
+        NS_FATAL_ERROR ("PcapSniffTxEvent(): DLT_PRISM_HEADER not implemented");
+        return;
+      }
+    case PcapHelper::DLT_IEEE802_11_RADIO:
+      {
+        Ptr<Packet> p = packet->Copy ();
+        RadiotapHeader header;
+        header.SetTsft (Simulator::Now ().GetMicroSeconds ());
+
+        if (isShortPreamble)
+          {
+            header.SetFrameFlags (RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE);
+          }
+        else
+          {
+            header.SetFrameFlags (RadiotapHeader::FRAME_FLAG_NONE);
+          }
+
+        header.SetRate (rate);
+
+        if (channelFreqMhz < 2500)
+          {
+            header.SetChannelFrequencyAndFlags (channelFreqMhz, 
+              RadiotapHeader::CHANNEL_FLAG_SPECTRUM_2GHZ | RadiotapHeader::CHANNEL_FLAG_CCK);
+          }
+        else
+          {
+            header.SetChannelFrequencyAndFlags (channelFreqMhz, 
+              RadiotapHeader::CHANNEL_FLAG_SPECTRUM_5GHZ | RadiotapHeader::CHANNEL_FLAG_OFDM);
+          }
+
+        p->AddHeader (header);
+        file->Write (Simulator::Now (), p);
+        return;
+      }
+    default:
+      NS_ABORT_MSG ("PcapSniffTxEvent(): Unexpected data link type " << dlt);
+    }
 }
 
-
-void 
-YansWifiPhyHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
+static void 
+PcapSniffRxEvent (
+  Ptr<PcapFileWrapper> file,
+  Ptr<const Packet> packet,
+  uint16_t channelFreqMhz,
+  uint16_t channelNumber,
+  uint32_t rate,
+  bool isShortPreamble,
+  double signalDbm,
+  double noiseDbm)
 {
-  std::ostringstream oss;
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/";
-  Config::MatchContainer matches = Config::LookupMatches (oss.str ());
-  if (matches.GetN () == 0)
+  uint32_t dlt = file->GetDataLinkType ();
+
+  switch (dlt)
     {
+    case PcapHelper::DLT_IEEE802_11:
+      file->Write (Simulator::Now (), packet);
       return;
-    }
-  oss.str ("");
-  oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
-  Ptr<PcapWriter> pcap = CreateObject<PcapWriter> ();
-  pcap->Open (oss.str ());
+    case PcapHelper::DLT_PRISM_HEADER:
+      {
+        NS_FATAL_ERROR ("PcapSniffRxEvent(): DLT_PRISM_HEADER not implemented");
+        return;
+      }
+    case PcapHelper::DLT_IEEE802_11_RADIO:
+      {
+        Ptr<Packet> p = packet->Copy ();
+        RadiotapHeader header;
+        header.SetTsft (Simulator::Now ().GetMicroSeconds ());
 
-  switch (m_pcapFormat) {
-  case PCAP_FORMAT_80211:
-    pcap->WriteWifiHeader ();  
-    break;
-  case PCAP_FORMAT_80211_RADIOTAP:
-    pcap->WriteWifiRadiotapHeader ();  
-    break;
-  case PCAP_FORMAT_80211_PRISM:
-    pcap->WriteWifiPrismHeader ();  
-    break;
-  }
-  
-  oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
-  oss << "/$ns3::WifiNetDevice/Phy/PromiscSnifferTx";
-  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapSniffTxEvent, pcap));
+        if (isShortPreamble)
+          {
+            header.SetFrameFlags (RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE);
+          }
+        else
+          {
+            header.SetFrameFlags (RadiotapHeader::FRAME_FLAG_NONE);
+          }
+
+        header.SetRate (rate);
 
-  oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
-  oss << "/$ns3::WifiNetDevice/Phy/PromiscSnifferRx";
-  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapSniffRxEvent, pcap));  
-}
+        if (channelFreqMhz < 2500)
+          {
+            header.SetChannelFrequencyAndFlags (channelFreqMhz, 
+              RadiotapHeader::CHANNEL_FLAG_SPECTRUM_2GHZ | RadiotapHeader::CHANNEL_FLAG_CCK);
+          }
+        else
+          {
+            header.SetChannelFrequencyAndFlags (channelFreqMhz, 
+              RadiotapHeader::CHANNEL_FLAG_SPECTRUM_5GHZ | RadiotapHeader::CHANNEL_FLAG_OFDM);
+          }
 
-void 
-YansWifiPhyHelper::EnablePcap (std::string filename, NetDeviceContainer d)
-{
-  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
-    {
-      Ptr<NetDevice> dev = *i;
-      EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
+        header.SetAntennaSignalPower (signalDbm);
+        header.SetAntennaNoisePower (noiseDbm);
+
+        p->AddHeader (header);
+        file->Write (Simulator::Now (), p);
+        return;
+      }
+    default:
+      NS_ABORT_MSG ("PcapSniffRxEvent(): Unexpected data link type " << dlt);
     }
 }
 
 void 
-YansWifiPhyHelper::EnablePcap (std::string filename, Ptr<NetDevice> nd)
+YansWifiPhyHelper::SetPcapDataLinkType (enum SupportedPcapDataLinkTypes dlt)
 {
-  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ());
+  switch (dlt)
+    {
+    case DLT_IEEE802_11:
+      m_pcapDlt = PcapHelper::DLT_IEEE802_11;
+      return;
+    case DLT_PRISM_HEADER:
+      m_pcapDlt = PcapHelper::DLT_PRISM_HEADER;
+      return;
+    case DLT_IEEE802_11_RADIO:
+      m_pcapDlt = PcapHelper::DLT_IEEE802_11_RADIO;
+      return;
+    default:
+      NS_ABORT_MSG ("YansWifiPhyHelper::SetPcapFormat(): Unexpected format");
+    }
 }
 
 void 
-YansWifiPhyHelper::EnablePcap (std::string filename, std::string ndName)
+YansWifiPhyHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous)
 {
-  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
-  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ());
-}
-
-void
-YansWifiPhyHelper::EnablePcap (std::string filename, NodeContainer n)
-{
-  NetDeviceContainer devs;
-  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+  //
+  // All of the Pcap enable functions vector through here including the ones
+  // that are wandering through all of devices on perhaps all of the nodes in
+  // the system.  We can only deal with devices of type WifiNetDevice.
+  //
+  Ptr<WifiNetDevice> device = nd->GetObject<WifiNetDevice> ();
+  if (device == 0)
     {
-      Ptr<Node> node = *i;
-      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-        {
-          devs.Add (node->GetDevice (j));
-        }
+      NS_LOG_INFO ("YansWifiHelper::EnablePcapInternal(): Device " << &device << " not of type ns3::WifiNetDevice");
+      return;
     }
-  EnablePcap (filename, devs);
-}
+
+  Ptr<WifiPhy> phy = device->GetPhy ();
+  NS_ABORT_MSG_IF (phy == 0, "YansWifiPhyHelper::EnablePcapInternal(): Phy layer in WifiNetDevice must be set");
 
-void
-YansWifiPhyHelper::EnablePcapAll (std::string filename)
-{
-  EnablePcap (filename, NodeContainer::GetGlobal ());
+  PcapHelper pcapHelper;
+  std::string filename = pcapHelper.GetFilenameFromDevice (prefix, device);
+
+  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, "w", m_pcapDlt);
+
+  phy->TraceConnectWithoutContext ("PromiscSnifferTx", MakeBoundCallback (&PcapSniffTxEvent, file));
+  phy->TraceConnectWithoutContext ("PromiscSnifferRx", MakeBoundCallback (&PcapSniffRxEvent, file));
 }
 
 void 
-YansWifiPhyHelper::EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid)
+YansWifiPhyHelper::EnableAsciiInternal (Ptr<OutputStreamWrapper> stream, std::string prefix, Ptr<NetDevice> nd)
 {
-  Ptr<AsciiWriter> writer = AsciiWriter::Get (os);
+  //
+  // All of the ascii enable functions vector through here including the ones
+  // that are wandering through all of devices on perhaps all of the nodes in
+  // the system.  We can only deal with devices of type CsmaNetDevice.
+  //
+  Ptr<WifiNetDevice> device = nd->GetObject<WifiNetDevice> ();
+  if (device == 0)
+    {
+      NS_LOG_INFO ("YansWifiHelper::EnableAsciiInternal(): Device " << device << " not of type ns3::WifiNetDevice");
+      return;
+    }
+
+  //
+  // Our trace sinks are going to use packet printing, so we have to make sure
+  // that is turned on.
+  //
   Packet::EnablePrinting ();
+
+  uint32_t nodeid = nd->GetNode ()->GetId ();
+  uint32_t deviceid = nd->GetIfIndex ();
   std::ostringstream oss;
+
+  //
+  // If we are not provided an OutputStreamWrapper, we are expected to create 
+  // one using the usual trace filename conventions and write our traces 
+  // without a context since there will be one file per context and therefore
+  // the context would be redundant.
+  //
+  if (stream == 0)
+    {
+      //
+      // Set up an output stream object to deal with private ofstream copy 
+      // constructor and lifetime issues.  Let the helper decide the actual
+      // name of the file given the prefix.
+      //
+      AsciiTraceHelper asciiTraceHelper;
+      std::string filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
+      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename, "w");
+
+      //
+      // We could go poking through the phy and the state looking for the 
+      // correct trace source, but we can let Config deal with that with 
+      // some search cost.  Since this is presumably happening at topology
+      // creation time, it doesn't seem much of a price to pay.
+      //
+      oss.str ("");
+      oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/RxOk";
+      Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&AsciiPhyReceiveSinkWithoutContext, stream));
+
+      oss.str ("");
+      oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/Tx";
+      Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&AsciiPhyTransmitSinkWithoutContext, stream));
+
+      return;
+    }
+
+  //
+  // If we are provided an OutputStreamWrapper, we are expected to use it, and
+  // to provide a context.  We are free to come up with our own context if we
+  // want, and use the AsciiTraceHelper Hook*WithContext functions, but for 
+  // compatibility and simplicity, we just use Config::Connect and let it deal
+  // with coming up with a context.
+  //
+  oss.str ("");
   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/RxOk";
-  Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyRxOkEvent, writer));
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyReceiveSinkWithContext, stream));
+
   oss.str ("");
   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/Tx";
-  Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyTxEvent, writer));
-}
-void 
-YansWifiPhyHelper::EnableAscii (std::ostream &os, NetDeviceContainer d)
-{
-  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
-    {
-      Ptr<NetDevice> dev = *i;
-      EnableAscii (os, dev->GetNode ()->GetId (), dev->GetIfIndex ());
-    }
-}
-void
-YansWifiPhyHelper::EnableAscii (std::ostream &os, NodeContainer n)
-{
-  NetDeviceContainer devs;
-  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
-    {
-      Ptr<Node> node = *i;
-      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-        {
-          devs.Add (node->GetDevice (j));
-        }
-    }
-  EnableAscii (os, devs);
-}
-
-void
-YansWifiPhyHelper::EnableAsciiAll (std::ostream &os)
-{
-  EnableAscii (os, NodeContainer::GetGlobal ());
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyTransmitSinkWithContext, stream));
 }
 
 } // namespace ns3
--- a/src/helper/yans-wifi-helper.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/helper/yans-wifi-helper.h	Thu Feb 25 14:17:21 2010 +0100
@@ -21,7 +21,9 @@
 #define YANS_WIFI_HELPER_H
 
 #include "wifi-helper.h"
+#include "trace-helper.h"
 #include "ns3/yans-wifi-channel.h"
+#include "ns3/deprecated.h"
 
 namespace ns3 {
 
@@ -131,9 +133,11 @@
  * http://cutebugs.net/files/wns2-yans.pdf
  *
  * The Pcap and ascii traces generated by the EnableAscii and EnablePcap methods defined
- * in this class correspond to PHY-level traces. 
+ * in this class correspond to PHY-level traces and come to us via WifiPhyHelper
+ *
  */
-class YansWifiPhyHelper : public WifiPhyHelper
+class YansWifiPhyHelper : public WifiPhyHelper,
+                          public PcapHelperForDevice, public AsciiTraceHelperForDevice
 {
 public:
   /**
@@ -198,132 +202,26 @@
                           std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
 
   /**
-   * PCAP formats 
-   * 
+   * An enumeration of the pcap data link types (DLTs) which this helper 
+   * supports.  See http://wiki.wireshark.org/Development/LibpcapFileFormat
+   * for more information on these formats.
    */
-  enum PcapFormat {   
-    PCAP_FORMAT_80211          = 1,
-    PCAP_FORMAT_80211_PRISM    = 2,
-    PCAP_FORMAT_80211_RADIOTAP = 3,
+  enum SupportedPcapDataLinkTypes {
+    DLT_IEEE802_11       = PcapHelper::DLT_IEEE802_11,       /**< IEEE 802.11 Wireless LAN headers on packets */
+    DLT_PRISM_HEADER     = PcapHelper::DLT_PRISM_HEADER,     /**< Include Prism monitor mode information */
+    DLT_IEEE802_11_RADIO = PcapHelper::DLT_IEEE802_11_RADIO  /**< Include Radiotap link layer information */
   };
-  
-  /** 
-   * Set the format of PCAP traces to be used. This function has to be
-   * called before EnablePcap(), so that the header of the pcap file
-   * can be written correctly.
-   *
-   * In madwifi, this corresponds to setting
-   * /proc/sys/net/ath0/dev_type to a particular value. See
-   * http://madwifi-project.org/wiki/UserDocs/MonitorModeInterface for
-   * more information.
-   * 
-   * @param format the PcapFormat to be used
-   */
-  void SetPcapFormat (enum PcapFormat format);
 
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param nodeid the id of the node to generate pcap output for.
-   * \param deviceid the id of the device to generate pcap output for.
-   *
-   * Generate a pcap file which contains the link-level data observed
-   * by the specified deviceid within the specified nodeid. The pcap
-   * data is stored in the file prefix-nodeid-deviceid.pcap. By
-   * default, no PHY layer information is provided. An optional header
-   * with PHY layer information, such as the radiotap or the prism
-   * header, can be used by invoking SetPcapFormat().
-   *
-   * This method should be invoked after the network topology has 
-   * been fully constructed.
-   */
-  void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param nd Net device on which you want to enable tracing.
-   *
-   * Enable pcap output on each input device which is of the
-   * ns3::WifiNetDevice type.
-   */
-   void EnablePcap (std::string filename, Ptr<NetDevice> nd);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param ndName Name of net device on which you want to enable tracing.
-   *
-   * Enable pcap output on each input device which is of the
-   * ns3::WifiNetDevice type.
-   */
-   void EnablePcap (std::string filename, std::string ndName);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param d container of devices of type ns3::WifiNetDevice
+  /** 
+   * Set the data link type of PCAP traces to be used. This function has to be
+   * called before EnablePcap(), so that the header of the pcap file can be 
+   * written correctly.
    *
-   * Enable pcap output on each input device which is of the
-   * ns3::WifiNetDevice type.
-   */
-   void EnablePcap (std::string filename, NetDeviceContainer d);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param n container of nodes.
+   * @see SupportedPcapDataLinkTypes
    *
-   * Enable pcap output on each device which is of the
-   * ns3::WifiNetDevice type and which is located in one of the 
-   * input nodes.
-   */
-   void EnablePcap (std::string filename, NodeContainer n);
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   *
-   * Enable pcap output on each device which is of the
-   * ns3::WifiNetDevice type
-   */
-   void EnablePcapAll (std::string filename);
-
-  /**
-   * \param os output stream
-   * \param nodeid the id of the node to generate ascii output for.
-   * \param deviceid the id of the device to generate ascii output for.
-   *
-   * Enable ascii output on the specified deviceid within the
-   * specified nodeid if it is of type ns3::WifiNetDevice and dump 
-   * that to the specified stdc++ output stream.
+   * @param dlt The data link type of the pcap file (and packets) to be used
    */
-  static void EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid);
-
-  /**
-   * \param os output stream
-   * \param d device container
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::WifiNetDevice type and which is located in the input
-   * device container and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, NetDeviceContainer d);
-
-  /**
-   * \param os output stream
-   * \param n node container
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::WifiNetDevice type and which is located in one
-   * of the input node and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, NodeContainer n);
-
-  /**
-   * \param os output stream
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::WifiNetDevice type and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAsciiAll (std::ostream &os);
+  void SetPcapDataLinkType (enum SupportedPcapDataLinkTypes dlt); 
 
 private:
   /**
@@ -335,10 +233,35 @@
    */
   virtual Ptr<WifiPhy> Create (Ptr<Node> node, Ptr<WifiNetDevice> device) const;
 
+  /**
+   * @brief Enable pcap output the indicated net device.
+   *
+   * NetDevice-specific implementation mechanism for hooking the trace and
+   * writing to the trace file.
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   * @param nd Net device for which you want to enable tracing.
+   * @param promiscuous If true capture all possible packets available at the device.
+   */
+  virtual void EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous);
+
+  /**
+   * \brief Enable ascii trace output on the indicated net device.
+   * \internal
+   *
+   * NetDevice-specific implementation mechanism for hooking the trace and
+   * writing to the trace file.
+   *
+   * \param stream The output stream object to use when logging ascii traces.
+   * \param prefix Filename prefix to use for ascii trace files.
+   * \param nd Net device for which you want to enable tracing.
+   */
+  virtual void EnableAsciiInternal (Ptr<OutputStreamWrapper> stream, std::string prefix, Ptr<NetDevice> nd);
+
   ObjectFactory m_phy;
   ObjectFactory m_errorRateModel;
   Ptr<YansWifiChannel> m_channel;
-  enum PcapFormat m_pcapFormat;
+  uint32_t m_pcapDlt;
 };
 
 } // namespace ns3
--- a/src/internet-stack/ipv4-end-point.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/ipv4-end-point.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -89,7 +89,7 @@
 }
 
 void 
-Ipv4EndPoint::SetRxCallback (Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> callback)
+Ipv4EndPoint::SetRxCallback (Callback<void,Ptr<Packet>, Ipv4Address, Ipv4Address, uint16_t> callback)
 {
   m_rxCallback = callback;
 }
@@ -106,17 +106,17 @@
 }
 
 void 
-Ipv4EndPoint::ForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport)
+Ipv4EndPoint::ForwardUp (Ptr<Packet> p, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport)
 {
   if (!m_rxCallback.IsNull ())
     {
-      Simulator::ScheduleNow (&Ipv4EndPoint::DoForwardUp, this, p, saddr, sport);
+      Simulator::ScheduleNow (&Ipv4EndPoint::DoForwardUp, this, p, saddr, daddr, sport);
     }
 }
 void 
-Ipv4EndPoint::DoForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport)
+Ipv4EndPoint::DoForwardUp (Ptr<Packet> p, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport)
 {
-  m_rxCallback (p, saddr, sport);
+  m_rxCallback (p, saddr, daddr, sport);
 }
 
 void 
--- a/src/internet-stack/ipv4-end-point.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/ipv4-end-point.h	Thu Feb 25 14:17:21 2010 +0100
@@ -59,13 +59,13 @@
   Ptr<NetDevice> GetBoundNetDevice (void);
 
   // Called from socket implementations to get notified about important events.
-  void SetRxCallback (Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> callback);
+  void SetRxCallback (Callback<void,Ptr<Packet>, Ipv4Address, Ipv4Address, uint16_t> callback);
   void SetIcmpCallback (Callback<void,Ipv4Address,uint8_t,uint8_t,uint8_t,uint32_t> callback);
   void SetDestroyCallback (Callback<void> callback);
 
   // Called from an L4Protocol implementation to notify an endpoint of a
   // packet reception.
-  void ForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport);
+  void ForwardUp (Ptr<Packet> p, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport);
   // Called from an L4Protocol implementation to notify an endpoint of
   // an icmp message reception.
   void ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, 
@@ -73,7 +73,7 @@
                     uint32_t icmpInfo);
 
 private:
-  void DoForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport);
+  void DoForwardUp (Ptr<Packet> p, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport);
   void DoForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, 
                       uint8_t icmpType, uint8_t icmpCode,
                       uint32_t icmpInfo);
@@ -82,7 +82,7 @@
   Ipv4Address m_peerAddr;
   uint16_t m_peerPort;
   Ptr<NetDevice> m_boundnetdevice;
-  Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> m_rxCallback;
+  Callback<void,Ptr<Packet>, Ipv4Address, Ipv4Address, uint16_t> m_rxCallback;
   Callback<void,Ipv4Address,uint8_t,uint8_t,uint8_t,uint32_t> m_icmpCallback;
   Callback<void> m_destroyCallback;
 };
--- a/src/internet-stack/ipv4-l3-protocol.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/ipv4-l3-protocol.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -196,6 +196,7 @@
       *i = 0;
     }
   m_interfaces.clear ();
+  m_sockets.clear ();
   m_node = 0;
   m_routingProtocol = 0;
   Object::DoDispose ();
@@ -441,15 +442,15 @@
         {
           if (ipv4Interface->IsUp ())
             {
-              m_rxTrace (packet, interface);
+              m_rxTrace (packet, m_node->GetObject<Ipv4> (), interface);
               break;
             }
           else
             {
-              NS_LOG_LOGIC ("Dropping received packet-- interface is down");
+              NS_LOG_LOGIC ("Dropping received packet -- interface is down");
               Ipv4Header ipHeader;
               packet->RemoveHeader (ipHeader);
-              m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, interface);
+              m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv4> (), interface);
               return;
             }
         }
@@ -462,9 +463,16 @@
     }
   packet->RemoveHeader (ipHeader);
 
+  // Trim any residual frame padding from underlying devices
+  if (ipHeader.GetPayloadSize () < packet->GetSize ())
+    {
+      packet->RemoveAtEnd (packet->GetSize () - ipHeader.GetPayloadSize ());
+    }
+
   if (!ipHeader.IsChecksumOk ()) 
     {
-      m_dropTrace (ipHeader, packet, DROP_BAD_CHECKSUM, interface);
+      NS_LOG_LOGIC ("Dropping received packet -- checksum not ok");
+      m_dropTrace (ipHeader, packet, DROP_BAD_CHECKSUM, m_node->GetObject<Ipv4> (), interface);
       return;
     }
 
@@ -475,6 +483,7 @@
       socket->ForwardUp (packet, ipHeader, device);
     }
 
+  NS_ASSERT_MSG (m_routingProtocol != 0, "Need a routing protocol object to process packets");
   m_routingProtocol->RouteInput (packet, ipHeader, device, 
     MakeCallback (&Ipv4L3Protocol::IpForward, this),
     MakeCallback (&Ipv4L3Protocol::IpMulticastForward, this),
@@ -546,7 +555,7 @@
 
           m_sendOutgoingTrace (ipHeader, packetCopy, ifaceIndex);
           packetCopy->AddHeader (ipHeader);
-          m_txTrace (packetCopy, ifaceIndex);
+          m_txTrace (packetCopy, m_node->GetObject<Ipv4> (), ifaceIndex);
           outInterface->Send (packetCopy, destination);
         }
       return;
@@ -570,7 +579,7 @@
               Ptr<Packet> packetCopy = packet->Copy ();
               m_sendOutgoingTrace (ipHeader, packetCopy, ifaceIndex);
               packetCopy->AddHeader (ipHeader);
-              m_txTrace (packetCopy, ifaceIndex);
+              m_txTrace (packetCopy, m_node->GetObject<Ipv4> (), ifaceIndex);
               outInterface->Send (packetCopy, destination);
               return;
             }
@@ -602,7 +611,15 @@
   Socket::SocketErrno errno_; 
   Ptr<NetDevice> oif (0); // unused for now
   ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, mayFragment);
-  Ptr<Ipv4Route> newRoute = m_routingProtocol->RouteOutput (packet, ipHeader, oif, errno_);
+  Ptr<Ipv4Route> newRoute;
+  if (m_routingProtocol != 0)
+    {
+      newRoute = m_routingProtocol->RouteOutput (packet, ipHeader, oif, errno_);
+    }
+  else
+    {
+      NS_LOG_ERROR ("Ipv4L3Protocol::Send: m_routingProtocol == 0");
+    }
   if (newRoute)
     {
       int32_t interface = GetInterfaceForDevice (newRoute->GetOutputDevice ());
@@ -612,7 +629,7 @@
   else
     {
       NS_LOG_WARN ("No route to host.  Drop.");
-      m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, 0);
+      m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, m_node->GetObject<Ipv4> (), 0);
     }
 }
 
@@ -665,7 +682,7 @@
   if (route == 0)
     {
       NS_LOG_WARN ("No route to host.  Drop.");
-      m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, 0);
+      m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, m_node->GetObject<Ipv4> (), 0);
       return;
     }
   packet->AddHeader (ipHeader);
@@ -681,15 +698,15 @@
       if (outInterface->IsUp ())
         {
           NS_LOG_LOGIC ("Send to gateway " << route->GetGateway ());
-          m_txTrace (packet, interface);
+          m_txTrace (packet, m_node->GetObject<Ipv4> (), interface);
           outInterface->Send (packet, route->GetGateway ());
         }
       else
         {
-          NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << route->GetGateway ());
+          NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << route->GetGateway ());
           Ipv4Header ipHeader;
           packet->RemoveHeader (ipHeader);
-          m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, interface);
+          m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv4> (), interface);
         }
     } 
   else 
@@ -697,15 +714,15 @@
       if (outInterface->IsUp ())
         {
           NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestination ());
-          m_txTrace (packet, interface);
+          m_txTrace (packet, m_node->GetObject<Ipv4> (), interface);
           outInterface->Send (packet, ipHeader.GetDestination ());
         }
       else
         {
-          NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << ipHeader.GetDestination ());
+          NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << ipHeader.GetDestination ());
           Ipv4Header ipHeader;
           packet->RemoveHeader (ipHeader);
-          m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, interface);
+          m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv4> (), interface);
         }
     }
 }
@@ -728,7 +745,7 @@
           if (h.GetTtl () == 0)
             {
               NS_LOG_WARN ("TTL exceeded.  Drop.");
-              m_dropTrace (header, packet, DROP_TTL_EXPIRED, i);
+              m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv4> (), i);
               return;
             }
           NS_LOG_LOGIC ("Forward multicast via interface " << i);
@@ -765,7 +782,7 @@
           icmp->SendTimeExceededTtl (ipHeader, packet);
         }
       NS_LOG_WARN ("TTL exceeded.  Drop.");
-      m_dropTrace (header, packet, DROP_TTL_EXPIRED, interface);
+      m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv4> (), interface);
       return;
     }
   m_unicastForwardTrace (ipHeader, packet, interface);
@@ -1035,8 +1052,7 @@
 {
   NS_LOG_FUNCTION (this << p << ipHeader << sockErrno);
   NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno); 
-  m_dropTrace (ipHeader, p, DROP_ROUTE_ERROR, 0);
+  m_dropTrace (ipHeader, p, DROP_ROUTE_ERROR, m_node->GetObject<Ipv4> (), 0);
 }
 
-
 }//namespace ns3
--- a/src/internet-stack/ipv4-l3-protocol.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/ipv4-l3-protocol.h	Thu Feb 25 14:17:21 2010 +0100
@@ -258,10 +258,10 @@
   TracedCallback<const Ipv4Header &, Ptr<const Packet>, uint32_t> m_localDeliverTrace;
 
   // The following two traces pass a packet with an IP header
-  TracedCallback<Ptr<const Packet>, uint32_t> m_txTrace;
-  TracedCallback<Ptr<const Packet>, uint32_t> m_rxTrace;
+  TracedCallback<Ptr<const Packet>, Ptr<Ipv4>,  uint32_t> m_txTrace;
+  TracedCallback<Ptr<const Packet>, Ptr<Ipv4>, uint32_t> m_rxTrace;
   // <ip-header, payload, reason, ifindex> (ifindex not valid if reason is DROP_NO_ROUTE)
-  TracedCallback<const Ipv4Header &, Ptr<const Packet>, DropReason, uint32_t> m_dropTrace;
+  TracedCallback<const Ipv4Header &, Ptr<const Packet>, DropReason, Ptr<Ipv4>, uint32_t> m_dropTrace;
 
   Ptr<Ipv4RoutingProtocol> m_routingProtocol;
 
--- a/src/internet-stack/ipv4-test.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/ipv4-test.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -94,7 +94,7 @@
   Ipv4InterfaceAddress output = interface->GetAddress (2);
   NS_TEST_ASSERT_MSG_EQ (ifaceAddr4, output,
       "The addresses should be identical");
-
+  Simulator::Destroy ();
   return false;
 }
 
--- a/src/internet-stack/ipv6-l3-protocol.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/ipv6-l3-protocol.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -695,6 +695,12 @@
   Ipv6Header hdr;
   packet->RemoveHeader (hdr);
 
+  // Trim any residual frame padding from underlying devices
+  if (hdr.GetPayloadLength () < packet->GetSize ())
+    {
+      packet->RemoveAtEnd (packet->GetSize () - hdr.GetPayloadLength ());
+    }
+
   /* forward up to IPv6 raw sockets */
   for (SocketList::iterator it = m_sockets.begin () ; it != m_sockets.end () ; ++it)
     {
--- a/src/internet-stack/ipv6-test.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/ipv6-test.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -135,7 +135,7 @@
 
   index = ipv6->GetInterfaceForAddress ("2001:ffff:5678:9000::1"); /* address we just remove */
   NS_TEST_ASSERT_MSG_EQ (index, (uint32_t) -1, "Address should not be found??");
-
+  Simulator::Destroy ();
   return false;
 }//end DoRun
 static class IPv6L3ProtocolTestSuite : public TestSuite
--- a/src/internet-stack/nsc-tcp-l4-protocol.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/nsc-tcp-l4-protocol.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -382,7 +382,7 @@
   for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
        endPoint != endPoints.end (); endPoint++) {
           // NSC HACK: (ab)use TcpSocket::ForwardUp for signalling
-          (*endPoint)->ForwardUp (NULL, Ipv4Address(), 0);
+          (*endPoint)->ForwardUp (NULL, Ipv4Address(), Ipv4Address(), 0);
   }
 }
 
--- a/src/internet-stack/nsc-tcp-socket-impl.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/nsc-tcp-socket-impl.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -465,7 +465,7 @@
 }
 
 void
-NscTcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
+NscTcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address saddr, Ipv4Address daddr, uint16_t port)
 {
   NSCWakeup();
 }
--- a/src/internet-stack/nsc-tcp-socket-impl.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/nsc-tcp-socket-impl.h	Thu Feb 25 14:17:21 2010 +0100
@@ -88,7 +88,7 @@
   friend class Tcp;
   // invoked by Tcp class
   int FinishBind (void);
-  void ForwardUp (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port);
+  void ForwardUp (Ptr<Packet> p, Ipv4Address saddr, Ipv4Address daddr, uint16_t port);
   void Destroy (void);
   //methods for state
   bool SendPendingData(void);
--- a/src/internet-stack/tcp-l4-protocol.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/tcp-l4-protocol.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -546,7 +546,7 @@
   }
   NS_ASSERT_MSG (endPoints.size() == 1 , "Demux returned more than one endpoint");
   NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
-  (*endPoints.begin ())->ForwardUp (packet, source, tcpHeader.GetSourcePort ());
+  (*endPoints.begin ())->ForwardUp (packet, source, destination, tcpHeader.GetSourcePort ());
   return Ipv4L4Protocol::RX_OK;
 }
 
@@ -584,7 +584,15 @@
       Socket::SocketErrno errno_;
       Ptr<Ipv4Route> route;
       Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
-      route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
+      if (ipv4->GetRoutingProtocol () != 0)
+        {
+          route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
+        }
+      else
+        {
+          NS_LOG_ERROR ("No IPV4 Routing Protocol");
+          route = 0;
+        }
       ipv4->Send (packet, saddr, daddr, PROT_NUMBER, route);
     }
 }
@@ -623,7 +631,15 @@
       header.SetProtocol (PROT_NUMBER);
       Socket::SocketErrno errno_;
       Ptr<Ipv4Route> route;
-      route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
+      if (ipv4->GetRoutingProtocol () != 0)
+        {
+          route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
+        }
+      else
+        {
+          NS_LOG_ERROR ("No IPV4 Routing Protocol");
+          route = 0;
+        }
       ipv4->Send (packet, saddr, daddr, PROT_NUMBER, route);
     }
   else
--- a/src/internet-stack/tcp-l4-protocol.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/tcp-l4-protocol.h	Thu Feb 25 14:17:21 2010 +0100
@@ -90,6 +90,7 @@
    * \param daddr The destination Ipv4Address
    * \param sport The source port number
    * \param dport The destination port number
+   * \param oif The output interface bound. Defaults to null (unspecified).
    */
   void Send (Ptr<Packet> packet,
              Ipv4Address saddr, Ipv4Address daddr, 
--- a/src/internet-stack/tcp-socket-impl.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/tcp-socket-impl.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -70,8 +70,6 @@
     m_endPoint (0),
     m_node (0),
     m_tcp (0),
-    m_localAddress (Ipv4Address::GetZero ()),
-    m_localPort (0),
     m_errno (ERROR_NOTERROR),
     m_shutdownSend (false),
     m_shutdownRecv (false),
@@ -109,10 +107,6 @@
     m_endPoint (0),
     m_node (sock.m_node),
     m_tcp (sock.m_tcp),
-    m_remoteAddress (sock.m_remoteAddress),
-    m_remotePort (sock.m_remotePort),
-    m_localAddress (sock.m_localAddress),
-    m_localPort (sock.m_localPort),
     m_errno (sock.m_errno),
     m_shutdownSend (sock.m_shutdownSend),
     m_shutdownRecv (sock.m_shutdownRecv),
@@ -266,8 +260,6 @@
     }
   m_endPoint->SetRxCallback (MakeCallback (&TcpSocketImpl::ForwardUp, Ptr<TcpSocketImpl>(this)));
   m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketImpl::Destroy, Ptr<TcpSocketImpl>(this)));
-  m_localAddress = m_endPoint->GetLocalAddress ();
-  m_localPort = m_endPoint->GetLocalPort ();
   return 0;
 }
 
@@ -366,6 +358,7 @@
   NS_LOG_FUNCTION (this << address);
 
   Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
+  NS_ASSERT (ipv4 != 0);
 
   if (m_endPoint == 0)
     {
@@ -377,13 +370,12 @@
       NS_ASSERT (m_endPoint != 0);
     }
   InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
-  m_remoteAddress = transport.GetIpv4 ();
-  m_remotePort = transport.GetPort ();
+  m_endPoint->SetPeer(transport.GetIpv4 (), transport.GetPort ());
   
   if (ipv4->GetRoutingProtocol () != 0)
     {
       Ipv4Header header;
-      header.SetDestination (m_remoteAddress);
+      header.SetDestination (m_endPoint->GetPeerAddress());
       Socket::SocketErrno errno_;
       Ptr<Ipv4Route> route;
       Ptr<NetDevice> oif = m_boundnetdevice; //specify non-zero if bound to a source address
@@ -396,7 +388,7 @@
         }
       else
         {
-          NS_LOG_LOGIC ("TcpSocketImpl::Connect():  Route to " << m_remoteAddress << " does not exist");
+          NS_LOG_LOGIC ("TcpSocketImpl::Connect():  Route to " << m_endPoint->GetPeerAddress() << " does not exist");
           NS_LOG_ERROR (errno_);
           m_errno = errno_;
           return -1;
@@ -602,7 +594,7 @@
     }
   }
   SocketAddressTag tag;
-  tag.SetAddress (InetSocketAddress (m_remoteAddress, m_remotePort));
+  tag.SetAddress (InetSocketAddress (m_endPoint->GetPeerAddress(), m_endPoint->GetPeerPort()));
   outPacket->AddPacketTag (tag);
   return outPacket;
 }
@@ -638,7 +630,8 @@
 TcpSocketImpl::GetSockName (Address &address) const
 {
   NS_LOG_FUNCTION_NOARGS ();
-  address = InetSocketAddress(m_localAddress, m_localPort);
+  address = InetSocketAddress(m_endPoint->GetLocalAddress (), 
+                              m_endPoint->GetLocalPort ());
   return 0;
 }
 
@@ -661,7 +654,7 @@
 }
 
 void
-TcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
+TcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address saddr, Ipv4Address daddr, uint16_t port)
 {
   NS_LOG_DEBUG("Socket " << this << " got forward up" <<
                " dport " << m_endPoint->GetLocalPort() <<
@@ -669,7 +662,11 @@
                " sport " << m_endPoint->GetPeerPort() <<
                " saddr " << m_endPoint->GetPeerAddress());
 
-  NS_LOG_FUNCTION (this << packet << ipv4 << port);
+  NS_LOG_FUNCTION (this << packet << saddr << daddr << port);
+
+  Address fromAddress = InetSocketAddress (saddr, port);
+  Address toAddress = InetSocketAddress (daddr, m_endPoint->GetLocalPort());
+
   if (m_shutdownRecv)
     {
       return;
@@ -677,16 +674,6 @@
   TcpHeader tcpHeader;
   packet->RemoveHeader (tcpHeader);
 
-  if (tcpHeader.GetFlags () & TcpHeader::RST)
-    { // Got an RST, just shut everything down
-      NotifyErrorClose();
-      CancelAllTimers();
-      m_endPoint->SetDestroyCallback(MakeNullCallback<void>());
-      m_tcp->DeAllocate (m_endPoint);
-      m_endPoint = 0;
-      return;
-    }
-      
   if (tcpHeader.GetFlags () & TcpHeader::ACK)
     {
       Time m = m_rtt->AckSeq (tcpHeader.GetAckNumber () );
@@ -705,11 +692,10 @@
 
   Events_t event = SimulationSingleton<TcpStateMachine>::Get ()->FlagsEvent (tcpHeader.GetFlags () );
   Actions_t action = ProcessEvent (event); //updates the state
-  Address address = InetSocketAddress (ipv4, port);
   NS_LOG_DEBUG("Socket " << this << 
                " processing pkt action, " << action <<
                " current state " << m_state);
-  ProcessPacketAction (action, packet, tcpHeader, address);
+  ProcessPacketAction (action, packet, tcpHeader, fromAddress, toAddress);
 }
 
 Actions_t TcpSocketImpl::ProcessEvent (Events_t e)
@@ -721,14 +707,7 @@
   // class intended to be a singleton; see simulation-singleton.h
   SA stateAction = SimulationSingleton<TcpStateMachine>::Get ()->Lookup (m_state,e);
   NS_LOG_LOGIC ("TcpSocketImpl::ProcessEvent stateAction " << stateAction.action);
-  // debug
-  if (stateAction.action == RST_TX)
-    {
-      NS_LOG_LOGIC ("TcpSocketImpl " << this << " sending RST from state "
-              << saveState << " event " << e);
-      SendRST();
-      return NO_ACT;
-    }
+
   bool needCloseNotify = (stateAction.state == CLOSED && m_state != CLOSED 
     && e != TIMEOUT);
   m_state = stateAction.state;
@@ -744,7 +723,6 @@
     {
       Simulator::ScheduleNow(&TcpSocketImpl::ConnectionSucceeded, this);
       m_connected = true;
-      m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
       NS_LOG_LOGIC ("TcpSocketImpl " << this << " Connected!");
     }
   if (saveState < CLOSING && (m_state == CLOSING || m_state == TIMED_WAIT) )
@@ -795,19 +773,25 @@
   Ptr<Packet> p = Create<Packet> ();
   TcpHeader header;
 
+  if (m_endPoint == 0) 
+    {
+      NS_LOG_WARN ("Failed to send empty packet due to null endpoint");
+      return;
+    }
+
   if (flags & TcpHeader::FIN)
     {
       flags |= TcpHeader::ACK;
     }
-
+ 
   header.SetFlags (flags);
   header.SetSequenceNumber (m_nextTxSequence);
   header.SetAckNumber (m_nextRxSequence);
   header.SetSourcePort (m_endPoint->GetLocalPort ());
-  header.SetDestinationPort (m_remotePort);
+  header.SetDestinationPort (m_endPoint->GetPeerPort ());
   header.SetWindowSize (AdvertisedWindowSize());
   m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (), 
-    m_remoteAddress, m_boundnetdevice);
+    m_endPoint->GetPeerAddress (), m_boundnetdevice);
   Time rto = m_rtt->RetransmitTimeout ();
   bool hasSyn = flags & TcpHeader::SYN;
   bool hasFin = flags & TcpHeader::FIN;
@@ -834,9 +818,12 @@
   SendEmptyPacket(TcpHeader::RST);
   NotifyErrorClose();
   CancelAllTimers();
-  m_endPoint->SetDestroyCallback(MakeNullCallback<void>());
-  m_tcp->DeAllocate (m_endPoint);
-  m_endPoint = 0;
+  if (m_endPoint != 0) 
+    {
+      m_endPoint->SetDestroyCallback(MakeNullCallback<void>());
+      m_tcp->DeAllocate (m_endPoint);
+      m_endPoint = 0;
+    }
 }
 
   
@@ -918,13 +905,20 @@
 
 bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
                                      const TcpHeader& tcpHeader,
-                                     const Address& fromAddress)
+                                     const Address& fromAddress,
+                                     const Address& toAddress)
 {
   NS_LOG_FUNCTION (this << a << p  << fromAddress);
   Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
 
   switch (a)
   {
+    case RST_TX:
+      {
+        NS_LOG_LOGIC ("TcpSocketImpl " << this << " Action RST_TX");
+        SendRST();
+        return NO_ACT;
+      }
     case ACK_TX:
       NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action ACK_TX");
       if(tcpHeader.GetFlags() & TcpHeader::FIN)
@@ -946,40 +940,18 @@
           NS_LOG_LOGIC ("Cloned a TcpSocketImpl " << newSock);
           //this listening socket should do nothing more
           Simulator::ScheduleNow (&TcpSocketImpl::CompleteFork, newSock,
-                                  p, tcpHeader,fromAddress);
+                                  p, tcpHeader, fromAddress, toAddress);
           return true;
         }
-        // This is the cloned endpoint
-        m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
+      else
+        {
+          // This is the cloned endpoint
+          // TCP SYN consumes one byte
+          m_nextRxSequence = tcpHeader.GetSequenceNumber () 
+                             + SequenceNumber (1);
+          SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
+        }
 
-        // Look up the source address
-        if (ipv4->GetRoutingProtocol () != 0)
-          {
-            Ipv4Header header;
-            Socket::SocketErrno errno_;
-            Ptr<Ipv4Route> route;
-            Ptr<NetDevice> oif = m_boundnetdevice; //specify non-zero if bound to a source address
-            header.SetDestination (m_remoteAddress);
-            route = ipv4->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
-            if (route != 0)
-              {
-                NS_LOG_LOGIC ("Route exists");
-                m_endPoint->SetLocalAddress (route->GetSource ());
-              }
-            else
-              {
-                NS_LOG_ERROR (errno_);
-                m_errno = errno_;
-                return -1;
-              }
-          }
-        else
-          {
-            NS_FATAL_ERROR ("No Ipv4RoutingProtocol in the node");
-          }
-        // TCP SYN consumes one byte
-        m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
-        SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
       break;
     case ACK_TX_1:
       NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action ACK_TX_1");
@@ -1012,7 +984,8 @@
                                  NEW_SEQ_RX,
                                  p,
                                  tcpHeader,
-                                 fromAddress);
+                                 fromAddress,
+                                 toAddress);
         }
       if (tcpHeader.GetAckNumber () < m_highestRxAck) //old ack, do nothing
       {
@@ -1036,7 +1009,7 @@
       break;
     case NEW_SEQ_RX:
       NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action NEW_SEQ_RX");
-      NewRx (p, tcpHeader, fromAddress); // Process new data received
+      NewRx (p, tcpHeader, fromAddress, toAddress); // Process new data received
       break;
     case PEER_CLOSE:
     {
@@ -1050,14 +1023,14 @@
           NS_LOG_LOGIC ("TcpSocketImpl " << this << " setting pendingClose" 
             << " rxseq " << tcpHeader.GetSequenceNumber () 
             << " nextRxSeq " << m_nextRxSequence);
-          NewRx (p, tcpHeader, fromAddress);
+          NewRx (p, tcpHeader, fromAddress, toAddress);
           return true;
         }
       // Now we need to see if any data came with the FIN
       // if so, call NewRx
       if (p->GetSize () != 0)
         {
-          NewRx (p, tcpHeader, fromAddress);
+          NewRx (p, tcpHeader, fromAddress, toAddress);
         }
       ++m_nextRxSequence; //bump this to account for the FIN
       States_t saveState = m_state; // Used to see if app responds
@@ -1089,7 +1062,7 @@
       NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action SERV_NOTIFY");
       NS_LOG_LOGIC ("TcpSocketImpl " << this << " Connected!");
       m_connected = true; // ! This is bogus; fix when we clone the tcp
-      m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
+      m_endPoint->SetPeer (m_endPoint->GetPeerAddress(), m_endPoint->GetPeerPort());
       //treat the connection orientation final ack as a newack
       CommonNewAck (tcpHeader.GetAckNumber (), true);
       NotifyNewConnectionCreated (this, fromAddress);
@@ -1100,21 +1073,19 @@
   return true;
 }
 
-void TcpSocketImpl::CompleteFork(Ptr<Packet> p, const TcpHeader& h, const Address& fromAddress)
+void TcpSocketImpl::CompleteFork(Ptr<Packet> p, const TcpHeader& h, const Address& fromAddress, const Address& toAddress)
 {
   // Get port and address from peer (connecting host)
-  m_remotePort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
-  m_remoteAddress = InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 ();
-  m_endPoint = m_tcp->Allocate (m_localAddress,
-                                m_localPort,
-                                m_remoteAddress,
-                                m_remotePort);
+  m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom(toAddress).GetIpv4 (),
+                                InetSocketAddress::ConvertFrom(toAddress).GetPort (),
+                                InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
+                                InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
   //the cloned socket with be in listen state, so manually change state
   m_state = SYN_RCVD;
   //equivalent to FinishBind
   m_endPoint->SetRxCallback (MakeCallback (&TcpSocketImpl::ForwardUp, Ptr<TcpSocketImpl>(this)));
   m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketImpl::Destroy, Ptr<TcpSocketImpl>(this)));
-  ProcessPacketAction(SYN_ACK_TX, p, h, fromAddress);
+  ProcessPacketAction(SYN_ACK_TX, p, h, fromAddress, toAddress);
  }
 
 void TcpSocketImpl::ConnectionSucceeded()
@@ -1132,6 +1103,11 @@
     {
       return false; // No data exists
     }
+  if (m_endPoint == 0)
+    {
+      NS_LOG_INFO ("TcpSocketImpl::SendPendingData: No endpoint; m_shutdownSend=" << m_shutdownSend);
+      return false; // Is this the right way to handle this condition?
+    }
   uint32_t nPacketsSent = 0;
   while (m_pendingData->SizeFromSeq (m_firstPendingSequence, m_nextTxSequence))
     {
@@ -1176,12 +1152,12 @@
       header.SetSequenceNumber (m_nextTxSequence);
       header.SetAckNumber (m_nextRxSequence);
       header.SetSourcePort (m_endPoint->GetLocalPort());
-      header.SetDestinationPort (m_remotePort);
+      header.SetDestinationPort (m_endPoint->GetPeerPort());
       header.SetWindowSize (AdvertisedWindowSize());
       if (m_shutdownSend)
         {
           m_errno = ERROR_SHUTDOWN;
-          return -1;
+          return false;
         }
 
       
@@ -1196,7 +1172,8 @@
       NS_LOG_LOGIC ("About to send a packet with flags: " << flags);
       m_tcp->SendPacket (p, header,
                          m_endPoint->GetLocalAddress (),
-                         m_remoteAddress, m_boundnetdevice);
+                         m_endPoint->GetPeerAddress (), 
+                         m_boundnetdevice);
       m_rtt->SentSeq(m_nextTxSequence, sz);       // notify the RTT
       // Notify the application of the data being sent
       Simulator::ScheduleNow(&TcpSocketImpl::NotifyDataSent, this, sz);
@@ -1254,7 +1231,8 @@
 
 void TcpSocketImpl::NewRx (Ptr<Packet> p,
                         const TcpHeader& tcpHeader, 
-                        const Address& fromAddress)
+                        const Address& fromAddress,
+                        const Address& toAddress)
 {
   NS_LOG_FUNCTION (this << p << "tcpHeader " << fromAddress);
   NS_LOG_LOGIC ("TcpSocketImpl " << this << " NewRx,"
@@ -1321,7 +1299,7 @@
         { // See if we can close now
           if (m_bufferedData.empty())
             {
-              ProcessPacketAction (PEER_CLOSE, p, tcpHeader, fromAddress);
+              ProcessPacketAction (PEER_CLOSE, p, tcpHeader, fromAddress, toAddress);
             }
         }
     }
@@ -1638,11 +1616,11 @@
   tcpHeader.SetSequenceNumber (m_nextTxSequence);
   tcpHeader.SetAckNumber (m_nextRxSequence);
   tcpHeader.SetSourcePort (m_endPoint->GetLocalPort());
-  tcpHeader.SetDestinationPort (m_remotePort);
+  tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
   tcpHeader.SetWindowSize (AdvertisedWindowSize());
 
   m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
-    m_remoteAddress, m_boundnetdevice);
+    m_endPoint->GetPeerAddress (), m_boundnetdevice);
   NS_LOG_LOGIC ("Schedule persist timeout at time " 
                     <<Simulator::Now ().GetSeconds () << " to expire at time "
                     << (Simulator::Now () + m_persistTime).GetSeconds());
@@ -1703,12 +1681,12 @@
   tcpHeader.SetSequenceNumber (m_nextTxSequence);
   tcpHeader.SetAckNumber (m_nextRxSequence);
   tcpHeader.SetSourcePort (m_endPoint->GetLocalPort());
-  tcpHeader.SetDestinationPort (m_remotePort);
+  tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
   tcpHeader.SetFlags (flags);
   tcpHeader.SetWindowSize (AdvertisedWindowSize());
 
   m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
-    m_remoteAddress, m_boundnetdevice);
+    m_endPoint->GetPeerAddress (), m_boundnetdevice);
 }
 
 void
--- a/src/internet-stack/tcp-socket-impl.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/tcp-socket-impl.h	Thu Feb 25 14:17:21 2010 +0100
@@ -101,7 +101,7 @@
   friend class Tcp;
   // invoked by Tcp class
   int FinishBind (void);
-  void ForwardUp (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port);
+  void ForwardUp (Ptr<Packet> p, Ipv4Address saddr, Ipv4Address daddr, uint16_t port);
   void Destroy (void);
   int DoSendTo (Ptr<Packet> p, const Address &daddr);
   int DoSendTo (Ptr<Packet> p, Ipv4Address daddr, uint16_t dport);
@@ -114,10 +114,11 @@
                       Ipv4Address saddr, Ipv4Address daddr);
   bool ProcessPacketAction (Actions_t a, Ptr<Packet> p,
                                        const TcpHeader& tcpHeader,
-                                       const Address& fromAddress);
+                                       const Address& fromAddress,
+                                       const Address& toAddress);
   Actions_t ProcessEvent (Events_t e);
   bool SendPendingData(bool withAck = false);
-  void CompleteFork(Ptr<Packet>, const TcpHeader&, const Address& fromAddress);
+  void CompleteFork(Ptr<Packet>, const TcpHeader&, const Address& fromAddress, const Address& toAddress);
   void ConnectionSucceeded();
   
   //methods for window management
@@ -131,7 +132,7 @@
   uint16_t AdvertisedWindowSize();
 
   // Manage data tx/rx
-  void NewRx (Ptr<Packet>, const TcpHeader&, const Address&);
+  void NewRx (Ptr<Packet>, const TcpHeader&, const Address& fromAddress, const Address& toAddress);
   void RxBufFinishInsert (SequenceNumber);
   Ptr<TcpSocketImpl> Copy ();
   virtual void NewAck (SequenceNumber seq); 
@@ -178,11 +179,7 @@
   Ipv4EndPoint *m_endPoint;
   Ptr<Node> m_node;
   Ptr<TcpL4Protocol> m_tcp;
-  Ipv4Address m_remoteAddress;
-  uint16_t m_remotePort;
-  //these two are so that the socket/endpoint cloning works
-  Ipv4Address m_localAddress;
-  uint16_t m_localPort;
+
   enum SocketErrno m_errno;
   bool m_shutdownSend;
   bool m_shutdownRecv;
--- a/src/internet-stack/udp-l4-protocol.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/udp-l4-protocol.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -230,7 +230,7 @@
   for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
        endPoint != endPoints.end (); endPoint++)
     {
-      (*endPoint)->ForwardUp (packet->Copy (), source, udpHeader.GetSourcePort ());
+      (*endPoint)->ForwardUp (packet->Copy (), source, destination, udpHeader.GetSourcePort ());
     }
   return Ipv4L4Protocol::RX_OK;
 }
--- a/src/internet-stack/udp-socket-impl.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/udp-socket-impl.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -583,9 +583,9 @@
 }
 
 void 
-UdpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
+UdpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address saddr, Ipv4Address daddr, uint16_t port)
 {
-  NS_LOG_FUNCTION (this << packet << ipv4 << port);
+  NS_LOG_FUNCTION (this << packet << saddr << daddr << port);
 
   if (m_shutdownRecv)
     {
@@ -593,7 +593,7 @@
     }
   if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
     {
-      Address address = InetSocketAddress (ipv4, port);
+      Address address = InetSocketAddress (saddr, port);
       SocketAddressTag tag;
       tag.SetAddress (address);
       packet->AddPacketTag (tag);
--- a/src/internet-stack/udp-socket-impl.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/internet-stack/udp-socket-impl.h	Thu Feb 25 14:17:21 2010 +0100
@@ -98,7 +98,7 @@
   friend class UdpSocketFactory;
   // invoked by Udp class
   int FinishBind (void);
-  void ForwardUp (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port);
+  void ForwardUp (Ptr<Packet> p, Ipv4Address saddr, Ipv4Address daddr, uint16_t port);
   void Destroy (void);
   int DoSend (Ptr<Packet> p);
   int DoSendTo (Ptr<Packet> p, const Address &daddr);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mobility/steady-state-random-waypoint-mobility-model.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,371 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * 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: Denis Fakhriev <fakhriev@iitp.ru>
+ */
+#include <cmath>
+#include "ns3/simulator.h"
+#include "ns3/double.h"
+#include "steady-state-random-waypoint-mobility-model.h"
+#include "ns3/test.h"
+#include "ns3/node-container.h"
+#include "ns3/mobility-helper.h"
+#include "ns3/simulator.h"
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (SteadyStateRandomWaypointMobilityModel);
+
+TypeId
+SteadyStateRandomWaypointMobilityModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::SteadyStateRandomWaypointMobilityModel")
+    .SetParent<MobilityModel> ()
+    .SetGroupName ("Mobility")
+    .AddConstructor<SteadyStateRandomWaypointMobilityModel> ()
+    .AddAttribute ("MinSpeed",
+                   "Minimum speed value, [m/s]",
+                   DoubleValue (0.3),
+                   MakeDoubleAccessor (&SteadyStateRandomWaypointMobilityModel::m_minSpeed),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("MaxSpeed",
+                   "Maximum speed value, [m/s]",
+                   DoubleValue (0.7),
+                   MakeDoubleAccessor (&SteadyStateRandomWaypointMobilityModel::m_maxSpeed),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("MinPause",
+                   "Minimum pause value, [s]",
+                   DoubleValue (0.0),
+                   MakeDoubleAccessor (&SteadyStateRandomWaypointMobilityModel::m_minPause),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("MaxPause",
+                   "Maximum pause value, [s]",
+                   DoubleValue (0.0),
+                   MakeDoubleAccessor (&SteadyStateRandomWaypointMobilityModel::m_maxPause),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("MinX",
+                   "Minimum X value of traveling region, [m]",
+                   DoubleValue (1),
+                   MakeDoubleAccessor (&SteadyStateRandomWaypointMobilityModel::m_minX),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("MaxX",
+                   "Maximum X value of traveling region, [m]",
+                   DoubleValue (1),
+                   MakeDoubleAccessor (&SteadyStateRandomWaypointMobilityModel::m_maxX),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("MinY",
+                   "Minimum Y value of traveling region, [m]",
+                   DoubleValue (1),
+                   MakeDoubleAccessor (&SteadyStateRandomWaypointMobilityModel::m_minY),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("MaxY",
+                   "Maximum Y value of traveling region, [m]",
+                   DoubleValue (1),
+                   MakeDoubleAccessor (&SteadyStateRandomWaypointMobilityModel::m_maxY),
+                   MakeDoubleChecker<double> ());
+  
+  return tid;
+}
+
+SteadyStateRandomWaypointMobilityModel::SteadyStateRandomWaypointMobilityModel ():
+  alreadyStarted (false)
+{
+}
+
+void
+SteadyStateRandomWaypointMobilityModel::DoStart (void)
+{
+  SteadyStateStart ();
+  MobilityModel::DoStart ();
+}
+
+void
+SteadyStateRandomWaypointMobilityModel::SteadyStateStart (void)
+{
+  alreadyStarted = true;
+  NS_ASSERT (m_minSpeed >= 1e-6);
+  NS_ASSERT (m_minSpeed <= m_maxSpeed);
+  m_speed = UniformVariable (m_minSpeed, m_maxSpeed);
+  NS_ASSERT (m_minX < m_maxX);
+  NS_ASSERT (m_minY < m_maxY);
+  m_position = CreateObject<RandomRectanglePositionAllocator> ();
+  m_position->SetX (UniformVariable (m_minX, m_maxX));
+  m_position->SetY (UniformVariable (m_minY, m_maxY));
+  NS_ASSERT (m_minPause <= m_maxPause);
+  m_pause = UniformVariable (m_minPause, m_maxPause);
+  
+  m_helper.Update ();
+  m_helper.Pause ();
+  
+  // calculate the steady-state probability that a node is initially paused
+  double expectedPauseTime = (m_minPause + m_maxPause)/2;
+  double a = m_maxX - m_minX;
+  double b = m_maxY - m_minY;
+  double v0 = m_minSpeed;
+  double v1 = m_maxSpeed;
+  double log1 = b*b / a*std::log (std::sqrt ((a*a)/(b*b) + 1) + a/b);
+  double log2 = a*a / b*std::log (std::sqrt ((b*b)/(a*a) + 1) + b/a);
+  double expectedTravelTime = 1.0/6.0*(log1 + log2);
+  expectedTravelTime += 1.0/15.0*((a*a*a)/(b*b) + (b*b*b)/(a*a)) -
+                        1.0/15.0*std::sqrt(a*a + b*b)*((a*a)/(b*b) + (b*b)/(a*a) - 3);
+  if (v0 == v1)
+    {
+      expectedTravelTime /= v0;
+    }
+  else
+    {
+      expectedTravelTime *= std::log(v1/v0)/(v1 - v0);
+    }
+  double probabilityPaused = expectedPauseTime/(expectedPauseTime + expectedTravelTime);
+  NS_ASSERT (probabilityPaused >= 0 && probabilityPaused <= 1);
+  
+  UniformVariable u_r;
+  double u = u_r.GetValue(0, 1);
+  if (u < probabilityPaused) // node initially paused
+    {
+      m_helper.SetPosition (m_position->GetNext ());
+      u = u_r.GetValue(0, 1);
+      Time pause;      
+      if (m_minPause != m_maxPause)
+        {
+          if (u < (2*m_minPause/(m_minPause + m_maxPause)))
+            {
+              pause = Seconds (u*(m_minPause + m_maxPause)/2);
+            }
+          else
+            {
+              // there is an error in equation 20 in the Tech. Report MCS-03-04
+              // this error is corrected in the TMC 2004 paper and below
+              pause = Seconds (m_maxPause - sqrt ((1 - u)*(m_maxPause*m_maxPause - m_minPause*m_minPause)));
+            }
+        }
+      else // if pause is constant
+        {
+          pause = Seconds (u*expectedPauseTime);
+        }
+      NS_ASSERT (!m_event.IsRunning());
+      m_event = Simulator::Schedule (pause, &SteadyStateRandomWaypointMobilityModel::BeginWalk, this);
+    }
+  else // node initially moving
+    {
+      UniformVariable x1_r, y1_r, x2_r, y2_r;
+      double x1, x2, y1, y2;
+      double r = 0;
+      double u1 = 1;
+      while (u1 >= r)
+        {
+          x1 = x1_r.GetValue (0, a);
+          y1 = y1_r.GetValue (0, b);
+          x2 = x2_r.GetValue (0, a);
+          y2 = y2_r.GetValue (0, b);
+          u1 = u_r.GetValue (0, 1);
+          r = std::sqrt (((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1))/(a*a + b*b));
+          NS_ASSERT (r <= 1);
+        }
+      double u2 = u_r.GetValue (0, 1);
+      m_helper.SetPosition (Vector (m_minX + u2*x1 + (1 - u2)*x2, m_minY + u2*y1 + (1 - u2)*y2, 0));
+      NS_ASSERT (!m_event.IsRunning());
+      m_event = Simulator::ScheduleNow (&SteadyStateRandomWaypointMobilityModel::SteadyStateBeginWalk, this, 
+                Vector (m_minX + x2, m_minY + y2, 0));
+    }
+  NotifyCourseChange ();
+}
+
+void
+SteadyStateRandomWaypointMobilityModel::SteadyStateBeginWalk (const Vector &destination)
+{
+  m_helper.Update ();
+  Vector m_current = m_helper.GetCurrentPosition ();
+  NS_ASSERT (m_minX <= m_current.x && m_current.x <= m_maxX);
+  NS_ASSERT (m_minY <= m_current.y && m_current.y <= m_maxY);
+  NS_ASSERT (m_minX <= destination.x && destination.x <= m_maxX);
+  NS_ASSERT (m_minY <= destination.y && destination.y <= m_maxY);
+  UniformVariable u_r;
+  double u = u_r.GetValue (0, 1);
+  double speed = std::pow (m_maxSpeed, u)/std::pow (m_minSpeed, u - 1);
+  double dx = (destination.x - m_current.x);
+  double dy = (destination.y - m_current.y);
+  double dz = (destination.z - m_current.z);
+  double k = speed / std::sqrt (dx*dx + dy*dy + dz*dz);
+
+  m_helper.SetVelocity (Vector (k*dx, k*dy, k*dz));
+  m_helper.Unpause ();
+  Time travelDelay = Seconds (CalculateDistance (destination, m_current) / speed);
+  m_event = Simulator::Schedule (travelDelay, 
+                                 &SteadyStateRandomWaypointMobilityModel::Start, this);
+  NotifyCourseChange ();
+}
+
+void
+SteadyStateRandomWaypointMobilityModel::BeginWalk (void)
+{
+  m_helper.Update ();
+  Vector m_current = m_helper.GetCurrentPosition ();
+  NS_ASSERT (m_minX <= m_current.x && m_current.x <= m_maxX);
+  NS_ASSERT (m_minY <= m_current.y && m_current.y <= m_maxY);
+  Vector destination = m_position->GetNext ();
+  double speed = m_speed.GetValue ();
+  double dx = (destination.x - m_current.x);
+  double dy = (destination.y - m_current.y);
+  double dz = (destination.z - m_current.z);
+  double k = speed / std::sqrt (dx*dx + dy*dy + dz*dz);
+
+  m_helper.SetVelocity (Vector (k*dx, k*dy, k*dz));
+  m_helper.Unpause ();
+  Time travelDelay = Seconds (CalculateDistance (destination, m_current) / speed);
+  m_event = Simulator::Schedule (travelDelay,
+				 &SteadyStateRandomWaypointMobilityModel::Start, this);
+  NotifyCourseChange ();
+}
+
+void
+SteadyStateRandomWaypointMobilityModel::Start (void)
+{
+  m_helper.Update ();
+  m_helper.Pause ();
+  Time pause = Seconds (m_pause.GetValue ());
+  m_event = Simulator::Schedule (pause, &SteadyStateRandomWaypointMobilityModel::BeginWalk, this);
+  NotifyCourseChange ();
+}
+
+Vector
+SteadyStateRandomWaypointMobilityModel::DoGetPosition (void) const
+{
+  m_helper.Update ();
+  return m_helper.GetCurrentPosition ();
+}
+void 
+SteadyStateRandomWaypointMobilityModel::DoSetPosition (const Vector &position)
+{
+  if (alreadyStarted)
+    {
+      m_helper.SetPosition (position);
+      Simulator::Remove (m_event);
+      m_event = Simulator::ScheduleNow (&SteadyStateRandomWaypointMobilityModel::Start, this);
+    }
+}
+Vector
+SteadyStateRandomWaypointMobilityModel::DoGetVelocity (void) const
+{
+  return m_helper.GetVelocity ();
+}
+
+class SteadyStateRandomWaypointTest : public TestCase
+{
+public:
+  SteadyStateRandomWaypointTest ()
+    : TestCase ("Check steady-state rwp mobility model velocity and position distributions") {}
+  virtual ~SteadyStateRandomWaypointTest () {}
+
+private:
+  NodeContainer nodes;
+  double NodeCount;
+private:
+  virtual bool DoRun (void);
+  void DistribCompare ();
+};
+
+bool
+SteadyStateRandomWaypointTest::DoRun (void)
+{
+  SeedManager::SetSeed(123);
+
+  // Total simulation time, seconds
+  double totalTime = 1000;
+  // Create nodes
+  NodeCount = 10000;
+  nodes.Create ((uint32_t) NodeCount);
+  // Installmobility
+  MobilityHelper mobility;
+  mobility.SetMobilityModel ("ns3::SteadyStateRandomWaypointMobilityModel",
+                             "MinSpeed", DoubleValue (0.01),
+                             "MaxSpeed", DoubleValue (20.0),
+                             "MinPause", DoubleValue (0.0),
+                             "MaxPause", DoubleValue (0.0),
+                             "MinX", DoubleValue (0),
+                             "MaxX", DoubleValue (1000),
+                             "MinY", DoubleValue (0),
+                             "MaxY", DoubleValue (600));
+  mobility.Install (nodes);
+
+  Simulator::Schedule (Seconds (0.001), & SteadyStateRandomWaypointTest::DistribCompare, this);
+  Simulator::Schedule (Seconds (totalTime), & SteadyStateRandomWaypointTest::DistribCompare, this);
+  Simulator::Stop (Seconds (totalTime));
+  Simulator::Run ();
+  Simulator::Destroy ();
+
+  return GetErrorStatus (); 
+}
+
+void
+SteadyStateRandomWaypointTest::DistribCompare ()
+{
+  Ptr<MobilityModel> model;
+  double velocity;
+  double sum_x = 0;
+  double sum_y = 0;
+  double sum_v = 0;
+  NodeContainer::Iterator i;
+  for (i = nodes.Begin (); i != nodes.End (); ++i)
+    {
+      model = (*i)->GetObject<MobilityModel> ();
+      velocity = sqrt (pow (model->GetVelocity().x, 2) + pow (model->GetVelocity().y, 2));
+      sum_x += model->GetPosition().x;
+      sum_y += model->GetPosition().y;
+      sum_v += velocity;
+    }
+  double mean_x = sum_x / NodeCount;
+  double mean_y = sum_y / NodeCount;
+  double mean_v = sum_v / NodeCount;
+
+  NS_TEST_EXPECT_MSG_EQ_TOL (500, mean_x, 25.0, "Got unexpected x-position mean value");
+  NS_TEST_EXPECT_MSG_EQ_TOL (300, mean_y, 15.0, "Got unexpected y-position mean value");
+  NS_TEST_EXPECT_MSG_EQ_TOL (2.6, mean_v, 0.13, "Got unexpected velocity mean value");
+
+  sum_x = 0;
+  sum_y = 0;
+  sum_v = 0;
+  double tmp;
+  for (i = nodes.Begin (); i != nodes.End (); ++i)
+    {
+      model = (*i)->GetObject<MobilityModel> ();
+      velocity = sqrt (pow (model->GetVelocity().x, 2) + pow (model->GetVelocity().y, 2));
+      tmp = model->GetPosition().x - mean_x;
+      sum_x += tmp * tmp;
+      tmp = model->GetPosition().y - mean_y;
+      sum_y += tmp * tmp;
+      tmp = velocity - mean_v;
+      sum_v += tmp * tmp;
+    }
+  double dev_x = std::sqrt (sum_x / (NodeCount - 1));
+  double dev_y = std::sqrt (sum_y / (NodeCount - 1));
+  double dev_v = std::sqrt (sum_v / (NodeCount - 1));
+
+  NS_TEST_EXPECT_MSG_EQ_TOL (230, dev_x, 10.0, "Got unexpected x-position standard deviation");
+  NS_TEST_EXPECT_MSG_EQ_TOL (140, dev_y, 7.0, "Got unexpected y-position standard deviation");
+  NS_TEST_EXPECT_MSG_EQ_TOL (4.4, dev_v, 0.22, "Got unexpected velocity standard deviation");
+}
+
+struct SteadyStateRandomWaypointTestSuite : public TestSuite
+{
+  SteadyStateRandomWaypointTestSuite () : TestSuite ("steady-state-rwp-mobility-model", UNIT)
+  {
+    AddTestCase (new SteadyStateRandomWaypointTest);
+  }
+} g_steadyStateRandomWaypointTestSuite;
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mobility/steady-state-random-waypoint-mobility-model.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,85 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * 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: Denis Fakhriev <fakhriev@iitp.ru>
+ */
+#ifndef STEADY_STATE_RANDOM_WAYPOINT_MOBILITY_MODEL_H
+#define STEADY_STATE_RANDOM_WAYPOINT_MOBILITY_MODEL_H
+
+#include "constant-velocity-helper.h"
+#include "mobility-model.h"
+#include "position-allocator.h"
+#include "ns3/ptr.h"
+#include "ns3/random-variable.h"
+
+namespace ns3 {
+
+/**
+ * \brief a steady-state random waypoint mobility model
+ *
+ * This model based on random waypoint mobility (RWM) model for case when 
+ * speed, pause and position are uniformly distributed random variables. 
+ * The difference is that the initial values of this parameters are not 
+ * from uniform distribution but from stationary distribution of RWM model.
+ * The implementation of this model is 2d-specific and with nonzero nodes speeds.
+ *
+ * Based on NS-2 implementation by Toilers Research Group -- Colorado
+ *      School of Mines (http://toilers.mines.edu). 
+ * The papers related to this code are:
+ *      W. Navidi and T. Camp, Stationary Distributions for the Random
+ *      Waypoint Mobility Model, IEEE Transactions on Mobile Computing,
+ *      vol. 3, no. 1, pp. 99-108, January-March 2004.
+ *      W. Navidi, T. Camp, and N. Bauer, Improving the Accuracy of
+ *      Random Waypoint Simulations Through Steady-State Initialization,
+ *      Proceedings of the 15th International Conference on Modeling and
+ *      Simulation (MS '04), pp. 319-326, March 2004.
+ */
+class SteadyStateRandomWaypointMobilityModel : public MobilityModel
+{
+public:
+  static TypeId GetTypeId (void);
+  SteadyStateRandomWaypointMobilityModel ();
+protected:
+  virtual void DoStart (void);
+private:
+  void SteadyStateStart (void);
+  void SteadyStateBeginWalk (const Vector &destination);
+  void Start (void);
+  void BeginWalk (void);
+  virtual Vector DoGetPosition (void) const;
+  virtual void DoSetPosition (const Vector &position);
+  virtual Vector DoGetVelocity (void) const;
+
+  ConstantVelocityHelper m_helper;
+  double m_maxSpeed;
+  double m_minSpeed;
+  UniformVariable m_speed;
+  double m_minX;
+  double m_maxX;
+  double m_minY;
+  double m_maxY;
+  Ptr<RandomRectanglePositionAllocator> m_position;
+  double m_minPause;
+  double m_maxPause;
+  UniformVariable m_pause;
+  EventId m_event;
+  bool alreadyStarted;
+};
+
+} // namespace ns3
+
+#endif /* STEADY_STATE_RANDOM_WAYPOINT_MOBILITY_MODEL_H */
--- a/src/mobility/waypoint.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/mobility/waypoint.h	Thu Feb 25 14:17:21 2010 +0100
@@ -35,8 +35,8 @@
 {
 public:
   /**
-   * \param _time time of waypoint.
-   * \param _position position of waypoint corresponding to the given time.
+   * \param waypointTime time of waypoint.
+   * \param waypointPosition position of waypoint corresponding to the given time.
    *
    * Create a waypoint.
    */
--- a/src/mobility/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/mobility/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -11,6 +11,7 @@
         'constant-velocity-helper.cc',
         'constant-velocity-mobility-model.cc',
         'random-waypoint-mobility-model.cc',
+        'steady-state-random-waypoint-mobility-model.cc',
         'random-walk-2d-mobility-model.cc',
         'random-direction-2d-mobility-model.cc',
         'constant-acceleration-mobility-model.cc',
@@ -29,6 +30,7 @@
         'constant-velocity-helper.h',
         'constant-velocity-mobility-model.h',
         'random-waypoint-mobility-model.h',
+        'steady-state-random-waypoint-mobility-model.h',
         'random-walk-2d-mobility-model.h',
         'random-direction-2d-mobility-model.h',
         'constant-acceleration-mobility-model.h',
--- a/src/node/application.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/node/application.h	Thu Feb 25 14:17:21 2010 +0100
@@ -67,7 +67,7 @@
 
   /**
    * \brief Specify application start time
-   * \param startTime Start time for this application,
+   * \param start Start time for this application,
    *        relative to the current simulation time.
    *
    * Applications start at various times in the simulation scenario.
@@ -80,7 +80,7 @@
   
   /**
    * \brief Specify application stop time
-   * \param stopTime Stop time for this application, relative to the
+   * \param stop Stop time for this application, relative to the
    *        current simulation time.
    *
    * Once an application has started, it is sometimes useful
--- a/src/node/ipv4-address-generator.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/node/ipv4-address-generator.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -560,6 +560,7 @@
 AddressAllocatorTestCase::DoTeardown (void)
 {
   Ipv4AddressGenerator::Reset ();
+  Simulator::Destroy ();
 }
 
 
@@ -579,6 +580,7 @@
 NetworkAndAddressTestCase::DoTeardown (void)
 {
   Ipv4AddressGenerator::Reset ();
+  Simulator::Destroy ();
 }
 
 bool
@@ -695,6 +697,7 @@
 AddressCollisionTestCase::DoTeardown (void)
 {
   Ipv4AddressGenerator::Reset ();
+  Simulator::Destroy ();
 }
 bool
 AddressCollisionTestCase::DoRun (void)
--- a/src/node/ipv4-address.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/node/ipv4-address.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -72,8 +72,16 @@
 {
   if (*mask == ASCII_SLASH)
     {
-      m_mask = static_cast<uint32_t> (atoi (++mask));
-      NS_ASSERT (m_mask <= 32);
+      uint32_t plen = static_cast<uint32_t> (atoi (++mask));
+      NS_ASSERT (plen <= 32);
+      if (plen > 0)
+        {
+          m_mask = 0xffffffff << (32 - plen);
+        }
+      else
+        {
+          m_mask = 0;
+        }
     }
   else
     {
--- a/src/node/node.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/node/node.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -30,6 +30,7 @@
 #include "ns3/assert.h"
 #include "ns3/global-value.h"
 #include "ns3/boolean.h"
+#include "ns3/simulator.h"
 
 NS_LOG_COMPONENT_DEFINE ("Node");
 
@@ -108,6 +109,8 @@
   device->SetNode (this);
   device->SetIfIndex(index);
   device->SetReceiveCallback (MakeCallback (&Node::NonPromiscReceiveFromDevice, this));
+  Simulator::ScheduleWithContext (GetId (), Seconds (0.0), 
+                                  &NetDevice::Start, device);
   NotifyDeviceAdded (device);
   return index;
 }
@@ -130,6 +133,8 @@
   uint32_t index = m_applications.size ();
   m_applications.push_back (application);
   application->SetNode (this);
+  Simulator::ScheduleWithContext (GetId (), Seconds (0.0), 
+                                  &Application::Start, application);
   return index;
 }
 Ptr<Application> 
--- a/src/node/packetbb.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/node/packetbb.h	Thu Feb 25 14:17:21 2010 +0100
@@ -631,7 +631,6 @@
   bool operator!= (const PbbPacket &other) const;
 
 protected:
-  void SerializePacketTlv (Buffer::Iterator &start) const;
 
 private:
   PbbTlvBlock m_tlvList;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/radiotap-header.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,404 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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, Include., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include <iomanip>
+#include <math.h>
+#include "ns3/log.h"
+#include "radiotap-header.h"
+
+NS_LOG_COMPONENT_DEFINE ("RadiotapHeader");  
+
+namespace ns3 {
+ 
+RadiotapHeader::RadiotapHeader()
+  : m_length(8),
+    m_present(0),
+    m_tsft(0),
+    m_flags(FRAME_FLAG_NONE),
+    m_rate(0),
+    m_channelFreq(0),
+    m_channelFlags(CHANNEL_FLAG_NONE),
+    m_antennaSignal(0),
+    m_antennaNoise(0)
+{       
+  NS_LOG_FUNCTION (this);
+}
+ 
+TypeId RadiotapHeader::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("RadiotapHeader")
+    .SetParent<Header> ()
+    .AddConstructor<RadiotapHeader> ()
+    ;
+  return tid;
+}
+
+TypeId 
+RadiotapHeader::GetInstanceTypeId (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return GetTypeId ();
+}
+
+uint32_t  
+RadiotapHeader::GetSerializedSize (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_length;
+}
+
+void  
+RadiotapHeader::Serialize (Buffer::Iterator start) const
+{
+  NS_LOG_FUNCTION (this);
+
+  start.WriteU8 (0); // major version of radiotap header
+  start.WriteU8 (0); // pad field
+  start.WriteU16 (m_length); // entire length of radiotap data + header
+  start.WriteU32 (m_present); // bits describing which fields follow header
+  
+  //
+  // Time Synchronization Function Timer (when the first bit of the MPDU 
+  // arrived at the MAC)
+  //
+  if (m_present & RADIOTAP_TSFT) // bit 0
+    {
+      start.WriteU64 (m_tsft);
+    }
+
+  //
+  // Properties of transmitted and received frames.
+  //
+  if (m_present & RADIOTAP_FLAGS) // bit 1
+    {
+      start.WriteU8 (m_flags);
+    }
+
+  //
+  // TX/RX data rate in units of 500 kbps
+  //
+  if (m_present & RADIOTAP_RATE) // bit 2
+    {
+      start.WriteU8 (m_rate);
+    }
+
+  //
+  // Tx/Rx frequency in MHz, followed by flags.
+  //
+  if (m_present & RADIOTAP_CHANNEL) // bit 3
+    {
+      start.WriteU16 (m_channelFreq);
+      start.WriteU16 (m_channelFlags);
+    }
+
+  //
+  // RF signal power at the antenna, decibel difference from an arbitrary, fixed
+  // reference.
+  //
+  if (m_present & RADIOTAP_DBM_ANTSIGNAL) // bit 5
+    {
+      start.WriteU8 (m_antennaSignal);
+    }
+
+  //
+  // RF noise power at the antenna, decibel difference from an arbitrary, fixed 
+  // reference.
+  //
+  if (m_present & RADIOTAP_DBM_ANTNOISE) // bit 6
+    {
+      start.WriteU8 (m_antennaNoise);
+    }
+}
+
+uint32_t  
+RadiotapHeader::Deserialize (Buffer::Iterator start)
+{
+  NS_LOG_FUNCTION (this);
+    
+  uint8_t __attribute__ ((unused)) tmp = start.ReadU8 (); // major version of radiotap header
+  NS_ASSERT_MSG (tmp == 0x00, "RadiotapHeader::Deserialize(): Unexpected major version");
+  start.ReadU8 (); // pad field
+  
+  m_length = start.ReadU16 (); // entire length of radiotap data + header
+  m_present = start.ReadU32 (); // bits describing which fields follow header
+  
+  uint32_t bytesRead = 8;
+  
+  //
+  // Time Synchronization Function Timer (when the first bit of the MPDU arrived at the MAC)
+  //
+  if (m_present & RADIOTAP_TSFT) // bit 0
+    {
+      m_tsft = start.ReadU64();
+      bytesRead += 8;
+    }
+
+  //
+  // Properties of transmitted and received frames.
+  //
+  if (m_present & RADIOTAP_FLAGS) // bit 1
+    {
+      m_flags = start.ReadU8();
+      ++bytesRead;
+    }
+
+  //
+  // TX/RX data rate in units of 500 kbps
+  //
+  if (m_present & RADIOTAP_RATE) // bit 2
+    {
+      m_rate = start.ReadU8();
+      ++bytesRead;
+    }
+
+  //
+  // Tx/Rx frequency in MHz, followed by flags.
+  //
+  if (m_present & RADIOTAP_CHANNEL) // bit 3
+    {
+      m_channelFreq = start.ReadU16();
+      m_channelFlags = start.ReadU16();
+      bytesRead += 4;
+    }
+
+  //
+  // The hop set and pattern for frequency-hopping radios.  We don't need it but
+  // still need to account for it.
+  //
+  if (m_present & RADIOTAP_FHSS) // bit 4
+    {
+      start.ReadU8(); 
+      ++bytesRead;
+    }
+
+  //
+  // RF signal power at the antenna, decibel difference from an arbitrary, fixed
+  // reference.
+  //
+  if (m_present & RADIOTAP_DBM_ANTSIGNAL) // bit 5
+    {
+      m_antennaSignal = start.ReadU8();
+      ++bytesRead;
+    }
+
+  //
+  // RF noise power at the antenna, decibel difference from an arbitrary, fixed 
+  // reference.
+  //
+  if (m_present & RADIOTAP_DBM_ANTNOISE) // bit 6
+    {
+      m_antennaNoise = start.ReadU8();
+      ++bytesRead;
+    }
+  
+  NS_ASSERT_MSG(m_length == bytesRead, "RadiotapHeader::Deserialize(): expected and actual lengths inconsistent");
+  return bytesRead;
+}
+
+void  
+RadiotapHeader::Print (std::ostream &os) const
+{
+  NS_LOG_FUNCTION (this);
+  os << " tsft=" << m_tsft
+     << " flags=" << std::hex << m_flags << std::dec
+     << " rate=" << (uint16_t) m_rate
+     << " freq=" << m_channelFreq
+     << " chflags=" << std::hex << (uint32_t)m_channelFlags << std::dec
+     << " signal=" << (int16_t) m_antennaSignal
+     << " noise=" << (int16_t) m_antennaNoise;
+}
+
+void  
+RadiotapHeader::SetTsft (uint64_t value)
+{
+  NS_LOG_FUNCTION (this << value);
+  m_tsft = value;
+
+  if (!(m_present & RADIOTAP_TSFT))
+    {
+      m_present |= RADIOTAP_TSFT;
+      m_length += 8;
+    }
+
+  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
+}
+
+uint64_t  
+RadiotapHeader::GetTsft () const
+{
+  NS_LOG_FUNCTION (this);
+  return m_tsft;
+}
+
+void 
+RadiotapHeader::SetFrameFlags (uint8_t flags)
+{
+  NS_LOG_FUNCTION (this << flags);
+  m_flags = flags;
+
+  if (!(m_present & RADIOTAP_FLAGS))
+    {
+      m_present |= RADIOTAP_FLAGS;
+      m_length += 1;
+    }
+
+  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
+}
+
+uint8_t
+RadiotapHeader::GetFrameFlags (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_flags;
+}
+
+void 
+RadiotapHeader::SetRate (uint8_t rate)
+{
+  NS_LOG_FUNCTION (this << rate);
+  m_rate = rate;
+
+  if (!(m_present & RADIOTAP_RATE))
+    {
+      m_present |= RADIOTAP_RATE;
+      m_length += 1;
+    }
+
+  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
+}
+
+uint8_t
+RadiotapHeader::GetRate (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_rate;
+}
+
+void 
+RadiotapHeader::SetChannelFrequencyAndFlags (uint16_t frequency, uint16_t flags)
+{
+  NS_LOG_FUNCTION (this << frequency << flags);
+  m_channelFreq = frequency;
+  m_channelFlags = flags;
+
+  if (!(m_present & RADIOTAP_CHANNEL))
+    {
+      m_present |= RADIOTAP_CHANNEL;
+      m_length += 4;
+    }
+
+  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
+}
+
+uint16_t 
+RadiotapHeader::GetChannelFrequency (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_channelFreq;
+}
+
+uint16_t 
+RadiotapHeader::GetChannelFlags (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_channelFlags;
+}
+
+void 
+RadiotapHeader::SetAntennaSignalPower (int8_t signal)
+{
+  NS_LOG_FUNCTION (this << signal);
+  m_antennaSignal = signal;
+
+  if (!(m_present & RADIOTAP_DBM_ANTSIGNAL))
+    {
+      m_present |= RADIOTAP_DBM_ANTSIGNAL;
+      m_length += 1;
+    }
+
+  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
+}
+
+void 
+RadiotapHeader::SetAntennaSignalPower (double signal)
+{
+  NS_LOG_FUNCTION (this << signal);
+
+  if (signal < -128)
+    {
+      return SetAntennaSignalPower (static_cast<int8_t> (-128));
+    }
+
+  if (signal > 127)
+    {
+      return SetAntennaSignalPower (static_cast<int8_t> (127));
+    }
+  
+  SetAntennaSignalPower (static_cast<int8_t> (floor(signal + 0.5)));
+}
+
+uint8_t 
+RadiotapHeader::GetAntennaSignalPower (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_antennaSignal;
+}
+
+void 
+RadiotapHeader::SetAntennaNoisePower (int8_t noise)
+{
+  NS_LOG_FUNCTION (this << noise);
+  m_antennaNoise = noise;
+
+  if (!(m_present & RADIOTAP_DBM_ANTNOISE))
+    {
+      m_present |= RADIOTAP_DBM_ANTNOISE;
+      m_length += 1;
+    }
+
+  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
+}
+
+void 
+RadiotapHeader::SetAntennaNoisePower (double noise)
+{
+  NS_LOG_FUNCTION (this << noise);
+
+  if (noise < -128)
+    {
+      return SetAntennaNoisePower (static_cast<int8_t> (-128));
+    }
+
+  if (noise > 127)
+    {
+      return SetAntennaNoisePower (static_cast<int8_t> (127));
+    }
+  
+  SetAntennaNoisePower (static_cast<int8_t> (floor(noise + 0.5)));
+}
+
+uint8_t 
+RadiotapHeader::GetAntennaNoisePower (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_antennaNoise;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/radiotap-header.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,279 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * 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, Include., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef RADIOTAP_HEADER_H
+#define RADIOTAP_HEADER_H
+
+
+#include <ns3/header.h> 
+
+namespace ns3 {
+    
+/**
+ * @brief Radiotap header implementation
+ *
+ * Radiotap is a de facto standard for 802.11 frame injection and reception. 
+ * The radiotap header format is a mechanism to supply additional information 
+ * about frames, from the driver to userspace applications such as libpcap, and 
+ * from a userspace application to the driver for transmission. 
+ *
+ * @warning the radiotap header specification says that the fields included in
+ * the header should be aligned to their natural ize (e.g., 16-bit fields 
+ * aligned to 16-bit boundaries, 32-bit fields aligned to 32-bit boundaries, 
+ * and so on.  This implementation does not enforce this.  However, the radiotap
+ * specification enforces an order in which fields have to appear (if they 
+ * appear), and this ordering is such that, provided you don't leave gaps, all
+ * fields will end up aligned without the need of inserting padding space.  By 
+ * the term "gap" I mean not using a field which would appear between two used 
+ * fields.  Moral: don't leave gaps, or if you do be careful about how you
+ * do it.  
+ */
+class RadiotapHeader : public Header
+{
+public:
+  RadiotapHeader();
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+
+  /**
+   * This method is used by Packet::AddHeader to store the header into the byte
+   * buffer of a packet.  This method returns the number of bytes which are 
+   * needed to store the header data during a Serialize.
+   *
+   * @returns The expected size of the header.
+   */
+  virtual uint32_t GetSerializedSize (void) const;
+
+  /**
+   * This method is used by Packet::AddHeader to store the header into the byte
+   * buffer of a packet.  The data written is expected to match bit-for-bit the 
+   * representation of this header in a real network.
+   *
+   * @param start An iterator which points to where the header should
+   *              be written.
+   */
+  virtual void Serialize (Buffer::Iterator start) const;
+
+  /**
+   * This method is used by Packet::RemoveHeader to re-create a header from the 
+   * byte buffer of a packet.  The data read is expected to match bit-for-bit 
+   * the representation of this header in real networks.
+   *
+   * @param start An iterator which points to where the header should
+   *              written.
+   * @returns The number of bytes read.
+   */
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+  /**
+   * This method is used by Packet::Print to print the content of the header as 
+   * ascii data to a C++ output stream.  Although the header is free to format 
+   * its output as it wishes, it is recommended to follow a few rules to integrate
+   * with the packet pretty printer: start with flags, small field 
+   * values located between a pair of parens. Values should be separated 
+   * by whitespace. Follow the parens with the important fields, 
+   * separated by whitespace.
+   *
+   * eg: (field1 val1 field2 val2 field3 val3) field4 val4 field5 val5
+   *
+   * @param os The output stream
+   */
+  virtual void Print (std::ostream &os) const;
+    
+  /**
+   * @brief Set the Time Synchronization Function Timer (TSFT) value.  Valid for
+   * received frames only. 
+   *
+   * @param tsft Value in microseconds of the MAC's 64-bit 802.11 Time 
+   *             Synchronization Function timer when the first bit of the MPDU
+   *             arrived at the MAC.
+   */
+  void SetTsft (uint64_t tsft);
+
+  /**
+   * @brief Get the Time Synchronization Function Timer (TSFT) value.  Valid for
+   * received frames only. 
+   *
+   * @returns The value in microseconds of the MAC's 64-bit 802.11 Time 
+   *          Synchronization Function timer when the first bit of the MPDU
+   *          arrived at the MAC.
+   */
+  uint64_t GetTsft (void) const;
+
+  enum {
+    FRAME_FLAG_NONE           = 0x00, /**< No flags set */
+    FRAME_FLAG_CFP            = 0x01, /**< Frame sent/received during CFP */
+    FRAME_FLAG_SHORT_PREAMBLE = 0x02, /**< Frame sent/received with short preamble */
+    FRAME_FLAG_WEP            = 0x04, /**< Frame sent/received with WEP encryption */
+    FRAME_FLAG_FRAGMENTED     = 0x08, /**< Frame sent/received with fragmentation */
+    FRAME_FLAG_FCS_INCLUDED   = 0x10, /**< Frame includes FCS */
+    FRAME_FLAG_DATA_PADDING   = 0x20, /**< Frame has padding between 802.11 header and payload (to 32-bit boundary) */
+    FRAME_FLAG_BAD_FCS        = 0x40, /**< Frame failed FCS check */
+    FRAME_FLAG_SHORT_GUARD    = 0x80  /**< Frame used short guard interval (HT) */
+  };
+
+  /**
+   * @brief Set the frame flags of the transmitted or received frame.
+   * @param flags flags to set.
+   */
+  void SetFrameFlags (uint8_t flags);
+
+  /**
+   * @brief Get the frame flags of the transmitted or received frame.
+   * @returns The frame flags.
+   * @see FrameFlags.
+   */
+  uint8_t GetFrameFlags (void) const;
+
+  /**
+   * @brief Set the transmit/receive channel frequency in units of megahertz
+   * @param rate the transmit/receive channel frequency in units of megahertz.
+   */
+  void SetRate (uint8_t rate);
+
+  /**
+   * @brief Get the transmit/receive channel frequency in units of megahertz.
+   * @returns The transmit/receive channel frequency in units of megahertz.
+   */
+  uint8_t GetRate (void) const;
+
+  enum {
+    CHANNEL_FLAG_NONE          = 0x0000, /**< No flags set */
+    CHANNEL_FLAG_TURBO         = 0x0010, /**< Turbo Channel */
+    CHANNEL_FLAG_CCK           = 0x0020, /**< CCK channel */
+    CHANNEL_FLAG_OFDM          = 0x0040, /**< OFDM channel */
+    CHANNEL_FLAG_SPECTRUM_2GHZ = 0x0080, /**< 2 GHz spectrum channel */
+    CHANNEL_FLAG_SPECTRUM_5GHZ = 0x0100, /**< 5 GHz spectrum channel */
+    CHANNEL_FLAG_PASSIVE       = 0x0200, /**< Only passive scan allowed */
+    CHANNEL_FLAG_DYNAMIC       = 0x0400, /**< Dynamic CCK-OFDM channel */
+    CHANNEL_FLAG_GFSK          = 0x0800  /**< GFSK channel (FHSS PHY) */
+  };
+
+  /**
+   * @brief Set the transmit/receive channel frequency and flags
+   * @param frequency The transmit/receive data rate in units of 500 kbps.
+   * @param flags The flags to set.
+   * @see ChannelFlags
+   */
+  void SetChannelFrequencyAndFlags (uint16_t frequency, uint16_t flags);
+
+  /**
+   * @brief Get the transmit/receive data rate in units of 500 kbps.
+   * @returns The transmit/receive data rate in units of 500 kbps.
+   */
+  uint16_t GetChannelFrequency (void) const;
+    
+  /**
+   * @brief Get the channel flags of the transmitted or received frame.
+   * @returns The frame flags.
+   * @see ChannelFlags.
+   */
+  uint16_t GetChannelFlags (void) const;
+
+  /**
+   * @brief Set the RF signal power at the antenna as a decibel difference
+   * from an arbitrary, fixed reference. 
+   *
+   * @param signal The RF signal power at the antenna as a decibel difference
+   *               from an arbitrary, fixed reference. 
+   */
+  void SetAntennaSignalPower (int8_t signal);
+
+  /**
+   * @brief Set the RF signal power at the antenna as a decibel difference
+   * from an arbitrary, fixed reference. 
+   *
+   * @param signal The RF signal power at the antenna as a decibel difference
+   *               from an arbitrary, fixed reference;
+   */
+  void SetAntennaSignalPower (double signal);
+
+  /**
+   * @brief Get the RF signal power at the antenna as a decibel difference
+   * from an arbitrary, fixed reference. 
+   *
+   * @returns The RF signal power at the antenna as a decibel difference
+   *          from an arbitrary, fixed reference. 
+   */
+  uint8_t GetAntennaSignalPower (void) const;
+
+  /**
+   * @brief Set the RF noise power at the antenna as a decibel difference
+   * from an arbitrary, fixed reference. 
+   *
+   * @param noise The RF noise power at the antenna as a decibel difference
+   *              from an arbitrary, fixed reference. 
+   */
+  void SetAntennaNoisePower (int8_t noise);
+
+  /**
+   * @brief Set the RF noise power at the antenna as a decibel difference
+   * from an arbitrary, fixed reference. 
+   *
+   * @param noise The RF noise power at the antenna as a decibel difference
+   *              from an arbitrary, fixed reference. 
+   */
+  void SetAntennaNoisePower (double noise);
+
+  /**
+   * @brief Get the RF noise power at the antenna as a decibel difference
+   * from an arbitrary, fixed reference. 
+   *
+   * @returns The RF noise power at the antenna as a decibel difference
+   *          from an arbitrary, fixed reference. 
+   */
+  uint8_t GetAntennaNoisePower (void) const;
+
+private:
+  enum {
+    RADIOTAP_TSFT              = 0x00000001,
+    RADIOTAP_FLAGS             = 0x00000002,
+    RADIOTAP_RATE              = 0x00000004,
+    RADIOTAP_CHANNEL           = 0x00000008,
+    RADIOTAP_FHSS              = 0x00000010,
+    RADIOTAP_DBM_ANTSIGNAL     = 0x00000020,
+    RADIOTAP_DBM_ANTNOISE      = 0x00000040,
+    RADIOTAP_LOCK_QUALITY      = 0x00000080,
+    RADIOTAP_TX_ATTENUATION    = 0x00000100,
+    RADIOTAP_DB_TX_ATTENUATION = 0x00000200,
+    RADIOTAP_DBM_TX_POWER      = 0x00000200,
+    RADIOTAP_ANTENNA           = 0x00000400,
+    RADIOTAP_DB_ANTSIGNAL      = 0x00000800,
+    RADIOTAP_DB_ANTNOISE       = 0x00001000,
+    RADIOTAP_EXT               = 0x10000000
+  };
+ 
+    void CheckAddChannelField();
+    
+    uint16_t m_length;
+    uint32_t m_present;
+    
+    uint64_t m_tsft;
+    uint8_t m_flags;
+    uint8_t m_rate;
+    uint16_t m_channelFreq;
+    uint16_t m_channelFlags;
+    int8_t m_antennaSignal;
+    int8_t m_antennaNoise;
+};
+
+} // namespace ns3
+
+#endif /*  RADIOTAP_HEADER_H */
--- a/src/node/socket.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/node/socket.h	Thu Feb 25 14:17:21 2010 +0100
@@ -529,7 +529,7 @@
    * is also possible to bind to mismatching device and address, even if
    * the socket can not receive any packets as a result.
    *
-   * \param Netdevice Pointer to Netdevice of desired interface
+   * \param netdevice Pointer to Netdevice of desired interface
    * \returns nothing
    */
   virtual void BindToNetDevice (Ptr<NetDevice> netdevice);
--- a/src/node/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/node/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -48,6 +48,7 @@
         'ipv6-routing-protocol.cc',
         'packetbb.cc',
         'packetbb-test-suite.cc',
+        'radiotap-header.cc',
         ]
 
     headers = bld.new_task_gen('ns3header')
@@ -96,4 +97,5 @@
         'ipv6-raw-socket-factory.h',
         'ipv6-routing-protocol.h',
         'packetbb.h',
+        'radiotap-header.h',
         ]
--- a/src/routing/aodv/aodv-packet.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/routing/aodv/aodv-packet.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -40,9 +40,18 @@
 }
 
 TypeId
+TypeHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::aodv::TypeHeader")
+      .SetParent<Header> ()
+      ;
+  return tid;
+}
+
+TypeId
 TypeHeader::GetInstanceTypeId () const
 {
-  return TypeId ();
+  return GetTypeId ();
 }
 
 uint32_t
@@ -135,9 +144,19 @@
 }
 
 TypeId
+RreqHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::aodv::RreqHeader")
+      .SetParent<Header> ()
+      .AddConstructor<RreqHeader> ()
+      ;
+  return tid;
+}
+
+TypeId
 RreqHeader::GetInstanceTypeId () const
 {
-  return TypeId ();
+  return GetTypeId ();
 }
 
 uint32_t
@@ -262,9 +281,19 @@
 }
 
 TypeId
+RrepHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::aodv::RrepHeader")
+      .SetParent<Header> ()
+      .AddConstructor<RrepHeader> ()
+      ;
+  return tid;
+}
+
+TypeId
 RrepHeader::GetInstanceTypeId () const
 {
-  return TypeId ();
+  return GetTypeId ();
 }
 
 uint32_t
@@ -393,9 +422,19 @@
 }
 
 TypeId
+RrepAckHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::aodv::RrepAckHeader")
+      .SetParent<Header> ()
+      .AddConstructor<RrepAckHeader> ()
+      ;
+  return tid;
+}
+
+TypeId
 RrepAckHeader::GetInstanceTypeId () const
 {
-  return TypeId ();
+  return GetTypeId ();
 }
 
 uint32_t
@@ -447,9 +486,19 @@
 }
 
 TypeId
+RerrHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::aodv::RerrHeader")
+      .SetParent<Header> ()
+      .AddConstructor<RerrHeader> ()
+      ;
+  return tid;
+}
+
+TypeId
 RerrHeader::GetInstanceTypeId () const
 {
-  return TypeId ();
+  return GetTypeId ();
 }
 
 uint32_t
--- a/src/routing/aodv/aodv-packet.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/routing/aodv/aodv-packet.h	Thu Feb 25 14:17:21 2010 +0100
@@ -58,6 +58,7 @@
 
   ///\name Header serialization/deserialization
   //\{
+  static TypeId GetTypeId ();
   TypeId GetInstanceTypeId () const;
   uint32_t GetSerializedSize () const;
   void Serialize (Buffer::Iterator start) const;
@@ -109,6 +110,7 @@
 
   ///\name Header serialization/deserialization
   //\{
+  static TypeId GetTypeId ();
   TypeId GetInstanceTypeId () const;
   uint32_t GetSerializedSize () const;
   void Serialize (Buffer::Iterator start) const;
@@ -184,6 +186,7 @@
       Ipv4Address (), Time lifetime = MilliSeconds (0));
   ///\name Header serialization/deserialization
   //\{
+  static TypeId GetTypeId ();
   TypeId GetInstanceTypeId () const;
   uint32_t GetSerializedSize () const;
   void Serialize (Buffer::Iterator start) const;
@@ -248,6 +251,7 @@
 
   ///\name Header serialization/deserialization
   //\{
+  static TypeId GetTypeId ();
   TypeId GetInstanceTypeId () const;
   uint32_t GetSerializedSize () const;
   void Serialize (Buffer::Iterator start) const;
@@ -289,6 +293,7 @@
 
   ///\name Header serialization/deserialization
   //\{
+  static TypeId GetTypeId ();
   TypeId GetInstanceTypeId () const;
   uint32_t GetSerializedSize () const;
   void Serialize (Buffer::Iterator i) const;
--- a/src/routing/aodv/aodv-test-suite.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/routing/aodv/aodv-test-suite.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -474,7 +474,7 @@
     NS_TEST_EXPECT_MSG_EQ (rt.IsPrecursorListEmpty (), true, "trivial");
     rt.GetPrecursors (prec);
     NS_TEST_EXPECT_MSG_EQ (prec.size (), 2, "trivial");
-
+    Simulator::Destroy ();
     return GetErrorStatus ();
   }
 };
@@ -528,7 +528,7 @@
     NS_TEST_EXPECT_MSG_EQ (rt.GetFlag (), INVALID, "trivial");
     NS_TEST_EXPECT_MSG_EQ (rtable.DeleteRoute (Ipv4Address ("1.2.3.4")), true, "trivial");
     NS_TEST_EXPECT_MSG_EQ (rtable.DeleteRoute (Ipv4Address ("1.2.3.4")), false, "trivial");
-
+    Simulator::Destroy ();
     return GetErrorStatus ();
   }
 };
--- a/src/routing/global-routing/global-route-manager-impl.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/routing/global-routing/global-route-manager-impl.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -222,53 +222,6 @@
   return m_distanceFromRoot;
 }
 
-void 
-SPFVertex::SetOutgoingInterfaceId (int32_t id)
-{
-  NS_LOG_FUNCTION (id);
-
-  // always maintain only one output interface index when using setter/getter methods
-  m_rootOif = id;
-}
-
-uint32_t 
-SPFVertex::GetOutgoingInterfaceId (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_rootOif;
-}
-
-//void 
-//SPFVertex::MergeOutgoingInterfaceId (const SPFVertex* v)
-//{
-//  NS_LOG_FUNCTION (v);
-//
-//  NS_LOG_LOGIC ("Before merge, list of root out-going interfaces = " << m_rootOif);
-//  // combine the two lists first, and then remove any duplicated after
-//  m_rootOif.insert (m_rootOif.end (), 
-//    v->m_rootOif.begin (), v->m_rootOif.end ());
-//  // remove duplication
-//  m_rootOif.sort ();
-//  m_rootOif.unique ();
-//  NS_LOG_LOGIC ("After merge, list of root out-going interfaces = " << m_rootOif);
-//}
-
-  void 
-SPFVertex::SetNextHop (Ipv4Address nextHop)
-{
-  NS_LOG_FUNCTION (nextHop);
-
-  // always maintain only one nexthop when using setter/getter methods
-  m_nextHop = nextHop;
-}
-
-  Ipv4Address
-SPFVertex::GetNextHop (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_nextHop;
-}
-
   void
 SPFVertex::SetParent (SPFVertex* parent)
 {
@@ -1637,11 +1590,6 @@
           Ipv4Address tempip = extlsa->GetLinkStateId ();
           tempip = tempip.CombineMask (tempmask);
 
-          NS_LOG_LOGIC (" Node " << node->GetId () <<
-              " add route to " << tempip <<
-              " with mask " << tempmask <<
-              " using next hop " << v->GetNextHop () <<
-              " via interface " << v->GetOutgoingInterfaceId ());
 //
 // Here's why we did all of that work.  We're going to add a host route to the
 // host address found in the m_linkData field of the point-to-point link
@@ -1662,20 +1610,28 @@
             }
           Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
           NS_ASSERT (gr);
-          if (v->GetOutgoingInterfaceId () >= 0)
+          // walk through all next-hop-IPs and out-going-interfaces for reaching
+          // the stub network gateway 'v' from the root node
+          for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++)
             {
-              gr->AddASExternalRouteTo (tempip, tempmask, v->GetNextHop (), v->GetOutgoingInterfaceId ());
-              NS_LOG_LOGIC ("Node " << node->GetId () <<
-                  " add network route to " << tempip <<
-                  " using next hop " << v->GetNextHop () <<
-                  " via interface " << v->GetOutgoingInterfaceId ());
-            }
-          else
-            {
-              NS_LOG_LOGIC ("Node " << node->GetId () <<
-                  " NOT able to add network route to " << tempip <<
-                  " using next hop " << v->GetNextHop () <<
-                  " since outgoing interface id is negative");
+              SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i);
+              Ipv4Address nextHop = exit.first;
+              int32_t outIf = exit.second;
+              if (outIf >= 0)
+                {
+                  gr->AddASExternalRouteTo (tempip, tempmask, nextHop, outIf);
+                  NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+                    " add external network route to " << tempip <<
+                    " using next hop " << nextHop <<
+                    " via interface " << outIf);
+                }
+              else
+                {
+                  NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () <<
+                    " NOT able to add network route to " << tempip <<
+                    " using next hop " << nextHop <<
+                    " since outgoing interface id is negative");
+                }
             }
           return;
         } // if
--- a/src/routing/global-routing/global-route-manager-impl.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/routing/global-routing/global-route-manager-impl.h	Thu Feb 25 14:17:21 2010 +0100
@@ -256,183 +256,6 @@
   void SetDistanceFromRoot (uint32_t distance);
 
 /**
- * \deprecated Use GetRootExitDirection instead
- *
- * @brief Get the interface ID that should be used to begin forwarding packets
- * from the root SPFVertex to "this" SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the 
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set.  The "this" SPFVertex is the vertex that
- * represents the host or network to which a route is being calculated from 
- * the root.  The outgoing interface that we're asking for is the interface
- * index on the root node that should be used to start packets along the
- * path to "this" vertex.
- *
- * When initializing the root SPFVertex, the interface ID is determined by
- * examining the Global Router Link Records of the Link State Advertisement
- * generated by the root node's GlobalRouter.  These interfaces are used to 
- * forward packets off of the root's network down those links.  As other 
- * vertices are discovered which are further away from the root, they will 
- * be accessible down one of the paths begun by a Global Router Link Record.
- * 
- * To forward packets to these hosts or networks, the root node must begin
- * the forwarding process by sending the packets to the interface of that
- * first hop.  This means that the first hop address and interface ID must
- * be the same for all downstream SPFVertices.  We call this "inheriting"
- * the interface and next hop.
- *
- * In this method, the root node is asking, "which of my local interfaces
- * should I use to get a packet to the network or host represented by 'this'
- * SPFVertex."
- *
- * @see GlobalRouter
- * @see GlobalRoutingLSA
- * @see GlobalRoutingLinkRecord
- * @returns The interface index to use when forwarding packets to the host
- * or network represented by "this" SPFVertex.
- */
-  uint32_t GetOutgoingInterfaceId (void) const NS_DEPRECATED;
-
-/**
- * \deprecated Use SetRootExitDirection instead
- *
- * @brief Set the interface ID that should be used to begin forwarding packets
- * from the root SPFVertex to "this" SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the 
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set.  The "this" SPFVertex is the vertex that
- * represents the host or network to which a route is being calculated from 
- * the root.  The outgoing interface that we're asking for is the interface
- * index on the root node that should be used to start packets along the
- * path to "this" vertex.
- *
- * When initializing the root SPFVertex, the interface ID is determined by
- * examining the Global Router Link Records of the Link State Advertisement
- * generated by the root node's GlobalRouter.  These interfaces are used to 
- * forward packets off of the root's network down those links.  As other 
- * vertices are discovered which are further away from the root, they will 
- * be accessible down one of the paths begun by a Global Router Link Record.
- * 
- * To forward packets to these hosts or networks, the root node must begin
- * the forwarding process by sending the packets to the interface of that
- * first hop.  This means that the first hop address and interface ID must
- * be the same for all downstream SPFVertices.  We call this "inheriting"
- * the interface and next hop.
- *
- * In this method, we are letting the root node know which of its local
- * interfaces it should use to get a packet to the network or host represented
- * by "this" SPFVertex.
- *
- * @see GlobalRouter
- * @see GlobalRoutingLSA
- * @see GlobalRoutingLinkRecord
- * @param id The interface index to use when forwarding packets to the host or
- * network represented by "this" SPFVertex.
- */
-  void SetOutgoingInterfaceId (int32_t id) NS_DEPRECATED;
-
-/**
- * \deprecated Use GetRootExitDirection instead
- *
- * @brief Get the IP address that should be used to begin forwarding packets 
- * from the root SPFVertex to "this" SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the 
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set.  The "this" SPFVertex is the vertex that
- * represents the host or network to which a route is being calculated from 
- * the root.  The IP address that we're asking for is the address on the 
- * remote side of a link off of the root node that should be used as the
- * destination for packets along the path to "this" vertex.
- *
- * When initializing the root SPFVertex, the IP address used when forwarding
- * packets is determined by examining the Global Router Link Records of the
- * Link State Advertisement generated by the root node's GlobalRouter.  This
- * address is used to forward packets off of the root's network down those
- * links.  As other vertices / nodes are discovered which are further away
- * from the root, they will be accessible down one of the paths via a link
- * described by one of these Global Router Link Records.
- * 
- * To forward packets to these hosts or networks, the root node must begin
- * the forwarding process by sending the packets to a first hop router down
- * an interface.  This means that the first hop address and interface ID must
- * be the same for all downstream SPFVertices.  We call this "inheriting"
- * the interface and next hop.
- *
- * In this method, the root node is asking, "which router should I send a
- * packet to in order to get that packet to the network or host represented 
- * by 'this' SPFVertex."
- *
- * @see GlobalRouter
- * @see GlobalRoutingLSA
- * @see GlobalRoutingLinkRecord
- * @returns The IP address to use when forwarding packets to the host
- * or network represented by "this" SPFVertex.
- */
-  Ipv4Address GetNextHop (void) const NS_DEPRECATED;
-
-/**
- * \deprecated Use SetRootExitDirection instead
- *
- * @brief Set the IP address that should be used to begin forwarding packets 
- * from the root SPFVertex to "this" SPFVertex.
- * @internal
- *
- * Each router node in the simulation is associated with an SPFVertex object.
- * When calculating routes, each of these routers is, in turn, chosen as the 
- * "root" of the calculation and routes to all of the other routers are
- * eventually saved in the routing tables of each of the chosen nodes.
- *
- * The "Root" vertex is then the SPFVertex representing the router that is
- * having its routing tables set.  The "this" SPFVertex is the vertex that
- * represents the host or network to which a route is being calculated from 
- * the root.  The IP address that we're asking for is the address on the 
- * remote side of a link off of the root node that should be used as the
- * destination for packets along the path to "this" vertex.
- *
- * When initializing the root SPFVertex, the IP address used when forwarding
- * packets is determined by examining the Global Router Link Records of the
- * Link State Advertisement generated by the root node's GlobalRouter.  This
- * address is used to forward packets off of the root's network down those
- * links.  As other vertices / nodes are discovered which are further away
- * from the root, they will be accessible down one of the paths via a link
- * described by one of these Global Router Link Records.
- * 
- * To forward packets to these hosts or networks, the root node must begin
- * the forwarding process by sending the packets to a first hop router down
- * an interface.  This means that the first hop address and interface ID must
- * be the same for all downstream SPFVertices.  We call this "inheriting"
- * the interface and next hop.
- *
- * In this method we are telling the root node which router it should send
- * should I send a packet to in order to get that packet to the network or
- * host represented by 'this' SPFVertex."
- *
- * @see GlobalRouter
- * @see GlobalRoutingLSA
- * @see GlobalRoutingLinkRecord
- * @param nextHop The IP address to use when forwarding packets to the host
- * or network represented by "this" SPFVertex.
- */
-  void SetNextHop (Ipv4Address nextHop) NS_DEPRECATED;
-/**
  * @brief Set the IP address and outgoing interface index that should be used 
  * to begin forwarding packets from the root SPFVertex to "this" SPFVertex.
  * @internal
--- a/src/routing/nix-vector-routing/ipv4-nix-vector-routing.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/routing/nix-vector-routing/ipv4-nix-vector-routing.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -117,7 +117,7 @@
 }
 
 Ptr<NixVector>
-Ipv4NixVectorRouting::GetNixVector (Ptr<Node> source, Ipv4Address dest)
+Ipv4NixVectorRouting::GetNixVector (Ptr<Node> source, Ipv4Address dest, Ptr<NetDevice> oif)
 {
   NS_LOG_FUNCTION_NOARGS ();
 
@@ -146,7 +146,8 @@
       // otherwise proceed as normal 
       // and build the nix vector
       std::vector< Ptr<Node> > parentVector;
-      BFS (NodeList::GetNNodes (), source, destNode, parentVector);
+
+      BFS (NodeList::GetNNodes (), source, destNode, parentVector, oif);
 
       if (BuildNixVector (parentVector, source->GetId (), destNode->GetId (), nixVector))
         {
@@ -495,7 +496,7 @@
       NS_LOG_LOGIC ("Nix-vector not in cache, build: ");
       // Build the nix-vector, given this node and the
       // dest IP address
-      nixVectorInCache = GetNixVector (m_node, header.GetDestination ());
+      nixVectorInCache = GetNixVector (m_node, header.GetDestination (), oif);
 
       // cache it
       m_nixCache.insert (NixMap_t::value_type (header.GetDestination (), nixVectorInCache));
@@ -523,18 +524,38 @@
       uint32_t numberOfBits = nixVectorForPacket->BitCount (m_totalNeighbors);
       uint32_t nodeIndex = nixVectorForPacket->ExtractNeighborIndex (numberOfBits);
 
-      // Possibly search here in a cache for this node index 
-      // and look for a Ipv4Route.  If we have it, don't 
-      // need to do the next 3 lines.
+      // Search here in a cache for this node index 
+      // and look for a Ipv4Route
       rtentry = GetIpv4RouteInCache (header.GetDestination ());
-      // not in cache
-      if (!rtentry)
+
+      if (!rtentry || !(rtentry->GetOutputDevice () == oif))
         {
+          // not in cache or a different specified output
+          // device is to be used
+
+          // first, make sure we erase existing (incorrect)
+          // rtentry from the map
+          if (rtentry)
+            {
+              m_ipv4RouteCache.erase(header.GetDestination ());
+            }
+
           NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
           Ipv4Address gatewayIp;
           uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
+          int32_t interfaceIndex = 0;
 
-          uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index));
+          if (!oif)
+            {
+              interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index));
+            }
+          else
+            {
+              interfaceIndex = (m_ipv4)->GetInterfaceForDevice(oif);
+            }
+
+          NS_ASSERT_MSG (interfaceIndex != -1, "Interface index not found for device");
+
           Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
 
           // start filling in the Ipv4Route info
@@ -543,7 +564,15 @@
 
           rtentry->SetGateway (gatewayIp);
           rtentry->SetDestination (header.GetDestination ());
-          rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
+
+          if (!oif)
+            {
+              rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
+            }
+          else
+            {
+              rtentry->SetOutputDevice (oif);
+            }
 
           sockerr = Socket::ERROR_NOTERROR;
 
@@ -582,143 +611,50 @@
   // Get the nix-vector from the packet
   Ptr<NixVector> nixVector = p->GetNixVector();
 
-  // make sure it exists, if not something
-  // went wrong
-  if (!nixVector)
-    {
-      NS_LOG_ERROR ("Nix-vector wasn't in the packet! Rebuild.");
-
-      Ptr<NixVector> nixVectorInCache;
-
-      NS_LOG_DEBUG ("Dest IP from header: " << header.GetDestination ());
-
-      // check if cache
-      nixVectorInCache = GetNixVectorInCache(header.GetDestination ());
-
-      // not in cache
-      if (!nixVectorInCache)
-        {
-          NS_LOG_LOGIC ("RouteInput(): Nix-vector not in cache, build: ");
-
-          // Build the nix-vector, given this node and the
-          // dest IP address
-          nixVectorInCache = GetNixVector (m_node, header.GetDestination ());
-        }
-
-      // path exists
-      if (nixVectorInCache)
-        {
-          NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache);
-
-          // cache it
-          m_nixCache.insert(NixMap_t::value_type(header.GetDestination (), nixVectorInCache));
+  // If nixVector isn't in packet, something went wrong
+  NS_ASSERT (nixVector);
 
-          // create a new nix vector to be used, 
-          // we want to keep the cached version clean
-          Ptr<NixVector> nixVectorForPacket;
-          nixVectorForPacket = CreateObject<NixVector> ();
-          nixVectorForPacket = nixVectorInCache->Copy(); 
-
-          // Get the interface number that we go out of, by extracting
-          // from the nix-vector
-          if (m_totalNeighbors == 0)
-            {
-              m_totalNeighbors = FindTotalNeighbors ();
-            }
-          uint32_t numberOfBits = nixVectorForPacket->BitCount (m_totalNeighbors);
-          uint32_t nodeIndex = nixVectorForPacket->ExtractNeighborIndex (numberOfBits);
+  // Get the interface number that we go out of, by extracting
+  // from the nix-vector
+  if (m_totalNeighbors == 0)
+    {
+      m_totalNeighbors = FindTotalNeighbors ();
+    }
+  uint32_t numberOfBits = nixVector->BitCount (m_totalNeighbors);
+  uint32_t nodeIndex = nixVector->ExtractNeighborIndex (numberOfBits);
 
-          rtentry = GetIpv4RouteInCache (header.GetDestination ());
-          // not in cache
-          if (!rtentry)
-            {
-              NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
-              Ipv4Address gatewayIp;
-              uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
-
-              uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index));
-              Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
-
-              // start filling in the Ipv4Route info
-              rtentry = Create<Ipv4Route> ();
-              rtentry->SetSource (ifAddr.GetLocal ());
-
-              rtentry->SetGateway (Ipv4Address(gatewayIp));
-              rtentry->SetDestination (header.GetDestination ());
-              rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
-
-              // add rtentry to cache
-              m_ipv4RouteCache.insert(Ipv4RouteMap_t::value_type(header.GetDestination (), rtentry));
-            }
+  rtentry = GetIpv4RouteInCache (header.GetDestination ());
+  // not in cache
+  if (!rtentry)
+    {
+      NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
+      Ipv4Address gatewayIp;
+      uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
+      uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index));
+      Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
 
-          NS_LOG_LOGIC ("Nix-vector contents: " << *nixVectorInCache << " : Remaining bits: " << nixVectorForPacket->GetRemainingBits());
-
-          // Add  nix-vector in the packet class 
-          // have to copy the packet first b/c 
-          // it is const
-          Ptr<Packet> newPacket = Create<Packet> ();
-          newPacket = p->Copy();
-
-          NS_LOG_LOGIC ("Adding Nix-vector to packet: " << *nixVectorForPacket);
-          newPacket->SetNixVector(nixVectorForPacket);
+      // start filling in the Ipv4Route info
+      rtentry = Create<Ipv4Route> ();
+      rtentry->SetSource (ifAddr.GetLocal ());
 
-          // call the unicast callback
-          // local deliver is handled by Ipv4StaticRoutingImpl
-          // so this code is never even called if the packet is
-          // destined for this node.
-          ucb (rtentry, newPacket, header);
-          return true;
-        }
-      else // path doesn't exist
-        {
-          NS_LOG_ERROR ("No path to the dest: " << header.GetDestination ());
-          return false;
-        }
+      rtentry->SetGateway (gatewayIp);
+      rtentry->SetDestination (header.GetDestination ());
+      rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
+
+      // add rtentry to cache
+      m_ipv4RouteCache.insert(Ipv4RouteMap_t::value_type(header.GetDestination (), rtentry));
     }
-  else
-    {
-      // Get the interface number that we go out of, by extracting
-      // from the nix-vector
-      if (m_totalNeighbors == 0)
-        {
-          m_totalNeighbors = FindTotalNeighbors ();
-        }
-      uint32_t numberOfBits = nixVector->BitCount (m_totalNeighbors);
-      uint32_t nodeIndex = nixVector->ExtractNeighborIndex (numberOfBits);
 
-      rtentry = GetIpv4RouteInCache (header.GetDestination ());
-      // not in cache
-      if (!rtentry)
-        {
-          NS_LOG_LOGIC ("Ipv4Route not in cache, build: ");
-          Ipv4Address gatewayIp;
-          uint32_t index = FindNetDeviceForNixIndex (nodeIndex, gatewayIp);
-          uint32_t interfaceIndex = (m_ipv4)->GetInterfaceForDevice(m_node->GetDevice(index));
-          Ipv4InterfaceAddress ifAddr = m_ipv4->GetAddress (interfaceIndex, 0);
+  NS_LOG_LOGIC ("At Node " << m_node->GetId() << ", Extracting " << numberOfBits << 
+                       " bits from Nix-vector: " << nixVector << " : " << *nixVector);
 
-          // start filling in the Ipv4Route info
-          rtentry = Create<Ipv4Route> ();
-          rtentry->SetSource (ifAddr.GetLocal ());
-
-          rtentry->SetGateway (gatewayIp);
-          rtentry->SetDestination (header.GetDestination ());
-          rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIndex));
-
-          // add rtentry to cache
-          m_ipv4RouteCache.insert(Ipv4RouteMap_t::value_type(header.GetDestination (), rtentry));
-        }
+  // call the unicast callback
+  // local deliver is handled by Ipv4StaticRoutingImpl
+  // so this code is never even called if the packet is
+  // destined for this node.
+  ucb (rtentry, p, header);
 
-      NS_LOG_LOGIC ("At Node " << m_node->GetId() << ", Extracting " << numberOfBits << 
-                           " bits from Nix-vector: " << nixVector << " : " << *nixVector);
-
-      // call the unicast callback
-      // local deliver is handled by Ipv4StaticRoutingImpl
-      // so this code is never even called if the packet is
-      // destined for this node.
-      ucb (rtentry, p, header);
-
-      return true;
-    }
+  return true;
 }
 
 // virtual functions from Ipv4RoutingProtocol 
@@ -744,7 +680,9 @@
 }
 
 bool
-Ipv4NixVectorRouting::BFS (uint32_t numberOfNodes, Ptr<Node> source, Ptr<Node> dest, std::vector< Ptr<Node> > & parentVector)
+Ipv4NixVectorRouting::BFS (uint32_t numberOfNodes, Ptr<Node> source, 
+                           Ptr<Node> dest, std::vector< Ptr<Node> > & parentVector,
+                           Ptr<NetDevice> oif)
 {
   NS_LOG_FUNCTION_NOARGS ();
 
@@ -772,41 +710,36 @@
           return true;
         }
 
-
-      // Iterate over the current node's adjacent vertices
-      // and push them into the queue
-      for (uint32_t i = 0; i < (currNode->GetNDevices ()); i++)
+      // if this is the first iteration of the loop and a 
+      // specific output interface was given, make sure 
+      // we go this way
+      if (currNode == source && oif)
         {
-          // Get a net device from the node
-          // as well as the channel, and figure
-          // out the adjacent net device
-          Ptr<NetDevice> localNetDevice = currNode->GetDevice (i);
-
           // make sure that we can go this way
           if (ipv4)
             {
-              uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(currNode->GetDevice(i));
+              uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(oif);
               if (!(ipv4->IsUp (interfaceIndex)))
                 {
                   NS_LOG_LOGIC ("Ipv4Interface is down");
-                  continue;
+                  return false;
                 }
             }
-            if (!(localNetDevice->IsLinkUp ()))
-              {
-                NS_LOG_LOGIC ("Link is down.");
-                continue;
-              }
-          Ptr<Channel> channel = localNetDevice->GetChannel ();
+          if (!(oif->IsLinkUp ()))
+            {
+              NS_LOG_LOGIC ("Link is down.");
+              return false;
+            }
+          Ptr<Channel> channel = oif->GetChannel ();
           if (channel == 0)
             { 
-              continue;
+              return false;
             }
 
           // this function takes in the local net dev, and channnel, and
           // writes to the netDeviceContainer the adjacent net devs
           NetDeviceContainer netDeviceContainer;
-          GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
+          GetAdjacentNetDevices (oif, channel, netDeviceContainer);
 
           // Finally we can get the adjacent nodes
           // and scan through them.  We push them
@@ -827,6 +760,63 @@
                 }
             }
         }
+      else
+        {
+          // Iterate over the current node's adjacent vertices
+          // and push them into the queue
+          for (uint32_t i = 0; i < (currNode->GetNDevices ()); i++)
+            {
+              // Get a net device from the node
+              // as well as the channel, and figure
+              // out the adjacent net device
+              Ptr<NetDevice> localNetDevice = currNode->GetDevice (i);
+
+              // make sure that we can go this way
+              if (ipv4)
+                {
+                  uint32_t interfaceIndex = (ipv4)->GetInterfaceForDevice(currNode->GetDevice(i));
+                  if (!(ipv4->IsUp (interfaceIndex)))
+                    {
+                      NS_LOG_LOGIC ("Ipv4Interface is down");
+                      continue;
+                    }
+                }
+                if (!(localNetDevice->IsLinkUp ()))
+                  {
+                    NS_LOG_LOGIC ("Link is down.");
+                    continue;
+                  }
+              Ptr<Channel> channel = localNetDevice->GetChannel ();
+              if (channel == 0)
+                { 
+                  continue;
+                }
+
+              // this function takes in the local net dev, and channnel, and
+              // writes to the netDeviceContainer the adjacent net devs
+              NetDeviceContainer netDeviceContainer;
+              GetAdjacentNetDevices (localNetDevice, channel, netDeviceContainer);
+
+              // Finally we can get the adjacent nodes
+              // and scan through them.  We push them
+              // to the greyNode queue, if they aren't 
+              // already there.
+              for (NetDeviceContainer::Iterator iter = netDeviceContainer.Begin (); iter != netDeviceContainer.End (); iter++)
+                {
+                  Ptr<Node> remoteNode = (*iter)->GetNode ();
+
+                  // check to see if this node has been pushed before
+                  // by checking to see if it has a parent
+                  // if it doesn't (null or 0), then set its parent and 
+                  // push to the queue
+                  if (parentVector.at (remoteNode->GetId ()) == 0)
+                    {
+                      parentVector.at (remoteNode->GetId ()) = currNode;
+                      greyNodeList.push (remoteNode);
+                    }
+                }
+            }
+        }
 
       // Pop off the head grey node.  We have all its children.
       // It is now black.
--- a/src/routing/nix-vector-routing/ipv4-nix-vector-routing.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/routing/nix-vector-routing/ipv4-nix-vector-routing.h	Thu Feb 25 14:17:21 2010 +0100
@@ -53,7 +53,7 @@
      *
      * @param node Node pointer 
      */
-    void SetNode (Ptr<Node>);
+    void SetNode (Ptr<Node> node);
 
     /** 
      * @brief Called when run-time link topology change occurs 
@@ -78,9 +78,9 @@
     void ResetTotalNeighbors (void);
 
     /*  takes in the source node and dest IP and calls GetNodeByIp, 
-     *  BFS, and BuildNixVector to finally return the built 
-     *  nix-vector */
-    Ptr<NixVector> GetNixVector (Ptr<Node>, Ipv4Address);
+     *  BFS, accounting for any output interface specified, and finally 
+     *  BuildNixVector to return the built nix-vector */
+    Ptr<NixVector> GetNixVector (Ptr<Node>, Ipv4Address, Ptr<NetDevice>);
 
     /* checks the cache based on dest IP for the nix-vector */
     Ptr<NixVector> GetNixVectorInCache (Ipv4Address);
@@ -124,7 +124,8 @@
     bool BFS (uint32_t numberOfNodes, 
              Ptr<Node> source, 
              Ptr<Node> dest, 
-             std::vector< Ptr<Node> > & parentVector);
+             std::vector< Ptr<Node> > & parentVector,
+             Ptr<NetDevice> oif);
 
     void DoDispose (void);
 
--- a/src/routing/olsr/olsr-routing-protocol.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/routing/olsr/olsr-routing-protocol.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -72,7 +72,7 @@
 /********** Holding times **********/
 
 /// Neighbor holding time.
-#define OLSR_NEIGHB_HOLD_TIME	(Scalar (3) * m_helloInterval)
+#define OLSR_NEIGHB_HOLD_TIME	(Scalar (3) * OLSR_REFRESH_INTERVAL)
 /// Top holding time.
 #define OLSR_TOP_HOLD_TIME	(Scalar (3) * m_tcInterval)
 /// Dup holding time.
@@ -2610,8 +2610,6 @@
 RoutingProtocol::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
 {  
   NS_LOG_FUNCTION (this << " " << m_ipv4->GetObject<Node> ()->GetId() << " " << header.GetDestination () << " " << oif);
-  // TBD:  oif is unused; can be used to restrict the outgoing interface
-  // of the found route if application bound to a source interface
   Ptr<Ipv4Route> rtentry;
   RoutingTableEntry entry1, entry2;
   if (Lookup (header.GetDestination (), entry1) != 0)
@@ -2621,9 +2619,22 @@
         {
           NS_FATAL_ERROR ("FindSendEntry failure");
         }
+      uint32_t interfaceIdx = entry2.interface;
+      if (oif && m_ipv4->GetInterfaceForDevice (oif) != static_cast<int> (interfaceIdx))
+        {
+          // We do not attempt to perform a constrained routing search
+          // if the caller specifies the oif; we just enforce that 
+          // that the found route matches the requested outbound interface 
+          NS_LOG_DEBUG ("Olsr node " << m_mainAddress 
+                        << ": RouteOutput for dest=" << header.GetDestination ()
+                        << " Route interface " << interfaceIdx 
+                        << " does not match requested output interface "
+                        << m_ipv4->GetInterfaceForDevice (oif));
+          sockerr = Socket::ERROR_NOROUTETOHOST;
+          return rtentry;
+        }
       rtentry = Create<Ipv4Route> ();
       rtentry->SetDestination (header.GetDestination ());
-      uint32_t interfaceIdx = entry2.interface;
       // the source address is the interface address that matches
       // the destination address (when multiple are present on the 
       // outgoing interface, one is selected via scoping rules)
@@ -2804,7 +2815,7 @@
 
 
 std::vector<RoutingTableEntry>
-RoutingProtocol::GetEntries () const
+RoutingProtocol::GetRoutingTableEntries () const
 {
   std::vector<RoutingTableEntry> retval;
   for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
--- a/src/routing/olsr/olsr-routing-protocol.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/routing/olsr/olsr-routing-protocol.h	Thu Feb 25 14:17:21 2010 +0100
@@ -100,6 +100,11 @@
   /// 
   void Dump (void);
 
+  /**
+   * Return the list of routing table entries discovered by OLSR
+   **/
+  std::vector<RoutingTableEntry> GetRoutingTableEntries () const;
+
 protected:
   virtual void DoStart (void);
 private:
@@ -133,7 +138,6 @@
 	
   void Clear ();
   uint32_t GetSize () const { return m_table.size (); }
-  std::vector<RoutingTableEntry> GetEntries () const;
   void RemoveEntry (const Ipv4Address &dest);
   void AddEntry (const Ipv4Address &dest,
                  const Ipv4Address &next,
--- a/src/routing/olsr/olsr.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/routing/olsr/olsr.h	Thu Feb 25 14:17:21 2010 +0100
@@ -36,8 +36,6 @@
  * Here is a summary of software's main features:
  * - Mostly compliant with OLSR as documented in RFC 3626 (http://www.ietf.org/rfc/rfc3626.txt), with the following differences:
  *  - The use of multiple interfaces was not supported by the NS-2 version, but is supported in NS-3;
- *  - Unlike the NS-2 version, does not yet support MAC layer feedback as described in RFC 3626;
- *  - HNA (Host/Network Association) messages are almost-but-not-quite supported in this version.
  *
  * \section api API and Usage
  * 
@@ -53,6 +51,21 @@
  * to set OLSR attributes.  These include HelloInterval, TcInterval,
  * MidInterval, Willingness.  Other parameters are defined as macros
  * in olsr-routing-protocol.cc.
+ *
+ * \section list Open Issues
+ *
+ * - OLSR does not repond to the routing event notifications correspondingg
+ * to dynamic interface up and down (RoutingProtocol::NotifyInterfaceUp and
+ * RoutingProtocol::NotifyInterfaceDown) or address insertion/removal
+ * (RoutingProtocol::NotifyAddAddress and 
+ * RoutingProtocol::NotifyRemoveAddress).
+ * - HNA (Host/Network Association) messages are almost-but-not-quite supported in this version.
+ * - Unlike the NS-2 version, does not yet support MAC layer feedback as described in RFC 3626;
+ * - If a user binds a socket to a particular output device, OLSR will not
+ * consider that constraint in its route selection for locally originated
+ * packets
+ *   
+ * 
  */
 
 
--- a/src/simulator/simulator.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/simulator/simulator.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -291,6 +291,10 @@
 Simulator::Remove (const EventId &ev)
 {
   NS_LOG_FUNCTION (&ev);
+  if (*PeekImpl () == 0)
+    {
+      return;
+    }
   return GetImpl ()->Remove (ev);
 }
 
@@ -298,6 +302,10 @@
 Simulator::Cancel (const EventId &ev)
 {
   NS_LOG_FUNCTION (&ev);
+  if (*PeekImpl () == 0)
+    {
+      return;
+    }
   return GetImpl ()->Cancel (ev);
 }
 
@@ -305,6 +313,10 @@
 Simulator::IsExpired (const EventId &id)
 {
   NS_LOG_FUNCTION (&id);
+  if (*PeekImpl () == 0)
+    {
+      return true;
+    }
   return GetImpl ()->IsExpired (id);
 }
 
@@ -324,7 +336,6 @@
 uint32_t
 Simulator::GetContext (void)
 {
-  NS_LOG_FUNCTION_NOARGS ();
   return GetImpl ()->GetContext ();
 }
 
--- a/src/simulator/simulator.h	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/simulator/simulator.h	Thu Feb 25 14:17:21 2010 +0100
@@ -75,7 +75,7 @@
   static Ptr<SimulatorImpl> GetImplementation (void);
 
   /**
-   * \param scheduler a new event scheduler
+   * \param schedulerFactory a new event scheduler factory
    *
    * The event scheduler can be set at any time: the events scheduled
    * in the previous scheduler will be transfered to the new scheduler
--- a/src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -323,7 +323,7 @@
 
   if (m_writeResults)
     {
-      PointToPointHelper::EnablePcapAll ("tcp-cwnd");
+      pointToPoint.EnablePcapAll ("tcp-cwnd");
     }
 
   Simulator::Stop (Seconds(2));
@@ -490,7 +490,8 @@
   if (m_writeResults)
     {
       // Write a pcap for tcp cwnd testcase with out-of-order delivery
-      PointToPointHelper::EnablePcapAll ("tcp-cwnd-ood");
+      PointToPointHelper pointToPoint;
+      pointToPoint.EnablePcapAll ("tcp-cwnd-ood");
     }
 
   // Finally, set up the simulator to run.
--- a/src/test/ns3tcp/ns3tcp-interop-test-suite.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/test/ns3tcp/ns3tcp-interop-test-suite.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -87,7 +87,7 @@
   virtual bool DoRun (void);
   virtual void DoTeardown (void);
 
-  void Ipv4L3Tx (std::string context, Ptr<const Packet> packet, uint32_t interfaceIndex);
+  void Ipv4L3Tx (std::string context, Ptr<const Packet> packet, Ptr<Ipv4> ipv4, uint32_t interface);
 
   std::string m_pcapFilename;
   PcapFile m_pcapFile;
@@ -131,7 +131,7 @@
 }
 
 void
-Ns3TcpInteroperabilityTestCase::Ipv4L3Tx (std::string context, Ptr<const Packet> packet, uint32_t interfaceIndex)
+Ns3TcpInteroperabilityTestCase::Ipv4L3Tx (std::string context, Ptr<const Packet> packet, Ptr<Ipv4> ipv4, uint32_t interface)
 {
   //
   // We're not testing IP so remove and toss the header.  In order to do this,
@@ -282,7 +282,7 @@
 
   if (m_writeVectors)
     {
-      PointToPointHelper::EnablePcapAll ("tcp-interop");
+      pointToPoint.EnablePcapAll ("tcp-interop");
     }
 
   Simulator::Stop (Seconds(20));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/ns3tcp/ns3tcp-socket-test-suite.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,360 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 University of Washington
+ *
+ * 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
+ */
+
+#include "ns3/log.h"
+#include "ns3/abort.h"
+#include "ns3/test.h"
+#include "ns3/pcap-file.h"
+#include "ns3/config.h"
+#include "ns3/string.h"
+#include "ns3/uinteger.h"
+#include "ns3/data-rate.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/point-to-point-helper.h"
+#include "ns3/csma-helper.h"
+#include "ns3/internet-stack-helper.h"
+#include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/ipv4-address-helper.h"
+#include "ns3/packet-sink-helper.h"
+#include "ns3/tcp-socket-factory.h"
+#include "ns3/node-container.h"
+#include "ns3/simulator.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("Ns3SocketTest");
+
+// ===========================================================================
+// Tests of TCP implementations from the application/socket perspective
+// ===========================================================================
+//
+//
+//  Simple class to write data to sockets
+class SocketWriter : public Application
+{
+public:
+  SocketWriter ();
+  virtual ~SocketWriter ();
+  void Setup (Ptr<Node> node, Address peer);
+  void Connect ();
+  void Write (uint32_t numBytes);
+  void Close ();
+
+private:
+  virtual void StartApplication (void);
+  virtual void StopApplication (void);
+  Address m_peer;
+  Ptr<Node> m_node;
+  Ptr<Socket> m_socket;
+  bool m_isSetup;
+  bool m_isConnected;
+};
+
+SocketWriter::SocketWriter () : m_node (0), m_socket (0), m_isSetup (false), m_isConnected (false)
+{
+}
+
+SocketWriter::~SocketWriter ()
+{
+  m_socket = 0;
+  m_node = 0;
+}
+
+void
+SocketWriter::StartApplication ()
+{
+  m_socket = Socket::CreateSocket (m_node, TcpSocketFactory::GetTypeId ());
+  m_socket->Bind ();
+}
+
+void
+SocketWriter::StopApplication ()
+{
+}
+
+void
+SocketWriter::Setup (Ptr<Node> node, Address peer)
+{
+  m_peer = peer;
+  m_node = node;
+  m_isSetup = true;
+}
+
+void
+SocketWriter::Connect ()
+{
+  if (!m_isSetup)
+    {
+      NS_FATAL_ERROR ("Forgot to call Setup() first");
+    }
+  m_socket->Connect (m_peer);
+  m_isConnected = true;
+}
+
+void
+SocketWriter::Write (uint32_t numBytes)
+{
+  if (!m_isConnected)
+    {
+      Connect ();
+    }
+  Ptr<Packet> packet = Create<Packet> (numBytes);
+  m_socket->Send (packet);
+}
+
+void
+SocketWriter::Close ()
+{
+  m_socket->Close ();
+}
+
+class Ns3TcpSocketTestCase1 : public TestCase
+{
+public:
+  Ns3TcpSocketTestCase1 ();
+  virtual ~Ns3TcpSocketTestCase1 () {}
+
+private:
+  virtual bool DoRun (void);
+  bool m_writeResults;
+
+  void SinkRx (std::string path, Ptr<const Packet> p, const Address &address);
+
+  TestVectors<uint32_t> m_inputs;
+  TestVectors<uint32_t> m_responses;
+};
+
+Ns3TcpSocketTestCase1::Ns3TcpSocketTestCase1 ()
+  : TestCase ("Check that ns-3 TCP successfully transfers an application data write of various sizes (point-to-point)"),
+    m_writeResults (false)
+{
+}
+
+void 
+Ns3TcpSocketTestCase1::SinkRx (std::string path, Ptr<const Packet> p, const Address &address)
+{
+  m_responses.Add (p->GetSize ());
+}
+
+bool
+Ns3TcpSocketTestCase1::DoRun (void)
+{
+  uint16_t sinkPort = 50000;
+  double sinkStopTime = 40;  // sec; will trigger Socket::Close
+  double writerStopTime = 30;  // sec; will trigger Socket::Close
+  double simStopTime = 60;  // sec
+  Time sinkStopTimeObj = Seconds (sinkStopTime);
+  Time writerStopTimeObj = Seconds (writerStopTime);
+  Time simStopTimeObj= Seconds (simStopTime);
+
+  Ptr<Node> n0 = CreateObject<Node> ();
+  Ptr<Node> n1 = CreateObject<Node> ();
+
+  PointToPointHelper pointToPoint;
+  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
+
+  NetDeviceContainer devices;
+  devices = pointToPoint.Install (n0, n1);
+
+  InternetStackHelper internet;
+  internet.InstallAll ();
+
+  Ipv4AddressHelper address;
+  address.SetBase ("10.1.1.0", "255.255.255.252");
+  Ipv4InterfaceContainer ifContainer = address.Assign (devices);
+
+  Ptr<SocketWriter> socketWriter = CreateObject<SocketWriter> ();
+  Address sinkAddress (InetSocketAddress (ifContainer.GetAddress (1), sinkPort));
+  socketWriter->Setup (n0, sinkAddress);
+  n0->AddApplication (socketWriter);
+  socketWriter->SetStartTime (Seconds (0.));
+  socketWriter->SetStopTime (writerStopTimeObj);
+
+  PacketSinkHelper sink ("ns3::TcpSocketFactory",
+                         InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
+  ApplicationContainer apps = sink.Install (n1);
+  // Start the sink application at time zero, and stop it at sinkStopTime
+  apps.Start (Seconds (0.0));
+  apps.Stop (sinkStopTimeObj);
+
+  Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx",
+                   MakeCallback (&Ns3TcpSocketTestCase1::SinkRx, this));
+
+  Simulator::Schedule(Seconds (2), &SocketWriter::Connect, socketWriter);
+  // Send 1, 10, 100, 1000 bytes
+  Simulator::Schedule(Seconds (10), &SocketWriter::Write, socketWriter, 1);
+  m_inputs.Add (1);
+  Simulator::Schedule(Seconds (12), &SocketWriter::Write, socketWriter, 10);
+  m_inputs.Add (10);
+  Simulator::Schedule(Seconds (14), &SocketWriter::Write, socketWriter, 100);
+  m_inputs.Add (100);
+  Simulator::Schedule(Seconds (16), &SocketWriter::Write, socketWriter, 1000);
+  m_inputs.Add (536);
+  m_inputs.Add (464);  // ns-3 TCP default segment size of 536
+  Simulator::Schedule(writerStopTimeObj, &SocketWriter::Close, socketWriter);
+
+  if (m_writeResults)
+    {
+      pointToPoint.EnablePcapAll ("tcp-socket-test-case-1");
+    }
+
+  Simulator::Stop (simStopTimeObj);
+  Simulator::Run ();
+  Simulator::Destroy ();
+
+  // Compare inputs and outputs
+  NS_TEST_ASSERT_MSG_EQ (m_inputs.GetN (), m_responses.GetN (), "Incorrect number of expected receive events");
+  for (uint32_t i = 0; i < m_responses.GetN (); i++)
+    {
+      uint32_t in = m_inputs.Get (i);
+      uint32_t out = m_responses.Get (i);
+      NS_TEST_ASSERT_MSG_EQ (in, out, "Mismatch:  expected " << in << " bytes, got " << out << " bytes");
+    }
+
+  return GetErrorStatus ();
+}
+
+class Ns3TcpSocketTestCase2 : public TestCase
+{
+public:
+  Ns3TcpSocketTestCase2 ();
+  virtual ~Ns3TcpSocketTestCase2 () {}
+
+private:
+  virtual bool DoRun (void);
+  bool m_writeResults;
+
+  void SinkRx (std::string path, Ptr<const Packet> p, const Address &address);
+
+  TestVectors<uint32_t> m_inputs;
+  TestVectors<uint32_t> m_responses;
+};
+
+Ns3TcpSocketTestCase2::Ns3TcpSocketTestCase2 ()
+  : TestCase ("Check to see that ns-3 TCP successfully transfers an application data write of various sizes (CSMA)"),
+    m_writeResults (false)
+{
+}
+
+void 
+Ns3TcpSocketTestCase2::SinkRx (std::string path, Ptr<const Packet> p, const Address &address)
+{
+  m_responses.Add (p->GetSize ());
+}
+
+bool
+Ns3TcpSocketTestCase2::DoRun (void)
+{
+  uint16_t sinkPort = 50000;
+  double sinkStopTime = 40;  // sec; will trigger Socket::Close
+  double writerStopTime = 30;  // sec; will trigger Socket::Close
+  double simStopTime = 60;  // sec
+  Time sinkStopTimeObj = Seconds (sinkStopTime);
+  Time writerStopTimeObj = Seconds (writerStopTime);
+  Time simStopTimeObj= Seconds (simStopTime);
+
+  Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (1000));
+
+  NodeContainer nodes;
+  nodes.Create (2);
+  Ptr<Node> n0 = nodes.Get (0);
+  Ptr<Node> n1 = nodes.Get (1);
+
+  CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", StringValue ("5Mbps"));
+  csma.SetChannelAttribute ("Delay", StringValue ("2ms"));
+
+  NetDeviceContainer devices;
+  devices = csma.Install (nodes);
+
+  InternetStackHelper internet;
+  internet.InstallAll ();
+
+  Ipv4AddressHelper address;
+  address.SetBase ("10.1.1.0", "255.255.255.252");
+  Ipv4InterfaceContainer ifContainer = address.Assign (devices);
+
+  Ptr<SocketWriter> socketWriter = CreateObject<SocketWriter> ();
+  Address sinkAddress (InetSocketAddress (ifContainer.GetAddress (1), sinkPort));
+  socketWriter->Setup (n0, sinkAddress);
+  n0->AddApplication (socketWriter);
+  socketWriter->SetStartTime (Seconds (0.));
+  socketWriter->SetStopTime (writerStopTimeObj);
+
+  PacketSinkHelper sink ("ns3::TcpSocketFactory",
+                         InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
+  ApplicationContainer apps = sink.Install (n1);
+  // Start the sink application at time zero, and stop it at sinkStopTime
+  apps.Start (Seconds (0.0));
+  apps.Stop (sinkStopTimeObj);
+
+  Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx",
+                   MakeCallback (&Ns3TcpSocketTestCase2::SinkRx, this));
+
+  Simulator::Schedule(Seconds (2), &SocketWriter::Connect, socketWriter);
+  // Send 1, 10, 100, 1000 bytes
+  // PointToPoint default MTU is 576 bytes, which leaves 536 bytes for TCP
+  Simulator::Schedule(Seconds (10), &SocketWriter::Write, socketWriter, 1);
+  m_inputs.Add (1);
+  Simulator::Schedule(Seconds (12), &SocketWriter::Write, socketWriter, 10);
+  m_inputs.Add (10);
+  Simulator::Schedule(Seconds (14), &SocketWriter::Write, socketWriter, 100);
+  m_inputs.Add (100);
+  Simulator::Schedule(Seconds (16), &SocketWriter::Write, socketWriter, 1000);
+  m_inputs.Add (1000);
+  // Next packet will fragment
+  Simulator::Schedule(Seconds (16), &SocketWriter::Write, socketWriter, 1001);
+  m_inputs.Add (1000);
+  m_inputs.Add (1);
+  Simulator::Schedule(writerStopTimeObj, &SocketWriter::Close, socketWriter);
+
+  if (m_writeResults)
+    {
+      csma.EnablePcapAll ("tcp-socket-test-case-2", false);
+    }
+  Simulator::Stop (simStopTimeObj);
+  Simulator::Run ();
+  Simulator::Destroy ();
+
+  // Compare inputs and outputs
+  NS_TEST_ASSERT_MSG_EQ (m_inputs.GetN (), m_responses.GetN (), "Incorrect number of expected receive events");
+  for (uint32_t i = 0; i < m_responses.GetN (); i++)
+    {
+      uint32_t in = m_inputs.Get (i);
+      uint32_t out = m_responses.Get (i);
+      NS_TEST_ASSERT_MSG_EQ (in, out, "Mismatch:  expected " << in << " bytes, got " << out << " bytes");
+    }
+
+  return GetErrorStatus ();
+}
+
+class Ns3TcpSocketTestSuite : public TestSuite
+{
+public:
+  Ns3TcpSocketTestSuite ();
+};
+
+Ns3TcpSocketTestSuite::Ns3TcpSocketTestSuite ()
+  : TestSuite ("ns3-tcp-socket", SYSTEM)
+{
+  AddTestCase (new Ns3TcpSocketTestCase1);
+  AddTestCase (new Ns3TcpSocketTestCase2);
+}
+
+Ns3TcpSocketTestSuite ns3TcpSocketTestSuite;
--- a/src/test/ns3tcp/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/test/ns3tcp/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -13,5 +13,6 @@
     if bld.env['NSC_ENABLED']:
         ns3tcp.source = [
             'ns3tcp-interop-test-suite.cc',
-            'ns3tcp-cwnd-test-suite.cc'
+            'ns3tcp-cwnd-test-suite.cc',
+            'ns3tcp-socket-test-suite.cc'
             ]
--- a/src/test/ns3wifi/wifi-interference-test-suite.cc	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/test/ns3wifi/wifi-interference-test-suite.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -149,8 +149,8 @@
   wifiPhy.Set ("RxGain", DoubleValue (0) ); 
   wifiPhy.Set ("CcaMode1Threshold", DoubleValue (0.0) );
   
-  // ns-3 support RadioTap and Prism tracing extensions for 802.11b
-  wifiPhy.SetPcapFormat (YansWifiPhyHelper::PCAP_FORMAT_80211_RADIOTAP); 
+  // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
+  wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO); 
   
   YansWifiChannelHelper wifiChannel ;
   wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/perf/perf-io.cc	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,137 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ */
+
+#include <time.h>
+#include <sys/time.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+#include <fstream>
+
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/core-module.h"
+#include "ns3/helper-module.h"
+
+using namespace ns3;
+using namespace std;
+
+static const uint64_t US_PER_NS = (uint64_t)1000;
+static const uint64_t US_PER_SEC = (uint64_t)1000000;
+static const uint64_t NS_PER_SEC = (uint64_t)1000000000;
+
+uint64_t
+GetRealtimeInNs (void)
+{
+  struct timeval tv;
+  gettimeofday (&tv, NULL);
+
+  uint64_t nsResult = tv.tv_sec * NS_PER_SEC + tv.tv_usec * US_PER_NS;
+  return nsResult;
+}
+
+void
+PerfFile (FILE *file, uint32_t n, const char *buffer, uint32_t size)
+{
+  for (uint32_t i = 0; i < n; ++i)
+    {
+      fwrite (buffer, 1, size, file);
+    }
+}
+
+void
+PerfStream (ostream &stream, uint32_t n, const char *buffer, uint32_t size)
+{
+
+  for (uint32_t i = 0; i < n; ++i)
+    {
+      stream.write (buffer, size);
+    }
+}
+
+int 
+main (int argc, char *argv[])
+{
+  uint32_t n = 100000;
+  uint32_t iter = 50;
+  bool doStream = false;
+  bool binmode = true;
+ 
+
+  CommandLine cmd;
+  cmd.AddValue ("n", "How many times to write (defaults to 100000", n);
+  cmd.AddValue ("iter", "How many times to run the test looking for a min (defaults to 50)", iter);
+  cmd.AddValue ("doStream", "Run the C++ I/O benchmark otherwise the C I/O ", doStream);
+  cmd.AddValue ("binmode", "Select binary mode for the C++ I/O benchmark (defaults to true)", binmode);
+  cmd.Parse (argc, argv);
+
+  uint64_t result = std::numeric_limits<uint64_t>::max ();
+  
+  char buffer[1024];
+
+  if (doStream)
+    {
+      //
+      // This will probably run on a machine doing other things.  Run it some
+      // relatively large number of times and try to find a minimum, which
+      // will hopefully represent a time when it runs free of interference.
+      //
+      for (uint32_t i = 0; i < iter; ++i)
+        {
+          ofstream stream;
+          if (binmode)
+            {
+              stream.open ("streamtest", std::ios_base::binary | std::ios_base::out);
+            }
+          else
+            {
+              stream.open ("streamtest", std::ios_base::out);
+            }
+
+          uint64_t start = GetRealtimeInNs ();
+          PerfStream (stream, n, buffer, 1024);
+          uint64_t et = GetRealtimeInNs () - start;
+          result = min (result, et);
+          stream.close ();
+          cout << "."; std::cout.flush ();
+        }
+      cout << std::endl;
+    }
+  else
+    {
+      //
+      // This will probably run on a machine doing other things.  Run it some
+      // relatively large number of times and try to find a minimum, which
+      // will hopefully represent a time when it runs free of interference.
+      //
+      for (uint32_t i = 0; i < iter; ++i)
+        {
+          FILE *file = fopen ("filetest", "w");
+
+          uint64_t start = GetRealtimeInNs ();
+          PerfFile (file, n, buffer, 1024);
+          uint64_t et = GetRealtimeInNs () - start;
+          result = std::min (result, et);
+          fclose (file);
+          file = 0;
+          std::cout << "."; std::cout.flush ();
+        }
+      std::cout << std::endl;
+    }
+  std::cout << argv[0] << ": " << result << "ns" << std::endl;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/perf/waf	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../../waf "$@"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/perf/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,14 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def configure(conf):
+    pass
+
+def build(bld):
+    obj = bld.create_ns3_module('perf')
+    headers = bld.new_task_gen('ns3header')
+    headers.module = 'perf'
+
+    obj = bld.create_ns3_program('perf-io', ['core'])
+    obj.source = 'perf-io.cc'
+
+
--- a/src/test/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/test/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -1,5 +1,8 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
+def configure(conf):
+    conf.sub_config('perf')
+
 def build(bld):
     test = bld.create_ns3_module('test', ['core'])
     test.source = [
--- a/src/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/src/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -44,6 +44,7 @@
     'applications/ping6',
     'applications/radvd',
     'test',
+    'test/perf',
     'test/ns3tcp',
     'test/ns3wifi',
     'contrib/flow-monitor',
@@ -72,6 +73,7 @@
     conf.sub_config('contrib')
     conf.sub_config('internet-stack')
     conf.sub_config('helper')
+    conf.sub_config('test')
 
     blddir = os.path.abspath(os.path.join(conf.blddir, conf.env.variant()))
     conf.env.append_value('NS3_MODULE_PATH', blddir)
@@ -83,13 +85,14 @@
 
 
 def create_ns3_module(bld, name, dependencies=()):
-    module = bld.new_task_gen('cxx')
+    module = bld.new_task_gen('cxx', 'cc')
     module.name = 'ns3-' + name
     module.target = module.name
     module.add_objects = ['ns3-' + dep for dep in dependencies]
     module.module_deps = list(dependencies)
     if not module.env['ENABLE_STATIC_NS3']:
         module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS'])
+        module.env.append_value('CCFLAGS', module.env['shlib_CXXFLAGS'])
     elif module.env['CXX_NAME'] in ['gcc', 'icc'] and \
             os.uname()[4] == 'x86_64' and \
             module.env['ENABLE_PYTHON_BINDINGS']:
@@ -97,8 +100,10 @@
         # when gcc is present and only when we want python bindings
         # (it's more efficient to not use this option if we can avoid it)
         module.env.append_value('CXXFLAGS', '-mcmodel=large')
+        module.env.append_value('CCFLAGS', '-mcmodel=large')
         
     module.env.append_value('CXXDEFINES', "NS3_MODULE_COMPILATION")
+    module.env.append_value('CCDEFINES', "NS3_MODULE_COMPILATION")
     return module
 
 def create_obj(bld, *args):
@@ -138,7 +143,7 @@
                 raise Utils.WafError("source ns3 header file %s not found" % (filename,))
             dst_node = ns3_dir_node.find_or_declare(os.path.basename(filename))
             assert dst_node is not None
-            task = self.create_task('ns3header', self.env)
+            task = self.create_task('ns3header', env=self.env)
             task.set_inputs([src_node])
             task.set_outputs([dst_node])
 
@@ -243,7 +248,7 @@
         module_obj = self.bld.name_to_obj("ns3-" + self.module, self.env)
         assert module_obj is not None
         all_headers_outputs = [ns3_dir_node.find_or_declare("%s-module.h" % self.module)]
-        task = self.create_task('gen_ns3_module_header', self.env)
+        task = self.create_task('gen_ns3_module_header', env=self.env)
         task.set_inputs(all_headers_inputs)
         task.set_outputs(all_headers_outputs)
         task.module = self.module
--- a/test.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/test.py	Thu Feb 25 14:17:21 2010 +0100
@@ -27,6 +27,7 @@
 import signal
 import xml.dom.minidom
 import shutil
+import re
 
 #
 # XXX This should really be part of a waf command to list the configuration
@@ -134,6 +135,7 @@
     ("tutorial/third", "True", "True"),
     ("tutorial/fourth", "True", "True"),
     ("tutorial/fifth", "True", "True"),
+    ("tutorial/sixth", "True", "True"),
 
     ("udp/udp-echo", "True", "True"),
 
@@ -585,10 +587,93 @@
         if options.verbose:
             print "os.environ[\"LD_LIBRARY_PATH\"] == %s" % os.environ["LD_LIBRARY_PATH"]
 
+#
+# Short note on generating suppressions:
+#
+# See the valgrind documentation for a description of suppressions.  The easiest
+# way to generate a suppression expression is by using the valgrind 
+# --gen-suppressions option.  To do that you have to figure out how to run the 
+# test in question.
+#
+# If you do "test.py -v -g -s <suitename> then test.py will output most of what
+# you need.  For example, if you are getting a valgrind error in the
+# devices-mesh-dot11s-regression test suite, you can run:
+#
+#   ./test.py -v -g -s devices-mesh-dot11s-regression 
+#
+# You should see in the verbose output something that looks like:
+#
+#   Synchronously execute valgrind --suppressions=/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/testpy.supp
+#   --leak-check=full --error-exitcode=2 /home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build/debug/utils/test-runner 
+#   --suite=devices-mesh-dot11s-regression --basedir=/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev 
+#   --tempdir=testpy-output/2010-01-12-22-47-50-CUT 
+#   --out=testpy-output/2010-01-12-22-47-50-CUT/devices-mesh-dot11s-regression.xml
+#
+# You need to pull out the useful pieces, and so could run the following to 
+# reproduce your error:
+#
+#   valgrind --suppressions=/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/testpy.supp
+#   --leak-check=full --error-exitcode=2 /home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build/debug/utils/test-runner 
+#   --suite=devices-mesh-dot11s-regression --basedir=/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev 
+#   --tempdir=testpy-output 
+#
+# Hint: Use the first part of the command as is, and point the "tempdir" to 
+# somewhere real.  You don't need to specify an "out" file.
+#
+# When you run the above command you should see your valgrind error.  The 
+# suppression expression(s) can be generated by adding the --gen-suppressions=yes
+# option to valgrind.  Use something like:
+#
+#   valgrind --gen-suppressions=yes --suppressions=/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/testpy.supp
+#   --leak-check=full --error-exitcode=2 /home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build/debug/utils/test-runner 
+#   --suite=devices-mesh-dot11s-regression --basedir=/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev 
+#   --tempdir=testpy-output 
+#
+# Now when valgrind detects an error it will ask:
+#
+#   ==27235== ---- Print suppression ? --- [Return/N/n/Y/y/C/c] ----
+#
+# to which you just enter 'y'<ret>.
+#
+# You will be provided with a suppression expression that looks something like
+# the following:
+#   {
+#     <insert_a_suppression_name_here>
+#     Memcheck:Addr8
+#     fun:_ZN3ns36dot11s15HwmpProtocolMac8SendPreqESt6vectorINS0_6IePreqESaIS3_EE
+#     fun:_ZN3ns36dot11s15HwmpProtocolMac10SendMyPreqEv
+#     fun:_ZN3ns36dot11s15HwmpProtocolMac18RequestDestinationENS_12Mac48AddressEjj
+#     ...
+#     the rest of the stack frame
+#     ...
+#   }
+#
+# You need to add a supression name which will only be printed out by valgrind in 
+# verbose mode (but it needs to be there in any case).  The entire stack frame is
+# shown to completely characterize the error, but in most cases you won't need 
+# all of that info.  For example, if you want to turn off all errors that happen
+# when the function (fun:) is called, you can just delete the rest of the stack
+# frame.  You can also use wildcards to make the mangled signatures more readable.
+#
+# I added the following to the testpy.supp file for this particular error:
+#
+#   {
+#     Supress invalid read size errors in SendPreq() when using HwmpProtocolMac
+#     Memcheck:Addr8
+#     fun:*HwmpProtocolMac*SendPreq*
+#   }
+#
+# Now, when you run valgrind the error will be suppressed.
+#
+VALGRIND_SUPPRESSIONS_FILE = "testpy.supp"
+
 def run_job_synchronously(shell_command, directory, valgrind):
+    (base, build) = os.path.split (NS3_BUILDDIR)
+    suppressions_path = os.path.join (base, VALGRIND_SUPPRESSIONS_FILE)
     path_cmd = os.path.join (NS3_BUILDDIR, NS3_ACTIVE_VARIANT, shell_command)
     if valgrind:
-        cmd = "valgrind --leak-check=full --error-exitcode=2 %s" % path_cmd
+        cmd = "valgrind --suppressions=%s --leak-check=full --show-reachable=yes --error-exitcode=2 %s" % (suppressions_path, 
+            path_cmd)
     else:
         cmd = path_cmd
 
@@ -600,11 +685,25 @@
     stdout_results, stderr_results = proc.communicate()
     elapsed_time = time.time() - start_time
 
+    retval = proc.returncode
+
+    #
+    # valgrind sometimes has its own idea about what kind of memory management
+    # errors are important.  We want to detect *any* leaks, so the way to do 
+    # that is to look for the presence of a valgrind leak summary section.
+    #
+    # If another error has occurred (like a test suite has failed), we don't 
+    # want to trump that error, so only do the valgrind output scan if the 
+    # test has otherwise passed (return code was zero).
+    #
+    if valgrind and retval == 0 and "== LEAK SUMMARY:" in stderr_results:
+        retval = 2
+    
     if options.verbose:
-        print "Return code = ", proc.returncode
+        print "Return code = ", retval
         print "stderr = ", stderr_results
 
-    return (proc.returncode, stdout_results, stderr_results, elapsed_time)
+    return (retval, stdout_results, stderr_results, elapsed_time)
 
 #
 # This class defines a unit of testing work.  It will typically refer to
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testpy.supp	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,5 @@
+{
+  Supress invalid read size errors in SendPreq() when using HwmpProtocolMac
+  Memcheck:Addr8
+  fun:*HwmpProtocolMac*SendPreq*
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/check-style.py	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,439 @@
+#!/usr/bin/env python
+
+import os
+import subprocess
+import tempfile
+import sys
+import filecmp
+import optparse
+import shutil
+import difflib
+import re
+
+def hg_modified_files():
+    files = os.popen ('hg st -nma')
+    return [filename.strip() for filename in files]
+
+def copy_file(filename):
+    [tmp,pathname] = tempfile.mkstemp()
+    src = open(filename, 'r')
+    dst = open(pathname, 'w')
+    for line in src:
+        dst.write(line)
+    dst.close()
+    src.close()
+    return pathname
+
+# generate a temporary configuration file
+def uncrustify_config_file(level):
+    level2 = """
+nl_collapse_empty_body=False
+nl_if_brace=Add
+nl_brace_else=Add
+nl_elseif_brace=Add
+nl_else_brace=Add
+nl_while_brace=Add
+nl_do_brace=Add
+nl_for_brace=Add
+nl_brace_while=Add
+nl_switch_brace=Add
+nl_after_case=True
+nl_namespace_brace=Remove
+nl_after_brace_open=True
+nl_class_leave_one_liners=False
+nl_enum_leave_one_liners=False
+nl_func_leave_one_liners=False
+nl_if_leave_one_liners=False
+nl_class_colon=Ignore
+nl_after_access_spec=1
+nl_after_semicolon=True
+pos_class_colon=Lead
+pos_class_comma=Trail
+pos_bool=Lead
+nl_class_init_args=Add
+nl_template_class=Add
+nl_class_brace=Add
+# does not work very well
+nl_func_type_name=Ignore
+nl_func_scope_name=Ignore
+nl_func_type_name_class=Ignore
+nl_func_proto_type_name=Ignore
+# function\\n(
+nl_func_paren=Remove
+nl_fdef_brace=Add
+nl_struct_brace=Add
+nl_enum_brace=Add
+nl_union_brace=Add
+mod_full_brace_do=Add
+mod_full_brace_for=Add
+mod_full_brace_if=Add
+mod_full_brace_while=Add
+mod_full_brace_for=Add
+mod_remove_extra_semicolon=True
+# max code width
+#code_width=128
+#ls_for_split_full=True
+#ls_func_split_full=True
+"""
+    level1 = """
+# extra spaces here and there
+sp_func_proto_paren=Add
+sp_func_def_paren=Add
+sp_func_call_paren=Add
+sp_brace_typedef=Add
+sp_enum_assign=Add
+sp_before_sparen=Add
+sp_after_semi_for=Add
+sp_arith=Add
+sp_assign=Add
+sp_compare=Add
+sp_cmt_cpp_start=Add
+sp_func_class_paren=Add
+sp_after_type=Add
+sp_type_func=Add
+sp_angle_paren=Add
+"""
+    level0 = """
+sp_after_semi_for=Ignore
+sp_before_sparen=Ignore
+sp_type_func=Ignore
+sp_after_type=Ignore
+nl_class_leave_one_liners=True
+nl_enum_leave_one_liners=True
+nl_func_leave_one_liners=True
+nl_assign_leave_one_liners=True
+#nl_collapse_empty_body=False
+nl_getset_leave_one_liners=True
+nl_if_leave_one_liners=True
+nl_fdef_brace=Ignore
+# finally, indentation configuration
+indent_with_tabs=0
+indent_namespace=false
+indent_columns=2
+indent_brace=2
+indent_case_brace=2
+indent_class=true
+indent_class_colon=True
+# alignment
+indent_align_assign=False
+align_left_shift=True
+# comment reformating disabled
+cmt_reflow_mode=1 # do not touch comments at all
+cmt_indent_multi=False # really, do not touch them
+"""
+    [tmp,pathname] = tempfile.mkstemp()
+    dst = open(pathname, 'w')
+    dst.write(level0)
+    if level >= 1:
+        dst.write(level1)
+    if level >= 2:
+        dst.write(level2)
+    dst.close()
+    return pathname
+
+class PatchChunkLine:
+    SRC = 1
+    DST = 2
+    BOTH = 3
+    def __init__(self):
+        self.__type = 0
+        self.__line = ''
+    def set_src(self,line):
+        self.__type = self.SRC
+        self.__line = line
+    def set_dst(self,line):
+        self.__type = self.DST
+        self.__line = line
+    def set_both(self,line):
+        self.__type = self.BOTH
+        self.__line = line
+    def append_to_line(self, s):
+        self.__line = self.__line + s
+    def line(self):
+        return self.__line
+    def is_src(self):
+        return self.__type == self.SRC or self.__type == self.BOTH
+    def is_dst(self):
+        return self.__type == self.DST or self.__type == self.BOTH
+    def write(self, f):
+        if self.__type == self.SRC:
+            f.write('-%s\n' % self.__line)
+        elif self.__type == self.DST:
+            f.write('+%s\n' % self.__line)
+        elif self.__type == self.BOTH:
+            f.write(' %s\n' % self.__line)
+        else:
+            raise Exception('invalid patch')
+    
+
+class PatchChunk:
+    def __init__(self, src_pos, dst_pos):
+        self.__lines = []
+        self.__src_pos = int(src_pos)
+        self.__dst_pos = int(dst_pos)
+    def src_start(self):
+        return self.__src_pos
+    def add_line(self,line):
+        self.__lines.append(line)
+    def src(self):
+        src = []
+        for line in self.__lines:
+            if line.is_src():
+                src.append(line)
+        return src
+    def dst(self):
+        dst = []
+        for line in self.__lines:
+            if line.is_dst():
+                dst.append(line)
+        return dst
+    def src_len(self):
+        return len(self.src())
+    def dst_len(self):
+        return len(self.dst())
+    def write(self,f):
+        f.write('@@ -%d,%d +%d,%d @@\n' % (self.__src_pos, self.src_len(),
+                                           self.__dst_pos, self.dst_len()))
+        for line in self.__lines:
+            line.write(f)
+
+class Patch:
+    def __init__(self):
+        self.__src = ''
+        self.__dst = ''
+        self.__chunks = []
+    def add_chunk(self, chunk):
+        self.__chunks.append(chunk)
+    def chunks(self):
+        return self.__chunks
+    def set_src(self,src):
+        self.__src = src
+    def set_dst(self,dst):
+        self.__dst = dst
+    def apply(self,filename):
+        # XXX: not implemented
+        return
+    def write(self,f):
+        f.write('--- %s\n' % self.__src )
+        f.write('+++ %s\n' % self.__dst )
+        for chunk in self.__chunks:
+            chunk.write(f)
+
+def parse_patchset(generator):
+    src_file = re.compile('^--- (.*)$')
+    dst_file = re.compile('^\+\+\+ (.*)$')
+    chunk_start = re.compile('^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@')
+    src = re.compile('^-(.*)$')
+    dst = re.compile('^\+(.*)$')
+    both = re.compile('^ (.*)$')
+    patchset = []
+    current_patch = None
+    for line in generator:
+        m = src_file.search(line)
+        if m is not None:
+            current_patch = Patch()
+            patchset.append(current_patch)
+            current_patch.set_src(m.group(1))
+            continue
+        m = dst_file.search(line)
+        if m is not None:
+            current_patch.set_dst(m.group(1))
+            continue
+        m = chunk_start.search(line)
+        if m is not None:
+            current_chunk = PatchChunk(m.group(1), m.group(3))
+            current_patch.add_chunk(current_chunk)
+            continue
+        m = src.search(line)
+        if m is not None:
+            l = PatchChunkLine()
+            l.set_src(m.group(1))
+            current_chunk.add_line(l)
+            continue
+        m = dst.search(line)
+        if m is not None:
+            l = PatchChunkLine()
+            l.set_dst(m.group(1))
+            current_chunk.add_line(l)
+            continue
+        m = both.search(line)
+        if m is not None:
+            l = PatchChunkLine()
+            l.set_both(m.group(1))
+            current_chunk.add_line(l)
+            continue
+        raise Exception()
+    return patchset
+
+def remove_trailing_whitespace_changes(patch_generator):
+    whitespace = re.compile('^(.*)([ \t]+)$')
+    patchset = parse_patchset(patch_generator)
+    for patch in patchset:
+        for chunk in patch.chunks():
+            src = chunk.src()
+            dst = chunk.dst()
+            try:
+                for i in range(0,len(src)):
+                    s = src[i]
+                    d = dst[i]
+                    m = whitespace.search(s.line())
+                    if m is not None and m.group(1) == d.line():
+                        d.append_to_line(m.group(2))
+            except:
+                return patchset
+    return patchset
+
+
+def indent(source, debug, level):
+    output = tempfile.mkstemp()[1]
+    # apply uncrustify
+    cfg = uncrustify_config_file(level)
+    if debug:
+        sys.stderr.write('original file=' + source + '\n')
+        sys.stderr.write('uncrustify config file=' + cfg + '\n')
+        sys.stderr.write('temporary file=' + output + '\n')
+    try:
+        uncrust = subprocess.Popen(['uncrustify', '-c', cfg, '-f', source, '-o', output],
+                                   stdin = subprocess.PIPE,
+                                   stdout = subprocess.PIPE,
+                                   stderr = subprocess.PIPE)
+        (out, err) = uncrust.communicate('')
+        if debug:
+            sys.stderr.write(out)
+            sys.stderr.write(err)
+    except OSError:
+        raise Exception ('uncrustify not installed')
+    # generate a diff file
+    src = open(source, 'r')
+    dst = open(output, 'r')
+    diff = difflib.unified_diff(src.readlines(), dst.readlines(), 
+                                fromfile=source, tofile=output)
+    src.close()
+    dst.close()
+    if debug:
+        initial_diff = tempfile.mkstemp()[1]
+        sys.stderr.write('initial diff file=' + initial_diff + '\n')
+        tmp = open(initial_diff, 'w')
+        tmp.writelines(diff)
+        tmp.close()
+    final_diff = tempfile.mkstemp()[1]
+    if level < 3:
+        patchset = remove_trailing_whitespace_changes(diff);
+        dst = open(final_diff, 'w')
+        if len(patchset) != 0:
+            patchset[0].write(dst)
+        dst.close()
+    else:
+        dst = open(final_diff, 'w')
+        dst.writelines(diff)
+        dst.close()
+            
+            
+    # apply diff file
+    if debug:
+        sys.stderr.write('final diff file=' + final_diff + '\n')
+    shutil.copyfile(source,output)
+    patch = subprocess.Popen(['patch', '-p1', '-i', final_diff, output],
+                             stdin = subprocess.PIPE,
+                             stdout = subprocess.PIPE,
+                             stderr = subprocess.PIPE)
+    (out, err) = patch.communicate('')
+    if debug:
+        sys.stderr.write(out)
+        sys.stderr.write(err)
+    return output
+ 
+
+
+def indent_files(files, diff=False, debug=False, level=0, inplace=False):
+    output = []
+    for f in files:
+        dst = indent(f, debug=debug, level=level)
+        output.append([f,dst])
+
+    # First, copy to inplace
+    if inplace:
+        for src,dst in output:
+            shutil.copyfile(dst,src)
+        return True
+
+    # now, compare
+    failed = []
+    for src,dst in output:
+        if filecmp.cmp(src,dst) == 0:
+            failed.append([src, dst])
+    if len(failed) > 0:
+        if not diff:
+            print 'Found %u badly indented files:' % len(failed)
+            for src,dst in failed:
+                print '  ' + src
+        else:
+            for src,dst in failed:
+                s = open(src, 'r').readlines()
+                d = open(dst, 'r').readlines()
+                for line in difflib.unified_diff(s, d, fromfile=src, tofile=dst):
+                    sys.stdout.write(line)
+        return False
+    return True
+
+def run_as_hg_hook(ui, repo, **kwargs):
+    # hack to work around mercurial < 1.3 bug
+    from mercurial import lock, error
+    lock.LockError = error.LockError
+    # actually do the work
+    files = hg_modified_files()
+    if not indent_files(files, inplace=False):
+        return True
+    return False
+
+def run_as_main():
+    parser = optparse.OptionParser()
+    parser.add_option('--debug', action='store_true', dest='debug', default=False,
+                      help='Output some debugging information')
+    parser.add_option('-l', '--level', type='int', dest='level', default=0,
+                      help="Level of style conformance: higher levels include all lower levels. "
+                      "level=0: re-indent only. level=1: add extra spaces. level=2: insert extra newlines and "
+                      "extra braces around single-line statements. level=3: remove all trailing spaces")
+    parser.add_option('--check-hg-hook', action='store_true', dest='hg_hook', default=False, 
+                      help='Get the list of files to check from mercurial\'s list of modified '
+                      'and added files and assume that the script runs as a pretxncommit mercurial hook')
+    parser.add_option('--check-hg', action='store_true', dest='hg', default=False,
+                      help="Get the list of files to check from mercurial\'s list of modified and added files")
+    parser.add_option('-f', '--check-file', action='store', dest='file', default='',
+                      help="Check a single file")
+    parser.add_option('--diff', action='store_true', dest='diff', default=False,
+                      help="Generate a diff on stdout of the indented files")
+    parser.add_option('-i', '--in-place', action='store_true', dest='in_place', default=False,
+                      help="Indent the input files in-place")
+    (options,args) = parser.parse_args()
+    debug = options.debug
+    if options.hg_hook:
+        files = hg_modified_files()
+        if not indent_files(files, debug=options.debug,
+                            level=options.level,
+                            inplace=False):
+            sys.exit(1)
+    elif options.hg:
+        files = hg_modified_files()
+        indent_files(files, diff=options.diff, 
+                     debug=options.debug,
+                     level=options.level,
+                     inplace=options.in_place)
+    elif options.file != '':
+        file = options.file
+        if not os.path.exists(file) or \
+                not os.path.isfile(file):
+            print 'file %s does not exist' % file
+            sys.exit(1)
+        indent_files([file], diff=options.diff, 
+                     debug=options.debug,
+                     level=options.level,
+                     inplace=options.in_place)
+    sys.exit(0)
+
+if __name__ == '__main__':
+#    try:
+        run_as_main()
+#    except Exception, e:
+#        sys.stderr.write(str(e) + '\n')
+#        sys.exit(1)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/utils.h	Thu Feb 25 14:17:21 2010 +0100
@@ -0,0 +1,80 @@
+/**
+ * \ingroup utils 
+ * \defgroup CheckStyle check-style.py
+ *
+ * The check-style.py script will test and reformat code according to the
+ * ns-3 coding style posted at http://www.nsnam.org/codingstyle.html
+ * It requires that you install 'uncrustify' 
+ *
+ * It has multiple levels of conformance:
+ *   - level=0: the default: merely checks indentation
+ *   - level=1: checks also for missing spaces before parentheses
+ *   - level=2: checks also for missing newlines and braces around single-line statements
+ *   - level=3: checks also for missing trailing whitespaces
+ *
+ * Examples:
+ * 
+ * check a single file (level 0 by default):
+\verbatim
+./check-style.py -f src/core/object.h
+\endverbatim
+ *  
+ * fix the style of a single file:
+\verbatim
+./check-style.py --level=2 --in-place -f src/core/object.h
+\endverbatim
+ * 
+ * look at the changes needed for a single file:
+\verbatim
+./check-style.py --diff --level=1 -f src/core/object.h | less
+\endverbatim
+ *
+ * look at the status of all files modified in your mercurial repository:
+\verbatim
+./check-style.py --check-hg
+\endverbatim
+ * 
+ * look at the changes needed for all modified files in your mercurial
+ * repository:
+\verbatim
+./check-style.py --check-hg --diff |less
+\endverbatim
+ * 
+ * Enable this script to run as a 'commit' hook in your repository and
+ * disallow commits which contain files with invalid style:
+ * 
+\verbatim
+cat hgrc (can be appended to .hg/hgrc or ~/.hg/hgrc or /etc/hg/hgrc
+[hooks]
+# uncomment below line to enable: works only with mercurial >= 1.3
+#pretxncommit.indent = path-to-binary/check-indent.py --check-hg-hook
+# uncomment below line to enable: works with all (?) versions 
+# of mercurial but requires that PYTHONPATH is defined to point to 
+# the directory which contains check-indent.py
+#pretxncommit.indent = python:check-indent.run_as_hg_hook
+\endverbatim
+ *
+ * Usage:
+\verbatim
+Usage: check-style.py [options]
+
+Options:
+  -h, --help            show this help message and exit
+  --debug               Output some debugging information
+  -l LEVEL, --level=LEVEL
+                        Level of style conformance: higher levels include all
+                        lower levels. level=0: re-indent only. level=1: add
+                        extra spaces. level=2: insert extra newlines and extra
+                        braces around single-line statements. level=3: remove
+                        all trailing spaces
+  --check-hg-hook       Get the list of files to check from mercurial's list
+                        of modified and added files and assume that the script
+                        runs as a pretxncommit mercurial hook
+  --check-hg            Get the list of files to check from mercurial's list
+                        of modified and added files
+  -f FILE, --check-file=FILE
+                        Check a single file
+  --diff                Generate a diff on stdout of the indented files
+  -i, --in-place        Indent the input files in-place
+\endverbatim
+ */
Binary file waf has changed
--- a/waf-tools/shellcmd.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/waf-tools/shellcmd.py	Thu Feb 25 14:17:21 2010 +0100
@@ -31,6 +31,17 @@
 else:
     dev_null = open("/dev/null", "w")
 
+fcntl = fd = fl = None
+try:
+    import fcntl
+except ImportError:
+    pass
+else:
+    fd = dev_null.fileno()
+    fl = fcntl.fcntl(fd, fcntl.F_GETFD)
+    fcntl.fcntl(fd, fcntl.F_SETFD, fl | fcntl.FD_CLOEXEC)
+del fcntl, fd, fl
+
 def _open_out_file(filename):
     if filename in ['NUL:', '/dev/null']:
         return dev_null
--- a/wscript	Thu Feb 25 13:51:59 2010 +0100
+++ b/wscript	Thu Feb 25 14:17:21 2010 +0100
@@ -112,6 +112,7 @@
 
 def set_options(opt):
     # options provided by the modules
+    opt.tool_options('compiler_cc')
     opt.tool_options('compiler_cxx')
     opt.tool_options('cflags')
 
@@ -236,6 +237,7 @@
     conf.env['NS3_OPTIONAL_FEATURES'] = []
 
     conf.env['NS3_BUILDDIR'] = conf.blddir
+    conf.check_tool('compiler_cc')
     conf.check_tool('compiler_cxx')
     conf.check_tool('cflags')
     try:
@@ -277,8 +279,6 @@
     conf.setenv(variant_name)
     env = variant_env
 
-    env.append_value('CXXDEFINES', 'RUN_SELF_TESTS')
-    
     if env['COMPILER_CXX'] == 'g++' and 'CXXFLAGS' not in os.environ:
         if conf.check_compilation_flag('-Wno-error=deprecated-declarations'):
             env.append_value('CXXFLAGS', '-Wno-error=deprecated-declarations')
@@ -388,6 +388,10 @@
         conf.env.append_value('CXXDEFINES', "ENABLE_GSL")
         conf.env.append_value('CCDEFINES', "ENABLE_GSL")
 
+    # for compiling C code, copy over the CXX* flags
+    conf.env.append_value('CCFLAGS', conf.env['CXXFLAGS'])
+    conf.env.append_value('CCDEFINES', conf.env['CXXDEFINES'])
+
     # append user defined flags after all our ones
     for (confvar, envvar) in [['CCFLAGS', 'CCFLAGS_EXTRA'],
                               ['CXXFLAGS', 'CXXFLAGS_EXTRA'],
@@ -697,12 +701,14 @@
                         self.bld.env, proc_env, force_no_valgrind=True)
 
 def check_shell(bld):
-    if 'NS3_MODULE_PATH' not in os.environ:
+    if ('NS3_MODULE_PATH' not in os.environ) or ('NS3_EXECUTABLE_PATH' not in os.environ):
         return
     env = bld.env
     correct_modpath = os.pathsep.join(env['NS3_MODULE_PATH'])
     found_modpath = os.environ['NS3_MODULE_PATH']
-    if found_modpath != correct_modpath:
+    correct_execpath = os.pathsep.join(env['NS3_EXECUTABLE_PATH'])
+    found_execpath = os.environ['NS3_EXECUTABLE_PATH']
+    if (found_modpath != correct_modpath) or (correct_execpath != found_execpath):
         msg = ("Detected shell (./waf shell) with incorrect configuration\n"
                "=========================================================\n"
                "Possible reasons for this problem:\n"
@@ -728,7 +734,8 @@
         shell = os.environ.get("SHELL", "/bin/sh")
 
     env = wutils.bld.env
-    wutils.run_argv([shell], env, {'NS3_MODULE_PATH': os.pathsep.join(env['NS3_MODULE_PATH'])})
+    os_env = {'NS3_MODULE_PATH': os.pathsep.join(env['NS3_MODULE_PATH']), 'NS3_EXECUTABLE_PATH': os.pathsep.join(env['NS3_EXECUTABLE_PATH'])}
+    wutils.run_argv([shell], env, os_env)
 
 def _doxygen(bld):
     env = wutils.bld.env
--- a/wutils.py	Thu Feb 25 13:51:59 2010 +0100
+++ b/wutils.py	Thu Feb 25 14:17:21 2010 +0100
@@ -112,6 +112,11 @@
     else:
         proc_env['PYTHONPATH'] = pymoddir
 
+    if 'PATH' in proc_env:
+        proc_env['PATH'] = os.pathsep.join(list(env['NS3_EXECUTABLE_PATH']) + [proc_env['PATH']])
+    else:
+        proc_env['PATH'] = os.pathsep.join(list(env['NS3_EXECUTABLE_PATH']))
+
     return proc_env
 
 def run_argv(argv, env, os_env=None, cwd=None, force_no_valgrind=False):
@@ -121,16 +126,12 @@
             raise Utils.WafError("Options --command-template and --valgrind are conflicting")
         if not env['VALGRIND']:
             raise Utils.WafError("valgrind is not installed")
-        argv = [env['VALGRIND'], "--leak-check=full", "--error-exitcode=1"] + argv
+        argv = [env['VALGRIND'], "--leak-check=full", "--show-reachable=yes", "--error-exitcode=1"] + argv
         proc = subprocess.Popen(argv, env=proc_env, cwd=cwd, stderr=subprocess.PIPE)
-        reg = re.compile ('definitely lost: ([^ ]+) bytes')
         error = False
         for line in proc.stderr:
             sys.stderr.write(line)
-            result = reg.search(line)
-            if result is None:
-                continue
-            if result.group(1) != "0":
+            if "== LEAK SUMMARY" in line:
                 error = True
         retval = proc.wait()
         if retval == 0 and error: