move trace code to core module
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Fri, 10 Aug 2007 15:53:43 +0200
changeset 1334 e8e07f44359f
parent 1333 c0d66de933e9
child 1335 d0e45d84f9c6
move trace code to core module
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/common/wscript
src/core/array-trace-resolver.h
src/core/callback-trace-source.cc
src/core/callback-trace-source.h
src/core/composite-trace-resolver.cc
src/core/composite-trace-resolver.h
src/core/empty-trace-resolver.cc
src/core/empty-trace-resolver.h
src/core/fv-trace-source.h
src/core/stream-tracer-test.cc
src/core/stream-tracer.h
src/core/sv-trace-source.h
src/core/terminal-trace-resolver.h
src/core/trace-context-element.cc
src/core/trace-context-element.h
src/core/trace-context.cc
src/core/trace-context.h
src/core/trace-resolver.cc
src/core/trace-resolver.h
src/core/trace-root.cc
src/core/trace-root.h
src/core/uv-trace-source.h
src/core/variable-tracer-test.cc
src/core/wscript
--- a/src/common/array-trace-resolver.h	Fri Aug 10 15:47:13 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +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 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:
-   * Ptr<TraceResolver> (*) (void)
-   */
-  ArrayTraceResolver (Callback<uint32_t> getSize, 
-                      Callback<T, uint32_t> get);
-
-  virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context);
-  virtual void Disconnect (std::string path, CallbackBase const &cb);
-private:
-  Callback<uint32_t> m_getSize;
-  Callback<T, uint32_t> m_get;
-};
-}//namespace ns3
-
-namespace ns3 {
-
-template <typename T, typename INDEX>
-ArrayTraceResolver<T,INDEX>::ArrayTraceResolver (Callback<uint32_t> getSize, 
-                                                 Callback<T, uint32_t> get)
-  : m_getSize (getSize),
-    m_get (get)
-{}
-
-template <typename T, typename INDEX>
-void 
-ArrayTraceResolver<T,INDEX>::Connect (std::string path, CallbackBase const &cb, const TraceContext &context)
-{
-  std::string id = GetElement (path);
-  std::string subpath = GetSubpath (path);
-  if (id == "*")
-  {
-    for (uint32_t i = 0; i < m_getSize (); i++)
-    {
-      TraceContext tmp = context;
-      INDEX index = i;
-      tmp.Add (index);
-      Ptr<TraceResolver> resolver = m_get (i)->CreateTraceResolver ();
-      resolver->Connect (subpath, cb, tmp);
-    }
-  }
-}
-template <typename T, typename INDEX>
-void 
-ArrayTraceResolver<T,INDEX>::Disconnect (std::string path, CallbackBase const &cb)
-{
-  std::string id = GetElement (path);
-  std::string subpath = GetSubpath (path);
-  if (id == "*")
-  {
-    for (uint32_t i = 0; i < m_getSize (); i++)
-    {
-      Ptr<TraceResolver> resolver = m_get (i)->CreateTraceResolver ();
-      resolver->Disconnect (subpath, cb);
-    }
-  }
-}
-
-
-}//namespace ns3
-
-#endif /* ARRAY_TRACE_RESOLVER_H */
--- a/src/common/callback-trace-source.cc	Fri Aug 10 15:47:13 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	Fri Aug 10 15:47:13 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	Fri Aug 10 15:47:13 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,410 +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"
-#include "ns3/debug.h"
-
-NS_DEBUG_COMPONENT_DEFINE ("CompositeTraceResolver");
-
-namespace ns3 {
-
-CompositeTraceResolver::CompositeTraceResolver ()
-{}
-
-CompositeTraceResolver::~CompositeTraceResolver ()
-{}
-
-void 
-CompositeTraceResolver::Add (std::string name, 
-                             Callback<Ptr<TraceResolver> > createResolver)
-{
-  DoAdd (name, createResolver, TraceContext ());
-}
-
-void 
-CompositeTraceResolver::DoAdd (std::string name, 
-			       Callback<Ptr<TraceResolver> > createResolver,
-			       TraceContext const &context)
-{
-  struct CallbackTraceSourceItem item;
-  item.name = name;
-  item.createResolver = createResolver;
-  item.context = context;
-  m_items.push_back (item);
-}
-
-void 
-CompositeTraceResolver::Connect (std::string path, CallbackBase const &cb, const TraceContext &context)
-{
-  NS_DEBUG ("connect path="<<path);
-  DoRecursiveOperation (path, cb, context, CONNECT);
-}
-void 
-CompositeTraceResolver::DoRecursiveOperation (std::string path, CallbackBase const &cb, 
-                                              const TraceContext &context,
-                                              enum Operation op)
-{
-  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++)
-	{
-          OperationOne (subpath, i, cb, context, op);
-        }
-      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)
-	    {
-              OperationOne (subpath, i, cb, context, op);
-              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)
-	    {
-              OperationOne (subpath, j, cb, context, op);
-	      break;
-	    }
-	}
-    }
-}
-
-void 
-CompositeTraceResolver::OperationOne (std::string subpath, 
-                                      TraceItems::const_iterator i,
-                                      const CallbackBase &cb,
-                                      const TraceContext &context,
-                                      enum Operation op)
-{
-  Ptr<TraceResolver> resolver = i->createResolver ();
-  switch (op) {
-  case CONNECT: {
-    NS_DEBUG ("connect to path="<<subpath<<" name="<<i->name);
-    TraceContext ctx = context;
-    ctx.Add (i->context);
-    resolver->Connect (subpath, cb, ctx);
-    } break;
-  case DISCONNECT:
-    resolver->Disconnect (subpath, cb);
-    break;
-  }
-}
-
-void 
-CompositeTraceResolver::Disconnect (std::string path, CallbackBase const &cb)
-{
-  DoRecursiveOperation (path, cb, TraceContext (), DISCONNECT);
-}
-
-}//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);
-  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.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;
-}
-
-Ptr<TraceResolver>
-CompositeTraceResolverTest::CreateSubResolver (void)
-{
-  Ptr<CompositeTraceResolver> subresolver = Create<CompositeTraceResolver> ();
-  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;
-
-  resolver.Add ("trace-double-a", traceDoubleA, 
-                TraceSourceTest (TraceSourceTest::DOUBLEA));
-  resolver.Add ("trace-double-b", 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),
-		TraceSourceTest (TraceSourceTest::SUBRESOLVER));
-
-  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;
-    }
-
-
-  
-
-  return ok;
-}
-
-static CompositeTraceResolverTest g_compositeTraceResolverTest;
-
-}//namespace ns3
-
-
-#endif /* RUN_SELF_TESTS */
--- a/src/common/composite-trace-resolver.h	Fri Aug 10 15:47:13 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +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 "ns3/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 "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 ();
-  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<Ptr<TraceResolver> > 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<Ptr<TraceResolver> > createResolver);
-  virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context);
-  virtual void Disconnect (std::string path, CallbackBase const &cb);
-
-private:
-  struct CallbackTraceSourceItem
-  {
-    std::string name;
-    Callback<Ptr<TraceResolver> > createResolver;
-    TraceContext context;
-  };
-  typedef std::list<struct CallbackTraceSourceItem> TraceItems;
-  enum Operation {
-    CONNECT,
-    DISCONNECT
-  };
-
-  template <typename SOURCE, typename CONTEXT>
-  void DoAddTraceSource (std::string name,
-                         SOURCE &traceSource, CONTEXT const &context);
-  template <typename SOURCE>
-  static Ptr<TraceResolver> CreateTerminalTraceResolver (SOURCE *trace);
-  void DoAdd (std::string name, 
-              Callback<Ptr<TraceResolver> > createResolver,
-              TraceContext const &context);
-  void OperationOne (std::string subpath, 
-                     TraceItems::const_iterator i,
-                     const CallbackBase &cb,
-                     const TraceContext &context,
-                     enum Operation op);
-  void DoRecursiveOperation (std::string path, CallbackBase const &cb, 
-                             const TraceContext &context,
-                             enum Operation op);
-
-
-
-  TraceItems m_items;
-};
-
-}//namespace ns3
-
-namespace ns3 {
-
-template <typename SOURCE, typename CONTEXT>
-void 
-CompositeTraceResolver::DoAddTraceSource (std::string name,
-                                          SOURCE &traceSource, CONTEXT const &context)
-{
-  Ptr<TraceResolver> (*create) (SOURCE *trace);
-  create = &CompositeTraceResolver::CreateTerminalTraceResolver<SOURCE>;
-  Callback<Ptr<TraceResolver> > createResolver = 
-    MakeBoundCallback (create, &traceSource);
-
-  TraceContext ctx;
-  ctx.Add (context);
-  DoAdd (name, createResolver, ctx);
-}
-
-template <typename SOURCE>
-Ptr<TraceResolver>
-CompositeTraceResolver::CreateTerminalTraceResolver (SOURCE *traceSource)
-{
-  return Create<TerminalTraceResolver<SOURCE> > (traceSource);
-}
-
-
-
-
-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<Ptr<TraceResolver> > createResolver,
-                             T const &context)
-{
-  TraceContext ctx;
-  ctx.Add (context);
-  DoAdd (name, createResolver, ctx);
-}
-
-}//namespace ns3
-
-#endif /* COMPOSITE_TRACE_RESOLVER_H */
--- a/src/common/empty-trace-resolver.cc	Fri Aug 10 15:47:13 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +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 ()
-{}
--- a/src/common/empty-trace-resolver.h	Fri Aug 10 15:47:13 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 ();
-};
-
-}//namespace ns3
-
-#endif /* EMPTY_TRACE_RESOLVER_H */
--- a/src/common/fv-trace-source.h	Fri Aug 10 15:47:13 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/stream-tracer-test.cc	Fri Aug 10 15:47:13 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	Fri Aug 10 15:47:13 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	Fri Aug 10 15:47:13 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	Fri Aug 10 15:47:13 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +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"
-#include "ns3/assert.h"
-
-namespace ns3 {
-
-class TraceContext;
-
-template <typename T>
-class TerminalTraceResolver : public TraceResolver
-{
- public:
-  TerminalTraceResolver (T *traceSource);
-
-  virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context);
-  virtual void Disconnect (std::string path, CallbackBase const &cb);
- private:
-  T *m_traceSource;
-};
-
-}//namespace ns3
-
-namespace ns3 {
-
-template <typename T>
-TerminalTraceResolver<T>::TerminalTraceResolver (T *traceSource)
-  : m_traceSource (traceSource)
-{}
-template <typename T>
-void 
-TerminalTraceResolver<T>::Connect (std::string path, CallbackBase const &cb, const TraceContext &context)
-{
-  if (path == "")
-    {
-      m_traceSource->AddCallback (cb, context);
-    }
-}
-template <typename T>
-void 
-TerminalTraceResolver<T>::Disconnect (std::string path, CallbackBase const &cb)
-{
-  if (path == "")
-    {
-      m_traceSource->RemoveCallback (cb);
-    }
-}
-
-}//namespace ns3
-
-#endif /* TERMINAL_TRACE_RESOLVER_H */
--- a/src/common/trace-context-element.cc	Fri Aug 10 15:47:13 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	Fri Aug 10 15:47:13 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	Fri Aug 10 15:47:13 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	Fri Aug 10 15:47:13 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	Fri Aug 10 15:47:13 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +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"
-#include "ns3/debug.h"
-
-NS_DEBUG_COMPONENT_DEFINE ("TraceResolver");
-
-namespace ns3 {
-
-TraceResolver::TraceResolver ()
-  : m_count (1)
-{}
-
-TraceResolver::~TraceResolver ()
-{}
-
-void 
-TraceResolver::Ref (void)
-{
-  m_count++;
-}
-void 
-TraceResolver::Unref (void)
-{
-  m_count--;
-  if (m_count == 0)
-    {
-      NS_DEBUG ("delete "<<this);
-      delete this;
-    }
-}
-
-
-void 
-TraceResolver::Connect (std::string path, CallbackBase const &cb, const TraceContext &context)
-{}
-
-void 
-TraceResolver::Disconnect (std::string path, CallbackBase const &cb)
-{}
-
-std::string 
-TraceResolver::GetElement (std::string path)
-{
-  std::string::size_type cur = 1;
-  // check that first char is "/"
-  std::string::size_type next = path.find ("/", cur);
-  std::string id = std::string (path, cur, next-1);
-  return id;
-}
-std::string 
-TraceResolver::GetSubpath (std::string path)
-{
-  std::string::size_type cur = 1;
-  // check that first char is "/"
-  std::string::size_type next = path.find ("/", cur);
-  std::string subpath;
-  if (next != std::string::npos)
-    {
-      subpath = std::string (path, next, std::string::npos);
-    }
-  else
-    {
-      subpath = "";
-    }
-  return subpath;
-}
-
-}//namespace ns3
--- a/src/common/trace-resolver.h	Fri Aug 10 15:47:13 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +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:
-
-  TraceResolver ();
-  virtual ~TraceResolver ();
-  void Ref (void);
-  void Unref (void);
-
-  /**
-   * \param path the namespace path to resolver
-   * \param cb the callback to connect to the matching namespace
-   *
-   * 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.
-   */
-  virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context);
-  /**
-   * \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.
-   */
-  virtual void Disconnect (std::string path, CallbackBase const &cb);
-protected:
-  std::string GetElement (std::string path);
-  std::string GetSubpath (std::string path);
-  uint32_t m_count;
-};
-
-}//namespace ns3
-
-#endif /* TRACE_RESOLVER_H */
--- a/src/common/trace-root.cc	Fri Aug 10 15:47:13 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)
-{
-  Ptr<TraceResolver> resolver = GetComposite ();
-  resolver->Connect (path, cb, TraceContext ());
-}
-void 
-TraceRoot::Disconnect (std::string path, CallbackBase const &cb)
-{
-  Ptr<TraceResolver> resolver = GetComposite ();
-  resolver->Disconnect (path, cb);
-}
-void 
-TraceRoot::Register (std::string name, 
-                     Callback<Ptr<TraceResolver> > createResolver)
-{
-  Ptr<CompositeTraceResolver> resolver = GetComposite ();
-  resolver->Add (name, createResolver);
-}
-
-Ptr<CompositeTraceResolver>
-TraceRoot::GetComposite (void)
-{
-  static CompositeTraceResolver resolver;
-  return &resolver;
-}
-
-} // namespace ns3
--- a/src/common/trace-root.h	Fri Aug 10 15:47:13 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<Ptr<TraceResolver> > createResolver);
-private:
-  static Ptr<CompositeTraceResolver> GetComposite (void);
-};
-
-}// namespace ns3
-
-#endif /* TRACE_ROOT_H */
--- a/src/common/uv-trace-source.h	Fri Aug 10 15:47:13 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	Fri Aug 10 15:47:13 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	Fri Aug 10 15:47:13 2007 +0200
+++ b/src/common/wscript	Fri Aug 10 15:53:43 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	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,110 @@
+/* -*- 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 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:
+   * Ptr<TraceResolver> (*) (void)
+   */
+  ArrayTraceResolver (Callback<uint32_t> getSize, 
+                      Callback<T, uint32_t> get);
+
+  virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context);
+  virtual void Disconnect (std::string path, CallbackBase const &cb);
+private:
+  Callback<uint32_t> m_getSize;
+  Callback<T, uint32_t> m_get;
+};
+}//namespace ns3
+
+namespace ns3 {
+
+template <typename T, typename INDEX>
+ArrayTraceResolver<T,INDEX>::ArrayTraceResolver (Callback<uint32_t> getSize, 
+                                                 Callback<T, uint32_t> get)
+  : m_getSize (getSize),
+    m_get (get)
+{}
+
+template <typename T, typename INDEX>
+void 
+ArrayTraceResolver<T,INDEX>::Connect (std::string path, CallbackBase const &cb, const TraceContext &context)
+{
+  std::string id = GetElement (path);
+  std::string subpath = GetSubpath (path);
+  if (id == "*")
+  {
+    for (uint32_t i = 0; i < m_getSize (); i++)
+    {
+      TraceContext tmp = context;
+      INDEX index = i;
+      tmp.Add (index);
+      Ptr<TraceResolver> resolver = m_get (i)->CreateTraceResolver ();
+      resolver->Connect (subpath, cb, tmp);
+    }
+  }
+}
+template <typename T, typename INDEX>
+void 
+ArrayTraceResolver<T,INDEX>::Disconnect (std::string path, CallbackBase const &cb)
+{
+  std::string id = GetElement (path);
+  std::string subpath = GetSubpath (path);
+  if (id == "*")
+  {
+    for (uint32_t i = 0; i < m_getSize (); i++)
+    {
+      Ptr<TraceResolver> resolver = m_get (i)->CreateTraceResolver ();
+      resolver->Disconnect (subpath, cb);
+    }
+  }
+}
+
+
+}//namespace ns3
+
+#endif /* ARRAY_TRACE_RESOLVER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/callback-trace-source.cc	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,95 @@
+/* -*- 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/callback-trace-source.h	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,157 @@
+/* -*- 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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/composite-trace-resolver.cc	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,410 @@
+/* -*- 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 "ns3/debug.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("CompositeTraceResolver");
+
+namespace ns3 {
+
+CompositeTraceResolver::CompositeTraceResolver ()
+{}
+
+CompositeTraceResolver::~CompositeTraceResolver ()
+{}
+
+void 
+CompositeTraceResolver::Add (std::string name, 
+                             Callback<Ptr<TraceResolver> > createResolver)
+{
+  DoAdd (name, createResolver, TraceContext ());
+}
+
+void 
+CompositeTraceResolver::DoAdd (std::string name, 
+			       Callback<Ptr<TraceResolver> > createResolver,
+			       TraceContext const &context)
+{
+  struct CallbackTraceSourceItem item;
+  item.name = name;
+  item.createResolver = createResolver;
+  item.context = context;
+  m_items.push_back (item);
+}
+
+void 
+CompositeTraceResolver::Connect (std::string path, CallbackBase const &cb, const TraceContext &context)
+{
+  NS_DEBUG ("connect path="<<path);
+  DoRecursiveOperation (path, cb, context, CONNECT);
+}
+void 
+CompositeTraceResolver::DoRecursiveOperation (std::string path, CallbackBase const &cb, 
+                                              const TraceContext &context,
+                                              enum Operation op)
+{
+  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++)
+	{
+          OperationOne (subpath, i, cb, context, op);
+        }
+      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)
+	    {
+              OperationOne (subpath, i, cb, context, op);
+              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)
+	    {
+              OperationOne (subpath, j, cb, context, op);
+	      break;
+	    }
+	}
+    }
+}
+
+void 
+CompositeTraceResolver::OperationOne (std::string subpath, 
+                                      TraceItems::const_iterator i,
+                                      const CallbackBase &cb,
+                                      const TraceContext &context,
+                                      enum Operation op)
+{
+  Ptr<TraceResolver> resolver = i->createResolver ();
+  switch (op) {
+  case CONNECT: {
+    NS_DEBUG ("connect to path="<<subpath<<" name="<<i->name);
+    TraceContext ctx = context;
+    ctx.Add (i->context);
+    resolver->Connect (subpath, cb, ctx);
+    } break;
+  case DISCONNECT:
+    resolver->Disconnect (subpath, cb);
+    break;
+  }
+}
+
+void 
+CompositeTraceResolver::Disconnect (std::string path, CallbackBase const &cb)
+{
+  DoRecursiveOperation (path, cb, TraceContext (), DISCONNECT);
+}
+
+}//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);
+  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.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;
+}
+
+Ptr<TraceResolver>
+CompositeTraceResolverTest::CreateSubResolver (void)
+{
+  Ptr<CompositeTraceResolver> subresolver = Create<CompositeTraceResolver> ();
+  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;
+
+  resolver.Add ("trace-double-a", traceDoubleA, 
+                TraceSourceTest (TraceSourceTest::DOUBLEA));
+  resolver.Add ("trace-double-b", 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),
+		TraceSourceTest (TraceSourceTest::SUBRESOLVER));
+
+  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;
+    }
+
+
+  
+
+  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	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,238 @@
+/* -*- 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 "ns3/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 "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 ();
+  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<Ptr<TraceResolver> > 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<Ptr<TraceResolver> > createResolver);
+  virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context);
+  virtual void Disconnect (std::string path, CallbackBase const &cb);
+
+private:
+  struct CallbackTraceSourceItem
+  {
+    std::string name;
+    Callback<Ptr<TraceResolver> > createResolver;
+    TraceContext context;
+  };
+  typedef std::list<struct CallbackTraceSourceItem> TraceItems;
+  enum Operation {
+    CONNECT,
+    DISCONNECT
+  };
+
+  template <typename SOURCE, typename CONTEXT>
+  void DoAddTraceSource (std::string name,
+                         SOURCE &traceSource, CONTEXT const &context);
+  template <typename SOURCE>
+  static Ptr<TraceResolver> CreateTerminalTraceResolver (SOURCE *trace);
+  void DoAdd (std::string name, 
+              Callback<Ptr<TraceResolver> > createResolver,
+              TraceContext const &context);
+  void OperationOne (std::string subpath, 
+                     TraceItems::const_iterator i,
+                     const CallbackBase &cb,
+                     const TraceContext &context,
+                     enum Operation op);
+  void DoRecursiveOperation (std::string path, CallbackBase const &cb, 
+                             const TraceContext &context,
+                             enum Operation op);
+
+
+
+  TraceItems m_items;
+};
+
+}//namespace ns3
+
+namespace ns3 {
+
+template <typename SOURCE, typename CONTEXT>
+void 
+CompositeTraceResolver::DoAddTraceSource (std::string name,
+                                          SOURCE &traceSource, CONTEXT const &context)
+{
+  Ptr<TraceResolver> (*create) (SOURCE *trace);
+  create = &CompositeTraceResolver::CreateTerminalTraceResolver<SOURCE>;
+  Callback<Ptr<TraceResolver> > createResolver = 
+    MakeBoundCallback (create, &traceSource);
+
+  TraceContext ctx;
+  ctx.Add (context);
+  DoAdd (name, createResolver, ctx);
+}
+
+template <typename SOURCE>
+Ptr<TraceResolver>
+CompositeTraceResolver::CreateTerminalTraceResolver (SOURCE *traceSource)
+{
+  return Create<TerminalTraceResolver<SOURCE> > (traceSource);
+}
+
+
+
+
+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<Ptr<TraceResolver> > createResolver,
+                             T const &context)
+{
+  TraceContext ctx;
+  ctx.Add (context);
+  DoAdd (name, createResolver, ctx);
+}
+
+}//namespace ns3
+
+#endif /* COMPOSITE_TRACE_RESOLVER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/empty-trace-resolver.cc	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,24 @@
+/* -*- 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 ()
+{}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/empty-trace-resolver.h	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,52 @@
+/* -*- 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 ();
+};
+
+}//namespace ns3
+
+#endif /* EMPTY_TRACE_RESOLVER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/fv-trace-source.h	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,67 @@
+/* -*- 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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/stream-tracer-test.cc	Fri Aug 10 15:53:43 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 "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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/stream-tracer.h	Fri Aug 10 15:53:43 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	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,242 @@
+/* -*- 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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/terminal-trace-resolver.h	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,72 @@
+/* -*- 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"
+#include "ns3/assert.h"
+
+namespace ns3 {
+
+class TraceContext;
+
+template <typename T>
+class TerminalTraceResolver : public TraceResolver
+{
+ public:
+  TerminalTraceResolver (T *traceSource);
+
+  virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context);
+  virtual void Disconnect (std::string path, CallbackBase const &cb);
+ private:
+  T *m_traceSource;
+};
+
+}//namespace ns3
+
+namespace ns3 {
+
+template <typename T>
+TerminalTraceResolver<T>::TerminalTraceResolver (T *traceSource)
+  : m_traceSource (traceSource)
+{}
+template <typename T>
+void 
+TerminalTraceResolver<T>::Connect (std::string path, CallbackBase const &cb, const TraceContext &context)
+{
+  if (path == "")
+    {
+      m_traceSource->AddCallback (cb, context);
+    }
+}
+template <typename T>
+void 
+TerminalTraceResolver<T>::Disconnect (std::string path, CallbackBase const &cb)
+{
+  if (path == "")
+    {
+      m_traceSource->RemoveCallback (cb);
+    }
+}
+
+}//namespace ns3
+
+#endif /* TERMINAL_TRACE_RESOLVER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-context-element.cc	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,34 @@
+#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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-context-element.h	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,189 @@
+#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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-context.cc	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,330 @@
+/* -*- 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-context.h	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,162 @@
+/* -*- 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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-resolver.cc	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,87 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "trace-resolver.h"
+#include "ns3/debug.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("TraceResolver");
+
+namespace ns3 {
+
+TraceResolver::TraceResolver ()
+  : m_count (1)
+{}
+
+TraceResolver::~TraceResolver ()
+{}
+
+void 
+TraceResolver::Ref (void)
+{
+  m_count++;
+}
+void 
+TraceResolver::Unref (void)
+{
+  m_count--;
+  if (m_count == 0)
+    {
+      NS_DEBUG ("delete "<<this);
+      delete this;
+    }
+}
+
+
+void 
+TraceResolver::Connect (std::string path, CallbackBase const &cb, const TraceContext &context)
+{}
+
+void 
+TraceResolver::Disconnect (std::string path, CallbackBase const &cb)
+{}
+
+std::string 
+TraceResolver::GetElement (std::string path)
+{
+  std::string::size_type cur = 1;
+  // check that first char is "/"
+  std::string::size_type next = path.find ("/", cur);
+  std::string id = std::string (path, cur, next-1);
+  return id;
+}
+std::string 
+TraceResolver::GetSubpath (std::string path)
+{
+  std::string::size_type cur = 1;
+  // check that first char is "/"
+  std::string::size_type next = path.find ("/", cur);
+  std::string subpath;
+  if (next != std::string::npos)
+    {
+      subpath = std::string (path, next, std::string::npos);
+    }
+  else
+    {
+      subpath = "";
+    }
+  return subpath;
+}
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-resolver.h	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,85 @@
+/* -*- 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:
+
+  TraceResolver ();
+  virtual ~TraceResolver ();
+  void Ref (void);
+  void Unref (void);
+
+  /**
+   * \param path the namespace path to resolver
+   * \param cb the callback to connect to the matching namespace
+   *
+   * 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.
+   */
+  virtual void Connect (std::string path, CallbackBase const &cb, const TraceContext &context);
+  /**
+   * \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.
+   */
+  virtual void Disconnect (std::string path, CallbackBase const &cb);
+protected:
+  std::string GetElement (std::string path);
+  std::string GetSubpath (std::string path);
+  uint32_t m_count;
+};
+
+}//namespace ns3
+
+#endif /* TRACE_RESOLVER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-root.cc	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,54 @@
+/* -*- 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)
+{
+  Ptr<TraceResolver> resolver = GetComposite ();
+  resolver->Connect (path, cb, TraceContext ());
+}
+void 
+TraceRoot::Disconnect (std::string path, CallbackBase const &cb)
+{
+  Ptr<TraceResolver> resolver = GetComposite ();
+  resolver->Disconnect (path, cb);
+}
+void 
+TraceRoot::Register (std::string name, 
+                     Callback<Ptr<TraceResolver> > createResolver)
+{
+  Ptr<CompositeTraceResolver> resolver = GetComposite ();
+  resolver->Add (name, createResolver);
+}
+
+Ptr<CompositeTraceResolver>
+TraceRoot::GetComposite (void)
+{
+  static CompositeTraceResolver resolver;
+  return &resolver;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-root.h	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,335 @@
+/* -*- 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<Ptr<TraceResolver> > createResolver);
+private:
+  static Ptr<CompositeTraceResolver> GetComposite (void);
+};
+
+}// namespace ns3
+
+#endif /* TRACE_ROOT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/uv-trace-source.h	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,245 @@
+/* -*- 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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/variable-tracer-test.cc	Fri Aug 10 15:53:43 2007 +0200
@@ -0,0 +1,272 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "uv-trace-source.h"
+#include "sv-trace-source.h"
+#include "trace-context.h"
+#include "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/core/wscript	Fri Aug 10 15:47:13 2007 +0200
+++ b/src/core/wscript	Fri Aug 10 15:53:43 2007 +0200
@@ -42,6 +42,14 @@
         'type-name.cc',
         'component-manager.cc',
         'random-variable-default-value.cc',
+        'variable-tracer-test.cc',
+        'trace-context.cc',
+        'trace-context-element.cc',
+        'trace-resolver.cc',
+        'callback-trace-source.cc',
+        'empty-trace-resolver.cc',
+        'composite-trace-resolver.cc',
+        'trace-root.cc',
         ]
 
     if sys.platform == 'win32':
@@ -73,5 +81,17 @@
         'component-manager.h',
         'type-traits.h',
         'random-variable-default-value.h',
+        'uv-trace-source.h',
+        'sv-trace-source.h',
+        'fv-trace-source.h',
+        'callback-trace-source.h',
+        'trace-context.h',
+        'trace-context-element.h',
+        'trace-resolver.h',
+        'empty-trace-resolver.h',
+        'composite-trace-resolver.h',
+        'array-trace-resolver.h',
+        'trace-root.h',
+        'terminal-trace-resolver.h',
         ]