merge tracing overhaul in trunk
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Tue, 11 Sep 2007 12:11:00 +0200
changeset 1421 df273f351a4c
parent 1323 08174b13d76f (current diff)
parent 1420 3feedd3e4f5f (diff)
child 1422 d40dfd686fc3
merge tracing overhaul in trunk
.hgignore
examples/simple-point-to-point.cc
src/common/array-trace-resolver.h
src/common/callback-trace-source.cc
src/common/callback-trace-source.h
src/common/composite-trace-resolver.cc
src/common/composite-trace-resolver.h
src/common/empty-trace-resolver.cc
src/common/empty-trace-resolver.h
src/common/fv-trace-source.h
src/common/stream-tracer-test.cc
src/common/stream-tracer.h
src/common/sv-trace-source.h
src/common/terminal-trace-resolver.h
src/common/trace-context-element.cc
src/common/trace-context-element.h
src/common/trace-context.cc
src/common/trace-context.h
src/common/trace-resolver.cc
src/common/trace-resolver.h
src/common/trace-root.cc
src/common/trace-root.h
src/common/uv-trace-source.h
src/common/variable-tracer-test.cc
src/internet-node/arp-ipv4-interface.cc
src/routing/global-routing/global-route-manager-impl.cc
utils/wscript
--- a/.hgignore	Tue Sep 11 10:35:56 2007 +0200
+++ b/.hgignore	Tue Sep 11 12:11:00 2007 +0200
@@ -6,5 +6,6 @@
 .*\.sconsign
 doc/html.*
 doc/latex.*
+doc/trace-source-list.h
 .lock-wscript
 .waf*
--- a/doc/doxygen.conf	Tue Sep 11 10:35:56 2007 +0200
+++ b/doc/doxygen.conf	Tue Sep 11 12:11:00 2007 +0200
@@ -450,7 +450,7 @@
 # directories like "/usr/src/myproject". Separate the files or directories 
 # with spaces.
 
-INPUT                  = src doc/main.txt 
+INPUT                  = src doc/main.txt doc/trace-source-list.h doc/tracing.h
 
 # 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 
@@ -514,7 +514,7 @@
 # directories that contain image that are included in the documentation (see 
 # the \image command).
 
-IMAGE_PATH             = 
+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 
--- a/doc/main.txt	Tue Sep 11 10:35:56 2007 +0200
+++ b/doc/main.txt	Tue Sep 11 12:11:00 2007 +0200
@@ -23,6 +23,7 @@
  *    - \ref config
  *    - a base class for objects which need to support reference counting 
  *      and QueryInterface: ns3::Object and ns3::InterfaceId
+ *    - a set of low-level trace facilities integrated in the ns3::Object system: \ref tracing
  *    - a ns3::ComponentManager which can be used to manage the creation
  *      of any object which derives from ns3::Object through an ns3::ClassId
  *    - a smart-pointer class ns3::Ptr designed to work together with ns3::Object
@@ -33,11 +34,10 @@
  *      ns3::Scheduler and ns3::SchedulerFactory
  *    - a simulator class used to create, schedule and cancel events: ns3::Simulator
  *
- * The "common" module contains:
+ * The "core" module contains:
  *    - a packet class to create and manipulate simulation packets: ns3::Packet, ns3::Header, 
  *      and ns3::Trailer. This packet class also supports per-packet ns3::Tag which are
  *      globs of data which can be attached to any packet.
- *    - a set of low-level trace facilities: \ref lowleveltracing
  *
  * The "node" module contains:
  *    - a ns3::Node base class which should be subclassed by any new type of
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/namespace-2.dia	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,1658 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
+  <dia:diagramdata>
+    <dia:attribute name="background">
+      <dia:color val="#ffffff"/>
+    </dia:attribute>
+    <dia:attribute name="pagebreak">
+      <dia:color val="#000099"/>
+    </dia:attribute>
+    <dia:attribute name="paper">
+      <dia:composite type="paper">
+        <dia:attribute name="name">
+          <dia:string>#A4#</dia:string>
+        </dia:attribute>
+        <dia:attribute name="tmargin">
+          <dia:real val="2.8222000598907471"/>
+        </dia:attribute>
+        <dia:attribute name="bmargin">
+          <dia:real val="2.8222000598907471"/>
+        </dia:attribute>
+        <dia:attribute name="lmargin">
+          <dia:real val="2.8222000598907471"/>
+        </dia:attribute>
+        <dia:attribute name="rmargin">
+          <dia:real val="2.8222000598907471"/>
+        </dia:attribute>
+        <dia:attribute name="is_portrait">
+          <dia:boolean val="true"/>
+        </dia:attribute>
+        <dia:attribute name="scaling">
+          <dia:real val="1.0929253101348877"/>
+        </dia:attribute>
+        <dia:attribute name="fitto">
+          <dia:boolean val="true"/>
+        </dia:attribute>
+        <dia:attribute name="fitwidth">
+          <dia:int val="2"/>
+        </dia:attribute>
+        <dia:attribute name="fitheight">
+          <dia:int val="2"/>
+        </dia:attribute>
+      </dia:composite>
+    </dia:attribute>
+    <dia:attribute name="grid">
+      <dia:composite type="grid">
+        <dia:attribute name="width_x">
+          <dia:real val="1"/>
+        </dia:attribute>
+        <dia:attribute name="width_y">
+          <dia:real val="1"/>
+        </dia:attribute>
+        <dia:attribute name="visible_x">
+          <dia:int val="1"/>
+        </dia:attribute>
+        <dia:attribute name="visible_y">
+          <dia:int val="1"/>
+        </dia:attribute>
+        <dia:composite type="color"/>
+      </dia:composite>
+    </dia:attribute>
+    <dia:attribute name="color">
+      <dia:color val="#d8e5e5"/>
+    </dia:attribute>
+    <dia:attribute name="guides">
+      <dia:composite type="guides">
+        <dia:attribute name="hguides"/>
+        <dia:attribute name="vguides"/>
+      </dia:composite>
+    </dia:attribute>
+  </dia:diagramdata>
+  <dia:layer name="Background" visible="true">
+    <dia:object type="Flowchart - Box" version="0" id="O0">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-1,-27"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-1.05,-27.05;6.05,-24.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-1,-27"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="7"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/devices/[0-n]#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-0.65,-25.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O1">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-8,-39"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-8.05,-39.05;-0.95,-36.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-8,-39"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="7"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="inner_color">
+        <dia:color val="#e6c7c7"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.10000000000000001"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#NodeList#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-4.5,-37.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="1"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O2">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-1,-29"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-1.05,-29.05;6.05,-26.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-1,-29"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="7"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="inner_color">
+        <dia:color val="#e6c7c7"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.10000000000000001"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#Node#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="2.5,-27.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="1"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O3">
+      <dia:attribute name="obj_pos">
+        <dia:point val="3,-16"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="2.95,-16.05;7.05,-13.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="3,-16"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="4"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/queue#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="3.35,-14.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O4">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-8,-37"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-8.05,-37.05;-0.95,-34.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-8,-37"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="7"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/nodes/[0-n]#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-7.65,-35.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O5">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-8,-31"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-8.05,-31.05;-3.95,-28.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-8,-31"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="4"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/udp#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-7.65,-29.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O6">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-16,-25"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-16.05,-25.05;-13.95,-22.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-16,-25"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/rx#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-15.65,-23.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O7">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-17,-19"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-17.05,-19.05;-9.95,-16.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-17,-19"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="7"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/netdevice#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-16.65,-17.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Standard - BezierLine" version="0" id="O8">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-4.5,-35"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-4.55754,-35.0575;3,-28.95"/>
+      </dia:attribute>
+      <dia:attribute name="bez_points">
+        <dia:point val="-4.5,-35"/>
+        <dia:point val="-4,-32"/>
+        <dia:point val="2.5,-31"/>
+        <dia:point val="2.5,-29"/>
+      </dia:attribute>
+      <dia:attribute name="corner_types">
+        <dia:enum val="0"/>
+        <dia:enum val="0"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow">
+        <dia:enum val="22"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_length">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_width">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O4" connection="13"/>
+        <dia:connection handle="3" to="O2" connection="2"/>
+      </dia:connections>
+    </dia:object>
+    <dia:object type="Standard - BezierLine" version="0" id="O9">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-4.5,-35"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-8.00142,-35.0606;-4.43937,-32.8685"/>
+      </dia:attribute>
+      <dia:attribute name="bez_points">
+        <dia:point val="-4.5,-35"/>
+        <dia:point val="-5,-33"/>
+        <dia:point val="-7,-36"/>
+        <dia:point val="-7.5,-33"/>
+      </dia:attribute>
+      <dia:attribute name="corner_types">
+        <dia:enum val="0"/>
+        <dia:enum val="0"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow">
+        <dia:enum val="22"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_length">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_width">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O4" connection="13"/>
+        <dia:connection handle="3" to="O18" connection="2"/>
+      </dia:connections>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O10">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-11,-31"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-11.05,-31.05;-7.95,-28.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-11,-31"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="3"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/ipv4#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-10.65,-29.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O11">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-14,-25"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-14.05,-25.05;-6.95,-22.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-14,-25"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="7"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/interfaces/[0-n]#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-13.65,-23.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O12">
+      <dia:attribute name="obj_pos">
+        <dia:point val="7,-16"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="6.95,-16.05;11.05,-13.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="7,-16"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="4"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/rx#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="7.35,-14.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O13">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-8,-16"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-8.05,-16.05;-3.95,-13.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-8,-16"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="4"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/queue#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-7.65,-14.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O14">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-4,-16"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-4.05,-16.05;2.05,-13.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-4,-16"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="6"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/rx#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-3.65,-14.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O15">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-7,-9"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-7.05,-9.05;-1.95,-6.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-7,-9"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="5"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/enqueue#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-6.65,-7.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O16">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-7,-7"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-7.05,-7.05;-1.95,-4.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-7,-7"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="5"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/dequeue#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-6.65,-5.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O17">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-7,-5"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-7.05,-5.05;-1.95,-2.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-7,-5"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="5"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/drop#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-6.65,-3.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O18">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-11,-33"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-11.05,-33.05;-3.95,-30.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-11,-33"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="7"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="inner_color">
+        <dia:color val="#e6c7c7"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.10000000000000001"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#InternetNode#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-7.5,-31.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="1"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O19">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-8,-18"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-8.05,-18.05;2.05,-15.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-8,-18"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="10"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2.0000000000000018"/>
+      </dia:attribute>
+      <dia:attribute name="inner_color">
+        <dia:color val="#e6c7c7"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.10000000000000001"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#PointToPointNetDevice#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-3,-16.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="1"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O20">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-7,-11"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-7.05,-11.05;-1.95,-8.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-7,-11"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="5"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="inner_color">
+        <dia:color val="#e6c7c7"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.10000000000000001"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#Queue#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-4.5,-9.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="1"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O21">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-16,-27"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-16.05,-27.05;-6.95,-24.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-16,-27"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="9"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="inner_color">
+        <dia:color val="#e6c7c7"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.10000000000000001"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#Ipv4L3Protocol#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-11.5,-25.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="1"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O22">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-17,-21"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-17.05,-21.05;-9.95,-18.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-17,-21"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="7"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="inner_color">
+        <dia:color val="#e6c7c7"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.10000000000000001"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#Ipv4Interface#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-13.5,-19.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="1"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O23">
+      <dia:attribute name="obj_pos">
+        <dia:point val="3,-18"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="2.95,-18.05;11.05,-15.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="3,-18"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="8.0000000000000071"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="inner_color">
+        <dia:color val="#e6c7c7"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.10000000000000001"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#CsmaNetDevice#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="7,-16.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="1"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Standard - BezierLine" version="0" id="O24">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-9.5,-29"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-12,-29.0606;-9.38388,-26.95"/>
+      </dia:attribute>
+      <dia:attribute name="bez_points">
+        <dia:point val="-9.5,-29"/>
+        <dia:point val="-9,-27"/>
+        <dia:point val="-11.5,-29"/>
+        <dia:point val="-11.5,-27"/>
+      </dia:attribute>
+      <dia:attribute name="corner_types">
+        <dia:enum val="0"/>
+        <dia:enum val="0"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow">
+        <dia:enum val="22"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_length">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_width">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O10" connection="13"/>
+        <dia:connection handle="3" to="O21" connection="2"/>
+      </dia:connections>
+    </dia:object>
+    <dia:object type="Standard - BezierLine" version="0" id="O25">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-10.5,-23"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-13.9972,-23.0606;-10.4066,-20.8302"/>
+      </dia:attribute>
+      <dia:attribute name="bez_points">
+        <dia:point val="-10.5,-23"/>
+        <dia:point val="-10,-21"/>
+        <dia:point val="-14,-23"/>
+        <dia:point val="-13.5,-21"/>
+      </dia:attribute>
+      <dia:attribute name="corner_types">
+        <dia:enum val="0"/>
+        <dia:enum val="0"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow">
+        <dia:enum val="22"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_length">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_width">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O11" connection="13"/>
+        <dia:connection handle="3" to="O22" connection="2"/>
+      </dia:connections>
+    </dia:object>
+    <dia:object type="Standard - BezierLine" version="0" id="O26">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-6,-14"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-6.05,-14.05;-4.0028,-10.8302"/>
+      </dia:attribute>
+      <dia:attribute name="bez_points">
+        <dia:point val="-6,-14"/>
+        <dia:point val="-6,-11"/>
+        <dia:point val="-5,-13"/>
+        <dia:point val="-4.5,-11"/>
+      </dia:attribute>
+      <dia:attribute name="corner_types">
+        <dia:enum val="0"/>
+        <dia:enum val="0"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow">
+        <dia:enum val="22"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_length">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_width">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O13" connection="13"/>
+        <dia:connection handle="3" to="O20" connection="2"/>
+      </dia:connections>
+    </dia:object>
+    <dia:object type="Standard - BezierLine" version="0" id="O27">
+      <dia:attribute name="obj_pos">
+        <dia:point val="5,-14"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="4.95,-14.05;7,-10.95"/>
+      </dia:attribute>
+      <dia:attribute name="bez_points">
+        <dia:point val="5,-14"/>
+        <dia:point val="5,-12"/>
+        <dia:point val="6.5,-13"/>
+        <dia:point val="6.5,-11"/>
+      </dia:attribute>
+      <dia:attribute name="corner_types">
+        <dia:enum val="0"/>
+        <dia:enum val="0"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow">
+        <dia:enum val="22"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_length">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_width">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O3" connection="13"/>
+        <dia:connection handle="3" to="O33" connection="2"/>
+      </dia:connections>
+    </dia:object>
+    <dia:object type="Standard - BezierLine" version="0" id="O28">
+      <dia:attribute name="obj_pos">
+        <dia:point val="2.5,-25"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-3.5,-25.05;2.55,-17.95"/>
+      </dia:attribute>
+      <dia:attribute name="bez_points">
+        <dia:point val="2.5,-25"/>
+        <dia:point val="2.5,-23"/>
+        <dia:point val="-3,-20"/>
+        <dia:point val="-3,-18"/>
+      </dia:attribute>
+      <dia:attribute name="corner_types">
+        <dia:enum val="0"/>
+        <dia:enum val="0"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow">
+        <dia:enum val="22"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_length">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_width">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O0" connection="13"/>
+        <dia:connection handle="3" to="O19" connection="2"/>
+      </dia:connections>
+    </dia:object>
+    <dia:object type="Standard - BezierLine" version="0" id="O29">
+      <dia:attribute name="obj_pos">
+        <dia:point val="2.5,-25"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="2.45,-25.05;7.5,-17.95"/>
+      </dia:attribute>
+      <dia:attribute name="bez_points">
+        <dia:point val="2.5,-25"/>
+        <dia:point val="2.5,-23"/>
+        <dia:point val="7,-20"/>
+        <dia:point val="7,-18"/>
+      </dia:attribute>
+      <dia:attribute name="corner_types">
+        <dia:enum val="0"/>
+        <dia:enum val="0"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow">
+        <dia:enum val="22"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_length">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_width">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O0" connection="13"/>
+        <dia:connection handle="3" to="O23" connection="2"/>
+      </dia:connections>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O30">
+      <dia:attribute name="obj_pos">
+        <dia:point val="4,-9"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="3.95,-9.05;9.05,-6.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="4,-9"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="5"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/enqueue#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="4.35,-7.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O31">
+      <dia:attribute name="obj_pos">
+        <dia:point val="4,-7"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="3.95,-7.05;9.05,-4.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="4,-7"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="5"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/dequeue#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="4.35,-5.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O32">
+      <dia:attribute name="obj_pos">
+        <dia:point val="4,-5"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="3.95,-5.05;9.05,-2.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="4,-5"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="5"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#/drop#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="4.35,-3.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Flowchart - Box" version="0" id="O33">
+      <dia:attribute name="obj_pos">
+        <dia:point val="4,-11"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="3.95,-11.05;9.05,-8.95"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="4,-11"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="5"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="2"/>
+      </dia:attribute>
+      <dia:attribute name="inner_color">
+        <dia:color val="#e6c7c7"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="corner_radius">
+        <dia:real val="0.40000000000000002"/>
+      </dia:attribute>
+      <dia:attribute name="padding">
+        <dia:real val="0.10000000000000001"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#Queue#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="1.1000000000000001"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="6.5,-9.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="1"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Standard - BezierLine" version="0" id="O34">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-10,-18"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-10.0693,-20.6883;-5.0028,-17.8302"/>
+      </dia:attribute>
+      <dia:attribute name="bez_points">
+        <dia:point val="-10,-18"/>
+        <dia:point val="-8,-21"/>
+        <dia:point val="-6.5,-22"/>
+        <dia:point val="-5.5,-18"/>
+      </dia:attribute>
+      <dia:attribute name="corner_types">
+        <dia:enum val="0"/>
+        <dia:enum val="0"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow">
+        <dia:enum val="22"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_length">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_width">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O7" connection="8"/>
+        <dia:connection handle="3" to="O19" connection="1"/>
+      </dia:connections>
+    </dia:object>
+    <dia:object type="Standard - BezierLine" version="0" id="O35">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-10,-18"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-10.0702,-22.2491;5.4972,-17.8302"/>
+      </dia:attribute>
+      <dia:attribute name="bez_points">
+        <dia:point val="-10,-18"/>
+        <dia:point val="-1,-25"/>
+        <dia:point val="4,-22"/>
+        <dia:point val="5,-18"/>
+      </dia:attribute>
+      <dia:attribute name="corner_types">
+        <dia:enum val="0"/>
+        <dia:enum val="0"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow">
+        <dia:enum val="22"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_length">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_width">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O7" connection="8"/>
+        <dia:connection handle="3" to="O23" connection="1"/>
+      </dia:connections>
+    </dia:object>
+  </dia:layer>
+</dia:diagram>
Binary file doc/namespace-2.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/trace-source-list.h	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,204 @@
+///
+/// \ingroup TraceSourceList
+/// \brief send ipv4 packet to outgoing interface
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet sent.
+/// \param arg3 index of output ipv4 interface.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/ipv4/tx.
+///
+/// The following classes can be extracted from \p arg1 with 
+/// ns3::TraceContext::GetElement:
+///  - ns3::NodeListIndex
+///  - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback0 (const TraceContext & arg1, const Packet & arg2, uint32_t arg3);
+
+///
+/// \ingroup TraceSourceList
+/// \brief receive ipv4 packet from incoming interface
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet received.
+/// \param arg3 index of input ipv4 interface.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/ipv4/rx.
+///
+/// The following classes can be extracted from \p arg1 with 
+/// ns3::TraceContext::GetElement:
+///  - ns3::NodeListIndex
+///  - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback1 (const TraceContext & arg1, const Packet & arg2, uint32_t arg3);
+
+///
+/// \ingroup TraceSourceList
+/// \brief drop ipv4 packet
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet dropped.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/ipv4/drop.
+///
+/// The following classes can be extracted from \p arg1 with 
+/// ns3::TraceContext::GetElement:
+///  - ns3::NodeListIndex
+///  - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback2 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief store packet in queue
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet queued.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/queue/enqueue.
+///
+/// The following classes can be extracted from \p arg1 with 
+/// ns3::TraceContext::GetElement:
+///  - ns3::NodeListIndex
+///  - ns3::NodeNetDeviceIndex
+///  - ns3::QueueTraceType
+void TraceSinkCallback3 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief remove packet from queue
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet dequeued.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/queue/dequeue.
+///
+/// The following classes can be extracted from \p arg1 with 
+/// ns3::TraceContext::GetElement:
+///  - ns3::NodeListIndex
+///  - ns3::NodeNetDeviceIndex
+///  - ns3::QueueTraceType
+void TraceSinkCallback4 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief drop packet from queue
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet dropped.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/queue/drop.
+///
+/// The following classes can be extracted from \p arg1 with 
+/// ns3::TraceContext::GetElement:
+///  - ns3::NodeListIndex
+///  - ns3::NodeNetDeviceIndex
+///  - ns3::QueueTraceType
+void TraceSinkCallback5 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief receive MAC packet
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet received.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/rx.
+///
+/// The following classes can be extracted from \p arg1 with 
+/// ns3::TraceContext::GetElement:
+///  - ns3::NodeListIndex
+///  - ns3::NodeNetDeviceIndex
+///  - ns3::PointToPointTraceType
+void TraceSinkCallback6 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief receive MAC packet
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet received.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/rx.
+///
+/// The following classes can be extracted from \p arg1 with 
+/// ns3::TraceContext::GetElement:
+///  - ns3::NodeListIndex
+///  - ns3::NodeNetDeviceIndex
+///  - ns3::CsmaTraceType
+void TraceSinkCallback7 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief drop MAC packet
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet dropped.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/devices/[0-n]/drop.
+///
+/// The following classes can be extracted from \p arg1 with 
+/// ns3::TraceContext::GetElement:
+///  - ns3::NodeListIndex
+///  - ns3::NodeNetDeviceIndex
+///  - ns3::CsmaTraceType
+void TraceSinkCallback8 (const TraceContext & arg1, const Packet & arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief The value of the speed vector changed
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 the mobility model whose course changed.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/$MobilityModelNotifier/course-change.
+///
+/// The following classes can be extracted from \p arg1 with 
+/// ns3::TraceContext::GetElement:
+///  - ns3::NodeListIndex
+void TraceSinkCallback9 (const TraceContext & arg1, Ptr<const MobilityModel> arg2);
+
+///
+/// \ingroup TraceSourceList
+/// \brief send ipv4 packet to outgoing interface
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet sent.
+/// \param arg3 index of output ipv4 interface.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/$Ipv4L3Protocol/tx.
+///
+/// The following classes can be extracted from \p arg1 with 
+/// ns3::TraceContext::GetElement:
+///  - ns3::NodeListIndex
+///  - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback10 (const TraceContext & arg1, const Packet & arg2, uint32_t arg3);
+
+///
+/// \ingroup TraceSourceList
+/// \brief receive ipv4 packet from incoming interface
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet received.
+/// \param arg3 index of input ipv4 interface.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/$Ipv4L3Protocol/rx.
+///
+/// The following classes can be extracted from \p arg1 with 
+/// ns3::TraceContext::GetElement:
+///  - ns3::NodeListIndex
+///  - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback11 (const TraceContext & arg1, const Packet & arg2, uint32_t arg3);
+
+///
+/// \ingroup TraceSourceList
+/// \brief drop ipv4 packet
+/// \param arg1 the trace context associated to the connected trace source.
+/// \param arg2 packet dropped.
+///
+///
+/// The path to this trace source is: /nodes/[0-n]/$Ipv4L3Protocol/drop.
+///
+/// The following classes can be extracted from \p arg1 with 
+/// ns3::TraceContext::GetElement:
+///  - ns3::NodeListIndex
+///  - ns3::Ipv4L3ProtocolTraceContextElement
+void TraceSinkCallback12 (const TraceContext & arg1, const Packet & arg2);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tracing.h	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,576 @@
+/**
+ * \defgroup TraceSourceList List of trace sources
+ */
+
+/**
+ * \defgroup tracing Tracing
+ *
+ * The flexibility of the ns-3 tracing system comes at the cost of quite
+ * a bit of complexity so, before trying to use the low-level aspects
+ * of the tracing API, it is important to focus on some basic definitions:
+ *
+ * - A trace source is an object instance which can report trace events
+ *   to a set of listening trace sinks.
+ *
+ * - A trace sink is a user-provided callback (a function) which can
+ *   be connected to a set of trace sources to receive the events generated
+ *   by each trace source.
+ *
+ * - A trace resolver is an object which allows users to establish 
+ *   connections between a set of trace sources and a set of trace sinks.
+ *
+ * \section TraceSource Generating Trace Events
+ *
+ * So, what does it look like in practice ? First, let's look at trace
+ * sources. We have two types of trace sources: numeric, and, normal 
+ * trace sources. Numeric trace sources behave as normal c++ integers 
+ * or c++ floating point numbers except that they report as trace events 
+ * each change of their value. For example:
+ * \code
+ * class MyModel 
+ * {
+ * public:
+ *   void DoSomething (void) 
+ *   {
+ *     // use the "int" trace source just 
+ *     // like any other "int" variable.
+ *     m_cwnd *= 2;
+ *     m_cwnd += 4;
+ *     if (m_cwnd > 100)
+ *       {
+ *         // do something.
+ *       }
+ *   }
+ * private:
+ *   // declare an instance of a "int" trace source
+ *   SVTraceSource<int> m_cwnd;
+ * };
+ * \endcode
+ * Normal trace sources, on the other hand, allow you to trace the
+ * call of arbitrary functions and methods, as shown below. They are
+ * typically used to track "rx", "tx", or "drop" events but could
+ * also be used to track route change events, or position change
+ * events:
+ * \code
+ * class MyModel 
+ * {
+ * public:
+ *   void DoSomething (Packet packet) 
+ *   {
+ *     // report this event on packet
+ *     m_doSomething (packet);
+ *     // do something
+ *   }
+ * private:
+ *   // report every "something" function call.
+ *   CallbackTraceSource<Packet> m_doSomething;
+ * };
+ * \endcode
+ * Every type of trace source derives from the ns3::TraceSource base class.
+ * As of today, the set of concrete subclasses is relatively short:
+ * ns3::CallbackTraceSource, ns3::SvTraceSource, ns3::UvTraceSource, and,
+ * ns3::FvTraceSource.
+ *
+ * \section TraceSink Receiving Trace Events
+ *
+ * To receive these trace events, a user should specify a set of trace sinks.
+ * For example, to receive the "int" and the "something" events shown in the
+ * examples above, a user would declare the following functions:
+ * \code
+ * // oldValue and newValue contain the previous and new values of 
+ * // the connected SVTraceSource<int> trace source.
+ * void 
+ * CwndTraceSink (const TraceContext &context, int64_t oldValue, int64_t newValue)
+ * {
+ *   // for example, print the new value:
+ *   std::cout << "cwnd=" << newValue << std::endl;
+ * }
+ * void 
+ * DoSomethingTraceSink (const TraceContext &context, Packet packet)
+ * {
+ *   // for example, print the arguments
+ *   std::cout << "packet " << packet << std::endl;
+ * }
+ * \endcode
+ * Each of these sink function takes, as a first argument, a reference to a 
+ * const TraceContext object. This context object contains information which
+ * describes the instance of the connected trace source: that information is
+ * setup during the connection process and does not change afterwards
+ * The type and the number of the other arguments to each trace sink depends
+ * on the type of the connected trace source: it conveys per-event information
+ * from the trace source to the trace sink. For example, UVTraceSource and 
+ * SVTraceSource trace sources require two extra arguments. The former requires
+ * two unsigned 64 bit integers while the latter requires two signed 64 bit 
+ * integers. More generally, users can consult the \ref TraceSourceList
+ * to figure out the arguments which a trace sink is required to receive
+ * for each trace source: a signature of the user trace sink must match 
+ * _exactly_ the signature documented in the \ref TraceSourceList.
+ *
+ *
+ * \section TraceSourceSimpleExport A simple way to connect Trace Sources with Trace Sinks
+ *
+ * The crux of the complexity of the ns-3 tracing system comes from its 
+ * flexible system used to connect trace sources to trace sinks but what is really
+ * nice about it is that it is not necessary to use it to setup simple traces.
+ * 
+ * The simplest way to export a set of trace sources to a user, for example, 
+ * during the early prototyping phases of a system, is to add a set of public methods
+ * to give to your users access to the trace source object instances you use to generate
+ * trace events:
+ * \code
+ * class MyModel 
+ * {
+ * public:
+ *   void DoSomething (Packet packet) 
+ *   {
+ *     // report this event on packet
+ *     m_doSomething (packet);
+ *     // do something
+ *   }
+ *   CallbackTraceSource<Packet> *PeekSomethingTraceSource (void) const 
+ *   {
+ *     return &m_doSomething
+ *   }
+ * private:
+ *   // report every "something" function call.
+ *   CallbackTraceSource<Packet> m_doSomething;
+ * };
+ * \endcode
+ * If your users hold a pointer to an instance of MyModel, and if they want to connect
+ * a MySomethingSink, they can simply do the following which invokes the 
+ * TraceSource::AddCallback method and creates a Callback object from the user's
+ * sink with the MakeCallback function.
+ * \code
+ * void 
+ * MySomethingSink (const TraceContext &context, Packet packet)
+ * {
+ *   // do whatever you want.
+ * }
+ * MyModel *model = ...;
+ * CallbackTraceSource<Packet> *source = model->PeekSomethingTraceSource ();
+ * source->AddCallback (MakeCallback (&MySomethingSink));
+ * \endcode
+ *
+ * The full power of the tracing system comes however from its ns3::NodeList::Connect
+ * method which is described in the following sections.
+ *
+ * \section TraceConnection Connecting Trace Sources to Trace Sinks
+ * 
+ * If a trace source is integrated in the ns-3 trace connection facility, a user 
+ * should call the ns3::NodeList::Connect method to establish a connection between
+ * a trace sink and a set of matching trace sources. The second argument to that
+ * method is a callback to the user's trace sink.
+ * That callback is easy to construct: call ns3::MakeCallback and you are done. The
+ * first argument is a string whose format is similar to a unix path and which is 
+ * used to uniquely identify the set of trace sources you want to connect to.
+ * The set of acceptable path strings is also documented in the \ref TraceSourceList.
+ *
+ * So, what does this look like from the perspective of a user ? If we wanted to 
+ * connect to a trace source defined somewhere deep into the a set of NetDevice objects
+ * located in some nodes of the system, we could write the following:
+ * \code
+ * void 
+ * DoSomethingTraceSink (const TraceContext &context, Packet packet)
+ * {
+ *   // for example, print the arguments
+ *   std::cout << "packet: " << packet << std::endl;
+ * }
+ * // connect the above sink to a matching trace source
+ * NodeList::Connect ("/nodes/* /devices/* /rx", MakeCallback &DoSomethingTraceSink);
+ * \endcode
+ *
+ * The connection path string "/nodes/* /devices/* /rx" matches the "rx" trace source
+ * located in every netdevice located in every node. The syntax of that path string
+ * is loosely based on regular expressions so, a user could conceivably connect
+ * to the trace sources present in only one node identified by node index:
+ * "/nodex/3/devices/* /rx".
+ *
+ * The matching algorithm used here is very useful since it allows you to connect
+ * at once a large set of trace sources to a single sink but it introduces another 
+ * problem: it becomes impossible when you receive an event in your trace sink to
+ * know from _which_ trace source the event is coming from. In our example, the
+ * trace source might be coming from the NetDevice number 2 of Node 10 or Netdevice
+ * number 0 of Node 5. In both cases, you might need to know which of these NetDevice
+ * is generating this event, if only to generate some ascii trace dump. Another 
+ * similar use-case is that you might have connected the same trace sink to
+ * multiple types of events which have the same signature: it is quite common
+ * to receive all tx, rx, and drop events in the same trace sink and that would be
+ * quite trivial to achieve with a string such as: "/nodes/* /devices/* /*"
+ *
+ * The source of a trace event can be retrieved from a trace sink using 
+ * different means: the simplest
+ * way to get this information is to use the builtin printing facility of
+ * the TraceContext object:
+ * \code
+ * void 
+ * DoSomethingTraceSink (const TraceContext &context, Packet packet)
+ * {
+ *   // for example, print the arguments
+ *   std::cout << "context=\"" << context << "\" packet: " << packet << std::endl;
+ * }
+ * \endcode
+ * The above code is going to generate output which looks like the following:
+ * \code
+ * context="nodeid=2 device=0 dev-rx" packet: IPV4(tos 0x0 ttl 64 id 0 offset ...
+ * context="nodeid=1 device=0 dev-rx" packet: IPV4(tos 0x0 ttl 64 id 0 offset ...
+ * ...
+ * \endcode
+ *
+ * Another more advanced way to get information out of a TraceContext is to call its
+ * ns3::TraceContext::GetElement method. This method takes as its first and only
+ * argument an instance of the object we want to read and the list of available
+ * object instances we can read from a TraceContext is documented, once again,
+ * in the \ref TraceSourceList. For example, we could write the following to
+ * generate adhoc trace output:
+ * \code
+ * void DeviceRxSink (const TraceContext &context, const Packet &packet)
+ * {
+ *   NodeListIndex nodeIndex;
+ *   NodeNetDeviceIndex deviceIndex;
+ *   context.GetElement (nodeIndex);
+ *   context.GetElement (deviceIndex);
+ *   std::cout << "node-index=" << nodeIndex.Get ();
+ *   std::cout << ", device-index=" << deviceIndex.Get ();
+ *   std::cout << ", packet: " << packet;
+ *   std::cout << std::endl;
+ * }
+ * \endcode
+ *
+ * \section ExportingTraceSources Exporting new Trace Sources
+ *
+ * Using existing trace sources to connect them to a set of adhoc trace sinks
+ * is not really complicated but, setting up new trace sources which can hook
+ * in this automatic connection system is a bit more complicated.
+ *
+ * So far, we know that a model author can generate trace events really easily:
+ * \code
+ * class MyModel 
+ * {
+ * public:
+ *   void DoSomething (Packet packet) 
+ *   {
+ *     // report this event on packet with value
+ *     m_doSomething (packet);
+ *     // do something
+ *   }
+ * private:
+ *   // report every "something" function call.
+ *   CallbackTraceSource<Packet> m_doSomething;
+ * };
+ * \endcode
+ *
+ * To make these new trace sources available to the rest of the connection system,
+ * the first step is to make sure that your model object derives from the ns3::Object
+ * base class either directly (as shown below) or indirectly through another base class:
+ * \code
+ * class MyModel : public Object {...};
+ * // or:
+ * class SomeOtherObject : public Object {...};
+ * class MyModel : public SomeOtherObject {...};
+ * \endcode
+ *
+ * This is pretty trivial and lays the ground for the second step: overriding the
+ * ns3::Object::GetTraceResolver method:
+ * \code
+ * class MyModel : public MyParent
+ * {
+ * public:
+ *   // declare overriden method
+ *   virtual Ptr<TraceResolver> GetTraceResolver (void) const;
+ * private:
+ *   // the new trace source to export.
+ *   CallbackTraceSource<Packet> m_rxSource;
+ * };
+ * \endcode
+ *
+ * To implement this method, you could attempt to implement a new subclass of
+ * the ns3::TraceResolver base class and return an instance from this method but
+ * this would be very hard. Instead, you should use the helper class
+ * ns3::CompositeTraceResolver to register your trace sources and chain up to
+ * your parent:
+ * \code
+ * Ptr<TraceResolver>
+ * MyModel::GetTraceResolver (void) const
+ * {
+ *   // create an empty trace resolver
+ *   Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+ *   // register m_rxSource
+ *   resolver->AddSource ("rx", // the name of the trace source in the path string
+ *                        TraceDoc ("some help text to explain the purpose of this trace source",
+ *                                  "Packet", // the type of the first argument to the trace source
+ *                                  "the purpose of the first argument",
+ *                                  "type-of-second-argument", "purpose-of-second-argument"),
+ *                        m_rxSource // the trace source itself is registered
+ *                       );
+ *   // make sure we include the trace sources implemented in the parent.
+ *   resolver->SetParentResolver (MyParent::GetTraceResolver ());
+ *   return resolver;
+ * }
+ * \endcode
+ *
+ * Once you have written that code, you must make sure that this new method GetTraceResolver
+ * is going to be called at some point by the tracing system. If your model is located somewhere
+ * deep in MAC or PHY layer, that is, it is part of a NetDevice implementation, all you
+ * have to do is to make sure that your model is registered as a "composite" of your NetDevice
+ * subclass:
+ * \code
+ * class MyNetDevice : public NetDevice
+ * {
+ * public:
+ *   Ptr<TraceResolver> GetTraceResolver (void) const;
+ * private:
+ *   Ptr<MyModel> m_model;
+ * };
+ * 
+ * Ptr<TraceResolver>
+ * MyNetDevice::GetTraceResolver (void) const
+ * {
+ *   Ptr<CompositeTraceResolver> resolver = ...;
+ *   // register other trace source
+ *   ...
+ *   // register now your model as a "composite"
+ *   resolver->AddComposite ("my-model", m_model);
+ *   // chain up to parent.
+ *   resolver->SetParentResolver (NetDevice::GetTraceResolver ());
+ *   return resolver;
+ * }
+ * \endcode
+ * 
+ * The code above will make your "rx" trace source appear under the
+ * /nodes/xx/devices/xx/my-model/rx namespace path.
+ *
+ * If you have implemented a new layer 3 or 4 protocol object, the process to
+ * export your trace sources is quite similar. You need to subclass from
+ * ns3::Object, override the ns3::Object::GetTraceResolver method, make
+ * sure you chain up to your parent's GetTraceResolver method, and, finally,
+ * make sure that someone calls your new GetTraceResolver method. How to accomplish
+ * the latter should be documented in the node's API documentation which describes
+ * how to implement a new layer 3 or 4 protocol object.
+ *
+ * \section AdvancedTraceContext Creating new Trace Context Elements
+ *
+ * The last important feature which model developers need to understand
+ * is how to provide extra context information to trace sinks. For example,
+ * if your model exports both rx and tx trace sources which share the same 
+ * signature, it is quite natural for a user to connect to a single trace sink
+ * to both of them with a trace path string such as "/nodes/* /devices/* /(rx|tx)".
+ * In this case, it becomes necessary to be able, from the trace sink function,
+ * to tell which event triggered the call to the trace sink: a rx or a tx event.
+ *
+ * That example is detailed below with a TX, a RX, and a DROP source:
+ * \code
+ * class MyModel
+ * {
+ * private:
+ *   CallbackTraceSource<Packet> m_rxSource;
+ *   CallbackTraceSource<Packet> m_txSource;
+ *   CallbackTraceSource<Packet> m_dropSource;
+ * };
+ * \endcode
+ * When a single sink is connected to all 3 sources here, one might want
+ * to write code like the following:
+ * \code
+ * void DeviceRxSink (const TraceContext &context, const Packet &packet)
+ * {
+ *   switch (type) {
+ *     case RX:
+ *       std::cout << "rx" << std::endl;
+ *       break;
+ *     case TX:
+ *       std::cout << "tx" << std::endl;
+ *       break;
+ *     case DROP:
+ *       std::cout << "drop" << std::endl;
+ *       break;
+ *   }
+ * \endcode
+ *
+ * \subsection AdvancedTraceContextSimpleSolution The simple solution
+ *
+ * The simplest way to do achieve the result shown above is to include
+ * in the trace source an extra explicit argument which describes the source event:
+ *   - define a small enum with 3 values
+ *   - change the signature of m_rxSource, m_txSource, and m_dropSource to include
+ *     the enum
+ *   - pass the enum value in each event
+ *
+ * The resulting code is shown below:
+ * \code
+ * class MyModel
+ * {
+ * public:
+ *   // define the trace type enum.
+ *   enum TraceType {
+ *     RX,
+ *     TX,
+ *     DROP
+ *   };
+ * private:
+ *   // generate events
+ *   void NotifyRxPacket (Packet p) {
+ *     m_rxSource (p, MyModel::RX);
+ *   }
+ *   void NotifyTxPacket (Packet p) {
+ *     m_rxSource (p, MyModel::TX);
+ *   }
+ *   void NotifyDropPacket (Packet p) {
+ *     m_rxSource (p, MyModel::DROP);
+ *   }
+ *   CallbackTraceSource<Packet,enum TraceType> m_rxSource;
+ *   CallbackTraceSource<Packet,enum TraceType> m_txSource;
+ *   CallbackTraceSource<Packet,enum TraceType> m_dropSource;
+ * };
+ * \endcode
+ * These 3 new sources can be connected easily to a new trace sink:
+ * \code
+ * void ASimpleTraceSink (const TraceContext &context, const Packet &packet, enum MyModel::TraceType type)
+ * {
+ *   // here, read the "type" argument
+ * }
+ * \endcode
+ *
+ * This solution works but it makes it impossible to connect a single trace sink to a set
+ * of trace sources which represent "rx" events in different NetDevice objects since
+ * each of them will define a different enum type with different values: since the
+ * trace sink signature must match exactly the trace source signature, it is impossible
+ * to connect at the same time to all "rx" events of different NetDevice.
+ *
+ * \subsection AdvancedTraceContextFancySolution The more complex and generic solution
+ *
+ * There is, hopefully, a way to get the best of both worlds, that is, to allow a
+ * user to connect to a lot of trace source events of the same kind but coming from different
+ * implementations and to allow the user to differentiate between these different
+ * implementations.
+ *
+ * Rather than define an adhoc enum type with a list of trace sources, you can also
+ * define a new ns3::TraceContextElement for your source sources. For example, if you
+ * define a new MyModelTraceType class which contains the type of trace, your users can
+ * then write trace sink code which looks like this:
+ * \code
+ * void AFancyTraceSink (const TraceContext &context, const Packet &packet)
+ * {
+ *   MyModelTraceType type;
+ *   if (context.GetElement (type))
+ *     {
+ *       switch (type.Get ())
+ *         {
+ *         case MyModelTraceType::RX:
+ *           std::cout << "rx" << std::endl;
+ *           break;
+ *         case MyModelTraceType::TX:
+ *           std::cout << "tx" << std::endl;
+ *           break;
+ *         case MyModelTraceType::DROP:
+ *           std::cout << "drop" << std::endl;
+ *           break;
+ *         }
+ *     }
+ * }
+ * \endcode
+ *
+ * Of course, since the type of trace is stored in the TraceContext, your users can
+ * also take the shortcut which uses the printing functionality of the TraceContext:
+ * \code
+ * void ALessFancyTraceSink (const TraceContext &context, const Packet &packet)
+ * {
+ *   std::cout << "context=\"" << context << "\" packet: " << packet << std::endl;
+ * }
+ * \endcode
+ * which will generate something like the following when the trace source comes
+ * from MyModel:
+ * \code
+ * context="my-model-rx" packet: ...
+ * \endcode
+ *
+ * The first step to achieve this is to define and implement a new
+ * subclass of the ns3::TraceContextElement base class. The exact list of
+ * public methods which must be implemented is described in the API
+ * documentation of the ns3::TraceContextElement class. 
+ * \code
+ * class MyModelTraceType : public TraceContextElement
+ * {
+ * public:
+ *   enum Type {
+ *     RX,
+ *     TX,
+ *     DROP
+ *   };
+ *   // called from MyModel::GetTraceResolver
+ *   MyModelTraceType (enum Type type);
+ *   // called from trace sink
+ *   enum Type Get (void) const;
+ *   // needed by the tracing subsystem
+ *   static uint16_t GetUid (void);
+ *   // needed by the tracing subsystem to
+ *   // print the content of a TraceContext
+ *   void Print (std::ostream &os) const;
+ *   // needed by the tracing subsystem to
+ *   // generate the doxygen documentation.
+ *   std::string GetTypeName (void) const;
+ * private:
+ *   enum Type m_type;
+ * };
+ * \endcode
+ * The implementation does not require much thinking:
+ * \code
+ * MyModelTraceType::MyModelTraceType (enum Type type)
+ *  : m_type (type)
+ * {}
+ * enum Type 
+ * MyModelTraceType::Get (void) const
+ * {
+ *   return m_type;
+ * }
+ * uint16_t 
+ * MyModelTraceType::GetUid (void)
+ * {
+ *   // use protected TraceContextElement::AllocateUid method
+ *   // the input string is used to uniquely identify this new subclass
+ *   static uint16_t uid = AllocateUid<MyModelTraceType> ("ns3::MyModelTraceType");
+ *   return uid;
+ * }
+ * void 
+ * MyModelTraceType::Print (std::ostream &os) const
+ * (
+ *   // this method is invoked by the print function of a TraceContext
+ *   // if it contains an instance of this TraceContextElement.
+ *   switch (m_type) {
+ *     case RX: os << "rx"; break;
+ *     // ...
+ *   }
+ * )
+ * std::string 
+ * MyModelTraceType::GetTypeName (void) const
+ * {
+ *   // This method should return a fully-qualified c++ typename
+ *   // This method is used only for documentation purposes to
+ *   // generate the content of the Trace Source List.
+ *   return "ns3::MyModelTraceType";
+ * }
+ * \endcode
+ *
+ * Once this subclass is implemented, the work is almost completed: you
+ * just need to pass an instance of that class as the last argument of 
+ * the ns3::CompositeTraceResolver::AddSource method as shown below:
+ * \code
+ * Ptr<TraceResolver>
+ * MyModel::GetTraceResolver (void) const
+ * {
+ *   // create an empty trace resolver
+ *   Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+ *   // register m_rxSource
+ *   resolver->AddSource ("rx", // the name of the trace source in the path string
+ *                        TraceDoc ("some help text to explain the purpose of this trace source",
+ *                                  "Packet", // the type of the first argument to the trace source
+ *                                  "the purpose of the first argument",
+ *                                  "type-of-second-argument", "purpose-of-second-argument"),
+ *                        m_rxSource, // the trace source itself is registered
+ *                        // the TraceContextElement associated to this trace source.
+ *                        MyModelTraceType (MyModelTraceType::RX) 
+ *                       );
+ *   // make sure we include the trace sources implemented in the parent.
+ *   resolver->SetParentResolver (MyParent::GetTraceResolver ());
+ *   return resolver;
+ * }
+ * \endcode
+ */
--- a/samples/main-random-topology.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/samples/main-random-topology.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -15,7 +15,7 @@
 using namespace ns3;
 
 static void 
-CourseChange (Ptr<const MobilityModel> position)
+CourseChange (const TraceContext &context, Ptr<const MobilityModel> position)
 {
   Position pos = position->Get ();
   std::cout << Simulator::Now () << ", pos=" << position << ", x=" << pos.x << ", y=" << pos.y
@@ -39,7 +39,7 @@
   for (uint32_t i = 0; i < 10000; i++)
     {
       Ptr<MobilityModelNotifier> notifier = Create<MobilityModelNotifier> ();
-      notifier->RegisterListener (MakeCallback (&CourseChange));
+      notifier->TraceConnect ("/course-change", MakeCallback (&CourseChange));
       objects.push_back (notifier);
     }
 
--- a/src/common/array-trace-resolver.h	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * 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 ARRAY_TRACE_RESOLVER_H
-#define ARRAY_TRACE_RESOLVER_H
-
-#include <stdint.h>
-#include <string>
-#include "ns3/callback.h"
-#include "trace-resolver.h"
-
-namespace ns3 {
-
-/**
- * \brief a helper class to offer trace resolution for an array of objects.
- * \ingroup lowleveltracing
- */
-template <typename T, typename INDEX>
-class ArrayTraceResolver : public TraceResolver
-{
-public:
-  /**
-   * \param context trace context associated to this trace resolver
-   * \param getSize callback which returns dynamically the size of underlying array
-   * \param get callback which returns any element in the underlying array
-   *
-   * Construct a trace resolver which can match any input integer
-   * against an element in an array. The array is accessed using a 
-   * pair of callbacks. It is the responsability of the user to
-   * provide two such callbacks whose job is to adapt the array
-   * API to the resolver needs. Each element of the array is expected
-   * to provide a method named CreateTraceResolver which takes as
-   * only argument a reference to a const TraceContext and returns
-   * a pointer to a TraceResolver. i.e. the signature is:
-   * TraceResolver * (*) (TraceContext const &)
-   */
-  ArrayTraceResolver (TraceContext const &context,
-                      Callback<uint32_t> getSize, 
-                      Callback<T, uint32_t> get);
-private:
-  virtual TraceResolverList DoLookup (std::string id) const;
-  Callback<uint32_t> m_getSize;
-  Callback<T, uint32_t> m_get;
-};
-}//namespace ns3
-
-namespace ns3 {
-
-template <typename T, typename INDEX>
-ArrayTraceResolver<T,INDEX>::ArrayTraceResolver (TraceContext const &context,
-                                                 Callback<uint32_t> getSize, 
-                                                 Callback<T, uint32_t> get)
-  : TraceResolver (context),
-    m_getSize (getSize),
-    m_get (get)
-{}
-template <typename T, typename INDEX>
-TraceResolver::TraceResolverList 
-ArrayTraceResolver<T,INDEX>::DoLookup (std::string id) const
-{
-  TraceResolverList list;
-  if (id == "*")
-  {
-    for (uint32_t i = 0; i < m_getSize (); i++)
-    {
-      TraceContext context = GetContext ();
-      INDEX index = i;
-      context.Add (index);
-      list.push_back (m_get (i)->CreateTraceResolver (context));
-    }
-  }
-  return list;
-}
-
-
-}//namespace ns3
-
-#endif /* ARRAY_TRACE_RESOLVER_H */
--- a/src/common/callback-trace-source.cc	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * 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 "callback-trace-source.h"
-#include "ns3/test.h"
-
-namespace ns3 {
-
-class CallbackTraceSourceTest : public Test 
-{
-public:
-  CallbackTraceSourceTest ();
-  virtual ~CallbackTraceSourceTest ();
-  virtual bool RunTests (void);
-private:
-  void CbOne (TraceContext const &context, uint8_t a, double b);
-  void CbTwo (TraceContext const &context, uint8_t a, double b);
-
-  bool m_one;
-  bool m_two;
-};
-
-CallbackTraceSourceTest::CallbackTraceSourceTest ()
-  : Test ("CallbackTraceSource")
-{}
-CallbackTraceSourceTest::~CallbackTraceSourceTest ()
-{}
-void
-CallbackTraceSourceTest::CbOne (TraceContext const &context, uint8_t a, double b)
-{
-  m_one = true;
-}
-void
-CallbackTraceSourceTest::CbTwo (TraceContext const &context, uint8_t a, double b)
-{
-  m_two = true;
-}
-bool 
-CallbackTraceSourceTest::RunTests (void)
-{
-  bool ok = true;
-  TraceContext ctx;
-
-  CallbackTraceSource<uint8_t,double> trace;
-  trace.AddCallback (MakeCallback (&CallbackTraceSourceTest::CbOne, this), ctx);
-  trace.AddCallback (MakeCallback (&CallbackTraceSourceTest::CbTwo, this), ctx);
-  m_one = false;
-  m_two = false;
-  trace (1, 2);
-  if (!m_one || !m_two)
-    {
-      ok = false;
-    }
-  trace.RemoveCallback (MakeCallback (&CallbackTraceSourceTest::CbOne, this));
-  m_one = false;
-  m_two = false;
-  trace (1, 2);
-  if (m_one || !m_two)
-    {
-      ok = false;
-    }
-  trace.RemoveCallback (MakeCallback (&CallbackTraceSourceTest::CbTwo, this));
-  m_one = false;
-  m_two = false;
-  trace (1, 2);
-  if (m_one || m_two)
-    {
-      ok = false;
-    }
-
-  return ok;
-}
-
-CallbackTraceSourceTest g_callbackTraceTest;
-
-
-
-}//namespace ns3
--- a/src/common/callback-trace-source.h	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 INRIA
- * All rights reserved.
- *
- * 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 CALLBACK_TRACE_H
-#define CALLBACK_TRACE_H
-
-#include <list>
-#include "ns3/callback.h"
-#include "ns3/fatal-error.h"
-#include "trace-context.h"
-
-namespace ns3 {
-
-
-/**
- * \brief log arbitrary number of parameters to a matching ns3::Callback
- * \ingroup lowleveltracing
- *
- * Whenever operator () is invoked on this class, the call and its arguments
- * are forwarded to the internal matching ns3::Callback.
- */
-template<typename T1 = empty, typename T2 = empty, 
-         typename T3 = empty, typename T4 = empty>
-class CallbackTraceSource {
-public:
-  CallbackTraceSource ();
-  void AddCallback (CallbackBase const & callback, TraceContext const & context);
-  void RemoveCallback (CallbackBase const & callback);
-  void operator() (void);
-  void operator() (T1 a1);
-  void operator() (T1 a1, T2 a2);
-  void operator() (T1 a1, T2 a2, T3 a3);
-  void operator() (T1 a1, T2 a2, T3 a3, T4 a4);
-
-private:
-  typedef std::list<Callback<void,TraceContext const &,T1,T2,T3,T4> > CallbackList;
-  TraceContext m_context;
-  CallbackList m_callbackList;
-};
-
-}; // namespace ns3
-
-// implementation below.
-
-namespace ns3 {
-
-template<typename T1, typename T2, 
-         typename T3, typename T4>
-CallbackTraceSource<T1,T2,T3,T4>::CallbackTraceSource ()
-  : m_callbackList () 
-{}
-template<typename T1, typename T2, 
-         typename T3, typename T4>
-void 
-CallbackTraceSource<T1,T2,T3,T4>::AddCallback (CallbackBase const & callback,
-                                               TraceContext const &context)
-{
-  Callback<void,TraceContext const &,T1,T2,T3,T4> cb;
-  cb.Assign (callback);
-  m_context.Add (context);
-  m_callbackList.push_back (cb);
-}
-template<typename T1, typename T2, 
-         typename T3, typename T4>
-void 
-CallbackTraceSource<T1,T2,T3,T4>::RemoveCallback (CallbackBase const & callback)
-{
-  for (typename CallbackList::iterator i = m_callbackList.begin ();
-       i != m_callbackList.end (); /* empty */)
-    {
-      if ((*i).IsEqual (callback))
-	{
-	  i = m_callbackList.erase (i);
-	}
-      else
-	{
-	  i++;
-	}
-    }
-}
-template<typename T1, typename T2, 
-         typename T3, typename T4>
-void 
-CallbackTraceSource<T1,T2,T3,T4>::operator() (void) 
-{
-  for (typename CallbackList::iterator i = m_callbackList.begin ();
-       i != m_callbackList.end (); i++)
-    {
-      (*i) (m_context);
-    }
-}
-template<typename T1, typename T2, 
-         typename T3, typename T4>
-void 
-CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1) 
-{
-  for (typename CallbackList::iterator i = m_callbackList.begin ();
-       i != m_callbackList.end (); i++)
-    {
-      (*i) (m_context, a1);
-    }
-}
-template<typename T1, typename T2, 
-         typename T3, typename T4>
-void 
-CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1, T2 a2) 
-{
-  for (typename CallbackList::iterator i = m_callbackList.begin ();
-       i != m_callbackList.end (); i++)
-    {
-      (*i) (m_context, a1, a2);
-    }
-}
-template<typename T1, typename T2, 
-         typename T3, typename T4>
-void 
-CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1, T2 a2, T3 a3) 
-{
-  for (typename CallbackList::iterator i = m_callbackList.begin ();
-       i != m_callbackList.end (); i++)
-    {
-      (*i) (m_context, a1, a2, a3);
-    }
-}
-template<typename T1, typename T2, 
-         typename T3, typename T4>
-void 
-CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1, T2 a2, T3 a3, T4 a4) 
-{
-  for (typename CallbackList::iterator i = m_callbackList.begin ();
-       i != m_callbackList.end (); i++)
-    {
-      (*i) (m_context, a1, a2, a3, a4);
-    }
-}
-
-}//namespace ns3
-
-#endif /* CALLBACK_TRACE_H */
--- a/src/common/composite-trace-resolver.cc	Tue Sep 11 10:35:56 2007 +0200
+++ /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) 2007 INRIA
- * All rights reserved.
- *
- * 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 "composite-trace-resolver.h"
-
-namespace ns3 {
-
-CompositeTraceResolver::CompositeTraceResolver (TraceContext const &context)
-  : TraceResolver (context)
-{}
-
-CompositeTraceResolver::~CompositeTraceResolver ()
-{}
-
-void 
-CompositeTraceResolver::Add (std::string name, 
-                             Callback<TraceResolver *,TraceContext const &> createResolver)
-{
-  TraceContext traceContext = GetContext ();
-  DoAdd (name, createResolver, traceContext);
-}
-
-void 
-CompositeTraceResolver::DoAdd (std::string name, 
-			       Callback<TraceResolver *,TraceContext const &> createResolver,
-			       TraceContext const &context)
-{
-  struct CallbackTraceSourceItem item;
-  item.name = name;
-  item.createResolver = createResolver;
-  item.context = context;
-  m_items.push_back (item);
-}
-
-TraceResolver::TraceResolverList 
-CompositeTraceResolver::DoLookup (std::string id) const
-{
-  if (id == "*")
-    {
-      TraceResolver::TraceResolverList list;
-      for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
-	{
-	  list.push_back (i->createResolver (i->context));
-	}
-      return list;
-    }
-  std::string::size_type start, end;
-  start = id.find_first_of ("(", 0);
-  end = id.find_first_of (")", 0);
-  if (start != 0 || end != (id.size ()-1))
-    {
-      for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
-	{
-	  if (i->name == id)
-	    {
-	      TraceResolver::TraceResolverList list;
-	      list.push_back (i->createResolver (i->context));
-	      return list;
-	    }
-	}
-    }
-  std::list<std::string> names;
-  std::string alternatives = std::string (id, start+1, end-1);
-  std::string::size_type next, cur;
-  next = 0;
-  cur = 0;
-  while (true)
-    {
-      std::string element;
-      next = alternatives.find ("|", cur);
-      if (next == std::string::npos)
-	{
-	  element = std::string (alternatives, cur, alternatives.size ());
-	  names.push_back (element);
-	  break;
-	}
-      element = std::string (alternatives, cur, next);
-      names.push_back (element);
-      cur = next + 1;
-    }
-  TraceResolver::TraceResolverList list;
-  for (std::list<std::string>::const_iterator i = names.begin (); i != names.end (); i++)
-    {
-      for (TraceItems::const_iterator j = m_items.begin (); j != m_items.end (); j++)
-	{
-	  if (j->name == *i)
-	    {
-	      list.push_back (j->createResolver (j->context));
-	      break;
-	    }
-	}
-    }
-  return list;
-}
-
-}//namespace ns3
-
-#ifdef RUN_SELF_TESTS
-
-#include "ns3/test.h"
-#include "trace-context-element.h"
-
-namespace ns3 {
-
-class TraceSourceTest : public TraceContextElement
-{
-public:
-  enum Sources {
-    DOUBLEA,
-    DOUBLEB,
-    SUBRESOLVER,
-  };
-  static uint16_t GetUid (void) 
-  {static uint16_t uid = AllocateUid<TraceSourceTest> ("TraceSourceTest"); return uid;}
-  void Print (std::ostream &os)
-  {os << "tracesource=";
-    if (m_sources == DOUBLEA) {os << "doubleA";}
-    else if (m_sources == DOUBLEB) {os << "doubleB";}
-    else if (m_sources == SUBRESOLVER) {os << "subresolver";}
-  }
-  TraceSourceTest () : m_sources (TraceSourceTest::DOUBLEA) {}
-  TraceSourceTest (enum Sources sources) :m_sources (sources) {}
-  bool IsDoubleA (void) {return m_sources == TraceSourceTest::DOUBLEA;}
-  bool IsDoubleB (void) {return m_sources == TraceSourceTest::DOUBLEB;}
-private:
-  enum TraceSourceTest::Sources m_sources;
-};
-
-class SubTraceSourceTest : public TraceContextElement
-{
-public:
-  enum Sources {
-    INT,
-  };
-  static uint16_t GetUid (void) 
-  {static uint16_t uid = AllocateUid<SubTraceSourceTest> ("SubTraceSourceTest"); return uid;}
-  void Print (std::ostream &os)
-  {os << "subtracesource=int";}
-  SubTraceSourceTest () : m_sources (SubTraceSourceTest::INT) {}
-  SubTraceSourceTest (enum Sources sources) : m_sources (sources) {}
-private:
-  enum Sources m_sources;
-};
-
-class CompositeTraceResolverTest : public Test
-{
-public:
-  CompositeTraceResolverTest ();
-  virtual ~CompositeTraceResolverTest ();
-  virtual bool RunTests (void);
-private:
-  void TraceDouble (TraceContext const &context, double v);
-  void TraceInt (TraceContext const &context, int v);
-  TraceResolver *CreateSubResolver (TraceContext const &context);
-
-
-  bool m_gotDoubleA;
-  bool m_gotDoubleB;
-  CallbackTraceSource<int> m_traceInt;
-  bool m_gotInt;
-};
-
-CompositeTraceResolverTest::CompositeTraceResolverTest ()
-  : Test ("CompositeTraceResolver")
-{}
-CompositeTraceResolverTest::~CompositeTraceResolverTest ()
-{}
-void 
-CompositeTraceResolverTest::TraceDouble (TraceContext const &context, double v)
-{
-  TraceSourceTest source;
-  context.Get (source);
-  if (source.IsDoubleA ())
-    {
-      m_gotDoubleA = true;
-    }
-  else if (source.IsDoubleB ())
-    {
-      m_gotDoubleB = true;
-    }
-  else
-    {
-      NS_FATAL_ERROR ("should not get any other trace source in this sink");
-    }
-  
-}
-
-void 
-CompositeTraceResolverTest::TraceInt (TraceContext const &context, int v)
-{
-  m_gotInt = true;
-}
-
-TraceResolver *
-CompositeTraceResolverTest::CreateSubResolver (TraceContext const &context)
-{
-  CompositeTraceResolver *subresolver = new CompositeTraceResolver (context);
-  subresolver->Add ("trace-int", m_traceInt, 
-                    SubTraceSourceTest (SubTraceSourceTest::INT));
-  return subresolver;
-}
-bool 
-CompositeTraceResolverTest::RunTests (void)
-{
-  bool ok = true;
-
-  CallbackTraceSource<double> traceDoubleA;
-  CallbackTraceSource<double> traceDoubleB;
-  TraceContext context;
-
-  CompositeTraceResolver resolver (context) ;
-
-  resolver.Add ("trace-double-a", traceDoubleA, 
-                TraceSourceTest (TraceSourceTest::DOUBLEA));
-  resolver.Add ("trace-double-b", traceDoubleB, 
-                TraceSourceTest (TraceSourceTest::DOUBLEB));
-
-  resolver.Connect ("/*", MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-
-  m_gotDoubleA = false;
-  m_gotDoubleB = false;
-  traceDoubleA (0);
-  if (!m_gotDoubleA || m_gotDoubleB)
-    {
-      ok = false;
-    }
-  m_gotDoubleA = false;
-  traceDoubleA (0);
-  traceDoubleB (0);
-  if (!m_gotDoubleA || !m_gotDoubleB)
-    {
-      ok = false;
-    }
-  m_gotDoubleA = false;
-  m_gotDoubleB = false;
-
-  resolver.Disconnect ("/*", MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-
-  m_gotDoubleA = false;
-  m_gotDoubleB = false;
-  traceDoubleA (0);
-  traceDoubleB (0);
-  if (m_gotDoubleA || m_gotDoubleB)
-    {
-      ok = false;
-    }
-
-  resolver.Connect ("/trace-double-a", 
-		    MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-  m_gotDoubleA = false;
-  m_gotDoubleB = false;
-  traceDoubleA (0);
-  traceDoubleB (0);
-  if (!m_gotDoubleA || m_gotDoubleB)
-    {
-      ok = false;
-    }
-  resolver.Disconnect ("/trace-double-a", 
-		       MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-
-  resolver.Connect ("/(trace-double-a)", 
-		    MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-  m_gotDoubleA = false;
-  m_gotDoubleB = false;
-  traceDoubleA (0);
-  traceDoubleB (0);
-  if (!m_gotDoubleA || m_gotDoubleB)
-    {
-      ok = false;
-    }
-  resolver.Disconnect ("/trace-double-a", 
-		       MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-
-  resolver.Connect ("/(trace-double-a|trace-double-b)", 
-		    MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-  m_gotDoubleA = false;
-  m_gotDoubleB = false;
-  traceDoubleA (0);
-  traceDoubleB (0);
-  if (!m_gotDoubleA || !m_gotDoubleB)
-    {
-      ok = false;
-    }
-  resolver.Disconnect ("/trace-double-a", 
-		       MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-  m_gotDoubleA = false;
-  m_gotDoubleB = false;
-  traceDoubleA (0);
-  traceDoubleB (0);
-  if (m_gotDoubleA || !m_gotDoubleB)
-    {
-      ok = false;
-    }
-
-
-  resolver.Disconnect ("/(trace-double-a|trace-double-b)", 
-		       MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
-  m_gotDoubleA = false;
-  m_gotDoubleB = false;
-  traceDoubleA (0);
-  traceDoubleB (0);
-  if (m_gotDoubleA || m_gotDoubleB)
-    {
-      ok = false;
-    }
-
-  resolver.Add ("subresolver", 
-		MakeCallback (&CompositeTraceResolverTest::CreateSubResolver, this),
-		TraceSourceTest (TraceSourceTest::SUBRESOLVER));
-
-  resolver.Connect ("/subresolver/trace-int", 
-		    MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
-  m_gotInt = false;
-  m_traceInt (1);
-  if (!m_gotInt)
-    {
-      ok = false;
-    }
-
-  resolver.Disconnect ("/subresolver/trace-int", 
-		       MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
-  m_gotInt = false;
-  m_traceInt (1);
-  if (m_gotInt)
-    {
-      ok = false;
-    }
-
-  resolver.Connect ("/*/trace-int", 
-		    MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
-  m_gotInt = false;
-  m_traceInt (1);
-  if (!m_gotInt)
-    {
-      ok = false;
-    }
-
-  resolver.Disconnect ("/subresolver/trace-int", 
-		       MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
-  m_gotInt = false;
-  m_traceInt (1);
-  if (m_gotInt)
-    {
-      ok = false;
-    }
-
-
-  
-
-  return ok;
-}
-
-static CompositeTraceResolverTest g_compositeTraceResolverTest;
-
-}//namespace ns3
-
-
-#endif /* RUN_SELF_TESTS */
--- a/src/common/composite-trace-resolver.h	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * 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 COMPOSITE_TRACE_RESOLVER_H
-#define COMPOSITE_TRACE_RESOLVER_H
-
-#include "ns3/callback.h"
-#include "trace-resolver.h"
-#include "callback-trace-source.h"
-#include "uv-trace-source.h"
-#include "sv-trace-source.h"
-#include "fv-trace-source.h"
-#include "terminal-trace-resolver.h"
-
-namespace ns3 {
-
-/**
- * \brief a helper class to aggregate contained TraceResolver and other trace sources.
- * \ingroup lowleveltracing
- */
-class CompositeTraceResolver : public TraceResolver
-{
-public:
-  CompositeTraceResolver (TraceContext const &context);
-  virtual ~CompositeTraceResolver ();
-  /**
-   * \param name name of trace source
-   * \param trace a callback trace source
-   * \param context the context associated to this trace source
-   *
-   * Add a callback trace source in this resolver. This trace
-   * source will match the name specified during namespace 
-   * resolution. The TraceContext of this trace source will also
-   * be automatically extended to contain the input context.
-   */
-  template <typename T1, typename T2,
-            typename T3, typename T4,
-            typename T>
-  void Add (std::string name,
-            CallbackTraceSource<T1,T2,T3,T4> &trace, T const &context);
-  /**
-   * \param name name of trace source
-   * \param trace a signed variable trace source
-   * \param context the context associated to this trace source
-   *
-   * Add a signed variable trace source in this resolver. 
-   * This trace source will match the name specified during namespace 
-   * resolution. The TraceContext of this trace source will also
-   * be automatically extended to contain the input context.
-   */
-  template <typename T>
-  void Add (std::string name,
-            SVTraceSource<T> &trace, T const &context);
-  /**
-   * \param name name of trace source
-   * \param trace an unsigned variable trace source
-   * \param context the context associated to this trace source
-   *
-   * Add an unsigned variable trace source in this resolver. 
-   * This trace source will match the name specified during namespace 
-   * resolution. The TraceContext of this trace source will also
-   * be automatically extended to contain the input context.
-   */
-  template <typename T>
-  void Add (std::string name,
-            UVTraceSource<T> &trace, T const &context);
-  /**
-   * \param name name of trace source
-   * \param trace a floating-point variable trace source
-   * \param context the context associated to this trace source
-   *
-   * Add a floating-point variable trace source in this resolver. 
-   * This trace source will match the name specified during namespace 
-   * resolution. The TraceContext of this trace source will also
-   * be automatically extended to contain the input context.
-   */
-  template <typename T>
-  void Add (std::string name,
-            FVTraceSource<T> &trace, T const &context);
-
-  /**
-   * \param name name of child trace resolver
-   * \param createResolver a trace resolver constructor
-   * \param context the context associated to this entry
-   *
-   * Add a child trace resolver to this resolver. This child
-   * trace resolver will match the name specified during
-   * namespace resolution. When this happens, the constructor
-   * will be invoked to create the child trace resolver and
-   * the associated TraceContext will be automatically extended
-   * to contain the input context.
-   */
-  template <typename T>
-  void Add (std::string name, 
-            Callback<TraceResolver *,TraceContext const &> createResolver,
-            T const &context);
-
-  /**
-   * \param name name of child trace resolver
-   * \param createResolver a trace resolver constructor
-   *
-   * Add a child trace resolver to this resolver. This child
-   * trace resolver will match the name specified during
-   * namespace resolution. When this happens, the constructor
-   * will be invoked to create the child trace resolver.
-   */
-  void Add (std::string name, 
-            Callback<TraceResolver *,TraceContext const &> createResolver);
-private:
-  template <typename SOURCE, typename CONTEXT>
-  void DoAddTraceSource (std::string name,
-                         SOURCE &traceSource, CONTEXT const &context);
-  template <typename SOURCE>
-  static TraceResolver *CreateTerminalTraceResolver (SOURCE *trace, 
-                                                     TraceContext const &context);
-  void DoAdd (std::string name, 
-              Callback<TraceResolver *,TraceContext const &> createResolver,
-              TraceContext const &context);
-  virtual TraceResolverList DoLookup (std::string id) const;
-
-  struct CallbackTraceSourceItem
-  {
-    std::string name;
-    Callback<TraceResolver *,TraceContext const &> createResolver;
-    TraceContext context;
-  };
-
-  typedef std::list<struct CallbackTraceSourceItem> TraceItems;
-  TraceItems m_items;
-};
-
-}//namespace ns3
-
-namespace ns3 {
-
-template <typename SOURCE, typename CONTEXT>
-void 
-CompositeTraceResolver::DoAddTraceSource (std::string name,
-                                          SOURCE &traceSource, CONTEXT const &context)
-{
-  TraceContext traceContext = GetContext ();
-  traceContext.Add (context);
-  TraceResolver *(*create) (SOURCE *trace, TraceContext const &context);
-  create = &CompositeTraceResolver::CreateTerminalTraceResolver<SOURCE>;
-  Callback<TraceResolver *,TraceContext const &> createResolver = 
-    MakeBoundCallback (create, &traceSource);
-  DoAdd (name, createResolver, traceContext);
-}
-
-template <typename SOURCE>
-TraceResolver *
-CompositeTraceResolver::CreateTerminalTraceResolver (SOURCE *traceSource, 
-                                                     TraceContext const &context)
-{
-  return new TerminalTraceResolver<SOURCE> (*traceSource, context);
-}
-
-
-
-
-template <typename T1, typename T2,
-          typename T3, typename T4,
-          typename T>
-void 
-CompositeTraceResolver::Add (std::string name,
-                             CallbackTraceSource<T1,T2,T3,T4> &trace, 
-                             T const &context)
-{
-  DoAddTraceSource (name, trace, context);
-}
-template <typename T>
-void 
-CompositeTraceResolver::Add (std::string name,
-                             SVTraceSource<T> &trace, T const &context)
-{
-  DoAddTraceSource (name, trace, context);
-}
-template <typename T>
-void 
-CompositeTraceResolver::Add (std::string name,
-                             UVTraceSource<T> &trace, T const &context)
-{
-  DoAddTraceSource (name, trace, context);
-}
-template <typename T>
-void 
-CompositeTraceResolver::Add (std::string name,
-                             FVTraceSource<T> &trace, T const &context)
-{
-  DoAddTraceSource (name, trace, context);
-}
-template <typename T>
-void 
-CompositeTraceResolver::Add (std::string name, 
-                             Callback<TraceResolver *,TraceContext const &> createResolver,
-                             T const &context)
-{
-  TraceContext traceContext = GetContext ();
-  traceContext.Add (context);
-  DoAdd (name, createResolver, traceContext);
-}
-
-}//namespace ns3
-
-#endif /* COMPOSITE_TRACE_RESOLVER_H */
--- a/src/common/empty-trace-resolver.cc	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * 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 "empty-trace-resolver.h"
-
-ns3::EmptyTraceResolver::EmptyTraceResolver (TraceContext const &context)
-  : TraceResolver (context)
-{}
--- a/src/common/empty-trace-resolver.h	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * 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 EMPTY_TRACE_RESOLVER_H
-#define EMPTY_TRACE_RESOLVER_H
-
-#include "trace-resolver.h"
-
-namespace ns3 {
-
-class TraceContext;
-
-/**
- * \brief a TraceResolver instance which does not resolve anything.
- * \ingroup tracing
- *
- * Trying to resolve against this class will yield no matches and no
- * connections. Returning an instance of this class from a 
- * CreateTraceResolver method is a hand way of not implementing
- * any Tracing code.
- */
-class EmptyTraceResolver : public TraceResolver
-{
-public:
-  /**
-   * \param o necessary context for this class.
-   *
-   * The only constructor exported by this class.
-   */
-  EmptyTraceResolver (TraceContext const &o);
-};
-
-}//namespace ns3
-
-#endif /* EMPTY_TRACE_RESOLVER_H */
--- a/src/common/fv-trace-source.h	Tue Sep 11 10:35:56 2007 +0200
+++ /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) 2006 INRIA
- * All rights reserved.
- *
- * 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 F_VARIABLE_TRACER_H
-#define F_VARIABLE_TRACER_H
-
-#include "callback-trace-source.h"
-#include <stdint.h>
-
-namespace ns3 {
-
-class FVTraceSourceBase {
-public:
-  typedef CallbackTraceSource<double, double> ChangeNotifyCallback;
-
-  FVTraceSourceBase () {}
-  FVTraceSourceBase (FVTraceSourceBase const &o) {}
-  FVTraceSourceBase &operator = (FVTraceSourceBase const &o) {
-      return *this;
-  }
-
-  ~FVTraceSourceBase () {}
-
-  void AddCallback (CallbackBase const & callback, TraceContext const & context) {
-    m_callback.AddCallback (callback, context);
-  }
-  void RemoveCallback (CallbackBase const & callback) {
-    m_callback.RemoveCallback (callback);
-  }
-protected:
-  void notify (double oldVal, double newVal) {
-      if (oldVal != newVal) 
-        {
-          m_callback (oldVal, newVal);
-        }
-  }
-private:
-  ChangeNotifyCallback m_callback;
-};
-
-template <typename T>
-class FVTraceSource : public FVTraceSourceBase 
-{
-public:
-};
-
-}; // namespace ns3
-
-#endif /* F_VARIABLE_TRACER_H */
--- a/src/common/packet.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/common/packet.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -199,6 +199,12 @@
   buffer.RemoveAtStart (metadataDeserialized);
 }
 
+std::ostream& operator<< (std::ostream& os, const Packet &packet)
+{
+  packet.Print (os);
+  return os;
+}
+
 
 } // namespace ns3
 
--- a/src/common/packet.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/common/packet.h	Tue Sep 11 12:11:00 2007 +0200
@@ -328,6 +328,8 @@
   static uint32_t m_globalUid;
 };
 
+std::ostream& operator<< (std::ostream& os, const Packet &packet);
+
 /**
  * \defgroup packetperf Packet Performance
  * The current implementation of the byte buffers and tag list is based
--- a/src/common/stream-tracer-test.cc	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * All rights reserved.
- *
- * 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 "stream-tracer.h"
-#include "ns3/test.h"
-#include <iostream>
-
-#ifdef RUN_SELF_TESTS
-
-namespace {
-
-class TestStreamTracer : public ns3::Test {
-public:
-  TestStreamTracer ();
-  virtual bool RunTests (void);
-};
-
-static TestStreamTracer gTestStream;
-
-TestStreamTracer::TestStreamTracer ()
-  : Test ("StreamTracer")
-{}
-
-bool
-TestStreamTracer::RunTests (void)
-{
-  bool ok = true;
-  ns3::StreamTracer trace;
-  //trace.setStream (&std::cout);
-  trace << 1;
-  trace << " X ";
-  trace << 1.0;
-  trace << std::endl;
-  trace << "test ";
-  trace << 1 << " test";
-  trace << "test "
-        << 1.0 << " "
-        << 0xdeadbead
-        << std::endl;
-  trace << "0x" << std::hex 
-        << 0xdeadbeaf 
-        << std::dec << " "
-        << 0xdeadbeaf
-        << std::endl;
-  return ok;
-}
-
-
-}; // namespace ns3
-
-#endif /* RUN_SELF_TESTS */
--- a/src/common/stream-tracer.h	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * All rights reserved.
- *
- * 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 STREAM_TRACER_H
-#define STREAM_TRACER_H
-
-#include <ostream>
-
-namespace ns3 {
-
-/**
- * \brief log arbitrary data to std::ostreams
- * 
- * Whenever operator << is invoked on this class,
- * it is forwarded to the stored std::ostream output
- * stream (if there is one).
- */
-class StreamTracer {
-public:
-  StreamTracer ()
-      : m_os (0) {}
-  template <typename T>
-  StreamTracer &operator << (T const&v) {
-      if (m_os != 0) 
-        {
-          (*m_os) << v;
-        }
-      return *this;
-  }
-  template <typename T>
-  StreamTracer &operator << (T &v) {
-      if (m_os != 0) 
-        {
-          (*m_os) << v;
-        }
-      return *this;
-  }
-  StreamTracer &operator << (std::ostream &(*v) (std::ostream &)) {
-      if (m_os != 0) 
-        {
-          (*m_os) << v;
-        }
-      return *this;
-  }
-
-  /**
-   * \param os the output stream to store
-   */
-  void SetStream (std::ostream * os) {
-      m_os = os;
-  }
-private:
-  std::ostream *m_os;
-};
-
-}; // namespace ns3
-
-
-#endif /* TRACER_STREAM_H */
--- a/src/common/sv-trace-source.h	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,242 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * All rights reserved.
- *
- * 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 SV_TRACE_SOURCE_H
-#define SV_TRACE_SOURCE_H
-
-#include "callback-trace-source.h"
-#include <stdint.h>
-
-namespace ns3 {
-
-class SVTraceSourceBase {
-public:
-  typedef CallbackTraceSource<int64_t, int64_t> ChangeNotifyCallback;
-
-  SVTraceSourceBase () {}
-  SVTraceSourceBase (SVTraceSourceBase const &o) {}
-  SVTraceSourceBase &operator = (SVTraceSourceBase const &o) {
-      return *this;
-  }
-
-  ~SVTraceSourceBase () {}
-
-  void AddCallback (CallbackBase const & callback, TraceContext const & context) {
-    m_callback.AddCallback (callback, context);
-  }
-  void RemoveCallback (CallbackBase const & callback) {
-    m_callback.RemoveCallback (callback);
-  }
-protected:
-  void Notify (int64_t oldVal, int64_t newVal) {
-      if (oldVal != newVal) 
-        {
-          m_callback (oldVal, newVal);
-        }
-  }
-private:
-  ChangeNotifyCallback m_callback;
-};
-
-template <typename T>
-class UVTraceSource;
-
-
-/**
- * \brief trace variables of type "signed integer"
- * \ingroup lowleveltracing
- *
- * This template class implements a POD type: it
- * behaves like any other variable of type "signed integer"
- * except that it also reports any changes to its
- * value with its internal callback.
- *
- * To instantiate a 32-bit signed variable (to store
- * a TCP counter for example), you would create a variable of type
- * ns3::UVTraceSource<int32_t> :
- \code
- #include <stdint.h>
- #include "ns3/sv-trace-source.h"
-
- ns3::SVTraceSource<uint16_t> var;
- \endcode
- * and you would use it like any other variable of type int32_t:
- \code
- var += 12;
- var = 10;
- var = -10;
- \endcode
- */
-template <typename T>
-class SVTraceSource : public SVTraceSourceBase {
-public:
-  SVTraceSource ()
-      : m_var (0)
-  {}
-  SVTraceSource (T const &var) 
-      : m_var (var)
-  {}
-
-  SVTraceSource &operator = (SVTraceSource const &o) {
-      Assign (o.Get ());
-      return *this;
-  }
-  template <typename TT>
-  SVTraceSource &operator = (SVTraceSource<TT> const &o) {
-      Assign (o.Get ());
-      return *this;
-  }
-  template <typename TT>
-  SVTraceSource &operator = (UVTraceSource<TT> const &o) {
-      Assign (o.Get ());
-      return *this;
-  }
-  SVTraceSource &operator++ () {
-      Assign (Get () + 1);
-      return *this;
-  }
-  SVTraceSource &operator-- () {
-      Assign (Get () - 1);
-      return *this;
-  }
-  SVTraceSource operator++ (int) {
-      SVTraceSource old (*this);
-      ++*this;
-      return old;
-  }
-  SVTraceSource operator-- (int) {
-      SVTraceSource old (*this);
-      --*this;
-      return old;
-  }
-  operator T () const {
-      return Get ();
-  }
-
-
-  void Assign (T var) {
-      Notify (m_var, var);
-      m_var = var;
-  }
-  T Get (void) const {
-      return m_var;
-  }
-
-private:
-  T m_var;
-};
-
-template <typename T>
-SVTraceSource<T> &operator += (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () + rhs.Get ());
-  return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator -= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () - rhs.Get ());
-  return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator *= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () * rhs.Get ());
-  return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator /= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () / rhs.Get ());
-  return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator <<= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () << rhs.Get ());
-  return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator >>= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () >> rhs.Get ());
-  return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator &= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () & rhs.Get ());
-  return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator |= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () | rhs.Get ());
-  return lhs;
-}
-template <typename T>
-SVTraceSource<T> &operator ^= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () ^ rhs.Get ());
-  return lhs;
-}
-
-
-template <typename T, typename U>
-SVTraceSource<T> &operator += (SVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () + rhs);
-  return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator -= (SVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () - rhs);
-  return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator *= (SVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () * rhs);
-  return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator /= (SVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () / rhs);
-  return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator <<= (SVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () << rhs);
-  return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator >>= (SVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () >> rhs);
-  return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator &= (SVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () & rhs);
-  return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator |= (SVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () | rhs);
-  return lhs;
-}
-template <typename T, typename U>
-SVTraceSource<T> &operator ^= (SVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () ^ rhs);
-  return lhs;
-}
-
-}; // namespace ns3
-
-#endif /* SV_TRACE_SOURCE_H */
--- a/src/common/terminal-trace-resolver.h	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * 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 TERMINAL_TRACE_RESOLVER_H
-#define TERMINAL_TRACE_RESOLVER_H
-
-#include "trace-resolver.h"
-
-namespace ns3 {
-
-class TraceContext;
-
-template <typename T>
-class TerminalTraceResolver : public TraceResolver
-{
- public:
-  TerminalTraceResolver (T &traceSource, TraceContext const &context);
- private:
-  virtual void DoConnect (CallbackBase const &cb);
-  virtual void DoDisconnect (CallbackBase const &cb);
-  T &m_traceSource;
-};
-
-}//namespace ns3
-
-namespace ns3 {
-
-template <typename T>
-TerminalTraceResolver<T>::TerminalTraceResolver (T &traceSource, 
-						 TraceContext const &context)
-  : TraceResolver (context),
-    m_traceSource (traceSource)
-{}
-template <typename T>
-void 
-TerminalTraceResolver<T>::DoConnect (CallbackBase const &cb)
-{
-  m_traceSource.AddCallback (cb, GetContext ());
-}
-template <typename T>
-void 
-TerminalTraceResolver<T>::DoDisconnect (CallbackBase const &cb)
-{
-  m_traceSource.RemoveCallback (cb);
-}
-
-}//namespace ns3
-
-#endif /* TERMINAL_TRACE_RESOLVER_H */
--- a/src/common/trace-context-element.cc	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-#include "trace-context-element.h"
-
-namespace ns3 {
-
-uint32_t 
-ElementRegistry::GetSize (uint16_t uid)
-{
-  InfoVector *vec = GetInfoVector ();
-  struct Info info = (*vec)[uid - 1];
-  return info.size;
-}
-void 
-ElementRegistry::Print (uint16_t uid, uint8_t *instance, std::ostream &os)
-{
-  InfoVector *vec = GetInfoVector ();
-  struct Info info = (*vec)[uid - 1];
-  info.print (instance, os);
-}
-void 
-ElementRegistry::Destroy (uint16_t uid, uint8_t *instance)
-{
-  InfoVector *vec = GetInfoVector ();
-  struct Info info = (*vec)[uid - 1];
-  info.destroy (instance);
-}
-ElementRegistry::InfoVector *
-ElementRegistry::GetInfoVector (void)
-{
-  static InfoVector vector;
-  return &vector;
-}
-
-
-} // namespace ns3
--- a/src/common/trace-context-element.h	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-#ifndef TRACE_CONTEXT_ELEMENT_H
-#define TRACE_CONTEXT_ELEMENT_H
-
-#include <string>
-#include <vector>
-
-#define NS_TRACE_CONTEXT_ELEMENT_ENSURE_REGISTERED(x)          \
-namespace {						       \
-static class thisisaveryverylongclassname ##x		       \
-  {							       \
-  public:						       \
-    thisisaveryverylongclassname ##x ()			       \
-      { uint32_t uid; uid = x::GetUid ();}		       \
-  } g_thisisanotherveryveryverylongname ##x ;		       \
-}
-
-namespace ns3 {
-
-/**
- * \brief an item stored in a TraceContext
- *
- * To store trace context information in a TraceContext instance,
- * users must subclass this base class and store subclass instances
- * in a TraceContext with TraceContext::Add.
- *
- * Each subclass should define and implement:
- *   - a public default constructor: it is used by the internals
- *     of the implementation of TraceContext.
- *   - a public destructor: it is also used by the internals of
- *     the implementation of TraceContext.
- *   - a public static method named GetUid which returns a 16 bit 
- *     integer. The integer returned from this method should be
- *     allocated with the protected AllocatedUid method.
- *   - a public Print method: this method is used by the 
- *     TraceContext::Print method to print the content of each
- *     of the trace context element stored in the trace context.
- *     This method takes a c++ output stream and argument and is
- *     expected to write an ascii string describing its content
- *     in this output stream.
- *
- * A typical subclass should look like this:
- * \code
- * class MyContext : public TraceContextElement
- * {
- * public:
- *   // the _required_ public API
- *   static uint16_t GetUid (void);
- *   MyContext ();
- *   ~MyContext ();
- *   void Print (std::ostream &os) const;
- *
- *   // the user-specific API to manipulate the context.
- *   void SetData (uint8_t data);
- *   uint8_t GetData (void) const;
- * private:
- *   uint8_t m_myContextData;
- * };
- *
- * uint16_t 
- * MyContext::GetUid (void)
- * {
- *   static uint16_t uid = AllocateUid<MyContext> ("MyContext");
- *   return uid;
- * }
- * MyContext::MyContext ()
- * {}
- * MyContext::~MyContext ()
- * {}
- * void 
- * MyContext::Print (std::ostream &os) const
- * {
- *   os << "mycontext=" << (uint32_t) m_myContextData;
- * }
- * void 
- * MyContext::SetData (uint8_t data)
- * {
- *   m_myContextData = data;
- * }
- * uint8_t 
- * MyContext::GetData (void) const
- * {
- *   return m_myContextData;
- * }
- * \endcode
- */
-class TraceContextElement
-{
-protected:
-  /**
-   * \param name a string which uniquely identifies the type
-   *        of the subclass which is calling this method.
-   * \returns a unique 32 bit integer associated to the
-   *          input string.
-   *
-   * Subclasses are expected to call this method from their
-   * public static GetUid method.
-   */
-  template <typename T>
-  static uint16_t AllocateUid (std::string name);
-};
-
-} // namespace ns3
-
-namespace ns3 {
-
-/**
- * \brief a registry of TraceContextElement subclasses
- * \internal
- */
-class ElementRegistry
-{
-public:
-  template <typename T>
-  static uint16_t AllocateUid (std::string name);
-
-  static uint32_t GetSize (uint16_t uid);
-  static void Print (uint16_t uid, uint8_t *instance, std::ostream &os);
-  static void Destroy (uint16_t uid, uint8_t *instance);
-private:
-  typedef void (*PrintCb) (uint8_t *instance, std::ostream &os);
-  typedef void (*DestroyCb) (uint8_t *instance);
-  struct Info {
-    uint32_t size;
-    std::string uidString;
-    PrintCb print;
-    DestroyCb destroy;
-  };
-  typedef std::vector<struct Info> InfoVector;
-  static InfoVector *GetInfoVector (void);
-  template <typename T>
-  static void DoPrint (uint8_t *instance, std::ostream &os);
-  template <typename T>
-  static void DoDestroy (uint8_t *instance);  
-};
-
-template <typename T>
-void 
-ElementRegistry::DoPrint (uint8_t *instance, std::ostream &os)
-{
-  static T obj;
-  // make sure we are aligned.
-  memcpy ((void*)&obj, instance, sizeof (T));
-  obj.Print (os);
-}
-template <typename T>
-void 
-ElementRegistry::DoDestroy (uint8_t *instance)
-{
-  static T obj;
-  // make sure we are aligned.
-  memcpy ((void*)&obj, instance, sizeof (T));
-  obj.~T ();
-}
-
-template <typename T>
-uint16_t 
-ElementRegistry::AllocateUid (std::string name)
-{
-  InfoVector *vec = GetInfoVector ();
-  uint16_t uid = 1;
-  for (InfoVector::iterator i = vec->begin (); i != vec->end (); i++)
-    {
-      if (i->uidString == name)
-	{
-	  return uid;
-	}
-      uid++;
-    }
-  struct Info info;
-  info.size = sizeof (T);
-  info.uidString = name;
-  info.print = &ElementRegistry::DoPrint<T>;
-  info.destroy = &ElementRegistry::DoDestroy<T>;
-  vec->push_back (info);
-  return vec->size ();
-}
-
-
-
-template <typename T>
-uint16_t 
-TraceContextElement::AllocateUid (std::string name)
-{
-  return ElementRegistry::AllocateUid<T> (name);
-}
-
-} // namespace ns3
-
-#endif /* TRACE_CONTEXT_ELEMENT_H */
--- a/src/common/trace-context.cc	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,330 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * 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 "trace-context.h"
-#include "trace-context-element.h"
-#include "ns3/assert.h"
-
-namespace ns3 {
-
-TraceContext::TraceContext ()
-  : m_data (0)
-{}
-TraceContext::TraceContext (TraceContext const &o)
-  : m_data (o.m_data)
-{
-  if (m_data != 0)
-    {
-      m_data->count++;
-    }
-}
-TraceContext const & 
-TraceContext::operator = (TraceContext const &o)
-{
-  if (m_data != 0)
-    {
-      m_data->count--;
-      if (m_data->count == 0)
-        {
-          uint8_t *buffer = (uint8_t *)m_data;
-          delete [] buffer;
-        }
-    }
-  m_data = o.m_data;
-  if (m_data != 0)
-    {
-      m_data->count++;
-    }
-  return *this;
-}
-TraceContext::~TraceContext ()
-{
-  if (m_data != 0)
-    {
-      m_data->count--;
-      if (m_data->count == 0)
-        {
-          uint8_t *buffer = (uint8_t *)m_data;
-          delete [] buffer;
-        }
-    }
-}
-
-void 
-TraceContext::Add (TraceContext const &o)
-{
-  if (o.m_data == 0)
-    {
-      return;
-    }
-  uint16_t currentUid;
-  uint16_t i = 0;
-  while (i < o.m_data->size) 
-    {
-      currentUid = o.m_data->data[i];
-      uint8_t size = ElementRegistry::GetSize (currentUid);
-      uint8_t *selfBuffer = CheckPresent (currentUid);
-      uint8_t *otherBuffer = &(o.m_data->data[i+1]);
-      if (selfBuffer != 0)
-        {
-          if (memcmp (selfBuffer, otherBuffer, size) != 0)
-            {
-              NS_FATAL_ERROR ("You cannot add TraceContexts which "<<
-                              "have different values stored in them.");
-            }
-        }
-      else
-        {
-          DoAdd (currentUid, otherBuffer);
-        }
-      i += 1 + size;
-    }
-}
-
-uint8_t *
-TraceContext::CheckPresent (uint8_t uid) const
-{
-  if (m_data == 0)
-    {
-      return false;
-    }
-  uint8_t currentUid;
-  uint16_t i = 0;
-  do {
-    currentUid = m_data->data[i];
-    uint8_t size = ElementRegistry::GetSize (currentUid);
-    if (currentUid == uid)
-      {
-        return &m_data->data[i+1];
-      }
-    i += 1 + size;
-  } while (i < m_data->size && currentUid != 0);
-  return 0;
-}
-
-
-bool
-TraceContext::DoAdd (uint8_t uid, uint8_t const *buffer)
-{
-  NS_ASSERT (uid != 0);
-  uint8_t size = ElementRegistry::GetSize (uid);
-  uint8_t *present = CheckPresent (uid);
-  if (present != 0) {
-    if (memcmp (present, buffer, size) == 0)
-      {
-        return true;
-      }
-    else
-      {
-        return false;
-      }
-  }
-  if (m_data == 0)
-    {
-      uint16_t newSize = 1 + size;
-      uint16_t allocatedSize;
-      if (newSize > 4)
-        {
-          allocatedSize = sizeof (struct Data) + newSize - 4;
-        }
-      else
-        {
-          allocatedSize = sizeof (struct Data);
-        }
-      struct Data *data = (struct Data *) (new uint8_t [allocatedSize] ());
-      data->size = newSize;
-      data->count = 1;
-      data->data[0] = uid;
-      memcpy (data->data + 1, buffer, size);
-      m_data = data;
-    }
-  else
-    {
-      uint16_t newSize = m_data->size + 1 + size;
-      uint16_t allocatedSize;
-      if (newSize > 4)
-        {
-          allocatedSize = sizeof (struct Data) + newSize - 4;
-        }
-      else
-        {
-          allocatedSize = sizeof (struct Data);
-        }
-      struct Data *data = (struct Data *) (new uint8_t [allocatedSize] ());
-      data->size = newSize;
-      data->count = 1;
-      memcpy (data->data, m_data->data, m_data->size);
-      data->data[m_data->size] = uid;
-      memcpy (data->data + m_data->size + 1, buffer, size);
-      m_data->count--;
-      if (m_data->count == 0)
-        {
-          uint8_t *buffer = (uint8_t *)m_data;
-          delete [] buffer;
-        }
-      m_data = data;
-    }
-  return true;
-}
-bool
-TraceContext::DoGet (uint8_t uid, uint8_t *buffer) const
-{
-  if (m_data == 0)
-    {
-      return false;
-    }
-  uint8_t currentUid;
-  uint16_t i = 0;
-  do {
-    currentUid = m_data->data[i];
-    uint8_t size = ElementRegistry::GetSize (currentUid);
-    if (currentUid == uid)
-      {
-        memcpy (buffer, &m_data->data[i+1], size);
-        return true;
-      }
-    i += 1 + size;
-  } while (i < m_data->size && currentUid != 0);
-  return false;
-}
-
-void 
-TraceContext::Print (std::ostream &os) const
-{
-  if (m_data == 0)
-    {
-      return;
-    }
-  uint8_t currentUid;
-  uint16_t i = 0;
-  do {
-    currentUid = m_data->data[i];
-    uint8_t size = ElementRegistry::GetSize (currentUid);
-    uint8_t *instance = &m_data->data[i+1];
-    ElementRegistry::Print (currentUid, instance, os);
-    i += 1 + size;
-    if (i < m_data->size && currentUid != 0)
-      {
-        os << " ";
-      }
-    else
-      {
-        break;
-      }
-  } while (true);
-}
-
-}//namespace ns3
-
-#include "ns3/test.h"
-#include <sstream>
-
-namespace ns3 {
-
-template <int N>
-class Ctx : public TraceContextElement
-{
-public:
-  static uint16_t GetUid (void) {static uint16_t uid = AllocateUid<Ctx<N> > (GetName ()); return uid;}
-  static std::string GetName (void) {std::ostringstream oss; oss << "Ctx" << N; return oss.str ();}
-  Ctx () : m_v (0) {}
-  Ctx (int v) : m_v (v) {}
-  void Print (std::ostream &os) {os << N;}
-  int Get (void) const { return N;}
-private:
-  int m_v;
-};
-
-class TraceContextTest : public Test
-{
-public:
-  TraceContextTest ();
-  virtual bool RunTests (void);
-};
-
-TraceContextTest::TraceContextTest ()
-  : Test ("TraceContext")
-{}
-bool 
-TraceContextTest::RunTests (void)
-{
-  bool ok = true;
-
-  TraceContext ctx;
-  Ctx<0> v0;
-  Ctx<0> v01 = Ctx<0> (1);
-  Ctx<1> v1;
-  Ctx<2> v2;
-  Ctx<3> v3;
-
-  if (ctx.SafeGet (v0))
-    {
-      ok = false;
-    }
-  ctx.Add (v0);
-  ctx.Add (v0);
-  if (ctx.SafeAdd (v01))
-    {
-      ok = false;
-    }
-  ctx.Get (v0);
-  ctx.Add (v1);
-  ctx.Get (v1);
-  ctx.Get (v0);
-  ctx.Get (v1);
-
-  TraceContext copy = ctx;
-  ctx.Get (v0);
-  ctx.Get (v1);
-  copy.Get (v0);
-  copy.Get (v1);
-  copy.Add (v2);
-  copy.Get (v0);
-  copy.Get (v1);
-  copy.Get (v2);
-  ctx.Add (v3);
-  ctx.Get (v0);
-  ctx.Get (v1);
-  ctx.Get (v3);
-
-  if (ctx.SafeGet (v2))
-    {
-      ok = false;
-    }
-  if (copy.SafeGet (v3))
-    {
-      ok = false;
-    }
-  ctx.Add (copy);
-  ctx.Get (v2);
-  if (copy.SafeGet (v3))
-    {
-      ok = false;
-    }
-  copy.Add (ctx);
-  copy.Get (v3);  
-  
-  return ok;
-}
-
-static TraceContextTest g_traceContextTest;
-
-
-}//namespace ns3
--- a/src/common/trace-context.h	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * 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 TRACE_CONTEXT_H
-#define TRACE_CONTEXT_H
-
-#include <stdint.h>
-#include <vector>
-#include "ns3/fatal-error.h"
-#include "trace-context-element.h"
-
-namespace ns3 {
-
-/**
- * \brief Provide context to trace sources
- * \ingroup lowleveltracing
- *
- * Instances of this class are used to hold context
- * for each trace source. Each instance holds a list of
- * 'contexts'. Trace sinks can lookup these contexts
- * from this list with the ns3::TraceContext::Get method.
- *
- * This class is implemented
- * using Copy On Write which means that copying unmodified
- * versions of this class is very cheap. However, modifying
- * the content of this class through a call 
- * to ns3::TraceContext::Add will trigger a costly memory
- * reallocation if needed.
- */
-class TraceContext
-{
-public:
-  TraceContext ();
-  TraceContext (TraceContext const &o);
-  TraceContext const & operator = (TraceContext const &o);
-  ~TraceContext ();
-
-  /**
-   * \param context add context to list of trace contexts.
-   */
-  template <typename T>
-  void Add (T const &context);
-
-  /**
-   * \param o the other context
-   *
-   * Perform the Union operation (in the sense of set theory) on the
-   * two input lists of elements. This method is used in the
-   * ns3::CallbackTraceSourceSource class when multiple sinks are connected
-   * to a single source to ensure that the source does not need
-   * to store a single TraceContext instance per connected sink.
-   * Instead, all sinks share the same TraceContext.
-   */
-  void Add (TraceContext const &o);
-
-  /**
-   * \param context context to get from this list of trace contexts.
-   *
-   * This method cannot fail. If the requested trace context is not
-   * stored in this TraceContext, then, the program will halt.
-   */
-  template <typename T>
-  void Get (T &context) const;
-
-  void Print (std::ostream &os) const;
-private:
-  friend class TraceContextTest;
-  // used exclusively for testing code.
-  template <typename T>
-  bool SafeGet (T &context) const;
-  template <typename T>
-  bool SafeAdd (const T &context);
-
-  uint8_t *CheckPresent (uint8_t uid) const;
-  bool DoAdd (uint8_t uid, uint8_t const *buffer);
-  bool DoGet (uint8_t uid, uint8_t *buffer) const;
-
-  struct Data {
-    uint16_t count;
-    uint16_t size;
-    uint8_t data[4];
-  } * m_data;
-};
-
-}//namespace ns3
-
-namespace ns3 {
-
-template <typename T>
-void 
-TraceContext::Add (T const &context)
-{
-  const TraceContextElement *parent;
-  // if the following assignment fails, it is because the input
-  // to this function is not a subclass of the TraceContextElement class.
-  parent = &context;
-  uint8_t *data = (uint8_t *) &context;
-  bool ok = DoAdd (T::GetUid (), data);
-  if (!ok)
-    {
-      NS_FATAL_ERROR ("Trying to add twice the same type with different values is invalid.");
-    }
-}
-template <typename T>
-void
-TraceContext::Get (T &context) const
-{
-  TraceContextElement *parent;
-  // if the following assignment fails, it is because the input
-  // to this function is not a subclass of the TraceContextElement class.
-  parent = &context;
-  uint8_t *data = (uint8_t *) &context;
-  bool found = DoGet (T::GetUid (), data);
-  if (!found)
-    {
-      NS_FATAL_ERROR ("Type not stored in TraceContext");
-    }
-}
-template <typename T>
-bool
-TraceContext::SafeGet (T &context) const
-{
-  TraceContextElement *parent;
-  // if the following assignment fails, it is because the input
-  // to this function is not a subclass of the TraceContextElement class.
-  parent = &context;
-  uint8_t *data = (uint8_t *) &context;
-  bool found = DoGet (T::GetUid (), data);
-  return found;
-}
-template <typename T>
-bool
-TraceContext::SafeAdd (const T &context)
-{
-  const TraceContextElement *parent;
-  // if the following assignment fails, it is because the input
-  // to this function is not a subclass of the TraceContextElement class.
-  parent = &context;
-  uint8_t *data = (uint8_t *) &context;
-  bool ok = DoAdd (T::GetUid (), data);
-  return ok;
-}
-}//namespace ns3
-
-#endif /* TRACE_CONTEXT_H */
--- a/src/common/trace-resolver.cc	Tue Sep 11 10:35:56 2007 +0200
+++ /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) 2007 INRIA
- * All rights reserved.
- *
- * 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 "trace-resolver.h"
-
-namespace ns3 {
-
-TraceResolver::TraceResolver (TraceContext const &context)
-  : m_context (context)
-{}
-
-TraceResolver::~TraceResolver ()
-{}
-
-TraceContext const &
-TraceResolver::GetContext (void) const
-{
-  return m_context;
-}
-
-void 
-TraceResolver::Connect (std::string path, CallbackBase const &cb)
-{
-  std::string::size_type cur = 1;
-  // check that first char is "/"
-  std::string::size_type next = path.find ("/", cur);
-  std::string element = std::string (path, cur, next-1);
-  TraceResolverList resolverList = DoLookup (element);
-  for (TraceResolverList::iterator i = resolverList.begin (); i != resolverList.end (); i++)
-    {
-      TraceResolver *resolver = *i;
-      if (next == std::string::npos) 
-	{
-	  // we really break the recursion here.
-	  resolver->DoConnect (cb);
-	}
-      else
-	{
-	  std::string subpath = std::string (path, next, std::string::npos);
-          resolver->Connect (subpath, cb);
-	}
-      delete resolver;
-    }
-  resolverList.erase (resolverList.begin (), resolverList.end ());
-}
-
-void 
-TraceResolver::Disconnect (std::string path, CallbackBase const &cb)
-{
-  std::string::size_type cur = 1;
-  // check that first char is "/"
-  std::string::size_type next = path.find ("/", cur);
-  std::string element = std::string (path, cur, next-1);
-  TraceResolverList resolverList = DoLookup (element);
-  for (TraceResolverList::iterator i = resolverList.begin (); i != resolverList.end (); i++)
-    {
-      TraceResolver *resolver = *i;
-      if (next == std::string::npos) 
-	{
-	  // we really break the recursion here.
-	  resolver->DoDisconnect (cb);
-	}
-      else
-	{
-	  std::string subpath = std::string (path, next, std::string::npos);
-          resolver->Disconnect (subpath, cb);
-	}
-      delete resolver;
-    }
-  resolverList.erase (resolverList.begin (), resolverList.end ());
-}
-
-TraceResolver::TraceResolverList 
-TraceResolver::DoLookup (std::string id) const
-{
-  return TraceResolverList ();
-}
-void 
-TraceResolver::DoConnect (CallbackBase const &cb)
-{}
-
-void 
-TraceResolver::DoDisconnect (CallbackBase const &cb)
-{}
-
-
-}//namespace ns3
--- a/src/common/trace-resolver.h	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * 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 TRACE_RESOLVER_H
-#define TRACE_RESOLVER_H
-
-#include <string>
-#include <list>
-#include "trace-context.h"
-
-namespace ns3 {
-
-class CallbackBase;
-
-/**
- * \brief the base class which is used to incremental perform trace
- *        namespace resolution.
- * \ingroup lowleveltracing
- *
- * This class provides a public API to the ns3::TraceRoot object:
- *   - ns3::TraceResolver::Connect
- *   - ns3::TraceResolver::Disconnect
- *
- * It also provides an API for its subclasses. Each subclass should 
- * implement one of:
- *   - ns3::TraceResolver::DoLookup
- *   - ns3::TraceResolver::DoConnect and ns3::TraceResolver::DoDisconnect
- * Each subclass must also provide an ns3::TraceContext to the TraceResolver
- * constructor. Finally, each subclass can access the ns3::TraceContext 
- * associated to this  ns3::TraceResolver through the 
- * ns3::TraceResolver::GetContext method.
- */
-class TraceResolver
-{
-public:
-  virtual ~TraceResolver ();
-  /**
-   * \param path the namespace path to resolver
-   * \param cb the callback to connect to the matching namespace
-   *
-   * This method is typically invoked by ns3::TraceRoot but advanced
-   * users could also conceivably call it directly if they want to
-   * skip the ns3::TraceRoot.
-   */
-  void Connect (std::string path, CallbackBase const &cb);
-  /**
-   * \param path the namespace path to resolver
-   * \param cb the callback to disconnect in the matching namespace
-   *
-   * This method is typically invoked by ns3::TraceRoot but advanced
-   * users could also conceivably call it directly if they want to
-   * skip the ns3::TraceRoot.
-   */
-  void Disconnect (std::string path, CallbackBase const &cb);
-protected:
-  /**
-   * \param context the context used to initialize this TraceResolver.
-   *
-   * Every subclass must call this constructor
-   */
-  TraceResolver (TraceContext const &context);
-  /**
-   * \returns the ns3::TraceContext stored in this ns3::TraceResolver.
-   *
-   * Subclasses usually invoke this method to get access to the
-   * TraceContext stored here to pass it down to the TraceResolver
-   * constructors invoked from within the DoLookup method.
-   */
-  TraceContext const &GetContext (void) const;
-  typedef std::list<TraceResolver *> TraceResolverList;
-private:
-  TraceResolver ();
-  /**
-   * \param id the id to resolve. This is supposed to be
-   * one element of the global tracing namespace.
-   * \returns a list of reslvers which match the input namespace element
-   *
-   * A subclass which overrides this method should return a potentially
-   * empty list of pointers to ns3::TraceResolver instances which match
-   * the input namespace element. Each of these TraceResolver should be
-   * instanciated with a TraceContext which holds enough context
-   * information to identify the type of the TraceResolver.
-   */
-  virtual TraceResolverList DoLookup (std::string id) const;
-  /**
-   * \param cb callback to connect
-   *
-   * This method is invoked on leaf trace resolvers.
-   */
-  virtual void DoConnect (CallbackBase const &cb);
-  /**
-   * \param cb callback to disconnect
-   *
-   * This method is invoked on leaf trace resolvers.
-   */
-  virtual void DoDisconnect (CallbackBase const &cb);
-  TraceContext m_context;
-};
-
-}//namespace ns3
-
-#endif /* TRACE_RESOLVER_H */
--- a/src/common/trace-root.cc	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * 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 "trace-root.h"
-#include "ns3/composite-trace-resolver.h"
-#include "ns3/trace-context.h"
-
-namespace ns3 {
-
-void 
-TraceRoot::Connect (std::string path, CallbackBase const &cb)
-{
-  TraceResolver *resolver = GetComposite ();
-  resolver->Connect (path, cb);
-}
-void 
-TraceRoot::Disconnect (std::string path, CallbackBase const &cb)
-{
-  TraceResolver *resolver = GetComposite ();
-  resolver->Disconnect (path, cb);
-}
-void 
-TraceRoot::Register (std::string name, 
-                     Callback<TraceResolver *,TraceContext const &> createResolver)
-{
-  CompositeTraceResolver *resolver = GetComposite ();
-  resolver->Add (name, createResolver);
-}
-
-CompositeTraceResolver *
-TraceRoot::GetComposite (void)
-{
-  static CompositeTraceResolver resolver = CompositeTraceResolver (TraceContext ());
-  return &resolver;
-}
-
-} // namespace ns3
--- a/src/common/trace-root.h	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,335 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * 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 TRACE_ROOT_H
-#define TRACE_ROOT_H
-
-#include <string>
-#include "ns3/callback.h"
-
-/**
- * \defgroup lowleveltracing Low-level tracing
- *
- * This low-level API is built around a few concepts:
- *   - There can be any number of trace source objects. Each trace source
- *     object can generate any number of trace events. The current
- *     trace source objects are: ns3::CallbackTraceSourceSource, ns3::UVTraceSource,
- *     ns3::SVTraceSource, and, ns3::FVTraceSource.
- *   - Each trace source can be connected to any number of trace sinks.
- *     A trace sink is a ns3::Callback with a very special signature. Its
- *     first argument is always a ns3::TraceContext.
- *   - Every trace source is uniquely identified by a ns3::TraceContext. Every
- *     trace sink can query a ns3::TraceContext for information. This allows
- *     a trace sink which is connected to multiple trace sources to identify
- *     from which source each event is coming from.
- *
- * To define new trace sources, a model author needs to instante one trace source
- * object for each kind of tracing event he wants to export. The trace source objects
- * currently defined are:
- *  - ns3::CallbackTraceSourceSource: this trace source can be used to convey any kind of 
- *    trace event to the user. It is a functor, that is, it is a variable
- *    which behaves like a function which will forward every event to every
- *    connected trace sink (i.e., ns3::Callback). This trace source takes
- *    up to four arguments and forwards these 4 arguments together with the
- *    ns3::TraceContext which identifies this trace source to the connected
- *    trace sinks.
- *  - ns3::UVTraceSource: this trace source is used to convey key state variable
- *    changes to the user. It behaves like a normal integer unsigned variable:
- *    you can apply every normal arithmetic operator to it. It will forward
- *    every change in the value of the variable back to every connected trace 
- *    sink by providing a TraceContext, the old value and the new value.
- *  - ns3::SVTraceSource: this is the signed integer equivalent of 
- *    ns3::UVTraceSource.
- *  - ns3::FVTraceSource: this is the floating point equivalent of 
- *    ns3::UVTraceSource and ns3::SVTraceSource.
- *
- * For example, to define a trace source which notifies you of a new packet
- * being transmitted, you would have to:
- * \code
- * class MyModel
- * {
- *  public:
- *   void Tx (Packet const &p);
- *  private:
- *   CallbackTraceSource<Packet const &> m_txTrace;
- * };
- *
- * void
- * MyModel::Tx (Packet const &p)
- * {
- *   // trace packet tx event.
- *   m_txTrace (p);
- *   // ... send the packet for real.
- * }
- * \endcode
- *
- * Once the model author has instantiated these objects and has wired them 
- * in his simulation code (that is, he calls them wherever he wants to trigger 
- * a trace event), he needs to make these trace sources available to users
- * to allow them to connect any number of trace sources to any number
- * of user trace sinks. While it would be possible to make each model
- * export directly each of his trace source instances and request users to
- * invoke a source->Connect (callback) method to perform the connection
- * explicitely, it was felt that this was a bit cumbersome to do.
- *
- * As such, the ``connection'' between a set of sources and a sink is 
- * performed through a third-party class, the TraceResolver, which
- * can be used to automate the connection of multiple matching trace sources
- * to a single sink. This TraceResolver works by defining a hierarchical 
- * tracing namespace: the root of this namespace is accessed through the 
- * ns3::TraceRoot class. The namespace is represented as a string made of 
- * multiple elements, each of which is separated from the other elements 
- * by the '/' character. A namespace string always starts with a '/'.
- * 
- * By default, the current simulation models provide a '/nodes' tracing root. 
- * This '/nodes' namespace is structured as follows:
- * \code
- *  /nodes/n/arp
- *  /nodes/n/udp
- *  /nodes/n/ipv4
- *               /tx
- *               /rx
- *               /drop
- *               /interfaces/n/netdevice
- *                                      /queue/
- *                                            /enque
- *                                            /deque
- *                                            /drop
- * \endcode
- *
- * The 'n' element which follows the /nodes and /interfaces namespace elements
- * identify a specific node and interface through their index within the 
- * ns3::NodeList and ns3::Ipv4 objects respectively.
- *
- * To connect a trace sink to a trace source identified by a namespace string,
- * a user can call the ns3::TraceRoot::Connect method (the ns3::TraceRoot::Disconnect
- * method does the symmetric operation). This connection method can accept
- * fully-detailed namespace strings but it can also perform pattern matching
- * on the user-provided namespace strings to connect multiple trace sources
- * to a single trace sink in a single connection operation.
- *
- * The syntax of the pattern matching rules are loosely based on regular 
- * expressions:
- *   - the '*' character matches every element
- *   - the (a|b) construct matches element 'a' or 'b'
- *   - the [ss-ee] construct matches all numerical values which belong
- *     to the interval which includes ss and ee
- *
- * For example, the user could use the following to connect a single sink
- * to the ipv4 tx, rx, and drop trace events:
- *
- * \code
- * void MyTraceSink (TraceContext const &context, Packet &packet);
- * TraceRoot::Connect ("/nodes/ * /ipv4/ *", MakeCallback (&MyTraceSink));
- * \endcode
- *
- * Of course, this code would work only if the signature of the trace sink
- * is exactly equal to the signature of all the trace sources which match
- * the namespace string (if one of the matching trace source does not match
- * exactly, a fatal error will be triggered at runtime during the connection
- * process). The ns3::TraceContext extra argument contains
- * information on where the trace source is located in the namespace tree.
- * In that example, if there are multiple nodes in this scenario, each
- * call to the MyTraceSink function would receive a different TraceContext,
- * each of which would contain a different NodeList::NodeIndex object.
- *
- * It is important to understand exactly what an ns3::TraceContext
- * is. It is a container for a number of type instances. Each instance of
- * a ns3::TraceContext contains one and only one instance of a given type.
- * ns3::TraceContext::Add can be called to add a type instance into a 
- * TraceContext instance and ns3::TraceContext::Get can be called to get
- * a copy of a type instance stored into the ns3::TraceContext. If ::Get
- * cannot retrieve the requested type, a fatal error is triggered at
- * runtime. The values stored into an ns3::TraceContext attached to a 
- * trace source are automatically determined during the namespace
- * resolution process. To retrieve a value from a ns3::TraceContext, the
- * code can be as simple as this:
- * \code
- * void MyTraceSink (TraceContext const &context, Packet &packet)
- * {
- *   NodeList::NodeIndex index;
- *   context.Get (index);
- *   std::cout << "node id=" << NodeList::GetNode (index)->GetId () << std::endl;
- * }
- * \endcode
- *
- * The hierarchical global namespace described here is not implemented
- * in a single central location: it was felt that doing this would make
- * it too hard to introduce user-specific models which could hook
- * automatically into the overal tracing system. If the tracing
- * namespace was implemented in a single central location, every model
- * author would have had to modify this central component to make
- * his own model available to trace users.
- *
- * Instead, the handling of the namespace is distributed across every relevant
- * model: every model implements only the part of the namespace it is
- * really responsible for. To do this, every model is expected
- * to provide an instance of a TraceResolver whose
- * responsability is to recursively provide access to the trace sources
- * defined in its model. Each TraceResolver instance should be a subclass
- * of the TraceResolver base class which implements either the DoLookup
- * or the DoConnect and DoDisconnect methods. Because implementing these
- * methods can be a bit tedious, our tracing framework provides a number 
- * of helper template classes which should save the model author from 
- * having to implement his own in most cases:
- *    - ns3::CompositeTraceResolver: this subclass of ns3::TraceResolver can 
- *      be used to aggregate together multiple trace sources and multiple other 
- *      ns3::TraceResolver instances.
- *    - ns3::ArrayTraceResolver: this subclass of ns3::TraceResolver can be 
- *      used to match any number of elements within an array where every element 
- *      is identified by its index.
- *
- * Once you can instantiate your own ns3::TraceResolver object instance, you 
- * have to hook it up into the global namespace. There are two ways to do this:
- *   - you can hook your ns3::TraceResolver creation method as a new trace 
- *     root by using the ns3::TraceRoot::Register method
- *   - you can hook your new ns3::TraceResolver creation method into the 
- *     container of your model. This step will obvsiouly depend on which model
- *     contains your own model but, if you wrote a new l3 protocol, all you
- *     would have to do to hook into your container L3Demux class is to implement 
- *     the pure virtual method inherited from the L3Protocol class whose name is 
- *     ns3::L3protocol::CreateTraceResolver.
- *
- * So, in most cases, exporting a model's trace sources is a matter of 
- * implementing a method CreateTraceResolver as shown below:
- * \code
- * class MyModel
- * {
- * public:
- *   enum TraceType {
- *    TX,
- *    RX,
- *    ...
- *   };
- *   TraceResolver *CreateTraceResolver (TraceContext const &context);
- *   void Tx (Packet const &p);
- * private:
- *   CallbackTraceSource<Packet const &> m_txTrace;
- * };
- *
- * TraceResolver *
- * MyModel::CreateTraceResolver (TraceContext const &context)
- * {
- *   CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
- *   resolver->Add ("tx", m_txTrace, MyModel::TX);
- *   return resolver;
- * }
- * void 
- * MyModel::Tx (Packet const &p)
- * {
- *   m_txTrace (p);
- * }
- * \endcode
- *
- * If you really want to have fun and implement your own ns3::TraceResolver 
- * subclass, you need to understand the basic Connection and Disconnection
- * algorithm. The code of that algorithm is wholy contained in the
- * ns3::TraceResolver::Connect and ns3::TraceResolver::Disconnect methods.
- * The idea is that we recursively parse the input namespace string by removing
- * the first namespace element. This element is 'resolved' is calling
- * the ns3::TraceResolver::DoLookup method which returns a list of
- * TraceResolver instances. Each of the returned TraceResolver instance is
- * then given what is left of the namespace by calling ns3::TraceResolver::Connect
- * until the last namespace element is processed. At this point, we invoke
- * the ns3::TraceResolver::DoConnect or ns3::TraceResolver::DoDisconnect 
- * methods to break the recursion. A good way to understand this algorithm
- * is to trace its behavior. Let's say that you want to connect to
- * '/nodes/ * /ipv4/interfaces/ * /netdevice/queue/ *'. It would generate
- * the following call traces:
- *
- * \code
- * TraceRoot::Connect ("/nodes/ * /ipv4/interfaces/ * /netdevice/queue/ *", callback);
- * traceContext = TraceContext ();
- * rootResolver = CompositeTraceResolver (traceContext);
- * rootResolver->Connect ("/nodes/ * /ipv4/interfaces/ * /netdevice/queue/ *", callback);
- *   resolver = CompositeTraceResolver::DoLookup ("nodes");
- *     return NodeList::CreateTraceResolver (GetContext ());
- *       return ArrayTraceResolver (context);
- *   resolver->Connect ("/ * /ipv4/interfaces/ * /netdevice/queue/ *", callback);
- *     ArrayTraceResolver::DoLookup ("*");
- *       for (i = 0; i < n_nodes; i++)
- *         resolver = nodes[i]->CreateTraceResolver (GetContext ());
- *           return CompositeTraceResolver (context);
- *         resolvers.add (resolver);
- *       return resolvers;
- *     for resolver in (resolvers)
- *       resolver->Connect ("/ipv4/interfaces/ * /netdevice/queue/ *", callback);
- *         CompositeTraceResolver::DoLookup ("ipv4");
- *           resolver = ipv4->CreateTraceResolver (GetContext ());
- *             return CompositeTraceResolver (context);
- *           return resolver;
- *         resolver->Connect ("/interfaces/ * /netdevice/queue/ *", callback);
- *           CompositeTraceResolver::DoLookup ("interfaces");
- *             resolver = ArrayTraceResolver (GetContext ());
- *           resolver->Connect ("/ * /netdevice/queue/ *", callback);
- *             ArrayTraceResolver::DoLookup ("*");
- *               for (i = 0; i < n_interfaces; i++)
- *                  resolver = interfaces[i]->CreateTraceResolver (GetContext ());
- *                    return CompositeTraceResolver ()
- *                  resolvers.add (resolver);
- *               return resolvers;
- *             resolver->Connect ("/netdevice/queue/ *", callback);
- *               CompositeTraceResolver::DoLookup ("netdevice");
- *                 resolver = NetDevice::CreateTraceResolver (GetContext ());
- *                   return CompositeTraceResolver ();
- *                 return resolver;
- *               resolver->Connect ("/queue/ *", callback);
- *                 CompositeTraceResolver::DoLookup ("queue");
- *                   resolver = Queue::CreateTraceResolver (GetContext ());
- *                     return CompositeTraceResolver ();
- *                   return resolver
- *                 resolver->Connect ("*", callback);
- *                   CompositeTraceResolver::DoLookup ("*");
- *                     for match in (matches)
- *                       resolver = TerminalTraceResolver ("match");
- *                       resolvers.add (resolver)
- *                     return resolvers;
- *                   for resolver in (resolvers)
- *                     TerminalTraceResolver->DoConnect (callback);
- * \endcode
- */
-
-namespace ns3 {
-
-class CompositeTraceResolver;
-class TraceResolver;
-class TraceContext;
-class CallbackBase;
-
-/**
- * \brief The main class used to access tracing functionality for
- * a user.
- *
- * \ingroup lowleveltracing
- */
-class TraceRoot
-{
-public:
-  static void Connect (std::string path, CallbackBase const &cb);
-  static void Disconnect (std::string path, CallbackBase const &cb);
-  static void Register (std::string name, 
-                        Callback<TraceResolver *,TraceContext const &> createResolver);
-private:
-  static CompositeTraceResolver *GetComposite (void);
-};
-
-}// namespace ns3
-
-#endif /* TRACE_ROOT_H */
--- a/src/common/uv-trace-source.h	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,245 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * All rights reserved.
- *
- * 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 UV_TRACE_SOURCE_H
-#define UV_TRACE_SOURCE_H
-
-#include "callback-trace-source.h"
-#include <stdint.h>
-
-namespace ns3 {
-
-class UVTraceSourceBase {
-public:
-  typedef CallbackTraceSource<uint64_t, uint64_t> ChangeNotifyCallback;
-
-  UVTraceSourceBase ()
-      : m_callback () {}
-  /* We don't want to copy the base callback. Only setCallback on
-   * a specific instance will do something to it. */
-  UVTraceSourceBase (UVTraceSourceBase const &o) 
-      : m_callback () {}
-  UVTraceSourceBase &operator = (UVTraceSourceBase const &o) {
-      return *this;
-  }
-  ~UVTraceSourceBase () {}
-
-  void AddCallback (CallbackBase const & callback, TraceContext const & context) {
-    m_callback.AddCallback (callback, context);
-  }
-  void RemoveCallback (CallbackBase const & callback) {
-    m_callback.RemoveCallback (callback);
-  }
-
-protected:
-  void Notify (uint64_t oldVal, uint64_t newVal) {
-      if (oldVal != newVal) 
-        {
-          m_callback (oldVal, newVal);
-        }
-  }
-private:
-  ChangeNotifyCallback m_callback;
-};
-
-template <typename T>
-class SVTraceSource;
-
-
-/**
- * \brief trace variables of type "unsigned integer"
- * \ingroup lowleveltracing
- *
- * This template class implements a POD type: it
- * behaves like any other variable of type "unsigned integer"
- * except that it also reports any changes to its
- * value with its internal callback.
- *
- * To instantiate a 32-bit unsigned variable (to store
- * a TCP counter for example), you would create a variable of type
- * ns3::UVTraceSource<uint32_t> :
- \code
- #include <stdint.h>
- #include "ns3/uv-trace-source.h"
-
- ns3::UVTraceSource<uint32_t> var;
- \endcode
- * and you would use it like any other variable of type uint32_t:
- \code
- var += 12;
- var = 10;
- \endcode
- */
-template <typename T>
-class UVTraceSource : public UVTraceSourceBase {
-public:
-  UVTraceSource ()
-      : m_var ()
-  {}
-  UVTraceSource (T const &var) 
-      : m_var (var)
-  {}
-
-  UVTraceSource &operator = (UVTraceSource const &o) {
-      Assign (o.Get ());
-      return *this;
-  }
-  template <typename TT>
-  UVTraceSource &operator = (UVTraceSource<TT> const &o) {
-      Assign (o.Get ());
-      return *this;
-  }
-  template <typename TT>
-  UVTraceSource &operator = (SVTraceSource<TT> const &o) {
-      Assign (o.Get ());
-      return *this;
-  }
-  UVTraceSource &operator++ () {
-      Assign (Get () + 1);
-      return *this;
-  }
-  UVTraceSource &operator-- () {
-      Assign (Get () - 1);
-      return *this;
-  }
-  UVTraceSource operator++ (int) {
-      UVTraceSource old (*this);
-      ++*this;
-      return old;
-  }
-  UVTraceSource operator-- (int) {
-      UVTraceSource old (*this);
-      --*this;
-      return old;
-  }
-  operator T () const {
-      return Get ();
-  }
-
-
-  void Assign (T var) {
-      Notify (m_var, var);
-      m_var = var;
-  }
-  T Get (void) const {
-      return m_var;
-  }
-
-private:
-  T m_var;
-};
-
-template <typename T>
-UVTraceSource<T> &operator += (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () + rhs.Get ());
-  return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator -= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () - rhs.Get ());
-  return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator *= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () * rhs.Get ());
-  return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator /= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () / rhs.Get ());
-  return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator <<= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () << rhs.Get ());
-  return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator >>= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () >> rhs.Get ());
-  return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator &= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () & rhs.Get ());
-  return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator |= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () | rhs.Get ());
-  return lhs;
-}
-template <typename T>
-UVTraceSource<T> &operator ^= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
-  lhs.Assign (lhs.Get () ^ rhs.Get ());
-  return lhs;
-}
-
-
-template <typename T, typename U>
-UVTraceSource<T> &operator += (UVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () + rhs);
-  return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator -= (UVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () - rhs);
-  return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator *= (UVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () * rhs);
-  return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator /= (UVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () / rhs);
-  return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator <<= (UVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () << rhs);
-  return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator >>= (UVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () >> rhs);
-  return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator &= (UVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () & rhs);
-  return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator |= (UVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () | rhs);
-  return lhs;
-}
-template <typename T, typename U>
-UVTraceSource<T> &operator ^= (UVTraceSource<T> &lhs, U const &rhs) {
-  lhs.Assign (lhs.Get () ^ rhs);
-  return lhs;
-}
-
-}; // namespace ns3
-
-#endif /* UV_TRACE_SOURCE_H */
--- a/src/common/variable-tracer-test.cc	Tue Sep 11 10:35:56 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,272 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * All rights reserved.
- *
- * 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 "uv-trace-source.h"
-#include "sv-trace-source.h"
-#include "trace-context.h"
-#include "ns3/test.h"
-#include "ns3/callback.h"
-
-
-namespace ns3 {
-
-class Foo {
-public:
-  void Notify (TraceContext const &contex, uint64_t oldVal, uint64_t newVal) {}
-};
-
-class VariableTracerTest: public Test {
-public:
-  VariableTracerTest ();
-  void RunUnsignedTests (void);
-  void RunSignedUnsignedTests (void);
-  virtual bool RunTests (void);
-};
-void
-VariableTracerTest::RunUnsignedTests (void)
-{
-  UVTraceSource<uint32_t> var, ovar, tmp;
-  uint32_t utmp;
-  Foo *foo = new Foo ();
-  
-  var.AddCallback (MakeCallback (&Foo::Notify, foo), TraceContext ());
-
-  var = 10;
-  ovar = var;
-
-  if (var == ovar) 
-    {
-    }
-  if (var != ovar) 
-    {
-    }
-  if (var > ovar) 
-    {
-    }
-  if (var >= ovar) 
-    {
-    }
-  if (var < ovar)
-    {
-    }
-  
-  if (var <= ovar)
-
-  if (var == 1)
-    {
-    }
-  if (var != 1)
-    {
-    }
-  if (var > 1)
-    {
-    }
-  if (var >= 1)
-    {
-    }
-  if (var < 1)
-    {
-    }
-  if (var <= 1)
-    {
-    }
-
-  if (1 == ovar)
-    {
-    }
-  if (1 != ovar)
-    {
-    }
-  if (1 > ovar)
-    {
-    }
-  if (1 >= ovar)
-    {
-    }
-  if (1 < ovar)
-    {
-    }
-  if (1 <= ovar)
-    {
-    }
-
-  var++;
-  ++var;
-  var--;
-  --var;
-
-  tmp = var + ovar;
-  tmp = var - ovar;
-  tmp = var / ovar;
-  tmp = var * ovar;
-  tmp = var << ovar;
-  tmp = var >> ovar;
-  tmp = var & ovar;
-  tmp = var | ovar;
-  tmp = var ^ ovar;
-
-  tmp = var + 1;
-  tmp = var - 1;
-  tmp = var / 1;
-  tmp = var * 1;
-  tmp = var << 1;
-  tmp = var >> 1;
-  tmp = var & 1;
-  tmp = var | 1;
-  tmp = var ^ 1;
-
-  tmp = 1 + ovar;
-  tmp = 1 - ovar;
-  tmp = 1 / ovar;
-  tmp = 1 * ovar;
-  tmp = 1 << ovar;
-  tmp = 1 >> ovar;
-  tmp = 1 & ovar;
-  tmp = 1 | ovar;
-  tmp = 1 ^ ovar;
-
-  tmp += var;
-  tmp -= var;
-  tmp /= var;
-  tmp *= var;
-  tmp <<= var;
-  tmp >>= var;
-  tmp &= var;
-  tmp |= var;
-  tmp ^= var;
-
-  tmp += 1;
-  tmp -= 1;
-  tmp /= 1;
-  tmp *= 1;
-  tmp <<= 1;
-  tmp >>= 1;
-  tmp &= 1;
-  tmp |= 1;
-  tmp ^= 1;
-
-
-  utmp = var + ovar;
-  utmp = var - ovar;
-  utmp = var / ovar;
-  utmp = var * ovar;
-  utmp = var << ovar;
-  utmp = var >> ovar;
-  utmp = var & ovar;
-  utmp = var | ovar;
-  utmp = var ^ ovar;
-
-  utmp = var + 1;
-  utmp = var - 1;
-  utmp = var / 1;
-  utmp = var * 1;
-  utmp = var << 1;
-  utmp = var >> 1;
-  utmp = var & 1;
-  utmp = var | 1;
-  utmp = var ^ 1;
-
-  utmp = 1 + ovar;
-  utmp = 1 - ovar;
-  utmp = 1 / ovar;
-  utmp = 1 * ovar;
-  utmp = 1 << ovar;
-  utmp = 1 >> ovar;
-  utmp = 1 & ovar;
-  utmp = 1 | ovar;
-  utmp = 1 ^ ovar;
-
-  utmp += var;
-  utmp -= var;
-  utmp /= var;
-  utmp *= var;
-  utmp <<= var;
-  utmp >>= var;
-  utmp &= var;
-  utmp |= var;
-  utmp ^= var;
-
-  utmp += 1;
-  utmp -= 1;
-  utmp /= 1;
-  utmp *= 1;
-  utmp <<= 1;
-  utmp >>= 1;
-  utmp &= 1;
-  utmp |= 1;
-  utmp ^= 1;
-
-  delete foo;
-}
-
-void
-VariableTracerTest::RunSignedUnsignedTests (void)
-{
-  unsigned short utmp = 10;
-  unsigned int uitmp = 7;
-  short stmp = 5;
-  utmp = stmp;
-  utmp += stmp;
-  uitmp = utmp;
-  utmp = uitmp;
-
-  UVTraceSource<unsigned short> uvar = 10;
-  UVTraceSource<unsigned int> uivar = 5;
-  SVTraceSource<short> svar = 5;
-  SVTraceSource<int> sivar = 5;
-  uvar = svar;
-  svar = uvar;
-  uvar += svar;
-  svar += uvar;
-
-  uvar = sivar;
-  sivar = uvar;
-  uvar += sivar;
-  sivar += uvar;
-
-  uivar = uvar;
-  uvar = uivar;
-  uivar += uvar;
-  uvar += uivar;
-
-  sivar = svar;
-  svar = sivar;
-  sivar += svar;
-  svar += sivar;
-}
-
-bool 
-VariableTracerTest::RunTests (void)
-{
-  RunUnsignedTests ();
-  RunSignedUnsignedTests ();
-
-  return true;
-}
-
-VariableTracerTest::VariableTracerTest ()
-  : Test ("VariableTracer") {}
-
-static VariableTracerTest gVariableTracerTest;
-
-}; // namespace ns3
-
-
--- a/src/common/wscript	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/common/wscript	Tue Sep 11 12:11:00 2007 +0200
@@ -12,14 +12,6 @@
         'tags.cc',
         'tag-registry.cc',
         'pcap-writer.cc',
-        'variable-tracer-test.cc',
-        'trace-context.cc',
-        'trace-context-element.cc',
-        'trace-resolver.cc',
-        'callback-trace-source.cc',
-        'empty-trace-resolver.cc',
-        'composite-trace-resolver.cc',
-        'trace-root.cc',
         'data-rate.cc',
         ]
 
@@ -35,18 +27,6 @@
         'packet.h',
         'packet-printer.h',
         'packet-metadata.h',
-        'uv-trace-source.h',
-        'sv-trace-source.h',
-        'fv-trace-source.h',
         'pcap-writer.h',
-        'callback-trace-source.h',
-        'trace-context.h',
-        'trace-context-element.h',
-        'trace-resolver.h',
-        'empty-trace-resolver.h',
-        'composite-trace-resolver.h',
-        'array-trace-resolver.h',
-        'trace-root.h',
-        'terminal-trace-resolver.h',
         'data-rate.h',
         ]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/array-trace-resolver.h	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,205 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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 ARRAY_TRACE_RESOLVER_H
+#define ARRAY_TRACE_RESOLVER_H
+
+#include <stdint.h>
+#include <string>
+#include "callback.h"
+#include "trace-resolver.h"
+#include "object.h"
+
+namespace ns3 {
+
+/**
+ * \brief a helper class to offer trace resolution for an array of objects.
+ * \ingroup tracing
+ *
+ * \class ArrayTraceResolver
+ *
+ * An ArrayTraceResolver is a resolver which can match any input integer
+ * against an element in an array. The array is accessed using a 
+ * pair iterators. Each element of the array is expected
+ * to be a subclass of the Object base class.
+ * 
+ * When the Connect method is called, this trace resolver will 
+ * automatically store in the TraceContext of each resolved object
+ * its index through an object of type INDEX specified during the
+ * instanciation of the ArrayTraceResolver template.
+ */
+template <typename INDEX>
+class ArrayTraceResolver : public TraceResolver
+{
+public:
+  ArrayTraceResolver ();
+  ~ArrayTraceResolver ();
+
+  /**
+   * \param begin an iterator which points to the start of the array.
+   * \param end an iterator which points to the end of the array.
+   */
+  template <typename T>
+  void SetIterators (T begin, T end);
+
+  // inherited from TraceResolver
+  virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context);
+  virtual void Disconnect (std::string path, CallbackBase const &cb);
+  virtual void CollectSources (std::string path, const TraceContext &context, 
+                               SourceCollection *collection);
+  virtual void TraceAll (std::ostream &os, const TraceContext &context);
+
+private:
+  class IteratorBase
+  {
+  public:
+    virtual ~IteratorBase () {}
+    virtual void Next (void) = 0;
+    virtual bool HasNext (void) = 0;
+    virtual Ptr<Object> Get (void) = 0;
+    virtual void Rewind (void) = 0;
+  };
+  IteratorBase *m_iter;
+};
+}//namespace ns3
+
+
+// implementation
+namespace ns3 {
+
+template <typename INDEX>
+ArrayTraceResolver<INDEX>::ArrayTraceResolver ()
+  : m_iter (0)
+{}
+
+template <typename INDEX>
+ArrayTraceResolver<INDEX>::~ArrayTraceResolver ()
+{
+  delete m_iter;
+}
+
+template <typename INDEX>
+template <typename T>
+void
+ArrayTraceResolver<INDEX>::SetIterators (T begin, T end)
+{
+  class Iterator : public IteratorBase 
+  {
+  public:
+    Iterator (T begin, T end)
+      : m_begin (begin), m_end (end), m_cur (begin)
+    {}
+    virtual void Next (void)
+    {m_cur++;}
+    virtual bool HasNext (void)
+    {return m_cur != m_end;}
+    virtual Ptr<Object> Get (void)
+    {return *m_cur;}
+    virtual void Rewind (void)
+    {m_cur = m_begin;}
+  private:
+    T m_begin;
+    T m_end;
+    T m_cur;
+  };
+  delete m_iter;
+  m_iter = new Iterator (begin, end);
+}
+
+template <typename INDEX>
+void 
+ArrayTraceResolver<INDEX>::Connect (std::string path, CallbackBase const &cb, const TraceContext &context)
+{
+  if (path == "")
+    {
+      return;
+    }
+  std::string id = GetElement (path);
+  std::string subpath = GetSubpath (path);
+  if (id == "*")
+  {
+    uint32_t j = 0;
+    for (m_iter->Rewind (); m_iter->HasNext (); m_iter->Next ())
+      {
+        TraceContext tmp = context;
+        INDEX index = j;
+        tmp.AddElement (index);
+        Ptr<Object> obj = m_iter->Get ();
+        obj->GetTraceResolver ()->Connect (subpath, cb, tmp);
+        j++;
+      }
+  }
+}
+template <typename INDEX>
+void 
+ArrayTraceResolver<INDEX>::Disconnect (std::string path, CallbackBase const &cb)
+{
+  if (path == "")
+    {
+      return;
+    }
+  std::string id = GetElement (path);
+  std::string subpath = GetSubpath (path);
+  if (id == "*")
+  {
+    for (m_iter->Rewind (); m_iter->HasNext (); m_iter->Next ())
+      {
+        Ptr<Object> obj = m_iter->Get ();
+        obj->TraceDisconnect (subpath, cb);
+      }
+  }
+}
+template <typename INDEX>
+void 
+ArrayTraceResolver<INDEX>::CollectSources (std::string path, const TraceContext &context, 
+                                           SourceCollection *collection)
+{
+  path.append ("/[0-n]");
+  uint32_t j = 0;
+  for (m_iter->Rewind (); m_iter->HasNext (); m_iter->Next ())
+    {
+        TraceContext tmp = context;
+        INDEX index = j;
+        tmp.AddElement (index);
+        Ptr<Object> obj = m_iter->Get ();
+        obj->GetTraceResolver ()->CollectSources (path, tmp, collection);
+        j++;
+    }
+}
+
+template <typename INDEX>
+void 
+ArrayTraceResolver<INDEX>::TraceAll (std::ostream &os, const TraceContext &context)
+{
+  uint32_t j = 0;
+  for (m_iter->Rewind (); m_iter->HasNext (); m_iter->Next ())
+    {
+        TraceContext tmp = context;
+        INDEX index = j;
+        tmp.AddElement (index);
+        Ptr<Object> obj = m_iter->Get ();
+        obj->GetTraceResolver ()->TraceAll (os, tmp);
+        j++;
+    }
+}
+
+}//namespace ns3
+
+#endif /* ARRAY_TRACE_RESOLVER_H */
--- a/src/core/callback-test.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/core/callback-test.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -57,6 +57,21 @@
   return a;
 }
 
+void TestFZero (void) {}
+void TestFOne (int) {}
+void TestFTwo (int, int) {}
+void TestFThree (int, int, int) {}
+void TestFFour (int, int, int, int) {}
+void TestFFive (int, int, int, int, int) {}
+void TestFSix (int, int, int, int, int, int) {}
+
+void TestFROne (int &) {}
+void TestFRTwo (int &, int &) {}
+void TestFRThree (int &, int &, int &) {}
+void TestFRFour (int &, int &, int &, int &) {}
+void TestFRFive (int &, int &, int &, int &, int &) {}
+void TestFRSix (int &, int &, int &, int &, int &, int &) {}
+
 class CallbackTest : public ns3::Test {
 private:
   bool m_test1;
@@ -73,6 +88,22 @@
   void Test3 (double a);
   int Test4 (double a, int b);
   void Test8 (Callback<void, int> callback);
+
+  void TestZero (void) {}
+  void TestOne (int) {}
+  void TestTwo (int, int) {}
+  void TestThree (int, int, int) {}
+  void TestFour (int, int, int, int) {}
+  void TestFive (int, int, int, int, int) {}
+  void TestSix (int, int, int, int, int, int) {}
+
+  void TestCZero (void) const {}
+  void TestCOne (int) const {}
+  void TestCTwo (int, int) const {}
+  void TestCThree (int, int, int) const {}
+  void TestCFour (int, int, int, int) const {}
+  void TestCFive (int, int, int, int, int) const {}
+  void TestCSix (int, int, int, int, int, int) const {}
 };
 
 CallbackTest::CallbackTest ()
@@ -110,6 +141,7 @@
 {
   callback (3);
 }
+
 bool
 CallbackTest::IsWrong (void)
 {
@@ -216,6 +248,53 @@
   MakeBoundCallback (&Test9, &v);
   MakeBoundCallback (&Test10, &v);
 
+
+  MakeCallback (&CallbackTest::TestZero, this);
+  MakeCallback (&CallbackTest::TestOne, this);
+  MakeCallback (&CallbackTest::TestTwo, this);
+  MakeCallback (&CallbackTest::TestThree, this);
+  MakeCallback (&CallbackTest::TestFour, this);
+  MakeCallback (&CallbackTest::TestFive, this);
+  MakeCallback (&CallbackTest::TestSix, this);
+
+  MakeCallback (&CallbackTest::TestCZero, this);
+  MakeCallback (&CallbackTest::TestCOne, this);
+  MakeCallback (&CallbackTest::TestCTwo, this);
+  MakeCallback (&CallbackTest::TestCThree, this);
+  MakeCallback (&CallbackTest::TestCFour, this);
+  MakeCallback (&CallbackTest::TestCFive, this);
+  MakeCallback (&CallbackTest::TestCSix, this);
+
+  MakeCallback (&TestFZero);
+  MakeCallback (&TestFOne);
+  MakeCallback (&TestFTwo);
+  MakeCallback (&TestFThree);
+  MakeCallback (&TestFFour);
+  MakeCallback (&TestFFive);
+  MakeCallback (&TestFSix);
+
+  MakeCallback (&TestFROne);
+  MakeCallback (&TestFRTwo);
+  MakeCallback (&TestFRThree);
+  MakeCallback (&TestFRFour);
+  MakeCallback (&TestFRFive);
+  MakeCallback (&TestFRSix);
+
+
+  MakeBoundCallback (&TestFOne, 1);
+  MakeBoundCallback (&TestFTwo, 1);
+  MakeBoundCallback (&TestFThree, 1);
+  MakeBoundCallback (&TestFFour, 1);
+  MakeBoundCallback (&TestFFive, 1);
+
+  MakeBoundCallback (&TestFROne, 1);
+  MakeBoundCallback (&TestFRTwo, 1);
+  MakeBoundCallback (&TestFRThree, 1);
+  MakeBoundCallback (&TestFRFour, 1);
+  MakeBoundCallback (&TestFRFive, 1);
+
+
+
   return ok;
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/callback-trace-source.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,101 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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 "callback-trace-source.h"
+
+#ifdef RUN_SELF_TESTS
+
+#include "test.h"
+
+namespace ns3 {
+
+class CallbackTraceSourceTest : public Test 
+{
+public:
+  CallbackTraceSourceTest ();
+  virtual ~CallbackTraceSourceTest ();
+  virtual bool RunTests (void);
+private:
+  void CbOne (TraceContext const &context, uint8_t a, double b);
+  void CbTwo (TraceContext const &context, uint8_t a, double b);
+
+  bool m_one;
+  bool m_two;
+};
+
+CallbackTraceSourceTest::CallbackTraceSourceTest ()
+  : Test ("CallbackTraceSource")
+{}
+CallbackTraceSourceTest::~CallbackTraceSourceTest ()
+{}
+void
+CallbackTraceSourceTest::CbOne (TraceContext const &context, uint8_t a, double b)
+{
+  m_one = true;
+}
+void
+CallbackTraceSourceTest::CbTwo (TraceContext const &context, uint8_t a, double b)
+{
+  m_two = true;
+}
+bool 
+CallbackTraceSourceTest::RunTests (void)
+{
+  bool result = true;
+  TraceContext ctx;
+
+  CallbackTraceSource<uint8_t,double> trace;
+  trace.AddCallback (MakeCallback (&CallbackTraceSourceTest::CbOne, this), ctx);
+  trace.AddCallback (MakeCallback (&CallbackTraceSourceTest::CbTwo, this), ctx);
+  m_one = false;
+  m_two = false;
+  trace (1, 2);
+  NS_TEST_ASSERT (m_one);
+  NS_TEST_ASSERT (m_two);
+
+  trace.RemoveCallback (MakeCallback (&CallbackTraceSourceTest::CbOne, this));
+  m_one = false;
+  m_two = false;
+  trace (1, 2);
+  NS_TEST_ASSERT (!m_one);
+  NS_TEST_ASSERT (m_two);
+  trace.RemoveCallback (MakeCallback (&CallbackTraceSourceTest::CbTwo, this));
+  m_one = false;
+  m_two = false;
+  trace (1, 2);
+  NS_TEST_ASSERT (!m_one);
+  NS_TEST_ASSERT (!m_two);
+
+  trace.AddCallback (MakeCallback (&CallbackTraceSourceTest::CbOne, this), ctx);
+  trace.AddCallback (MakeCallback (&CallbackTraceSourceTest::CbTwo, this), ctx);
+  m_one = false;
+  m_two = false;
+  trace (1, 2);
+  NS_TEST_ASSERT (m_one);
+  NS_TEST_ASSERT (m_two);
+
+  return result;
+}
+
+CallbackTraceSourceTest g_callbackTraceTest;
+
+}//namespace ns3
+
+#endif /* RUN_SELF_TESTS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/callback-trace-source.h	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,251 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 INRIA
+ * All rights reserved.
+ *
+ * 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 CALLBACK_TRACE_H
+#define CALLBACK_TRACE_H
+
+#include <list>
+#include "callback.h"
+#include "fatal-error.h"
+#include "trace-context.h"
+#include "trace-source.h"
+
+namespace ns3 {
+
+/**
+ * \brief log arbitrary number of parameters to a matching ns3::Callback
+ * \ingroup tracing
+ *
+ * Whenever operator () is invoked on this class, the call and its arguments
+ * are forwarded to the internal matching ns3::Callback.
+ */
+template<typename T1 = empty, typename T2 = empty, 
+         typename T3 = empty, typename T4 = empty>
+class CallbackTraceSource : public TraceSource {
+public:
+  CallbackTraceSource ();
+  virtual void AddCallback (CallbackBase const & callback, TraceContext const & context);
+  virtual void RemoveCallback (CallbackBase const & callback);
+  virtual void ConnectPrinter (std::ostream &os, const TraceContext &context);
+  void operator() (void) const;
+  void operator() (T1 a1) const;
+  void operator() (T1 a1, T2 a2) const;
+  void operator() (T1 a1, T2 a2, T3 a3) const;
+  void operator() (T1 a1, T2 a2, T3 a3, T4 a4) const;
+
+private:
+  typedef std::list<Callback<void,TraceContext const &,T1,T2,T3,T4> > CallbackList;
+  TraceContext m_context;
+  CallbackList m_callbackList;
+};
+
+}; // namespace ns3
+
+// implementation below.
+
+namespace ns3 {
+
+namespace internal {
+
+template<typename T1, typename T2, 
+         typename T3, typename T4>
+class TraceSinkPrint;
+
+template<typename T1, typename T2, 
+         typename T3, typename T4>
+class TraceSinkPrint
+{
+public:
+  static Callback<void,const TraceContext &,T1,T2,T3,T4> Make (std::ostream &os)
+  {
+    return ns3::MakeBoundCallback (&DoPrint, &os);
+  }
+private:
+  static void DoPrint (std::ostream *os, const TraceContext &context, T1 a1, T2 a2, T3 a3, T4 a4)
+  {
+    *os << "context=\"" << context << "\" arg1=\"" << a1 << "\" arg2=\"" << a2 << "\" arg3=\"" << a3 << "\" arg4=\"" << a4 << "\"" << std::endl;
+  }
+};
+
+template<typename T1, typename T2, 
+         typename T3>
+class TraceSinkPrint<T1,T2,T3,empty>
+{
+public:
+  static Callback<void,const TraceContext &,T1,T2,T3> Make (std::ostream &os)
+  {
+    return ns3::MakeBoundCallback (&DoPrint, &os);
+  }
+private:
+  static void DoPrint (std::ostream *os, const TraceContext &context, T1 a1, T2 a2, T3 a3)
+  {
+    *os << "context=\"" << context << "\" arg1=\"" << a1 << "\" arg2=\"" << a2 << "\" arg3=\"" << a3 << "\"" << std::endl;
+  }
+};
+
+template<typename T1, typename T2>
+class TraceSinkPrint<T1,T2,empty,empty>
+{
+public:
+  static Callback<void,const TraceContext &,T1,T2> Make (std::ostream &os)
+  {
+    return ns3::MakeBoundCallback (&DoPrint, &os);
+  }
+private:
+  static void DoPrint (std::ostream *os, const TraceContext &context, T1 a1, T2 a2)
+  {
+    *os << "context=\"" << context << "\" arg1=\"" << a1 << "\" arg2=\"" << a2 << "\"" << std::endl;
+  }
+};
+
+template<typename T1>
+class TraceSinkPrint<T1,empty,empty,empty>
+{
+public:
+  static Callback<void,const TraceContext &,T1> Make (std::ostream &os)
+  {
+    return ns3::MakeBoundCallback (&DoPrint, &os);
+  }
+private:
+  static void DoPrint (std::ostream *os, const TraceContext &context, T1 a1)
+  {
+    *os << "context=\"" << context << "\" arg1=\"" << a1 << "\"" << std::endl;
+  }
+};
+
+template <>
+class TraceSinkPrint<empty,empty,empty,empty>
+{
+public:
+  static Callback<void,const TraceContext &> Make (std::ostream &os)
+  {
+    return ns3::MakeBoundCallback (&DoPrint, &os);
+  }
+private:
+  static void DoPrint (std::ostream *os, const TraceContext &context)
+  {
+    *os << "context=\"" << context << std::endl;
+  }
+};
+
+} // namespace internal
+
+
+template<typename T1, typename T2, 
+         typename T3, typename T4>
+CallbackTraceSource<T1,T2,T3,T4>::CallbackTraceSource ()
+  : m_callbackList () 
+{}
+template<typename T1, typename T2, 
+         typename T3, typename T4>
+void 
+CallbackTraceSource<T1,T2,T3,T4>::AddCallback (CallbackBase const & callback,
+                                               TraceContext const &context)
+{
+  Callback<void,TraceContext const &,T1,T2,T3,T4> cb;
+  cb.Assign (callback);
+  m_context.Union (context);
+  m_callbackList.push_back (cb);
+}
+template<typename T1, typename T2, 
+         typename T3, typename T4>
+void 
+CallbackTraceSource<T1,T2,T3,T4>::RemoveCallback (CallbackBase const & callback)
+{
+  for (typename CallbackList::iterator i = m_callbackList.begin ();
+       i != m_callbackList.end (); /* empty */)
+    {
+      if ((*i).IsEqual (callback))
+	{
+	  i = m_callbackList.erase (i);
+	}
+      else
+	{
+	  i++;
+	}
+    }
+}
+template<typename T1, typename T2, 
+         typename T3, typename T4>
+void 
+CallbackTraceSource<T1,T2,T3,T4>::ConnectPrinter (std::ostream &os, const TraceContext &context)
+{
+  AddCallback (ns3::internal::TraceSinkPrint<T1,T2,T3,T4>::Make (os), context);
+}
+template<typename T1, typename T2, 
+         typename T3, typename T4>
+void 
+CallbackTraceSource<T1,T2,T3,T4>::operator() (void) const
+{
+  for (typename CallbackList::const_iterator i = m_callbackList.begin ();
+       i != m_callbackList.end (); i++)
+    {
+      (*i) (m_context);
+    }
+}
+template<typename T1, typename T2, 
+         typename T3, typename T4>
+void 
+CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1) const
+{
+  for (typename CallbackList::const_iterator i = m_callbackList.begin ();
+       i != m_callbackList.end (); i++)
+    {
+      (*i) (m_context, a1);
+    }
+}
+template<typename T1, typename T2, 
+         typename T3, typename T4>
+void 
+CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1, T2 a2) const
+{
+  for (typename CallbackList::const_iterator i = m_callbackList.begin ();
+       i != m_callbackList.end (); i++)
+    {
+      (*i) (m_context, a1, a2);
+    }
+}
+template<typename T1, typename T2, 
+         typename T3, typename T4>
+void 
+CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1, T2 a2, T3 a3) const
+{
+  for (typename CallbackList::const_iterator i = m_callbackList.begin ();
+       i != m_callbackList.end (); i++)
+    {
+      (*i) (m_context, a1, a2, a3);
+    }
+}
+template<typename T1, typename T2, 
+         typename T3, typename T4>
+void 
+CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1, T2 a2, T3 a3, T4 a4) const
+{
+  for (typename CallbackList::const_iterator i = m_callbackList.begin ();
+       i != m_callbackList.end (); i++)
+    {
+      (*i) (m_context, a1, a2, a3, a4);
+    }
+}
+
+}//namespace ns3
+
+#endif /* CALLBACK_TRACE_H */
--- a/src/core/callback.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/core/callback.h	Tue Sep 11 12:11:00 2007 +0200
@@ -25,6 +25,7 @@
 #include "ptr.h"
 #include "fatal-error.h"
 #include "empty.h"
+#include "type-traits.h"
 
 namespace ns3 {
 
@@ -89,55 +90,62 @@
 };
 
 // declare the CallbackImpl class
-template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
+template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
 class CallbackImpl;
 // define CallbackImpl for 0 params
 template <typename R>
-class CallbackImpl<R,empty,empty,empty,empty,empty> : public CallbackImplBase {
+class CallbackImpl<R,empty,empty,empty,empty,empty,empty> : public CallbackImplBase {
 public:
   virtual ~CallbackImpl () {}
   virtual R operator() (void) = 0;
 };
 // define CallbackImpl for 1 params
 template <typename R, typename T1>
-class CallbackImpl<R,T1,empty,empty,empty,empty> : public CallbackImplBase {
+class CallbackImpl<R,T1,empty,empty,empty,empty,empty> : public CallbackImplBase {
 public:
   virtual ~CallbackImpl () {}
   virtual R operator() (T1) = 0;
 };
 // define CallbackImpl for 2 params
 template <typename R, typename T1, typename T2>
-class CallbackImpl<R,T1,T2,empty,empty,empty> : public CallbackImplBase {
+class CallbackImpl<R,T1,T2,empty,empty,empty,empty> : public CallbackImplBase {
 public:
   virtual ~CallbackImpl () {}
   virtual R operator() (T1, T2) = 0;
 };
 // define CallbackImpl for 3 params
 template <typename R, typename T1, typename T2, typename T3>
-class CallbackImpl<R,T1,T2,T3,empty,empty> : public CallbackImplBase {
+class CallbackImpl<R,T1,T2,T3,empty,empty,empty> : public CallbackImplBase {
 public:
   virtual ~CallbackImpl () {}
   virtual R operator() (T1, T2, T3) = 0;
 };
 // define CallbackImpl for 4 params
 template <typename R, typename T1, typename T2, typename T3, typename T4>
-class CallbackImpl<R,T1,T2,T3,T4,empty> : public CallbackImplBase {
+class CallbackImpl<R,T1,T2,T3,T4,empty,empty> : public CallbackImplBase {
 public:
   virtual ~CallbackImpl () {}
   virtual R operator() (T1, T2, T3, T4) = 0;
 };
 // define CallbackImpl for 5 params
 template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
-class CallbackImpl : public CallbackImplBase {
+class CallbackImpl<R,T1,T2,T3,T4,T5,empty> : public CallbackImplBase {
 public:
   virtual ~CallbackImpl () {}
   virtual R operator() (T1, T2, T3, T4, T5) = 0;
 };
+// define CallbackImpl for 6 params
+  template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
+class CallbackImpl : public CallbackImplBase {
+public:
+  virtual ~CallbackImpl () {}
+  virtual R operator() (T1, T2, T3, T4, T5, T6) = 0;
+};
 
 
 // an impl for Functors:
-template <typename T, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
-class FunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> {
+template <typename T, typename R, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6>
+class FunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,T6> {
 public:
   FunctorCallbackImpl (T const &functor)
     : m_functor (functor) {}
@@ -160,9 +168,12 @@
   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
       return m_functor (a1,a2,a3,a4,a5);
   }
+  R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) {
+    return m_functor (a1,a2,a3,a4,a5,a6);
+  }
   virtual bool IsEqual (CallbackImplBase const *other) const {
-    FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5> const *otherDerived = 
-      dynamic_cast<FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5> const *> (other);
+    FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5,T6> const *otherDerived = 
+      dynamic_cast<FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5,T6> const *> (other);
     if (otherDerived == 0)
       {
         return false;
@@ -178,8 +189,8 @@
 };
 
 // an impl for pointer to member functions
-template <typename OBJ_PTR, typename MEM_PTR, typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
-class MemPtrCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> {
+template <typename OBJ_PTR, typename MEM_PTR, typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
+class MemPtrCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,T6> {
 public:
   MemPtrCallbackImpl (OBJ_PTR const&objPtr, MEM_PTR mem_ptr)
     : m_objPtr (objPtr), m_memPtr (mem_ptr) {}
@@ -202,9 +213,12 @@
   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3, a4, a5);
   }
+  R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) {
+    return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3, a4, a5, a6);
+  }
   virtual bool IsEqual (CallbackImplBase const *other) const {
-    MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> const *otherDerived = 
-      dynamic_cast<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> const *> (other);
+    MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5,T6> const *otherDerived = 
+      dynamic_cast<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5,T6> const *> (other);
     if (otherDerived == 0)
       {
         return false;
@@ -260,22 +274,22 @@
 template<typename R, 
    typename T1 = empty, typename T2 = empty, 
    typename T3 = empty, typename T4 = empty,
-   typename T5 = empty>
+   typename T5 = empty, typename T6 = empty>
 class Callback : public CallbackBase {
 public:
   // There are two dummy args below to ensure that this constructor is
   // always properly disambiguited by the c++ compiler
   template <typename FUNCTOR>
   Callback (FUNCTOR const &functor, bool, bool) 
-      : m_impl (Create<FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5> > (functor))
+    : m_impl (Create<FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5,T6> > (functor))
   {}
 
   template <typename OBJ_PTR, typename MEM_PTR>
   Callback (OBJ_PTR const &objPtr, MEM_PTR mem_ptr)
-      : m_impl (Create<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> > (objPtr, mem_ptr))
+    : m_impl (Create<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5,T6> > (objPtr, mem_ptr))
   {}
 
-  Callback (Ptr<CallbackImpl<R,T1,T2,T3,T4,T5> > const &impl)
+  Callback (Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,T6> > const &impl)
       : m_impl (impl)
   {}
 
@@ -305,14 +319,17 @@
   R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5) const {
     return (*(PeekImpl ())) (a1,a2,a3,a4,a5);
   }
+  R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5,T6 a6) const {
+    return (*(PeekImpl ())) (a1,a2,a3,a4,a5,a6);
+  }
 
-  bool IsEqual (CallbackBase const &other) {
+  bool IsEqual (CallbackBase const &other) const {
     return PeekImpl ()->IsEqual (other.PeekImpl ());
   }
 
-  bool CheckType (CallbackBase const& other) {
+  bool CheckType (CallbackBase const& other) const {
     CallbackImplBase *otherBase = other.PeekImpl ();
-    if (dynamic_cast<CallbackImpl<R,T1,T2,T3,T4,T5> *> (otherBase) != 0)
+    if (dynamic_cast<CallbackImpl<R,T1,T2,T3,T4,T5,T6> *> (otherBase) != 0)
       {
         return true;
       }
@@ -328,27 +345,27 @@
                         " got=" << typeid (other).name () << 
                         ", expected=" << typeid (*this).name ());
       }
-    const Callback<R, T1,T2,T3,T4,T5> *goodType = static_cast<const Callback<R,T1,T2,T3,T4,T5> *> (&other);
+    const Callback<R, T1,T2,T3,T4,T5,T6> *goodType = static_cast<const Callback<R,T1,T2,T3,T4,T5,T6> *> (&other);
     *this = *goodType;
   }
   void Assign (Ptr<CallbackImplBase> other) {
-    CallbackImpl<R,T1,T2,T3,T4,T5> *impl = dynamic_cast<CallbackImpl<R,T1,T2,T3,T4,T5> *> (PeekPointer (other));
+    CallbackImpl<R,T1,T2,T3,T4,T5,T6> *impl = dynamic_cast<CallbackImpl<R,T1,T2,T3,T4,T5,T6> *> (PeekPointer (other));
     if (other == 0)
       {
         NS_FATAL_ERROR ("Incompatible types. (feed to \"c++filt -t\")"
                         " got=" << typeid (other).name () << 
                         ", expected=" << typeid (*impl).name ());
       }
-    *this = Callback<R,T1,T2,T3,T4,T5> (impl);
+    *this = Callback<R,T1,T2,T3,T4,T5,T6> (impl);
   }
   virtual Ptr<CallbackImplBase>GetImpl (void) const {
     return m_impl;
   }
 private:
-  virtual CallbackImpl<R,T1,T2,T3,T4,T5> *PeekImpl (void) const {
+  virtual CallbackImpl<R,T1,T2,T3,T4,T5,T6> *PeekImpl (void) const {
     return PeekPointer (m_impl);
   }
-  Ptr<CallbackImpl<R,T1,T2,T3,T4,T5> > m_impl;
+  Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,T6> > m_impl;
 };
 
 /**
@@ -369,7 +386,7 @@
   return Callback<R> (objPtr, memPtr);
 }
 template <typename T, typename OBJ, typename R>
-Callback<R> MakeCallback (R (T::*mem_ptr) () const, OBJ const objPtr) {
+Callback<R> MakeCallback (R (T::*mem_ptr) () const, OBJ objPtr) {
   return Callback<R> (objPtr, mem_ptr);
 }
 /**
@@ -381,11 +398,11 @@
  * and potentially return a value.
  */
 template <typename T, typename OBJ, typename R, typename T1>
-Callback<R,T1> MakeCallback (R (T::*mem_ptr) (T1), OBJ *const objPtr) {
+Callback<R,T1> MakeCallback (R (T::*mem_ptr) (T1), OBJ objPtr) {
   return Callback<R,T1> (objPtr, mem_ptr);
 }
 template <typename T, typename OBJ, typename R, typename T1>
-Callback<R,T1> MakeCallback (R (T::*mem_ptr) (T1) const, OBJ const *const objPtr) {
+Callback<R,T1> MakeCallback (R (T::*mem_ptr) (T1) const, OBJ objPtr) {
   return Callback<R,T1> (objPtr, mem_ptr);
 }
 /**
@@ -397,11 +414,11 @@
  * and potentially return a value.
  */
 template <typename T, typename OBJ, typename R, typename T1, typename T2>
-Callback<R,T1,T2> MakeCallback (R (T::*mem_ptr) (T1,T2), OBJ *const objPtr) {
+Callback<R,T1,T2> MakeCallback (R (T::*mem_ptr) (T1,T2), OBJ objPtr) {
   return Callback<R,T1,T2> (objPtr, mem_ptr);
 }
 template <typename T, typename OBJ, typename R, typename T1, typename T2>
-Callback<R,T1,T2> MakeCallback (R (T::*mem_ptr) (T1,T2) const, OBJ const*const objPtr) {
+Callback<R,T1,T2> MakeCallback (R (T::*mem_ptr) (T1,T2) const, OBJ objPtr) {
   return Callback<R,T1,T2> (objPtr, mem_ptr);
 }
 /**
@@ -413,11 +430,11 @@
  * and potentially return a value.
  */
 template <typename T, typename OBJ, typename R, typename T1,typename T2, typename T3>
-Callback<R,T1,T2,T3> MakeCallback (R (T::*mem_ptr) (T1,T2,T3), OBJ *const objPtr) {
+Callback<R,T1,T2,T3> MakeCallback (R (T::*mem_ptr) (T1,T2,T3), OBJ objPtr) {
   return Callback<R,T1,T2,T3> (objPtr, mem_ptr);
 }
 template <typename T, typename OBJ, typename R, typename T1,typename T2, typename T3>
-Callback<R,T1,T2,T3> MakeCallback (R (T::*mem_ptr) (T1,T2,T3) const, OBJ const*const objPtr) {
+Callback<R,T1,T2,T3> MakeCallback (R (T::*mem_ptr) (T1,T2,T3) const, OBJ objPtr) {
   return Callback<R,T1,T2,T3> (objPtr, mem_ptr);
 }
 /**
@@ -429,11 +446,11 @@
  * and potentially return a value.
  */
 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4>
-Callback<R,T1,T2,T3,T4> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4), OBJ *const objPtr) {
+Callback<R,T1,T2,T3,T4> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4), OBJ objPtr) {
   return Callback<R,T1,T2,T3,T4> (objPtr, mem_ptr);
 }
 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4>
-Callback<R,T1,T2,T3,T4> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4) const, OBJ const*const objPtr) {
+Callback<R,T1,T2,T3,T4> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4) const, OBJ objPtr) {
   return Callback<R,T1,T2,T3,T4> (objPtr, mem_ptr);
 }
 /**
@@ -445,13 +462,29 @@
  * and potentially return a value.
  */
 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
-Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5), OBJ *const objPtr) {
+Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5), OBJ objPtr) {
   return Callback<R,T1,T2,T3,T4,T5> (objPtr, mem_ptr);
 }
 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
-Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5) const, OBJ const*const objPtr) {
+Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5) const, OBJ objPtr) {
   return Callback<R,T1,T2,T3,T4,T5> (objPtr, mem_ptr);
 }
+/**
+ * \ingroup MakeCallback
+ * \param mem_ptr class method member pointer
+ * \param objPtr class instance
+ * \return a wrapper Callback
+ * Build Callbacks for class method members which takes five arguments
+ * and potentially return a value.
+ */
+template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5,typename T6>
+Callback<R,T1,T2,T3,T4,T5,T6> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5,T6), OBJ objPtr) {
+  return Callback<R,T1,T2,T3,T4,T5,T6> (objPtr, mem_ptr);
+}
+template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6>
+Callback<R,T1,T2,T3,T4,T5,T6> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5,T6) const, OBJ objPtr) {
+  return Callback<R,T1,T2,T3,T4,T5,T6> (objPtr, mem_ptr);
+}
 
 /**
  * \ingroup MakeCallback
@@ -519,6 +552,17 @@
 Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (*fnPtr) (T1,T2,T3,T4,T5)) {
   return Callback<R,T1,T2,T3,T4,T5> (fnPtr, true, true);
 }
+/**
+ * \ingroup MakeCallback
+ * \param fnPtr function pointer
+ * \return a wrapper Callback
+ * Build Callbacks for functions which takes five arguments
+ * and potentially return a value.
+ */
+template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5,typename T6>
+Callback<R,T1,T2,T3,T4,T5,T6> MakeCallback (R (*fnPtr) (T1,T2,T3,T4,T5,T6)) {
+  return Callback<R,T1,T2,T3,T4,T5,T6> (fnPtr, true, true);
+}
 
 
 
@@ -587,6 +631,17 @@
 Callback<R,T1,T2,T3,T4,T5> MakeNullCallback (void) {
   return Callback<R,T1,T2,T3,T4,T5> ();
 }
+/**
+ * \ingroup MakeCallback
+ * \overload Callback<R> MakeNullCallback (void)
+ * \return a wrapper Callback
+ * Build a null callback which takes five arguments
+ * and potentially return a value.
+ */
+template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5,typename T6>
+Callback<R,T1,T2,T3,T4,T5,T6> MakeNullCallback (void) {
+  return Callback<R,T1,T2,T3,T4,T5,T6> ();
+}
 
 
 /*
@@ -596,9 +651,10 @@
  */
 // an impl for Bound Functors:
 template <typename T, typename R, typename TX, typename T1, typename T2, typename T3, typename T4,typename T5>
-class BoundFunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> {
+class BoundFunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,empty> {
 public:
-  BoundFunctorCallbackImpl (T const &functor, TX a)
+  template <typename FUNCTOR, typename ARG>
+  BoundFunctorCallbackImpl (FUNCTOR functor, ARG a)
       : m_functor (functor), m_a (a) {}
   virtual ~BoundFunctorCallbackImpl () {}
   R operator() (void) {
@@ -635,38 +691,48 @@
   }
 private:
   T m_functor;
-  TX m_a;
+  typename TypeTraits<TX>::ReferencedType m_a;
 };
 
-template <typename R, typename TX>
-Callback<R> MakeBoundCallback (R (*fnPtr) (TX), TX a) {
-  Ptr<CallbackImpl<R,empty,empty,empty,empty,empty> > impl =
+template <typename R, typename TX, typename ARG>
+Callback<R> MakeBoundCallback (R (*fnPtr) (TX), ARG a) {
+  Ptr<CallbackImpl<R,empty,empty,empty,empty,empty,empty> > impl =
     Create<BoundFunctorCallbackImpl<R (*) (TX),R,TX,empty,empty,empty,empty,empty> >(fnPtr, a);
   return Callback<R> (impl);
 }
 
-template <typename R, typename TX, typename T1>
-Callback<R,T1> MakeBoundCallback (R (*fnPtr) (TX,T1), TX a) {
-  Ptr<CallbackImpl<R,T1,empty,empty,empty,empty> > impl =
+template <typename R, typename TX, typename ARG, 
+          typename T1>
+Callback<R,T1> MakeBoundCallback (R (*fnPtr) (TX,T1), ARG a) {
+  Ptr<CallbackImpl<R,T1,empty,empty,empty,empty,empty> > impl =
     Create<BoundFunctorCallbackImpl<R (*) (TX,T1),R,TX,T1,empty,empty,empty,empty> > (fnPtr, a);
   return Callback<R,T1> (impl);
 }
-template <typename R, typename TX, typename T1, typename T2>
-Callback<R,T1,T2> MakeBoundCallback (R (*fnPtr) (TX,T1,T2), TX a) {
-  Ptr<CallbackImpl<R,T1,T2,empty,empty,empty> > impl =
+template <typename R, typename TX, typename ARG, 
+          typename T1, typename T2>
+Callback<R,T1,T2> MakeBoundCallback (R (*fnPtr) (TX,T1,T2), ARG a) {
+  Ptr<CallbackImpl<R,T1,T2,empty,empty,empty,empty> > impl =
     Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2),R,TX,T1,T2,empty,empty,empty> > (fnPtr, a);
   return Callback<R,T1,T2> (impl);
 }
-template <typename R, typename TX, typename T1, typename T2,typename T3,typename T4>
-Callback<R,T1,T2,T3,T4> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4), TX a) {
-  Ptr<CallbackImpl<R,T1,T2,T3,T4,empty> > impl =
+template <typename R, typename TX, typename ARG,
+          typename T1, typename T2,typename T3>
+Callback<R,T1,T2,T3> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3), ARG a) {
+  Ptr<CallbackImpl<R,T1,T2,T3,empty,empty,empty> > impl =
+    Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3),R,TX,T1,T2,T3,empty,empty> > (fnPtr, a);
+  return Callback<R,T1,T2,T3> (impl);
+}
+template <typename R, typename TX, typename ARG,
+          typename T1, typename T2,typename T3,typename T4>
+Callback<R,T1,T2,T3,T4> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4), ARG a) {
+  Ptr<CallbackImpl<R,T1,T2,T3,T4,empty,empty> > impl =
     Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4),R,TX,T1,T2,T3,T4,empty> > (fnPtr, a);
   return Callback<R,T1,T2,T3,T4> (impl);
 }
-
-template <typename R, typename TX, typename T1, typename T2,typename T3,typename T4,typename T5>
-Callback<R,T1,T2,T3,T4,T5> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5), TX a) {
-  Ptr<CallbackImpl<R,T1,T2,T3,T4,T5> > impl =
+template <typename R, typename TX, typename ARG,
+          typename T1, typename T2,typename T3,typename T4,typename T5>
+Callback<R,T1,T2,T3,T4,T5> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5), ARG a) {
+  Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,empty> > impl =
     Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5),R,TX,T1,T2,T3,T4,T5> > (fnPtr, a);
   return Callback<R,T1,T2,T3,T4,T5> (impl);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/composite-trace-resolver.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,595 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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 "composite-trace-resolver.h"
+#include "debug.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("CompositeTraceResolver");
+
+namespace ns3 {
+
+CompositeTraceResolver::CompositeTraceResolver ()
+{}
+
+CompositeTraceResolver::~CompositeTraceResolver ()
+{
+  for (TraceItems::iterator i = m_items.begin (); i != m_items.end (); i++)
+    {
+      delete *i;
+    }
+  m_items.clear ();
+}
+
+void 
+CompositeTraceResolver::AddItem (ResolveItem *item)
+{
+  m_items.push_back (item);
+}
+
+void 
+CompositeTraceResolver::Add (std::string name, 
+                             Callback<Ptr<TraceResolver> > createResolver)
+{
+  class MakerResolveItem : public ResolveItem
+  {
+  public:
+    virtual void Connect (std::string subpath, const CallbackBase &cb, const TraceContext &context)
+    {maker ()->Connect (subpath, cb, context);}
+    virtual void Disconnect (std::string subpath, const CallbackBase &cb)
+    {maker ()->Disconnect (subpath, cb);}
+    virtual void CollectSources (std::string path, const TraceContext &context, 
+                                 SourceCollection *collection)
+    {
+      path.append ("/");
+      path.append (this->name);
+      TraceContext ctx = context;
+      ctx.Union (this->context);
+      this->maker ()->CollectSources (path, ctx, collection);
+    }
+    virtual void TraceAll (std::ostream &os, const TraceContext &context)
+    {
+      TraceContext ctx = context;
+      ctx.Union (this->context);
+      this->maker ()->TraceAll (os, ctx);
+    }
+    Callback<Ptr<TraceResolver> > maker;
+  } *item = new MakerResolveItem ();
+  item->name = name;
+  item->context = TraceContext ();
+  item->maker = createResolver;
+  AddItem (item);
+}
+
+void 
+CompositeTraceResolver::AddSource (std::string name,
+                                   const TraceDoc &doc,
+                                   const TraceSource &trace)
+{
+  DoAddSource (name, doc, trace, TraceContext ());
+}
+
+void 
+CompositeTraceResolver::DoAddSource (std::string name,
+                                     const TraceDoc &doc,
+                                     const TraceSource &trace, 
+                                     const TraceContext &context)
+{
+  class SourceResolveItem : public ResolveItem
+  {
+  public:
+    virtual void Connect (std::string subpath, const CallbackBase &cb, const TraceContext &context)
+    {if (subpath == "") {trace->AddCallback (cb, context);}}
+    virtual void Disconnect (std::string subpath, const CallbackBase &cb)
+    {if (subpath == "") {trace->RemoveCallback (cb);}}
+    virtual void CollectSources (std::string path, const TraceContext &context, 
+                                 SourceCollection *collection)
+    {
+      path.append ("/");
+      path.append (this->name);
+      TraceContext ctx = context;
+      ctx.Union (this->context);
+      collection->AddUnique (path, ctx, this->doc);
+    }
+    virtual void TraceAll (std::ostream &os, const TraceContext &context)
+    {
+      TraceContext ctx = context;
+      ctx.Union (this->context);
+      this->trace->ConnectPrinter (os, ctx);
+    }
+    TraceSource *trace;
+    TraceDoc doc;
+  } *item = new SourceResolveItem ();
+  item->name = name;
+  item->context = context;
+  item->trace = const_cast<TraceSource *> (&trace);
+  item->doc = doc;
+  AddItem (item);
+}
+
+
+
+
+void 
+CompositeTraceResolver::AddComposite (std::string name, Ptr<Object> composite)
+{
+  DoAddComposite (name, composite, TraceContext ());
+}
+void 
+CompositeTraceResolver::DoAddComposite (std::string name, Ptr<Object> composite, const TraceContext &context)
+{
+  class CompositeResolveItem : public ResolveItem
+  {
+  public:
+    virtual void Connect (std::string subpath, const CallbackBase &cb, const TraceContext &context)
+    {composite->GetTraceResolver ()->Connect (subpath, cb, context);}
+    virtual void Disconnect (std::string subpath, const CallbackBase &cb)
+    {composite->TraceDisconnect (subpath, cb);}
+    virtual void CollectSources (std::string path, const TraceContext &context, 
+                                 SourceCollection *collection)
+    {
+      path.append ("/");
+      path.append (this->name);
+      TraceContext ctx = context;
+      ctx.Union (this->context);
+      this->composite->GetTraceResolver ()->CollectSources (path, ctx, collection);
+    }
+    virtual void TraceAll (std::ostream &os, const TraceContext &context)
+    {
+      TraceContext ctx = context;
+      ctx.Union (this->context);
+      this->composite->GetTraceResolver ()->TraceAll (os, ctx);
+    }
+
+    Ptr<Object> composite;
+  } *item = new CompositeResolveItem ();
+  item->name = name;
+  item->context = context;
+  item->composite = composite;
+  AddItem (item);
+}
+
+void
+CompositeTraceResolver::SetParentResolver (Ptr<TraceResolver> resolver)
+{
+  m_parent = resolver;
+}
+
+void 
+CompositeTraceResolver::Connect (std::string path, CallbackBase const &cb, const TraceContext &context)
+{
+  NS_DEBUG ("connect path="<<path);
+  class ConnectOperation : public Operation
+  {
+  public:
+    ConnectOperation (const CallbackBase &cb, const TraceContext &context)
+      : m_cb (cb), m_context (context)
+    {}
+    virtual void Do (std::string subpath, ResolveItem *item) const
+    {
+      NS_DEBUG ("connect to path="<<subpath<<" name="<<item->name);
+      TraceContext context = m_context;
+      context.Union (item->context);
+      item->Connect (subpath, m_cb, context);
+    }
+    virtual void DoParent (std::string path, Ptr<TraceResolver> parent) const
+    {
+      if (parent != 0)
+        {
+          parent->Connect (path, m_cb, m_context);
+        }
+    }
+  private:
+    const CallbackBase &m_cb;
+    const TraceContext &m_context;
+  } operation  = ConnectOperation (cb, context);
+  DoRecursiveOperation (path, operation);
+}
+void 
+CompositeTraceResolver::DoRecursiveOperation (std::string path, 
+                                              const Operation &operation)
+{
+  if (path == "")
+    {
+      return;
+    }
+  std::string id = GetElement (path);
+  std::string subpath = GetSubpath (path);
+
+  if (id == "*")
+    {
+      for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
+	{
+          operation.Do (subpath, *i);
+        }
+      operation.DoParent (path, m_parent);
+      return;
+    }
+  std::string::size_type start, end;
+  start = id.find_first_of ("(", 0);
+  end = id.find_first_of (")", 0);
+  if (start != 0 || end != (id.size ()-1))
+    {
+      for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
+	{
+	  if ((*i)->name == id)
+	    {
+              operation.Do (subpath, *i);
+              operation.DoParent (path, m_parent);
+              return;
+	    }
+	}
+    }
+  std::list<std::string> names;
+  std::string alternatives = std::string (id, start+1, end-1);
+  std::string::size_type next_pos, cur_pos;
+  next_pos = 0;
+  cur_pos = 0;
+  while (true)
+    {
+      std::string element;
+      next_pos = alternatives.find ("|", cur_pos);
+      if (next_pos == std::string::npos)
+	{
+	  element = std::string (alternatives, cur_pos, alternatives.size ());
+	  names.push_back (element);
+	  break;
+	}
+      element = std::string (alternatives, cur_pos, next_pos);
+      names.push_back (element);
+      cur_pos = next_pos + 1;
+    }
+  for (std::list<std::string>::const_iterator i = names.begin (); i != names.end (); i++)
+    {
+      for (TraceItems::const_iterator j = m_items.begin (); j != m_items.end (); j++)
+	{
+	  if ((*j)->name == *i)
+	    {
+              operation.Do (subpath, *j);
+	      break;
+	    }
+	}
+    }
+  operation.DoParent (path, m_parent);
+}
+
+void 
+CompositeTraceResolver::Disconnect (std::string path, CallbackBase const &cb)
+{
+  NS_DEBUG ("disconnect path="<<path);
+  class DisconnectOperation : public Operation
+  {
+  public:
+    DisconnectOperation (const CallbackBase &cb)
+      : m_cb (cb)
+    {}
+    virtual void Do (std::string subpath, ResolveItem *item) const
+    {
+      NS_DEBUG ("disconnect from path="<<subpath<<" name="<<item->name);
+      item->Disconnect (subpath, m_cb);
+    }
+    virtual void DoParent (std::string path, Ptr<TraceResolver> parent) const
+    {
+      if (parent != 0)
+        {
+          parent->Disconnect (path, m_cb);
+        }
+    }
+  private:
+    const CallbackBase &m_cb;
+  } operation  = DisconnectOperation (cb);
+  DoRecursiveOperation (path, operation);
+}
+
+void 
+CompositeTraceResolver::CollectSources (std::string path, const TraceContext &context, 
+                                        SourceCollection *collection)
+{
+  for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
+    {
+      NS_DEBUG ("print " << (*i)->name);
+      (*i)->CollectSources (path, context, collection);
+    }
+  if (m_parent != 0)
+    {
+      m_parent->CollectSources (path, context, collection);
+    }
+}
+void 
+CompositeTraceResolver::TraceAll (std::ostream &os, const TraceContext &context)
+{
+  for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
+    {
+      NS_DEBUG ("print " << (*i)->name);
+      (*i)->TraceAll (os, context);
+    }
+  if (m_parent != 0)
+    {
+      m_parent->TraceAll (os, context);
+    }  
+}
+
+
+}//namespace ns3
+
+#ifdef RUN_SELF_TESTS
+
+#include "test.h"
+#include "trace-context-element.h"
+
+namespace ns3 {
+
+class TraceSourceTest : public TraceContextElement
+{
+public:
+  enum Sources {
+    DOUBLEA,
+    DOUBLEB,
+    UINT16_T
+  };
+  static uint16_t GetUid (void) 
+  {static uint16_t uid = AllocateUid<TraceSourceTest> ("TraceSourceTest"); return uid;}
+  void Print (std::ostream &os)
+  {os << "tracesource=";
+    if (m_sources == DOUBLEA) {os << "doubleA";}
+    else if (m_sources == DOUBLEB) {os << "doubleB";}
+    else if (m_sources == UINT16_T) {os << "uint16_t";}
+  }
+  std::string GetTypeName (void) {return "ns3::TraceSourceTest";}
+  TraceSourceTest () : m_sources (TraceSourceTest::DOUBLEA) {}
+  TraceSourceTest (enum Sources sources) :m_sources (sources) {}
+  bool IsDoubleA (void) const {return m_sources == TraceSourceTest::DOUBLEA;}
+  bool IsDoubleB (void) const {return m_sources == TraceSourceTest::DOUBLEB;}
+  bool IsUint16 (void) const {return m_sources == TraceSourceTest::UINT16_T;}
+private:
+  enum TraceSourceTest::Sources m_sources;
+};
+
+class SubTraceSourceTest : public TraceContextElement
+{
+public:
+  enum Sources {
+    INT,
+  };
+  static uint16_t GetUid (void) 
+  {static uint16_t uid = AllocateUid<SubTraceSourceTest> ("SubTraceSourceTest"); return uid;}
+  void Print (std::ostream &os)
+  {os << "subtracesource=int";}
+  std::string GetTypeName (void) const {return "ns3::SubTraceSourceTest";}
+  SubTraceSourceTest () : m_sources (SubTraceSourceTest::INT) {}
+  SubTraceSourceTest (enum Sources sources) : m_sources (sources) {}
+private:
+  enum Sources m_sources;
+};
+
+class CompositeTraceResolverTest : public Test
+{
+public:
+  CompositeTraceResolverTest ();
+  virtual ~CompositeTraceResolverTest ();
+  virtual bool RunTests (void);
+private:
+  void TraceDouble (TraceContext const &context, double v);
+  void TraceInt (TraceContext const &context, int v);
+  Ptr<TraceResolver> CreateSubResolver ();
+
+
+  bool m_gotDoubleA;
+  bool m_gotDoubleB;
+  CallbackTraceSource<int> m_traceInt;
+  bool m_gotInt;
+};
+
+CompositeTraceResolverTest::CompositeTraceResolverTest ()
+  : Test ("CompositeTraceResolver")
+{}
+CompositeTraceResolverTest::~CompositeTraceResolverTest ()
+{}
+void 
+CompositeTraceResolverTest::TraceDouble (TraceContext const &context, double v)
+{
+  TraceSourceTest source;
+  context.GetElement (source);
+  if (source.IsDoubleA ())
+    {
+      m_gotDoubleA = true;
+    }
+  else if (source.IsDoubleB ())
+    {
+      m_gotDoubleB = true;
+    }
+  else
+    {
+      NS_FATAL_ERROR ("should not get any other trace source in this sink");
+    }
+  
+}
+
+void 
+CompositeTraceResolverTest::TraceInt (TraceContext const &context, int v)
+{
+  m_gotInt = true;
+}
+
+Ptr<TraceResolver>
+CompositeTraceResolverTest::CreateSubResolver (void)
+{
+  Ptr<CompositeTraceResolver> subresolver = Create<CompositeTraceResolver> ();
+  subresolver->AddSource ("trace-int", TraceDoc ("test source"), m_traceInt, 
+                          SubTraceSourceTest (SubTraceSourceTest::INT));
+  return subresolver;
+}
+bool 
+CompositeTraceResolverTest::RunTests (void)
+{
+  bool ok = true;
+
+  CallbackTraceSource<double> traceDoubleA;
+  CallbackTraceSource<double> traceDoubleB;
+  TraceContext context;
+
+  CompositeTraceResolver resolver;
+
+  resolver.AddSource ("trace-double-a", TraceDoc ("test source"), traceDoubleA, 
+                      TraceSourceTest (TraceSourceTest::DOUBLEA));
+  resolver.AddSource ("trace-double-b", TraceDoc ("test source"), traceDoubleB, 
+                      TraceSourceTest (TraceSourceTest::DOUBLEB));
+
+  resolver.Connect ("/*", MakeCallback (&CompositeTraceResolverTest::TraceDouble, this), TraceContext ());
+
+  m_gotDoubleA = false;
+  m_gotDoubleB = false;
+  traceDoubleA (0);
+  if (!m_gotDoubleA || m_gotDoubleB)
+    {
+      ok = false;
+    }
+  m_gotDoubleA = false;
+  traceDoubleA (0);
+  traceDoubleB (0);
+  if (!m_gotDoubleA || !m_gotDoubleB)
+    {
+      ok = false;
+    }
+  m_gotDoubleA = false;
+  m_gotDoubleB = false;
+
+  resolver.Disconnect ("/*", MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+
+  m_gotDoubleA = false;
+  m_gotDoubleB = false;
+  traceDoubleA (0);
+  traceDoubleB (0);
+  if (m_gotDoubleA || m_gotDoubleB)
+    {
+      ok = false;
+    }
+
+  resolver.Connect ("/trace-double-a", 
+		    MakeCallback (&CompositeTraceResolverTest::TraceDouble, this), TraceContext ());
+  m_gotDoubleA = false;
+  m_gotDoubleB = false;
+  traceDoubleA (0);
+  traceDoubleB (0);
+  if (!m_gotDoubleA || m_gotDoubleB)
+    {
+      ok = false;
+    }
+  resolver.Disconnect ("/trace-double-a", 
+		       MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+
+  resolver.Connect ("/(trace-double-a)", 
+		    MakeCallback (&CompositeTraceResolverTest::TraceDouble, this), TraceContext ());
+  m_gotDoubleA = false;
+  m_gotDoubleB = false;
+  traceDoubleA (0);
+  traceDoubleB (0);
+  if (!m_gotDoubleA || m_gotDoubleB)
+    {
+      ok = false;
+    }
+  resolver.Disconnect ("/trace-double-a", 
+		       MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+
+  resolver.Connect ("/(trace-double-a|trace-double-b)", 
+		    MakeCallback (&CompositeTraceResolverTest::TraceDouble, this), TraceContext ());
+  m_gotDoubleA = false;
+  m_gotDoubleB = false;
+  traceDoubleA (0);
+  traceDoubleB (0);
+  if (!m_gotDoubleA || !m_gotDoubleB)
+    {
+      ok = false;
+    }
+  resolver.Disconnect ("/trace-double-a", 
+		       MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+  m_gotDoubleA = false;
+  m_gotDoubleB = false;
+  traceDoubleA (0);
+  traceDoubleB (0);
+  if (m_gotDoubleA || !m_gotDoubleB)
+    {
+      ok = false;
+    }
+
+
+  resolver.Disconnect ("/(trace-double-a|trace-double-b)", 
+		       MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+  m_gotDoubleA = false;
+  m_gotDoubleB = false;
+  traceDoubleA (0);
+  traceDoubleB (0);
+  if (m_gotDoubleA || m_gotDoubleB)
+    {
+      ok = false;
+    }
+
+  resolver.Add ("subresolver", 
+                MakeCallback (&CompositeTraceResolverTest::CreateSubResolver, this));
+
+  resolver.Connect ("/subresolver/trace-int", 
+		    MakeCallback (&CompositeTraceResolverTest::TraceInt, this), TraceContext ());
+  m_gotInt = false;
+  m_traceInt (1);
+  if (!m_gotInt)
+    {
+      ok = false;
+    }
+
+  resolver.Disconnect ("/subresolver/trace-int", 
+		       MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
+  m_gotInt = false;
+  m_traceInt (1);
+  if (m_gotInt)
+    {
+      ok = false;
+    }
+
+  resolver.Connect ("/*/trace-int", 
+		    MakeCallback (&CompositeTraceResolverTest::TraceInt, this), TraceContext ());
+  m_gotInt = false;
+  m_traceInt (1);
+  if (!m_gotInt)
+    {
+      ok = false;
+    }
+
+  resolver.Disconnect ("/subresolver/trace-int", 
+		       MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
+  m_gotInt = false;
+  m_traceInt (1);
+  if (m_gotInt)
+    {
+      ok = false;
+    }
+
+  SVTraceSource<uint16_t> source;
+
+  resolver.AddSource ("uint16_t", TraceDoc ("test source"), source, TraceSourceTest (TraceSourceTest::UINT16_T));
+  
+
+  return ok;
+}
+
+static CompositeTraceResolverTest g_compositeTraceResolverTest;
+
+}//namespace ns3
+
+
+#endif /* RUN_SELF_TESTS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/composite-trace-resolver.h	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,233 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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 COMPOSITE_TRACE_RESOLVER_H
+#define COMPOSITE_TRACE_RESOLVER_H
+
+#include <vector>
+#include "callback.h"
+#include "ptr.h"
+#include "trace-resolver.h"
+#include "callback-trace-source.h"
+#include "uv-trace-source.h"
+#include "sv-trace-source.h"
+#include "fv-trace-source.h"
+#include "array-trace-resolver.h"
+#include "trace-doc.h"
+
+namespace ns3 {
+
+/**
+ * \brief a helper class to aggregate contained TraceResolver and other trace sources.
+ * \ingroup tracing
+ */
+class CompositeTraceResolver : public TraceResolver
+{
+public:
+  CompositeTraceResolver ();
+  virtual ~CompositeTraceResolver ();
+  /**
+   * \param name name of trace source
+   * \param doc the documentation associated to this trace source
+   * \param trace a callback trace source
+   * \param context the context associated to this trace source
+   *
+   * Add a callback trace source in this resolver. This trace
+   * source will match the name specified during namespace 
+   * resolution. The TraceContext of this trace source will also
+   * be automatically extended to contain the input context.
+   */
+  template <typename T>
+  void AddSource (std::string name, const TraceDoc &doc,
+                  const TraceSource &trace, T const &context);
+  /**
+   * \param name name of trace source
+   * \param doc the documentation associated to this trace source
+   * \param trace a callback trace source
+   *
+   * Add a callback trace source in this resolver. This trace
+   * source will match the name specified during namespace 
+   * resolution.
+   */
+  void AddSource (std::string name,
+                  const TraceDoc &doc,
+                  const TraceSource &trace);
+
+  /**
+   * \param name the name of the composite element
+   * \param composite the composite object
+   *
+   * The input composite object will be used to resolve a connection
+   * of a disconnection attempt if its name matches the trace path.
+   * 
+   */
+  void AddComposite (std::string name, Ptr<Object> composite);
+
+  /**
+   * \param name the name of the composite element
+   * \param composite the composite object
+   * \param contextElement the context element associated to the composite
+   *
+   * The input composite object will be used to resolve a connection
+   * of a disconnection attempt if its name matches the trace path.
+   * The contextElement will be appended to the TraceContext during connection.
+   */
+  template <typename T>
+  void AddComposite (std::string name, Ptr<Object> composite, const T &contextElement);
+
+  /**
+   * \param name the name of the array
+   * \param begin an iterator which points to the first element of the array
+   * \param end an iterator which points to the last element of the array
+   * \param index an object which can store the index of an element in the
+   *        array. In practice, this object should support a constructor
+   *        whose single argument is an array index.
+   */
+  template <typename ITERATOR, typename INDEX>
+  void AddArray (std::string name, 
+                 ITERATOR begin, ITERATOR end, INDEX index);
+
+  /**
+   * \param parent the parent trace resolver
+   *
+   * The parent trace resolver is the trace resolver returned by the 
+   * GetTraceResolver method of the base class of the caller. It is 
+   * used during connection and disconnection to chain up the connect
+   * and disconnect calls to the parent.
+   */
+  void SetParentResolver (Ptr<TraceResolver> parent);
+
+
+private:
+  virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context);
+  virtual void Disconnect (std::string path, CallbackBase const &cb);
+  virtual void CollectSources (std::string path, const TraceContext &context, 
+                               SourceCollection *collection);
+  virtual void TraceAll (std::ostream &os, const TraceContext &context);
+  friend class CompositeTraceResolverTest;
+  class ResolveItem 
+  {
+  public:
+    virtual ~ResolveItem () {}
+    virtual void Connect (std::string subpath, const CallbackBase &cb, const TraceContext &context) = 0;
+    virtual void Disconnect (std::string subpath, const CallbackBase &cb) = 0;
+    virtual void CollectSources (std::string path, const TraceContext &context, 
+                                 SourceCollection *collection) = 0;
+    virtual void TraceAll (std::ostream &os, const TraceContext &context) = 0;
+
+    std::string name;
+    TraceContext context;
+  };
+  typedef std::vector<ResolveItem *> TraceItems;
+  class Operation
+  {
+  public:
+    virtual ~Operation () {}
+    virtual void Do (std::string subpath, ResolveItem *item) const = 0;
+    virtual void DoParent (std::string path, Ptr<TraceResolver> parent) const = 0;
+  };
+
+  void AddItem (ResolveItem *item);
+  void DoRecursiveOperation (std::string path, 
+                             const Operation &operation);
+  void DoRecursiveOperationForParent (std::string path, 
+                                      const Operation &operation);
+  void DoAddComposite (std::string name, Ptr<Object> composite, const TraceContext &context);
+  void DoAddSource (std::string name,
+                    const TraceDoc &doc,
+                    const TraceSource &trace,
+                    const TraceContext &context);
+  void Add (std::string name, 
+            Callback<Ptr<TraceResolver> > createResolver);
+
+
+  CompositeTraceResolver::TraceItems m_items;
+  Ptr<TraceResolver> m_parent;
+};
+
+}//namespace ns3
+
+namespace ns3 {
+
+
+
+template <typename T>
+void 
+CompositeTraceResolver::AddSource (std::string name,
+                                   const TraceDoc &doc,
+                                   const TraceSource &trace, 
+                                   T const &context)
+{
+  TraceContext ctx;
+  ctx.AddElement (context);
+  DoAddSource (name, doc, trace, ctx);  
+}
+
+template <typename ITERATOR, typename INDEX>
+void 
+CompositeTraceResolver::AddArray (std::string name, 
+                                  ITERATOR begin, ITERATOR end, INDEX index)
+{
+  class ArrayResolveItem : public ResolveItem
+  {
+  public:
+    virtual void Connect (std::string subpath, const CallbackBase &cb, const TraceContext &context)
+    {array->Connect (subpath, cb, context);}
+    virtual void Disconnect (std::string subpath, const CallbackBase &cb)
+    {array->Disconnect (subpath, cb);}
+    virtual void CollectSources (std::string path, const TraceContext &context, 
+                                 SourceCollection *collection)
+    {
+      path.append ("/");
+      path.append (this->name);
+      TraceContext ctx = context;
+      ctx.Union (this->context);
+      array->CollectSources (path, ctx, collection);
+    }
+    virtual void TraceAll (std::ostream &os, const TraceContext &context)
+    {
+      TraceContext ctx = context;
+      ctx.Union (this->context);
+      array->TraceAll (os, ctx);
+    }
+
+    Ptr<ArrayTraceResolver<INDEX> > array;
+  } *item = new ArrayResolveItem ();
+  item->name = name;
+  item->context = TraceContext ();
+  item->array = Create<ArrayTraceResolver<INDEX> > ();
+  item->array->SetIterators (begin, end);
+  AddItem (item);
+}
+
+template <typename T>
+void 
+CompositeTraceResolver::AddComposite (std::string name, Ptr<Object> composite, const T &contextElement)
+{
+  TraceContext context;
+  context.AddElement (contextElement);
+  DoAddComposite (name, composite, context);
+}
+
+
+
+}//namespace ns3
+
+#endif /* COMPOSITE_TRACE_RESOLVER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/fv-trace-source.h	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,71 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * 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 F_VARIABLE_TRACER_H
+#define F_VARIABLE_TRACER_H
+
+#include "callback-trace-source.h"
+#include "trace-source.h"
+#include <stdint.h>
+
+namespace ns3 {
+
+class FVTraceSourceBase : public TraceSource {
+public:
+  typedef CallbackTraceSource<double, double> ChangeNotifyCallback;
+
+  FVTraceSourceBase () {}
+  FVTraceSourceBase (FVTraceSourceBase const &o) {}
+  FVTraceSourceBase &operator = (FVTraceSourceBase const &o) {
+      return *this;
+  }
+
+  ~FVTraceSourceBase () {}
+
+  virtual void AddCallback (CallbackBase const & callback, TraceContext const & context) {
+    m_callback.AddCallback (callback, context);
+  }
+  virtual void RemoveCallback (CallbackBase const & callback) {
+    m_callback.RemoveCallback (callback);
+  }
+  virtual void ConnectPrinter (std::ostream &os, const TraceContext &context) {
+    m_callback.ConnectPrinter (os, context);
+  }
+protected:
+  void notify (double oldVal, double newVal) {
+      if (oldVal != newVal) 
+        {
+          m_callback (oldVal, newVal);
+        }
+  }
+private:
+  ChangeNotifyCallback m_callback;
+};
+
+template <typename T>
+class FVTraceSource : public FVTraceSourceBase 
+{
+public:
+};
+
+}; // namespace ns3
+
+#endif /* F_VARIABLE_TRACER_H */
--- a/src/core/object.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/core/object.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -22,8 +22,12 @@
 #include "assert.h"
 #include "singleton.h"
 #include "uid-manager.h"
+#include "trace-resolver.h"
+#include "debug.h"
 #include <vector>
 
+NS_DEBUG_COMPONENT_DEFINE ("Object");
+
 namespace {
 
 class IidManager : public ns3::UidManager
@@ -34,6 +38,7 @@
 public:
   void SetParent (uint16_t child, const uint16_t *parent);
   uint16_t LookupParent (uint16_t child);
+
 private:
   std::vector<const uint16_t *> m_parents;
 };
@@ -55,6 +60,68 @@
 
 namespace ns3 {
 
+class InterfaceIdTraceResolver : public TraceResolver
+{
+public:
+  InterfaceIdTraceResolver (Ptr<const Object> aggregate);
+  virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context);
+  virtual void Disconnect (std::string path, CallbackBase const &cb);
+  virtual void CollectSources (std::string path, const TraceContext &context, 
+                               SourceCollection *collection);
+  virtual void TraceAll (std::ostream &os, const TraceContext &context);
+private:
+  Ptr<const Object> ParseForInterface (std::string path);
+  Ptr<const Object> m_aggregate;
+};
+
+InterfaceIdTraceResolver::InterfaceIdTraceResolver (Ptr<const Object> aggregate)
+  : m_aggregate (aggregate)
+{}
+Ptr<const Object>
+InterfaceIdTraceResolver::ParseForInterface (std::string path)
+{
+  std::string element = GetElement (path);
+  std::string::size_type dollar_pos = element.find ("$");
+  if (dollar_pos != 0)
+    {
+      return 0;
+    }
+  std::string interfaceName = element.substr (1, std::string::npos);
+  InterfaceId interfaceId = InterfaceId::LookupByName (interfaceName);
+  Ptr<Object> interface = m_aggregate->QueryInterface<Object> (interfaceId);
+  return interface;
+}
+void 
+InterfaceIdTraceResolver::Connect (std::string path, CallbackBase const &cb, const TraceContext &context)
+{
+  Ptr<const Object> interface = ParseForInterface (path);
+  if (interface != 0)
+    {
+      interface->GetTraceResolver ()->Connect (GetSubpath (path), cb, context);
+    }
+}
+void 
+InterfaceIdTraceResolver::Disconnect (std::string path, CallbackBase const &cb)
+{
+  Ptr<const Object> interface = ParseForInterface (path);
+  if (interface != 0)
+    {
+      interface->TraceDisconnect (GetSubpath (path), cb);
+    }
+}
+void 
+InterfaceIdTraceResolver::CollectSources (std::string path, const TraceContext &context, 
+                                          SourceCollection *collection)
+{
+  m_aggregate->DoCollectSources (path, context, collection);
+}
+void 
+InterfaceIdTraceResolver::TraceAll (std::ostream &os, const TraceContext &context)
+{
+  m_aggregate->DoTraceAll (os, context);
+}
+
+
 InterfaceId::InterfaceId (uint16_t iid)
   : m_iid (iid)
 {}
@@ -72,6 +139,12 @@
 {
   return Singleton<IidTree>::Get ()->LookupParent (iid.m_iid);
 }
+std::string 
+InterfaceId::GetName (void) const
+{
+  std::string name = Singleton<IidManager>::Get ()->LookupByUid (m_iid);
+  return name;
+}
 
 bool operator == (const InterfaceId &a, const InterfaceId &b)
 {
@@ -109,6 +182,7 @@
   : m_count (1),
     m_iid (Object::iid),
     m_disposed (false),
+    m_collecting (false),
     m_next (this)
 {}
 Object::~Object () 
@@ -164,6 +238,17 @@
 }
 
 void 
+Object::TraceConnect (std::string path, const CallbackBase &cb) const
+{
+  GetTraceResolver ()->Connect (path, cb, TraceContext ());
+}
+void 
+Object::TraceDisconnect (std::string path, const CallbackBase &cb) const
+{
+  GetTraceResolver ()->Disconnect (path, cb);
+}
+
+void 
 Object::SetInterfaceId (InterfaceId iid)
 {
   NS_ASSERT (Check ());
@@ -176,6 +261,14 @@
   NS_ASSERT (!m_disposed);
 }
 
+Ptr<TraceResolver>
+Object::GetTraceResolver (void) const
+{
+  Ptr<InterfaceIdTraceResolver> resolver =
+    Create<InterfaceIdTraceResolver> (this);
+  return resolver;
+}
+
 bool 
 Object::Check (void) const
 {
@@ -209,12 +302,77 @@
   } while (current != end);
 }
 
+void 
+Object::DoCollectSources (std::string path, const TraceContext &context, 
+                          TraceResolver::SourceCollection *collection) const
+{
+  const Object *current;
+  current = this;
+  do {
+    if (current->m_collecting)
+      {
+        return;
+      }
+    current = current->m_next;
+  } while (current != this);
+
+  m_collecting = true;
+
+  current = this->m_next;
+  while (current != this)
+    {
+      NS_ASSERT (current != 0);
+      NS_DEBUG ("collect current=" << current);
+      InterfaceId cur = current->m_iid;
+      while (cur != Object::iid)
+        {
+          std::string name = cur.GetName ();
+          std::string fullpath = path;
+          fullpath.append ("/$");
+          fullpath.append (name);
+          NS_DEBUG ("collect: " << fullpath);
+          current->GetTraceResolver ()->CollectSources (fullpath, context, collection);
+          cur = InterfaceId::LookupParent (cur);
+        }
+      current = current->m_next;
+    }
+
+  m_collecting = false;
+}
+void 
+Object::DoTraceAll (std::ostream &os, const TraceContext &context) const
+{
+  const Object *current;
+  current = this;
+  do {
+    if (current->m_collecting)
+      {
+        return;
+      }
+    current = current->m_next;
+  } while (current != this);
+
+  m_collecting = true;
+
+  current = this->m_next;
+  while (current != this)
+    {
+      NS_ASSERT (current != 0);
+      current->GetTraceResolver ()->TraceAll (os, context);
+      current = current->m_next;
+    }
+
+  m_collecting = false;
+}
+
 } // namespace ns3
 
 
 #ifdef RUN_SELF_TESTS
 
 #include "test.h"
+#include "sv-trace-source.h"
+#include "composite-trace-resolver.h"
 
 namespace {
 
@@ -226,7 +384,18 @@
   {
     SetInterfaceId (BaseA::iid);
   }
+  void BaseGenerateTrace (int16_t v)
+  { m_source = v; }
   virtual void Dispose (void) {}
+  virtual ns3::Ptr<ns3::TraceResolver> GetTraceResolver (void) const
+  {
+    ns3::Ptr<ns3::CompositeTraceResolver> resolver = 
+      ns3::Create<ns3::CompositeTraceResolver> ();
+    resolver->AddSource ("basea-x", ns3::TraceDoc ("test source"), m_source);
+    resolver->SetParentResolver (Object::GetTraceResolver ());
+    return resolver;
+  }
+  ns3::SVTraceSource<int16_t> m_source;
 };
 
 class DerivedA : public BaseA
@@ -237,9 +406,20 @@
   {
     SetInterfaceId (DerivedA::iid);
   }
+  void DerivedGenerateTrace (int16_t v)
+  { m_sourceDerived = v; }
   virtual void Dispose (void) {
     BaseA::Dispose ();
   }
+  virtual ns3::Ptr<ns3::TraceResolver> GetTraceResolver (void) const
+  {
+    ns3::Ptr<ns3::CompositeTraceResolver> resolver = 
+      ns3::Create<ns3::CompositeTraceResolver> ();
+    resolver->AddSource ("deriveda-x", ns3::TraceDoc ("test source"), m_sourceDerived);
+    resolver->SetParentResolver (BaseA::GetTraceResolver ());
+    return resolver;
+  }
+  ns3::SVTraceSource<int16_t> m_sourceDerived;
 };
 
 const ns3::InterfaceId BaseA::iid = 
@@ -255,7 +435,18 @@
   {
     SetInterfaceId (BaseB::iid);
   }
+  void BaseGenerateTrace (int16_t v)
+  { m_source = v; }
   virtual void Dispose (void) {}
+  virtual ns3::Ptr<ns3::TraceResolver> GetTraceResolver (void) const
+  {
+    ns3::Ptr<ns3::CompositeTraceResolver> resolver = 
+      ns3::Create<ns3::CompositeTraceResolver> ();
+    resolver->AddSource ("baseb-x", ns3::TraceDoc ("test source"), m_source);
+    resolver->SetParentResolver (Object::GetTraceResolver ());
+    return resolver;
+  }
+  ns3::SVTraceSource<int16_t> m_source;
 };
 
 class DerivedB : public BaseB
@@ -266,9 +457,20 @@
   {
     SetInterfaceId (DerivedB::iid);
   }
+  void DerivedGenerateTrace (int16_t v)
+  { m_sourceDerived = v; }
   virtual void Dispose (void) {
     BaseB::Dispose ();
   }
+  virtual ns3::Ptr<ns3::TraceResolver> GetTraceResolver (void) const
+  {
+    ns3::Ptr<ns3::CompositeTraceResolver> resolver = 
+      ns3::Create<ns3::CompositeTraceResolver> ();
+    resolver->AddSource ("derivedb-x", ns3::TraceDoc ("test source"), m_sourceDerived);
+    resolver->SetParentResolver (BaseB::GetTraceResolver ());
+    return resolver;
+  }
+  ns3::SVTraceSource<int16_t> m_sourceDerived;
 };
 
 const ns3::InterfaceId BaseB::iid = 
@@ -285,120 +487,82 @@
 public:
   ObjectTest ();
   virtual bool RunTests (void);
+private:
+  void BaseATrace (const TraceContext &context, int64_t oldValue, int64_t newValue);
+  void DerivedATrace (const TraceContext &context, int64_t oldValue, int64_t newValue);
+  void BaseBTrace (const TraceContext &context, int64_t oldValue, int64_t newValue);
+  void DerivedBTrace (const TraceContext &context, int64_t oldValue, int64_t newValue);
+
+  bool m_baseATrace;
+  bool m_derivedATrace;
+  bool m_baseBTrace;
+  bool m_derivedBTrace;
 };
 
 ObjectTest::ObjectTest ()
   : Test ("Object")
 {}
+void 
+ObjectTest::BaseATrace (const TraceContext &context, int64_t oldValue, int64_t newValue)
+{
+  m_baseATrace = true;
+}
+void 
+ObjectTest::DerivedATrace (const TraceContext &context, int64_t oldValue, int64_t newValue)
+{
+  m_derivedATrace = true;
+}
+void 
+ObjectTest::BaseBTrace (const TraceContext &context, int64_t oldValue, int64_t newValue)
+{
+  m_baseBTrace = true;
+}
+void 
+ObjectTest::DerivedBTrace (const TraceContext &context, int64_t oldValue, int64_t newValue)
+{
+  m_derivedBTrace = true;
+}
+
 bool 
 ObjectTest::RunTests (void)
 {
-  bool ok = true;
+  bool result = true;
 
   Ptr<BaseA> baseA = Create<BaseA> ();
-  if (baseA->QueryInterface<BaseA> (BaseA::iid) != baseA)
-    {
-      ok = false;
-    }
-  if (baseA->QueryInterface<BaseA> (DerivedA::iid) != 0)
-    {
-      ok = false;
-    }
-  if (baseA->QueryInterface<DerivedA> (DerivedA::iid) != 0)
-    {
-      ok = false;
-    }
+  NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<BaseA> (BaseA::iid), baseA);
+  NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<BaseA> (DerivedA::iid), 0);
+  NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<DerivedA> (DerivedA::iid), 0);
   baseA = Create<DerivedA> (10);
-  if (baseA->QueryInterface<BaseA> (BaseA::iid) != baseA)
-    {
-      ok = false;
-    }
-  if (baseA->QueryInterface<BaseA> (DerivedA::iid) != baseA)
-    {
-      ok = false;
-    }
-  if (baseA->QueryInterface<DerivedA> (DerivedA::iid) == 0)
-    {
-      ok = false;
-    }
+  NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<BaseA> (BaseA::iid), baseA);
+  NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<BaseA> (DerivedA::iid), baseA);
+  NS_TEST_ASSERT_UNEQUAL (baseA->QueryInterface<DerivedA> (DerivedA::iid), 0);
 
   baseA = Create<BaseA> ();
   Ptr<BaseB> baseB = Create<BaseB> ();
   Ptr<BaseB> baseBCopy = baseB;
   baseA->AddInterface (baseB);
-  if (baseA->QueryInterface<BaseA> (BaseA::iid) == 0)
-    {
-      ok = false;
-    }
-  if (baseA->QueryInterface<DerivedA> (DerivedA::iid) != 0)
-    {
-      ok = false;
-    }
-  if (baseA->QueryInterface<BaseB> (BaseB::iid) == 0)
-    {
-      ok = false;
-    }
-  if (baseA->QueryInterface<DerivedB> (DerivedB::iid) != 0)
-    {
-      ok = false;
-    }
-  if (baseB->QueryInterface<BaseB> (BaseB::iid) == 0)
-    {
-      ok = false;
-    }
-  if (baseB->QueryInterface<DerivedB> (DerivedB::iid) != 0)
-    {
-      ok = false;
-    }
-  if (baseB->QueryInterface<BaseA> (BaseA::iid) == 0)
-    {
-      ok = false;
-    }
-  if (baseB->QueryInterface<DerivedA> (DerivedA::iid) != 0)
-    {
-      ok = false;
-    }
-  if (baseBCopy->QueryInterface<BaseA> (BaseA::iid) == 0)
-    {
-      ok = false;
-    }
+  NS_TEST_ASSERT_UNEQUAL (baseA->QueryInterface<BaseA> (BaseA::iid), 0);
+  NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<DerivedA> (DerivedA::iid), 0);
+  NS_TEST_ASSERT_UNEQUAL (baseA->QueryInterface<BaseB> (BaseB::iid), 0);
+  NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<DerivedB> (DerivedB::iid), 0);
+  NS_TEST_ASSERT_UNEQUAL (baseB->QueryInterface<BaseB> (BaseB::iid), 0);
+  NS_TEST_ASSERT_EQUAL (baseB->QueryInterface<DerivedB> (DerivedB::iid), 0);
+  NS_TEST_ASSERT_UNEQUAL (baseB->QueryInterface<BaseA> (BaseA::iid), 0);
+  NS_TEST_ASSERT_EQUAL (baseB->QueryInterface<DerivedA> (DerivedA::iid), 0);
+  NS_TEST_ASSERT_UNEQUAL (baseBCopy->QueryInterface<BaseA> (BaseA::iid), 0);
 
   baseA = Create<DerivedA> (1);
   baseB = Create<DerivedB> (1);
   baseBCopy = baseB;
   baseA->AddInterface (baseB);
-  if (baseA->QueryInterface<DerivedB> (DerivedB::iid) == 0)
-    {
-      ok = false;
-    }
-  if (baseA->QueryInterface<BaseB> (BaseB::iid) == 0)
-    {
-      ok = false;
-    }
-  if (baseB->QueryInterface<DerivedA> (DerivedA::iid) == 0)
-    {
-      ok = false;
-    }
-  if (baseB->QueryInterface<BaseA> (BaseA::iid) == 0)
-    {
-      ok = false;
-    }
-  if (baseBCopy->QueryInterface<DerivedA> (DerivedA::iid) == 0)
-    {
-      ok = false;
-    }
-  if (baseBCopy->QueryInterface<BaseA> (BaseA::iid) == 0)
-    {
-      ok = false;
-    }
-  if (baseB->QueryInterface<DerivedB> (DerivedB::iid) == 0)
-    {
-      ok = false;
-    }
-  if (baseB->QueryInterface<BaseB> (BaseB::iid) == 0)
-    {
-      ok = false;
-    }
+  NS_TEST_ASSERT_UNEQUAL (baseA->QueryInterface<DerivedB> (DerivedB::iid), 0);
+  NS_TEST_ASSERT_UNEQUAL (baseA->QueryInterface<BaseB> (BaseB::iid), 0);
+  NS_TEST_ASSERT_UNEQUAL (baseB->QueryInterface<DerivedA> (DerivedA::iid), 0);
+  NS_TEST_ASSERT_UNEQUAL (baseB->QueryInterface<BaseA> (BaseA::iid), 0);
+  NS_TEST_ASSERT_UNEQUAL (baseBCopy->QueryInterface<DerivedA> (DerivedA::iid), 0);
+  NS_TEST_ASSERT_UNEQUAL (baseBCopy->QueryInterface<BaseA> (BaseA::iid), 0);
+  NS_TEST_ASSERT_UNEQUAL (baseB->QueryInterface<DerivedB> (DerivedB::iid), 0);
+  NS_TEST_ASSERT_UNEQUAL (baseB->QueryInterface<BaseB> (BaseB::iid), 0)
 
   baseA = Create<BaseA> ();
   baseB = Create<BaseB> ();
@@ -406,7 +570,76 @@
   baseA = 0;
   baseA = baseB->QueryInterface<BaseA> (BaseA::iid);
 
-  return ok;
+  baseA = Create<BaseA> ();
+  baseA->TraceConnect ("/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+  m_baseATrace = false;
+  baseA->BaseGenerateTrace (1);
+  NS_TEST_ASSERT (m_baseATrace);
+  baseA->TraceDisconnect ("/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+
+  baseB = Create<BaseB> ();
+  baseB->TraceConnect ("/baseb-x",  MakeCallback (&ObjectTest::BaseBTrace, this));
+  m_baseBTrace = false;
+  baseB->BaseGenerateTrace (2);
+  NS_TEST_ASSERT (m_baseBTrace);
+  baseB->TraceDisconnect ("/baseb-x",  MakeCallback (&ObjectTest::BaseBTrace, this));
+
+  baseA->AddInterface (baseB);
+
+  baseA->TraceConnect ("/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+  m_baseATrace = false;
+  baseA->BaseGenerateTrace (3);
+  NS_TEST_ASSERT (m_baseATrace);
+  baseA->TraceDisconnect ("/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+
+  baseA->TraceConnect ("/$BaseB/baseb-x",  MakeCallback (&ObjectTest::BaseBTrace, this));
+  m_baseBTrace = false;
+  baseB->BaseGenerateTrace (4);
+  NS_TEST_ASSERT (m_baseBTrace);
+  baseA->TraceDisconnect ("/$BaseB/baseb-x",  MakeCallback (&ObjectTest::BaseBTrace, this));
+  m_baseBTrace = false;
+  baseB->BaseGenerateTrace (5);
+  NS_TEST_ASSERT (!m_baseBTrace);
+
+  baseB->TraceConnect ("/$BaseA/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+  m_baseATrace = false;
+  baseA->BaseGenerateTrace (6);
+  NS_TEST_ASSERT (m_baseATrace);
+  baseB->TraceDisconnect ("/$BaseA/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+
+  baseA->TraceConnect ("/$BaseA/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+  m_baseATrace = false;
+  baseA->BaseGenerateTrace (7);
+  NS_TEST_ASSERT (m_baseATrace);
+  baseA->TraceDisconnect ("/$BaseA/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+
+  Ptr<DerivedA> derivedA;
+  derivedA = Create<DerivedA> (1);
+  baseB = Create<BaseB> ();
+  derivedA->AddInterface (baseB);
+  baseB->TraceConnect ("/$DerivedA/deriveda-x", MakeCallback (&ObjectTest::DerivedATrace, this));
+  baseB->TraceConnect ("/$DerivedA/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+  m_derivedATrace = false;
+  m_baseATrace = false;
+  derivedA->DerivedGenerateTrace (8);
+  derivedA->BaseGenerateTrace (9);
+  NS_TEST_ASSERT (m_derivedATrace);
+  NS_TEST_ASSERT (m_baseATrace);
+  baseB->TraceDisconnect ("/$DerivedA/deriveda-x", MakeCallback (&ObjectTest::BaseATrace, this));
+  baseB->TraceDisconnect ("/$DerivedA/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
+
+  baseB->TraceConnect ("/$DerivedA/*", MakeCallback (&ObjectTest::DerivedATrace, this));
+  m_derivedATrace = false;
+  derivedA->DerivedGenerateTrace (10);
+  NS_TEST_ASSERT (m_derivedATrace);
+  // here, we have connected the derived trace sink to all 
+  // trace sources, including the base trace source.
+  m_derivedATrace = false;
+  derivedA->BaseGenerateTrace (11);
+  NS_TEST_ASSERT (m_derivedATrace);
+  baseB->TraceDisconnect ("/$DerivedA/*", MakeCallback (&ObjectTest::BaseATrace, this));
+
+  return result;
 }
 
 static ObjectTest g_interfaceObjectTests;
--- a/src/core/object.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/core/object.h	Tue Sep 11 12:11:00 2007 +0200
@@ -24,9 +24,13 @@
 #include <stdint.h>
 #include <string>
 #include "ptr.h"
+#include "trace-resolver.h"
 
 namespace ns3 {
 
+class TraceContext;
+class CallbackBase;
+
 /**
  * \brief a unique identifier for an interface.
  *
@@ -56,6 +60,11 @@
    * id is not a valid interface id.
    */
   static InterfaceId LookupParent (InterfaceId iid);
+
+  /**
+   * \returns the name of this interface.
+   */
+  std::string GetName (void) const;
   ~InterfaceId ();
 private:
   InterfaceId (uint16_t iid);
@@ -131,6 +140,30 @@
    * on one to get the other, and vice-versa. 
    */
   void AddInterface (Ptr<Object> other);
+
+  /**
+   * \param path the path to match for the callback
+   * \param cb callback to connect
+   *
+   * Connect the input callback to all trace sources which
+   * match the input path.
+   *
+   */
+  void TraceConnect (std::string path, const CallbackBase &cb) const;
+  /**
+   * \param path the path to match for the callback
+   * \param cb callback to disconnect
+   *
+   * Disconnect the input callback from all trace sources which
+   * match the input path.
+   */
+  void TraceDisconnect (std::string path, const CallbackBase &cb) const;
+  /**
+   * \returns the trace resolver associated to this object.
+   *
+   * This method should be rarely called by users.
+   */
+  virtual Ptr<TraceResolver> GetTraceResolver (void) const;
 protected:
   /**
    * \param iid an InterfaceId
@@ -147,12 +180,17 @@
    */
   virtual void DoDispose (void);
 private:
+  friend class InterfaceIdTraceResolver;
   Ptr<Object> DoQueryInterface (InterfaceId iid) const;
+  void DoCollectSources (std::string path, const TraceContext &context, 
+                         TraceResolver::SourceCollection *collection) const;
+  void DoTraceAll (std::ostream &os, const TraceContext &context) const;
   bool Check (void) const;
   void MaybeDelete (void) const;
   mutable uint32_t m_count;
   InterfaceId m_iid;
   bool m_disposed;
+  mutable bool m_collecting;
   Object *m_next;
 };
 
--- a/src/core/random-variable-default-value.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/core/random-variable-default-value.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -19,7 +19,7 @@
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 #include "random-variable-default-value.h"
-#include "ns3/debug.h"
+#include "debug.h"
 
 NS_DEBUG_COMPONENT_DEFINE ("RandomVariableDefaultValue");
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/stream-tracer-test.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,68 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * 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 "stream-tracer.h"
+#include "test.h"
+#include <iostream>
+
+#ifdef RUN_SELF_TESTS
+
+namespace {
+
+class TestStreamTracer : public ns3::Test {
+public:
+  TestStreamTracer ();
+  virtual bool RunTests (void);
+};
+
+static TestStreamTracer gTestStream;
+
+TestStreamTracer::TestStreamTracer ()
+  : Test ("StreamTracer")
+{}
+
+bool
+TestStreamTracer::RunTests (void)
+{
+  bool ok = true;
+  ns3::StreamTracer trace;
+  //trace.setStream (&std::cout);
+  trace << 1;
+  trace << " X ";
+  trace << 1.0;
+  trace << std::endl;
+  trace << "test ";
+  trace << 1 << " test";
+  trace << "test "
+        << 1.0 << " "
+        << 0xdeadbead
+        << std::endl;
+  trace << "0x" << std::hex 
+        << 0xdeadbeaf 
+        << std::dec << " "
+        << 0xdeadbeaf
+        << std::endl;
+  return ok;
+}
+
+
+}; // namespace ns3
+
+#endif /* RUN_SELF_TESTS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/stream-tracer.h	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,76 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * 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 STREAM_TRACER_H
+#define STREAM_TRACER_H
+
+#include <ostream>
+
+namespace ns3 {
+
+/**
+ * \brief log arbitrary data to std::ostreams
+ * 
+ * Whenever operator << is invoked on this class,
+ * it is forwarded to the stored std::ostream output
+ * stream (if there is one).
+ */
+class StreamTracer {
+public:
+  StreamTracer ()
+      : m_os (0) {}
+  template <typename T>
+  StreamTracer &operator << (T const&v) {
+      if (m_os != 0) 
+        {
+          (*m_os) << v;
+        }
+      return *this;
+  }
+  template <typename T>
+  StreamTracer &operator << (T &v) {
+      if (m_os != 0) 
+        {
+          (*m_os) << v;
+        }
+      return *this;
+  }
+  StreamTracer &operator << (std::ostream &(*v) (std::ostream &)) {
+      if (m_os != 0) 
+        {
+          (*m_os) << v;
+        }
+      return *this;
+  }
+
+  /**
+   * \param os the output stream to store
+   */
+  void SetStream (std::ostream * os) {
+      m_os = os;
+  }
+private:
+  std::ostream *m_os;
+};
+
+}; // namespace ns3
+
+
+#endif /* TRACER_STREAM_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/sv-trace-source.h	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,246 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * 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 SV_TRACE_SOURCE_H
+#define SV_TRACE_SOURCE_H
+
+#include "callback-trace-source.h"
+#include "trace-source.h"
+#include <stdint.h>
+
+namespace ns3 {
+
+class SVTraceSourceBase : public TraceSource {
+public:
+  typedef CallbackTraceSource<int64_t, int64_t> ChangeNotifyCallback;
+
+  SVTraceSourceBase () {}
+  SVTraceSourceBase (SVTraceSourceBase const &o) {}
+  SVTraceSourceBase &operator = (SVTraceSourceBase const &o) {
+      return *this;
+  }
+
+  virtual ~SVTraceSourceBase () {}
+
+  virtual void AddCallback (CallbackBase const & callback, TraceContext const & context) {
+    m_callback.AddCallback (callback, context);
+  }
+  virtual void RemoveCallback (CallbackBase const & callback) {
+    m_callback.RemoveCallback (callback);
+  }
+  virtual void ConnectPrinter (std::ostream &os, const TraceContext &context) {
+    m_callback.ConnectPrinter (os, context);
+  }
+protected:
+  void Notify (int64_t oldVal, int64_t newVal) {
+      if (oldVal != newVal) 
+        {
+          m_callback (oldVal, newVal);
+        }
+  }
+private:
+  ChangeNotifyCallback m_callback;
+};
+
+template <typename T>
+class UVTraceSource;
+
+
+/**
+ * \brief trace variables of type "signed integer"
+ * \ingroup tracing
+ *
+ * This template class implements a POD type: it
+ * behaves like any other variable of type "signed integer"
+ * except that it also reports any changes to its
+ * value with its internal callback.
+ *
+ * To instantiate a 32-bit signed variable (to store
+ * a TCP counter for example), you would create a variable of type
+ * ns3::UVTraceSource<int32_t> :
+ \code
+ #include <stdint.h>
+ #include "sv-trace-source.h"
+
+ ns3::SVTraceSource<uint16_t> var;
+ \endcode
+ * and you would use it like any other variable of type int32_t:
+ \code
+ var += 12;
+ var = 10;
+ var = -10;
+ \endcode
+ */
+template <typename T>
+class SVTraceSource : public SVTraceSourceBase {
+public:
+  SVTraceSource ()
+      : m_var (0)
+  {}
+  SVTraceSource (T const &var) 
+      : m_var (var)
+  {}
+
+  SVTraceSource &operator = (SVTraceSource const &o) {
+      Assign (o.Get ());
+      return *this;
+  }
+  template <typename TT>
+  SVTraceSource &operator = (SVTraceSource<TT> const &o) {
+      Assign (o.Get ());
+      return *this;
+  }
+  template <typename TT>
+  SVTraceSource &operator = (UVTraceSource<TT> const &o) {
+      Assign (o.Get ());
+      return *this;
+  }
+  SVTraceSource &operator++ () {
+      Assign (Get () + 1);
+      return *this;
+  }
+  SVTraceSource &operator-- () {
+      Assign (Get () - 1);
+      return *this;
+  }
+  SVTraceSource operator++ (int) {
+      SVTraceSource old (*this);
+      ++*this;
+      return old;
+  }
+  SVTraceSource operator-- (int) {
+      SVTraceSource old (*this);
+      --*this;
+      return old;
+  }
+  operator T () const {
+      return Get ();
+  }
+
+
+  void Assign (T var) {
+      Notify (m_var, var);
+      m_var = var;
+  }
+  T Get (void) const {
+      return m_var;
+  }
+
+private:
+  T m_var;
+};
+
+template <typename T>
+SVTraceSource<T> &operator += (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () + rhs.Get ());
+  return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator -= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () - rhs.Get ());
+  return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator *= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () * rhs.Get ());
+  return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator /= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () / rhs.Get ());
+  return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator <<= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () << rhs.Get ());
+  return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator >>= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () >> rhs.Get ());
+  return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator &= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () & rhs.Get ());
+  return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator |= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () | rhs.Get ());
+  return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator ^= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () ^ rhs.Get ());
+  return lhs;
+}
+
+
+template <typename T, typename U>
+SVTraceSource<T> &operator += (SVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () + rhs);
+  return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator -= (SVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () - rhs);
+  return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator *= (SVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () * rhs);
+  return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator /= (SVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () / rhs);
+  return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator <<= (SVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () << rhs);
+  return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator >>= (SVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () >> rhs);
+  return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator &= (SVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () & rhs);
+  return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator |= (SVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () | rhs);
+  return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator ^= (SVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () ^ rhs);
+  return lhs;
+}
+
+}; // namespace ns3
+
+#endif /* SV_TRACE_SOURCE_H */
--- a/src/core/test.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/core/test.h	Tue Sep 11 12:11:00 2007 +0200
@@ -119,6 +119,23 @@
         result = false;                                 \
       }
 /**
+ * Convenience macro to check that a value returned by a test is what
+ * is expected.  Note: this macro assumes a 'bool result = true'
+ * declaration exists in the test function body, and that the function
+ * returns that value.
+ *
+ * \param got value obtained from the test
+ * \param expected value that the test is expected to return
+ */
+#define NS_TEST_ASSERT_UNEQUAL(got, expected)           \
+    if ((got) == (expected))                            \
+      {                                                 \
+        Failure () << __FILE__ << ":" <<__LINE__        \
+                   << ": did not want " << (expected)   \
+                   << ", got " << (got) << std::endl;   \
+        result = false;                                 \
+      }
+/**
  * Convenience macro to check an assertion is held during an unit
  * test.  Note: this macro assumes a 'bool result = true' declaration
  * exists in the test function body, and that the function returns
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-context-element.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,41 @@
+#include "trace-context-element.h"
+
+namespace ns3 {
+
+std::string 
+ElementRegistry::GetTypeName (uint16_t uid)
+{
+  InfoVector *vec = GetInfoVector ();
+  struct Info info = (*vec)[uid - 1];
+  return info.getTypeName ();
+}
+uint32_t 
+ElementRegistry::GetSize (uint16_t uid)
+{
+  InfoVector *vec = GetInfoVector ();
+  struct Info info = (*vec)[uid - 1];
+  return info.size;
+}
+void 
+ElementRegistry::Print (uint16_t uid, uint8_t *instance, std::ostream &os)
+{
+  InfoVector *vec = GetInfoVector ();
+  struct Info info = (*vec)[uid - 1];
+  info.print (instance, os);
+}
+void 
+ElementRegistry::Destroy (uint16_t uid, uint8_t *instance)
+{
+  InfoVector *vec = GetInfoVector ();
+  struct Info info = (*vec)[uid - 1];
+  info.destroy (instance);
+}
+ElementRegistry::InfoVector *
+ElementRegistry::GetInfoVector (void)
+{
+  static InfoVector vector;
+  return &vector;
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-context-element.h	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,211 @@
+#ifndef TRACE_CONTEXT_ELEMENT_H
+#define TRACE_CONTEXT_ELEMENT_H
+
+#include <string>
+#include <vector>
+
+#define NS_TRACE_CONTEXT_ELEMENT_ENSURE_REGISTERED(x)          \
+namespace {						       \
+static class thisisaveryverylongclassname ##x		       \
+  {							       \
+  public:						       \
+    thisisaveryverylongclassname ##x ()			       \
+      { uint32_t uid; uid = x::GetUid ();}		       \
+  } g_thisisanotherveryveryverylongname ##x ;		       \
+}
+
+namespace ns3 {
+
+/**
+ * \brief an item stored in a TraceContext
+ *
+ * To store trace context information in a TraceContext instance,
+ * users must subclass this base class and store subclass instances
+ * in a TraceContext with TraceContext::Add.
+ *
+ * Each subclass should define and implement:
+ *   - a public default constructor: it is used by the internals
+ *     of the implementation of TraceContext.
+ *   - a public destructor: it is also used by the internals of
+ *     the implementation of TraceContext.
+ *   - a public static method named GetUid which returns a 16 bit 
+ *     integer. The integer returned from this method should be
+ *     allocated with the protected AllocatedUid method.
+ *   - a public Print method: this method is used by the 
+ *     TraceContext::Print method to print the content of each
+ *     of the trace context element stored in the trace context.
+ *     This method takes a c++ output stream and argument and is
+ *     expected to write an ascii string describing its content
+ *     in this output stream.
+ *   - a public GetTypeName method which returns the fully-qualified
+ *     c++ type name of this subclass as a string.
+ *
+ * A typical subclass should look like this:
+ * \code
+ * class MyContext : public TraceContextElement
+ * {
+ * public:
+ *   // the _required_ public API
+ *   static uint16_t GetUid (void);
+ *   MyContext ();
+ *   ~MyContext ();
+ *   void Print (std::ostream &os) const;
+ *   std::string GetTypeName (void) const;
+ *
+ *   // the user-specific API to manipulate the context.
+ *   void SetData (uint8_t data);
+ *   uint8_t GetData (void) const;
+ * private:
+ *   uint8_t m_myContextData;
+ * };
+ *
+ * uint16_t 
+ * MyContext::GetUid (void)
+ * {
+ *   static uint16_t uid = AllocateUid<MyContext> ("MyContext");
+ *   return uid;
+ * }
+ * MyContext::MyContext ()
+ * {}
+ * MyContext::~MyContext ()
+ * {}
+ * void 
+ * MyContext::Print (std::ostream &os) const
+ * {
+ *   os << "mycontext=" << (uint32_t) m_myContextData;
+ * }
+ * std::string 
+ * MyContext::GetTypeName (void) const
+ * {
+ *   // return a fully-qualified c++ type name
+ *   return "MyContext";
+ * }
+ * void 
+ * MyContext::SetData (uint8_t data)
+ * {
+ *   m_myContextData = data;
+ * }
+ * uint8_t 
+ * MyContext::GetData (void) const
+ * {
+ *   return m_myContextData;
+ * }
+ * \endcode
+ */
+class TraceContextElement
+{
+protected:
+  /**
+   * \param name a string which uniquely identifies the type
+   *        of the subclass which is calling this method.
+   * \returns a unique 32 bit integer associated to the
+   *          input string.
+   *
+   * Subclasses are expected to call this method from their
+   * public static GetUid method.
+   */
+  template <typename T>
+  static uint16_t AllocateUid (std::string name);
+};
+
+} // namespace ns3
+
+namespace ns3 {
+
+/**
+ * \brief a registry of TraceContextElement subclasses
+ * \internal
+ */
+class ElementRegistry
+{
+public:
+  template <typename T>
+  static uint16_t AllocateUid (std::string name);
+
+  static uint32_t GetSize (uint16_t uid);
+  static void Print (uint16_t uid, uint8_t *instance, std::ostream &os);
+  static std::string GetTypeName (uint16_t uid);
+  static void Destroy (uint16_t uid, uint8_t *instance);
+private:
+  typedef std::string (*GetTypeNameCb) (void);
+  typedef void (*PrintCb) (uint8_t *instance, std::ostream &os);
+  typedef void (*DestroyCb) (uint8_t *instance);
+  struct Info {
+    uint32_t size;
+    std::string uidString;
+    GetTypeNameCb getTypeName;
+    PrintCb print;
+    DestroyCb destroy;
+  };
+  typedef std::vector<struct Info> InfoVector;
+  static InfoVector *GetInfoVector (void);
+  template <typename T>
+  static std::string DoGetTypeName (void);
+  template <typename T>
+  static void DoPrint (uint8_t *instance, std::ostream &os);
+  template <typename T>
+  static void DoDestroy (uint8_t *instance);  
+};
+
+template <typename T>
+void 
+ElementRegistry::DoPrint (uint8_t *instance, std::ostream &os)
+{
+  static T obj;
+  // make sure we are aligned.
+  memcpy ((void*)&obj, instance, sizeof (T));
+  obj.Print (os);
+}
+template <typename T>
+std::string
+ElementRegistry::DoGetTypeName (void)
+{
+  static T obj;
+  return obj.GetTypeName ();
+}
+template <typename T>
+void 
+ElementRegistry::DoDestroy (uint8_t *instance)
+{
+  static T obj;
+  // make sure we are aligned.
+  memcpy ((void*)&obj, instance, sizeof (T));
+  obj.~T ();
+}
+
+template <typename T>
+uint16_t 
+ElementRegistry::AllocateUid (std::string name)
+{
+  InfoVector *vec = GetInfoVector ();
+  uint16_t uid = 1;
+  for (InfoVector::iterator i = vec->begin (); i != vec->end (); i++)
+    {
+      if (i->uidString == name)
+	{
+	  return uid;
+	}
+      uid++;
+    }
+  struct Info info;
+  info.size = sizeof (T);
+  info.uidString = name;
+  info.getTypeName = &ElementRegistry::DoGetTypeName<T>;
+  info.print = &ElementRegistry::DoPrint<T>;
+  info.destroy = &ElementRegistry::DoDestroy<T>;
+  vec->push_back (info);
+  return vec->size ();
+}
+
+
+
+template <typename T>
+uint16_t 
+TraceContextElement::AllocateUid (std::string name)
+{
+  return ElementRegistry::AllocateUid<T> (name);
+}
+
+} // namespace ns3
+
+#endif /* TRACE_CONTEXT_ELEMENT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-context.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,459 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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 "trace-context.h"
+#include "trace-context-element.h"
+#include "assert.h"
+
+namespace ns3 {
+
+TraceContext::Iterator::Iterator ()
+  : m_buffer (0),
+    m_size (0),
+    m_current (0)
+{}
+TraceContext::Iterator::Iterator (uint8_t *buffer, uint16_t size)
+  : m_buffer (buffer),
+    m_size (size),
+    m_current (0)
+{
+  m_uid = m_buffer[m_current];
+}
+bool
+TraceContext::Iterator::IsLast (void) const
+{
+  if (m_buffer == 0 || m_uid == 0 || m_current >= m_size)
+    {
+      return true;
+    }
+  return false;
+}
+void
+TraceContext::Iterator::Next (void)
+{
+  if (m_buffer == 0)
+    {
+      return;
+    }
+  if (m_uid == 0)
+    {
+      return;
+    }
+  else
+    {
+      uint8_t size = ElementRegistry::GetSize (m_uid); 
+      m_current += 1 + size;
+    }
+  m_uid = m_buffer[m_current];
+}
+std::string
+TraceContext::Iterator::Get (void) const
+{
+  std::string name = ElementRegistry::GetTypeName (m_uid);
+  return name;
+}
+
+TraceContext::TraceContext ()
+  : m_data (0)
+{}
+TraceContext::TraceContext (TraceContext const &o)
+  : m_data (o.m_data)
+{
+  if (m_data != 0)
+    {
+      m_data->count++;
+    }
+}
+TraceContext const & 
+TraceContext::operator = (TraceContext const &o)
+{
+  if (m_data != 0)
+    {
+      m_data->count--;
+      if (m_data->count == 0)
+        {
+          uint8_t *buffer = (uint8_t *)m_data;
+          delete [] buffer;
+        }
+    }
+  m_data = o.m_data;
+  if (m_data != 0)
+    {
+      m_data->count++;
+    }
+  return *this;
+}
+TraceContext::~TraceContext ()
+{
+  if (m_data != 0)
+    {
+      m_data->count--;
+      if (m_data->count == 0)
+        {
+          uint8_t *buffer = (uint8_t *)m_data;
+          delete [] buffer;
+        }
+    }
+}
+
+void 
+TraceContext::Union (TraceContext const &o)
+{
+  if (o.m_data == 0)
+    {
+      return;
+    }
+  uint16_t currentUid;
+  uint16_t i = 0;
+  while (i < o.m_data->size) 
+    {
+      currentUid = o.m_data->data[i];
+      uint8_t size = ElementRegistry::GetSize (currentUid);
+      uint8_t *selfBuffer = CheckPresent (currentUid);
+      uint8_t *otherBuffer = &(o.m_data->data[i+1]);
+      if (selfBuffer != 0)
+        {
+          if (memcmp (selfBuffer, otherBuffer, size) != 0)
+            {
+              NS_FATAL_ERROR ("You cannot add TraceContexts which "<<
+                              "have different values stored in them.");
+            }
+        }
+      else
+        {
+          DoAdd (currentUid, otherBuffer);
+        }
+      i += 1 + size;
+    }
+}
+
+uint8_t *
+TraceContext::CheckPresent (uint8_t uid) const
+{
+  if (m_data == 0)
+    {
+      return false;
+    }
+  uint8_t currentUid;
+  uint16_t i = 0;
+  do {
+    currentUid = m_data->data[i];
+    uint8_t size = ElementRegistry::GetSize (currentUid);
+    if (currentUid == uid)
+      {
+        return &m_data->data[i+1];
+      }
+    i += 1 + size;
+  } while (i < m_data->size && currentUid != 0);
+  return 0;
+}
+
+
+bool
+TraceContext::DoAdd (uint8_t uid, uint8_t const *buffer)
+{
+  NS_ASSERT (uid != 0);
+  uint8_t size = ElementRegistry::GetSize (uid);
+  uint8_t *present = CheckPresent (uid);
+  if (present != 0) {
+    if (memcmp (present, buffer, size) == 0)
+      {
+        return true;
+      }
+    else
+      {
+        return false;
+      }
+  }
+  if (m_data == 0)
+    {
+      uint16_t newSize = 1 + size;
+      uint16_t allocatedSize;
+      if (newSize > 4)
+        {
+          allocatedSize = sizeof (struct Data) + newSize - 4;
+        }
+      else
+        {
+          allocatedSize = sizeof (struct Data);
+        }
+      struct Data *data = (struct Data *) (new uint8_t [allocatedSize] ());
+      data->size = newSize;
+      data->count = 1;
+      data->data[0] = uid;
+      memcpy (data->data + 1, buffer, size);
+      m_data = data;
+    }
+  else
+    {
+      uint16_t newSize = m_data->size + 1 + size;
+      uint16_t allocatedSize;
+      if (newSize > 4)
+        {
+          allocatedSize = sizeof (struct Data) + newSize - 4;
+        }
+      else
+        {
+          allocatedSize = sizeof (struct Data);
+        }
+      struct Data *data = (struct Data *) (new uint8_t [allocatedSize] ());
+      data->size = newSize;
+      data->count = 1;
+      memcpy (data->data, m_data->data, m_data->size);
+      data->data[m_data->size] = uid;
+      memcpy (data->data + m_data->size + 1, buffer, size);
+      m_data->count--;
+      if (m_data->count == 0)
+        {
+          uint8_t *buffer = (uint8_t *)m_data;
+          delete [] buffer;
+        }
+      m_data = data;
+    }
+  return true;
+}
+bool
+TraceContext::DoGet (uint8_t uid, uint8_t *buffer) const
+{
+  if (m_data == 0)
+    {
+      return false;
+    }
+  uint8_t currentUid;
+  uint16_t i = 0;
+  do {
+    currentUid = m_data->data[i];
+    uint8_t size = ElementRegistry::GetSize (currentUid);
+    if (currentUid == uid)
+      {
+        memcpy (buffer, &m_data->data[i+1], size);
+        return true;
+      }
+    i += 1 + size;
+  } while (i < m_data->size && currentUid != 0);
+  return false;
+}
+
+void 
+TraceContext::Print (std::ostream &os) const
+{
+  if (m_data == 0)
+    {
+      return;
+    }
+  uint8_t currentUid;
+  uint16_t i = 0;
+  do {
+    currentUid = m_data->data[i];
+    uint8_t size = ElementRegistry::GetSize (currentUid);
+    uint8_t *instance = &m_data->data[i+1];
+    ElementRegistry::Print (currentUid, instance, os);
+    i += 1 + size;
+    if (i < m_data->size && currentUid != 0)
+      {
+        os << " ";
+      }
+    else
+      {
+        break;
+      }
+  } while (true);
+}
+TraceContext::Iterator 
+TraceContext::Begin (void) const
+{
+  if (m_data == 0)
+    {
+      return Iterator ();
+    }
+  return Iterator (m_data->data, m_data->size);
+}
+
+void 
+TraceContext::PrintAvailable (std::ostream &os, std::string separator) const
+{
+  if (m_data == 0)
+    {
+      return;
+    }
+  uint8_t currentUid;
+  uint16_t i = 0;
+  do {
+    currentUid = m_data->data[i];
+    uint8_t size = ElementRegistry::GetSize (currentUid);
+    os << ElementRegistry::GetTypeName (currentUid);
+    i += 1 + size;
+    if (i < m_data->size && currentUid != 0)
+      {
+        os << separator;
+      }
+    else
+      {
+        break;
+      }
+  } while (true);
+}
+
+bool 
+TraceContext::IsSimilar (const TraceContext &o) const
+{
+  if (m_data == 0 && o.m_data == 0)
+    {
+      return true;
+    }
+  if ((m_data != 0 && o.m_data == 0) || 
+      (m_data == 0 && o.m_data != 0))
+    {
+      return false;
+    }
+  uint8_t myCurrentUid;
+  uint16_t myI = 0;
+  uint8_t otherCurrentUid;
+  uint16_t otherI = 0;
+
+  myCurrentUid = m_data->data[myI];
+  otherCurrentUid = o.m_data->data[otherI];
+
+  while (myCurrentUid == otherCurrentUid && 
+         myCurrentUid != 0 && 
+         otherCurrentUid != 0 &&
+         myI < m_data->size &&
+         otherI < o.m_data->size)
+    {
+      uint8_t mySize = ElementRegistry::GetSize (myCurrentUid);
+      uint8_t otherSize = ElementRegistry::GetSize (otherCurrentUid);
+      myI += 1 + mySize;
+      otherI += 1 + otherSize;
+      myCurrentUid = m_data->data[myI];
+      otherCurrentUid = o.m_data->data[otherI];
+    }
+  if (myCurrentUid == 0 && otherCurrentUid == 0)
+    {
+      return true;
+    }
+  else
+    {
+      return false;
+    }
+}
+
+std::ostream& operator<< (std::ostream& os, const TraceContext &context)
+{
+  context.Print (os);
+  return os;
+}
+
+}//namespace ns3
+
+#include "test.h"
+#include <sstream>
+
+namespace ns3 {
+
+template <int N>
+class Ctx : public TraceContextElement
+{
+public:
+  static uint16_t GetUid (void) {static uint16_t uid = AllocateUid<Ctx<N> > (GetTypeName ()); return uid;}
+  static std::string GetTypeName (void) {std::ostringstream oss; oss << "Ctx" << N; return oss.str ();}
+  Ctx () : m_v (0) {}
+  Ctx (int v) : m_v (v) {}
+  void Print (std::ostream &os) {os << N;}
+  int Get (void) const { return N;}
+private:
+  int m_v;
+};
+
+class TraceContextTest : public Test
+{
+public:
+  TraceContextTest ();
+  virtual bool RunTests (void);
+};
+
+TraceContextTest::TraceContextTest ()
+  : Test ("TraceContext")
+{}
+bool 
+TraceContextTest::RunTests (void)
+{
+  bool ok = true;
+
+  TraceContext ctx;
+  Ctx<0> v0;
+  Ctx<0> v01 = Ctx<0> (1);
+  Ctx<1> v1;
+  Ctx<2> v2;
+  Ctx<3> v3;
+
+  if (ctx.SafeGet (v0))
+    {
+      ok = false;
+    }
+  ctx.AddElement (v0);
+  ctx.AddElement (v0);
+  if (ctx.SafeAdd (v01))
+    {
+      ok = false;
+    }
+  ctx.GetElement (v0);
+  ctx.AddElement (v1);
+  ctx.GetElement (v1);
+  ctx.GetElement (v0);
+  ctx.GetElement (v1);
+
+  TraceContext copy = ctx;
+  ctx.GetElement (v0);
+  ctx.GetElement (v1);
+  copy.GetElement (v0);
+  copy.GetElement (v1);
+  copy.AddElement (v2);
+  copy.GetElement (v0);
+  copy.GetElement (v1);
+  copy.GetElement (v2);
+  ctx.AddElement (v3);
+  ctx.GetElement (v0);
+  ctx.GetElement (v1);
+  ctx.GetElement (v3);
+
+  if (ctx.SafeGet (v2))
+    {
+      ok = false;
+    }
+  if (copy.SafeGet (v3))
+    {
+      ok = false;
+    }
+  ctx.Union (copy);
+  ctx.GetElement (v2);
+  if (copy.SafeGet (v3))
+    {
+      ok = false;
+    }
+  copy.Union (ctx);
+  copy.GetElement (v3);  
+  
+  return ok;
+}
+
+static TraceContextTest g_traceContextTest;
+
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-context.h	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,204 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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 TRACE_CONTEXT_H
+#define TRACE_CONTEXT_H
+
+#include <stdint.h>
+#include <vector>
+#include "fatal-error.h"
+#include "trace-context-element.h"
+
+namespace ns3 {
+
+/**
+ * \brief Provide context to trace sources
+ * \ingroup tracing
+ *
+ * Instances of this class are used to hold context
+ * for each trace source. Each instance holds a list of
+ * TraceContextElement. Trace sinks can lookup these contexts
+ * from this list with the ns3::TraceContext::Get method.
+ * They can also ask the TraceContext for the list of 
+ * TraceContextElements it contains with the PrintAvailable method.
+ *
+ * This class is implemented
+ * using Copy On Write which means that copying unmodified
+ * versions of this class is very cheap. However, modifying
+ * the content of this class through a call 
+ * to ns3::TraceContext::AddElement or ns3::TraceContext::Union 
+ * will trigger a costly memory reallocation if needed.
+ */
+class TraceContext
+{
+public:
+  TraceContext ();
+  TraceContext (TraceContext const &o);
+  TraceContext const & operator = (TraceContext const &o);
+  ~TraceContext ();
+
+  /**
+   * \param context add context to list of trace contexts.
+   *
+   * A copy of the input context is appended at the end of the list
+   * stored in this TraceContext.
+   */
+  template <typename T>
+  void AddElement (T const &context);
+
+  /**
+   * \param o the other context
+   *
+   * Perform the Union operation (in the sense of set theory) on the
+   * two input lists of elements. This method is used in the
+   * ns3::CallbackTraceSource class when multiple sinks are connected
+   * to a single source to ensure that the source does not need
+   * to store a single TraceContext instance per connected sink.
+   * Instead, all sinks share the same TraceContext.
+   */
+  void Union (TraceContext const &o);
+
+  /**
+   * \param context context to get from this list of trace contexts.
+   * \returns true if the requested trace context element was found 
+   *          in this TraceContext, false otherwise.
+   */
+  template <typename T>
+  bool GetElement (T &context) const;
+
+  /**
+   * \param os a c++ STL output stream
+   *
+   * Iterate over the list of TraceContextElement stored in this
+   * TraceContext and invoke each of their Print method.
+   */
+  void Print (std::ostream &os) const;
+  /**
+   * \param os a c++ STL output stream
+   * \param separator the separator inserted between each TraceContextElement typename.
+   *
+   * Print the typename of each TraceContextElement stored in this TraceContext.
+   */
+  void PrintAvailable (std::ostream &os, std::string separator) const;
+  class Iterator 
+  {
+  public:
+    void Next (void);
+    bool IsLast (void) const;
+    std::string Get (void) const;
+  private:
+    friend class TraceContext;
+    Iterator ();
+    Iterator (uint8_t *buffer, uint16_t index);
+    uint8_t *m_buffer;
+    uint16_t m_size;
+    uint16_t m_current;
+    uint8_t m_uid;
+  };
+  Iterator Begin (void) const;
+  /**
+   * \param o another trace context
+   * \returns true if the input trace context contains exactly the same set of
+   *          TraceContextElement instances, false otherwise.
+   *
+   * This method does not test for equality: the content of each matching 
+   * TraceContextElement could be different. It merely checks that both
+   * trace contexts contain the same types of TraceContextElements.
+   */
+  bool IsSimilar (const TraceContext &o) const;
+private:
+  friend class TraceContextTest;
+  // used exclusively for testing code.
+  template <typename T>
+  bool SafeGet (T &context) const;
+  template <typename T>
+  bool SafeAdd (const T &context);
+
+  uint8_t *CheckPresent (uint8_t uid) const;
+  bool DoAdd (uint8_t uid, uint8_t const *buffer);
+  bool DoGet (uint8_t uid, uint8_t *buffer) const;
+
+  struct Data {
+    uint16_t count;
+    uint16_t size;
+    uint8_t data[4];
+  } * m_data;
+};
+
+std::ostream& operator<< (std::ostream& os, const TraceContext &context);
+
+}//namespace ns3
+
+namespace ns3 {
+
+template <typename T>
+void 
+TraceContext::AddElement (T const &context)
+{
+  const TraceContextElement *parent;
+  // if the following assignment fails, it is because the input
+  // to this function is not a subclass of the TraceContextElement class.
+  parent = &context;
+  uint8_t *data = (uint8_t *) &context;
+  bool ok = DoAdd (T::GetUid (), data);
+  if (!ok)
+    {
+      NS_FATAL_ERROR ("Trying to add twice the same type with different values is invalid.");
+    }
+}
+template <typename T>
+bool
+TraceContext::GetElement (T &context) const
+{
+  TraceContextElement *parent;
+  // if the following assignment fails, it is because the input
+  // to this function is not a subclass of the TraceContextElement class.
+  parent = &context;
+  uint8_t *data = (uint8_t *) &context;
+  bool found = DoGet (T::GetUid (), data);
+  return found;
+}
+template <typename T>
+bool
+TraceContext::SafeGet (T &context) const
+{
+  TraceContextElement *parent;
+  // if the following assignment fails, it is because the input
+  // to this function is not a subclass of the TraceContextElement class.
+  parent = &context;
+  uint8_t *data = (uint8_t *) &context;
+  bool found = DoGet (T::GetUid (), data);
+  return found;
+}
+template <typename T>
+bool
+TraceContext::SafeAdd (const T &context)
+{
+  const TraceContextElement *parent;
+  // if the following assignment fails, it is because the input
+  // to this function is not a subclass of the TraceContextElement class.
+  parent = &context;
+  uint8_t *data = (uint8_t *) &context;
+  bool ok = DoAdd (T::GetUid (), data);
+  return ok;
+}
+}//namespace ns3
+
+#endif /* TRACE_CONTEXT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-doc.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,74 @@
+#include "trace-doc.h"
+
+namespace ns3 {
+
+TraceDoc::TraceDoc ()
+  : m_help ("empty help")
+{}
+
+TraceDoc::TraceDoc (std::string help)
+  : m_help (help)
+{}
+TraceDoc::TraceDoc (std::string help,
+		    std::string arg0Type,
+		    std::string arg0Help)
+  : m_help (help)
+{
+  m_argVector.push_back (std::make_pair (arg0Type, arg0Help));
+}
+TraceDoc::TraceDoc (std::string help,
+		    std::string arg0Type,
+		    std::string arg0Help,
+		    std::string arg1Type,
+		    std::string arg1Help)
+  : m_help (help)
+{
+  m_argVector.push_back (std::make_pair (arg0Type, arg0Help));
+  m_argVector.push_back (std::make_pair (arg1Type, arg1Help));
+}
+TraceDoc::TraceDoc (std::string help,
+		    std::string arg0Type,
+		    std::string arg0Help,
+		    std::string arg1Type,
+		    std::string arg1Help,
+		    std::string arg2Type,
+		    std::string arg2Help)
+  : m_help (help)
+{
+  m_argVector.push_back (std::make_pair (arg0Type, arg0Help));
+  m_argVector.push_back (std::make_pair (arg1Type, arg1Help));
+  m_argVector.push_back (std::make_pair (arg2Type, arg2Help));
+}
+TraceDoc::TraceDoc (std::string help,
+		    std::string arg0Type,
+		    std::string arg0Help,
+		    std::string arg1Type,
+		    std::string arg1Help,
+		    std::string arg2Type,
+		    std::string arg2Help,
+		    std::string arg3Type,
+		    std::string arg3Help)
+  : m_help (help)
+{
+  m_argVector.push_back (std::make_pair (arg0Type, arg0Help));
+  m_argVector.push_back (std::make_pair (arg1Type, arg1Help));
+  m_argVector.push_back (std::make_pair (arg2Type, arg2Help));
+  m_argVector.push_back (std::make_pair (arg3Type, arg3Help));
+}
+std::string 
+TraceDoc::GetHelp (void) const
+{
+  return m_help;
+}
+TraceDoc::Iterator 
+TraceDoc::ArgsBegin (void) const
+{
+  return m_argVector.begin ();
+}
+TraceDoc::Iterator 
+TraceDoc::ArgsEnd (void) const
+{
+  return m_argVector.end ();
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-doc.h	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,50 @@
+#ifndef TRACE_DOC_H
+#define TRACE_DOC_H
+
+#include <vector>
+#include <string>
+
+namespace ns3 {
+
+class TraceDoc
+{
+  typedef std::vector<std::pair<std::string,std::string> > ArgVector;
+public:
+  typedef ArgVector::const_iterator Iterator;
+  TraceDoc ();
+  TraceDoc (std::string help);
+  TraceDoc (std::string help,
+	    std::string arg0Type,
+	    std::string arg0Help);
+  TraceDoc (std::string help,
+	    std::string arg0Type,
+	    std::string arg0Help,
+	    std::string arg1Type,
+	    std::string arg1Help);
+  TraceDoc (std::string help,
+	    std::string arg0Type,
+	    std::string arg0Help,
+	    std::string arg1Type,
+	    std::string arg1Help,
+	    std::string arg2Type,
+	    std::string arg2Help);
+  TraceDoc (std::string help,
+	    std::string arg0Type,
+	    std::string arg0Help,
+	    std::string arg1Type,
+	    std::string arg1Help,
+	    std::string arg2Type,
+	    std::string arg2Help,
+	    std::string arg3Type,
+	    std::string arg3Help);
+  std::string GetHelp (void) const;
+  Iterator ArgsBegin (void) const;
+  Iterator ArgsEnd (void) const;
+private:
+  ArgVector m_argVector;
+  std::string m_help;
+};
+
+} // namespace ns3
+
+#endif /* TRACE_DOC_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-resolver.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,107 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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 "trace-resolver.h"
+#include "debug.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("TraceResolver");
+
+namespace ns3 {
+
+TraceResolver::TraceResolver ()
+  : m_count (1)
+{}
+
+TraceResolver::~TraceResolver ()
+{}
+
+void 
+TraceResolver::Ref (void)
+{
+  m_count++;
+}
+void 
+TraceResolver::Unref (void)
+{
+  m_count--;
+  if (m_count == 0)
+    {
+      NS_DEBUG ("delete "<<this);
+      delete this;
+    }
+}
+
+std::string 
+TraceResolver::GetElement (std::string path)
+{
+  std::string::size_type cur = 1;
+  // check that first char is "/"
+  std::string::size_type next = path.find ("/", cur);
+  std::string id = std::string (path, cur, next-1);
+  return id;
+}
+std::string 
+TraceResolver::GetSubpath (std::string path)
+{
+  std::string::size_type cur = 1;
+  // check that first char is "/"
+  std::string::size_type next = path.find ("/", cur);
+  std::string subpath;
+  if (next != std::string::npos)
+    {
+      subpath = std::string (path, next, std::string::npos);
+    }
+  else
+    {
+      subpath = "";
+    }
+  return subpath;
+}
+
+void 
+TraceResolver::SourceCollection::AddUnique (std::string path, 
+                                            const TraceContext &context,
+                                            const TraceDoc &doc)
+{
+  for (SourceVector::const_iterator i = m_sources.begin (); i != m_sources.end (); i++)
+    {
+      if (i->path == path &&
+          context.IsSimilar (i->context))
+        {
+          return;
+        }
+    }
+  struct Source source;
+  source.path = path;
+  source.context = context;
+  source.doc = doc;
+  m_sources.push_back (source);
+}
+TraceResolver::SourceCollection::Iterator
+TraceResolver::SourceCollection::Begin (void) const
+{
+  return m_sources.begin ();
+}
+TraceResolver::SourceCollection::Iterator
+TraceResolver::SourceCollection::End (void) const
+{
+  return m_sources.end ();
+}
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-resolver.h	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,128 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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 TRACE_RESOLVER_H
+#define TRACE_RESOLVER_H
+
+#include <string>
+#include <list>
+#include "trace-context.h"
+#include "trace-doc.h"
+
+namespace ns3 {
+
+class CallbackBase;
+
+/**
+ * \brief the base class which is used to recursively perform trace
+ *        namespace resolution.
+ * \ingroup tracing
+ *
+ * Although users could conceivably implement their own trace resolver
+ * subclasses, doing so is complicated so, it is recommended to use
+ * the default implementation ns3::CompositeTraceResolver instead.
+ */
+class TraceResolver
+{
+public:
+
+  TraceResolver ();
+  virtual ~TraceResolver ();
+  void Ref (void);
+  void Unref (void);
+
+  /**
+   * \param path the namespace path to resolver
+   * \param cb the callback to connect to the matching namespace
+   * \param context the context in which to store the trace context
+   *
+   * First, extract the leading path element from the input path, and 
+   * match this leading patch element against any terminal trace source
+   * contained in this trace resolver.
+   * Second, recursively resolve the rest of the path using other 
+   * objects if there are any.
+   * If there is any TraceContextElement associated to one of the matching
+   * elements, it should be added to the input TraceContext.
+   */
+  virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context) = 0;
+  /**
+   * \param path the namespace path to resolver
+   * \param cb the callback to disconnect in the matching namespace
+   *
+   * This method should behave as Connect.
+   */
+  virtual void Disconnect (std::string path, CallbackBase const &cb) = 0;
+
+  class SourceCollection
+  {
+  public:
+    struct Source
+    {
+      std::string path;
+      TraceContext context;
+      TraceDoc doc;
+    };
+    typedef std::vector<struct Source>::const_iterator Iterator;
+    void AddUnique (std::string path, 
+                    const TraceContext &context,
+                    const TraceDoc &doc);
+
+    Iterator Begin (void) const;
+    Iterator End (void) const;
+  private:
+    typedef std::vector<struct Source> SourceVector;
+    SourceVector m_sources;
+  };
+  /**
+   * \param path the path to the current recursive level.
+   * \param context the trace context associated to the current recursive level
+   * \param collection the collection in which to gather every trace source found.
+   *
+   * This method is invoked recursively until all trace sources have been
+   * stored in the output SourceCollection argument.
+   */
+  virtual void CollectSources (std::string path, const TraceContext &context, 
+                               SourceCollection *collection) = 0;
+
+  virtual void TraceAll (std::ostream &os, const TraceContext &context) = 0;
+protected:
+  /**
+   * \param path a namespace path
+   * \returns the initial element of the path.
+   *
+   * If the input path is "/foo/...", the return
+   * value is "foo".
+   */
+  std::string GetElement (std::string path);
+  /**
+   * \param path a namespace path
+   * \returns the subpath.
+   *
+   * If the input path is "/foo/bar/...", the return
+   * value is "/bar/...".
+   */
+  std::string GetSubpath (std::string path);
+private:
+  uint32_t m_count;
+};
+
+}//namespace ns3
+
+#endif /* TRACE_RESOLVER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-source.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,31 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 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 "trace-source.h"
+#include "trace-context.h"
+
+namespace ns3 {
+
+void 
+TraceSource::AddCallback (CallbackBase const & callback)
+{
+  AddCallback (callback, TraceContext ());
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-source.h	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,61 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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 TRACE_SOURCE_H
+#define TRACE_SOURCE_H
+
+#include <ostream>
+
+namespace ns3 {
+
+class CallbackBase;
+class TraceContext;
+
+/**
+ * \brief the base class for all trace sources
+ *
+ * Every trace source which wishes to be connectable and disconnectable with
+ * the TraceResolver system should derive from this base class and implement
+ * all three methods below.
+ */
+class TraceSource
+{
+public:
+  virtual ~TraceSource () {}
+  /**
+   * \param callback the callback to connect to this trace source
+   * \param context the context associated to the input callback which should be passed
+   *        back to the user.
+   */
+  virtual void AddCallback (CallbackBase const & callback, TraceContext const & context) = 0;
+  /**
+   * \param callback the callback to connect to this trace source
+   */
+  void AddCallback (CallbackBase const & callback);
+  /**
+   * \param callback the callback to disconnect from this trace source
+   */
+  virtual void RemoveCallback (CallbackBase const & callback) = 0;
+  virtual void ConnectPrinter (std::ostream &os, TraceContext const &context) = 0;
+};
+
+} // namespace ns3
+
+#endif /* TRACE_SOURCE_H */
--- a/src/core/uid-manager.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/core/uid-manager.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -19,8 +19,8 @@
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 #include "uid-manager.h"
-#include "ns3/fatal-error.h"
-#include "ns3/assert.h"
+#include "fatal-error.h"
+#include "assert.h"
 
 
 namespace ns3 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/uv-trace-source.h	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,249 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * 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 UV_TRACE_SOURCE_H
+#define UV_TRACE_SOURCE_H
+
+#include "callback-trace-source.h"
+#include "trace-source.h"
+#include <stdint.h>
+
+namespace ns3 {
+
+class UVTraceSourceBase : public TraceSource {
+public:
+  typedef CallbackTraceSource<uint64_t, uint64_t> ChangeNotifyCallback;
+
+  UVTraceSourceBase ()
+      : m_callback () {}
+  /* We don't want to copy the base callback. Only setCallback on
+   * a specific instance will do something to it. */
+  UVTraceSourceBase (UVTraceSourceBase const &o) 
+      : m_callback () {}
+  UVTraceSourceBase &operator = (UVTraceSourceBase const &o) {
+      return *this;
+  }
+  ~UVTraceSourceBase () {}
+
+  virtual void AddCallback (CallbackBase const & callback, TraceContext const & context) {
+    m_callback.AddCallback (callback, context);
+  }
+  virtual void RemoveCallback (CallbackBase const & callback) {
+    m_callback.RemoveCallback (callback);  
+  }  
+  virtual void ConnectPrinter (std::ostream &os, const TraceContext &context) {
+    m_callback.ConnectPrinter (os, context);
+  }
+
+protected:
+  void Notify (uint64_t oldVal, uint64_t newVal) {
+      if (oldVal != newVal) 
+        {
+          m_callback (oldVal, newVal);
+        }
+  }
+private:
+  ChangeNotifyCallback m_callback;
+};
+
+template <typename T>
+class SVTraceSource;
+
+
+/**
+ * \brief trace variables of type "unsigned integer"
+ * \ingroup tracing
+ *
+ * This template class implements a POD type: it
+ * behaves like any other variable of type "unsigned integer"
+ * except that it also reports any changes to its
+ * value with its internal callback.
+ *
+ * To instantiate a 32-bit unsigned variable (to store
+ * a TCP counter for example), you would create a variable of type
+ * ns3::UVTraceSource<uint32_t> :
+ \code
+ #include <stdint.h>
+ #include "uv-trace-source.h"
+
+ ns3::UVTraceSource<uint32_t> var;
+ \endcode
+ * and you would use it like any other variable of type uint32_t:
+ \code
+ var += 12;
+ var = 10;
+ \endcode
+ */
+template <typename T>
+class UVTraceSource : public UVTraceSourceBase {
+public:
+  UVTraceSource ()
+      : m_var ()
+  {}
+  UVTraceSource (T const &var) 
+      : m_var (var)
+  {}
+
+  UVTraceSource &operator = (UVTraceSource const &o) {
+      Assign (o.Get ());
+      return *this;
+  }
+  template <typename TT>
+  UVTraceSource &operator = (UVTraceSource<TT> const &o) {
+      Assign (o.Get ());
+      return *this;
+  }
+  template <typename TT>
+  UVTraceSource &operator = (SVTraceSource<TT> const &o) {
+      Assign (o.Get ());
+      return *this;
+  }
+  UVTraceSource &operator++ () {
+      Assign (Get () + 1);
+      return *this;
+  }
+  UVTraceSource &operator-- () {
+      Assign (Get () - 1);
+      return *this;
+  }
+  UVTraceSource operator++ (int) {
+      UVTraceSource old (*this);
+      ++*this;
+      return old;
+  }
+  UVTraceSource operator-- (int) {
+      UVTraceSource old (*this);
+      --*this;
+      return old;
+  }
+  operator T () const {
+      return Get ();
+  }
+
+
+  void Assign (T var) {
+      Notify (m_var, var);
+      m_var = var;
+  }
+  T Get (void) const {
+      return m_var;
+  }
+
+private:
+  T m_var;
+};
+
+template <typename T>
+UVTraceSource<T> &operator += (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () + rhs.Get ());
+  return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator -= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () - rhs.Get ());
+  return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator *= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () * rhs.Get ());
+  return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator /= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () / rhs.Get ());
+  return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator <<= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () << rhs.Get ());
+  return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator >>= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () >> rhs.Get ());
+  return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator &= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () & rhs.Get ());
+  return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator |= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () | rhs.Get ());
+  return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator ^= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+  lhs.Assign (lhs.Get () ^ rhs.Get ());
+  return lhs;
+}
+
+
+template <typename T, typename U>
+UVTraceSource<T> &operator += (UVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () + rhs);
+  return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator -= (UVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () - rhs);
+  return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator *= (UVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () * rhs);
+  return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator /= (UVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () / rhs);
+  return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator <<= (UVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () << rhs);
+  return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator >>= (UVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () >> rhs);
+  return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator &= (UVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () & rhs);
+  return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator |= (UVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () | rhs);
+  return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator ^= (UVTraceSource<T> &lhs, U const &rhs) {
+  lhs.Assign (lhs.Get () ^ rhs);
+  return lhs;
+}
+
+}; // namespace ns3
+
+#endif /* UV_TRACE_SOURCE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/variable-tracer-test.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,272 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * 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 "uv-trace-source.h"
+#include "sv-trace-source.h"
+#include "trace-context.h"
+#include "test.h"
+#include "callback.h"
+
+
+namespace ns3 {
+
+class Foo {
+public:
+  void Notify (TraceContext const &contex, uint64_t oldVal, uint64_t newVal) {}
+};
+
+class VariableTracerTest: public Test {
+public:
+  VariableTracerTest ();
+  void RunUnsignedTests (void);
+  void RunSignedUnsignedTests (void);
+  virtual bool RunTests (void);
+};
+void
+VariableTracerTest::RunUnsignedTests (void)
+{
+  UVTraceSource<uint32_t> var, ovar, tmp;
+  uint32_t utmp;
+  Foo *foo = new Foo ();
+  
+  var.AddCallback (MakeCallback (&Foo::Notify, foo), TraceContext ());
+
+  var = 10;
+  ovar = var;
+
+  if (var == ovar) 
+    {
+    }
+  if (var != ovar) 
+    {
+    }
+  if (var > ovar) 
+    {
+    }
+  if (var >= ovar) 
+    {
+    }
+  if (var < ovar)
+    {
+    }
+  
+  if (var <= ovar)
+
+  if (var == 1)
+    {
+    }
+  if (var != 1)
+    {
+    }
+  if (var > 1)
+    {
+    }
+  if (var >= 1)
+    {
+    }
+  if (var < 1)
+    {
+    }
+  if (var <= 1)
+    {
+    }
+
+  if (1 == ovar)
+    {
+    }
+  if (1 != ovar)
+    {
+    }
+  if (1 > ovar)
+    {
+    }
+  if (1 >= ovar)
+    {
+    }
+  if (1 < ovar)
+    {
+    }
+  if (1 <= ovar)
+    {
+    }
+
+  var++;
+  ++var;
+  var--;
+  --var;
+
+  tmp = var + ovar;
+  tmp = var - ovar;
+  tmp = var / ovar;
+  tmp = var * ovar;
+  tmp = var << ovar;
+  tmp = var >> ovar;
+  tmp = var & ovar;
+  tmp = var | ovar;
+  tmp = var ^ ovar;
+
+  tmp = var + 1;
+  tmp = var - 1;
+  tmp = var / 1;
+  tmp = var * 1;
+  tmp = var << 1;
+  tmp = var >> 1;
+  tmp = var & 1;
+  tmp = var | 1;
+  tmp = var ^ 1;
+
+  tmp = 1 + ovar;
+  tmp = 1 - ovar;
+  tmp = 1 / ovar;
+  tmp = 1 * ovar;
+  tmp = 1 << ovar;
+  tmp = 1 >> ovar;
+  tmp = 1 & ovar;
+  tmp = 1 | ovar;
+  tmp = 1 ^ ovar;
+
+  tmp += var;
+  tmp -= var;
+  tmp /= var;
+  tmp *= var;
+  tmp <<= var;
+  tmp >>= var;
+  tmp &= var;
+  tmp |= var;
+  tmp ^= var;
+
+  tmp += 1;
+  tmp -= 1;
+  tmp /= 1;
+  tmp *= 1;
+  tmp <<= 1;
+  tmp >>= 1;
+  tmp &= 1;
+  tmp |= 1;
+  tmp ^= 1;
+
+
+  utmp = var + ovar;
+  utmp = var - ovar;
+  utmp = var / ovar;
+  utmp = var * ovar;
+  utmp = var << ovar;
+  utmp = var >> ovar;
+  utmp = var & ovar;
+  utmp = var | ovar;
+  utmp = var ^ ovar;
+
+  utmp = var + 1;
+  utmp = var - 1;
+  utmp = var / 1;
+  utmp = var * 1;
+  utmp = var << 1;
+  utmp = var >> 1;
+  utmp = var & 1;
+  utmp = var | 1;
+  utmp = var ^ 1;
+
+  utmp = 1 + ovar;
+  utmp = 1 - ovar;
+  utmp = 1 / ovar;
+  utmp = 1 * ovar;
+  utmp = 1 << ovar;
+  utmp = 1 >> ovar;
+  utmp = 1 & ovar;
+  utmp = 1 | ovar;
+  utmp = 1 ^ ovar;
+
+  utmp += var;
+  utmp -= var;
+  utmp /= var;
+  utmp *= var;
+  utmp <<= var;
+  utmp >>= var;
+  utmp &= var;
+  utmp |= var;
+  utmp ^= var;
+
+  utmp += 1;
+  utmp -= 1;
+  utmp /= 1;
+  utmp *= 1;
+  utmp <<= 1;
+  utmp >>= 1;
+  utmp &= 1;
+  utmp |= 1;
+  utmp ^= 1;
+
+  delete foo;
+}
+
+void
+VariableTracerTest::RunSignedUnsignedTests (void)
+{
+  unsigned short utmp = 10;
+  unsigned int uitmp = 7;
+  short stmp = 5;
+  utmp = stmp;
+  utmp += stmp;
+  uitmp = utmp;
+  utmp = uitmp;
+
+  UVTraceSource<unsigned short> uvar = 10;
+  UVTraceSource<unsigned int> uivar = 5;
+  SVTraceSource<short> svar = 5;
+  SVTraceSource<int> sivar = 5;
+  uvar = svar;
+  svar = uvar;
+  uvar += svar;
+  svar += uvar;
+
+  uvar = sivar;
+  sivar = uvar;
+  uvar += sivar;
+  sivar += uvar;
+
+  uivar = uvar;
+  uvar = uivar;
+  uivar += uvar;
+  uvar += uivar;
+
+  sivar = svar;
+  svar = sivar;
+  sivar += svar;
+  svar += sivar;
+}
+
+bool 
+VariableTracerTest::RunTests (void)
+{
+  RunUnsignedTests ();
+  RunSignedUnsignedTests ();
+
+  return true;
+}
+
+VariableTracerTest::VariableTracerTest ()
+  : Test ("VariableTracer") {}
+
+static VariableTracerTest gVariableTracerTest;
+
+}; // namespace ns3
+
+
--- a/src/core/wscript	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/core/wscript	Tue Sep 11 12:11:00 2007 +0200
@@ -42,6 +42,14 @@
         'type-name.cc',
         'component-manager.cc',
         'random-variable-default-value.cc',
+        'variable-tracer-test.cc',
+        'trace-context.cc',
+        'trace-context-element.cc',
+        'trace-resolver.cc',
+        'callback-trace-source.cc',
+        'composite-trace-resolver.cc',
+        'trace-doc.cc',
+        'trace-source.cc',
         ]
 
     if sys.platform == 'win32':
@@ -73,5 +81,16 @@
         'component-manager.h',
         'type-traits.h',
         'random-variable-default-value.h',
+        'trace-source.h',
+        'uv-trace-source.h',
+        'sv-trace-source.h',
+        'fv-trace-source.h',
+        'callback-trace-source.h',
+        'trace-context.h',
+        'trace-context-element.h',
+        'trace-resolver.h',
+        'composite-trace-resolver.h',
+        'array-trace-resolver.h',
+        'trace-doc.h',
         ]
 
--- a/src/devices/csma/csma-net-device.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/devices/csma/csma-net-device.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -59,6 +59,16 @@
   static uint16_t uid = AllocateUid<CsmaTraceType> ("CsmaTraceType");
   return uid;
 }
+std::string 
+CsmaTraceType::GetTypeName (void) const
+{
+  return "ns3::CsmaTraceType";
+}
+enum CsmaTraceType::Type 
+CsmaTraceType::Get (void) const
+{
+  return m_type;
+}
 
 
 CsmaNetDevice::CsmaNetDevice (Ptr<Node> node)
@@ -452,20 +462,23 @@
     }
 }
 
-TraceResolver *
-CsmaNetDevice::DoCreateTraceResolver (TraceContext const &context)
+Ptr<TraceResolver>
+CsmaNetDevice::GetTraceResolver (void) const
 {
-  CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
-  resolver->Add ("queue", 
-                 MakeCallback (&Queue::CreateTraceResolver, 
-                               PeekPointer (m_queue)));
-  resolver->Add ("rx",
-                 m_rxTrace,
-                 CsmaTraceType (CsmaTraceType::RX));
-  resolver->Add ("drop",
-                 m_dropTrace,
-                 CsmaTraceType (CsmaTraceType::DROP));
-   return resolver;
+  Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+  resolver->AddComposite ("queue", m_queue);
+  resolver->AddSource ("rx",
+                       TraceDoc ("receive MAC packet",
+                                 "const Packet &", "packet received"),
+                       m_rxTrace,
+                       CsmaTraceType (CsmaTraceType::RX));
+  resolver->AddSource ("drop",
+                       TraceDoc ("drop MAC packet",
+                                 "const Packet &", "packet dropped"),
+                       m_dropTrace,
+                       CsmaTraceType (CsmaTraceType::DROP));
+  resolver->SetParentResolver (NetDevice::GetTraceResolver ());
+  return resolver;
 }
 
 bool
--- a/src/devices/csma/csma-net-device.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/devices/csma/csma-net-device.h	Tue Sep 11 12:11:00 2007 +0200
@@ -41,6 +41,9 @@
 class Queue;
 class CsmaChannel;
 
+/**
+ * \brief hold in a TraceContext the type of trace source from a CsmaNetDevice
+ */
 class CsmaTraceType : public TraceContextElement
 {
 public:
@@ -52,6 +55,11 @@
   CsmaTraceType ();
   void Print (std::ostream &os) const;
   static uint16_t GetUid (void);
+  std::string GetTypeName (void) const;
+  /**
+   * \returns the type of the trace source which generated an event.
+   */
+  enum Type Get (void) const;
 private:
   enum Type m_type;
 };
@@ -207,6 +215,13 @@
   virtual bool DoNeedsArp (void) const;
   virtual void DoDispose (void);
   /**
+   * Create a Trace Resolver for events in the net device.
+   * (NOT TESTED)
+   * @see class TraceResolver
+   */
+  virtual Ptr<TraceResolver> GetTraceResolver (void) const;
+
+  /**
    * Get a copy of the attached Queue.
    *
    * This method is provided for any derived class that may need to get
@@ -321,12 +336,6 @@
    * @see TransmitStart ()
    */
   void TransmitReadyEvent (void);
-  /**
-   * Create a Trace Resolver for events in the net device.
-   * (NOT TESTED)
-   * @see class TraceResolver
-   */
-  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
 
   /**
    * Aborts the transmission of the current packet
--- a/src/devices/point-to-point/point-to-point-net-device.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/devices/point-to-point/point-to-point-net-device.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -53,6 +53,11 @@
   static uint16_t uid = AllocateUid<PointToPointTraceType> ("PointToPointTraceType");
   return uid;
 }
+std::string 
+PointToPointTraceType::GetTypeName (void) const
+{
+  return "ns3::PointToPointTraceType";
+}
 
 
 PointToPointNetDevice::PointToPointNetDevice (Ptr<Node> node,
@@ -189,15 +194,17 @@
   TransmitStart(p);
 }
 
-TraceResolver* PointToPointNetDevice::DoCreateTraceResolver (
-                                      TraceContext const &context)
+Ptr<TraceResolver> 
+PointToPointNetDevice::GetTraceResolver (void) const
 {
-  CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
-  resolver->Add ("queue", 
-                 MakeCallback (&Queue::CreateTraceResolver, PeekPointer (m_queue)));
-  resolver->Add ("rx",
-                 m_rxTrace,
-                 PointToPointTraceType ());
+  Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+  resolver->AddComposite ("queue", m_queue);
+  resolver->AddSource ("rx",
+                       TraceDoc ("receive MAC packet",
+                                 "const Packet &", "packet received"),
+                       m_rxTrace,
+                       PointToPointTraceType ());
+  resolver->SetParentResolver (NetDevice::GetTraceResolver ());
   return resolver;
 }
 
--- a/src/devices/point-to-point/point-to-point-net-device.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/devices/point-to-point/point-to-point-net-device.h	Tue Sep 11 12:11:00 2007 +0200
@@ -38,12 +38,16 @@
 class Queue;
 class PointToPointChannel;
 
+/**
+ * \brief hold in a TraceContext the type of trace source from a PointToPointNetDevice
+ */
 class PointToPointTraceType : public TraceContextElement
 {
 public:
   PointToPointTraceType ();
   void Print (std::ostream &os) const;
   static uint16_t GetUid (void);
+  std::string GetTypeName (void) const;
 };
 
 /**
@@ -152,6 +156,12 @@
    */
   void Receive (Packet& p);
 protected:
+  /**
+   * Create a Trace Resolver for events in the net device.
+   *
+   * @see class TraceResolver
+   */
+  virtual Ptr<TraceResolver> GetTraceResolver (void) const;
   virtual void DoDispose (void);
   /**
    * Get a copy of the attached Queue.
@@ -237,12 +247,6 @@
    *
    */
   void TransmitComplete(void);
-  /**
-   * Create a Trace Resolver for events in the net device.
-   *
-   * @see class TraceResolver
-   */
-  virtual TraceResolver* DoCreateTraceResolver (TraceContext const &context);
   virtual bool DoNeedsArp (void) const;
   /**
    * Enumeration of the states of the transmit machine of the net device.
--- a/src/internet-node/arp-cache.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/arp-cache.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -19,16 +19,16 @@
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 #include "ns3/assert.h"
-
 #include "ns3/packet.h"
 #include "ns3/simulator.h"
 
 #include "arp-cache.h"
 #include "arp-header.h"
+#include "ipv4-interface.h"
 
 namespace ns3 {
 
-ArpCache::ArpCache (Ptr<NetDevice> device, Ipv4Interface *interface)
+ArpCache::ArpCache (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface)
   : m_device (device), 
     m_interface (interface),
     m_aliveTimeout (Seconds (120)),
@@ -47,7 +47,7 @@
   return m_device;
 }
 
-Ipv4Interface *
+Ptr<Ipv4Interface>
 ArpCache::GetInterface (void) const
 {
   return m_interface;
--- a/src/internet-node/arp-cache.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/arp-cache.h	Tue Sep 11 12:11:00 2007 +0200
@@ -48,7 +48,7 @@
    * \param device The hardware NetDevice associated with this ARP chache
    * \param interface the Ipv4Interface associated with this ARP chache
    */
-  ArpCache (Ptr<NetDevice> device, Ipv4Interface *interface);
+  ArpCache (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface);
   ~ArpCache ();
   /**
    * \return The NetDevice that this ARP cache is associated with
@@ -57,7 +57,7 @@
   /**
    * \return the Ipv4Interface that this ARP cache is associated with
    */
-  Ipv4Interface *GetInterface (void) const;
+  Ptr<Ipv4Interface> GetInterface (void) const;
   
   void SetAliveTimeout (Time aliveTimeout);
   void SetDeadTimeout (Time deadTimeout);
@@ -152,7 +152,7 @@
   typedef sgi::hash_map<Ipv4Address, ArpCache::Entry *, Ipv4AddressHash>::iterator CacheI;
 
   Ptr<NetDevice> m_device;
-  Ipv4Interface *m_interface;
+  Ptr<Ipv4Interface> m_interface;
   Time m_aliveTimeout;
   Time m_deadTimeout;
   Time m_waitReplyTimeout;
--- a/src/internet-node/arp-ipv4-interface.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/arp-ipv4-interface.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -40,16 +40,15 @@
 ArpIpv4Interface::~ArpIpv4Interface ()
 {}
 
-TraceResolver *
-ArpIpv4Interface::DoCreateTraceResolver (TraceContext const &context)
+Ptr<TraceResolver>
+ArpIpv4Interface::GetTraceResolver (void) const
 {
-  CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+  Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
   if (GetDevice () != 0)
     {
-      resolver->Add ("netdevice",
-                     MakeCallback (&NetDevice::CreateTraceResolver, PeekPointer (GetDevice ())));
+      resolver->AddComposite ("netdevice", GetDevice ());
     }
-  
+  resolver->SetParentResolver (Ipv4Interface::GetTraceResolver ());
   return resolver;
 }
 
--- a/src/internet-node/arp-ipv4-interface.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/arp-ipv4-interface.h	Tue Sep 11 12:11:00 2007 +0200
@@ -42,9 +42,10 @@
   ArpIpv4Interface (Ptr<Node> node, Ptr<NetDevice> device);
   virtual ~ArpIpv4Interface ();
 
- private:
+protected:
+  virtual Ptr<TraceResolver> GetTraceResolver (void) const;
+private:
   virtual void SendTo (Packet p, Ipv4Address dest);
-  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
   Ptr<Node> m_node;
 };
 
--- a/src/internet-node/arp-l3-protocol.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/arp-l3-protocol.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -20,7 +20,6 @@
  */
 #include "ns3/packet.h"
 #include "ns3/debug.h"
-#include "ns3/empty-trace-resolver.h"
 #include "ns3/node.h"
 #include "ns3/net-device.h"
 
@@ -58,12 +57,6 @@
   Object::DoDispose ();
 }
 
-TraceResolver *
-ArpL3Protocol::CreateTraceResolver (TraceContext const &context)
-{
-  return new EmptyTraceResolver (context);
-}
-
 ArpCache *
 ArpL3Protocol::FindCache (Ptr<NetDevice> device)
 {
@@ -75,7 +68,7 @@
 	}
     }
   Ptr<Ipv4L3Protocol> ipv4 = m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
-  Ipv4Interface *interface = ipv4->FindInterfaceForDevice (device);
+  Ptr<Ipv4Interface> interface = ipv4->FindInterfaceForDevice (device);
   ArpCache * cache = new ArpCache (device, interface);
   NS_ASSERT (device->IsBroadcast ());
   device->SetLinkChangeCallback (MakeCallback (&ArpCache::Flush, cache));
--- a/src/internet-node/arp-l3-protocol.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/arp-l3-protocol.h	Tue Sep 11 12:11:00 2007 +0200
@@ -48,8 +48,6 @@
    */
   ArpL3Protocol (Ptr<Node> node);
   virtual ~ArpL3Protocol ();
-
-  virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
   /**
    * \brief Recieve a packet
    */
--- a/src/internet-node/ascii-trace.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/ascii-trace.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -21,9 +21,9 @@
 #include "ascii-trace.h"
 
 #include "ns3/trace-context.h"
-#include "ns3/trace-root.h"
 #include "ns3/simulator.h"
 #include "ns3/node.h"
+#include "ns3/node-list.h"
 #include "ns3/packet.h"
 #include "ns3/queue.h"
 
@@ -41,19 +41,19 @@
 AsciiTrace::TraceAllQueues (void)
 {
   Packet::EnableMetadata ();
-  TraceRoot::Connect ("/nodes/*/devices/*/queue/enqueue",
+  NodeList::Connect ("/nodes/*/devices/*/queue/enqueue",
                       MakeCallback (&AsciiTrace::LogDevQueueEnqueue, this));
-  TraceRoot::Connect ("/nodes/*/devices/*/queue/dequeue",
+  NodeList::Connect ("/nodes/*/devices/*/queue/dequeue",
                       MakeCallback (&AsciiTrace::LogDevQueueDequeue, this));
-  TraceRoot::Connect ("/nodes/*/devices/*/queue/drop",
+  NodeList::Connect ("/nodes/*/devices/*/queue/drop",
                       MakeCallback (&AsciiTrace::LogDevQueueDrop, this));
 }
 void
 AsciiTrace::TraceAllNetDeviceRx (void)
 {
   Packet::EnableMetadata ();
-  TraceRoot::Connect ("/nodes/*/devices/*/rx",
-                      MakeCallback (&AsciiTrace::LogDevRx, this));
+  NodeList::Connect ("/nodes/*/devices/*/rx",
+                     MakeCallback (&AsciiTrace::LogDevRx, this));
 }
 
 void 
--- a/src/internet-node/internet-node.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/internet-node.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -74,13 +74,14 @@
   Object::AddInterface (ipv4L4Demux);
 }
 
-void
-InternetNode::DoFillTraceResolver (CompositeTraceResolver &resolver)
+Ptr<TraceResolver>
+InternetNode::GetTraceResolver () const
 {
-  Node::DoFillTraceResolver (resolver);
+  Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
   Ptr<Ipv4L3Protocol> ipv4 = QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
-  resolver.Add ("ipv4",
-                MakeCallback (&Ipv4L3Protocol::CreateTraceResolver, PeekPointer (ipv4)));
+  resolver->AddComposite ("ipv4", ipv4);
+  resolver->SetParentResolver (Node::GetTraceResolver ());
+  return resolver;
 }
 
 void 
--- a/src/internet-node/internet-node.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/internet-node.h	Tue Sep 11 12:11:00 2007 +0200
@@ -42,8 +42,8 @@
 
 protected:
   virtual void DoDispose(void);
+  virtual Ptr<TraceResolver> GetTraceResolver (void) const;
 private:
-  virtual void DoFillTraceResolver (CompositeTraceResolver &resolver);
   bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &p, uint16_t protocolNumber) const;
   void Construct (void);
 };
--- a/src/internet-node/ipv4-interface.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/ipv4-interface.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -22,6 +22,7 @@
 #include "ipv4-interface.h"
 #include "ns3/ipv4-address.h"
 #include "ns3/net-device.h"
+#include "ns3/trace-resolver.h"
 
 namespace ns3 {
 
@@ -39,18 +40,19 @@
 Ipv4Interface::~Ipv4Interface ()
 {}
 
+void
+Ipv4Interface::DoDispose (void)
+{
+  m_netdevice = 0;
+  Object::DoDispose ();
+}
+
 Ptr<NetDevice>
 Ipv4Interface::GetDevice (void) const
 {
   return m_netdevice;
 }
 
-TraceResolver *
-Ipv4Interface::CreateTraceResolver (TraceContext const &context)
-{
-  return DoCreateTraceResolver (context);
-}
-
 void 
 Ipv4Interface::SetAddress (Ipv4Address a)
 {
--- a/src/internet-node/ipv4-interface.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/ipv4-interface.h	Tue Sep 11 12:11:00 2007 +0200
@@ -26,6 +26,7 @@
 #include <list>
 #include "ns3/ipv4-address.h"
 #include "ns3/ptr.h"
+#include "ns3/object.h"
 
 namespace ns3 {
 
@@ -60,9 +61,8 @@
  *
  * Subclasses must implement the two methods:
  *   - Ipv4Interface::SendTo
- *   - Ipv4Interface::DoCreateTraceResolver
  */
-class Ipv4Interface 
+class Ipv4Interface  : public Object
 {
 public:
   /**
@@ -74,17 +74,6 @@
   virtual ~Ipv4Interface();
 
   /**
-   * \param context the trace context to use to construct the
-   *        TraceResolver to return
-   * \returns a TraceResolver which can resolve all traces
-   *          performed in this object. The caller must
-   *          delete the returned object.
-   *
-   * This method will delegate the work to the private DoCreateTraceResolver 
-   * method which is supposed to be implemented by subclasses.
-   */
-  TraceResolver *CreateTraceResolver (TraceContext const &context);
-  /**
    * \returns the underlying NetDevice. This method can return
    *          zero if this interface has no associated NetDevice.
    */
@@ -150,10 +139,10 @@
    */ 
   void Send(Packet p, Ipv4Address dest);
 
-
- private:
+protected:
+  virtual void DoDispose (void);
+private:
   virtual void SendTo (Packet p, Ipv4Address dest) = 0;
-  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
   Ptr<NetDevice> m_netdevice;
   bool m_ifup;
   Ipv4Address m_address;
--- a/src/internet-node/ipv4-l3-protocol.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/ipv4-l3-protocol.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -22,7 +22,6 @@
 #include "ns3/packet.h"
 #include "ns3/debug.h"
 #include "ns3/composite-trace-resolver.h"
-#include "ns3/array-trace-resolver.h"
 #include "ns3/callback.h"
 #include "ns3/ipv4-address.h"
 #include "ns3/ipv4-route.h"
@@ -88,30 +87,40 @@
   static uint16_t uid = AllocateUid<Ipv4L3ProtocolTraceContextElement> ("Ipv4L3ProtocolTraceContextElement");
   return uid;
 }
+std::string 
+Ipv4L3ProtocolTraceContextElement::GetTypeName (void) const
+{
+  return "ns3::Ipv4L3ProtocolTraceContextElement";
+}
 
 
-Ipv4l3ProtocolInterfaceIndex::Ipv4l3ProtocolInterfaceIndex ()
+Ipv4L3ProtocolInterfaceIndex::Ipv4L3ProtocolInterfaceIndex ()
   : m_index (0)
 {}
-Ipv4l3ProtocolInterfaceIndex::Ipv4l3ProtocolInterfaceIndex (uint32_t index)
+Ipv4L3ProtocolInterfaceIndex::Ipv4L3ProtocolInterfaceIndex (uint32_t index)
   : m_index (index)
 {}
 uint32_t 
-Ipv4l3ProtocolInterfaceIndex::Get (void) const
+Ipv4L3ProtocolInterfaceIndex::Get (void) const
 {
   return m_index;
 }
 void 
-Ipv4l3ProtocolInterfaceIndex::Print (std::ostream &os) const
+Ipv4L3ProtocolInterfaceIndex::Print (std::ostream &os) const
 {
   os << "ipv4-interface=" << m_index;
 }
 uint16_t 
-Ipv4l3ProtocolInterfaceIndex::GetUid (void)
+Ipv4L3ProtocolInterfaceIndex::GetUid (void)
 {
-  static uint16_t uid = AllocateUid<Ipv4l3ProtocolInterfaceIndex> ("Ipv4l3ProtocolInterfaceIndex");
+  static uint16_t uid = AllocateUid<Ipv4L3ProtocolInterfaceIndex> ("Ipv4L3ProtocolInterfaceIndex");
   return uid;
 }
+std::string
+Ipv4L3ProtocolInterfaceIndex::GetTypeName (void) const
+{
+  return "ns3::Ipv4L3ProtocolInterfaceIndex";
+}
 
 
 Ipv4L3Protocol::Ipv4L3Protocol(Ptr<Node> node)
@@ -131,10 +140,6 @@
 void 
 Ipv4L3Protocol::DoDispose (void)
 {
-  for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
-    {
-      delete (*i);
-    }
   m_interfaces.clear ();
   m_node = 0;
   m_staticRouting->Dispose ();
@@ -145,7 +150,7 @@
 void
 Ipv4L3Protocol::SetupLoopback (void)
 {
-  Ipv4LoopbackInterface * interface = new Ipv4LoopbackInterface (m_node);
+  Ptr<Ipv4LoopbackInterface> interface = Create<Ipv4LoopbackInterface> (m_node);
   interface->SetAddress (Ipv4Address::GetLoopback ());
   interface->SetNetworkMask (Ipv4Mask::GetLoopback ());
   uint32_t index = AddIpv4Interface (interface);
@@ -153,26 +158,27 @@
   interface->SetUp ();
 }
 
-TraceResolver *
-Ipv4L3Protocol::CreateTraceResolver (TraceContext const &context)
+Ptr<TraceResolver>
+Ipv4L3Protocol::GetTraceResolver (void) const
 {
-  CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
-  resolver->Add ("tx", m_txTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::TX));
-  resolver->Add ("rx", m_rxTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::RX));
-  resolver->Add ("drop", m_dropTrace, Ipv4L3ProtocolTraceContextElement (Ipv4L3ProtocolTraceContextElement::DROP));
-  resolver->Add ("interfaces", 
-                 MakeCallback (&Ipv4L3Protocol::InterfacesCreateTraceResolver, this));
-  return resolver;
-}
-
-TraceResolver *
-Ipv4L3Protocol::InterfacesCreateTraceResolver (TraceContext const &context) const
-{
-  ArrayTraceResolver<Ipv4Interface *, Ipv4l3ProtocolInterfaceIndex> *resolver = 
-    new ArrayTraceResolver<Ipv4Interface *,Ipv4l3ProtocolInterfaceIndex> 
-    (context,
-     MakeCallback (&Ipv4L3Protocol::GetNInterfaces, this),
-     MakeCallback (&Ipv4L3Protocol::GetInterface, this));
+  Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+  resolver->AddSource ("tx", 
+                       TraceDoc ("send ipv4 packet to outgoing interface",
+                                 "const Packet &", "packet sent",
+                                 "uint32_t", "index of output ipv4 interface"),
+                       m_txTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::TX));
+  resolver->AddSource ("rx",
+                       TraceDoc ("receive ipv4 packet from incoming interface",
+                                 "const Packet &", "packet received",
+                                 "uint32_t", "index of input ipv4 interface"),
+                       m_rxTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::RX));
+  resolver->AddSource ("drop", 
+                       TraceDoc ("drop ipv4 packet",
+                                 "const Packet &", "packet dropped"),
+                       m_dropTrace, Ipv4L3ProtocolTraceContextElement (Ipv4L3ProtocolTraceContextElement::DROP));
+  resolver->AddArray ("interfaces", 
+                      m_interfaces.begin (), m_interfaces.end (), 
+                      Ipv4L3ProtocolInterfaceIndex ());
   return resolver;
 }
 
@@ -265,18 +271,18 @@
 uint32_t 
 Ipv4L3Protocol::AddInterface (Ptr<NetDevice> device)
 {
-  Ipv4Interface *interface = new ArpIpv4Interface (m_node, device);
+  Ptr<Ipv4Interface> interface = Create<ArpIpv4Interface> (m_node, device);
   return AddIpv4Interface (interface);
 }
 uint32_t 
-Ipv4L3Protocol::AddIpv4Interface (Ipv4Interface *interface)
+Ipv4L3Protocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
 {
   uint32_t index = m_nInterfaces;
   m_interfaces.push_back (interface);
   m_nInterfaces++;
   return index;
 }
-Ipv4Interface *
+Ptr<Ipv4Interface>
 Ipv4L3Protocol::GetInterface (uint32_t index) const
 {
   uint32_t tmp = 0;
@@ -296,7 +302,7 @@
   return m_nInterfaces;
 }
 
-Ipv4Interface *
+Ptr<Ipv4Interface>
 Ipv4L3Protocol::FindInterfaceForDevice (Ptr<const NetDevice> device)
 {
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
@@ -364,7 +370,7 @@
       for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
            ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
         {
-          Ipv4Interface *outInterface = *ifaceIter;
+          Ptr<Ipv4Interface> outInterface = *ifaceIter;
           Packet packetCopy = packet;
 
           NS_ASSERT (packetCopy.GetSize () <= outInterface->GetMtu ());
@@ -401,7 +407,7 @@
       return;
     }
   packet.AddHeader (ipHeader);
-  Ipv4Interface *outInterface = GetInterface (route.GetInterface ());
+  Ptr<Ipv4Interface> outInterface = GetInterface (route.GetInterface ());
   NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ());
   m_txTrace (packet, route.GetInterface ());
   if (route.IsGateway ()) 
@@ -431,7 +437,7 @@
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
        i != m_interfaces.end (); i++) 
     {
-      Ipv4Interface *interface = *i;
+      Ptr<Ipv4Interface> interface = *i;
       if (interface->GetDevice () == device)
 	{
 	  if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ())) 
@@ -481,43 +487,43 @@
 void 
 Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address)
 {
-  Ipv4Interface *interface = GetInterface (i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
   interface->SetAddress (address);
 }
 void 
 Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask)
 {
-  Ipv4Interface *interface = GetInterface (i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
   interface->SetNetworkMask (mask);
 }
 Ipv4Mask 
 Ipv4L3Protocol::GetNetworkMask (uint32_t i) const
 {
-  Ipv4Interface *interface = GetInterface (i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
   return interface->GetNetworkMask ();
 }
 Ipv4Address 
 Ipv4L3Protocol::GetAddress (uint32_t i) const
 {
-  Ipv4Interface *interface = GetInterface (i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
   return interface->GetAddress ();
 }
 uint16_t 
 Ipv4L3Protocol::GetMtu (uint32_t i) const
 {
-  Ipv4Interface *interface = GetInterface (i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
   return interface->GetMtu ();
 }
 bool 
 Ipv4L3Protocol::IsUp (uint32_t i) const
 {
-  Ipv4Interface *interface = GetInterface (i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
   return interface->IsUp ();
 }
 void 
 Ipv4L3Protocol::SetUp (uint32_t i)
 {
-  Ipv4Interface *interface = GetInterface (i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
   interface->SetUp ();
 
   // If interface address and network mask have been set, add a route
@@ -533,7 +539,7 @@
 void 
 Ipv4L3Protocol::SetDown (uint32_t ifaceIndex)
 {
-  Ipv4Interface *interface = GetInterface (ifaceIndex);
+  Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
   interface->SetDown ();
 
   // Remove all routes that are going through this interface
--- a/src/internet-node/ipv4-l3-protocol.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/ipv4-l3-protocol.h	Tue Sep 11 12:11:00 2007 +0200
@@ -44,6 +44,9 @@
 class TraceResolver;
 class TraceContext;
 
+/**
+ * \brief hold in a TraceContext the type of trace source used by this Ipv4L3Protocol
+ */
 class Ipv4L3ProtocolTraceContextElement : public TraceContextElement
 {
 public:
@@ -54,23 +57,40 @@
   };
   Ipv4L3ProtocolTraceContextElement ();
   Ipv4L3ProtocolTraceContextElement (enum Type type);
+  /**
+   * \returns true if this is a tx event, false otherwise.
+   */
   bool IsTx (void) const;
+  /**
+   * \returns true if this is a rx event, false otherwise.
+   */
   bool IsRx (void) const;
+  /**
+   * \returns true if this is a drop event, false otherwise.
+   */
   bool IsDrop (void) const;
   void Print (std::ostream &os) const;
   static uint16_t GetUid (void);
+  std::string GetTypeName (void) const;
 private:
   enum Type m_type;
 };
 
-class Ipv4l3ProtocolInterfaceIndex : public TraceContextElement
+/**
+ * \brief hold in a TraceContext the index of an Ipv4Interface within the ipv4 stack of a Node
+ */
+class Ipv4L3ProtocolInterfaceIndex : public TraceContextElement
 {
 public:
-  Ipv4l3ProtocolInterfaceIndex ();
-  Ipv4l3ProtocolInterfaceIndex (uint32_t index);
+  Ipv4L3ProtocolInterfaceIndex ();
+  Ipv4L3ProtocolInterfaceIndex (uint32_t index);
+  /**
+   * \returns the index of the Ipv4Interface within a Node.
+   */
   uint32_t Get (void) const;
   void Print (std::ostream &os) const;
   static uint16_t GetUid (void);
+  std::string GetTypeName (void) const;
 private:
   uint32_t m_index;
 };
@@ -86,15 +106,6 @@
   virtual ~Ipv4L3Protocol ();
 
   /**
-   * \param context the trace context to use to construct the
-   *        TraceResolver to return
-   * \returns a TraceResolver which can resolve all traces
-   *          performed in this object. The caller must
-   *          delete the returned object.
-   */
-  virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
-
-  /**
    * \param ttl default ttl to use
    *
    * When we need to send an ipv4 packet, we use this default
@@ -109,7 +120,7 @@
    * Try to find an Ipv4Interface whose NetDevice is equal to
    * the input NetDevice.
    */
-  Ipv4Interface *FindInterfaceForDevice (Ptr<const NetDevice> device);
+  Ptr<Ipv4Interface> FindInterfaceForDevice (Ptr<const NetDevice> device);
 
   /**
    * Lower layer calls this method after calling L3Demux::Lookup
@@ -159,7 +170,7 @@
   void RemoveRoute (uint32_t i);
 
   uint32_t AddInterface (Ptr<NetDevice> device);
-  Ipv4Interface * GetInterface (uint32_t i) const;
+  Ptr<Ipv4Interface> GetInterface (uint32_t i) const;
   uint32_t GetNInterfaces (void) const;
 
   
@@ -178,6 +189,7 @@
 protected:
 
   virtual void DoDispose (void);
+  virtual Ptr<TraceResolver> GetTraceResolver (void) const;
 
 private:
 
@@ -187,11 +199,10 @@
                     Ipv4Header const &ipHeader);
   bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device);
   void ForwardUp (Packet p, Ipv4Header const&ip);
-  uint32_t AddIpv4Interface (Ipv4Interface *interface);
+  uint32_t AddIpv4Interface (Ptr<Ipv4Interface> interface);
   void SetupLoopback (void);
-  TraceResolver *InterfacesCreateTraceResolver (TraceContext const &context) const;
 
-  typedef std::list<Ipv4Interface*> Ipv4InterfaceList;
+  typedef std::list<Ptr<Ipv4Interface> > Ipv4InterfaceList;
   typedef std::list< std::pair< int, Ptr<Ipv4RoutingProtocol> > > Ipv4RoutingProtocolList;
 
   Ipv4InterfaceList m_interfaces;
--- a/src/internet-node/ipv4-l4-demux.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/ipv4-l4-demux.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -54,6 +54,11 @@
   static uint16_t uid = AllocateUid<Ipv4L4ProtocolTraceContextElement> ("Ipv4L4ProtocolTraceContextElement");
   return uid;
 }
+std::string 
+Ipv4L4ProtocolTraceContextElement::GetTypeName (void) const
+{
+  return "ns3::Ipv4L4ProtocolTraceContextElement";
+}
 
 
 Ipv4L4Demux::Ipv4L4Demux (Ptr<Node> node)
@@ -78,21 +83,19 @@
   Object::DoDispose ();
 }
 
-TraceResolver *
-Ipv4L4Demux::CreateTraceResolver (TraceContext const &context)
+Ptr<TraceResolver>
+Ipv4L4Demux::GetTraceResolver (void) const
 {
-  CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+  Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
   for (L4List_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
     {
       Ptr<Ipv4L4Protocol> protocol = *i;
-      std::string protValue;
-      std::ostringstream oss (protValue);
-      oss << (*i)->GetProtocolNumber ();
+      std::ostringstream oss;
+      oss << (unsigned int) (*i)->GetProtocolNumber ();
       Ipv4L4ProtocolTraceContextElement protocolNumber = (*i)->GetProtocolNumber ();
-      resolver->Add (protValue,
-                     MakeCallback (&Ipv4L4Protocol::CreateTraceResolver, PeekPointer (protocol)),
-                     protocolNumber);
+      resolver->AddComposite (oss.str (), protocol, protocolNumber);
     }
+  resolver->SetParentResolver (Object::GetTraceResolver ());
   return resolver;
 }
 void
--- a/src/internet-node/ipv4-l4-demux.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/ipv4-l4-demux.h	Tue Sep 11 12:11:00 2007 +0200
@@ -37,14 +37,21 @@
 class TraceResolver;
 class TraceContext;
 
+/**
+ * \brief hold in a TraceContext the protocol number of a L4 Protocol
+ */
 class Ipv4L4ProtocolTraceContextElement : public TraceContextElement
 {
 public:
   Ipv4L4ProtocolTraceContextElement ();
   Ipv4L4ProtocolTraceContextElement (int protocolNumber);
+  /**
+   * \returns the protocol number as registered in the Ipv4L4Demux.
+   */
   int Get (void) const;
   void Print (std::ostream &os) const;
   static uint16_t GetUid (void);
+  std::string GetTypeName (void) const;
 private:
   int m_protocolNumber;
 };
@@ -60,14 +67,6 @@
   virtual ~Ipv4L4Demux();
 
   /**
-   * \param context the trace context to use to construct the
-   *        TraceResolver to return
-   * \returns a TraceResolver which can resolve all traces
-   *          performed in this object. The caller must
-   *          delete the returned object.
-   */
-  TraceResolver *CreateTraceResolver (TraceContext const &context);
-  /**
    * \param protocol a template for the protocol to add to this L4 Demux.
    * \returns the L4Protocol effectively added.
    *
@@ -95,8 +94,10 @@
    * returned from the Ipv4L4Protocol::Insert method.
    */
   void Remove (Ptr<Ipv4L4Protocol> protocol);
+protected:
+  Ptr<TraceResolver> GetTraceResolver (void) const;
+  virtual void DoDispose (void);
 private:
-  virtual void DoDispose (void);
   typedef std::list<Ptr<Ipv4L4Protocol> > L4List_t;
   L4List_t m_protocols;
   Ptr<Node> m_node;
--- a/src/internet-node/ipv4-l4-protocol.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/ipv4-l4-protocol.h	Tue Sep 11 12:11:00 2007 +0200
@@ -37,10 +37,6 @@
 /**
  * \brief L4 Protocol base class 
  *
- * All subclasses must implement:
- *   - Ipv4L4Protocol::Copy
- *   - Ipv4L4Protocol::CreateTraceResolver
- *
  * If you want to implement a new L4 protocol, all you have to do is
  * implement a subclass of this base class and add it to an L4Demux.
  */  
@@ -59,8 +55,6 @@
    */
   int GetVersion() const;
 
-  virtual TraceResolver *CreateTraceResolver (TraceContext const &context) = 0;
-
   /**
    * \param p packet to forward up
    * \param source source address of packet received
--- a/src/internet-node/ipv4-loopback-interface.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/ipv4-loopback-interface.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -19,7 +19,6 @@
  * Authors: 
  *  Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
  */
-#include "ns3/empty-trace-resolver.h"
 #include "ns3/net-device.h"
 #include "ns3/node.h"
 #include "ns3/eui48-address.h"
@@ -34,13 +33,6 @@
 {}
 Ipv4LoopbackInterface::~Ipv4LoopbackInterface ()
 {}
-
-TraceResolver *
-Ipv4LoopbackInterface::DoCreateTraceResolver (TraceContext const &context)
-{
-  return new EmptyTraceResolver (context);
-}
-
 void 
 Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest)
 {
--- a/src/internet-node/ipv4-loopback-interface.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/ipv4-loopback-interface.h	Tue Sep 11 12:11:00 2007 +0200
@@ -43,7 +43,6 @@
 
  private:
   virtual void SendTo (Packet p, Ipv4Address dest);
-  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
 
   Ptr<Node> m_node;
 };
--- a/src/internet-node/pcap-trace.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/pcap-trace.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -22,7 +22,7 @@
 
 #include <sstream>
 
-#include "ns3/trace-root.h"
+#include "ns3/node-list.h"
 #include "ns3/trace-context.h"
 #include "ns3/callback.h"
 #include "ns3/pcap-writer.h"
@@ -50,8 +50,8 @@
 void 
 PcapTrace::TraceAllIp (void)
 {
-  TraceRoot::Connect ("/nodes/*/ipv4/(tx|rx)",
-		      MakeCallback (&PcapTrace::LogIp, this));
+  NodeList::Connect ("/nodes/*/ipv4/(tx|rx)",
+                     MakeCallback (&PcapTrace::LogIp, this));
 }
 
 PcapWriter *
@@ -83,7 +83,7 @@
 PcapTrace::LogIp (TraceContext const &context, Packet const &p, uint32_t interfaceIndex)
 {
   NodeListIndex nodeIndex;
-  context.Get (nodeIndex);
+  context.GetElement (nodeIndex);
   PcapWriter *writer = GetStream (nodeIndex.Get (), interfaceIndex);
   writer->WritePacket (p);
 }
--- a/src/internet-node/udp-l4-protocol.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/udp-l4-protocol.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -21,7 +21,6 @@
 
 #include "ns3/assert.h"
 #include "ns3/packet.h"
-#include "ns3/empty-trace-resolver.h"
 #include "ns3/node.h"
 
 #include "udp-l4-protocol.h"
@@ -45,12 +44,6 @@
 UdpL4Protocol::~UdpL4Protocol ()
 {}
 
-TraceResolver *
-UdpL4Protocol::CreateTraceResolver (TraceContext const &context)
-{
-  return new EmptyTraceResolver (context);
-}
-
 void
 UdpL4Protocol::DoDispose (void)
 {
--- a/src/internet-node/udp-l4-protocol.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/internet-node/udp-l4-protocol.h	Tue Sep 11 12:11:00 2007 +0200
@@ -49,7 +49,6 @@
   UdpL4Protocol (Ptr<Node> node);
   virtual ~UdpL4Protocol ();
 
-  virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
   /**
    * \return A smart Socket pointer to a UdpSocket, allocated by this instance
    * of the UDP protocol
--- a/src/mobility/hierarchical-mobility-model.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/mobility/hierarchical-mobility-model.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -41,8 +41,8 @@
       parentNotifier = Create<MobilityModelNotifier> ();
       parent->AddInterface (parentNotifier);
     }
-  childNotifier->RegisterListener (MakeCallback (&HierarchicalMobilityModel::ChildChanged, this));
-  parentNotifier->RegisterListener (MakeCallback (&HierarchicalMobilityModel::ParentChanged, this));
+  childNotifier->TraceConnect ("/course-changed", MakeCallback (&HierarchicalMobilityModel::ChildChanged, this));
+  parentNotifier->TraceConnect ("/course-changed", MakeCallback (&HierarchicalMobilityModel::ParentChanged, this));
 }
 
 Ptr<MobilityModel> 
@@ -89,13 +89,13 @@
 }
 
 void 
-HierarchicalMobilityModel::ParentChanged (Ptr<const MobilityModel> model)
+HierarchicalMobilityModel::ParentChanged (const TraceContext &context, Ptr<const MobilityModel> model)
 {
   MobilityModel::NotifyCourseChange ();
 }
 
 void 
-HierarchicalMobilityModel::ChildChanged (Ptr<const MobilityModel> model)
+HierarchicalMobilityModel::ChildChanged (const TraceContext &context, Ptr<const MobilityModel> model)
 {
   MobilityModel::NotifyCourseChange ();
 }
--- a/src/mobility/hierarchical-mobility-model.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/mobility/hierarchical-mobility-model.h	Tue Sep 11 12:11:00 2007 +0200
@@ -63,8 +63,8 @@
   virtual void DoSet (const Position &position);
   virtual Speed DoGetSpeed (void) const;
 
-  void ParentChanged (Ptr<const MobilityModel> model);
-  void ChildChanged (Ptr<const MobilityModel> model);
+  void ParentChanged (const TraceContext &context, Ptr<const MobilityModel> model);
+  void ChildChanged (const TraceContext &context, Ptr<const MobilityModel> model);
 
   Ptr<MobilityModel> m_child;
   Ptr<MobilityModel> m_parent;
--- a/src/mobility/mobility-model-notifier.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/mobility/mobility-model-notifier.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -19,6 +19,8 @@
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 #include "mobility-model-notifier.h"
+#include "ns3/composite-trace-resolver.h"
+#include "ns3/trace-doc.h"
 
 namespace ns3 {
 
@@ -33,36 +35,23 @@
 }
 
 void 
-MobilityModelNotifier::RegisterListener (Listener listener)
-{
-  m_listeners.push_back (listener);
-}
-void 
-MobilityModelNotifier::UnregisterListener (Listener callback)
-{
-  for (std::list<Listener>::iterator i = m_listeners.begin ();
-       i != m_listeners.end ();)
-    {
-      Listener listener = *i;
-      if (listener.IsEqual (callback))
-	{
-	  i = m_listeners.erase (i);
-	}
-      else
-	{
-	  i++;
-	}
-    }  
-}
-void 
 MobilityModelNotifier::Notify (Ptr<const MobilityModel> position) const
 {
-  for (std::list<Listener>::const_iterator i = m_listeners.begin ();
-       i != m_listeners.end (); i++)
-    {
-      Listener listener = *i;
-      listener (position);
-    }
+  m_trace (position);
+}
+
+Ptr<TraceResolver> 
+MobilityModelNotifier::GetTraceResolver (void) const
+{
+  Ptr<CompositeTraceResolver> resolver = 
+    Create<CompositeTraceResolver> ();
+  resolver->AddSource ("course-change", 
+                       TraceDoc ("The value of the speed vector changed",
+                                 "Ptr<const MobilityModel>", 
+                                 "the mobility model whose course changed"),
+                       m_trace);
+  resolver->SetParentResolver (Object::GetTraceResolver ());
+  return resolver;
 }
 
 } // namespace ns3
--- a/src/mobility/mobility-model-notifier.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/mobility/mobility-model-notifier.h	Tue Sep 11 12:11:00 2007 +0200
@@ -24,6 +24,7 @@
 #include "ns3/object.h"
 #include "ns3/component-manager.h"
 #include "ns3/callback.h"
+#include "ns3/callback-trace-source.h"
 #include "mobility-model.h"
 
 namespace ns3 {
@@ -37,8 +38,6 @@
   static const InterfaceId iid;
   static const ClassId cid;
 
-  typedef Callback<void,Ptr<const MobilityModel> > Listener;
-
   /**
    * Create a new position notifier
    */
@@ -48,23 +47,10 @@
    * \param position the position which just changed.
    */
   void Notify (Ptr<const MobilityModel> position) const;
-
-  /**
-   * \param listener listener to add
-   *
-   * The listener will be notified upon every position change.
-   */
-  void RegisterListener (Listener listener);
-  /**
-   * \param listener listener to remove
-   *
-   * The listener will not be notified anymore upon every 
-   * position change. It is not an error to try to unregister
-   * a non-registered liste
-   */
-  void UnregisterListener (Listener listener);
+protected:
+  virtual Ptr<TraceResolver> GetTraceResolver (void) const;
 private:
-  std::list<Listener> m_listeners;
+  CallbackTraceSource<Ptr<const MobilityModel> > m_trace;
 };
 
 } // namespace ns3
--- a/src/node/net-device.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/node/net-device.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -23,6 +23,7 @@
 #include "ns3/assert.h"
 #include "ns3/object.h"
 #include "ns3/debug.h"
+#include "ns3/trace-resolver.h"
 
 
 #include "channel.h"
@@ -183,12 +184,6 @@
     }
 }
 
-TraceResolver *
-NetDevice::CreateTraceResolver (TraceContext const &context)
-{
-  return DoCreateTraceResolver (context);
-}
-
 Ptr<Channel>
 NetDevice::GetChannel (void) const
 {
--- a/src/node/net-device.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/node/net-device.h	Tue Sep 11 12:11:00 2007 +0200
@@ -62,14 +62,6 @@
   static const InterfaceId iid;
   virtual ~NetDevice();
 
-  /**
-   * \param context the trace context to use to construct the
-   *        TraceResolver to return
-   * \returns a TraceResolver which can resolve all traces
-   *          performed in this object. The caller must
-   *          delete the returned object.
-   */
-  TraceResolver *CreateTraceResolver (TraceContext const &context);
 
   /**
    * \return the channel this NetDevice is connected to. The value
@@ -283,15 +275,6 @@
    */
   virtual bool DoNeedsArp (void) const = 0;
   /**
-   * \param context the trace context to associated to the
-   *        trace resolver.
-   * \returns a trace resolver associated to the input context.
-   *          the caller takes ownership of the pointer returned.
-   *
-   * Subclasses must implement this method.
-   */
-  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
-  /**
    * \returns the channel associated to this NetDevice.
    *
    * Subclasses must implement this method.
--- a/src/node/node-list.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/node/node-list.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -20,24 +20,12 @@
  *  Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
  */
 
-#include "ns3/array-trace-resolver.h"
-#include "ns3/trace-root.h"
+#include "ns3/composite-trace-resolver.h"
 #include "ns3/simulator.h"
 #include "ns3/simulation-singleton.h"
 #include "node-list.h"
 #include "node.h"
 
-namespace {
-static class Initialization 
-{
-public:
-  Initialization ()
-  {
-    ns3::TraceRoot::Register ("nodes", ns3::MakeCallback (&ns3::NodeList::CreateTraceResolver));
-  }
-} g_initialization;
-}
-
 namespace ns3 {
 
 NodeListIndex::NodeListIndex ()
@@ -62,6 +50,11 @@
 {
   return m_index;
 }
+std::string 
+NodeListIndex::GetTypeName (void) const
+{
+  return "ns3::NodeListIndex";
+}
 
 
 /**
@@ -74,9 +67,9 @@
   ~NodeListPriv ();
 
   uint32_t Add (Ptr<Node> node);
-  NodeList::Iterator Begin (void);
-  NodeList::Iterator End (void);
-  TraceResolver *CreateTraceResolver (TraceContext const &context);
+  NodeList::Iterator Begin (void) const;
+  NodeList::Iterator End (void) const;
+  Ptr<TraceResolver> GetTraceResolver (void) const;
   Ptr<Node> GetNode (uint32_t n);
   uint32_t GetNNodes (void);
 
@@ -108,12 +101,12 @@
   
 }
 NodeList::Iterator 
-NodeListPriv::Begin (void)
+NodeListPriv::Begin (void) const
 {
   return m_nodes.begin ();
 }
 NodeList::Iterator 
-NodeListPriv::End (void)
+NodeListPriv::End (void) const
 {
   return m_nodes.end ();
 }
@@ -130,14 +123,11 @@
 }
 
 
-TraceResolver *
-NodeListPriv::CreateTraceResolver (TraceContext const &context)
+Ptr<TraceResolver>
+NodeListPriv::GetTraceResolver (void) const
 {
-  ArrayTraceResolver<Ptr<Node>, NodeListIndex> *resolver =
-    new ArrayTraceResolver<Ptr<Node>, NodeListIndex>
-    (context, 
-     MakeCallback (&NodeListPriv::GetNNodes, this),
-     MakeCallback (&NodeListPriv::GetNode, this));
+  Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+  resolver->AddArray ("nodes", Begin (), End (), NodeListIndex ());
   return resolver;
 }
 
@@ -165,17 +155,30 @@
 {
   return SimulationSingleton<NodeListPriv>::Get ()->End ();
 }
-TraceResolver *
-NodeList::CreateTraceResolver (TraceContext const &context)
-{
-  return SimulationSingleton<NodeListPriv>::Get ()->CreateTraceResolver (context);
-}
 Ptr<Node>
 NodeList::GetNode (uint32_t n)
 {
   return SimulationSingleton<NodeListPriv>::Get ()->GetNode (n);
 }
 
-
-
+void 
+NodeList::Connect (std::string name, const CallbackBase &cb)
+{
+  SimulationSingleton<NodeListPriv>::Get ()->GetTraceResolver ()->Connect (name, cb, TraceContext ());
+}
+void 
+NodeList::Disconnect (std::string name, const CallbackBase &cb)
+{
+  SimulationSingleton<NodeListPriv>::Get ()->GetTraceResolver ()->Disconnect (name, cb);
+}
+void 
+NodeList::TraceAll (std::ostream &os)
+{
+  SimulationSingleton<NodeListPriv>::Get ()->GetTraceResolver ()->TraceAll (os, TraceContext ());
+}
+Ptr<TraceResolver> 
+NodeList::GetTraceResolver (void)
+{
+  return SimulationSingleton<NodeListPriv>::Get ()->GetTraceResolver ();
+}
 }//namespace ns3
--- a/src/node/node-list.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/node/node-list.h	Tue Sep 11 12:11:00 2007 +0200
@@ -29,9 +29,12 @@
 namespace ns3 {
 
 class Node;
+class CallbackBase;
 class TraceResolver;
-class TraceContext;
 
+/**
+ * \brief hold in a TraceContext the index of a node within a NodeList.
+ */
 class NodeListIndex : public TraceContextElement
 {
 public:
@@ -39,7 +42,11 @@
   NodeListIndex (uint32_t index);
   void Print (std::ostream &os);
   static uint16_t GetUid (void);
+  /**
+   * \returns the index of the node within the NodeList
+   */
   uint32_t Get (void) const;
+  std::string GetTypeName (void) const;
 private:
   uint32_t m_index;
 };
@@ -53,7 +60,7 @@
 class NodeList
 {
 public:
-  typedef std::vector< Ptr<Node> >::iterator Iterator;
+  typedef std::vector< Ptr<Node> >::const_iterator Iterator;
 
   /**
    * \param node node to add
@@ -74,18 +81,29 @@
    */
   static Iterator End (void);
   /**
-   * \param context trace context to use for trace resolver
-   *        to create.
-   * \returns the requested trace resolver. The caller
-   *          takes ownership of the returned pointer.
-   */
-  static TraceResolver *CreateTraceResolver (TraceContext const &context);
-
-  /**
    * \param n index of requested node.
    * \returns the Node associated to index n.
    */
   static Ptr<Node> GetNode (uint32_t n);
+  /**
+   * \param name namespace regexp to match
+   * \param cb callback to connect
+   *
+   * Connect input callback to all trace sources which match
+   * the input namespace regexp.
+   */
+  static void Connect (std::string name, const CallbackBase &cb);
+  /**
+   * \param name namespace regexp to match
+   * \param cb callback to connect
+   *
+   * Disconnect input callback from all trace sources which match
+   * the input namespace regexp.
+   */
+  static void Disconnect (std::string name, const CallbackBase &cb);
+  static void TraceAll (std::ostream &os);
+  static Ptr<TraceResolver> GetTraceResolver (void);
+private:
 };
 
 }//namespace ns3
--- a/src/node/node.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/node/node.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -25,7 +25,6 @@
 #include "packet-socket-factory.h"
 #include "ns3/simulator.h"
 #include "ns3/composite-trace-resolver.h"
-#include "ns3/array-trace-resolver.h"
 
 namespace ns3{
 
@@ -53,6 +52,11 @@
   static uint16_t uid = AllocateUid<NodeNetDeviceIndex> ("NodeNetDeviceIndex");
   return uid;
 }
+std::string 
+NodeNetDeviceIndex::GetTypeName (void) const
+{
+  return "ns3::NodeNetDeviceIndex";
+}
 
 
 
@@ -82,11 +86,12 @@
 Node::~Node ()
 {}
 
-TraceResolver *
-Node::CreateTraceResolver (TraceContext const &context)
+Ptr<TraceResolver>
+Node::GetTraceResolver (void) const
 {
-  CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
-  DoFillTraceResolver (*resolver);
+  Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+  resolver->AddArray ("devices", m_devices.begin (), m_devices.end (), NodeNetDeviceIndex ());
+  resolver->SetParentResolver (Object::GetTraceResolver ());
   return resolver;
 }
 
@@ -141,25 +146,6 @@
   return m_applications.size ();
 }
 
-TraceResolver *
-Node::CreateDevicesTraceResolver (const TraceContext &context)
-{
-  ArrayTraceResolver<Ptr<NetDevice>,NodeNetDeviceIndex> *resolver = 
-    new ArrayTraceResolver<Ptr<NetDevice>,NodeNetDeviceIndex> 
-    (context,
-     MakeCallback (&Node::GetNDevices, this), 
-     MakeCallback (&Node::GetDevice, this));
-  
-  return resolver;
-}
-
-void
-Node::DoFillTraceResolver (CompositeTraceResolver &resolver)
-{
-  resolver.Add ("devices", 
-                MakeCallback (&Node::CreateDevicesTraceResolver, this));
-}
-
 void 
 Node::DoDispose()
 {
--- a/src/node/node.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/node/node.h	Tue Sep 11 12:11:00 2007 +0200
@@ -37,13 +37,20 @@
 class Address;
 class CompositeTraceResolver;
 
+/**
+ * \brief hold in a TraceContext the index of a NetDevice within a Node
+ */
 class NodeNetDeviceIndex : public TraceContextElement
 {
 public:
   NodeNetDeviceIndex ();
   NodeNetDeviceIndex (uint32_t index);
+  /**
+   * \returns the index of the NetDevice within its container Node.
+   */
   uint32_t Get (void) const;
   void Print (std::ostream &os) const;
+  std::string GetTypeName (void) const;
   static uint16_t GetUid (void);
 private:
   uint32_t m_index;
@@ -85,17 +92,6 @@
   virtual ~Node();
 
   /**
-   * \param context the trace context for the TraceResolver to create
-   * \returns a newly-created TraceResolver. The caller takes
-   *          ownership of the returned pointer.
-   *
-   * Request the Node to create a trace resolver. This method
-   * could be used directly by a user who needs access to very low-level
-   * trace configuration.
-   */
-  TraceResolver *CreateTraceResolver (TraceContext const &context);
-
-  /**
    * \returns the unique id of this node.
    * 
    * This unique id happens to be also the index of the Node into
@@ -183,23 +179,15 @@
   void UnregisterProtocolHandler (ProtocolHandler handler);
 
 protected:
+  virtual Ptr<TraceResolver> GetTraceResolver (void) const;
   /**
    * The dispose method. Subclasses must override this method
    * and must chain up to it by calling Node::DoDispose at the
    * end of their own DoDispose method.
    */
   virtual void DoDispose (void);
-  /**
-   * \param resolver the resolver to store trace sources in.
-   *
-   * If a subclass wants to add new traces to a Node, it needs
-   * to override this method and record the new trace sources
-   * in the input resolver. Subclasses also _must_ chain up to
-   * their parent's DoFillTraceResolver method prior
-   * to recording they own trace sources.
-   */
-  virtual void DoFillTraceResolver (CompositeTraceResolver &resolver);
 private:
+
   /**
    * \param device the device added to this Node.
    *
@@ -213,7 +201,6 @@
   bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &packet, 
                           uint16_t protocol, const Address &from);
   void Construct (void);
-  TraceResolver *CreateDevicesTraceResolver (const TraceContext &context);
 
   struct ProtocolHandlerEntry {
     ProtocolHandler handler;
--- a/src/node/queue.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/node/queue.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -32,6 +32,11 @@
                                                   Queue::iid, "DropTailQueue");
 
 
+std::string 
+QueueTraceType::GetTypeName (void) const
+{
+  return "ns3::QueueTraceType";
+}
 uint16_t 
 QueueTraceType::GetUid (void)
 {
@@ -94,13 +99,23 @@
   NS_DEBUG("Queue::~Queue ()");
 }
 
-TraceResolver *
-Queue::CreateTraceResolver (TraceContext const &context)
+Ptr<TraceResolver>
+Queue::GetTraceResolver (void) const
 {
-  CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
-  resolver->Add ("enqueue", m_traceEnqueue, QueueTraceType (QueueTraceType::ENQUEUE));
-  resolver->Add ("dequeue", m_traceDequeue, QueueTraceType (QueueTraceType::DEQUEUE));
-  resolver->Add ("drop", m_traceDrop, QueueTraceType (QueueTraceType::DROP));
+  Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+  resolver->AddSource ("enqueue", 
+                       TraceDoc ("store packet in queue",
+                                 "const Packet &", "packet queued"),
+                       m_traceEnqueue, QueueTraceType (QueueTraceType::ENQUEUE));
+  resolver->AddSource ("dequeue", 
+                       TraceDoc ("remove packet from queue",
+                                 "const Packet &", "packet dequeued"),
+                       m_traceDequeue, QueueTraceType (QueueTraceType::DEQUEUE));
+  resolver->AddSource ("drop", 
+                       TraceDoc ("drop packet from queue", 
+                                 "const Packet &", "packet dropped"),
+                       m_traceDrop, QueueTraceType (QueueTraceType::DROP));
+  resolver->SetParentResolver (Object::GetTraceResolver ());
   return resolver;
 }
 
--- a/src/node/queue.h	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/node/queue.h	Tue Sep 11 12:11:00 2007 +0200
@@ -37,6 +37,9 @@
 
 class StringEnumDefaultValue;
 
+/**
+ * \brief hold in a TraceContext the type of a trace source 
+ */
 class QueueTraceType : public TraceContextElement
 {
 public:
@@ -48,10 +51,20 @@
   static uint16_t GetUid (void);
   QueueTraceType ();
   QueueTraceType (enum Type type);
+  /**
+   * \returns true if this is an enqueue event, false otherwise.
+   */
   bool IsEnqueue (void) const;
+  /**
+   * \returns true if this is a dequeue event, false otherwise.
+   */
   bool IsDequeue (void) const;
+  /**
+   * \returns true if this is a drop event, false otherwise.
+   */
   bool IsDrop (void) const;
   void Print (std::ostream &os) const;
+  std::string GetTypeName (void) const;
 private:
   enum Type m_type;
 };
@@ -69,8 +82,6 @@
 
   Queue ();
   virtual ~Queue ();
-
-  TraceResolver *CreateTraceResolver (TraceContext const &context);
   
   /**
    * \return true if the queue is empty; false otherwise
@@ -167,6 +178,7 @@
   virtual bool DoPeek (Packet &p) = 0;
 
 protected:
+  Ptr<TraceResolver> GetTraceResolver (void) const;
   // called by subclasses to notify parent of packet drops.
   void Drop (const Packet& p);
 
--- a/src/routing/global-routing/global-route-manager-impl.cc	Tue Sep 11 10:35:56 2007 +0200
+++ b/src/routing/global-routing/global-route-manager-impl.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -1407,27 +1407,6 @@
 
 namespace ns3 {
 
-class GlobalRouterTestNode : public Node
-{
-public:
-  GlobalRouterTestNode ();
-
-private:
-  virtual void DoAddDevice (Ptr<NetDevice> device) const {};
-  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
-};
-
-GlobalRouterTestNode::GlobalRouterTestNode ()
-{
-//  Ptr<Ipv4L3Protocol> ipv4 = Create<Ipv4L3Protocol> (this);
-}
-
-  TraceResolver*
-GlobalRouterTestNode::DoCreateTraceResolver (TraceContext const &context)
-{
-  return 0;
-}
-
 class GlobalRouteManagerImplTest : public Test {
 public:
   GlobalRouteManagerImplTest ();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/print-trace-sources.cc	Tue Sep 11 12:11:00 2007 +0200
@@ -0,0 +1,100 @@
+#include "ns3/internet-node.h"
+#include "ns3/ptr.h"
+#include "ns3/trace-resolver.h"
+#include "ns3/node-list.h"
+#include "ns3/point-to-point-net-device.h"
+#include "ns3/csma-net-device.h"
+#include "ns3/queue.h"
+#include "ns3/mobility-model-notifier.h"
+
+using namespace ns3;
+
+void
+PrintSimpleText (const TraceResolver::SourceCollection *sources, std::ostream &os)
+{
+  for (TraceResolver::SourceCollection::Iterator i = sources->Begin (); i != sources->End (); i++)
+    {
+      os << "source=" << i->path << std::endl;
+      os << "TraceContext=[";
+      i->context.PrintAvailable (os, ",");
+      os << "]" << std::endl;
+      os << "help=\"" << i->doc.GetHelp () << "\"" << std::endl;
+      os << "void TraceSinkCallback (const TraceContext &";
+      for (TraceDoc::Iterator k = i->doc.ArgsBegin (); k != i->doc.ArgsEnd (); k++)
+        {
+          os << ", " << k->first;
+        }
+      os << ")" << std::endl;
+      os << "argument 1  --  the trace context associated to the connected trace source." << std::endl;
+      uint32_t k = 2;
+      for (TraceDoc::Iterator j = i->doc.ArgsBegin (); j != i->doc.ArgsEnd (); j++)
+        {
+          os << "argument " << k << "  --  " << j->second << "." << std::endl;
+          k++;
+        }
+      os << std::endl;
+    }
+}
+void
+PrintDoxygenText (const TraceResolver::SourceCollection *sources, std::ostream &os)
+{
+  uint32_t z = 0;
+  for (TraceResolver::SourceCollection::Iterator i = sources->Begin (); i != sources->End (); i++)
+    {
+      os << "///" << std::endl;
+      os << "/// \\ingroup TraceSourceList" << std::endl; 
+      os << "/// \\brief " << i->doc.GetHelp () << std::endl;
+      os << "/// \\param arg1 the trace context associated to the connected trace source." << std::endl;
+      uint32_t j = 2;
+      for (TraceDoc::Iterator l = i->doc.ArgsBegin (); l != i->doc.ArgsEnd (); l++)
+        {
+          os << "/// \\param arg" << j << " " << l->second << "." << std::endl;
+          j++;
+        }
+      os << "///" << std::endl;
+      os << "///" << std::endl;
+      os << "/// The path to this trace source is: " << i->path << "." << std::endl;
+      os << "///" << std::endl;
+      if (i->context.Begin ().IsLast ())
+        {
+          os << "/// No data can be extracted from \\p arg1 with ns3::TraceContext::GetElement." << std::endl;
+        }
+      else
+        {
+          os << "/// The following classes can be extracted from \\p arg1 with " << std::endl;
+          os << "/// ns3::TraceContext::GetElement:" << std::endl;
+          for (TraceContext::Iterator m = i->context.Begin (); !m.IsLast (); m.Next ())
+            {
+              os << "///  - " << m.Get () << std::endl;
+            }
+        }
+      os << "void TraceSinkCallback" << z << " (const TraceContext & arg1" ;
+      j = 2;
+      for (TraceDoc::Iterator k = i->doc.ArgsBegin (); k != i->doc.ArgsEnd (); k++)
+        {
+          os << ", " << k->first << " arg" << j;
+          j++;
+        }
+      os << ");" << std::endl;
+      os << std::endl;
+      z++;
+    }
+}
+
+
+int main (int argc, char *argv[])
+{
+  Ptr<Node> node = Create<InternetNode> ();
+  node->AddInterface (Create<MobilityModelNotifier> ());
+
+  Ptr<PointToPointNetDevice> p2p = Create<PointToPointNetDevice> (node);
+  p2p->AddQueue (Queue::CreateDefault ());
+  Ptr<CsmaNetDevice> csma = Create<CsmaNetDevice> (node);
+  csma->AddQueue (Queue::CreateDefault ());
+
+  TraceResolver::SourceCollection collection;
+  NodeList::GetTraceResolver ()->CollectSources ("", TraceContext (), &collection);
+  PrintDoxygenText (&collection, std::cout);
+
+  return 0;
+}
--- a/utils/wscript	Tue Sep 11 10:35:56 2007 +0200
+++ b/utils/wscript	Tue Sep 11 12:11:00 2007 +0200
@@ -19,3 +19,7 @@
 
     obj = bld.create_ns3_program('replay-simulation', ['simulator'])
     obj.source = 'replay-simulation.cc'
+
+    obj = bld.create_ns3_program('print-trace-sources',
+                                 ['internet-node', 'csma-cd', 'point-to-point'])
+    obj.source = 'print-trace-sources.cc'