doc/tutorial/tracing.texi
changeset 6754 7ff69b244b5b
parent 6753 c9133c87760d
child 6755 b3da3ed88b6e
--- a/doc/tutorial/tracing.texi	Sun Jan 02 22:57:04 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3174 +0,0 @@
-@c ============================================================================
-@c Begin document body here
-@c ============================================================================
-
-@c ============================================================================
-@c PART:  The Tracing System
-@c ============================================================================
-@c The below chapters are under the major heading "The Tracing System"
-@c This is similar to the Latex \part command
-@c
-@c ============================================================================
-@c The Tracing System
-@c ============================================================================
-@node The Tracing System
-@chapter The Tracing System
-
-@menu
-* Background::
-* Overview::
-* A Real Example::
-* Using Mid-Level Trace Helpers::
-@end menu
-
-@c ============================================================================
-@c Background
-@c ============================================================================
-@node Background
-@section Background
-
-As mentioned in the Using the Tracing System section, the whole point of running
-an @code{ns-3} simulation is to generate output for study.  You have two basic 
-strategies to work with in @code{ns-3}: using generic pre-defined bulk output 
-mechanisms and parsing their content to extract interesting information; or 
-somehow developing an output mechanism that conveys exactly (and perhaps only) 
-the information wanted.
-
-Using pre-defined bulk output mechanisms has the advantage of not requiring any
-changes to @code{ns-3}, but it does require programming.  Often, pcap or NS_LOG
-output messages are gathered during simulation runs and separately run through 
-scripts that use grep, sed or awk to parse the messages and reduce and transform
-the data to a manageable form.  Programs must be written to do the 
-transformation, so this does not come for free.  Of course, if the information
-of interest in does not exist in any of the pre-defined output mechanisms,
-this approach fails.
-
-If you need to add some tidbit of information to the pre-defined bulk mechanisms,
-this can certainly be done; and if you use one of the @code{ns-3} mechanisms, 
-you may get your code added as a contribution.
-
-@code{ns-3} provides another mechanism, called Tracing, that avoids some of the 
-problems inherent in the bulk output mechanisms.  It has several important 
-advantages.  First, you can reduce the amount of data you have to manage by only
-tracing the events of interest to you (for large simulations, dumping everything
-to disk for post-processing can create I/O bottlenecks).  Second, if you use this
-method, you can control the format of the output directly so you avoid the 
-postprocessing step with sed or awk script.  If you desire, your output can be 
-formatted directly into a form acceptable by gnuplot, for example.  You can add 
-hooks in the core which can then be accessed by other users, but which will 
-produce no information unless explicitly asked to do so.  For these reasons, we 
-believe that the @code{ns-3} tracing system is the best way to get information 
-out of a simulation and is also therefore one of the most important mechanisms
-to understand in @command{ns-3}.
-
-@subsection Blunt Instruments
-There are many ways to get information out of a program.  The most 
-straightforward way is to just directly print the information to the standard 
-output, as in,
-
-@verbatim
-  #include <iostream>
-  ...
-  void
-  SomeFunction (void)
-  {
-    uint32_t x = SOME_INTERESTING_VALUE;
-    ...
-    std::cout << "The value of x is " << x << std::endl;
-    ...
-  } 
-@end verbatim
-
-Nobody is going to prevent you from going deep into the core of @code{ns-3} and
-adding print statements.  This is insanely easy to do and, after all, you have 
-complete control of your own @code{ns-3} branch.  This will probably not turn 
-out to be very satisfactory in the long term, though.
-
-As the number of print statements increases in your programs, the task of 
-dealing with the large number of outputs will become more and more complicated.  
-Eventually, you may feel the need to control what information is being printed 
-in some way; perhaps by turning on and off certain categories of prints, or 
-increasing or decreasing the amount of information you want.  If you continue 
-down this path you may discover that you have re-implemented the @code{NS_LOG}
-mechanism.  In order to avoid that, one of the first things you might consider
-is using @code{NS_LOG} itself.
-
-We mentioned above that one way to get information out of @code{ns-3} is to 
-parse existing NS_LOG output for interesting information.  If you discover that 
-some tidbit of information you need is not present in existing log output, you 
-could edit the core of @code{ns-3} and simply add your interesting information
-to the output stream.  Now, this is certainly better than adding your own
-print statements since it follows @code{ns-3} coding conventions and could 
-potentially be useful to other people as a patch to the existing core.
-
-Let's pick a random example.  If you wanted to add more logging to the 
-@code{ns-3} TCP socket (@code{tcp-socket-impl.cc}) you could just add a new 
-message down in the implementation.  Notice that in TcpSocketImpl::ProcessAction()
-there is no log message for the @code{ACK_TX} case.  You could simply add one, 
-changing the code from:
-
-@verbatim
-  bool TcpSocketImpl::ProcessAction (Actions_t a)
-  { // These actions do not require a packet or any TCP Headers
-    NS_LOG_FUNCTION (this << a);
-    switch (a)
-    {
-      case NO_ACT:
-        NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action: NO_ACT");
-        break;
-      case ACK_TX:
-        SendEmptyPacket (TcpHeader::ACK);
-        break;
-      ...
-@end verbatim
-
-to add a new @code{NS_LOG_LOGIC} in the appropriate @code{case} statement:
-
-@verbatim
-  bool TcpSocketImpl::ProcessAction (Actions_t a)
-  { // These actions do not require a packet or any TCP Headers
-    NS_LOG_FUNCTION (this << a);
-    switch (a)
-    {
-      case NO_ACT:
-        NS_LOG_LOGIC ("TcpSocketImpl " << this << " Action: NO_ACT");
-        break;
-      case ACK_TX:
-        NS_LOG_LOGIC ("TcpSocketImpl " << this << " Action: ACK_TX");
-        SendEmptyPacket (TcpHeader::ACK);
-        break;
-      ...
-@end verbatim
-
-This may seem fairly simple and satisfying at first glance, but something to
-consider is that you will be writing code to add the @code{NS_LOG} statement 
-and you will also have to write code (as in grep, sed or awk scripts) to parse
-the log output in order to isolate your information.  This is because even 
-though you have some control over what is output by the logging system, you 
-only have control down to the log component level.  
-
-If you are adding code to an existing module, you will also have to live with the
-output that every other developer has found interesting.  You may find that in 
-order to get the small amount of information you need, you may have to wade 
-through huge amounts of extraneous messages that are of no interest to you.  You
-may be forced to save huge log files to disk and process them down to a few lines
-whenever you want to do anything.
-
-Since there are no guarantees in @code{ns-3} about the stability of @code{NS_LOG}
-output, you may also discover that pieces of log output on which you depend 
-disappear or change between releases.  If you depend on the structure of the 
-output, you may find other messages being added or deleted which may affect your
-parsing code.
-
-For these reasons, we consider prints to @code{std::cout} and NS_LOG messages 
-to be quick and dirty ways to get more information out of @code{ns-3}.
-
-It is desirable to have a stable facility using stable APIs that allow one to 
-reach into the core system and only get the information required.  It is
-desirable to be able to do this without having to change and recompile the
-core system.  Even better would be a system that notified the user when an item
-of interest changed or an interesting event happened so the user doesn't have 
-to actively poke around in the system looking for things.
-
-The @command{ns-3} tracing system is designed to work along those lines and is 
-well-integrated with the Attribute and Config subsystems allowing for relatively
-simple use scenarios.
-
-@node Overview
-@section Overview
-
-The ns-3 tracing system is built on the concepts of independent tracing sources
-and tracing sinks; along with a uniform mechanism for connecting sources to sinks.
-
-Trace sources are entities that can signal events that happen in a simulation and 
-provide access to interesting underlying data.  For example, a trace source could
-indicate when a packet is received by a net device and provide access to the 
-packet contents for interested trace sinks.  A trace source might also indicate 
-when an interesting state change happens in a model.  For example, the congestion
-window of a TCP model is a prime candidate for a trace source.
-
-Trace sources are not useful by themselves; they must be connected to other pieces
-of code that actually do something useful with the information provided by the source.
-The entities that consume trace information are called trace sinks.  Trace sources 
-are generators of events and trace sinks are consumers.  This explicit division 
-allows for large numbers of trace sources to be scattered around the system in 
-places which model authors believe might be useful.  
-
-There can be zero or more consumers of trace events generated by a trace source.  
-One can think of a trace source as a kind of point-to-multipoint information link.  
-Your code looking for trace events from a particular piece of core code could 
-happily coexist with other code doing something entirely different from the same
-information.
-
-Unless a user connects a trace sink to one of these sources, nothing is output.  By
-using the tracing system, both you and other people at the same trace source are 
-getting exactly what they want and only what they want out of the system.  Neither
-of you are impacting any other user by changing what information is output by the 
-system.  If you happen to add a trace source, your work as a good open-source 
-citizen may allow other users to provide new utilities that are perhaps very useful
-overall, without making any changes to the @code{ns-3} core.  
-
-@node A Simple Low-Level Example
-@subsection A Simple Low-Level Example
-
-Let's take a few minutes and walk through a simple tracing example.  We are going
-to need a little background on Callbacks to understand what is happening in the
-example, so we have to take a small detour right away.
-
-@node Callbacks
-@subsubsection Callbacks
-
-The goal of the Callback system in @code{ns-3} is to allow one piece of code to 
-call a function (or method in C++) without any specific inter-module dependency.
-This ultimately means you need some kind of indirection -- you treat the address
-of the called function as a variable.  This variable is called a pointer-to-function
-variable.  The relationship between function and pointer-to-function pointer is 
-really no different that that of object and pointer-to-object.
-
-In C the canonical example of a pointer-to-function is a 
-pointer-to-function-returning-integer (PFI).  For a PFI taking one int parameter,
-this could be declared like,
-
-@verbatim
-  int (*pfi)(int arg) = 0;
-@end verbatim
-
-What you get from this is a variable named simply ``pfi'' that is initialized
-to the value 0.  If you want to initialize this pointer to something meaningful,
-you have to have a function with a matching signature.  In this case, you could
-provide a function that looks like,
-
-@verbatim
-  int MyFunction (int arg) {}
-@end verbatim
-
-If you have this target, you can initialize the variable to point to your
-function:
-
-@verbatim
-  pfi = MyFunction;
-@end verbatim
-
-You can then call MyFunction indirectly using the more suggestive form of
-the call,
-
-@verbatim
-  int result = (*pfi) (1234);
-@end verbatim
-
-This is suggestive since it looks like you are dereferencing the function
-pointer just like you would dereference any pointer.  Typically, however,
-people take advantage of the fact that the compiler knows what is going on
-and will just use a shorter form,
-
-@verbatim
-  int result = pfi (1234);
-@end verbatim
-
-This looks like you are calling a function named ``pfi,'' but the compiler is
-smart enough to know to call through the variable @code{pfi} indirectly to
-the function @code{MyFunction}.
-
-Conceptually, this is almost exactly how the tracing system will work.
-Basically, a trace source @emph{is} a callback.  When a trace sink expresses
-interest in receiving trace events, it adds a Callback to a list of Callbacks
-internally held by the trace source.  When an interesting event happens, the 
-trace source invokes its @code{operator()} providing zero or more parameters.
-The @code{operator()} eventually wanders down into the system and does something
-remarkably like the indirect call you just saw.  It provides zero or more 
-parameters (the call to ``pfi'' above passed one parameter to the target function
-@code{MyFunction}.
-
-The important difference that the tracing system adds is that for each trace
-source there is an internal list of Callbacks.  Instead of just making one 
-indirect call, a trace source may invoke any number of Callbacks.  When a trace
-sink expresses interest in notifications from a trace source, it basically just
-arranges to add its own function to the callback list.
-
-If you are interested in more details about how this is actually arranged in 
-@code{ns-3}, feel free to peruse the Callback section of the manual.
-
-@node Example Code
-@subsubsection Example Code
-
-We have provided some code to implement what is really the simplest example
-of tracing that can be assembled.  You can find this code in the tutorial
-directory as @code{fourth.cc}.  Let's walk through it.
-
-@verbatim
-  /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-  /*
-   * This program is free software; you can redistribute it and/or modify
-   * it under the terms of the GNU General Public License version 2 as
-   * published by the Free Software Foundation;
-   *
-   * This program is distributed in the hope that it will be useful,
-   * but WITHOUT ANY WARRANTY; without even the implied warranty of
-   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   * GNU General Public License for more details.
-   *
-   * You should have received a copy of the GNU General Public License
-   * along with this program; if not, write to the Free Software
-   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-   */
-  
-  #include "ns3/object.h"
-  #include "ns3/uinteger.h"
-  #include "ns3/traced-value.h"
-  #include "ns3/trace-source-accessor.h"
-  
-  #include <iostream>
-  
-  using namespace ns3;
-@end verbatim
-
-Most of this code should be quite familiar to you.  As mentioned above, the
-trace system makes heavy use of the Object and Attribute systems, so you will 
-need to include them.  The first two includes above bring in the declarations
-for those systems explicitly.  You could use the core module header, but this
-illustrates how simple this all really is.  
-
-The file, @code{traced-value.h} brings in the required declarations for tracing
-of data that obeys value semantics.  In general, value semantics just means that
-you can pass the object around, not an address.  In order to use value semantics
-at all you have to have an object with an associated copy constructor and 
-assignment operator available.  We extend the requirements to talk about the set
-of operators that are pre-defined for plain-old-data (POD) types.  Operator=, 
-operator++, operator---, operator+, operator==, etc.
-
-What this all really means is that you will be able to trace changes to a C++
-object made using those operators.
-
-Since the tracing system is integrated with Attributes, and Attributes work
-with Objects, there must be an @command{ns-3} @code{Object} for the trace source
-to live in.  The next code snippet declares and defines a simple Object we can
-work with.
-
-@verbatim
-  class MyObject : public Object
-  {
-  public:
-    static TypeId GetTypeId (void)
-    {
-      static TypeId tid = TypeId ("MyObject")
-        .SetParent (Object::GetTypeId ())
-        .AddConstructor<MyObject> ()
-        .AddTraceSource ("MyInteger",
-                         "An integer value to trace.",
-                         MakeTraceSourceAccessor (&MyObject::m_myInt))
-        ;
-      return tid;
-    }
-    
-    MyObject () {}
-    TracedValue<int32_t> m_myInt;
-  };
-@end verbatim
-
-The two important lines of code, above, with respect to tracing are the 
-@code{.AddTraceSource} and the @code{TracedValue} declaration of @code{m_myInt}.
-
-The @code{.AddTraceSource} provides the ``hooks'' used for connecting the trace
-source to the outside world through the config system.  The @code{TracedValue} 
-declaration provides the infrastructure that overloads the operators mentioned 
-above and drives the callback process.
-
-@verbatim
-  void
-  IntTrace (int32_t oldValue, int32_t newValue)
-  {
-    std::cout << "Traced " << oldValue << " to " << newValue << std::endl;
-  }
-@end verbatim
-
-This is the definition of the trace sink.  It corresponds directly to a callback
-function.  Once it is connected, this function will be called whenever one of the
-overloaded operators of the @code{TracedValue} is executed.
-
-We have now seen the trace source and the trace sink.  What remains is code to
-connect the source to the sink.
-
-@verbatim
-  int
-  main (int argc, char *argv[])
-  {
-    Ptr<MyObject> myObject = CreateObject<MyObject> ();
-    myObject->TraceConnectWithoutContext ("MyInteger", MakeCallback(&IntTrace));
-  
-    myObject->m_myInt = 1234;
-  }
-@end verbatim
-
-Here we first create the Object in which the trace source lives.
-
-The next step, the @code{TraceConnectWithoutContext}, forms the connection
-between the trace source and the trace sink.  Notice the @code{MakeCallback}
-template function.  This function does the magic required to create the
-underlying @code{ns-3} Callback object and associate it with the function
-@code{IntTrace}.  TraceConnect makes the association between your provided
-function and the overloaded @code{operator()} in the traced variable referred 
-to by the ``MyInteger'' Attribute.  After this association is made, the trace
-source will ``fire'' your provided callback function.
-
-The code to make all of this happen is, of course, non-trivial, but the essence
-is that you are arranging for something that looks just like the @code{pfi()}
-example above to be called by the trace source.  The declaration of the 
-@code{TracedValue<int32_t> m_myInt;} in the Object itself performs the magic 
-needed to provide the overloaded operators (++, ---, etc.) that will use the
-@code{operator()} to actually invoke the Callback with the desired parameters.
-The @code{.AddTraceSource} performs the magic to connect the Callback to the 
-Config system, and @code{TraceConnectWithoutContext} performs the magic to
-connect your function to the trace source, which is specified by Attribute
-name.
-
-Let's ignore the bit about context for now.
-
-Finally, the line,
-
-@verbatim
-   myObject->m_myInt = 1234;
-@end verbatim
-
-should be interpreted as an invocation of @code{operator=} on the member 
-variable @code{m_myInt} with the integer @code{1234} passed as a parameter.
-
-It turns out that this operator is defined (by @code{TracedValue}) to execute
-a callback that returns void and takes two integer values as parameters --- 
-an old value and a new value for the integer in question.  That is exactly 
-the function signature for the callback function we provided --- @code{IntTrace}.
-
-To summarize, a trace source is, in essence, a variable that holds a list of
-callbacks.  A trace sink is a function used as the target of a callback.  The
-Attribute and object type information systems are used to provide a way to 
-connect trace sources to trace sinks.  The act of ``hitting'' a trace source
-is executing an operator on the trace source which fires callbacks.  This 
-results in the trace sink callbacks registering interest in the source being 
-called with the parameters provided by the source.
-
-If you now build and run this example,
-
-@verbatim
-  ./waf --run fourth
-@end verbatim
-
-you will see the output from the @code{IntTrace} function execute as soon as the
-trace source is hit:
-
-@verbatim
-  Traced 0 to 1234
-@end verbatim
-
-When we executed the code, @code{myObject->m_myInt = 1234;}, the trace source 
-fired and automatically provided the before and after values to the trace sink.
-The function @code{IntTrace} then printed this to the standard output.  No 
-problem.
-
-@subsection Using the Config Subsystem to Connect to Trace Sources
-
-The @code{TraceConnectWithoutContext} call shown above in the simple example is
-actually very rarely used in the system.  More typically, the @code{Config}
-subsystem is used to allow selecting a trace source in the system using what is
-called a @emph{config path}.  We saw an example of this in the previous section
-where we hooked the ``CourseChange'' event when we were playing with 
-@code{third.cc}.
-
-Recall that we defined a trace sink to print course change information from the
-mobility models of our simulation.  It should now be a lot more clear to you 
-what this function is doing.
-
-@verbatim
-  void
-  CourseChange (std::string context, Ptr<const MobilityModel> model)
-  {
-    Vector position = model->GetPosition ();
-    NS_LOG_UNCOND (context << 
-      " x = " << position.x << ", y = " << position.y);
-  }
-@end verbatim
-
-When we connected the ``CourseChange'' trace source to the above trace sink,
-we used what is called a ``Config Path'' to specify the source when we
-arranged a connection between the pre-defined trace source and the new trace 
-sink:
-
-@verbatim
-  std::ostringstream oss;
-  oss <<
-    "/NodeList/" << wifiStaNodes.Get (nWifi - 1)->GetId () <<
-    "/$ns3::MobilityModel/CourseChange";
-
-  Config::Connect (oss.str (), MakeCallback (&CourseChange));
-@end verbatim
-
-Let's try and make some sense of what is sometimes considered relatively
-mysterious code.  For the purposes of discussion, assume that the node 
-number returned by the @code{GetId()} is ``7''.  In this case, the path
-above turns out to be,
-
-@verbatim
-  "/NodeList/7/$ns3::MobilityModel/CourseChange"
-@end verbatim
-
-The last segment of a config path must be an @code{Attribute} of an 
-@code{Object}.  In fact, if you had a pointer to the @code{Object} that has the
-``CourseChange'' @code{Attribute} handy, you could write this just like we did 
-in the previous example.  You know by now that we typically store pointers to 
-our nodes in a NodeContainer.  In the @code{third.cc} example, the Nodes of
-interest are stored in the @code{wifiStaNodes} NodeContainer.  In fact, while
-putting the path together, we used this container to get a Ptr<Node> which we
-used to call GetId() on.  We could have used this Ptr<Node> directly to call
-a connect method directly:
-
-@verbatim
-  Ptr<Object> theObject = wifiStaNodes.Get (nWifi - 1);
-  theObject->TraceConnectWithoutContext ("CourseChange", MakeCallback (&CourseChange));
-@end verbatim
-
-In the @code{third.cc} example, we actually want an additional ``context'' to 
-be delivered along with the Callback parameters (which will be explained below) so we 
-could actually use the following equivalent code,
-
-@verbatim
-  Ptr<Object> theObject = wifiStaNodes.Get (nWifi - 1);
-  theObject->TraceConnect ("CourseChange", MakeCallback (&CourseChange));
-@end verbatim
-
-It turns out that the internal code for @code{Config::ConnectWithoutContext} and
-@code{Config::Connect} actually do find a Ptr<Object> and call the appropriate
-TraceConnect method at the lowest level.
-
-The @code{Config} functions take a path that represents a chain of @code{Object} 
-pointers.  Each segment of a path corresponds to an Object Attribute.  The last 
-segment is the Attribute of interest, and prior segments must be typed to contain
-or find Objects.  The @code{Config} code parses and ``walks'' this path until it 
-gets to the final segment of the path.  It then interprets the last segment as
-an @code{Attribute} on the last Object it found while walking the path.  The  
-@code{Config} functions then call the appropriate @code{TraceConnect} or 
-@code{TraceConnectWithoutContext} method on the final Object.  Let's see what 
-happens in a bit more detail when the above path is walked.
-
-The leading ``/'' character in the path refers to a so-called namespace.  One 
-of the predefined namespaces in the config system is ``NodeList'' which is a 
-list of all of the nodes in the simulation.  Items in the list are referred to
-by indices into the list, so ``/NodeList/7'' refers to the eighth node in the
-list of nodes created during the simulation.  This reference is actually a 
-@code{Ptr<Node>} and so is a subclass of an @code{ns3::Object}.  
-
-As described in the Object Model section of the @code{ns-3} manual, we support
-Object Aggregation.  This allows us to form an association between different 
-Objects without any programming.  Each Object in an Aggregation can be reached 
-from the other Objects.  
-
-The next path segment being walked begins with the ``$'' character.  This 
-indicates to the config system that a @code{GetObject} call should be made 
-looking for the type that follows.  It turns out that the MobilityHelper used in 
-@code{third.cc} arranges to Aggregate, or associate, a mobility model to each of 
-the wireless Nodes.  When you add the ``$'' you are asking for another Object that
-has presumably been previously aggregated.  You can think of this as switching
-pointers from the original Ptr<Node> as specified by ``/NodeList/7'' to its 
-associated mobility model --- which is of type ``$ns3::MobilityModel''.  If you
-are familiar with @code{GetObject}, we have asked the system to do the following:
-
-@verbatim
-  Ptr<MobilityModel> mobilityModel = node->GetObject<MobilityModel> ()
-@end verbatim
-
-We are now at the last Object in the path, so we turn our attention to the 
-Attributes of that Object.  The @code{MobilityModel} class defines an Attribute 
-called ``CourseChange''.  You can see this by looking at the source code in
-@code{src/mobility/mobility-model.cc} and searching for ``CourseChange'' in your
-favorite editor.  You should find,
-
-@verbatim
-  .AddTraceSource (``CourseChange'',
-                   ``The value of the position and/or velocity vector changed'',
-                   MakeTraceSourceAccessor (&MobilityModel::m_courseChangeTrace))
-@end verbatim
-
-which should look very familiar at this point.  
-
-If you look for the corresponding declaration of the underlying traced variable 
-in @code{mobility-model.h} you will find
-
-@verbatim
-  TracedCallback<Ptr<const MobilityModel> > m_courseChangeTrace;
-@end verbatim
-
-The type declaration @code{TracedCallback} identifies @code{m_courseChangeTrace}
-as a special list of Callbacks that can be hooked using the Config functions 
-described above.
-
-The @code{MobilityModel} class is designed to be a base class providing a common
-interface for all of the specific subclasses.  If you search down to the end of 
-the file, you will see a method defined called @code{NotifyCourseChange()}:
-
-@verbatim
-  void
-  MobilityModel::NotifyCourseChange (void) const
-  {
-    m_courseChangeTrace(this);
-  }
-@end verbatim
-
-Derived classes will call into this method whenever they do a course change to
-support tracing.  This method invokes @code{operator()} on the underlying 
-@code{m_courseChangeTrace}, which will, in turn, invoke all of the registered
-Callbacks, calling all of the trace sinks that have registered interest in the
-trace source by calling a Config function.
-
-So, in the @code{third.cc} example we looked at, whenever a course change is 
-made in one of the @code{RandomWalk2dMobilityModel} instances installed, there
-will be a @code{NotifyCourseChange()} call which calls up into the 
-@code{MobilityModel} base class.  As seen above, this invokes @code{operator()}
-on @code{m_courseChangeTrace}, which in turn, calls any registered trace sinks.
-In the example, the only code registering an interest was the code that provided
-the config path.  Therefore, the @code{CourseChange} function that was hooked 
-from Node number seven will be the only Callback called.
-
-The final piece of the puzzle is the ``context''.  Recall that we saw an output 
-looking something like the following from @code{third.cc}:
-
-@verbatim
-  /NodeList/7/$ns3::MobilityModel/CourseChange x = 7.27897, y = 2.22677
-@end verbatim
-
-The first part of the output is the context.  It is simply the path through
-which the config code located the trace source.  In the case we have been looking at
-there can be any number of trace sources in the system corresponding to any number
-of nodes with mobility models.  There needs to be some way to identify which trace
-source is actually the one that fired the Callback.  An easy way is to request a 
-trace context when you @code{Config::Connect}.
-
-@subsection How to Find and Connect Trace Sources, and Discover Callback Signatures
-
-The first question that inevitably comes up for new users of the Tracing system is,
-``okay, I know that there must be trace sources in the simulation core, but how do
-I find out what trace sources are available to me''?  
-
-The second question is, ``okay, I found a trace source, how do I figure out the
-config path to use when I connect to it''? 
-
-The third question is, ``okay, I found a trace source, how do I figure out what 
-the return type and formal arguments of my callback function need to be''?
-
-The fourth question is, ``okay, I typed that all in and got this incredibly bizarre
-error message, what in the world does it mean''?
-
-@subsection What Trace Sources are Available?
-
-The answer to this question is found in the @code{ns-3} Doxygen.  Go to the 
-@code{ns-3} web site @uref{http://www.nsnam.org/getting_started.html,,``here''}
-and select the ``Doxygen (stable)'' link ``Documentation'' on the navigation
-bar to the left side of the page.  Expand the ``Modules'' book in the NS-3 
-documentation tree a the upper left by clicking the ``+'' box.  Now, expand
-the ``Core'' book in the tree by clicking its ``+'' box.  You should now
-see three extremely useful links:
-
-@itemize @bullet
-@item The list of all trace sources
-@item The list of all attributes
-@item The list of all global values
-@end itemize
-
-The list of interest to us here is ``the list of all trace sources''.  Go 
-ahead and select that link.  You will see, perhaps not too surprisingly, a
-list of all of the trace sources available in the @code{ns-3} core.
-
-As an example, scroll down to @code{ns3::MobilityModel}.  You will find
-an entry for
-
-@verbatim
-  CourseChange: The value of the position and/or velocity vector changed 
-@end verbatim
-
-You should recognize this as the trace source we used in the @code{third.cc}
-example.  Perusing this list will be helpful.
-
-@subsection What String do I use to Connect?
-
-The easiest way to do this is to grep around in the @code{ns-3} codebase for someone
-who has already figured it out,  You should always try to copy someone else's
-working code before you start to write your own.  Try something like:
-
-@verbatim
-  find . -name '*.cc' | xargs grep CourseChange | grep Connect
-@end verbatim
-
-and you may find your answer along with working code.  For example, in this
-case, @code{./ns-3-dev/examples/wireless/mixed-wireless.cc} has something
-just waiting for you to use:
-
-@verbatim
-  Config::Connect (``/NodeList/*/$ns3::MobilityModel/CourseChange'', 
-    MakeCallback (&CourseChangeCallback));
-@end verbatim
-
-If you cannot find any examples in the distribution, you can find this out
-from the @code{ns-3} Doxygen.  It will probably be simplest just to walk 
-through the ``CourseChanged'' example.
-
-Let's assume that you have just found the ``CourseChanged'' trace source in 
-``The list of all trace sources'' and you want to figure out how to connect to
-it.  You know that you are using (again, from the @code{third.cc} example) an
-@code{ns3::RandomWalk2dMobilityModel}.  So open the ``Class List'' book in
-the NS-3 documentation tree by clicking its ``+'' box.  You will now see a
-list of all of the classes in @code{ns-3}.  Scroll down until you see the
-entry for @code{ns3::RandomWalk2dMobilityModel} and follow that link.
-You should now be looking at the ``ns3::RandomWalk2dMobilityModel Class 
-Reference''.
-
-If you now scroll down to the ``Member Function Documentation'' section, you
-will see documentation for the @code{GetTypeId} function.  You constructed one
-of these in the simple tracing example above:
-
-@verbatim
-    static TypeId GetTypeId (void)
-    {
-      static TypeId tid = TypeId ("MyObject")
-        .SetParent (Object::GetTypeId ())
-        .AddConstructor<MyObject> ()
-        .AddTraceSource ("MyInteger",
-                         "An integer value to trace.",
-                         MakeTraceSourceAccessor (&MyObject::m_myInt))
-        ;
-      return tid;
-    }
-@end verbatim
-
-As mentioned above, this is the bit of code that connected the Config 
-and Attribute systems to the underlying trace source.  This is also the
-place where you should start looking for information about the way to 
-connect. 
-
-You are looking at the same information for the RandomWalk2dMobilityModel; and
-the information you want is now right there in front of you in the Doxygen:
-
-@verbatim
-  This object is accessible through the following paths with Config::Set and Config::Connect: 
-
-  /NodeList/[i]/$ns3::MobilityModel/$ns3::RandomWalk2dMobilityModel 
-@end verbatim
-
-The documentation tells you how to get to the @code{RandomWalk2dMobilityModel} 
-Object.  Compare the string above with the string we actually used in the 
-example code:
-
-@verbatim
-  "/NodeList/7/$ns3::MobilityModel"
-@end verbatim
-
-The difference is due to the fact that two @code{GetObject} calls are implied 
-in the string found in the documentation.  The first, for @code{$ns3::MobilityModel}
-will query the aggregation for the base class.  The second implied 
-@code{GetObject} call, for @code{$ns3::RandomWalk2dMobilityModel}, is used to ``cast''
-the base class to the concrete implementation class.  The documentation shows 
-both of these operations for you.  It turns out that the actual Attribute you are
-going to be looking for is found in the base class as we have seen.
-
-Look further down in the @code{GetTypeId} doxygen.  You will find,
-
-@verbatim
-  No TraceSources defined for this type.
-  TraceSources defined in parent class ns3::MobilityModel:
-
-  CourseChange: The value of the position and/or velocity vector changed 
-  Reimplemented from ns3::MobilityModel
-@end verbatim
-
-This is exactly what you need to know.  The trace source of interest is found in
-@code{ns3::MobilityModel} (which you knew anyway).  The interesting thing this
-bit of Doxygen tells you is that you don't need that extra cast in the config
-path above to get to the concrete class, since the trace source is actually in
-the base class.  Therefore the additional @code{GetObject} is not required and
-you simply use the path:
-
-@verbatim
-  /NodeList/[i]/$ns3::MobilityModel
-@end verbatim
-
-which perfectly matches the example path:
-
-@verbatim
-  /NodeList/7/$ns3::MobilityModel
-@end verbatim
-
-@subsection What Return Value and Formal Arguments?
-
-The easiest way to do this is to grep around in the @code{ns-3} codebase for someone
-who has already figured it out,  You should always try to copy someone else's
-working code.  Try something like:
-
-@verbatim
-  find . -name '*.cc' | xargs grep CourseChange | grep Connect
-@end verbatim
-
-and you may find your answer along with working code.  For example, in this
-case, @code{./ns-3-dev/examples/wireless/mixed-wireless.cc} has something
-just waiting for you to use.  You will find
-
-@verbatim
-  Config::Connect (``/NodeList/*/$ns3::MobilityModel/CourseChange'', 
-    MakeCallback (&CourseChangeCallback));
-@end verbatim
-
-as a result of your grep.  The @code{MakeCallback} should indicate to you that
-there is a callback function there which you can use.  Sure enough, there is:
-
-@verbatim
-  static void
-  CourseChangeCallback (std::string path, Ptr<const MobilityModel> model)
-  {
-    ...
-  }
-@end verbatim
-
-@subsubsection Take my Word for It
-
-If there are no examples to work from, this can be, well, challenging to 
-actually figure out from the source code.
-
-Before embarking on a walkthrough of the code, I'll be kind and just tell you
-a simple way to figure this out:  The return value of your callback will always 
-be void.  The formal parameter list for a @code{TracedCallback} can be found 
-from the template parameter list in the declaration.  Recall that for our
-current example, this is in @code{mobility-model.h}, where we have previously
-found:
-
-@verbatim
-  TracedCallback<Ptr<const MobilityModel> > m_courseChangeTrace;
-@end verbatim
-
-There is a one-to-one correspondence between the template parameter list in 
-the declaration and the formal arguments of the callback function.  Here,
-there is one template parameter, which is a @code{Ptr<const MobilityModel>}.
-This tells you that you need a function that returns void and takes a
-a @code{Ptr<const MobilityModel>}.  For example,
-
-@verbatim
-  void
-  CourseChangeCallback (Ptr<const MobilityModel> model)
-  {
-    ...
-  }
-@end verbatim
-
-That's all you need if you want to @code{Config::ConnectWithoutContext}.  If
-you want a context, you need to @code{Config::Connect} and use a Callback 
-function that takes a string context, then the required argument.
-
-@verbatim
-  void
-  CourseChangeCallback (std::string path, Ptr<const MobilityModel> model)
-  {
-    ...
-  }
-@end verbatim
-
-If you want to ensure that your @code{CourseChangeCallback} is only visible
-in your local file, you can add the keyword @code{static} and come up with:
-
-@verbatim
-  static void
-  CourseChangeCallback (std::string path, Ptr<const MobilityModel> model)
-  {
-    ...
-  }
-@end verbatim
-
-which is exactly what we used in the @code{third.cc} example.
-
-@subsubsection The Hard Way
-
-This section is entirely optional.  It is going to be a bumpy ride, especially
-for those unfamiliar with the details of templates.  However, if you get through
-this, you will have a very good handle on a lot of the @code{ns-3} low level
-idioms.
-
-So, again, let's figure out what signature of callback function is required for
-the ``CourseChange'' Attribute.  This is going to be painful, but you only need
-to do this once.  After you get through this, you will be able to just look at
-a @code{TracedCallback} and understand it.
-
-The first thing we need to look at is the declaration of the trace source.
-Recall that this is in @code{mobility-model.h}, where we have previously
-found:
-
-@verbatim
-  TracedCallback<Ptr<const MobilityModel> > m_courseChangeTrace;
-@end verbatim
-
-This declaration is for a template.  The template parameter is inside the
-angle-brackets, so we are really interested in finding out what that
-@code{TracedCallback<>} is.  If you have absolutely no idea where this might
-be found, grep is your friend.
-
-We are probably going to be interested in some kind of declaration in the 
-@code{ns-3} source, so first change into the @code{src} directory.  Then, 
-we know this declaration is going to have to be in some kind of header file,
-so just grep for it using:
-
-@verbatim
-  find . -name '*.h' | xargs grep TracedCallback
-@end verbatim
-
-You'll see 124 lines fly by (I piped this through wc to see how bad it was).
-Although that may seem like it, that's not really a lot.  Just pipe the output
-through more and start scanning through it.  On the first page, you will see
-some very suspiciously template-looking stuff.
-
-@verbatim
-  TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::TracedCallback ()
-  TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::ConnectWithoutContext (c ...
-  TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::Connect (const CallbackB ...
-  TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::DisconnectWithoutContext ...
-  TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::Disconnect (const Callba ...
-  TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (void) const ...
-  TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1) const ...
-  TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
-  TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
-  TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
-  TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
-  TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
-  TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
-@end verbatim
-
-It turns out that all of this comes from the header file 
-@code{traced-callback.h} which sounds very promising.  You can then take a
-look at @code{mobility-model.h} and see that there is a line which confirms
-this hunch:
-
-@verbatim
-  #include "ns3/traced-callback.h"
-@end verbatim
-
-Of course, you could have gone at this from the other direction and started
-by looking at the includes in @code{mobility-model.h} and noticing the 
-include of @code{traced-callback.h} and inferring that this must be the file
-you want.
-
-In either case, the next step is to take a look at @code{src/core/traced-callback.h}
-in your favorite editor to see what is happening.
-
-You will see a comment at the top of the file that should be comforting:
-
-@verbatim
-  An ns3::TracedCallback has almost exactly the same API as a normal ns3::Callback but
-  instead of forwarding calls to a single function (as an ns3::Callback normally does),
-  it forwards calls to a chain of ns3::Callback.
-@end verbatim
-
-This should sound very familiar and let you know you are on the right track.
-
-Just after this comment, you will find,
-
-@verbatim
-  template<typename T1 = empty, typename T2 = empty, 
-           typename T3 = empty, typename T4 = empty,
-           typename T5 = empty, typename T6 = empty,
-           typename T7 = empty, typename T8 = empty>
-  class TracedCallback 
-  {
-    ...
-@end verbatim
-
-This tells you that TracedCallback is a templated class.  It has eight possible
-type parameters with default values.  Go back and compare this with the 
-declaration you are trying to understand:
-
-@verbatim
-  TracedCallback<Ptr<const MobilityModel> > m_courseChangeTrace;
-@end verbatim
-
-The @code{typename T1} in the templated class declaration corresponds to the 
-@code{Ptr<const MobilityModel>} in the declaration above.  All of the other
-type parameters are left as defaults.  Looking at the constructor really
-doesn't tell you much.  The one place where you have seen a connection made
-between your Callback function and the tracing system is in the @code{Connect}
-and @code{ConnectWithoutContext} functions.  If you scroll down, you will see
-a @code{ConnectWithoutContext} method here:
-
-@verbatim
-  template<typename T1, typename T2, 
-           typename T3, typename T4,
-           typename T5, typename T6,
-           typename T7, typename T8>
-  void 
-  TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::ConnectWithoutContext ...
-  {
-    Callback<void,T1,T2,T3,T4,T5,T6,T7,T8> cb;
-    cb.Assign (callback);
-    m_callbackList.push_back (cb);
-  }
-@end verbatim
-
-You are now in the belly of the beast.  When the template is instantiated for
-the declaration above, the compiler will replace @code{T1} with 
-@code{Ptr<const MobilityModel>}.  
-
-@verbatim
-  void 
-  TracedCallback<Ptr<const MobilityModel>::ConnectWithoutContext ... cb
-  {
-    Callback<void, Ptr<const MobilityModel> > cb;
-    cb.Assign (callback);
-    m_callbackList.push_back (cb);
-  }
-@end verbatim
-
-You can now see the implementation of everything we've been talking about.  The
-code creates a Callback of the right type and assigns your function to it.  This
-is the equivalent of the @code{pfi = MyFunction} we discussed at the start of
-this section.  The code then adds the Callback to the list of Callbacks for 
-this source.  The only thing left is to look at the definition of Callback.
-Using the same grep trick as we used to find @code{TracedCallback}, you will be
-able to find that the file @code{./core/callback.h} is the one we need to look at.
-
-If you look down through the file, you will see a lot of probably almost
-incomprehensible template code.  You will eventually come to some Doxygen for
-the Callback template class, though.  Fortunately, there is some English:
-
-@verbatim
-  This class template implements the Functor Design Pattern.
-  It is used to declare the type of a Callback:
-   - the first non-optional template argument represents
-     the return type of the callback.
-   - the second optional template argument represents
-     the type of the first argument to the callback.
-   - the third optional template argument represents
-     the type of the second argument to the callback.
-   - the fourth optional template argument represents
-     the type of the third argument to the callback.
-   - the fifth optional template argument represents
-     the type of the fourth argument to the callback.
-   - the sixth optional template argument represents
-     the type of the fifth argument to the callback.
-@end verbatim
-
-We are trying to figure out what the
-
-@verbatim
-    Callback<void, Ptr<const MobilityModel> > cb;
-@end verbatim
-
-declaration means.  Now we are in a position to understand that the first
-(non-optional) parameter, @code{void}, represents the return type of the 
-Callback.  The second (non-optional) parameter, @code{Ptr<const MobilityModel>} 
-represents the first argument to the callback.
-
-The Callback in question is your function to receive the trace events.  From
-this you can infer that you need a function that returns @code{void} and takes
-a @code{Ptr<const MobilityModel>}.  For example,
-
-@verbatim
-  void
-  CourseChangeCallback (Ptr<const MobilityModel> model)
-  {
-    ...
-  }
-@end verbatim
-
-That's all you need if you want to @code{Config::ConnectWithoutContext}.  If
-you want a context, you need to @code{Config::Connect} and use a Callback 
-function that takes a string context.  This is because the @code{Connect}
-function will provide the context for you.  You'll need:
-
-@verbatim
-  void
-  CourseChangeCallback (std::string path, Ptr<const MobilityModel> model)
-  {
-    ...
-  }
-@end verbatim
-
-If you want to ensure that your @code{CourseChangeCallback} is only visible
-in your local file, you can add the keyword @code{static} and come up with:
-
-@verbatim
-  static void
-  CourseChangeCallback (std::string path, Ptr<const MobilityModel> model)
-  {
-    ...
-  }
-@end verbatim
-
-which is exactly what we used in the @code{third.cc} example.  Perhaps you
-should now go back and reread the previous section (Take My Word for It).
-
-If you are interested in more details regarding the implementation of 
-Callbacks, feel free to take a look at the @code{ns-3} manual.  They are one
-of the most frequently used constructs in the low-level parts of @code{ns-3}.
-It is, in my opinion, a quite elegant thing.
-
-@subsection What About TracedValue?
-
-Earlier in this section, we presented a simple piece of code that used a
-@code{TracedValue<int32_t>} to demonstrate the basics of the tracing code.
-We just glossed over the way to find the return type and formal arguments
-for the @code{TracedValue}.  Rather than go through the whole exercise, we
-will just point you at the correct file, @code{src/core/traced-value.h} and
-to the important piece of code:
-
-@verbatim
-  template <typename T>
-  class TracedValue
-  {
-  public:
-    ...
-    void Set (const T &v) {
-      if (m_v != v)
-        {
-  	m_cb (m_v, v);
-  	m_v = v;
-        }
-    }
-    ...
-  private:
-    T m_v;
-    TracedCallback<T,T> m_cb;
-  };
-@end verbatim
-
-Here you see that the @code{TracedValue} is templated, of course.  In the simple
-example case at the start of the section, the typename is int32_t.  This means 
-that the member variable being traced (@code{m_v} in the private section of the 
-class) will be an @code{int32_t m_v}.  The @code{Set} method will take a 
-@code{const int32_t &v} as a parameter.  You should now be able to understand 
-that the @code{Set} code will fire the @code{m_cb} callback with two parameters:
-the first being the current value of the @code{TracedValue}; and the second 
-being the new value being set.
-
-The callback, @code{m_cb} is declared as a @code{TracedCallback<T, T>} which
-will correspond to a @code{TracedCallback<int32_t, int32_t>} when the class is 
-instantiated.
-
-Recall that the callback target of a TracedCallback always returns @code{void}.  
-Further recall that there is a one-to-one correspondence between the template 
-parameter list in the declaration and the formal arguments of the callback 
-function.  Therefore the callback will need to have a function signature that 
-looks like:
-
-@verbatim
-  void
-  MyCallback (int32_t oldValue, int32_t newValue)
-  {
-    ...
-  }
-@end verbatim
-
-It probably won't surprise you that this is exactly what we provided in that 
-simple example we covered so long ago:
-
-@verbatim
-  void
-  IntTrace (int32_t oldValue, int32_t newValue)
-  {
-    std::cout << "Traced " << oldValue << " to " << newValue << std::endl;
-  }
-@end verbatim
-
-@c ============================================================================
-@c A Real Example
-@c ============================================================================
-@node A Real Example
-@section A Real Example
-
-Let's do an example taken from one of the best-known books on TCP around.  
-``TCP/IP Illustrated, Volume 1: The Protocols,'' by W. Richard Stevens is a 
-classic.  I just flipped the book open and ran across a nice plot of both the 
-congestion window and sequence numbers versus time on page 366.  Stevens calls 
-this, ``Figure 21.10. Value of cwnd and send sequence number while data is being 
-transmitted.''  Let's just recreate the cwnd part of that plot in @command{ns-3}
-using the tracing system and @code{gnuplot}.
-
-@subsection Are There Trace Sources Available?
-
-The first thing to think about is how we want to get the data out.  What is it
-that we need to trace?  The first thing to do is to consult ``The list of all
-trace sources'' to see what we have to work with.  Recall that this is found
-in the @command{ns-3} Doxygen in the ``Core'' Module section.  If you scroll
-through the list, you will eventually find:
-
-@verbatim
-  ns3::TcpSocketImpl
-  CongestionWindow: The TCP connection's congestion window
-@end verbatim
-
-It turns out that the @command{ns-3} TCP implementation lives (mostly) in the 
-file @code{src/internet-stack/tcp-socket-impl.cc}.  If you don't know this a 
-priori, you can use the recursive grep trick:
-
-@verbatim
-  find . -name '*.cc' | xargs grep -i tcp
-@end verbatim
-
-You will find page after page of instances of tcp pointing you to that file. 
-
-If you open @code{src/internet-stack/tcp-socket-impl.cc} in your favorite 
-editor, you will see right up at the top of the file, the following declarations:
-
-@verbatim
-  TypeId
-  TcpSocketImpl::GetTypeId ()
-  {
-    static TypeId tid = TypeId(``ns3::TcpSocketImpl'')
-      .SetParent<TcpSocket> ()
-      .AddTraceSource (``CongestionWindow'',
-                       ``The TCP connection's congestion window'',
-                       MakeTraceSourceAccessor (&TcpSocketImpl::m_cWnd))
-      ;
-    return tid;
-  }
-@end verbatim
-
-This should tell you to look for the declaration of @code{m_cWnd} in the header
-file @code{src/internet-stack/tcp-socket-impl.h}.  If you open this file in your
-favorite editor, you will find:
-
-@verbatim
-  TracedValue<uint32_t> m_cWnd; //Congestion window
-@end verbatim
-
-You should now understand this code completely.  If we have a pointer to the 
-@code{TcpSocketImpl}, we can @code{TraceConnect} to the ``CongestionWindow'' trace 
-source if we provide an appropriate callback target.  This is the same kind of
-trace source that we saw in the simple example at the start of this section,
-except that we are talking about @code{uint32_t} instead of @code{int32_t}.
-
-We now know that we need to provide a callback that returns void and takes 
-two @code{uint32_t} parameters, the first being the old value and the second 
-being the new value:
-
-@verbatim
-  void
-  CwndTrace (uint32_t oldValue, uint32_t newValue)
-  {
-    ...
-  }
-@end verbatim
-
-@subsection What Script to Use?
-
-It's always best to try and find working code laying around that you can 
-modify, rather than starting from scratch.  So the first order of business now
-is to find some code that already hooks the ``CongestionWindow'' trace source
-and see if we can modify it.  As usual, grep is your friend:
-
-@verbatim
-  find . -name '*.cc' | xargs grep CongestionWindow
-@end verbatim
-
-This will point out a couple of promising candidates: 
-@code{examples/tcp/tcp-large-transfer.cc} and 
-@code{src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc}.
-
-We haven't visited any of the test code yet, so let's take a look there.  You
-will typically find that test code is fairly minimal, so this is probably a
-very good bet.  Open @code{src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc} in your
-favorite editor and search for ``CongestionWindow''.  You will find,
-
-@verbatim
-  ns3TcpSocket->TraceConnectWithoutContext (``CongestionWindow'', 
-    MakeCallback (&Ns3TcpCwndTestCase1::CwndChange, this));
-@end verbatim
-
-This should look very familiar to you.  We mentioned above that if we had a
-pointer to the @code{TcpSocketImpl}, we could @code{TraceConnect} to the 
-``CongestionWindow'' trace source.  That's exactly what we have here; so it
-turns out that this line of code does exactly what we want.  Let's go ahead
-and extract the code we need from this function 
-(@code{Ns3TcpCwndTestCase1::DoRun (void)}).  If you look at this function,
-you will find that it looks just like an @code{ns-3} script.  It turns out that
-is exactly what it is.  It is a script run by the test framework, so we can just
-pull it out and wrap it in @code{main} instead of in @code{DoRun}.  Rather than
-walk through this, step, by step, we have provided the file that results from
-porting this test back to a native @code{ns-3} script --
-@code{examples/tutorial/fifth.cc}.  
-
-@subsection A Common Problem and Solution
-
-The @code{fifth.cc} example demonstrates an extremely important rule that you 
-must understand before using any kind of @code{Attribute}:  you must ensure 
-that the target of a @code{Config} command exists before trying to use it.
-This is no different than saying an object must be instantiated before trying
-to call it.  Although this may seem obvious when stated this way, it does
-trip up many people trying to use the system for the first time.
-
-Let's return to basics for a moment.  There are three basic time periods that
-exist in any @command{ns-3} script.  The first time period is sometimes called 
-``Configuration Time'' or ``Setup Time,'' and is in force during the period 
-when the @code{main} function of your script is running, but before 
-@code{Simulator::Run} is called.  The second time period  is sometimes called
-``Simulation Time'' and is in force during the time period when 
-@code{Simulator::Run} is actively executing its events.  After it completes
-executing the simulation,  @code{Simulator::Run} will return control back to 
-the @code{main} function.  When this happens, the script enters what can be 
-called ``Teardown Time,'' which is when the structures and objects created 
-during setup and taken apart and released.
-
-Perhaps the most common mistake made in trying to use the tracing system is 
-assuming that entities constructed dynamically during simulation time are
-available during configuration time.  In particular, an @command{ns-3}
-@code{Socket} is a dynamic object often created by @code{Applications} to
-communicate between @code{Nodes}.  An @command{ns-3} @code{Application} 
-always has a ``Start Time'' and a ``Stop Time'' associated with it.  In the
-vast majority of cases, an @code{Application} will not attempt to create 
-a dynamic object until its @code{StartApplication} method is called at some
-``Start Time''.  This is to ensure that the simulation is completely 
-configured before the app tries to do anything (what would happen if it tried
-to connect to a node that didn't exist yet during configuration time).  The 
-answer to this issue is to 1) create a simulator event that is run after the 
-dynamic object is created and hook the trace when that event is executed; or
-2) create the dynamic object at configuration time, hook it then, and give 
-the object to the system to use during simulation time.  We took the second 
-approach in the @code{fifth.cc} example.  This decision required us to create
-the @code{MyApp} @code{Application}, the entire purpose of which is to take 
-a @code{Socket} as a parameter.  
-
-@subsection A fifth.cc Walkthrough
-
-Now, let's take a look at the example program we constructed by dissecting
-the congestion window test.  Open @code{examples/tutorial/fifth.cc} in your
-favorite editor.  You should see some familiar looking code:
-
-@verbatim
-  /* -*- Mode:C++; c-file-style:''gnu''; indent-tabs-mode:nil; -*- */
-  /*
-   * This program is free software; you can redistribute it and/or modify
-   * it under the terms of the GNU General Public License version 2 as
-   * published by the Free Software Foundation;
-   *
-   * This program is distributed in the hope that it will be useful,
-   * but WITHOUT ANY WARRANTY; without even the implied warranty of
-   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   * GNU General Public License for more details.
-   *
-   * You should have received a copy of the GNU General Public License
-   * along with this program; if not, write to the Free Software
-   * Foundation, Include., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-   */
-  
-  #include <fstream>
-  #include "ns3/core-module.h"
-  #include "ns3/common-module.h"
-  #include "ns3/simulator-module.h"
-  #include "ns3/node-module.h"
-  #include "ns3/helper-module.h"
-  
-  using namespace ns3;
-  
-  NS_LOG_COMPONENT_DEFINE ("FifthScriptExample");
-@end verbatim
-
-This has all been covered, so we won't rehash it.  The next lines of source are
-the network illustration and a comment addressing the problem described above
-with @code{Socket}.
-
-@verbatim
-  // ===========================================================================
-  //
-  //         node 0                 node 1
-  //   +----------------+    +----------------+
-  //   |    ns-3 TCP    |    |    ns-3 TCP    |
-  //   +----------------+    +----------------+
-  //   |    10.1.1.1    |    |    10.1.1.2    |
-  //   +----------------+    +----------------+
-  //   | point-to-point |    | point-to-point |
-  //   +----------------+    +----------------+
-  //           |                     |
-  //           +---------------------+
-  //                5 Mbps, 2 ms
-  //
-  //
-  // We want to look at changes in the ns-3 TCP congestion window.  We need
-  // to crank up a flow and hook the CongestionWindow attribute on the socket
-  // of the sender.  Normally one would use an on-off application to generate a
-  // flow, but this has a couple of problems.  First, the socket of the on-off
-  // application is not created until Application Start time, so we wouldn't be
-  // able to hook the socket (now) at configuration time.  Second, even if we
-  // could arrange a call after start time, the socket is not public so we
-  // couldn't get at it.
-  //
-  // So, we can cook up a simple version of the on-off application that does what
-  // we want.  On the plus side we don't need all of the complexity of the on-off
-  // application.  On the minus side, we don't have a helper, so we have to get
-  // a little more involved in the details, but this is trivial.
-  //
-  // So first, we create a socket and do the trace connect on it; then we pass
-  // this socket into the constructor of our simple application which we then
-  // install in the source node.
-  // ===========================================================================
-  //
-@end verbatim
-
-This should also be self-explanatory.  
-
-The next part is the declaration of the @code{MyApp} @code{Application} that
-we put together to allow the @code{Socket} to be created at configuration time.
-
-@verbatim
-  class MyApp : public Application
-  {
-  public:
-  
-    MyApp ();
-    virtual ~MyApp();
-  
-    void Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, 
-      uint32_t nPackets, DataRate dataRate);
-  
-  private:
-    virtual void StartApplication (void);
-    virtual void StopApplication (void);
-  
-    void ScheduleTx (void);
-    void SendPacket (void);
-  
-    Ptr<Socket>     m_socket;
-    Address         m_peer;
-    uint32_t        m_packetSize;
-    uint32_t        m_nPackets;
-    DataRate        m_dataRate;
-    EventId         m_sendEvent;
-    bool            m_running;
-    uint32_t        m_packetsSent;
-  };
-@end verbatim
-
-You can see that this class inherits from the @command{ns-3} @code{Application}
-class.  Take a look at @code{src/node/application.h} if you are interested in 
-what is inherited.  The @code{MyApp} class is obligated to override the 
-@code{StartApplication} and @code{StopApplication} methods.  These methods are
-automatically called when @code{MyApp} is required to start and stop sending
-data during the simulation.
-
-@subsubsection How Applications are Started and Stopped (optional)
-
-It is worthwhile to spend a bit of time explaining how events actually get 
-started in the system.  This is another fairly deep explanation, and can be
-ignored if you aren't planning on venturing down into the guts of the system.
-It is useful, however, in that the discussion touches on how some very important
-parts of @code{ns-3} work and exposes some important idioms.  If you are 
-planning on implementing new models, you probably want to understand this
-section.
-
-The most common way to start pumping events is to start an @code{Application}.
-This is done as the result of the following (hopefully) familar lines of an 
-@command{ns-3} script:
-
-@verbatim
-  ApplicationContainer apps = ...
-  apps.Start (Seconds (1.0));
-  apps.Stop (Seconds (10.0));
-@end verbatim
-
-The application container code (see @code{src/helper/application-container.h} if
-you are interested) loops through its contained applications and calls,
-
-@verbatim
-  app->SetStartTime (startTime);
-@end verbatim
-
-as a result of the @code{apps.Start} call and
-
-@verbatim
-  app->SetStopTime (stopTime);
-@end verbatim
-
-as a result of the @code{apps.Stop} call.
-
-The ultimate result of these calls is that we want to have the simulator 
-automatically make calls into our @code{Applications} to tell them when to
-start and stop.  In the case of @code{MyApp}, it inherits from class
-@code{Application} and overrides @code{StartApplication}, and 
-@code{StopApplication}.  These are the functions that will be called by
-the simulator at the appropriate time.  In the case of @code{MyApp} you
-will find that @code{MyApp::StartApplication} does the initial @code{Bind},
-and @code{Connect} on the socket, and then starts data flowing by calling
-@code{MyApp::SendPacket}.  @code{MyApp::StopApplication} stops generating
-packets by cancelling any pending send events and closing the socket.
-
-One of the nice things about @command{ns-3} is that you can completely 
-ignore the implementation details of how your @code{Application} is 
-``automagically'' called by the simulator at the correct time.  But since
-we have already ventured deep into @command{ns-3} already, let's go for it.
-
-If you look at @code{src/node/application.cc} you will find that the
-@code{SetStartTime} method of an @code{Application} just sets the member 
-variable @code{m_startTime} and the @code{SetStopTime} method just sets 
-@code{m_stopTime}.  From there, without some hints, the trail will probably
-end.
-
-The key to picking up the trail again is to know that there is a global 
-list of all of the nodes in the system.  Whenever you create a node in 
-a simulation, a pointer to that node is added to the global @code{NodeList}.
-
-Take a look at @code{src/node/node-list.cc} and search for 
-@code{NodeList::Add}.  The public static implementation calls into a private
-implementation called @code{NodeListPriv::Add}.  This is a relatively common
-idom in @command{ns-3}.  So, take a look at @code{NodeListPriv::Add}.  There
-you will find,
-
-@verbatim
-  Simulator::ScheduleWithContext (index, TimeStep (0), &Node::Start, node);
-@end verbatim
-
-This tells you that whenever a @code{Node} is created in a simulation, as
-a side-effect, a call to that node's @code{Start} method is scheduled for
-you that happens at time zero.  Don't read too much into that name, yet.
-It doesn't mean that the node is going to start doing anything, it can be
-interpreted as an informational call into the @code{Node} telling it that 
-the simulation has started, not a call for action telling the @code{Node}
-to start doing something.
-
-So, @code{NodeList::Add} indirectly schedules a call to @code{Node::Start}
-at time zero to advise a new node that the simulation has started.  If you 
-look in @code{src/node/node.h} you will, however, not find a method called
-@code{Node::Start}.  It turns out that the @code{Start} method is inherited
-from class @code{Object}.  All objects in the system can be notified when
-the simulation starts, and objects of class @code{Node} are just one kind
-of those objects.
-
-Take a look at @code{src/core/object.cc} next and search for @code{Object::Start}.
-This code is not as straightforward as you might have expected since 
-@command{ns-3} @code{Objects} support aggregation.  The code in 
-@code{Object::Start} then loops through all of the objects that have been
-aggregated together and calls their @code{DoStart} method.  This is another
-idiom that is very common in @command{ns-3}.  There is a public API method,
-that stays constant across implementations, that calls a private implementation
-method that is inherited and implemented by subclasses.  The names are typically
-something like @code{MethodName} for the public API and @code{DoMethodName} for
-the private API.
-
-This tells us that we should look for a @code{Node::DoStart} method in 
-@code{src/node/node.cc} for the method that will continue our trail.  If you
-locate the code, you will find a method that loops through all of the devices
-in the node and then all of the applications in the node calling 
-@code{device->Start} and @code{application->Start} respectively.
-
-You may already know that classes @code{Device} and @code{Application} both
-inherit from class @code{Object} and so the next step will be to look at
-what happens when @code{Application::DoStart} is called.  Take a look at
-@code{src/node/application.cc} and you will find:
-
-@verbatim
-  void
-  Application::DoStart (void)
-  {
-    m_startEvent = Simulator::Schedule (m_startTime, &Application::StartApplication, this);
-    if (m_stopTime != TimeStep (0))
-      {
-        m_stopEvent = Simulator::Schedule (m_stopTime, &Application::StopApplication, this);
-      }
-    Object::DoStart ();
-  }
-@end verbatim
-
-Here, we finally come to the end of the trail.  If you have kept it all straight,
-when you implement an @command{ns-3} @code{Application}, your new application 
-inherits from class @code{Application}.  You override the @code{StartApplication}
-and @code{StopApplication} methods and provide mechanisms for starting and 
-stopping the flow of data out of your new @code{Application}.  When a @code{Node}
-is created in the simulation, it is added to a global @code{NodeList}.  The act
-of adding a node to this @code{NodeList} causes a simulator event to be scheduled
-for time zero which calls the @code{Node::Start} method of the newly added 
-@code{Node} to be called when the simulation starts.  Since a @code{Node} inherits
-from @code{Object}, this calls the @code{Object::Start} method on the @code{Node}
-which, in turn, calls the @code{DoStart} methods on all of the @code{Objects}
-aggregated to the @code{Node} (think mobility models).  Since the @code{Node}
-@code{Object} has overridden @code{DoStart}, that method is called when the 
-simulation starts.  The @code{Node::DoStart} method calls the @code{Start} methods
-of all of the @code{Applications} on the node.  Since @code{Applications} are
-also @code{Objects}, this causes @code{Application::DoStart} to be called.  When
-@code{Application::DoStart} is called, it schedules events for the 
-@code{StartApplication} and @code{StopApplication} calls on the @code{Application}.
-These calls are designed to start and stop the flow of data from the 
-@code{Application}
-
-This has been another fairly long journey, but it only has to be made once, and
-you now understand another very deep piece of @command{ns-3}.
-
-@subsubsection The MyApp Application
-
-The @code{MyApp} @code{Application} needs a constructor and a destructor,
-of course:
-
-@verbatim
-  MyApp::MyApp ()
-    : m_socket (0),
-      m_peer (),
-      m_packetSize (0),
-      m_nPackets (0),
-      m_dataRate (0),
-      m_sendEvent (),
-      m_running (false),
-      m_packetsSent (0)
-  {
-  }
-  
-  MyApp::~MyApp()
-  {
-    m_socket = 0;
-  }
-@end verbatim
-
-The existence of the next bit of code is the whole reason why we wrote this
-@code{Application} in the first place.
-
-@verbatim
-void
-MyApp::Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, 
-                     uint32_t nPackets, DataRate dataRate)
-{
-  m_socket = socket;
-  m_peer = address;
-  m_packetSize = packetSize;
-  m_nPackets = nPackets;
-  m_dataRate = dataRate;
-}
-@end verbatim
-
-This code should be pretty self-explanatory.  We are just initializing member
-variables.  The important one from the perspective of tracing is the 
-@code{Ptr<Socket> socket} which we needed to provide to the application 
-during configuration time.  Recall that we are going to create the @code{Socket}
-as a @code{TcpSocket} (which is implemented by @code{TcpSocketImpl}) and hook 
-its ``CongestionWindow'' trace source before passing it to the @code{Setup}
-method.
-
-@verbatim
-  void
-  MyApp::StartApplication (void)
-  {
-    m_running = true;
-    m_packetsSent = 0;
-    m_socket->Bind ();
-    m_socket->Connect (m_peer);
-    SendPacket ();
-  }
-@end verbatim
-
-The above code is the overridden implementation @code{Application::StartApplication}
-that will be automatically called by the simulator to start our @code{Application}
-running at the appropriate time.  You can see that it does a @code{Socket} @code{Bind}
-operation.  If you are familiar with Berkeley Sockets this shouldn't be a surprise.
-It performs the required work on the local side of the connection just as you might 
-expect.  The following @code{Connect} will do what is required to establish a connection 
-with the TCP at @code{Address} m_peer.  It should now be clear why we need to defer
-a lot of this to simulation time, since the @code{Connect} is going to need a fully
-functioning network to complete.  After the @code{Connect}, the @code{Application} 
-then starts creating simulation events by calling @code{SendPacket}.
-
-The next bit of code explains to the @code{Application} how to stop creating 
-simulation events.
-
-@verbatim
-  void
-  MyApp::StopApplication (void)
-  {
-    m_running = false;
-  
-    if (m_sendEvent.IsRunning ())
-      {
-        Simulator::Cancel (m_sendEvent);
-      }
-  
-    if (m_socket)
-      {
-        m_socket->Close ();
-      }
-  }
-@end verbatim
-
-Every time a simulation event is scheduled, an @code{Event} is created.  If the 
-@code{Event} is pending execution or executing, its method @code{IsRunning} will
-return @code{true}.  In this code, if @code{IsRunning()} returns true, we 
-@code{Cancel} the event which removes it from the simulator event queue.  By 
-doing this, we break the chain of events that the @code{Application} is using to
-keep sending its @code{Packets} and the @code{Application} goes quiet.  After we 
-quiet the @code{Application} we @code{Close} the socket which tears down the TCP 
-connection.
-
-The socket is actually deleted in the destructor when the @code{m_socket = 0} is
-executed.  This removes the last reference to the underlying Ptr<Socket> which 
-causes the destructor of that Object to be called.
-
-Recall that @code{StartApplication} called @code{SendPacket} to start the 
-chain of events that describes the @code{Application} behavior.
-
-@verbatim
-  void
-  MyApp::SendPacket (void)
-  {
-    Ptr<Packet> packet = Create<Packet> (m_packetSize);
-    m_socket->Send (packet);
-  
-    if (++m_packetsSent < m_nPackets)
-      {
-        ScheduleTx ();
-      }
-  }
-@end verbatim
-
-Here, you see that @code{SendPacket} does just that.  It creates a @code{Packet}
-and then does a @code{Send} which, if you know Berkeley Sockets, is probably 
-just what you expected to see.
-
-It is the responsibility of the @code{Application} to keep scheduling the 
-chain of events, so the next lines call @code{ScheduleTx} to schedule another
-transmit event (a @code{SendPacket}) until the @code{Application} decides it
-has sent enough.
-
-@verbatim
-  void
-  MyApp::ScheduleTx (void)
-  {
-    if (m_running)
-      {
-        Time tNext (Seconds (m_packetSize * 8 / static_cast<double> (m_dataRate.GetBitRate ())));
-        m_sendEvent = Simulator::Schedule (tNext, &MyApp::SendPacket, this);
-      }
-  }
-@end verbatim
-
-Here, you see that @code{ScheduleTx} does exactly that.  If the @code{Application}
-is running (if @code{StopApplication} has not been called) it will schedule a 
-new event, which calls @code{SendPacket} again.  The alert reader will spot
-something that also trips up new users.  The data rate of an @code{Application} is
-just that.  It has nothing to do with the data rate of an underlying @code{Channel}.
-This is the rate at which the @code{Application} produces bits.  It does not take
-into account any overhead for the various protocols or channels that it uses to 
-transport the data.  If you set the data rate of an @code{Application} to the same
-data rate as your underlying @code{Channel} you will eventually get a buffer overflow.
-
-@subsubsection The Trace Sinks
-
-The whole point of this exercise is to get trace callbacks from TCP indicating the
-congestion window has been updated.  The next piece of code implements the 
-corresponding trace sink:
-
-@verbatim
-  static void
-  CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
-  {
-    NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << ``\t'' << newCwnd);
-  }
-@end verbatim
-
-This should be very familiar to you now, so we won't dwell on the details.  This
-function just logs the current simulation time and the new value of the 
-congestion window every time it is changed.  You can probably imagine that you
-could load the resulting output into a graphics program (gnuplot or Excel) and
-immediately see a nice graph of the congestion window behavior over time.
-
-We added a new trace sink to show where packets are dropped.  We are going to 
-add an error model to this code also, so we wanted to demonstrate this working.
-
-@verbatim
-  static void
-  RxDrop (Ptr<const Packet> p)
-  {
-    NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
-  }
-@end verbatim
-
-This trace sink will be connected to the ``PhyRxDrop'' trace source of the 
-point-to-point NetDevice.  This trace source fires when a packet is dropped
-by the physical layer of a @code{NetDevice}.  If you take a small detour to the
-source (@code{src/devices/point-to-point/point-to-point-net-device.cc}) you will
-see that this trace source refers to @code{PointToPointNetDevice::m_phyRxDropTrace}.
-If you then look in @code{src/devices/point-to-point/point-to-point-net-device.h}
-for this member variable, you will find that it is declared as a
-@code{TracedCallback<Ptr<const Packet> >}.  This should tell you that the
-callback target should be a function that returns void and takes a single
-parameter which is a @code{Ptr<const Packet>} -- just what we have above.
-
-@subsubsection The Main Program
-
-The following code should be very familiar to you by now:
-
-@verbatim
-  int
-  main (int argc, char *argv[])
-  {
-    NodeContainer nodes;
-    nodes.Create (2);
-  
-    PointToPointHelper pointToPoint;
-    pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
-    pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
-  
-    NetDeviceContainer devices;
-    devices = pointToPoint.Install (nodes);
-@end verbatim
-
-This creates two nodes with a point-to-point channel between them, just as
-shown in the illustration at the start of the file.
-
-The next few lines of code show something new.  If we trace a connection that
-behaves perfectly, we will end up with a monotonically increasing congestion
-window.  To see any interesting behavior, we really want to introduce link 
-errors which will drop packets, cause duplicate ACKs and trigger the more
-interesting behaviors of the congestion window.
-
-@command{ns-3} provides @code{ErrorModel} objects which can be attached to
-@code{Channels}.  We are using the @code{RateErrorModel} which allows us
-to introduce errors into a @code{Channel} at a given @emph{rate}. 
-
-@verbatim
-  Ptr<RateErrorModel> em = CreateObjectWithAttributes<RateErrorModel> (
-    "RanVar", RandomVariableValue (UniformVariable (0., 1.)),
-    "ErrorRate", DoubleValue (0.00001));
-  devices.Get (1)->SetAttribute ("ReceiveErrorModel", PointerValue (em));
-@end verbatim
-
-The above code instantiates a @code{RateErrorModel} Object.  Rather than 
-using the two-step process of instantiating it and then setting Attributes,
-we use the convenience function @code{CreateObjectWithAttributes} which
-allows us to do both at the same time.  We set the ``RanVar'' 
-@code{Attribute} to a random variable that generates a uniform distribution
-from 0 to 1.  We also set the ``ErrorRate'' @code{Attribute}.
-We then set the resulting instantiated @code{RateErrorModel} as the error
-model used by the point-to-point @code{NetDevice}.  This will give us some
-retransmissions and make our plot a little more interesting.
-
-@verbatim
-  InternetStackHelper stack;
-  stack.Install (nodes);
-
-  Ipv4AddressHelper address;
-  address.SetBase (``10.1.1.0'', ``255.255.255.252'');
-  Ipv4InterfaceContainer interfaces = address.Assign (devices);
-@end verbatim
-
-The above code should be familiar.  It installs internet stacks on our two
-nodes and creates interfaces and assigns IP addresses for the point-to-point
-devices.
-
-Since we are using TCP, we need something on the destination node to receive
-TCP connections and data.  The @code{PacketSink} @code{Application} is commonly
-used in @command{ns-3} for that purpose.
-
-@verbatim
-  uint16_t sinkPort = 8080;
-  Address sinkAddress (InetSocketAddress(interfaces.GetAddress (1), sinkPort));
-  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", 
-    InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
-  ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (1));
-  sinkApps.Start (Seconds (0.));
-  sinkApps.Stop (Seconds (20.));
-@end verbatim
-
-This should all be familiar, with the exception of,
-
-@verbatim
-  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", 
-    InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
-@end verbatim
-
-This code instantiates a @code{PacketSinkHelper} and tells it to create sockets
-using the class @code{ns3::TcpSocketFactory}.  This class implements a design 
-pattern called ``object factory'' which is a commonly used mechanism for 
-specifying a class used to create objects in an abstract way.  Here, instead of 
-having to create the objects themselves, you provide the @code{ PacketSinkHelper}
-a string that specifies a @code{TypeId} string used to create an object which 
-can then be used, in turn, to create instances of the Objects created by the 
-factory.
-
-The remaining parameter tells the @code{Application} which address and port it
-should @code{Bind} to.
-
-The next two lines of code will create the socket and connect the trace source.
-
-@verbatim
-  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (nodes.Get (0), 
-    TcpSocketFactory::GetTypeId ());
-  ns3TcpSocket->TraceConnectWithoutContext (``CongestionWindow'', 
-    MakeCallback (&CwndChange));
-@end verbatim
-
-The first statement calls the static member function @code{Socket::CreateSocket}
-and provides a @code{Node} and an explicit @code{TypeId} for the object factory
-used to create the socket.  This is a slightly lower level call than the 
-@code{PacketSinkHelper} call above, and uses an explicit C++ type instead of 
-one referred to by a string.  Otherwise, it is conceptually the same thing.
-
-Once the @code{TcpSocket} is created and attached to the @code{Node}, we can
-use @code{TraceConnectWithoutContext} to connect the CongestionWindow trace 
-source to our trace sink.
-
-Recall that we coded an @code{Application} so we could take that @code{Socket}
-we just made (during configuration time) and use it in simulation time.  We now 
-have to instantiate that @code{Application}.  We didn't go to any trouble to
-create a helper to manage the @code{Application} so we are going to have to 
-create and install it ``manually''.  This is actually quite easy:
-
-@verbatim
-  Ptr<MyApp> app = CreateObject<MyApp> ();
-  app->Setup (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("1Mbps"));
-  nodes.Get (0)->AddApplication (app);
-  app->Start (Seconds (1.));
-  app->Stop (Seconds (20.));
-@end verbatim
-
-The first line creates an @code{Object} of type @code{MyApp} -- our
-@code{Application}.  The second line tells the @code{Application} what
-@code{Socket} to use, what address to connect to, how much data to send 
-at each send event, how many send events to generate and the rate at which
-to produce data from those events.
-
-Next, we manually add the @code{MyApp Application} to the source node
-and explicitly call the @code{Start} and @code{Stop} methods on the 
-@code{Application} to tell it when to start and stop doing its thing.
-
-We need to actually do the connect from the receiver point-to-point @code{NetDevice}
-to our callback now.
-
-@verbatim
-  devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeCallback (&RxDrop));
-@end verbatim
-
-It should now be obvious that we are getting a reference to the receiving 
-@code{Node NetDevice} from its container and connecting the trace source defined
-by the attribute ``PhyRxDrop'' on that device to the trace sink @code{RxDrop}.
-
-Finally, we tell the simulator to override any @code{Applications} and just
-stop processing events at 20 seconds into the simulation.
-
-@verbatim
-    Simulator::Stop (Seconds(20));
-    Simulator::Run ();
-    Simulator::Destroy ();
-
-    return 0;
-  }
-@end verbatim
-
-Recall that as soon as @code{Simulator::Run} is called, configuration time
-ends, and simulation time begins.  All of the work we orchestrated by 
-creating the @code{Application} and teaching it how to connect and send
-data actually happens during this function call.
-
-As soon as @code{Simulator::Run} returns, the simulation is complete and
-we enter the teardown phase.  In this case, @code{Simulator::Destroy} takes
-care of the gory details and we just return a success code after it completes.
-
-@subsection Running fifth.cc
-
-Since we have provided the file @code{fifth.cc} for you, if you have built
-your distribution (in debug mode since it uses NS_LOG -- recall that optimized
-builds optimize out NS_LOGs) it will be waiting for you to run.
-
-@verbatim
-  ./waf --run fifth
-  Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build
-  Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build'
-  'build' finished successfully (0.684s)
-  1.20919 1072
-  1.21511 1608
-  1.22103 2144
-  ...
-  1.2471  8040
-  1.24895 8576
-  1.2508  9112
-  RxDrop at 1.25151
-  ...
-@end verbatim
-
-You can probably see immediately a downside of using prints of any kind in your
-traces.  We get those extraneous waf messages printed all over our interesting
-information along with those RxDrop messages.  We will remedy that soon, but I'm
-sure you can't wait to see the results of all of this work.  Let's redirect that
-output to a file called @code{cwnd.dat}:
-
-@verbatim
-  ./waf --run fifth > cwnd.dat 2>&1
-@end verbatim
-
-Now edit up ``cwnd.dat'' in your favorite editor and remove the waf build status
-and drop lines, leaving only the traced data (you could also comment out the
-@code{TraceConnectWithoutContext("PhyRxDrop", MakeCallback (&RxDrop));} in the
-script to get rid of the drop prints just as easily. 
-
-You can now run gnuplot (if you have it installed) and tell it to generate some 
-pretty pictures:
-
-@verbatim
-  gnuplot> set terminal png size 640,480
-  gnuplot> set output "cwnd.png"
-  gnuplot> plot "cwnd.dat" using 1:2 title 'Congestion Window' with linespoints
-  gnuplot> exit
-@end verbatim
-
-You should now have a graph of the congestion window versus time sitting in the 
-file ``cwnd.png'' in all of its glory, that looks like:
-
-@sp 1
-@center @image{figures/cwnd,,,,png}
-
-@subsection Using Mid-Level Helpers
-
-In the previous section, we showed how to hook a trace source and get hopefully
-interesting information out of a simulation.  Perhaps you will recall that we 
-called logging to the standard output using @code{std::cout} a ``Blunt Instrument'' 
-much earlier in this chapter.  We also wrote about how it was a problem having
-to parse the log output in order to isolate interesting information.  It may 
-have occurred to you that we just spent a lot of time implementing an example
-that exhibits all of the problems we purport to fix with the @code{ns-3} tracing
-system!  You would be correct.  But, bear with us.  We're not done yet.
-
-One of the most important things we want to do is to is to have the ability to 
-easily control the amount of output coming out of the simulation; and we also 
-want to save those data to a file so we can refer back to it later.  We can use
-the mid-level trace helpers provided in @code{ns-3} to do just that and complete
-the picture.
-
-We provide a script that writes the cwnd change and drop events developed in 
-the example @code{fifth.cc } to disk in separate files.  The cwnd changes are 
-stored as a tab-separated ASCII file and the drop events are stored in a pcap
-file.  The changes to make this happen are quite small.
-
-@subsubsection A sixth.cc Walkthrough
-
-Let's take a look at the changes required to go from @code{fifth.cc} to 
-@code{sixth.cc}.  Open @code{examples/tutorial/fifth.cc} in your favorite 
-editor.  You can see the first change by searching for CwndChange.  You will 
-find that we have changed the signatures for the trace sinks and have added 
-a single line to each sink that writes the traced information to a stream
-representing a file.
-
-@verbatim
-  static void
-  CwndChange (Ptr<OutputStreamWrapper> stream, uint32_t oldCwnd, uint32_t newCwnd)
-  {
-    NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
-    *stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
-  }
-  
-  static void
-  RxDrop (Ptr<PcapFileWrapper> file, Ptr<const Packet> p)
-  {
-    NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
-    file->Write(Simulator::Now(), p);
-  }
-@end verbatim
-
-We have added a ``stream'' parameter to the @code{CwndChange} trace sink.  
-This is an object that holds (keeps safely alive) a C++ output stream.  It 
-turns out that this is a very simple object, but one that manages lifetime 
-issues for the stream and solves a problem that even experienced C++ users 
-run into.  It turns out that the copy constructor for ostream is marked 
-private.  This means that ostreams do not obey value semantics and cannot 
-be used in any mechanism that requires the stream to be copied.  This includes
-the @command{ns-3} callback system, which as you may recall, requires objects
-that obey value semantics.  Further notice that we have added the following 
-line in the @code{CwndChange} trace sink implementation:
-
-@verbatim
-  *stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
-@end verbatim  
-
-This would be very familiar code if you replaced @code{*stream->GetStream ()}
-with @code{std::cout}, as in:
-
-@verbatim
-  std::cout << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
-@end verbatim  
-
-This illustrates that the @code{Ptr<OutputStreamWrapper>} is really just
-carrying around a @code{std::ofstream} for you, and you can use it here like 
-any other output stream.
-
-A similar situation happens in @code{RxDrop} except that the object being 
-passed around (a @code{Ptr<PcapFileWrapper>}) represents a pcap file.  There
-is a one-liner in the trace sink to write a timestamp and the contents of the 
-packet being dropped to the pcap file:
-
-@verbatim
-  file->Write(Simulator::Now(), p);
-@end verbatim
-
-Of course, if we have objects representing the two files, we need to create
-them somewhere and also cause them to be passed to the trace sinks.  If you 
-look in the @code{main} function, you will find new code to do just that:
-
-@verbatim
-  AsciiTraceHelper asciiTraceHelper;
-  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("sixth.cwnd");
-  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeBoundCallback (&CwndChange, stream));
-
-  ...
-
-  PcapHelper pcapHelper;
-  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile ("sixth.pcap", std::ios::out, PcapHelper::DLT_PPP);
-  devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file));
-@end verbatim
-
-In the first section of the code snippet above, we are creating the ASCII
-trace file, creating an object responsible for managing it and using a
-variant of the callback creation function to arrange for the object to be 
-passed to the sink.  Our ASCII trace helpers provide a rich set of
-functions to make using text (ASCII) files easy.  We are just going to 
-illustrate the use of the file stream creation function here.
-
-The @code{CreateFileStream{}} function is basically going to instantiate
-a std::ofstream object and create a new file (or truncate an existing file).
-This ofstream is packaged up in an @code{ns-3} object for lifetime management
-and copy constructor issue resolution.
-
-We then take this @code{ns-3} object representing the file and pass it to
-@code{MakeBoundCallback()}.  This function creates a callback just like
-@code{MakeCallback()}, but it ``binds'' a new value to the callback.  This
-value is added to the callback before it is called.  
-
-Essentially, @code{MakeBoundCallback(&CwndChange, stream)} causes the trace 
-source to add the additional ``stream'' parameter to the front of the formal
-parameter list before invoking the callback.  This changes the required 
-signature of the @code{CwndChange} sink to match the one shown above, which
-includes the ``extra'' parameter @code{Ptr<OutputStreamWrapper> stream}.
-
-In the second section of code in the snippet above, we instantiate a 
-@code{PcapHelper} to do the same thing for our pcap trace file that we did
-with the @code{AsciiTraceHelper}. The line of code,
-
-@verbatim
-  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile ("sixth.pcap", "w", PcapHelper::DLT_PPP);
-@end verbatim
-
-creates a pcap file named ``sixth.pcap'' with file mode ``w''.   This means that
-the new file is to truncated if an existing file with that name is found.  The
-final parameter is the ``data link type'' of the new pcap file.  These are 
-the same as the pcap library data link types defined in @code{bpf.h} if you are
-familar with pcap.  In this case, @code{DLT_PPP} indicates that the pcap file
-is going to contain packets prefixed with point to point headers.  This is true
-since the packets are coming from our point-to-point device driver.  Other
-common data link types are DLT_EN10MB (10 MB Ethernet) appropriate for csma
-devices and DLT_IEEE802_11 (IEEE 802.11) appropriate for wifi devices.  These
-are defined in @code{src/helper/trace-helper.h"} if you are interested in seeing
-the list.  The entries in the list match those in @code{bpf.h} but we duplicate
-them to avoid a pcap source dependence.
-
-A @code{ns-3} object representing the pcap file is returned from @code{CreateFile}
-and used in a bound callback exactly as it was in the ascii case.
-
-An important detour:  It is important to notice that even though both of these 
-objects are declared in very similar ways,
-
-@verbatim
-  Ptr<PcapFileWrapper> file ...
-  Ptr<OutputStreamWrapper> stream ...
-@end verbatim
-
-The underlying objects are entirely different.  For example, the 
-Ptr<PcapFileWrapper> is a smart pointer to an @command{ns-3} Object that is a 
-fairly heaviweight thing that supports @code{Attributes} and is integrated into
-the config system.  The Ptr<OutputStreamWrapper>, on the other hand, is a smart 
-pointer to a reference counted object that is a very lightweight thing.
-Remember to always look at the object you are referencing before making any
-assumptions about the ``powers'' that object may have.  
-
-For example, take a look at @code{src/common/pcap-file-object.h} in the 
-distribution and notice, 
-
-@verbatim
-  class PcapFileWrapper : public Object
-@end verbatim
-
-that class @code{PcapFileWrapper} is an @command{ns-3} Object by virtue of 
-its inheritance.  Then look at @code{src/common/output-stream-wrapper.h} and 
-notice,
-
-@verbatim
-  class OutputStreamWrapper : public SimpleRefCount<OutputStreamWrapper>
-@end verbatim
-
-that this object is not an @command{ns-3} Object at all, it is ``merely'' a
-C++ object that happens to support intrusive reference counting.
-
-The point here is that just because you read Ptr<something> it does not necessarily
-mean that ``something'' is an @command{ns-3} Object on which you can hang @command{ns-3}
-@code{Attributes}, for example.
-
-Now, back to the example.  If you now build and run this example,
-
-@verbatim
-  ./waf --run sixth
-@end verbatim
-
-you will see the same messages appear as when you ran ``fifth'', but two new 
-files will appear in the top-level directory of your @code{ns-3} distribution.
-
-@verbatim
-  sixth.cwnd  sixth.pcap
-@end verbatim
-
-Since ``sixth.cwnd'' is an ASCII text file, you can view it with @code{cat}
-or your favorite file viewer.
-
-@verbatim
-  1.20919 536     1072
-  1.21511 1072    1608
-  ...
-  9.30922 8893    8925
-  9.31754 8925    8957
-@end verbatim
-
-You have a tab separated file with a timestamp, an old congestion window and a
-new congestion window suitable for directly importing into your plot program.
-There are no extraneous prints in the file, no parsing or editing is required.
-
-Since ``sixth.pcap'' is a pcap file, you can fiew it with @code{tcpdump}.
-
-@verbatim
-  reading from file ../../sixth.pcap, link-type PPP (PPP)
-  1.251507 IP 10.1.1.1.49153 > 10.1.1.2.8080: . 17689:18225(536) ack 1 win 65535
-  1.411478 IP 10.1.1.1.49153 > 10.1.1.2.8080: . 33808:34312(504) ack 1 win 65535
-  ...
-  7.393557 IP 10.1.1.1.49153 > 10.1.1.2.8080: . 781568:782072(504) ack 1 win 65535
-  8.141483 IP 10.1.1.1.49153 > 10.1.1.2.8080: . 874632:875168(536) ack 1 win 65535
-@end verbatim
-
-You have a pcap file with the packets that were dropped in the simulation.  There
-are no other packets present in the file and there is nothing else present to
-make life difficult.
-
-It's been a long journey, but we are now at a point where we can appreciate the
-@code{ns-3} tracing system.  We have pulled important events out of the middle
-of a TCP implementation and a device driver.  We stored those events directly in
-files usable with commonly known tools.  We did this without modifying any of the
-core code involved, and we did this in only 18 lines of code:
-
-@verbatim
-  static void
-  CwndChange (Ptr<OutputStreamWrapper> stream, uint32_t oldCwnd, uint32_t newCwnd)
-  {
-    NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
-    *stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
-  }
-
-  ...
-
-  AsciiTraceHelper asciiTraceHelper;
-  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("sixth.cwnd");
-  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeBoundCallback (&CwndChange, stream));
-
-  ...
-
-  static void
-  RxDrop (Ptr<PcapFileWrapper> file, Ptr<const Packet> p)
-  {
-    NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
-    file->Write(Simulator::Now(), p);
-  }
-
-  ...
-  
-  PcapHelper pcapHelper;
-  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile ("sixth.pcap", "w", PcapHelper::DLT_PPP);
-  devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file));
-@end verbatim
-
-@c ============================================================================
-@c Using Trace Helpers
-@c ============================================================================
-@node Using Trace Helpers
-@section Using Trace Helpers
-
-The @code{ns-3} trace helpers provide a rich environment for configuring and
-selecting different trace events and writing them to files.  In previous
-sections, primarily ``Building Topologies,'' we have seen several varieties
-of the trace helper methods designed for use inside other (device) helpers.
-
-Perhaps you will recall seeing some of these variations: 
-
-@verbatim
-  pointToPoint.EnablePcapAll ("second");
-  pointToPoint.EnablePcap ("second", p2pNodes.Get (0)->GetId (), 0);
-  csma.EnablePcap ("third", csmaDevices.Get (0), true);
-  pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));
-@end verbatim
-
-What may not be obvious, though, is that there is a consistent model for all of 
-the trace-related methods found in the system.  We will now take a little time
-and take a look at the ``big picture''.
-
-There are currently two primary use cases of the tracing helpers in @code{ns-3}:
-Device helpers and protocol helpers.  Device helpers look at the problem
-of specifying which traces should be enabled through a node, device pair.  For 
-example, you may want to specify that pcap tracing should be enabled on a 
-particular device on a specific node.  This follows from the @code{ns-3} device
-conceptual model, and also the conceptual models of the various device helpers.
-Following naturally from this, the files created follow a 
-<prefix>-<node>-<device> naming convention.  
-
-Protocol helpers look at the problem of specifying which traces should be
-enabled through a protocol and interface pair.  This follows from the @code{ns-3}
-protocol stack conceptual model, and also the conceptual models of internet
-stack helpers.  Naturally, the trace files should follow a 
-<prefix>-<protocol>-<interface> naming convention.
-
-The trace helpers therefore fall naturally into a two-dimensional taxonomy.
-There are subtleties that prevent all four classes from behaving identically,
-but we do strive to make them all work as similarly as possible; and whenever
-possible there are analogs for all methods in all classes.
-
-@verbatim
-                   | pcap | ascii |
-  -----------------+------+-------|
-  Device Helper    |      |       |
-  -----------------+------+-------|
-  Protocol Helper  |      |       |
-  -----------------+------+-------|
-@end verbatim
-
-We use an approach called a @code{mixin} to add tracing functionality to our 
-helper classes.  A @code{mixin} is a class that provides functionality to that
-is inherited by a subclass.  Inheriting from a mixin is not considered a form 
-of specialization but is really a way to collect functionality. 
-
-Let's take a quick look at all four of these cases and their respective 
-@code{mixins}.
-
-@subsection Pcap Tracing Device Helpers
-
-The goal of these helpers is to make it easy to add a consistent pcap trace
-facility to an @code{ns-3} device.  We want all of the various flavors of
-pcap tracing to work the same across all devices, so the methods of these 
-helpers are inherited by device helpers.  Take a look at 
-@code{src/helper/trace-helper.h} if you want to follow the discussion while 
-looking at real code.
-
-The class @code{PcapHelperForDevice} is a @code{mixin} provides the high level 
-functionality for using pcap tracing in an @code{ns-3} device.  Every device 
-must implement a single virtual method inherited from this class.
-
-@verbatim
-  virtual void EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous, bool explicitFilename) = 0;
-@end verbatim
-
-The signature of this method reflects the device-centric view of the situation
-at this level.  All of the public methods inherited from class 
-2@code{PcapUserHelperForDevice} reduce to calling this single device-dependent
-implementation method.  For example, the lowest level pcap method,
-
-@verbatim
-  void EnablePcap (std::string prefix, Ptr<NetDevice> nd, bool promiscuous = false, bool explicitFilename = false);
-@end verbatim
-
-will call the device implementation of @code{EnablePcapInternal} directly.  All
-other public pcap tracing methods build on this implementation to provide 
-additional user-level functionality.  What this means to the user is that all 
-device helpers in the system will have all of the pcap trace methods available;
-and these methods will all work in the same way across devices if the device 
-implements @code{EnablePcapInternal} correctly.
-
-@subsubsection Pcap Tracing Device Helper Methods
-
-@verbatim
-  void EnablePcap (std::string prefix, Ptr<NetDevice> nd, bool promiscuous = false, bool explicitFilename = false);
-  void EnablePcap (std::string prefix, std::string ndName, bool promiscuous = false, bool explicitFilename = false);
-  void EnablePcap (std::string prefix, NetDeviceContainer d, bool promiscuous = false);
-  void EnablePcap (std::string prefix, NodeContainer n, bool promiscuous = false);
-  void EnablePcap (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool promiscuous = false);
-  void EnablePcapAll (std::string prefix, bool promiscuous = false);
-@end verbatim
-
-In each of the methods shown above, there is a default parameter called 
-@code{promiscuous} that defaults to false.  This parameter indicates that the
-trace should not be gathered in promiscuous mode.  If you do want your traces
-to include all traffic seen by the device (and if the device supports a 
-promiscuous mode) simply add a true parameter to any of the calls above.  For example,
-
-@verbatim
-  Ptr<NetDevice> nd;
-  ...
-  helper.EnablePcap ("prefix", nd, true);
-@end verbatim
-
-will enable promiscuous mode captures on the @code{NetDevice} specified by @code{nd}.
-
-The first two methods also include a default parameter called @code{explicitFilename}
-that will be discussed below.
-
-You are encouraged to peruse the Doxygen for class @code{PcapHelperForDevice}
-to find the details of these methods; but to summarize ...
-
-You can enable pcap tracing on a particular node/net-device pair by providing a
-@code{Ptr<NetDevice>} to an @code{EnablePcap} method.  The @code{Ptr<Node>} is 
-implicit since the net device must belong to exactly one @code{Node}.
-For example, 
-
-@verbatim
-  Ptr<NetDevice> nd;
-  ...
-  helper.EnablePcap ("prefix", nd);
-@end verbatim
-
-You can enable pcap tracing on a particular node/net-device pair by providing a
-@code{std::string} representing an object name service string to an 
-@code{EnablePcap} method.  The @code{Ptr<NetDevice>} is looked up from the name
-string.  Again, the @code<Node> is implicit since the named net device must 
-belong to exactly one @code{Node}.  For example, 
-
-@verbatim
-  Names::Add ("server" ...);
-  Names::Add ("server/eth0" ...);
-  ...
-  helper.EnablePcap ("prefix", "server/ath0");
-@end verbatim
-
-You can enable pcap tracing on a collection of node/net-device pairs by 
-providing a @code{NetDeviceContainer}.  For each @code{NetDevice} in the container
-the type is checked.  For each device of the proper type (the same type as is 
-managed by the device helper), tracing is enabled.    Again, the @code<Node> is 
-implicit since the found net device must belong to exactly one @code{Node}.
-For example, 
-
-@verbatim
-  NetDeviceContainer d = ...;
-  ...
-  helper.EnablePcap ("prefix", d);
-@end verbatim
-
-You can enable pcap tracing on a collection of node/net-device pairs by 
-providing a @code{NodeContainer}.  For each @code{Node} in the @code{NodeContainer}
-its attached @code{NetDevices} are iterated.  For each @code{NetDevice} attached
-to each node in the container, the type of that device is checked.  For each 
-device of the proper type (the same type as is managed by the device helper), 
-tracing is enabled.
-
-@verbatim
-  NodeContainer n;
-  ...
-  helper.EnablePcap ("prefix", n);
-@end verbatim
-
-You can enable pcap tracing on the basis of node ID and device ID as well as
-with explicit @code{Ptr}.  Each @code{Node} in the system has an integer node ID
-and each device connected to a node has an integer device ID.
-
-@verbatim
-  helper.EnablePcap ("prefix", 21, 1);
-@end verbatim
-
-Finally, you can enable pcap tracing for all devices in the system, with the
-same type as that managed by the device helper.
-
-@verbatim
-  helper.EnablePcapAll ("prefix");
-@end verbatim
-
-@subsubsection Pcap Tracing Device Helper Filename Selection
-
-Implicit in the method descriptions above is the construction of a complete 
-filename by the implementation method.  By convention, pcap traces in the 
-@code{ns-3} system are of the form ``<prefix>-<node id>-<device id>.pcap''
-
-As previously mentioned, every node in the system will have a system-assigned
-node id; and every device will have an interface index (also called a device id)
-relative to its node.  By default, then, a pcap trace file created as a result
-of enabling tracing on the first device of node 21 using the prefix ``prefix''
-would be ``prefix-21-1.pcap''.
-
-You can always use the @code{ns-3} object name service to make this more clear.
-For example, if you use the object name service to assign the name ``server''
-to node 21, the resulting pcap trace file name will automatically become,
-``prefix-server-1.pcap'' and if you also assign the name ``eth0'' to the 
-device, your pcap file name will automatically pick this up and be called
-``prefix-server-eth0.pcap''.
-
-Finally, two of the methods shown above,
-
-@verbatim
-  void EnablePcap (std::string prefix, Ptr<NetDevice> nd, bool promiscuous = false, bool explicitFilename = false);
-  void EnablePcap (std::string prefix, std::string ndName, bool promiscuous = false, bool explicitFilename = false);
-@end verbatim
-
-have a default parameter called @code{explicitFilename}.  When set to true,
-this parameter disables the automatic filename completion mechanism and allows
-you to create an explicit filename.  This option is only available in the 
-methods which enable pcap tracing on a single device.  
-
-For example, in order to arrange for a device helper to create a single 
-promiscuous pcap capture file of a specific name (``my-pcap-file.pcap'') on a
-given device, one could:
-
-@verbatim
-  Ptr<NetDevice> nd;
-  ...
-  helper.EnablePcap ("my-pcap-file.pcap", nd, true, true);
-@end verbatim
-
-The first @code{true} parameter enables promiscuous mode traces and the second
-tells the helper to interpret the @code{prefix} parameter as a complete filename.
-
-@subsection Ascii Tracing Device Helpers
-
-The behavior of the ascii trace helper @code{mixin} is substantially similar to 
-the pcap version.  Take a look at @code{src/helper/trace-helper.h} if you want to 
-follow the discussion while looking at real code.
-
-The class @code{AsciiTraceHelperForDevice} adds the high level functionality for 
-using ascii tracing to a device helper class.  As in the pcap case, every device
-must implement a single virtual method inherited from the ascii trace @code{mixin}.
-
-@verbatim
-  virtual void EnableAsciiInternal (Ptr<OutputStreamWrapper> stream, 
-                                    std::string prefix, 
-                                    Ptr<NetDevice> nd,
-                                    bool explicitFilename) = 0;
-
-@end verbatim
-
-The signature of this method reflects the device-centric view of the situation
-at this level; and also the fact that the helper may be writing to a shared
-output stream.  All of the public ascii-trace-related methods inherited from 
-class @code{AsciiTraceHelperForDevice} reduce to calling this single device-
-dependent implementation method.  For example, the lowest level ascii trace
-methods,
-
-@verbatim
-  void EnableAscii (std::string prefix, Ptr<NetDevice> nd, bool explicitFilename = false);
-  void EnableAscii (Ptr<OutputStreamWrapper> stream, Ptr<NetDevice> nd);
-@verbatim
-
-will call the device implementation of @code{EnableAsciiInternal} directly,
-providing either a valid prefix or stream.  All other public ascii tracing 
-methods will build on these low-level functions to provide additional user-level
-functionality.  What this means to the user is that all device helpers in the 
-system will have all of the ascii trace methods available; and these methods
-will all work in the same way across devices if the devices implement 
-@code{EnablAsciiInternal} correctly.
-
-@subsubsection Ascii Tracing Device Helper Methods
-
-@verbatim
-  void EnableAscii (std::string prefix, Ptr<NetDevice> nd, bool explicitFilename = false);
-  void EnableAscii (Ptr<OutputStreamWrapper> stream, Ptr<NetDevice> nd);
-
-  void EnableAscii (std::string prefix, std::string ndName, bool explicitFilename = false);
-  void EnableAscii (Ptr<OutputStreamWrapper> stream, std::string ndName);
-
-  void EnableAscii (std::string prefix, NetDeviceContainer d);
-  void EnableAscii (Ptr<OutputStreamWrapper> stream, NetDeviceContainer d);
-
-  void EnableAscii (std::string prefix, NodeContainer n);
-  void EnableAscii (Ptr<OutputStreamWrapper> stream, NodeContainer n);
-
-  void EnableAsciiAll (std::string prefix);
-  void EnableAsciiAll (Ptr<OutputStreamWrapper> stream);
-
-  void EnableAscii (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool explicitFilename);
-  void EnableAscii (Ptr<OutputStreamWrapper> stream, uint32_t nodeid, uint32_t deviceid);
-@end verbatim
-
-You are encouraged to peruse the Doxygen for class @code{TraceHelperForDevice}
-to find the details of these methods; but to summarize ...
-
-There are twice as many methods available for ascii tracing as there were for
-pcap tracing.  This is because, in addition to the pcap-style model where traces
-from each unique node/device pair are written to a unique file, we support a model
-in which trace information for many node/device pairs is written to a common file.
-This means that the <prefix>-<node>-<device> file name generation mechanism is 
-replaced by a mechanism to refer to a common file; and the number of API methods
-is doubled to allow all combinations.
-
-Just as in pcap tracing, you can enable ascii tracing on a particular 
-node/net-device pair by providing a @code{Ptr<NetDevice>} to an @code{EnableAscii}
-method.  The @code{Ptr<Node>} is implicit since the net device must belong to 
-exactly one @code{Node}.  For example, 
-
-@verbatim
-  Ptr<NetDevice> nd;
-  ...
-  helper.EnableAscii ("prefix", nd);
-@end verbatim
-
-The first four methods also include a default parameter called @code{explicitFilename}
-that operate similar to equivalent parameters in the pcap case.
-
-In this case, no trace contexts are written to the ascii trace file since they
-would be redundant.  The system will pick the file name to be created using
-the same rules as described in the pcap section, except that the file will
-have the suffix ``.tr'' instead of ``.pcap''.
-
-If you want to enable ascii tracing on more than one net device and have all 
-traces sent to a single file, you can do that as well by using an object to
-refer to a single file.  We have already seen this in the ``cwnd'' example
-above:
-
-@verbatim
-  Ptr<NetDevice> nd1;
-  Ptr<NetDevice> nd2;
-  ...
-  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
-  ...
-  helper.EnableAscii (stream, nd1);
-  helper.EnableAscii (stream, nd2);
-@verbatim
-
-In this case, trace contexts are written to the ascii trace file since they
-are required to disambiguate traces from the two devices.  Note that since the
-user is completely specifying the file name, the string should include the ``,tr''
-for consistency.
-
-You can enable ascii tracing on a particular node/net-device pair by providing a
-@code{std::string} representing an object name service string to an 
-@code{EnablePcap} method.  The @code{Ptr<NetDevice>} is looked up from the name
-string.  Again, the @code<Node> is implicit since the named net device must 
-belong to exactly one @code{Node}.  For example, 
-
-@verbatim
-  Names::Add ("client" ...);
-  Names::Add ("client/eth0" ...);
-  Names::Add ("server" ...);
-  Names::Add ("server/eth0" ...);
-  ...
-  helper.EnableAscii ("prefix", "client/eth0");
-  helper.EnableAscii ("prefix", "server/eth0");
-@end verbatim
-
-This would result in two files named ``prefix-client-eth0.tr'' and 
-``prefix-server-eth0.tr'' with traces for each device in the respective trace
-file.  Since all of the EnableAscii functions are overloaded to take a stream wrapper,
-you can use that form as well:
-
-@verbatim
-  Names::Add ("client" ...);
-  Names::Add ("client/eth0" ...);
-  Names::Add ("server" ...);
-  Names::Add ("server/eth0" ...);
-  ...
-  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
-  ...
-  helper.EnableAscii (stream, "client/eth0");
-  helper.EnableAscii (stream, "server/eth0");
-@end verbatim
-
-This would result in a single trace file called ``trace-file-name.tr'' that 
-contains all of the trace events for both devices.  The events would be 
-disambiguated by trace context strings.
-
-You can enable ascii tracing on a collection of node/net-device pairs by 
-providing a @code{NetDeviceContainer}.  For each @code{NetDevice} in the container
-the type is checked.  For each device of the proper type (the same type as is 
-managed by the device helper), tracing is enabled.    Again, the @code<Node> is 
-implicit since the found net device must belong to exactly one @code{Node}.
-For example, 
-
-@verbatim
-  NetDeviceContainer d = ...;
-  ...
-  helper.EnableAscii ("prefix", d);
-@end verbatim
-
-This would result in a number of ascii trace files being created, each of which
-follows the <prefix>-<node id>-<device id>.tr convention.  Combining all of the
-traces into a single file is accomplished similarly to the examples above:
-
-@verbatim
-  NetDeviceContainer d = ...;
-  ...
-  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
-  ...
-  helper.EnableAscii (stream, d);
-@end verbatim
-
-You can enable ascii tracing on a collection of node/net-device pairs by 
-providing a @code{NodeContainer}.  For each @code{Node} in the @code{NodeContainer}
-its attached @code{NetDevices} are iterated.  For each @code{NetDevice} attached
-to each node in the container, the type of that device is checked.  For each 
-device of the proper type (the same type as is managed by the device helper), 
-tracing is enabled.
-
-@verbatim
-  NodeContainer n;
-  ...
-  helper.EnableAscii ("prefix", n);
-@end verbatim
-
-This would result in a number of ascii trace files being created, each of which
-follows the <prefix>-<node id>-<device id>.tr convention.  Combining all of the
-traces into a single file is accomplished similarly to the examples above:
-
-You can enable pcap tracing on the basis of node ID and device ID as well as
-with explicit @code{Ptr}.  Each @code{Node} in the system has an integer node ID
-and each device connected to a node has an integer device ID.
-
-@verbatim
-  helper.EnableAscii ("prefix", 21, 1);
-@end verbatim
-
-Of course, the traces can be combined into a single file as shown above.
-
-Finally, you can enable pcap tracing for all devices in the system, with the
-same type as that managed by the device helper.
-
-@verbatim
-  helper.EnableAsciiAll ("prefix");
-@end verbatim
-
-This would result in a number of ascii trace files being created, one for
-every device in the system of the type managed by the helper.  All of these
-files will follow the <prefix>-<node id>-<device id>.tr convention.  Combining
-all of the traces into a single file is accomplished similarly to the examples
-above.
-
-@subsubsection Ascii Tracing Device Helper Filename Selection
-
-Implicit in the prefix-style method descriptions above is the construction of the
-complete filenames by the implementation method.  By convention, ascii traces
-in the @code{ns-3} system are of the form ``<prefix>-<node id>-<device id>.tr''
-
-As previously mentioned, every node in the system will have a system-assigned
-node id; and every device will have an interface index (also called a device id)
-relative to its node.  By default, then, an ascii trace file created as a result
-of enabling tracing on the first device of node 21, using the prefix ``prefix'',
-would be ``prefix-21-1.tr''.
-
-You can always use the @code{ns-3} object name service to make this more clear.
-For example, if you use the object name service to assign the name ``server''
-to node 21, the resulting ascii trace file name will automatically become,
-``prefix-server-1.tr'' and if you also assign the name ``eth0'' to the 
-device, your ascii trace file name will automatically pick this up and be called
-``prefix-server-eth0.tr''.
-
-Several of the methods have a default parameter called @code{explicitFilename}.
-When set to true, this parameter disables the automatic filename completion 
-mechanism and allows you to create an explicit filename.  This option is only
-available in the methods which take a prefix and enable tracing on a single device.  
-
-@subsection Pcap Tracing Protocol Helpers
-
-The goal of these @code{mixins} is to make it easy to add a consistent pcap trace
-facility to protocols.  We want all of the various flavors of pcap tracing to 
-work the same across all protocols, so the methods of these helpers are 
-inherited by stack helpers.  Take a look at @code{src/helper/trace-helper.h} 
-if you want to follow the discussion while looking at real code.
-
-In this section we will be illustrating the methods as applied to the protocol
-@code{Ipv4}.  To specify traces in similar protocols, just substitute the
-appropriate type.  For example, use a @code{Ptr<Ipv6>} instead of a
-@code{Ptr<Ipv4>} and call @code{EnablePcapIpv6} instead of @code{EnablePcapIpv4}.
-
-The class @code{PcapHelperForIpv4} provides the high level functionality for
-using pcap tracing in the @code{Ipv4} protocol.  Each protocol helper enabling these
-methods must implement a single virtual method inherited from this class.  There
-will be a separate implementation for @code{Ipv6}, for example, but the only
-difference will be in the method names and signatures.  Different method names
-are required to disambiguate class @code{Ipv4} from @code{Ipv6} which are both 
-derived from class @code{Object}, and methods that share the same signature.
-
-@verbatim
-  virtual void EnablePcapIpv4Internal (std::string prefix, 
-                                       Ptr<Ipv4> ipv4, 
-                                       uint32_t interface,
-                                       bool explicitFilename) = 0;
-@end verbatim
-
-The signature of this method reflects the protocol and interface-centric view 
-of the situation at this level.  All of the public methods inherited from class 
-@code{PcapHelperForIpv4} reduce to calling this single device-dependent
-implementation method.  For example, the lowest level pcap method,
-
-@verbatim
-  void EnablePcapIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface, bool explicitFilename = false);
-@verbatim
-
-will call the device implementation of @code{EnablePcapIpv4Internal} directly.
-All other public pcap tracing methods build on this implementation to provide 
-additional user-level functionality.  What this means to the user is that all 
-protocol helpers in the system will have all of the pcap trace methods 
-available; and these methods will all work in the same way across 
-protocols if the helper implements @code{EnablePcapIpv4Internal} correctly.
-
-@subsubsection Pcap Tracing Protocol Helper Methods
-
-These methods are designed to be in one-to-one correspondence with the @code{Node}-
-and @code{NetDevice}- centric versions of the device versions.  Instead of
-@code{Node} and @code{NetDevice} pair constraints, we use protocol and interface
-constraints.
-
-Note that just like in the device version, there are six methods:
-
-@verbatim
-  void EnablePcapIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface, bool explicitFilename = false);
-  void EnablePcapIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface, bool explicitFilename = false);
-  void EnablePcapIpv4 (std::string prefix, Ipv4InterfaceContainer c);
-  void EnablePcapIpv4 (std::string prefix, NodeContainer n);
-  void EnablePcapIpv4 (std::string prefix, uint32_t nodeid, uint32_t interface, bool explicitFilename);
-  void EnablePcapIpv4All (std::string prefix);
-@end verbatim
-
-You are encouraged to peruse the Doxygen for class @code{PcapHelperForIpv4}
-to find the details of these methods; but to summarize ...
-
-You can enable pcap tracing on a particular protocol/interface pair by providing a
-@code{Ptr<Ipv4>} and @code{interface} to an @code{EnablePcap} method.  For example, 
-
-@verbatim
-  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
-  ...
-  helper.EnablePcapIpv4 ("prefix", ipv4, 0);
-@end verbatim
-
-You can enable pcap tracing on a particular node/net-device pair by providing a
-@code{std::string} representing an object name service string to an 
-@code{EnablePcap} method.  The @code{Ptr<Ipv4>} is looked up from the name
-string.  For example, 
-
-@verbatim
-  Names::Add ("serverIPv4" ...);
-  ...
-  helper.EnablePcapIpv4 ("prefix", "serverIpv4", 1);
-@end verbatim
-
-You can enable pcap tracing on a collection of protocol/interface pairs by 
-providing an @code{Ipv4InterfaceContainer}.  For each @code{Ipv4} / interface
-pair in the container the protocol type is checked.  For each protocol of the 
-proper type (the same type as is managed by the device helper), tracing is 
-enabled for the corresponding interface.  For example, 
-
-@verbatim
-  NodeContainer nodes;
-  ...
-  NetDeviceContainer devices = deviceHelper.Install (nodes);
-  ... 
-  Ipv4AddressHelper ipv4;
-  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
-  Ipv4InterfaceContainer interfaces = ipv4.Assign (devices);
-  ...
-  helper.EnablePcapIpv4 ("prefix", interfaces);
-@end verbatim
-
-You can enable pcap tracing on a collection of protocol/interface pairs by 
-providing a @code{NodeContainer}.  For each @code{Node} in the @code{NodeContainer}
-the appropriate protocol is found.  For each protocol, its interfaces are 
-enumerated and tracing is enabled on the resulting pairs.  For example,
-
-@verbatim
-  NodeContainer n;
-  ...
-  helper.EnablePcapIpv4 ("prefix", n);
-@end verbatim
-
-You can enable pcap tracing on the basis of node ID and interface as well.  In
-this case, the node-id is translated to a @code{Ptr<Node>} and the appropriate
-protocol is looked up in the node.  The resulting protocol and interface are
-used to specify the resulting trace source.
-
-@verbatim
-  helper.EnablePcapIpv4 ("prefix", 21, 1);
-@end verbatim
-
-Finally, you can enable pcap tracing for all interfaces in the system, with
-associated protocol being the same type as that managed by the device helper.
-
-@verbatim
-  helper.EnablePcapIpv4All ("prefix");
-@end verbatim
-
-@subsubsection Pcap Tracing Protocol Helper Filename Selection
-
-Implicit in all of the method descriptions above is the construction of the
-complete filenames by the implementation method.  By convention, pcap traces
-taken for devices in the @code{ns-3} system are of the form 
-``<prefix>-<node id>-<device id>.pcap''.  In the case of protocol traces,
-there is a one-to-one correspondence between protocols and @code{Nodes}.
-This is because protocol @code{Objects} are aggregated to @code{Node Objects}.
-Since there is no global protocol id in the system, we use the corresponding
-node id in file naming.  Therefore there is a possibility for file name 
-collisions in automatically chosen trace file names.  For this reason, the
-file name convention is changed for protocol traces.
-
-As previously mentioned, every node in the system will have a system-assigned
-node id.  Since there is a one-to-one correspondence between protocol instances
-and node instances we use the node id.  Each interface has an interface id 
-relative to its protocol.  We use the convention 
-"<prefix>-n<node id>-i<interface id>.pcap" for trace file naming in protocol
-helpers.
-
-Therefore, by default, a pcap trace file created as a result of enabling tracing
-on interface 1 of the Ipv4 protocol of node 21 using the prefix ``prefix''
-would be ``prefix-n21-i1.pcap''.
-
-You can always use the @code{ns-3} object name service to make this more clear.
-For example, if you use the object name service to assign the name ``serverIpv4''
-to the Ptr<Ipv4> on node 21, the resulting pcap trace file name will 
-automatically become, ``prefix-nserverIpv4-i1.pcap''.
-
-Several of the methods have a default parameter called @code{explicitFilename}.
-When set to true, this parameter disables the automatic filename completion 
-mechanism and allows you to create an explicit filename.  This option is only
-available in the methods which take a prefix and enable tracing on a single device.  
-
-@subsection Ascii Tracing Protocol Helpers
-
-The behavior of the ascii trace helpers is substantially similar to the pcap
-case.  Take a look at @code{src/helper/trace-helper.h} if you want to 
-follow the discussion while looking at real code.
-
-In this section we will be illustrating the methods as applied to the protocol
-@code{Ipv4}.  To specify traces in similar protocols, just substitute the
-appropriate type.  For example, use a @code{Ptr<Ipv6>} instead of a
-@code{Ptr<Ipv4>} and call @code{EnableAsciiIpv6} instead of @code{EnableAsciiIpv4}.
-
-The class @code{AsciiTraceHelperForIpv4} adds the high level functionality
-for using ascii tracing to a protocol helper.  Each protocol that enables these
-methods must implement a single virtual method inherited from this class.
-
-@verbatim
-  virtual void EnableAsciiIpv4Internal (Ptr<OutputStreamWrapper> stream, 
-                                        std::string prefix, 
-                                        Ptr<Ipv4> ipv4, 
-                                        uint32_t interface,
-                                        bool explicitFilename) = 0;
-@end verbatim
-
-The signature of this method reflects the protocol- and interface-centric view 
-of the situation at this level; and also the fact that the helper may be writing
-to a shared output stream.  All of the public methods inherited from class 
-@code{PcapAndAsciiTraceHelperForIpv4} reduce to calling this single device-
-dependent implementation method.  For example, the lowest level ascii trace
-methods,
-
-@verbatim
-  void EnableAsciiIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface, bool explicitFilename = false);
-  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, Ptr<Ipv4> ipv4, uint32_t interface);
-@verbatim
-
-will call the device implementation of @code{EnableAsciiIpv4Internal} directly,
-providing either the prefix or the stream.  All other public ascii tracing 
-methods will build on these low-level functions to provide additional user-level
-functionality.  What this means to the user is that all device helpers in the 
-system will have all of the ascii trace methods available; and these methods
-will all work in the same way across protocols if the protocols implement 
-@code{EnablAsciiIpv4Internal} correctly.
-
-@subsubsection Ascii Tracing Protocol Helper Methods
-
-@verbatim
-  void EnableAsciiIpv4 (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface, bool explicitFilename = false);
-  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, Ptr<Ipv4> ipv4, uint32_t interface);
-
-  void EnableAsciiIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface, bool explicitFilename = false);
-  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, std::string ipv4Name, uint32_t interface);
-
-  void EnableAsciiIpv4 (std::string prefix, Ipv4InterfaceContainer c);
-  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, Ipv4InterfaceContainer c);
-
-  void EnableAsciiIpv4 (std::string prefix, NodeContainer n);
-  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, NodeContainer n);
-
-  void EnableAsciiIpv4All (std::string prefix);
-  void EnableAsciiIpv4All (Ptr<OutputStreamWrapper> stream);
-
-  void EnableAsciiIpv4 (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool explicitFilename);
-  void EnableAsciiIpv4 (Ptr<OutputStreamWrapper> stream, uint32_t nodeid, uint32_t interface);
-@end verbatim
-
-You are encouraged to peruse the Doxygen for class @code{PcapAndAsciiHelperForIpv4}
-to find the details of these methods; but to summarize ...
-
-There are twice as many methods available for ascii tracing as there were for
-pcap tracing.  This is because, in addition to the pcap-style model where traces
-from each unique protocol/interface pair are written to a unique file, we 
-support a model in which trace information for many protocol/interface pairs is 
-written to a common file.  This means that the <prefix>-n<node id>-<interface>
-file name generation mechanism is replaced by a mechanism to refer to a common 
-file; and the number of API methods is doubled to allow all combinations.
-
-Just as in pcap tracing, you can enable ascii tracing on a particular 
-protocol/interface pair by providing a @code{Ptr<Ipv4>} and an @code{interface}
-to an @code{EnableAscii} method.
-For example, 
-
-@verbatim
-  Ptr<Ipv4> ipv4;
-  ...
-  helper.EnableAsciiIpv4 ("prefix", ipv4, 1);
-@end verbatim
-
-In this case, no trace contexts are written to the ascii trace file since they
-would be redundant.  The system will pick the file name to be created using
-the same rules as described in the pcap section, except that the file will
-have the suffix ``.tr'' instead of ``.pcap''.
-
-If you want to enable ascii tracing on more than one interface and have all 
-traces sent to a single file, you can do that as well by using an object to
-refer to a single file.  We have already something similar to this in the
-``cwnd'' example above:
-
-@verbatim
-  Ptr<Ipv4> protocol1 = node1->GetObject<Ipv4> ();
-  Ptr<Ipv4> protocol2 = node2->GetObject<Ipv4> ();
-  ...
-  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
-  ...
-  helper.EnableAsciiIpv4 (stream, protocol1, 1);
-  helper.EnableAsciiIpv4 (stream, protocol2, 1);
-@verbatim
-
-In this case, trace contexts are written to the ascii trace file since they
-are required to disambiguate traces from the two interfaces.  Note that since 
-the user is completely specifying the file name, the string should include the
-``,tr'' for consistency.
-
-You can enable ascii tracing on a particular protocol by providing a 
-@code{std::string} representing an object name service string to an 
-@code{EnablePcap} method.  The @code{Ptr<Ipv4>} is looked up from the name
-string.  The @code<Node> in the resulting filenames is implicit since there
-is a one-to-one correspondence between protocol instances and nodes,
-For example, 
-
-@verbatim
-  Names::Add ("node1Ipv4" ...);
-  Names::Add ("node2Ipv4" ...);
-  ...
-  helper.EnableAsciiIpv4 ("prefix", "node1Ipv4", 1);
-  helper.EnableAsciiIpv4 ("prefix", "node2Ipv4", 1);
-@end verbatim
-
-This would result in two files named ``prefix-nnode1Ipv4-i1.tr'' and 
-``prefix-nnode2Ipv4-i1.tr'' with traces for each interface in the respective 
-trace file.  Since all of the EnableAscii functions are overloaded to take a 
-stream wrapper, you can use that form as well:
-
-@verbatim
-  Names::Add ("node1Ipv4" ...);
-  Names::Add ("node2Ipv4" ...);
-  ...
-  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
-  ...
-  helper.EnableAsciiIpv4 (stream, "node1Ipv4", 1);
-  helper.EnableAsciiIpv4 (stream, "node2Ipv4", 1);
-@end verbatim
-
-This would result in a single trace file called ``trace-file-name.tr'' that 
-contains all of the trace events for both interfaces.  The events would be 
-disambiguated by trace context strings.
-
-You can enable ascii tracing on a collection of protocol/interface pairs by 
-providing an @code{Ipv4InterfaceContainer}.  For each protocol of the proper 
-type (the same type as is managed by the device helper), tracing is enabled
-for the corresponding interface.  Again, the @code<Node> is implicit since 
-there is a one-to-one correspondence between each protocol and its node.
-For example, 
-
-@verbatim
-  NodeContainer nodes;
-  ...
-  NetDeviceContainer devices = deviceHelper.Install (nodes);
-  ... 
-  Ipv4AddressHelper ipv4;
-  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
-  Ipv4InterfaceContainer interfaces = ipv4.Assign (devices);
-  ...
-  ...
-  helper.EnableAsciiIpv4 ("prefix", interfaces);
-@end verbatim
-
-This would result in a number of ascii trace files being created, each of which
-follows the <prefix>-n<node id>-i<interface>.tr convention.  Combining all of the
-traces into a single file is accomplished similarly to the examples above:
-
-@verbatim
-  NodeContainer nodes;
-  ...
-  NetDeviceContainer devices = deviceHelper.Install (nodes);
-  ... 
-  Ipv4AddressHelper ipv4;
-  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
-  Ipv4InterfaceContainer interfaces = ipv4.Assign (devices);
-  ...
-  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
-  ...
-  helper.EnableAsciiIpv4 (stream, interfaces);
-@end verbatim
-
-You can enable ascii tracing on a collection of protocol/interface pairs by 
-providing a @code{NodeContainer}.  For each @code{Node} in the @code{NodeContainer}
-the appropriate protocol is found.  For each protocol, its interfaces are 
-enumerated and tracing is enabled on the resulting pairs.  For example,
-
-@verbatim
-  NodeContainer n;
-  ...
-  helper.EnableAsciiIpv4 ("prefix", n);
-@end verbatim
-
-This would result in a number of ascii trace files being created, each of which
-follows the <prefix>-<node id>-<device id>.tr convention.  Combining all of the
-traces into a single file is accomplished similarly to the examples above:
-
-You can enable pcap tracing on the basis of node ID and device ID as well.  In
-this case, the node-id is translated to a @code{Ptr<Node>} and the appropriate
-protocol is looked up in the node.  The resulting protocol and interface are
-used to specify the resulting trace source.
-
-@verbatim
-  helper.EnableAsciiIpv4 ("prefix", 21, 1);
-@end verbatim
-
-Of course, the traces can be combined into a single file as shown above.
-
-Finally, you can enable ascii tracing for all interfaces in the system, with
-associated protocol being the same type as that managed by the device helper.
-
-@verbatim
-  helper.EnableAsciiIpv4All ("prefix");
-@end verbatim
-
-This would result in a number of ascii trace files being created, one for
-every interface in the system related to a protocol of the type managed by the
-helper.  All of these files will follow the <prefix>-n<node id>-i<interface.tr
-convention.  Combining all of the traces into a single file is accomplished 
-similarly to the examples above.
-
-@subsubsection Ascii Tracing Protocol Helper Filename Selection
-
-Implicit in the prefix-style method descriptions above is the construction of the
-complete filenames by the implementation method.  By convention, ascii traces
-in the @code{ns-3} system are of the form ``<prefix>-<node id>-<device id>.tr''
-
-As previously mentioned, every node in the system will have a system-assigned
-node id.  Since there is a one-to-one correspondence between protocols and nodes
-we use to node-id to identify the protocol identity.  Every interface on a 
-given protocol will have an interface index (also called simply an interface) 
-relative to its protocol.  By default, then, an ascii trace file created as a result
-of enabling tracing on the first device of node 21, using the prefix ``prefix'',
-would be ``prefix-n21-i1.tr''.  Use the prefix to disambiguate multiple protocols
-per node.
-
-You can always use the @code{ns-3} object name service to make this more clear.
-For example, if you use the object name service to assign the name ``serverIpv4''
-to the protocol on node 21, and also specify interface one, the resulting ascii 
-trace file name will automatically become, ``prefix-nserverIpv4-1.tr''.
-
-Several of the methods have a default parameter called @code{explicitFilename}.
-When set to true, this parameter disables the automatic filename completion 
-mechanism and allows you to create an explicit filename.  This option is only
-available in the methods which take a prefix and enable tracing on a single device.  
-
-@c ============================================================================
-@c Summary
-@c ============================================================================
-@node Summary
-@section Summary
-
-@code{ns-3} includes an extremely rich environment allowing users at several 
-levels to customize the kinds of information that can be extracted from 
-simulations.  
-
-There are high-level helper functions that allow users to simply control the 
-collection of pre-defined outputs to a fine granularity.  There are mid-level
-helper functions to allow more sophisticated users to customize how information
-is extracted and saved; and there are low-level core functions to allow expert
-users to alter the system to present new and previously unexported information
-in a way that will be immediately accessible to users at higher levels.
-
-This is a very comprehensive system, and we realize that it is a lot to 
-digest, especially for new users or those not intimately familiar with C++
-and its idioms.  We do consider the tracing system a very important part of
-@code{ns-3} and so recommend becoming as familiar as possible with it.  It is
-probably the case that understanding the rest of the @code{ns-3} system will
-be quite simple once you have mastered the tracing system