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 &