branch merge
authorTom Henderson <tomh@tomh.org>
Tue, 22 Apr 2008 21:19:39 -0700
changeset 2997 caf9d364c6fc
parent 2996 a83b94e277d4 (current diff)
parent 2994 de48c60ad186 (diff)
child 2998 b991704f870f
branch merge
doc/tracing.h
examples/csma-broadcast.cc
examples/csma-multicast.cc
examples/csma-one-subnet.cc
examples/mixed-global-routing.cc
examples/mixed-wireless.cc
examples/simple-alternate-routing.cc
examples/simple-error-model.cc
examples/simple-global-routing.cc
examples/simple-point-to-point-olsr.cc
examples/tcp-large-transfer.cc
examples/udp-echo.cc
examples/wifi-adhoc.cc
examples/wifi-ap.cc
samples/main-grid-topology.cc
samples/main-random-topology.cc
samples/main-random-walk.cc
src/devices/wifi/wifi-trace.cc
src/devices/wifi/wifi-trace.h
src/helper/csma-helper.cc
src/helper/csma-helper.h
src/helper/mobility-helper.cc
src/helper/mobility-helper.h
src/helper/olsr-helper.cc
src/helper/olsr-helper.h
src/helper/point-to-point-helper.cc
src/helper/point-to-point-helper.h
src/helper/wifi-helper.cc
src/helper/wifi-helper.h
src/simulator/scheduler-heap.cc
src/simulator/scheduler-heap.h
src/simulator/scheduler-list.cc
src/simulator/scheduler-list.h
src/simulator/scheduler-map.cc
src/simulator/scheduler-map.h
tutorial/tutorial-bus-network.cc
tutorial/tutorial-csma-echo-ascii-trace.cc
tutorial/tutorial-csma-echo-pcap-trace.cc
tutorial/tutorial-linear-dumbbell.cc
tutorial/tutorial-point-to-point.cc
tutorial/tutorial-star-routing.cc
tutorial/tutorial-star.cc
--- a/doc/doxygen.conf	Tue Apr 22 21:18:04 2008 -0700
+++ b/doc/doxygen.conf	Tue Apr 22 21:19:39 2008 -0700
@@ -496,7 +496,6 @@
 INPUT                  = doc/modules \
                          doc/main.h \
                          doc/introspected-doxygen.h \
-                         doc/tracing.h \ 
                          doc/howtos/ \ 
                          src
 
@@ -1047,13 +1046,13 @@
 # compilation will be performed. Macro expansion can be done in a controlled 
 # way by setting EXPAND_ONLY_PREDEF to YES.
 
-MACRO_EXPANSION        = NO
+MACRO_EXPANSION        = YES
 
 # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
 # then the macro expansion is limited to the macros specified with the 
 # PREDEFINED and EXPAND_AS_DEFINED tags.
 
-EXPAND_ONLY_PREDEF     = NO
+EXPAND_ONLY_PREDEF     = YES
 
 # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
 # in the INCLUDE_PATH (see below) will be search if a #include is found.
@@ -1090,7 +1089,9 @@
 # The macro definition that is found in the sources will be used. 
 # Use the PREDEFINED tag if you want to use a different macro definition.
 
-EXPAND_AS_DEFINED      = 
+EXPAND_AS_DEFINED      = ATTRIBUTE_VALUE_DEFINE \
+		       ATTRIBUTE_VALUE_DEFINE_WITH_NAME \
+		       ATTRIBUTE_HELPER_HEADER_2
 
 # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
 # doxygen's preprocessor will remove all function-like macros that are alone 
--- a/doc/modules	Tue Apr 22 21:18:04 2008 -0700
+++ b/doc/modules	Tue Apr 22 21:19:39 2008 -0700
@@ -15,12 +15,13 @@
  *    - a class to register regression tests with the test manager: ns3::Test and ns3::TestManager
  *    - debugging facilities: \ref logging, \ref assert, \ref error
  *    - \ref randomvariable
+ *    - a base class for objects which need to support per-instance "attributes" and
+ *      trace sources: ns3::ObjectBase
  *    - a base class for objects which need to support reference counting
- *      and QueryInterface: ns3::Object and ns3::InterfaceId 
- *    - a set of low-level trace facilities integrated in the ns3::Object system: \ref tracing
- *    - a ns3::ComponentManager which can be used to manage the creation
- *      of any object which derives from ns3::Object through an ns3::ClassId 
+ *      and dynamic object aggregation: ns3::Object
  *    - a smart-pointer class ns3::Ptr designed to work together with ns3::Object
+ *    - a configuration class used to set and control all attributes and trace sources
+ *      in a simulation: ns3::Config.
  *
  * @defgroup common Common
  * The "core" module contains: 
@@ -61,5 +62,4 @@
  * @brief Constants you can change
  *
  * @defgroup contrib Contrib
- */
-
+ */
\ No newline at end of file
--- a/doc/tracing.h	Tue Apr 22 21:18:04 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,584 +0,0 @@
-/**
- * \ingroup core
- * \defgroup TraceSourceList List of trace sources
- */
-
-/**
- * \ingroup core
- * \defgroup tracing Tracing
- *
- * The flexibility of the ns-3 tracing system comes at the cost of quite
- * a bit of complexity so, before trying to use the low-level aspects
- * of the tracing API, it is important to focus on some basic definitions:
- *
- * - A trace source is an object instance which can report trace events
- *   to a set of listening trace sinks.
- *
- * - A trace sink is a user-provided callback (a function) which can
- *   be connected to a set of trace sources to receive the events generated
- *   by each trace source.
- *
- * - A trace resolver is an object which allows users to establish 
- *   connections between a set of trace sources and a set of trace sinks.
- *
- * \section TraceSource Generating Trace Events
- *
- * So, what does it look like in practice ? First, let's look at trace
- * sources. We have two types of trace sources: numeric, and, normal 
- * trace sources. Numeric trace sources behave as normal c++ integers 
- * or c++ floating point numbers except that they report as trace events 
- * each change of their value. For example:
- * \code
- * class MyModel 
- * {
- * public:
- *   void DoSomething (void) 
- *   {
- *     // use the "int" trace source just 
- *     // like any other "int" variable.
- *     m_cwnd *= 2;
- *     m_cwnd += 4;
- *     if (m_cwnd > 100)
- *       {
- *         // do something.
- *       }
- *   }
- * private:
- *   // declare an instance of a "int" trace source
- *   SVTraceSource<int> m_cwnd;
- * };
- * \endcode
- * Normal trace sources, on the other hand, allow you to trace the
- * call of arbitrary functions and methods, as shown below. They are
- * typically used to track "rx", "tx", or "drop" events but could
- * also be used to track route change events, or position change
- * events:
- * \code
- * class MyModel 
- * {
- * public:
- *   void DoSomething (Ptr<Packet> packet) 
- *   {
- *     // report this event on packet
- *     m_doSomething (packet);
- *     // do something
- *   }
- * private:
- *   // report every "something" function call.
- *   CallbackTraceSource<Ptr<Packet> > m_doSomething;
- * };
- * \endcode
- * Every type of trace source derives from the ns3::TraceSource base class.
- * As of today, the set of concrete subclasses is relatively short:
- * ns3::CallbackTraceSource, ns3::SvTraceSource, ns3::UvTraceSource, and,
- * ns3::FvTraceSource.
- *
- * \section TraceSink Receiving Trace Events
- *
- * To receive these trace events, a user should specify a set of trace sinks.
- * For example, to receive the "int" and the "something" events shown in the
- * examples above, a user would declare the following functions:
- * \code
- * // oldValue and newValue contain the previous and new values of 
- * // the connected SVTraceSource<int> trace source.
- * void 
- * CwndTraceSink (const TraceContext &context, int64_t oldValue, int64_t newValue)
- * {
- *   // for example, print the new value:
- *   std::cout << "cwnd=" << newValue << std::endl;
- * }
- * void 
- * DoSomethingTraceSink (const TraceContext &context, Ptr<Packet> packet)
- * {
- *   // for example, print the packet
- *   std::cout << "packet " << packet->Print () << std::endl;
- * }
- * \endcode
- * Each of these sink function takes, as a first argument, a reference to a 
- * const TraceContext object. This context object contains information which
- * describes the instance of the connected trace source: that information is
- * setup during the connection process and does not change afterwards
- * The type and the number of the other arguments to each trace sink depends
- * on the type of the connected trace source: it conveys per-event information
- * from the trace source to the trace sink. For example, UVTraceSource and 
- * SVTraceSource trace sources require two extra arguments. The former requires
- * two unsigned 64 bit integers while the latter requires two signed 64 bit 
- * integers. More generally, users can consult the \ref TraceSourceList
- * to figure out the arguments which a trace sink is required to receive
- * for each trace source: a signature of the user trace sink must match 
- * _exactly_ the signature documented in the \ref TraceSourceList.
- *
- *
- * \section TraceSourceSimpleExport A simple way to connect Trace Sources with Trace Sinks
- *
- * The crux of the complexity of the ns-3 tracing system comes from its 
- * flexible system used to connect trace sources to trace sinks but what is really
- * nice about it is that it is not necessary to use it to setup simple traces.
- * 
- * The simplest way to export a set of trace sources to a user, for example, 
- * during the early prototyping phases of a system, is to add a set of public methods
- * to give to your users access to the trace source object instances you use to generate
- * trace events:
- * \code
- * class MyModel 
- * {
- * public:
- *   void DoSomething (Ptr<Packet> packet) 
- *   {
- *     // report this event on packet
- *     m_doSomething (packet);
- *     // do something
- *   }
- *   CallbackTraceSource<Ptr<Packet>> *PeekSomethingTraceSource (void) const 
- *   {
- *     return &m_doSomething
- *   }
- * private:
- *   // report every "something" function call.
- *   CallbackTraceSource<Ptr<Packet>> m_doSomething;
- * };
- * \endcode
- * If your users hold a pointer to an instance of MyModel, and if they want to connect
- * a MySomethingSink, they can simply do the following which invokes the 
- * TraceSource::AddCallback method and creates a Callback object from the user's
- * sink with the MakeCallback function.
- * \code
- * void 
- * MySomethingSink (const TraceContext &context, Ptr<Packet> packet)
- * {
- *   // do whatever you want.
- * }
- * MyModel *model = ...;
- * CallbackTraceSource<Ptr<Packet>> *source = model->PeekSomethingTraceSource ();
- * source->AddCallback (MakeCallback (&MySomethingSink));
- * \endcode
- *
- * The full power of the tracing system comes however from its ns3::NodeList::Connect
- * method which is described in the following sections.
- *
- * \section TraceConnection Connecting Trace Sources to Trace Sinks
- * 
- * If a trace source is integrated in the ns-3 trace connection facility, a user 
- * should call the ns3::NodeList::ConnectWithoutContext method to establish a connection between
- * a trace sink and a set of matching trace sources. The second argument to that
- * method is a callback to the user's trace sink.
- * That callback is easy to construct: call ns3::MakeCallback and you are done. The
- * first argument is a string whose format is similar to a unix path and which is 
- * used to uniquely identify the set of trace sources you want to connect to.
- * The set of acceptable path strings is also documented in the \ref TraceSourceList.
- *
- * So, what does this look like from the perspective of a user ? If we wanted to 
- * connect to a trace source defined somewhere deep into the a set of NetDevice objects
- * located in some nodes of the system, we could write the following:
- * \code
- * void 
- * DoSomethingTraceSink (const TraceContext &context, Ptr<Packet> packet)
- * {
- *   // for example, print the packet
- *   std::cout << "packet: " << packet->Print () << std::endl;
- * }
- * // connect the above sink to a matching trace source
- * NodeList::ConnectWithoutContext ("/nodes/* /devices/* /rx", MakeCallback (&DoSomethingTraceSink));
- * \endcode
- *
- * The connection path string "/nodes/* /devices/* /rx" matches the "rx" trace source
- * located in every netdevice located in every node. The syntax of that path string
- * is loosely based on regular expressions so, a user could conceivably connect
- * to the trace sources present in only one node identified by node index:
- * "/nodex/3/devices/* /rx".
- *
- * The matching algorithm used here is very useful since it allows you to connect
- * at once a large set of trace sources to a single sink but it introduces another 
- * problem: it becomes impossible when you receive an event in your trace sink to
- * know from _which_ trace source the event is coming from. In our example, the
- * trace source might be coming from the NetDevice number 2 of Node 10 or Netdevice
- * number 0 of Node 5. In both cases, you might need to know which of these NetDevice
- * is generating this event, if only to generate some ascii trace dump. Another 
- * similar use-case is that you might have connected the same trace sink to
- * multiple types of events which have the same signature: it is quite common
- * to receive all tx, rx, and drop events in the same trace sink and that would be
- * quite trivial to achieve with a string such as: "/nodes/* /devices/* /*"
- *
- * The source of a trace event can be retrieved from a trace sink using 
- * different means: the simplest
- * way to get this information is to use the builtin printing facility of
- * the TraceContext object:
- * \code
- * void 
- * DoSomethingTraceSink (const TraceContext &context, Ptr<Packet> packet)
- * {
- *   // for example, print the packet
- *   std::cout << "context=\"" << context << "\" packet: " << packet->Print () << std::endl;
- * }
- * \endcode
- * The above code is going to generate output which looks like the following:
- * \code
- * context="nodeid=2 device=0 dev-rx" packet: IPV4(tos 0x0 ttl 64 id 0 offset ...
- * context="nodeid=1 device=0 dev-rx" packet: IPV4(tos 0x0 ttl 64 id 0 offset ...
- * ...
- * \endcode
- *
- * Another more advanced way to get information out of a TraceContext is to call its
- * ns3::TraceContext::GetElement method. This method takes as its first and only
- * argument an instance of the object we want to read and the list of available
- * object instances we can read from a TraceContext is documented, once again,
- * in the \ref TraceSourceList. For example, we could write the following to
- * generate adhoc trace output:
- * \code
- * void DeviceRxSink (const TraceContext &context, Ptr<const Packet> packet)
- * {
- *   NodeListIndex nodeIndex;
- *   NodeNetDeviceIndex deviceIndex;
- *   context.GetElement (nodeIndex);
- *   context.GetElement (deviceIndex);
- *   std::cout << "node-index=" << nodeIndex.Get ();
- *   std::cout << ", device-index=" << deviceIndex.Get ();
- *   std::cout << ", packet: " << packet->Print ();
- *   std::cout << std::endl;
- * }
- * \endcode
- *
- * \section ExportingTraceSources Exporting new Trace Sources
- *
- * Using existing trace sources to connect them to a set of adhoc trace sinks
- * is not really complicated but, setting up new trace sources which can hook
- * in this automatic connection system is a bit more complicated.
- *
- * So far, we know that a model author can generate trace events really easily:
- * \code
- * class MyModel 
- * {
- * public:
- *   void DoSomething (Ptr<Packet> packet) 
- *   {
- *     // report this event on packet with value
- *     m_doSomething (packet);
- *     // do something
- *   }
- * private:
- *   // report every "something" function call.
- *   CallbackTraceSource<Ptr<Packet>> m_doSomething;
- * };
- * \endcode
- *
- * To make these new trace sources available to the rest of the connection system,
- * the first step is to make sure that your model object derives from the ns3::Object
- * base class either directly (as shown below) or indirectly through another base class:
- * \code
- * class MyModel : public Object {...};
- * // or:
- * class SomeOtherObject : public Object {...};
- * class MyModel : public SomeOtherObject {...};
- * \endcode
- *
- * This is pretty trivial and lays the ground for the second step: overriding the
- * ns3::Object::GetTraceResolver method:
- * \code
- * class MyModel : public MyParent
- * {
- * public:
- *   // declare overriden method
- *   virtual Ptr<TraceResolver> GetTraceResolver (void) const;
- * private:
- *   // the new trace source to export.
- *   CallbackTraceSource<Ptr<Packet>> m_rxSource;
- * };
- * \endcode
- *
- * To implement this method, you could attempt to implement a new subclass of
- * the ns3::TraceResolver base class and return an instance from this method but
- * this would be very hard. Instead, you should use the helper class
- * ns3::CompositeTraceResolver to register your trace sources and chain up to
- * your parent:
- * \code
- * Ptr<TraceResolver>
- * MyModel::GetTraceResolver (void) const
- * {
- *   // create an empty trace resolver
- *   Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
- *   // register m_rxSource
- *   resolver->AddSource ("rx", // the name of the trace source in the path string
- *                        TraceDoc ("some help text to explain the purpose of this trace source",
- *                                  "Packet", // the type of the first argument to the trace source
- *                                  "the purpose of the first argument",
- *                                  "type-of-second-argument", "purpose-of-second-argument"),
- *                        m_rxSource // the trace source itself is registered
- *                       );
- *   // make sure we include the trace sources implemented in the parent.
- *   resolver->SetParentResolver (MyParent::GetTraceResolver ());
- *   return resolver;
- * }
- * \endcode
- *
- * Once you have written that code, you must make sure that this new method GetTraceResolver
- * is going to be called at some point by the tracing system. If your model is located somewhere
- * deep in MAC or PHY layer, that is, it is part of a NetDevice implementation, all you
- * have to do is to make sure that your model is registered as a "composite" of your NetDevice
- * subclass:
- * \code
- * class MyNetDevice : public NetDevice
- * {
- * public:
- *   Ptr<TraceResolver> GetTraceResolver (void) const;
- * private:
- *   Ptr<MyModel> m_model;
- * };
- * 
- * Ptr<TraceResolver>
- * MyNetDevice::GetTraceResolver (void) const
- * {
- *   Ptr<CompositeTraceResolver> resolver = ...;
- *   // register other trace source
- *   ...
- *   // register now your model as a "composite"
- *   resolver->AddComposite ("my-model", m_model);
- *   // chain up to parent.
- *   resolver->SetParentResolver (NetDevice::GetTraceResolver ());
- *   return resolver;
- * }
- * \endcode
- * 
- * The code above will make your "rx" trace source appear under the
- * /nodes/xx/devices/xx/my-model/rx namespace path.
- *
- * If you have implemented a new layer 3 or 4 protocol object, the process to
- * export your trace sources is quite similar. You need to subclass from
- * ns3::Object, override the ns3::Object::GetTraceResolver method, make
- * sure you chain up to your parent's GetTraceResolver method, and, finally,
- * make sure that someone calls your new GetTraceResolver method. How to accomplish
- * the latter should be documented in the node's API documentation which describes
- * how to implement a new layer 3 or 4 protocol object.
- *
- * \section AdvancedTraceContext Creating new Trace Context Elements
- *
- * The last important feature which model developers need to understand
- * is how to provide extra context information to trace sinks. For example,
- * if your model exports both rx and tx trace sources which share the same 
- * signature, it is quite natural for a user to connect to a single trace sink
- * to both of them with a trace path string such as "/nodes/* /devices/* /(rx|tx)".
- * In this case, it becomes necessary to be able, from the trace sink function,
- * to tell which event triggered the call to the trace sink: a rx or a tx event.
- *
- * That example is detailed below with a TX, a RX, and a DROP source:
- * \code
- * class MyModel
- * {
- * private:
- *   CallbackTraceSource<Ptr<Packet>> m_rxSource;
- *   CallbackTraceSource<Ptr<Packet>> m_txSource;
- *   CallbackTraceSource<Ptr<Packet>> m_dropSource;
- * };
- * \endcode
- * When a single sink is connected to all 3 sources here, one might want
- * to write code like the following:
- * \code
- * void DeviceRxSink (const TraceContext &context, Ptr<const Packet> &packet)
- * {
- *   switch (type) {
- *     case RX:
- *       std::cout << "rx" << std::endl;
- *       break;
- *     case TX:
- *       std::cout << "tx" << std::endl;
- *       break;
- *     case DROP:
- *       std::cout << "drop" << std::endl;
- *       break;
- *   }
- * \endcode
- *
- * \subsection AdvancedTraceContextSimpleSolution The simple solution
- *
- * The simplest way to do achieve the result shown above is to include
- * in the trace source an extra explicit argument which describes the source event:
- *   - define a small enum with 3 values
- *   - change the signature of m_rxSource, m_txSource, and m_dropSource to include
- *     the enum
- *   - pass the enum value in each event
- *
- * The resulting code is shown below:
- * \code
- * class MyModel
- * {
- * public:
- *   // define the trace type enum.
- *   enum TraceType {
- *     RX,
- *     TX,
- *     DROP
- *   };
- * private:
- *   // generate events
- *   void NotifyRxPacket (Ptr<Packet> p) {
- *     m_rxSource (p, MyModel::RX);
- *   }
- *   void NotifyTxPacket (Ptr<Packet> p) {
- *     m_rxSource (p, MyModel::TX);
- *   }
- *   void NotifyDropPacket (Ptr<Packet> p) {
- *     m_rxSource (p, MyModel::DROP);
- *   }
- *   CallbackTraceSource<Ptr<Packet>,enum TraceType> m_rxSource;
- *   CallbackTraceSource<Ptr<Packet>,enum TraceType> m_txSource;
- *   CallbackTraceSource<Ptr<Packet>,enum TraceType> m_dropSource;
- * };
- * \endcode
- * These 3 new sources can be connected easily to a new trace sink:
- * \code
- * void ASimpleTraceSink (const TraceContext &context, Ptr<const Packet> packet, enum MyModel::TraceType type)
- * {
- *   // here, read the "type" argument
- * }
- * \endcode
- *
- * This solution works but it makes it impossible to connect a single trace sink to a set
- * of trace sources which represent "rx" events in different NetDevice objects since
- * each of them will define a different enum type with different values: since the
- * trace sink signature must match exactly the trace source signature, it is impossible
- * to connect at the same time to all "rx" events of different NetDevice.
- *
- * \subsection AdvancedTraceContextFancySolution The more complex and generic solution
- *
- * There is, hopefully, a way to get the best of both worlds, that is, to allow a
- * user to connect to a lot of trace source events of the same kind but coming from different
- * implementations and to allow the user to differentiate between these different
- * implementations.
- *
- * Rather than define an adhoc enum type with a list of trace sources, you can also
- * define a new ns3::TraceContextElement for your source sources. For example, if you
- * define a new MyModelTraceType class which contains the type of trace, your users can
- * then write trace sink code which looks like this:
- * \code
- * void AFancyTraceSink (const TraceContext &context, Ptr<const Packet> packet)
- * {
- *   MyModelTraceType type;
- *   if (context.GetElement (type))
- *     {
- *       switch (type.Get ())
- *         {
- *         case MyModelTraceType::RX:
- *           std::cout << "rx" << std::endl;
- *           break;
- *         case MyModelTraceType::TX:
- *           std::cout << "tx" << std::endl;
- *           break;
- *         case MyModelTraceType::DROP:
- *           std::cout << "drop" << std::endl;
- *           break;
- *         }
- *     }
- * }
- * \endcode
- *
- * Of course, since the type of trace is stored in the TraceContext, your users can
- * also take the shortcut which uses the printing functionality of the TraceContext:
- * \code
- * void ALessFancyTraceSink (const TraceContext &context, Ptr<const Packet> packet)
- * {
- *   std::cout << "context=\"" << context << "\" packet: " << packet->Print () << std::endl;
- * }
- * \endcode
- * which will generate something like the following when the trace source comes
- * from MyModel:
- * \code
- * context="my-model-rx" packet: ...
- * \endcode
- *
- * The first step to achieve this is to define and implement a new
- * subclass of the ns3::TraceContextElement base class. The exact list of
- * public methods which must be implemented is described in the API
- * documentation of the ns3::TraceContextElement class. 
- * \code
- * class MyModelTraceType : public TraceContextElement
- * {
- * public:
- *   enum Type {
- *     RX,
- *     TX,
- *     DROP
- *   };
- *   // called from MyModel::GetTraceResolver
- *   MyModelTraceType (enum Type type);
- *   // needed for by the tracing subsystem.
- *   MyModelTraceType ();
- *   // called from trace sink
- *   enum Type Get (void) const;
- *   // needed by the tracing subsystem
- *   static uint16_t GetUid (void);
- *   // needed by the tracing subsystem to
- *   // print the content of a TraceContext
- *   void Print (std::ostream &os) const;
- *   // needed by the tracing subsystem to
- *   // generate the doxygen documentation.
- *   std::string GetTypeName (void) const;
- * private:
- *   enum Type m_type;
- * };
- * \endcode
- * The implementation does not require much thinking:
- * \code
- * MyModelTraceType::MyModelTraceType ()
- *  : m_type (RX)
- * {// an arbitrary default value.
- * }
- * MyModelTraceType::MyModelTraceType (enum Type type)
- *  : m_type (type)
- * {}
- * enum MyModelTraceType::Type 
- * MyModelTraceType::Get (void) const
- * {
- *   return m_type;
- * }
- * uint16_t 
- * MyModelTraceType::GetUid (void)
- * {
- *   // use protected TraceContextElement::AllocateUid method
- *   // the input string is used to uniquely identify this new subclass
- *   static uint16_t uid = AllocateUid<MyModelTraceType> ("ns3::MyModelTraceType");
- *   return uid;
- * }
- * void 
- * MyModelTraceType::Print (std::ostream &os) const
- * {
- *   // this method is invoked by the print function of a TraceContext
- *   // if it contains an instance of this TraceContextElement.
- *   switch (m_type) {
- *     case RX: os << "rx"; break;
- *     // ...
- *   }
- * }
- * std::string 
- * MyModelTraceType::GetTypeName (void) const
- * {
- *   // This method should return a fully-qualified c++ typename
- *   // This method is used only for documentation purposes to
- *   // generate the content of the Trace Source List.
- *   return "ns3::MyModelTraceType";
- * }
- * \endcode
- *
- * Once this subclass is implemented, the work is almost completed: you
- * just need to pass an instance of that class as the last argument of 
- * the ns3::CompositeTraceResolver::AddSource method as shown below:
- * \code
- * Ptr<TraceResolver>
- * MyModel::GetTraceResolver (void) const
- * {
- *   // create an empty trace resolver
- *   Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
- *   // register m_rxSource
- *   resolver->AddSource ("rx", // the name of the trace source in the path string
- *                        TraceDoc ("some help text to explain the purpose of this trace source",
- *                                  "Packet", // the type of the first argument to the trace source
- *                                  "the purpose of the first argument",
- *                                  "type-of-second-argument", "purpose-of-second-argument"),
- *                        m_rxSource, // the trace source itself is registered
- *                        // the TraceContextElement associated to this trace source.
- *                        MyModelTraceType (MyModelTraceType::RX) 
- *                       );
- *   // make sure we include the trace sources implemented in the parent.
- *   resolver->SetParentResolver (MyParent::GetTraceResolver ());
- *   return resolver;
- * }
- * \endcode
- */
--- a/examples/csma-broadcast.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/examples/csma-broadcast.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -68,8 +68,8 @@
 
   NS_LOG_INFO ("Build Topology.");
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", DataRate(5000000));
-  csma.SetChannelParameter ("Delay", MilliSeconds(2));
+  csma.SetChannelParameter ("BitRate", DataRateValue (DataRate(5000000)));
+  csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds(2)));
 
   NetDeviceContainer n0 = csma.Install (c0);
   NetDeviceContainer n1 = csma.Install (c1);
@@ -95,8 +95,8 @@
   NS_LOG_INFO ("Create Applications.");
   OnOffHelper onoff ("ns3::Udp", 
     Address (InetSocketAddress (Ipv4Address ("255.255.255.255"), port)));
-  onoff.SetAttribute ("OnTime", ConstantVariable (1));
-  onoff.SetAttribute ("OffTime", ConstantVariable (0));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
 
   ApplicationContainer app = onoff.Install (c0.Get (0));
   // Start the application
--- a/examples/csma-multicast.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/examples/csma-multicast.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -59,7 +59,7 @@
   // Set up default values for the simulation.  
   //
   // Select Ethernet II-style encapsulation (no LLC/Snap header)
-  Config::SetDefault ("ns3::CsmaNetDevice::EncapsulationMode", String ("IpArp"));  
+  Config::SetDefault ("ns3::CsmaNetDevice::EncapsulationMode", StringValue ("IpArp"));  
 
   // Allow the user to override any of the defaults at
   // run-time, via command-line arguments
@@ -75,8 +75,8 @@
   
   NS_LOG_INFO ("Build Topology.");
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", DataRate (5000000));
-  csma.SetChannelParameter ("Delay", MilliSeconds (2));
+  csma.SetChannelParameter ("BitRate", DataRateValue (DataRate (5000000)));
+  csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2)));
  
   // We will use these NetDevice containers later, for IP addressing
   NetDeviceContainer nd0 = csma.Install (c0);  // First LAN
@@ -142,10 +142,10 @@
   // every few seconds
   OnOffHelper onoff ("ns3::Udp", 
     Address (InetSocketAddress (multicastGroup, multicastPort)));
-  onoff.SetAttribute ("OnTime", ConstantVariable (1));
-  onoff.SetAttribute ("OffTime", ConstantVariable (0));
-  onoff.SetAttribute ("DataRate", DataRate ("255b/s"));
-  onoff.SetAttribute ("PacketSize", Uinteger (128));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+  onoff.SetAttribute ("DataRate", DataRateValue (DataRate ("255b/s")));
+  onoff.SetAttribute ("PacketSize", UintegerValue (128));
 
   ApplicationContainer srcC = onoff.Install (c0.Get (0));
 
@@ -157,7 +157,7 @@
 
   // Create an optional packet sink to receive these packets
   PacketSinkHelper sink ("ns3::Udp",
-    Address (InetSocketAddress (Ipv4Address::GetAny(), multicastPort)));
+                         InetSocketAddress (Ipv4Address::GetAny(), multicastPort));
 
   ApplicationContainer sinkC = sink.Install (c1.Get (2)); // Node n4 
   // Start the sink
--- a/examples/csma-one-subnet.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/examples/csma-one-subnet.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -66,8 +66,8 @@
 
   NS_LOG_INFO ("Build Topology");
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", DataRate (5000000));
-  csma.SetChannelParameter ("Delay", MilliSeconds (2));
+  csma.SetChannelParameter ("BitRate", DataRateValue (5000000));
+  csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2)));
 //
 // Now fill out the topology by creating the net devices required to connect
 // the nodes to the channels and hooking them up.  AddIpv4CsmaNetDevice will
@@ -97,8 +97,8 @@
 
   OnOffHelper onoff ("ns3::Udp", 
     Address (InetSocketAddress (Ipv4Address ("10.1.1.2"), port)));
-  onoff.SetAttribute ("OnTime", ConstantVariable (1));
-  onoff.SetAttribute ("OffTime", ConstantVariable (0));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
 
   ApplicationContainer app = onoff.Install (c.Get (0));
   // Start the application
@@ -114,7 +114,7 @@
 // Create a similar flow from n3 to n0, starting at time 1.1 seconds
 //
   onoff.SetAttribute ("Remote", 
-    Address (InetSocketAddress (Ipv4Address ("10.1.1.1"), port)));
+                      AddressValue (InetSocketAddress (Ipv4Address ("10.1.1.1"), port)));
   ApplicationContainer app2 = onoff.Install (c.Get (3));
 
   sink.Install (c.Get (0));
--- a/examples/csma-packet-socket.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/examples/csma-packet-socket.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -70,13 +70,13 @@
 
   // create the shared medium used by all csma devices.
   NS_LOG_INFO ("Create channels.");
-  Ptr<CsmaChannel> channel = CreateObject<CsmaChannel> ("BitRate", DataRate(5000000), 
-                                                        "Delay", MilliSeconds(2));
+  Ptr<CsmaChannel> channel = CreateObject<CsmaChannel> ("BitRate", DataRateValue (DataRate(5000000)), 
+                                                        "Delay", TimeValue (MilliSeconds(2)));
 
   // use a helper function to connect our nodes to the shared channel.
   NS_LOG_INFO ("Build Topology.");
   CsmaHelper csma;
-  csma.SetDeviceParameter ("EncapsulationMode", String ("Llc"));
+  csma.SetDeviceParameter ("EncapsulationMode", StringValue ("Llc"));
   NetDeviceContainer devs = csma.Install (c, channel);
 
   NS_LOG_INFO ("Create Applications.");
@@ -86,8 +86,8 @@
   socket.SetPhysicalAddress (devs.Get (1)->GetAddress ());
   socket.SetProtocol (2);
   OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket));
-  onoff.SetAttribute ("OnTime", ConstantVariable (1.0));
-  onoff.SetAttribute ("OffTime", ConstantVariable (0.0));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1.0)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0)));
 
   ApplicationContainer apps = onoff.Install (c.Get (0));
   apps.Start (Seconds (1.0));
@@ -96,8 +96,8 @@
   socket.SetSingleDevice (devs.Get (3)->GetIfIndex ());
   socket.SetPhysicalAddress (devs.Get (0)->GetAddress ());
   socket.SetProtocol (3);
-  onoff.SetAttribute ("Remote", Address (socket));
-  onoff.SetAttribute ("OffTime", ConstantVariable (0.0));
+  onoff.SetAttribute ("Remote", AddressValue (socket));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0)));
   apps = onoff.Install (c.Get (3));
   apps.Start (Seconds (1.0));
   apps.Stop (Seconds (10.0));
--- a/examples/mixed-global-routing.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/examples/mixed-global-routing.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -51,8 +51,8 @@
 int 
 main (int argc, char *argv[])
 {
-  Config::SetDefault ("ns3::OnOffApplication::PacketSize", Uinteger (210));
-  Config::SetDefault ("ns3::OnOffApplication::DataRate", DataRate ("448kb/s"));
+  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
+  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s"));
 
   // Allow the user to override any of the defaults and the above
   // Bind ()s at run-time, via command-line arguments
@@ -73,20 +73,20 @@
   // We create the channels first without any IP addressing information
   NS_LOG_INFO ("Create channels.");
   PointToPointHelper p2p;
-  p2p.SetChannelParameter ("BitRate", DataRate (5000000));
-  p2p.SetChannelParameter ("Delay", MilliSeconds (2));
+  p2p.SetChannelParameter ("BitRate", StringValue ("5Mbps"));
+  p2p.SetChannelParameter ("Delay", StringValue ("2ms"));
   NetDeviceContainer d0d2 = p2p.Install (n0n2);
 
   NetDeviceContainer d1d2 = p2p.Install (n1n2);
 
-  p2p.SetChannelParameter ("BitRate", DataRate (1500000));
-  p2p.SetChannelParameter ("Delay", MilliSeconds (10));
+  p2p.SetChannelParameter ("BitRate", StringValue ("1500kbps"));
+  p2p.SetChannelParameter ("Delay", StringValue ("10ms"));
   NetDeviceContainer d5d6 = p2p.Install (n5n6);
 
   // We create the channels first without any IP addressing information
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", DataRate (5000000));
-  csma.SetChannelParameter ("Delay", MilliSeconds (2));
+  csma.SetChannelParameter ("BitRate", StringValue ("5Mbps"));
+  csma.SetChannelParameter ("Delay", StringValue ("2ms"));
   NetDeviceContainer d2345 = csma.Install (n2345);
   
   // Later, we add IP addresses.  
@@ -113,11 +113,11 @@
   NS_LOG_INFO ("Create Applications.");
   uint16_t port = 9;   // Discard port (RFC 863)
   OnOffHelper onoff ("ns3::Udp",
-    Address (InetSocketAddress (i5i6.GetAddress (1), port)));
-  onoff.SetAttribute ("OnTime", ConstantVariable (1));
-  onoff.SetAttribute ("OffTime", ConstantVariable (0));
-  onoff.SetAttribute ("DataRate", DataRate("300bps"));
-  onoff.SetAttribute ("PacketSize", Uinteger (50));
+                     InetSocketAddress (i5i6.GetAddress (1), port));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+  onoff.SetAttribute ("DataRate", StringValue ("300bps"));
+  onoff.SetAttribute ("PacketSize", UintegerValue (50));
 
   ApplicationContainer apps = onoff.Install (c.Get (0));
   apps.Start (Seconds (1.0));
--- a/examples/mixed-wireless.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/examples/mixed-wireless.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -96,8 +96,8 @@
   // Simulation defaults are typically set next, before command line
   // arguments are parsed.
   //
-  Config::SetDefault ("ns3::OnOffApplication::PacketSize", String ("210"));
-  Config::SetDefault ("ns3::OnOffApplication::DataRate", String ("448kb/s"));
+  Config::SetDefault ("ns3::OnOffApplication::PacketSize", StringValue ("210"));
+  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s"));
 
   //
   // For convenience, we add the local variables to the command line argument
@@ -163,10 +163,10 @@
   positionAlloc->Add (Vector (5.0, 0.0, 0.0));
   mobility.SetPositionAllocator (positionAlloc);
   mobility.SetMobilityModel ("ns3::RandomDirection2dMobilityModel",
-                              "Bounds", Rectangle (0, 1000, 0, 1000),
-                              "Speed", ConstantVariable (2000),
-                              "Pause", ConstantVariable (0.2));
-  mobility.Install (backbone);
+                             "Bounds", RectangleValue (Rectangle (0, 1000, 0, 1000)),
+                             "Speed", RandomVariableValue (ConstantVariable (2000)),
+                             "Pause", RandomVariableValue (ConstantVariable (0.2)));
+  mobility.Layout (backbone);
 
   /////////////////////////////////////////////////////////////////////////// 
   //                                                                       //
@@ -196,8 +196,8 @@
       // collection.
       //
       CsmaHelper csma;
-      csma.SetChannelParameter ("BitRate", DataRate (5000000));
-      csma.SetChannelParameter ("Delay", MilliSeconds (2));
+      csma.SetChannelParameter ("BitRate", DataRateValue (DataRate (5000000)));
+      csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2)));
       NetDeviceContainer lanDevices = csma.Install (lan);
       //
       // Add the IPv4 protocol stack to the new LAN nodes
@@ -272,10 +272,10 @@
       mobility.PushReferenceMobilityModel (backbone.Get (i));
       mobility.SetPositionAllocator (subnetAlloc);
       mobility.SetMobilityModel ("ns3::RandomDirection2dMobilityModel",
-                                 "Bounds", Rectangle (-25, 25, -25, 25),
-                                 "Speed", ConstantVariable (30),
-                                 "Pause", ConstantVariable (0.4));
-      mobility.Install (infra);
+                                 "Bounds", RectangleValue (Rectangle (-25, 25, -25, 25)),
+                                 "Speed", RandomVariableValue (ConstantVariable (30)),
+                                 "Pause", RandomVariableValue (ConstantVariable (0.4)));
+      mobility.Layout (infra);
     }
   /////////////////////////////////////////////////////////////////////////// 
   //                                                                       //
@@ -307,8 +307,8 @@
 
   OnOffHelper onoff ("ns3::Udp", 
                      Address (InetSocketAddress (remoteAddr, port)));
-  onoff.SetAttribute ("OnTime", ConstantVariable (1));
-  onoff.SetAttribute ("OffTime", ConstantVariable (0));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
   ApplicationContainer apps = onoff.Install (appSource);
   apps.Start (Seconds (3.0));
   apps.Stop (Seconds (20.0));
--- a/examples/simple-alternate-routing.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/examples/simple-alternate-routing.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -62,8 +62,8 @@
   //
   RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
 
-  Config::SetDefault ("ns3::OnOffApplication::PacketSize", Uinteger (210));
-  Config::SetDefault ("ns3::OnOffApplication::DataRate", DataRate ("300b/s"));
+  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
+  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("300b/s"));
 
   // The below metric, if set to 3 or higher, will cause packets between
   // n1 and n3 to take the 2-hop route through n2
@@ -97,17 +97,17 @@
   // We create the channels first without any IP addressing information
   NS_LOG_INFO ("Create channels.");
   PointToPointHelper p2p;
-  p2p.SetChannelParameter ("BitRate", DataRate (5000000));
-  p2p.SetChannelParameter ("Delay", MilliSeconds (2));
+  p2p.SetChannelParameter ("BitRate", StringValue ("5Mbps"));
+  p2p.SetChannelParameter ("Delay", StringValue ("2ms"));
   NetDeviceContainer d0d2 = p2p.Install (n0n2);
 
   NetDeviceContainer d1d2 = p2p.Install (n1n2);
 
-  p2p.SetChannelParameter ("BitRate", DataRate(1500000));
-  p2p.SetChannelParameter ("Delay", MilliSeconds (10));
+  p2p.SetChannelParameter ("BitRate", StringValue ("1500kbps"));
+  p2p.SetChannelParameter ("Delay", StringValue ("10ms"));
   NetDeviceContainer d3d2 = p2p.Install (n3n2);
 
-  p2p.SetChannelParameter ("Delay", MilliSeconds (100));
+  p2p.SetChannelParameter ("Delay", StringValue ("100ms"));
   NetDeviceContainer d1d3 = p2p.Install (n1n3);
 
   InternetStackHelper internet;
@@ -143,8 +143,8 @@
   // Create a flow from n3 to n1, starting at time 1.1 seconds
   OnOffHelper onoff ("ns3::Udp",
     Address (InetSocketAddress (i1i2.GetAddress (0), port)));
-  onoff.SetAttribute ("OnTime", ConstantVariable (1));
-  onoff.SetAttribute ("OffTime", ConstantVariable (0));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
 
   ApplicationContainer apps = onoff.Install (c.Get (3));
   apps.Start (Seconds (1.1));
--- a/examples/simple-error-model.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/examples/simple-error-model.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -65,11 +65,11 @@
   RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
 
   // Set a few parameters
-  Config::SetDefault ("ns3::RateErrorModel::ErrorRate", Double (0.01));
-  Config::SetDefault ("ns3::RateErrorModel::ErrorUnit", String ("EU_PKT"));
+  Config::SetDefault ("ns3::RateErrorModel::ErrorRate", DoubleValue (0.01));
+  Config::SetDefault ("ns3::RateErrorModel::ErrorUnit", StringValue ("EU_PKT"));
   
-  Config::SetDefault ("ns3::OnOffApplication::PacketSize", Uinteger (210));
-  Config::SetDefault ("ns3::OnOffApplication::DataRate", DataRate ("448kb/s"));
+  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
+  Config::SetDefault ("ns3::OnOffApplication::DataRate", DataRateValue (DataRate ("448kb/s")));
 
 
   // Allow the user to override any of the defaults and the above
@@ -92,14 +92,14 @@
   // We create the channels first without any IP addressing information
   NS_LOG_INFO ("Create channels.");
   PointToPointHelper p2p;
-  p2p.SetChannelParameter ("BitRate", DataRate (5000000));
-  p2p.SetChannelParameter ("Delay", MilliSeconds (2));
+  p2p.SetChannelParameter ("BitRate", DataRateValue (DataRate (5000000)));
+  p2p.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2)));
   NetDeviceContainer d0d2 = p2p.Install (n0n2);
 
   NetDeviceContainer d1d2 = p2p.Install (n1n2);
 
-  p2p.SetChannelParameter ("BitRate", DataRate (1500000));
-  p2p.SetChannelParameter ("Delay", MilliSeconds (10));
+  p2p.SetChannelParameter ("BitRate", DataRateValue (DataRate (1500000)));
+  p2p.SetChannelParameter ("Delay", TimeValue (MilliSeconds (10)));
   NetDeviceContainer d3d2 = p2p.Install (n3n2);
   
   // Later, we add IP addresses.  
@@ -124,8 +124,8 @@
 
   OnOffHelper onoff ("ns3::Udp",
     Address (InetSocketAddress (i3i2.GetAddress (1), port)));
-  onoff.SetAttribute ("OnTime", ConstantVariable(1));
-  onoff.SetAttribute ("OffTime", ConstantVariable(0));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable(1)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable(0)));
 
   ApplicationContainer apps = onoff.Install (c.Get (0));
   apps.Start(Seconds(1.0));
@@ -140,14 +140,14 @@
 
   // Create a similar flow from n3 to n1, starting at time 1.1 seconds
   onoff.SetAttribute ("Remote", 
-    Address (InetSocketAddress (i1i2.GetAddress (0), port)));
+                      AddressValue (InetSocketAddress (i1i2.GetAddress (0), port)));
   apps = onoff.Install (c.Get (3));
   apps.Start(Seconds(1.1));
   apps.Stop (Seconds(10.0));
 
   // Create a packet sink to receive these packets
   sink.SetAttribute ("Local", 
-    Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
+                     AddressValue (InetSocketAddress (Ipv4Address::GetAny (), port)));
   apps = sink.Install (c.Get (1));
   apps.Start (Seconds (1.1));
   apps.Stop (Seconds (10.0));
@@ -157,9 +157,9 @@
   //
   // Create an ErrorModel based on the implementation (constructor)
   // specified by the default classId
-  Ptr<RateErrorModel> em = CreateObject<RateErrorModel> ("RanVar", UniformVariable (0.0, 1.0),
-                                                         "ErrorRate", Double (0.001));
-  d3d2.Get (0)->SetAttribute ("ReceiveErrorModel", em);
+  Ptr<RateErrorModel> em = CreateObject<RateErrorModel> ("RanVar", RandomVariableValue (UniformVariable (0.0, 1.0)),
+                                                         "ErrorRate", DoubleValue (0.001));
+  d3d2.Get (0)->SetAttribute ("ReceiveErrorModel", PointerValue (em));
 
   // Now, let's use the ListErrorModel and explicitly force a loss
   // of the packets with pkt-uids = 11 and 17 on node 2, device 0
@@ -169,7 +169,7 @@
   // This time, we'll explicitly create the error model we want
   Ptr<ListErrorModel> pem = CreateObject<ListErrorModel> ();
   pem->SetList (sampleList);
-  d0d2.Get (1)->SetAttribute ("ReceiveErrorModel", pem);
+  d0d2.Get (1)->SetAttribute ("ReceiveErrorModel", PointerValue (pem));
 
   std::ofstream ascii;
   ascii.open ("simple-error-model.tr");
--- a/examples/simple-global-routing.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/examples/simple-global-routing.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -67,8 +67,8 @@
   RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
 
   // Set up some default values for the simulation.  Use the 
-  Config::SetDefault ("ns3::OnOffApplication::PacketSize", Uinteger (210));
-  Config::SetDefault ("ns3::OnOffApplication::DataRate", DataRate ("448kb/s"));
+  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
+  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s"));
 
   //DefaultValue::Bind ("DropTailQueue::m_maxPackets", 30);   
 
@@ -92,14 +92,14 @@
   // We create the channels first without any IP addressing information
   NS_LOG_INFO ("Create channels.");
   PointToPointHelper p2p;
-  p2p.SetChannelParameter ("BitRate", DataRate (5000000));
-  p2p.SetChannelParameter ("Delay", MilliSeconds (2));
+  p2p.SetChannelParameter ("BitRate", StringValue ("5Mbps"));
+  p2p.SetChannelParameter ("Delay", StringValue ("2ms"));
   NetDeviceContainer d0d2 = p2p.Install (n0n2);
 
   NetDeviceContainer d1d2 = p2p.Install (n1n2);
   
-  p2p.SetChannelParameter ("BitRate", DataRate (1500000));
-  p2p.SetChannelParameter ("Delay", MilliSeconds (10));
+  p2p.SetChannelParameter ("BitRate", StringValue ("1500kbps"));
+  p2p.SetChannelParameter ("Delay", StringValue ("10ms"));
   NetDeviceContainer d3d2 = p2p.Install (n3n2);
   
   // Later, we add IP addresses.  
@@ -124,8 +124,8 @@
   uint16_t port = 9;   // Discard port (RFC 863)
   OnOffHelper onoff ("ns3::Udp", 
     Address (InetSocketAddress (i3i2.GetAddress (0), port)));
-  onoff.SetAttribute ("OnTime", ConstantVariable (1));
-  onoff.SetAttribute ("OffTime", ConstantVariable (0));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
   ApplicationContainer apps = onoff.Install (c.Get (0));
   apps.Start (Seconds (1.0));
   apps.Stop (Seconds (10.0));
@@ -139,7 +139,7 @@
 
   // Create a similar flow from n3 to n1, starting at time 1.1 seconds
   onoff.SetAttribute ("Remote", 
-    Address (InetSocketAddress (i1i2.GetAddress (0), port)));
+    AddressValue (InetSocketAddress (i1i2.GetAddress (0), port)));
   apps = onoff.Install (c.Get (3));
   apps.Start (Seconds (1.1));
   apps.Stop (Seconds (10.0));
--- a/examples/simple-point-to-point-olsr.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/examples/simple-point-to-point-olsr.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -67,8 +67,8 @@
 
   // Set up some default values for the simulation.  Use the 
 
-  Config::SetDefault ("ns3::OnOffApplication::PacketSize", Uinteger (210));
-  Config::SetDefault ("ns3::OnOffApplication::DataRate", DataRate ("448kb/s"));
+  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
+  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s"));
 
   //DefaultValue::Bind ("DropTailQueue::m_maxPackets", 30);   
 
@@ -93,12 +93,12 @@
   // We create the channels first without any IP addressing information
   NS_LOG_INFO ("Create channels.");
   PointToPointHelper p2p;
-  p2p.SetChannelParameter ("BitRate", DataRate (5000000));
-  p2p.SetChannelParameter ("Delay", MilliSeconds (2));
+  p2p.SetChannelParameter ("BitRate", StringValue ("5Mbps"));
+  p2p.SetChannelParameter ("Delay", StringValue ("2ms"));
   NetDeviceContainer nd02 = p2p.Install (n02);
   NetDeviceContainer nd12 = p2p.Install (n12);
-  p2p.SetChannelParameter ("BitRate", DataRate (1500000));
-  p2p.SetChannelParameter ("Delay", MilliSeconds (10));
+  p2p.SetChannelParameter ("BitRate", StringValue ("1500kbps"));
+  p2p.SetChannelParameter ("Delay", StringValue ("10ms"));
   NetDeviceContainer nd32 = p2p.Install (n32);
   NetDeviceContainer nd34 = p2p.Install (n34);
   
@@ -128,9 +128,9 @@
   uint16_t port = 9;   // Discard port (RFC 863)
 
   OnOffHelper onoff ("ns3::Udp", 
-    Address (InetSocketAddress (i34.GetAddress (1), port)));
-  onoff.SetAttribute ("OnTime", ConstantVariable (1));
-  onoff.SetAttribute ("OffTime", ConstantVariable (0));
+                     InetSocketAddress (i34.GetAddress (1), port));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
 
   ApplicationContainer apps = onoff.Install (c.Get (0));
   apps.Start (Seconds (1.0));
@@ -138,7 +138,7 @@
 
   // Create a packet sink to receive these packets
   PacketSinkHelper sink ("ns3::Udp",
-    Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
+                         InetSocketAddress (Ipv4Address::GetAny (), port));
 
   apps = sink.Install (c.Get (3));
   apps.Start (Seconds (1.0));
@@ -146,7 +146,7 @@
 
   // Create a similar flow from n3 to n1, starting at time 1.1 seconds
   onoff.SetAttribute ("Remote",
-    Address (InetSocketAddress (i12.GetAddress (0), port)));
+                      AddressValue (InetSocketAddress (i12.GetAddress (0), port)));
   apps = onoff.Install (c.Get (3));
   apps.Start (Seconds (1.1));
   apps.Stop (Seconds (10.0));
--- a/examples/tcp-large-transfer.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/examples/tcp-large-transfer.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -137,8 +137,8 @@
 
   // We create the channels first without any IP addressing information
   PointToPointHelper p2p;
-  p2p.SetChannelParameter ("BitRate", DataRate(10000000));
-  p2p.SetChannelParameter ("Delay", MilliSeconds(10));
+  p2p.SetChannelParameter ("BitRate", DataRateValue (DataRate(10000000)));
+  p2p.SetChannelParameter ("Delay", TimeValue (MilliSeconds(10)));
   NetDeviceContainer dev0 = p2p.Install (c0);
   NetDeviceContainer dev1 = p2p.Install (c1);
 
@@ -170,7 +170,7 @@
 
   // Create a packet sink to receive these packets
   PacketSinkHelper sink ("ns3::Tcp",
-    Address (InetSocketAddress (Ipv4Address::GetAny (), servPort)));
+                         InetSocketAddress (Ipv4Address::GetAny (), servPort));
 
   ApplicationContainer apps = sink.Install (c1.Get (1));
   apps.Start (Seconds (0.0));
--- a/examples/udp-echo.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/examples/udp-echo.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -87,8 +87,8 @@
 // Explicitly create the channels required by the topology (shown above).
 //
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", DataRate(5000000));
-  csma.SetChannelParameter ("Delay", MilliSeconds (2));
+  csma.SetChannelParameter ("BitRate", DataRateValue (DataRate(5000000)));
+  csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2)));
   NetDeviceContainer d = csma.Install (n);
 
   Ipv4AddressHelper ipv4;
@@ -119,9 +119,9 @@
   Time interPacketInterval = Seconds (1.);
   UdpEchoClientHelper client;
   client.SetRemote (i.GetAddress (1), port);
-  client.SetAppAttribute ("MaxPackets", Uinteger (maxPacketCount));
-  client.SetAppAttribute ("Interval", interPacketInterval);
-  client.SetAppAttribute ("PacketSize", Uinteger (packetSize));
+  client.SetAppAttribute ("MaxPackets", UintegerValue (maxPacketCount));
+  client.SetAppAttribute ("Interval", TimeValue (interPacketInterval));
+  client.SetAppAttribute ("PacketSize", UintegerValue (packetSize));
   apps = client.Install (n.Get (0));
   apps.Start (Seconds (2.0));
   apps.Stop (Seconds (10.0));
--- a/examples/wifi-adhoc.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/examples/wifi-adhoc.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -134,10 +134,10 @@
   socket.SetProtocol (1);
 
   OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket));
-  onoff.SetAttribute ("OnTime", ConstantVariable (250));
-  onoff.SetAttribute ("OffTime", ConstantVariable (0));
-  onoff.SetAttribute ("DataRate", DataRate (60000000));
-  onoff.SetAttribute ("PacketSize", Uinteger (2000));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (250)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+  onoff.SetAttribute ("DataRate", DataRateValue (DataRate (60000000)));
+  onoff.SetAttribute ("PacketSize", UintegerValue (2000));
 
   ApplicationContainer apps = onoff.Install (c.Get (0));
   apps.Start (Seconds (0.5));
@@ -156,8 +156,8 @@
 int main (int argc, char *argv[])
 {
   // disable fragmentation
-  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", String ("2200"));
-  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", String ("2200"));
+  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));
+  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200"));
 
   CommandLine cmd;
   cmd.Parse (argc, argv);
@@ -174,56 +174,56 @@
   NS_LOG_DEBUG ("54");
   experiment = Experiment ("54mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
-                                "DataMode", String ("wifia-54mbs"));
+                                "DataMode", StringValue ("wifia-54mbs"));
   dataset = experiment.Run (wifi);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("48");
   experiment = Experiment ("48mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
-                                "DataMode", String ("wifia-48mbs"));
+                                "DataMode", StringValue ("wifia-48mbs"));
   dataset = experiment.Run (wifi);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("36");
   experiment = Experiment ("36mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
-                                "DataMode", String ("wifia-36mbs"));
+                                "DataMode", StringValue ("wifia-36mbs"));
   dataset = experiment.Run (wifi);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("24");
   experiment = Experiment ("24mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
-                                "DataMode", String ("wifia-24mbs"));
+                                "DataMode", StringValue ("wifia-24mbs"));
   dataset = experiment.Run (wifi);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("18");
   experiment = Experiment ("18mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
-                                "DataMode", String ("wifia-18mbs"));
+                                "DataMode", StringValue ("wifia-18mbs"));
   dataset = experiment.Run (wifi);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("12");
   experiment = Experiment ("12mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
-                                "DataMode", String ("wifia-12mbs"));
+                                "DataMode", StringValue ("wifia-12mbs"));
   dataset = experiment.Run (wifi);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("9");
   experiment = Experiment ("9mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
-                                "DataMode", String ("wifia-9mbs"));
+                                "DataMode", StringValue ("wifia-9mbs"));
   dataset = experiment.Run (wifi);
   gnuplot.AddDataset (dataset);
 
   NS_LOG_DEBUG ("6");
   experiment = Experiment ("6mb");
   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
-                                "DataMode", String ("wifia-6mbs"));
+                                "DataMode", StringValue ("wifia-6mbs"));
   dataset = experiment.Run (wifi);
   gnuplot.AddDataset (dataset);
 
@@ -231,7 +231,7 @@
 
 
   gnuplot = Gnuplot ("rate-control.png");
-  Config::SetDefault ("ns3::WifiPhy::Standard", String ("holland"));
+  Config::SetDefault ("ns3::WifiPhy::Standard", StringValue ("holland"));
 
 
   NS_LOG_DEBUG ("arf");
--- a/examples/wifi-ap.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/examples/wifi-ap.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -113,9 +113,9 @@
   Packet::EnableMetadata ();
 
   // enable rts cts all the time.
-  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", String ("0"));
+  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("0"));
   // disable fragmentation
-  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", String ("2200"));
+  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));
 
   WifiHelper wifi;
   MobilityHelper mobility;
@@ -141,13 +141,14 @@
   wifi.SetPhy ("ns3::WifiPhy");
   wifi.SetRemoteStationManager ("ns3::ArfWifiManager");
   // setup stas.
-  wifi.SetMac ("ns3::NqstaWifiMac", "Ssid", ssid,
-               "ActiveProbing", Boolean (false));
+  wifi.SetMac ("ns3::NqstaWifiMac", 
+               "Ssid", SsidValue (ssid),
+               "ActiveProbing", BooleanValue (false));
   staDevs = wifi.Install (stas, channel);
   // setup ap.
-  wifi.SetMac ("ns3::NqapWifiMac", "Ssid", ssid,
-               "BeaconGeneration", Boolean (true),
-               "BeaconInterval", Seconds (2.5));
+  wifi.SetMac ("ns3::NqapWifiMac", "Ssid", SsidValue (ssid),
+               "BeaconGeneration", BooleanValue (true),
+               "BeaconInterval", TimeValue (Seconds (2.5)));
   wifi.Install (ap, channel);
 
   // mobility.
@@ -162,8 +163,8 @@
   socket.SetProtocol (1);
 
   OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket));
-  onoff.SetAttribute ("OnTime", ConstantVariable (42));
-  onoff.SetAttribute ("OffTime", ConstantVariable (0));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (42)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
 
   ApplicationContainer apps = onoff.Install (stas.Get (0));
   apps.Start (Seconds (0.5));
--- a/samples/main-attribute-value.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/samples/main-attribute-value.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -24,6 +24,7 @@
 #include "ns3/config.h"
 #include "ns3/uinteger.h"
 #include "ns3/string.h"
+#include "ns3/pointer.h"
 #include "ns3/simulator.h"
 
 #include "ns3/node.h"
@@ -50,10 +51,10 @@
   // (this default can be observed in the function DropTailQueue::GetTypeId)
   // 
   // Here, we set it to 80 packets.  We could use one of two value types:
-  // a string-based value or a Uinteger value
-  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", String ("80"));
+  // a string-based value or a UintegerValue value
+  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("80"));
   // The below function call is redundant
-  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", Uinteger(80));
+  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (80));
 
   // Allow the user to override any of the defaults and the above
   // SetDefaults() at run-time, via command-line arguments
@@ -87,7 +88,9 @@
   // First, we observe that we can get a pointer to the (base class)
   // queue via the PointToPointNetDevice attributes, where it is called
   // TxQueue 
-  Ptr<Queue> txQueue = net0->GetAttribute ("TxQueue");
+  PointerValue ptr;
+  net0->GetAttribute ("TxQueue", ptr);
+  Ptr<Queue> txQueue = ptr.Get<Queue> ();
 
   // Using the GetObject function, we can perform a safe downcast
   // to a DropTailQueue, where MaxPackets is a member
@@ -100,18 +103,19 @@
   // the attribute system stores values and not disparate types.
   // Here, the attribute value is assigned to a Uinteger, and
   // the Get() method on this value produces the (unwrapped) uint32_t.
-  Uinteger limit = dtq->GetAttribute ("MaxPackets");
+  UintegerValue limit;
+  dtq->GetAttribute ("MaxPackets", limit);
   NS_LOG_INFO ("1.  dtq limit: " << limit.Get () << " packets");
   
   // Note that the above downcast is not really needed; we could have
   // done the same using the Ptr<Queue> even though the attribute
   // is a member of the subclass
-  limit = txQueue->GetAttribute ("MaxPackets");
+  txQueue->GetAttribute ("MaxPackets", limit);
   NS_LOG_INFO ("2.  txQueue limit: " << limit.Get () << " packets");
 
   // Now, let's set it to another value (60 packets)
-  txQueue->SetAttribute("MaxPackets", Uinteger (60));
-  limit = txQueue->GetAttribute ("MaxPackets");
+  txQueue->SetAttribute("MaxPackets", UintegerValue (60));
+  txQueue->GetAttribute ("MaxPackets", limit);
   NS_LOG_INFO ("3.  txQueue limit changed: " << limit.Get () << " packets");
 
   // 2.  Namespace-based access
@@ -121,18 +125,18 @@
   // namespace; this approach is useful if one doesn't have access to
   // the underlying pointers and would like to configure a specific
   // attribute with a single statement.  
-  Config::Set ("/NodeList/0/DeviceList/0/TxQueue/MaxPackets", Uinteger (25));
-  limit = txQueue->GetAttribute ("MaxPackets"); 
+  Config::Set ("/NodeList/0/DeviceList/0/TxQueue/MaxPackets", UintegerValue (25));
+  txQueue->GetAttribute ("MaxPackets", limit); 
   NS_LOG_INFO ("4.  txQueue limit changed through namespace: " << 
-    limit.Get () << " packets");
+               limit.Get () << " packets");
 
   // we could have also used wildcards to set this value for all nodes
   // and all net devices (which in this simple example has the same
   // effect as the previous Set())
-  Config::Set ("/NodeList/*/DeviceList/*/TxQueue/MaxPackets", Uinteger (15));
-  limit = txQueue->GetAttribute ("MaxPackets"); 
+  Config::Set ("/NodeList/*/DeviceList/*/TxQueue/MaxPackets", UintegerValue (15));
+  txQueue->GetAttribute ("MaxPackets", limit); 
   NS_LOG_INFO ("5.  txQueue limit changed through wildcarded namespace: " << 
-    limit.Get () << " packets");
+               limit.Get () << " packets");
 
   Simulator::Destroy ();
 }
--- a/samples/main-grid-topology.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/samples/main-grid-topology.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -23,12 +23,12 @@
   // the x interval between each object is 5 meters
   // and the y interval between each object is 20 meters
   mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
-                                 "MinX", Double (-100.0),
-                                 "MinY", Double (-100.0),
-                                 "DeltaX", Double (5.0),
-                                 "DeltaY", Double (20.0),
-                                 "GridWidth", Uinteger (20),
-                                 "LayoutType", String ("RowFirst"));
+                                 "MinX", DoubleValue (-100.0),
+                                 "MinY", DoubleValue (-100.0),
+                                 "DeltaX", DoubleValue (5.0),
+                                 "DeltaY", DoubleValue (20.0),
+                                 "GridWidth", UintegerValue (20),
+                                 "LayoutType", StringValue ("RowFirst"));
   // each object will be attached a static position.
   // i.e., once set by the "position allocator", the
   // position will never change.
--- a/samples/main-propagation-loss.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/samples/main-propagation-loss.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -51,8 +51,8 @@
 int main (int argc, char *argv[])
 {
 
-  Config::SetGlobal ("LogDistancePropagationLossModel::ReferenceDistance", String ("1.0"));
-  Config::SetGlobal ("LogDistancePropagationLossModel::Exponent", String ("4"));
+  Config::SetGlobal ("LogDistancePropagationLossModel::ReferenceDistance", StringValue ("1.0"));
+  Config::SetGlobal ("LogDistancePropagationLossModel::Exponent", StringValue ("4"));
 
   PrintOne (-10, 20, 5, 0, 10000, 2);
 
--- a/samples/main-random-topology.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/samples/main-random-topology.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -27,9 +27,9 @@
   MobilityHelper mobility;
   mobility.EnableNotifier ();
   mobility.SetPositionAllocator ("ns3::RandomDiscPositionAllocator",
-                                 "X", String ("100.0"),
-                                 "Y", String ("100.0"),
-                                 "Rho", String ("Uniform:0:30"));
+                                 "X", StringValue ("100.0"),
+                                 "Y", StringValue ("100.0"),
+                                 "Rho", StringValue ("Uniform:0:30"));
   mobility.SetMobilityModel ("ns3::StaticMobilityModel");
   mobility.Install (c);
 
--- a/samples/main-random-walk.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/samples/main-random-walk.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -19,10 +19,10 @@
 
 int main (int argc, char *argv[])
 {
-  Config::SetDefault ("ns3::RandomWalk2dMobilityModel::Mode", String ("Time"));
-  Config::SetDefault ("ns3::RandomWalk2dMobilityModel::Time", String ("2s"));
-  Config::SetDefault ("ns3::RandomWalk2dMobilityModel::Speed", String ("Constant:1.0"));
-  Config::SetDefault ("ns3::RandomWalk2dMobilityModel::Bounds", String ("0:200:0:100"));
+  Config::SetDefault ("ns3::RandomWalk2dMobilityModel::Mode", StringValue ("Time"));
+  Config::SetDefault ("ns3::RandomWalk2dMobilityModel::Time", StringValue ("2s"));
+  Config::SetDefault ("ns3::RandomWalk2dMobilityModel::Speed", StringValue ("Constant:1.0"));
+  Config::SetDefault ("ns3::RandomWalk2dMobilityModel::Bounds", StringValue ("0:200:0:100"));
 
   CommandLine cmd;
   cmd.Parse (argc, argv);
@@ -33,17 +33,17 @@
   MobilityHelper mobility;
   mobility.EnableNotifier ();
   mobility.SetPositionAllocator ("ns3::RandomDiscPositionAllocator",
-                                 "X", String ("100.0"),
-                                 "Y", String ("100.0"),
-                                 "Rho", String ("Uniform:0:30"));
+                                 "X", StringValue ("100.0"),
+                                 "Y", StringValue ("100.0"),
+                                 "Rho", StringValue ("Uniform:0:30"));
   mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",
-                             "Mode", String ("Time"),
-                             "Time", String ("2s"),
-                             "Speed", String ("Constant:1.0"),
-                             "Bounds", String ("0:200:0:100"));
-  mobility.InstallAll ();
+                             "Mode", StringValue ("Time"),
+                             "Time", StringValue ("2s"),
+                             "Speed", StringValue ("Constant:1.0"),
+                             "Bounds", StringValue ("0:200:0:100"));
+  mobility.LayoutAll ();
   Config::Connect ("/NodeList/*/$ns3::MobilityModelNotifier/CourseChange",
-                              MakeCallback (&CourseChange));
+                   MakeCallback (&CourseChange));
 
   Simulator::StopAt (Seconds (100.0));
 
--- a/src/applications/onoff/onoff-application.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/applications/onoff/onoff-application.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -52,34 +52,34 @@
     .SetParent<Application> ()
     .AddConstructor<OnOffApplication> ()
     .AddAttribute ("DataRate", "The data rate in on state.",
-                   DataRate ("500kb/s"),
+                   DataRateValue (DataRate ("500kb/s")),
                    MakeDataRateAccessor (&OnOffApplication::m_cbrRate),
                    MakeDataRateChecker ())
     .AddAttribute ("PacketSize", "The size of packets sent in on state",
-                   Uinteger (512),
+                   UintegerValue (512),
                    MakeUintegerAccessor (&OnOffApplication::m_pktSize),
                    MakeUintegerChecker<uint32_t> (1))
     .AddAttribute ("Remote", "The address of the destination",
-                   Address (),
+                   AddressValue (),
                    MakeAddressAccessor (&OnOffApplication::m_peer),
                    MakeAddressChecker ())
     .AddAttribute ("OnTime", "A RandomVariable used to pick the duration of the 'On' state.",
-                   ConstantVariable (1.0),
+                   RandomVariableValue (ConstantVariable (1.0)),
                    MakeRandomVariableAccessor (&OnOffApplication::m_onTime),
                    MakeRandomVariableChecker ())
     .AddAttribute ("OffTime", "A RandomVariable used to pick the duration of the 'Off' state.",
-                   ConstantVariable (1.0),
+                   RandomVariableValue (ConstantVariable (1.0)),
                    MakeRandomVariableAccessor (&OnOffApplication::m_offTime),
                    MakeRandomVariableChecker ())
     .AddAttribute ("MaxBytes", 
                    "The total number of bytes to send. Once these bytes are sent, "
                    "no packet is sent again, even in on state. The value zero means "
                    "that there is no limit.",
-                   Uinteger (0),
+                   UintegerValue (0),
                    MakeUintegerAccessor (&OnOffApplication::m_maxBytes),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("Protocol", "The type of protocol to use.",
-                   Udp::GetTypeId (),
+                   TypeIdValue (Udp::GetTypeId ()),
                    MakeTypeIdAccessor (&OnOffApplication::m_tid),
                    MakeTypeIdChecker ())
     .AddTraceSource ("Tx", "A new packet is created and is sent",
@@ -91,7 +91,7 @@
 
 OnOffApplication::OnOffApplication ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_socket = 0;
   m_connected = false;
   m_residualBits = 0;
@@ -101,14 +101,13 @@
 
 OnOffApplication::~OnOffApplication()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 void 
 OnOffApplication::SetMaxBytes(uint32_t maxBytes)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << maxBytes);
+  NS_LOG_FUNCTION (this << maxBytes);
   m_maxBytes = maxBytes;
 }
 
@@ -116,7 +115,7 @@
 void
 OnOffApplication::DoDispose (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   m_socket = 0;
   // chain up
@@ -126,7 +125,7 @@
 // Application Methods
 void OnOffApplication::StartApplication() // Called at time specified by Start
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   // Create the socket if not already
   if (!m_socket)
@@ -146,7 +145,7 @@
 
 void OnOffApplication::StopApplication() // Called at time specified by Stop
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   if (m_sendEvent.IsRunning ())
     { // Cancel the pending send packet event
@@ -161,14 +160,14 @@
 // Event handlers
 void OnOffApplication::StartSending()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   ScheduleNextTx();  // Schedule the send packet event
 }
 
 void OnOffApplication::StopSending()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   Simulator::Cancel(m_sendEvent);
 }
@@ -176,7 +175,7 @@
 // Private helpers
 void OnOffApplication::ScheduleNextTx()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   if (m_maxBytes == 0 || m_totBytes < m_maxBytes)
     {
@@ -196,7 +195,7 @@
 
 void OnOffApplication::ScheduleStartEvent()
 {  // Schedules the event to start sending data (switch to the "On" state)
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   Time offInterval = Seconds(m_offTime.GetValue());
   NS_LOG_LOGIC ("start at " << offInterval);
@@ -205,7 +204,7 @@
 
 void OnOffApplication::ScheduleStopEvent()
 {  // Schedules the event to stop sending data (switch to "Off" state)
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   Time onInterval = Seconds(m_onTime.GetValue());
   NS_LOG_LOGIC ("stop at " << onInterval);
@@ -215,7 +214,7 @@
   
 void OnOffApplication::SendPacket()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC ("sending packet at " << Simulator::Now());
   NS_ASSERT (m_sendEvent.IsExpired ());
   Ptr<Packet> packet = Create<Packet> (m_pktSize);
@@ -229,7 +228,7 @@
 
 void OnOffApplication::ConnectionSucceeded(Ptr<Socket>)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   m_connected = true;
   ScheduleStartEvent();
@@ -237,7 +236,7 @@
   
 void OnOffApplication::ConnectionFailed(Ptr<Socket>)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   cout << "OnOffApplication, Connection Failed" << endl;
 }
 
--- a/src/applications/packet-sink/packet-sink.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/applications/packet-sink/packet-sink.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -43,11 +43,11 @@
     .SetParent<Application> ()
     .AddConstructor<PacketSink> ()
     .AddAttribute ("Local", "The Address on which to Bind the rx socket.",
-                   Address (),
+                   AddressValue (),
                    MakeAddressAccessor (&PacketSink::m_local),
                    MakeAddressChecker ())
     .AddAttribute ("Protocol", "The type id of the protocol to use for the rx socket.",
-                   Udp::GetTypeId (),
+                   TypeIdValue (Udp::GetTypeId ()),
                    MakeTypeIdAccessor (&PacketSink::m_tid),
                    MakeTypeIdChecker ())
     .AddTraceSource ("Rx", "A packet has been received",
--- a/src/applications/udp-echo/udp-echo-client.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/applications/udp-echo/udp-echo-client.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -38,23 +38,23 @@
     .SetParent<Application> ()
     .AddConstructor<UdpEchoClient> ()
     .AddAttribute ("MaxPackets", "XXX",
-                   Uinteger (100),
+                   UintegerValue (100),
                    MakeUintegerAccessor (&UdpEchoClient::m_count),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("Interval", "XXX",
-                   Seconds (1.0),
+                   TimeValue (Seconds (1.0)),
                    MakeTimeAccessor (&UdpEchoClient::m_interval),
                    MakeTimeChecker ())
     .AddAttribute ("RemoteIpv4", "XXX",
-                   Ipv4Address (),
+                   Ipv4AddressValue (),
                    MakeIpv4AddressAccessor (&UdpEchoClient::m_peerAddress),
                    MakeIpv4AddressChecker ())
     .AddAttribute ("RemotePort", "XXX",
-                   Uinteger (0),
+                   UintegerValue (0),
                    MakeUintegerAccessor (&UdpEchoClient::m_peerPort),
                    MakeUintegerChecker<uint16_t> ())
     .AddAttribute ("PacketSize", "Size of packets generated",
-                   Uinteger (100),
+                   UintegerValue (100),
                    MakeUintegerAccessor (&UdpEchoClient::m_size),
                    MakeUintegerChecker<uint32_t> ())
     ;
@@ -63,7 +63,7 @@
 
 UdpEchoClient::UdpEchoClient ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_sent = 0;
   m_socket = 0;
   m_sendEvent = EventId ();
@@ -71,7 +71,7 @@
 
 UdpEchoClient::~UdpEchoClient()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 void 
@@ -84,14 +84,14 @@
 void
 UdpEchoClient::DoDispose (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Application::DoDispose ();
 }
 
 void 
 UdpEchoClient::StartApplication (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   if (!m_socket)
     {
@@ -111,7 +111,7 @@
 void 
 UdpEchoClient::StopApplication ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   if (!m_socket) 
     {
@@ -125,14 +125,14 @@
 void 
 UdpEchoClient::ScheduleTransmit (Time dt)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_sendEvent = Simulator::Schedule(dt, &UdpEchoClient::Send, this);
 }
 
 void 
 UdpEchoClient::Send (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   NS_ASSERT (m_sendEvent.IsExpired ());
 
@@ -154,8 +154,7 @@
   Ptr<Packet> packet,
   const Address &from) 
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << socket << packet << from);
+  NS_LOG_FUNCTION (this << socket << packet << from);
 
   if (InetSocketAddress::IsMatchingType (from))
     {
--- a/src/applications/udp-echo/udp-echo-client.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/applications/udp-echo/udp-echo-client.h	Tue Apr 22 21:19:39 2008 -0700
@@ -29,6 +29,11 @@
 class Socket;
 class Packet;
 
+/**
+ * \brief A Udp Echo client
+ *
+ * Every packet sent should be returned by the server and received here.
+ */
 class UdpEchoClient : public Application 
 {
 public:
--- a/src/applications/udp-echo/udp-echo-server.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/applications/udp-echo/udp-echo-server.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -40,7 +40,7 @@
     .SetParent<Application> ()
     .AddConstructor<UdpEchoServer> ()
     .AddAttribute ("Port", "Port on which we listen for incoming packets.",
-                   Uinteger (9),
+                   UintegerValue (9),
                    MakeUintegerAccessor (&UdpEchoServer::m_port),
                    MakeUintegerChecker<uint16_t> ())
     ;
@@ -49,25 +49,25 @@
 
 UdpEchoServer::UdpEchoServer ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 UdpEchoServer::~UdpEchoServer()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 void
 UdpEchoServer::DoDispose (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Application::DoDispose ();
 }
 
 void 
 UdpEchoServer::StartApplication (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   if (!m_socket)
     {
@@ -85,7 +85,7 @@
 void 
 UdpEchoServer::StopApplication ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   if (!m_socket) 
     {
@@ -100,8 +100,7 @@
   Ptr<Packet> packet,
   const Address &from) 
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << socket << packet << from);
+  NS_LOG_FUNCTION (this << socket << packet << from);
 
   if (InetSocketAddress::IsMatchingType (from))
     {
--- a/src/applications/udp-echo/udp-echo-server.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/applications/udp-echo/udp-echo-server.h	Tue Apr 22 21:19:39 2008 -0700
@@ -29,6 +29,11 @@
 class Socket;
 class Packet;
 
+/**
+ * \brief A Udp Echo server
+ *
+ * Every packet received is sent back.
+ */
 class UdpEchoServer : public Application 
 {
 public:
--- a/src/common/buffer.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/common/buffer.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -462,6 +462,40 @@
 }
 
 void 
+Buffer::AddAtEnd (const Buffer &o)
+{
+  if (m_end == m_zeroAreaEnd &&
+      o.m_start == o.m_zeroAreaStart &&
+      o.m_zeroAreaEnd - o.m_zeroAreaStart > 0)
+    {
+      /**
+       * This is an optimization which kicks in when
+       * we attempt to aggregate two buffers which contain
+       * adjacent zero areas.
+       */
+      uint32_t zeroSize = o.m_zeroAreaEnd - o.m_zeroAreaStart;
+      m_zeroAreaEnd += zeroSize;
+      m_end = m_zeroAreaEnd;
+      uint32_t endData = o.m_end - o.m_zeroAreaEnd;
+      AddAtEnd (endData);
+      Buffer::Iterator dst = End ();
+      dst.Prev (endData);
+      Buffer::Iterator src = o.End ();
+      src.Prev (endData);
+      dst.Write (src, o.End ());
+      return;
+    }
+  Buffer dst = CreateFullCopy ();
+  Buffer src = o.CreateFullCopy ();
+
+  dst.AddAtEnd (src.GetSize ());
+  Buffer::Iterator destStart = dst.End ();
+  destStart.Prev (src.GetSize ());
+  destStart.Write (src.Begin (), src.End ());
+  *this = dst;
+}
+
+void 
 Buffer::RemoveAtStart (uint32_t start)
 {
   NS_ASSERT (CheckInternalState ());
@@ -544,14 +578,6 @@
 Buffer::CreateFragment (uint32_t start, uint32_t length) const
 {
   NS_ASSERT (CheckInternalState ());
-  uint32_t zeroStart = m_zeroAreaStart - m_start;
-  uint32_t zeroEnd = zeroStart + m_zeroAreaEnd;
-  if (m_zeroAreaEnd != 0 &&
-      start + length > zeroStart &&
-      start <= zeroEnd) 
-    {
-      TransformIntoRealBuffer ();
-    }
   Buffer tmp = *this;
   tmp.RemoveAtStart (start);
   tmp.RemoveAtEnd (GetSize () - (start + length));
@@ -563,7 +589,7 @@
 Buffer::CreateFullCopy (void) const
 {
   NS_ASSERT (CheckInternalState ());
-  if (m_zeroAreaEnd != 0) 
+  if (m_zeroAreaEnd - m_zeroAreaStart != 0) 
     {
       Buffer tmp;
       tmp.AddAtStart (m_zeroAreaEnd - m_zeroAreaStart);
@@ -1331,6 +1357,21 @@
     NS_TEST_ASSERT (memcmp (inputBuffer.PeekData (), outputBuffer.PeekData (), chunkSize) == 0);
   }
 
+  buffer = Buffer (5);
+  buffer.AddAtEnd (2);
+  i = buffer.End ();
+  i.Prev (2);
+  i.WriteU8 (0);
+  i.WriteU8 (0x66);
+  ENSURE_WRITTEN_BYTES (buffer, 7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66);
+  Buffer frag0 = buffer.CreateFragment (0, 2);
+  ENSURE_WRITTEN_BYTES (frag0, 2, 0x00, 0x00);
+  Buffer frag1 = buffer.CreateFragment (2, 5);
+  ENSURE_WRITTEN_BYTES (frag1, 5, 0x00, 0x00, 0x00, 0x00, 0x66);
+  frag0.AddAtEnd (frag1);
+  ENSURE_WRITTEN_BYTES (buffer, 7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66);
+  ENSURE_WRITTEN_BYTES (frag0, 7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66);
+
   return result;
 }
 
--- a/src/common/buffer.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/common/buffer.h	Tue Apr 22 21:19:39 2008 -0700
@@ -410,6 +410,8 @@
    * pointing to this Buffer.
    */
   void AddAtEnd (uint32_t end);
+
+  void AddAtEnd (const Buffer &o);
   /**
    * \param start size to remove
    *
--- a/src/common/data-rate.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/common/data-rate.h	Tue Apr 22 21:19:39 2008 -0700
@@ -89,6 +89,11 @@
 std::ostream &operator << (std::ostream &os, const DataRate &rate);
 std::istream &operator >> (std::istream &is, DataRate &rate);
 
+/**
+ * \class ns3::DataRateValue
+ * \brief hold objects of type ns3::DataRate
+ */
+
 ATTRIBUTE_HELPER_HEADER_2 (DataRate);
 
 /**
--- a/src/common/error-model.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/common/error-model.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -42,7 +42,7 @@
   static TypeId tid = TypeId ("ns3::ErrorModel")
     .SetParent<Object> ()
     .AddAttribute ("IsEnabled", "Whether this ErrorModel is enabled or not.",
-                   Boolean (true),
+                   BooleanValue (true),
                    MakeBooleanAccessor (&ErrorModel::m_enable),
                    MakeBooleanChecker ())
     ;
@@ -52,18 +52,18 @@
 ErrorModel::ErrorModel () :
   m_enable (true) 
 {
-  NS_LOG_FUNCTION;  
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 ErrorModel::~ErrorModel ()
 {
-  NS_LOG_FUNCTION;  
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 bool
 ErrorModel::IsCorrupt (Ptr<Packet> p)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   bool result;
   // Insert any pre-conditions here
   result = DoCorrupt (p);
@@ -74,28 +74,28 @@
 void
 ErrorModel::Reset (void)
 {
-  NS_LOG_FUNCTION;  
+  NS_LOG_FUNCTION_NOARGS ();
   DoReset ();
 }
 
 void
 ErrorModel::Enable (void)
 {
-  NS_LOG_FUNCTION;  
+  NS_LOG_FUNCTION_NOARGS ();
   m_enable = true;
 }
 
 void
 ErrorModel::Disable (void)
 {
-  NS_LOG_FUNCTION;  
+  NS_LOG_FUNCTION_NOARGS ();
   m_enable = false;
 }
 
 bool
 ErrorModel::IsEnabled (void) const
 {
-  NS_LOG_FUNCTION;  
+  NS_LOG_FUNCTION_NOARGS ();
   return m_enable;
 }
 
@@ -111,17 +111,17 @@
     .SetParent<ErrorModel> ()
     .AddConstructor<RateErrorModel> ()
     .AddAttribute ("ErrorUnit", "The error unit",
-                   Enum (EU_BYTE),
+                   EnumValue (EU_BYTE),
                    MakeEnumAccessor (&RateErrorModel::m_unit),
                    MakeEnumChecker (EU_BYTE, "EU_BYTE",
                                     EU_PKT, "EU_PKT",
                                     EU_BIT, "EU_BIT"))
     .AddAttribute ("ErrorRate", "The error rate.",
-                   Double (0.0),
+                   DoubleValue (0.0),
                    MakeDoubleAccessor (&RateErrorModel::m_rate),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("RanVar", "The decision variable attached to this error model.",
-                   UniformVariable (0.0, 1.0),
+                   RandomVariableValue (UniformVariable (0.0, 1.0)),
                    MakeRandomVariableAccessor (&RateErrorModel::m_ranvar),
                    MakeRandomVariableChecker ())
     ;
@@ -131,53 +131,53 @@
 
 RateErrorModel::RateErrorModel ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 RateErrorModel::~RateErrorModel () 
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 enum ErrorUnit 
 RateErrorModel::GetUnit (void) const 
 { 
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_unit; 
 }
 
 void 
 RateErrorModel::SetUnit (enum ErrorUnit error_unit) 
 { 
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_unit = error_unit; 
 }
 
 double
 RateErrorModel::GetRate (void) const 
 { 
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_rate; 
 }
 
 void 
 RateErrorModel::SetRate (double rate)
 { 
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_rate = rate;
 }
 
 void 
 RateErrorModel::SetRandomVariable (const RandomVariable &ranvar)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_ranvar = ranvar;
 }
 
 bool 
 RateErrorModel::DoCorrupt (Ptr<Packet> p) 
 { 
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (!m_enable)
     {
       return false;  
@@ -200,14 +200,14 @@
 bool
 RateErrorModel::DoCorruptPkt (Ptr<Packet> p)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return (m_ranvar.GetValue () < m_rate);
 }
 
 bool
 RateErrorModel::DoCorruptByte (Ptr<Packet> p)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   // compute pkt error rate, assume uniformly distributed byte error
   double per = 1 - pow (1.0 - m_rate, p->GetSize ());
   return (m_ranvar.GetValue () < per);
@@ -216,7 +216,7 @@
 bool
 RateErrorModel::DoCorruptBit(Ptr<Packet> p)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   // compute pkt error rate, assume uniformly distributed bit error
   double per = 1 - pow (1.0 - m_rate, (8 * p->GetSize ()) );
   return (m_ranvar.GetValue () < per);
@@ -225,7 +225,7 @@
 void 
 RateErrorModel::DoReset (void) 
 { 
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   /* re-initialize any state; no-op for now */ 
 }
 
@@ -246,25 +246,25 @@
 
 ListErrorModel::ListErrorModel ()  
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 ListErrorModel::~ListErrorModel () 
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 std::list<uint32_t> 
 ListErrorModel::GetList (void) const 
 { 
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_packetList; 
 }
 
 void 
 ListErrorModel::SetList (const std::list<uint32_t> &packetlist)
 { 
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_packetList = packetlist;
 }
 
@@ -274,7 +274,7 @@
 bool 
 ListErrorModel::DoCorrupt (Ptr<Packet> p) 
 { 
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (!m_enable)
     {
       return false;  
@@ -294,7 +294,7 @@
 void 
 ListErrorModel::DoReset (void) 
 { 
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_packetList.clear();
 }
 
--- a/src/common/packet-metadata.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/common/packet-metadata.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -649,7 +649,7 @@
       m_metadataSkipped = true;
       return;
     }
-  NS_LOG_PARAMS ("uid=" << uid << "size=" << size << "");
+  NS_LOG_FUNCTION ("uid=" << uid << "size=" << size << "");
 
   struct PacketMetadata::SmallItem item;
   item.next = m_head;
@@ -670,7 +670,7 @@
       m_metadataSkipped = true;
       return;
     }
-  NS_LOG_PARAMS ("(uid=" << uid << ", size=" << size << ")");
+  NS_LOG_FUNCTION ("(uid=" << uid << ", size=" << size << ")");
   struct PacketMetadata::SmallItem item;
   struct PacketMetadata::ExtraItem extraItem;
   uint32_t read = ReadItems (m_head, &item, &extraItem);
@@ -708,7 +708,7 @@
       m_metadataSkipped = true;
       return;
     }
-  NS_LOG_PARAMS ("(uid=" << uid << ", size=" << size << ")");
+  NS_LOG_FUNCTION ("(uid=" << uid << ", size=" << size << ")");
   struct PacketMetadata::SmallItem item;
   item.next = 0xffff;
   item.prev = m_tail;
@@ -728,7 +728,7 @@
       m_metadataSkipped = true;
       return;
     }
-  NS_LOG_PARAMS ("(uid=" << uid << ", size=" << size << ")");
+  NS_LOG_FUNCTION ("(uid=" << uid << ", size=" << size << ")");
   struct PacketMetadata::SmallItem item;
   struct PacketMetadata::ExtraItem extraItem;
   uint32_t read = ReadItems (m_tail, &item, &extraItem);
--- a/src/common/packet.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/common/packet.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -159,14 +159,7 @@
 void 
 Packet::AddAtEnd (Ptr<const Packet> packet)
 {
-  Buffer src = packet->m_buffer.CreateFullCopy ();
-  Buffer dst = m_buffer.CreateFullCopy ();
-
-  dst.AddAtEnd (src.GetSize ());
-  Buffer::Iterator destStart = dst.End ();
-  destStart.Prev (src.GetSize ());
-  destStart.Write (src.Begin (), src.End ());
-  m_buffer = dst;
+  m_buffer.AddAtEnd (packet->m_buffer);
   /**
    * XXX: we might need to merge the tag list of the
    * other packet into the current packet.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/config-store.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -0,0 +1,205 @@
+#include "config-store.h"
+#include "ns3/string.h"
+#include "ns3/config.h"
+#include "ns3/object-vector.h"
+#include "ns3/pointer.h"
+#include "ns3/log.h"
+#include <string>
+#include <fstream>
+#include <iostream>
+#include <unistd.h>
+
+NS_LOG_COMPONENT_DEFINE ("ConfigStore");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (ConfigStore);
+
+TypeId 
+ConfigStore::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::ConfigStore")
+    .SetParent<ObjectBase> ()
+    .AddAttribute ("LoadFilename", 
+		   "The file where the configuration should be loaded from.",
+		   StringValue (""),
+		   MakeStringAccessor (&ConfigStore::m_loadFilename),
+		   MakeStringChecker ())
+    .AddAttribute ("StoreFilename", 
+		   "The file where the configuration should be stored to.",
+		   StringValue (""),
+		   MakeStringAccessor (&ConfigStore::m_storeFilename),
+		   MakeStringChecker ())
+    ;
+  return tid;
+}
+TypeId 
+ConfigStore::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+
+ConfigStore::ConfigStore ()
+{
+  ObjectBase::ConstructSelf (AttributeList ());
+}
+
+void 
+ConfigStore::LoadFrom (std::string filename)
+{
+  std::ifstream is;
+  is.open (filename.c_str (), std::ios::in);
+  std::string path, value;
+  while (is.good())
+    {
+      is >> path >> value;
+      NS_LOG_DEBUG (path << "=" << value);
+      Config::Set (path, StringValue (value));
+    }
+}
+void 
+ConfigStore::StoreTo (std::string filename)
+{
+  std::ofstream os;
+  os.open (filename.c_str (), std::ios::out);
+  for (uint32_t i = 0; i < Config::GetRootNamespaceObjectN (); ++i)
+    {
+      Ptr<Object> object = Config::GetRootNamespaceObject (i);
+      Store (os, object);
+    }
+  os.close ();
+  NS_ASSERT (m_currentPath.empty ());
+  NS_ASSERT (m_examined.empty ());
+  exit (0);
+}
+
+bool
+ConfigStore::IsExamined (Ptr<const Object> object)
+{
+  for (uint32_t i = 0; i < m_examined.size (); ++i)
+    {
+      if (object == m_examined[i])
+	{
+	  return true;
+	}
+    }
+  return false;
+}
+
+std::string
+ConfigStore::GetCurrentPath (std::string attr) const
+{
+  std::ostringstream oss;
+  for (uint32_t i = 0; i < m_currentPath.size (); ++i)
+    {
+      oss << "/" << m_currentPath[i];
+    }
+  oss << "/" << attr;
+  return oss.str ();
+}
+
+void
+ConfigStore::Store (std::ostream &os, Ptr<const Object> object)
+{
+  if (IsExamined (object))
+    {
+      return;
+    }
+  TypeId tid = object->GetInstanceTypeId ();
+  m_currentPath.push_back ("$" + tid.GetName ());
+  NS_LOG_DEBUG ("store " << tid.GetName ());
+  for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
+    {
+      Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (i);
+      const PointerChecker *ptrChecker = dynamic_cast<const PointerChecker *> (PeekPointer (checker));
+      if (ptrChecker != 0)
+	{
+	  NS_LOG_DEBUG ("pointer attribute " << tid.GetAttributeName (i));
+	  PointerValue ptr;
+	  object->GetAttribute (tid.GetAttributeName (i), ptr);
+	  Ptr<const Object> tmp = ptr.Get<Object> ();
+	  if (tmp != 0)
+	    {
+	      m_currentPath.push_back (tid.GetAttributeName (i));
+	      m_examined.push_back (object);
+	      Store (os, tmp);
+	      m_examined.pop_back ();
+	      m_currentPath.pop_back ();
+	    }
+	  continue;
+	}
+      // attempt to cast to an object vector.
+      const ObjectVectorChecker *vectorChecker = dynamic_cast<const ObjectVectorChecker *> (PeekPointer (checker));
+      if (vectorChecker != 0)
+	{
+	  NS_LOG_DEBUG ("vector attribute " << tid.GetAttributeName (i));
+	  ObjectVectorValue vector;
+	  object->GetAttribute (tid.GetAttributeName (i), vector);
+	  for (uint32_t j = 0; j < vector.GetN (); ++j)
+	    {
+	      NS_LOG_DEBUG ("vector attribute item " << j);
+	      Ptr<const Object> tmp = vector.Get (j);
+	      std::ostringstream oss;
+	      oss << tid.GetAttributeName (i) << "/" << j;
+	      m_currentPath.push_back (oss.str ());
+	      m_examined.push_back (object);
+	      Store (os, tmp);
+	      m_examined.pop_back ();
+	      m_currentPath.pop_back ();
+	    }
+	  continue;
+	}
+      uint32_t flags = tid.GetAttributeFlags (i);
+      Ptr<const AttributeAccessor> accessor = tid.GetAttributeAccessor (i);
+      if ((flags & TypeId::ATTR_GET) && accessor->HasGetter () &&
+	  (flags & TypeId::ATTR_SET) && accessor->HasSetter ())
+	{
+	  StringValue str;
+	  object->GetAttribute (tid.GetAttributeName (i), str);
+	  os << GetCurrentPath (tid.GetAttributeName (i)) << " " << str.Get () << std::endl;
+	}
+      else
+	{
+	  NS_LOG_DEBUG ("could not store " << tid.GetAttributeName (i));
+	}
+    }
+  Object::AggregateIterator iter = object->GetAggregateIterator ();
+  bool recursiveAggregate = false;
+  while (iter.HasNext ())
+    {
+      Ptr<const Object> tmp = iter.Next ();
+      if (IsExamined (tmp))
+	{
+	  recursiveAggregate = true;
+	}
+    }
+  if (!recursiveAggregate)
+    {
+      iter = object->GetAggregateIterator ();
+      while (iter.HasNext ())
+	{
+	  Ptr<const Object> tmp = iter.Next ();
+	  m_examined.push_back (object);
+	  Store (os, tmp);
+	  m_examined.pop_back ();
+	}
+    }
+  m_currentPath.pop_back ();
+}
+
+
+void 
+ConfigStore::Configure (void)
+{
+  if (m_loadFilename != "")
+    {
+      LoadFrom (m_loadFilename);
+    }
+  if (m_storeFilename != "")
+    {
+      StoreTo (m_storeFilename);
+    }
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/config-store.h	Tue Apr 22 21:19:39 2008 -0700
@@ -0,0 +1,44 @@
+#ifndef CONFIG_STORE_H
+#define CONFIG_STORE_H
+
+#include "ns3/object-base.h"
+#include "ns3/object.h"
+#include <vector>
+
+namespace ns3 {
+
+/**
+ * \brief Store and load simulation attribute configuration
+ *
+ */
+class ConfigStore : public ObjectBase
+{
+public:
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+
+  ConfigStore ();
+
+  /**
+   * Depending on which attribute was set:
+   *  - Store simulation configuration in file and exit
+   *  - Load simulation configuration from file and proceed.
+   */
+  void Configure (void);
+
+private:
+  void LoadFrom (std::string filename);
+  void StoreTo (std::string filename);
+  void Store (std::ostream &os, Ptr<const Object> object);
+  bool IsExamined (Ptr<const Object> object);
+  std::string GetCurrentPath (std::string attr) const;
+
+  std::string m_loadFilename;
+  std::string m_storeFilename;
+  std::vector<Ptr<const Object> > m_examined;
+  std::vector<std::string> m_currentPath;
+};
+
+}  // namespace ns3
+
+#endif /* CONFIG_STORE_H */
--- a/src/contrib/wscript	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/contrib/wscript	Tue Apr 22 21:19:39 2008 -0700
@@ -6,6 +6,7 @@
         'event-garbage-collector.cc',
         'gnuplot.cc',
         'delay-jitter-estimation.cc',
+        'config-store.cc',
         ]
 
     headers = bld.create_obj('ns3header')
@@ -14,4 +15,5 @@
         'event-garbage-collector.h',
         'gnuplot.h',
         'delay-jitter-estimation.h',
+        'config-store.h',
         ]
--- a/src/core/attribute-accessor-helper.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/attribute-accessor-helper.h	Tue Apr 22 21:19:39 2008 -0700
@@ -48,8 +48,8 @@
 public:
   AccessorHelper () {}
 
-  virtual bool Set (ObjectBase * object, Attribute val) const {
-    const U *value = val.DynCast<const U*> ();
+  virtual bool Set (ObjectBase * object, const AttributeValue & val) const {
+    const U *value = dynamic_cast<const U *> (&val);
     if (value == 0)
       {
 	return false;
@@ -62,8 +62,8 @@
     return DoSet (obj, value);
   }
 
-  virtual bool Get (const ObjectBase * object, Attribute val) const {
-    U *value = val.DynCast<U*> ();
+  virtual bool Get (const ObjectBase * object, AttributeValue &val) const {
+    U *value = dynamic_cast<U *> (&val);
     if (value == 0)
       {
 	return false;
@@ -76,7 +76,6 @@
     return DoGet (obj, value);
   }
 
-
 private:
   virtual bool DoSet (T *object, const U *v) const = 0;
   virtual bool DoGet (const T *object, U *v) const = 0;
@@ -102,6 +101,12 @@
 	v->Set (object->*m_memberVariable);
 	return true;
       }
+      virtual bool HasGetter (void) const {
+        return true;
+      }
+      virtual bool HasSetter (void) const {
+        return true;
+      }
       
       U T::*m_memberVariable;
     };
@@ -127,6 +132,12 @@
 	v->Set ((object->*m_getter) ());
 	return true;
       }
+      virtual bool HasGetter (void) const {
+        return true;
+      }
+      virtual bool HasSetter (void) const {
+        return false;
+      }
       U (T::*m_getter) (void) const;
     };
   return Ptr<const AttributeAccessor> (new MemberMethod (getter), false);
@@ -152,6 +163,12 @@
       virtual bool DoGet (const T *object, V *v) const {
 	return false;
       }
+      virtual bool HasGetter (void) const {
+        return false;
+      }
+      virtual bool HasSetter (void) const {
+        return true;
+      }
       void (T::*m_setter) (U);
     };
   return Ptr<const AttributeAccessor> (new MemberMethod (setter), false);
@@ -180,6 +197,12 @@
 	v->Set ((object->*m_getter) ());
 	return true;
       }
+      virtual bool HasGetter (void) const {
+        return true;
+      }
+      virtual bool HasSetter (void) const {
+        return true;
+      }
       void (T::*m_setter) (U);
       V (T::*m_getter) (void) const;
     };
--- a/src/core/attribute-helper.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/attribute-helper.h	Tue Apr 22 21:19:39 2008 -0700
@@ -29,28 +29,40 @@
 
 template <typename T, typename BASE>
 Ptr<AttributeChecker>
-MakeSimpleAttributeChecker (std::string name)
+MakeSimpleAttributeChecker (std::string name, std::string underlying)
 {
   struct SimpleAttributeChecker : public BASE
   {
-    virtual bool Check (Attribute value) const {
-      return value.DynCast<const T *> () != 0;
+    virtual bool Check (const AttributeValue &value) const {
+      return dynamic_cast<const T *> (&value) != 0;
     }
-    virtual std::string GetType (void) const {
+    virtual std::string GetValueTypeName (void) const {
       return m_type;
     }
-    virtual bool HasTypeConstraints (void) const {
-      return false;
+    virtual bool HasUnderlyingTypeInformation (void) const {
+      return true;
+    }
+    virtual std::string GetUnderlyingTypeInformation (void) const {
+      return m_underlying;
+    }
+    virtual Ptr<AttributeValue> Create (void) const {
+      return ns3::Create<T> ();
     }
-    virtual std::string GetTypeConstraints (void) const {
-      return "";
-    }
-    virtual Attribute Create (void) const {
-      return Attribute::Create<T> ();
+    virtual bool Copy (const AttributeValue &source, AttributeValue &destination) const {
+      const T *src = dynamic_cast<const T *> (&source);
+      T *dst = dynamic_cast<T *> (&destination);
+      if (src == 0 || dst == 0)
+        {
+          return false;
+        }
+      *dst = *src;
+      return true;
     }
     std::string m_type;
+    std::string m_underlying;
   } *checker = new SimpleAttributeChecker ();
   checker->m_type = name;
+  checker->m_underlying = underlying;
   return Ptr<AttributeChecker> (checker, false);
 }
 
@@ -98,6 +110,22 @@
     return MakeAccessorHelper<type##Value> (a1, a2);			\
   }
 
+#define ATTRIBUTE_VALUE_DEFINE_WITH_NAME(type,name)                     \
+  class name##Value : public AttributeValue				\
+  {									\
+  public:								\
+    name##Value ();							\
+    name##Value (const type &value);					\
+    void Set (const type &value);					\
+    type Get (void) const;						\
+    virtual Ptr<AttributeValue> Copy (void) const;                      \
+    virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const; \
+    virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker); \
+  private:								\
+    type m_value;							\
+  };
+
+
 /**
  * \ingroup AttributeHelper
  * \param type the name of the class.
@@ -106,21 +134,8 @@
  * This macro is typically invoked in a class header.
  */
 #define ATTRIBUTE_VALUE_DEFINE(type)					\
-  class type##Value : public AttributeValue				\
-  {									\
-  public:								\
-    type##Value ();							\
-    type##Value (const type &value);					\
-    void Set (const type &value);					\
-    type Get (void) const;						\
-    virtual Attribute Copy (void) const;				\
-    virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const; \
-    virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker); \
-    type##Value (Attribute value);					\
-    operator Attribute () const;					\
-  private:								\
-    type m_value;							\
-  };
+  ATTRIBUTE_VALUE_DEFINE_WITH_NAME (type,type)
+
 
 /**
  * \ingroup AttributeHelper
@@ -130,9 +145,7 @@
  * from instances of type Attribute.
  * Typically invoked from xxx.h.
  */
-#define ATTRIBUTE_CONVERTER_DEFINE(type)	\
-  type (Attribute value);			\
-  operator Attribute () const;
+#define ATTRIBUTE_CONVERTER_DEFINE(type)
 
 /**
  * \ingroup AttributeHelper
@@ -146,42 +159,34 @@
   class type##Checker : public AttributeChecker {};		\
   Ptr<const AttributeChecker> Make##type##Checker (void);	\
 
-/**
- * \ingroup AttributeHelper
- * \param type the name of the class
- *
- * This macro implements the XXXValue class (without the 
- * XXXValue::SerializeToString and XXXValue::DeserializeFromString 
- * methods).
- * Typically invoked from xxx.cc.
- */
-#define ATTRIBUTE_VALUE_IMPLEMENT_NO_SERIALIZE(type)			\
-  type##Value::type##Value ()						\
+
+#define ATTRIBUTE_VALUE_IMPLEMENT_WITH_NAME(type,name)                  \
+  name##Value::name##Value ()						\
     : m_value () {}							\
-  type##Value::type##Value (const type &value)				\
+  name##Value::name##Value (const type &value)				\
   : m_value (value) {}							\
-  void type##Value::Set (const type &v) {				\
+  void name##Value::Set (const type &v) {				\
     m_value = v;							\
   }									\
-  type type##Value::Get (void) const {					\
+  type name##Value::Get (void) const {					\
     return m_value;							\
   }									\
-  Attribute								\
-  type##Value::Copy (void) const {					\
-    return Attribute::Create<type##Value> (*this);			\
+  Ptr<AttributeValue>                                                   \
+  name##Value::Copy (void) const {					\
+    return ns3::Create<name##Value> (*this);                            \
+  }                                                                     \
+  std::string								\
+  name##Value::SerializeToString (Ptr<const AttributeChecker> checker) const { \
+    std::ostringstream oss;						\
+    oss << m_value;							\
+    return oss.str ();							\
   }									\
-  type##Value::type##Value (Attribute value)				\
-  {									\
-    type##Value *v = value.DynCast<type##Value *> ();			\
-    if (v == 0)								\
-      {									\
-	NS_FATAL_ERROR ("Unexpected type of value. Expected \"" << #type << "Value\""); \
-      }									\
-    m_value = v->Get ();						\
-  }									\
-  type##Value::operator Attribute () const				\
-  {									\
-    return Attribute::Create<type##Value> (*this);			\
+  bool									\
+  name##Value::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker) { \
+    std::istringstream iss;						\
+    iss.str (value);							\
+    iss >> m_value;							\
+    return !iss.bad () && !iss.fail ();					\
   }
 
 /**
@@ -194,20 +199,8 @@
  * Typically invoked from xxx.cc.
  */
 #define ATTRIBUTE_VALUE_IMPLEMENT(type)					\
-  std::string								\
-  type##Value::SerializeToString (Ptr<const AttributeChecker> checker) const { \
-    std::ostringstream oss;						\
-    oss << m_value;							\
-    return oss.str ();							\
-  }									\
-  bool									\
-  type##Value::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker) { \
-    std::istringstream iss;						\
-    iss.str (value);							\
-    iss >> m_value;							\
-    return !iss.bad () && !iss.fail ();					\
-  }									\
-  ATTRIBUTE_VALUE_IMPLEMENT_NO_SERIALIZE (type)
+  ATTRIBUTE_VALUE_IMPLEMENT_WITH_NAME(type,type)
+
 
 /**
  * \ingroup AttributeHelper
@@ -219,9 +212,16 @@
 #define ATTRIBUTE_CHECKER_IMPLEMENT(type)				\
   Ptr<const AttributeChecker> Make##type##Checker (void)		\
   {									\
-    return MakeSimpleAttributeChecker<type##Value,type##Checker> (#type);	\
+    return MakeSimpleAttributeChecker<type##Value,type##Checker> (#type "Value", #type); \
   }									\
 
+#define ATTRIBUTE_CHECKER_IMPLEMENT_WITH_NAME(type,name)                    \
+  Ptr<const AttributeChecker> Make##type##Checker (void)		\
+  {									\
+    return MakeSimpleAttributeChecker<type##Value,type##Checker> (#type "Value", name); \
+  }									\
+
+
 /**
  * \ingroup AttributeHelper
  * \param type the name of the class
@@ -229,20 +229,7 @@
  * This macro implements the conversion operators to and from
  * instances of type Attribute. Typically invoked from xxx.cc.
  */
-#define ATTRIBUTE_CONVERTER_IMPLEMENT(type)				\
-  type::type (Attribute value)						\
-  {									\
-    const type##Value *v = value.DynCast<const type##Value *> ();	\
-    if (v == 0)								\
-      {									\
-      NS_FATAL_ERROR ("Unexpected type of value. Expected \"" << #type << "Value\""); \
-      }									\
-    *this = v->Get ();							\
-  }									\
-  type::operator Attribute () const					\
-  {									\
-    return Attribute::Create<type##Value> (*this);			\
-  }
+#define ATTRIBUTE_CONVERTER_IMPLEMENT(type)
 
 
 /**
@@ -252,8 +239,7 @@
  * This macro should be invoked from a public section of the class
  * declaration.
  */
-#define ATTRIBUTE_HELPER_HEADER_1(type) \
-  ATTRIBUTE_CONVERTER_DEFINE (type)
+#define ATTRIBUTE_HELPER_HEADER_1(type)
 
 /**
  * \ingroup AttributeHelper
--- a/src/core/attribute-list.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/attribute-list.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -36,7 +36,7 @@
     {
       struct Attr attr;
       attr.checker = i->checker;
-      attr.value = i->value.Copy ();
+      attr.value = i->value->Copy ();
       m_attributes.push_back (attr);
     }
 }
@@ -48,7 +48,7 @@
     {
       struct Attr attr;
       attr.checker = i->checker;
-      attr.value = i->value.Copy ();
+      attr.value = i->value->Copy ();
       m_attributes.push_back (attr);
     }
   return *this;
@@ -59,7 +59,7 @@
 }
 
 void
-AttributeList::Set (std::string name, Attribute value)
+AttributeList::Set (std::string name, const AttributeValue &value)
 {
   struct TypeId::AttributeInfo info;
   bool ok = TypeId::LookupAttributeByFullName (name, &info);
@@ -74,7 +74,7 @@
     }
 }
 bool 
-AttributeList::SetFailSafe (std::string name, Attribute value)
+AttributeList::SetFailSafe (std::string name, const AttributeValue &value)
 {
   struct TypeId::AttributeInfo info;
   bool ok = TypeId::LookupAttributeByFullName (name, &info);
@@ -86,7 +86,7 @@
   return ok;
 }
 void
-AttributeList::SetWithTid (TypeId tid, std::string name, Attribute value)
+AttributeList::SetWithTid (TypeId tid, std::string name, const AttributeValue & value)
 {
   struct TypeId::AttributeInfo info;
   bool ok = tid.LookupAttributeByName (name, &info);
@@ -102,7 +102,7 @@
 }
 
 void
-AttributeList::DoSetOne (Ptr<const AttributeChecker> checker, Attribute value)
+AttributeList::DoSetOne (Ptr<const AttributeChecker> checker, const AttributeValue &value)
 {
   // get rid of any previous value stored in this
   // vector of values.
@@ -121,36 +121,38 @@
   m_attributes.push_back (attr);
 }
 bool
-AttributeList::DoSet (struct TypeId::AttributeInfo *info, Attribute value)
+AttributeList::DoSet (struct TypeId::AttributeInfo *info, const AttributeValue &value)
 {
   if (info->checker == 0)
     {
       return false;
     }
   bool ok = info->checker->Check (value);
+  if (ok)
+    {
+      DoSetOne (info->checker, value);
+      return true;
+    }
+
+  // attempt to convert to string.
+  const StringValue *str = dynamic_cast<const StringValue *> (&value);
+  if (str == 0)
+    {
+      return false;
+    }
+  // attempt to convert back to value.
+  Ptr<AttributeValue> v = info->checker->Create ();
+  ok = v->DeserializeFromString (str->Get (), info->checker);
   if (!ok)
     {
-      // attempt to convert to string.
-      const StringValue *str = value.DynCast<const StringValue *> ();
-      if (str == 0)
-        {
-          return false;
-        }
-      // attempt to convert back to value.
-      Attribute v = info->checker->Create ();
-      ok = v.DeserializeFromString (str->Get ().Get (), info->checker);
-      if (!ok)
-        {
-          return false;
-        }
-      ok = info->checker->Check (v);
-      if (!ok)
-        {
-          return false;
-        }
-      value = v;
+      return false;
     }
-  DoSetOne (info->checker, value);
+  ok = info->checker->Check (*v);
+  if (!ok)
+    {
+      return false;
+    }
+  DoSetOne (info->checker, *v);
   return true;
 }
 void 
@@ -187,10 +189,11 @@
 AttributeList::SerializeToString (void) const
 {
   std::ostringstream oss;
-  for (Attrs::const_iterator i = m_attributes.begin (); i != m_attributes.end (); i++)
+  for (Attrs::const_iterator i = m_attributes.begin (); i != m_attributes.end ();)
     {
       std::string name = LookupAttributeFullNameByChecker (i->checker);
-      oss << name << "=" << i->value.SerializeToString (i->checker);
+      oss << name << "=" << i->value->SerializeToString (i->checker);
+      i++;
       if (i != m_attributes.end ())
         {
           oss << "|";
@@ -235,8 +238,8 @@
                 value = str.substr (equal+1, next - (equal+1));
                 cur++;
               }
-            Attribute val = info.checker->Create ();
-            bool ok = val.DeserializeFromString (value, info.checker);
+            Ptr<AttributeValue> val = info.checker->Create ();
+            bool ok = val->DeserializeFromString (value, info.checker);
             if (!ok)
               {
                 // XXX invalid value
@@ -244,7 +247,7 @@
               }
             else
               {
-                DoSetOne (info.checker, val);
+                DoSetOne (info.checker, *val);
               }
           }
       }
--- a/src/core/attribute-list.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/attribute-list.h	Tue Apr 22 21:19:39 2008 -0700
@@ -48,14 +48,14 @@
    * value of that attribute. If any of these checks fails,
    * the program terminates with a message.
    */
-  void Set (std::string name, Attribute value);
+  void Set (std::string name, const AttributeValue &value);
   /**
    * \param name the full name of the attribute to set
    * \param value the value to set
    * \returns true if the requested attribute exists and could be
    *          stored, false otherwise.
    */
-  bool SetFailSafe (std::string name, Attribute value);
+  bool SetFailSafe (std::string name, const AttributeValue &value);
   /**
    * \param tid the TypeId associated to this attribute
    * \param name the name (not full!) of the attribute
@@ -66,7 +66,7 @@
    * value of that attribute. If any of these checks fails,
    * the program terminates with a message.
    */
-  void SetWithTid (TypeId tid, std::string name, Attribute value);
+  void SetWithTid (TypeId tid, std::string name, const AttributeValue &value);
 
   /**
    * Clear the content of this instance.
@@ -92,7 +92,7 @@
   friend class ObjectBase;
   struct Attr {
     Ptr<const AttributeChecker> checker;
-    Attribute value;
+    Ptr<const AttributeValue> value;
   };
   typedef std::vector<struct Attr> Attrs;
   typedef Attrs::iterator Iterator;
@@ -100,8 +100,8 @@
 
 
 
-  bool DoSet (struct TypeId::AttributeInfo *info, Attribute param);
-  void DoSetOne (Ptr<const AttributeChecker> checker, Attribute param);
+  bool DoSet (struct TypeId::AttributeInfo *info, const AttributeValue &param);
+  void DoSetOne (Ptr<const AttributeChecker> checker, const AttributeValue &param);
   std::string LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const;
 
   Attrs m_attributes;
--- a/src/core/attribute-test.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/attribute-test.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -30,6 +30,7 @@
 #include "object-vector.h"
 #include "traced-value.h"
 #include "trace-source-accessor.h"
+#include "pointer.h"
 
 namespace ns3 {
 
@@ -37,7 +38,6 @@
 {
 public:
   ValueClassTest () {}
-  ATTRIBUTE_HELPER_HEADER_1 (ValueClassTest);
 private:
   int m_v;
 };
@@ -90,7 +90,7 @@
 class AttributeObjectTest : public Object
 {
 public:
-  enum TestEnum {
+  enum Test_e {
     TEST_A,
     TEST_B,
     TEST_C
@@ -100,69 +100,65 @@
       .SetParent<Object> ()
       .HideFromDocumentation ()
       .AddAttribute ("TestBoolName", "help text",
-		     Boolean (false),
+		     BooleanValue (false),
 		     MakeBooleanAccessor (&AttributeObjectTest::m_boolTest),
 		     MakeBooleanChecker ())
       .AddAttribute ("TestBoolA", "help text",
-		     Boolean (false),
+		     BooleanValue (false),
 		     MakeBooleanAccessor (&AttributeObjectTest::DoSetTestB,
 					   &AttributeObjectTest::DoGetTestB),
 		     MakeBooleanChecker ())
-      .AddAttribute ("TestPtr", "help text", 
-		     Ptr<Derived> (0),
-		     MakePtrAccessor (&AttributeObjectTest::m_derived),
-		     MakePtrChecker<Derived> ())
       .AddAttribute ("TestInt16", "help text",
-		     Integer (-2),
+		     IntegerValue (-2),
 		     MakeIntegerAccessor (&AttributeObjectTest::m_int16),
 		     MakeIntegerChecker<int16_t> ())
       .AddAttribute ("TestInt16WithBounds", "help text",
-		     Integer (-2),
+		     IntegerValue (-2),
 		     MakeIntegerAccessor (&AttributeObjectTest::m_int16WithBounds),
 		     MakeIntegerChecker<int16_t> (-5, 10))
       .AddAttribute ("TestInt16SetGet", "help text",
-		     Integer (6),
+		     IntegerValue (6),
 		     MakeIntegerAccessor (&AttributeObjectTest::DoSetInt16,
 				       &AttributeObjectTest::DoGetInt16),
 		     MakeIntegerChecker<int16_t> ())
       .AddAttribute ("TestUint8", "help text",
-		     Uinteger (1),
+		     UintegerValue (1),
 		     MakeUintegerAccessor (&AttributeObjectTest::m_uint8),
 		     MakeUintegerChecker<uint8_t> ())
       .AddAttribute ("TestEnum", "help text",
-		     Enum (TEST_A),
+		     EnumValue (TEST_A),
 		     MakeEnumAccessor (&AttributeObjectTest::m_enum),
 		     MakeEnumChecker (TEST_A, "TestA",
 				      TEST_B, "TestB",
 				      TEST_C, "TestC"))
       .AddAttribute ("TestRandom", "help text",
-		     ConstantVariable (1.0),
+		     RandomVariableValue (ConstantVariable (1.0)),
 		     MakeRandomVariableAccessor (&AttributeObjectTest::m_random),
 		     MakeRandomVariableChecker ())
       .AddAttribute ("TestFloat", "help text",
-		     Double (-1.1),
+		     DoubleValue (-1.1),
 		     MakeDoubleAccessor (&AttributeObjectTest::m_float),
 		     MakeDoubleChecker<float> ())
       .AddAttribute ("TestVector1", "help text",
-		     ObjectVector (),
+		     ObjectVectorValue (),
 		     MakeObjectVectorAccessor (&AttributeObjectTest::m_vector1),
-		     MakeObjectVectorChecker ())
+		     MakeObjectVectorChecker<Derived> ())
       .AddAttribute ("TestVector2", "help text",
-		     ObjectVector (),
+		     ObjectVectorValue (),
 		     MakeObjectVectorAccessor (&AttributeObjectTest::DoGetVectorN,
 						&AttributeObjectTest::DoGetVector),
-		     MakeObjectVectorChecker ())
+		     MakeObjectVectorChecker<Derived> ())
       .AddAttribute ("IntegerTraceSource1", "help text",
-		     Integer (-2),
+		     IntegerValue (-2),
 		     MakeIntegerAccessor (&AttributeObjectTest::m_intSrc1),
 		     MakeIntegerChecker<int8_t> ())
       .AddAttribute ("IntegerTraceSource2", "help text",
-		     Integer (-2),
+		     IntegerValue (-2),
 		     MakeIntegerAccessor (&AttributeObjectTest::DoSetIntSrc,
 					  &AttributeObjectTest::DoGetIntSrc),
 		     MakeIntegerChecker<int8_t> ())
       .AddAttribute ("ValueClassSource", "help text",
-		     ValueClassTest (),
+		     ValueClassTestValue (ValueClassTest ()),
 		     MakeValueClassTestAccessor (&AttributeObjectTest::m_valueSrc),
 		     MakeValueClassTestChecker ())
       .AddTraceSource ("Source1", "help test",
@@ -171,6 +167,10 @@
 		       MakeTraceSourceAccessor (&AttributeObjectTest::m_cb))
       .AddTraceSource ("ValueSource", "help text",
 		       MakeTraceSourceAccessor (&AttributeObjectTest::m_valueSrc))
+      .AddAttribute ("Pointer", "XXX",
+                     PointerValue (),
+                     MakePointerAccessor (&AttributeObjectTest::m_ptr),
+                     MakePointerChecker<Derived> ())
       ;
         
     return tid;
@@ -214,13 +214,12 @@
   }
   bool m_boolTestA;
   bool m_boolTest;
-  Ptr<Derived> m_derived;
   int16_t m_int16;
   int16_t m_int16WithBounds;
   int16_t m_int16SetGet;
   uint8_t m_uint8;
   float m_float;
-  enum TestEnum m_enum;
+  enum Test_e m_enum;
   RandomVariable m_random;
   std::vector<Ptr<Derived> > m_vector1;
   std::vector<Ptr<Derived> > m_vector2;
@@ -228,25 +227,24 @@
   TracedValue<int8_t> m_intSrc2;
   TracedCallback<double, int, float> m_cb;
   TracedValue<ValueClassTest> m_valueSrc;
+  Ptr<Derived> m_ptr;
 };
 
 
-#define CHECK_GET_STR(p,name,value)                             \
-  {                                                             \
-    std::string expected = value;                               \
-    std::string got;                                            \
-    bool ok = p->GetAttributeAsStringFailSafe (name, got);	\
-    NS_TEST_ASSERT (ok);                                        \
-    NS_TEST_ASSERT_EQUAL (got, expected);                       \
+#define CHECK_GET_STR(p,name,value)                               \
+  {                                                               \
+    std::string expected = value;                                 \
+    StringValue got;                                              \
+    bool ok = p->GetAttributeFailSafe (name, got);                \
+    NS_TEST_ASSERT (ok);                                          \
+    NS_TEST_ASSERT_EQUAL (got.Get (), expected);                  \
   }
 #define CHECK_GET_PARAM(p,name,type,value)		\
   {							\
     const type expected = value;			\
-    type got = value;					\
-    Attribute v;                                        \
-    bool ok = p->GetAttributeFailSafe (name, v);        \
+    type got;                                           \
+    bool ok = p->GetAttributeFailSafe (name, got);      \
     NS_TEST_ASSERT (ok);                                \
-    got = v;                                            \
     NS_TEST_ASSERT_EQUAL (got.Get (), expected.Get ());	\
   }
 
@@ -262,211 +260,199 @@
 
   AttributeList params;
   Ptr<AttributeObjectTest> p;
-  NS_TEST_ASSERT (params.SetFailSafe ("ns3::AttributeObjectTest::TestBoolName", String ("false")));
+  NS_TEST_ASSERT (params.SetFailSafe ("ns3::AttributeObjectTest::TestBoolName", StringValue ("false")));
   p = CreateObject<AttributeObjectTest> (params);
   CHECK_GET_STR (p, "TestBoolName", "false");
-  CHECK_GET_PARAM (p, "TestBoolName", Boolean, false);
-
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestBoolName", String ("true")));
-  CHECK_GET_STR (p, "TestBoolName", "true");
-  CHECK_GET_PARAM (p, "TestBoolName", Boolean, true);
-
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestBoolName", Boolean (false)));
-  CHECK_GET_STR (p, "TestBoolName", "false");
-  CHECK_GET_PARAM (p, "TestBoolName", Boolean, false);
+  CHECK_GET_PARAM (p, "TestBoolName", BooleanValue, false);
 
-  p = CreateObject<AttributeObjectTest> ("TestBoolName", String ("true"));
-  CHECK_GET_STR (p, "TestBoolName", "true");
-  CHECK_GET_PARAM (p, "TestBoolName", Boolean, true);
-
-  p = CreateObject<AttributeObjectTest> ("TestBoolName", Boolean (true));
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestBoolName", StringValue ("true")));
   CHECK_GET_STR (p, "TestBoolName", "true");
-  CHECK_GET_PARAM (p, "TestBoolName", Boolean, true);
+  CHECK_GET_PARAM (p, "TestBoolName", BooleanValue, true);
 
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestBoolA", String ("false")));
-  CHECK_GET_STR (p, "TestBoolA", "false");
-  CHECK_GET_PARAM (p, "TestBoolA", Boolean, false);
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestBoolName", BooleanValue (false)));
+  CHECK_GET_STR (p, "TestBoolName", "false");
+  CHECK_GET_PARAM (p, "TestBoolName", BooleanValue, false);
 
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestBoolA", String ("true")));
-  CHECK_GET_STR (p, "TestBoolA", "true");
-  CHECK_GET_PARAM (p, "TestBoolA", Boolean, true);
+  p = CreateObject<AttributeObjectTest> ("TestBoolName", StringValue ("true"));
+  CHECK_GET_STR (p, "TestBoolName", "true");
+  CHECK_GET_PARAM (p, "TestBoolName", BooleanValue, true);
 
+  p = CreateObject<AttributeObjectTest> ("TestBoolName", BooleanValue (true));
+  CHECK_GET_STR (p, "TestBoolName", "true");
+  CHECK_GET_PARAM (p, "TestBoolName", BooleanValue, true);
 
-  Ptr<Derived> derived = p->GetAttribute ("TestPtr");
-  NS_TEST_ASSERT (derived == 0);
-  derived = Create<Derived> ();
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestPtr", derived));
-  Ptr<Derived> stored = p->GetAttribute ("TestPtr");
-  NS_TEST_ASSERT (stored == derived);
-  Ptr<Object> storedBase = p->GetAttribute ("TestPtr");
-  NS_TEST_ASSERT (stored == storedBase);
-  Ptr<AttributeObjectTest> x = p->GetAttribute ("TestPtr");
-  NS_TEST_ASSERT (x == 0);
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestBoolA", StringValue ("false")));
+  CHECK_GET_STR (p, "TestBoolA", "false");
+  CHECK_GET_PARAM (p, "TestBoolA", BooleanValue, false);
 
-  p = CreateObject<AttributeObjectTest> ("TestPtr", Create<Derived> ());
-  NS_TEST_ASSERT (p != 0);
-  derived = 0;
-  derived = p->GetAttribute ("TestPtr");
-  NS_TEST_ASSERT (derived != 0);
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestBoolA", StringValue ("true")));
+  CHECK_GET_STR (p, "TestBoolA", "true");
+  CHECK_GET_PARAM (p, "TestBoolA", BooleanValue, true);
+
 
   CHECK_GET_STR (p, "TestInt16", "-2");
-  CHECK_GET_PARAM (p, "TestInt16", Integer, -2);
+  CHECK_GET_PARAM (p, "TestInt16", IntegerValue, -2);
 
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16", String ("-5")));
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16", StringValue ("-5")));
   CHECK_GET_STR (p, "TestInt16", "-5");
-  CHECK_GET_PARAM (p, "TestInt16", Integer, -5);
+  CHECK_GET_PARAM (p, "TestInt16", IntegerValue, -5);
 
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16", Integer (+2)));
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16", IntegerValue (+2)));
   CHECK_GET_STR (p, "TestInt16", "2");
-  CHECK_GET_PARAM (p, "TestInt16", Integer, +2);
+  CHECK_GET_PARAM (p, "TestInt16", IntegerValue, +2);
 
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16", Integer (-32768)));
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16", IntegerValue (-32768)));
   CHECK_GET_STR (p, "TestInt16", "-32768");
-  CHECK_GET_PARAM (p, "TestInt16", Integer, -32768);
+  CHECK_GET_PARAM (p, "TestInt16", IntegerValue, -32768);
 
-  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestInt16", Integer (-32769)));
+  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestInt16", IntegerValue (-32769)));
   CHECK_GET_STR (p, "TestInt16", "-32768");
-  CHECK_GET_PARAM (p, "TestInt16", Integer, -32768);
+  CHECK_GET_PARAM (p, "TestInt16", IntegerValue, -32768);
 
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16", Integer (32767)));
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16", IntegerValue (32767)));
   CHECK_GET_STR (p, "TestInt16", "32767");
-  CHECK_GET_PARAM (p, "TestInt16", Integer, 32767);
+  CHECK_GET_PARAM (p, "TestInt16", IntegerValue, 32767);
 
-  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestInt16", Integer (32768)));
+  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestInt16", IntegerValue (32768)));
   CHECK_GET_STR (p, "TestInt16", "32767");
-  CHECK_GET_PARAM (p, "TestInt16", Integer, 32767);
+  CHECK_GET_PARAM (p, "TestInt16", IntegerValue, 32767);
 
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16WithBounds", Integer (10)));
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue (10)));
   CHECK_GET_STR (p, "TestInt16WithBounds", "10");
-  CHECK_GET_PARAM (p, "TestInt16WithBounds", Integer, 10);
-  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestInt16WithBounds", Integer (11)));
+  CHECK_GET_PARAM (p, "TestInt16WithBounds", IntegerValue, 10);
+  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue (11)));
   CHECK_GET_STR (p, "TestInt16WithBounds", "10");
-  CHECK_GET_PARAM (p, "TestInt16WithBounds", Integer, 10);
+  CHECK_GET_PARAM (p, "TestInt16WithBounds", IntegerValue, 10);
 
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16WithBounds", Integer (-5)));
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue (-5)));
   CHECK_GET_STR (p, "TestInt16WithBounds", "-5");
-  CHECK_GET_PARAM (p, "TestInt16WithBounds", Integer, -5);
-  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestInt16WithBounds", Integer (-6)));
+  CHECK_GET_PARAM (p, "TestInt16WithBounds", IntegerValue, -5);
+  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestInt16WithBounds", IntegerValue (-6)));
   CHECK_GET_STR (p, "TestInt16WithBounds", "-5");
-  CHECK_GET_PARAM (p, "TestInt16WithBounds", Integer, -5);
+  CHECK_GET_PARAM (p, "TestInt16WithBounds", IntegerValue, -5);
 
   CHECK_GET_STR (p, "TestInt16SetGet", "6");
-  CHECK_GET_PARAM (p, "TestInt16SetGet", Integer, 6);
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16SetGet", Integer (0)));
+  CHECK_GET_PARAM (p, "TestInt16SetGet", IntegerValue, 6);
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestInt16SetGet", IntegerValue (0)));
   CHECK_GET_STR (p, "TestInt16SetGet", "0");
-  CHECK_GET_PARAM (p, "TestInt16SetGet", Integer, 0);
+  CHECK_GET_PARAM (p, "TestInt16SetGet", IntegerValue, 0);
 
   CHECK_GET_STR (p, "TestUint8", "1");
-  CHECK_GET_PARAM (p, "TestUint8", Uinteger, 1);
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestUint8", Uinteger (0)));
+  CHECK_GET_PARAM (p, "TestUint8", UintegerValue, 1);
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestUint8", UintegerValue (0)));
   CHECK_GET_STR (p, "TestUint8", "0");
-  CHECK_GET_PARAM (p, "TestUint8", Uinteger, 0);
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestUint8", Uinteger (255)));
+  CHECK_GET_PARAM (p, "TestUint8", UintegerValue, 0);
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestUint8", UintegerValue (255)));
   CHECK_GET_STR (p, "TestUint8", "255");
-  CHECK_GET_PARAM (p, "TestUint8", Uinteger, 255);
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestUint8", String ("255")));
+  CHECK_GET_PARAM (p, "TestUint8", UintegerValue, 255);
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestUint8", StringValue ("255")));
   CHECK_GET_STR (p, "TestUint8", "255");
-  CHECK_GET_PARAM (p, "TestUint8", Uinteger, 255);
-  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestUint8", String ("256")));
+  CHECK_GET_PARAM (p, "TestUint8", UintegerValue, 255);
+  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestUint8", StringValue ("256")));
   CHECK_GET_STR (p, "TestUint8", "255");
-  CHECK_GET_PARAM (p, "TestUint8", Uinteger, 255);
-  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestUint8", String ("-1")));
+  CHECK_GET_PARAM (p, "TestUint8", UintegerValue, 255);
+  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestUint8", StringValue ("-1")));
   CHECK_GET_STR (p, "TestUint8", "255");
-  CHECK_GET_PARAM (p, "TestUint8", Uinteger, 255);
-  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestUint8", Uinteger ((uint64_t)-1)));
+  CHECK_GET_PARAM (p, "TestUint8", UintegerValue, 255);
+  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestUint8", UintegerValue ((uint64_t)-1)));
   CHECK_GET_STR (p, "TestUint8", "255");
-  CHECK_GET_PARAM (p, "TestUint8", Uinteger, 255);
+  CHECK_GET_PARAM (p, "TestUint8", UintegerValue, 255);
 
   CHECK_GET_STR (p, "TestFloat", "-1.1");
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestFloat", Double ((float)+2.3)));
-  CHECK_GET_PARAM (p, "TestFloat", Double, (float)+2.3);
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestFloat", DoubleValue ((float)+2.3)));
+  CHECK_GET_PARAM (p, "TestFloat", DoubleValue, (float)+2.3);
 
   CHECK_GET_STR (p, "TestEnum", "TestA");
-  CHECK_GET_PARAM (p, "TestEnum", Enum, AttributeObjectTest::TEST_A);
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestEnum", Enum (AttributeObjectTest::TEST_C)));
+  CHECK_GET_PARAM (p, "TestEnum", EnumValue, AttributeObjectTest::TEST_A);
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestEnum", EnumValue (AttributeObjectTest::TEST_C)));
   CHECK_GET_STR (p, "TestEnum", "TestC");
-  CHECK_GET_PARAM (p, "TestEnum", Enum, AttributeObjectTest::TEST_C);
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestEnum", String ("TestB")));
+  CHECK_GET_PARAM (p, "TestEnum", EnumValue, AttributeObjectTest::TEST_C);
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestEnum", StringValue ("TestB")));
   CHECK_GET_STR (p, "TestEnum", "TestB");
-  CHECK_GET_PARAM (p, "TestEnum", Enum, AttributeObjectTest::TEST_B);
-  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestEnum", String ("TestD")));
+  CHECK_GET_PARAM (p, "TestEnum", EnumValue, AttributeObjectTest::TEST_B);
+  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestEnum", StringValue ("TestD")));
   CHECK_GET_STR (p, "TestEnum", "TestB");
-  CHECK_GET_PARAM (p, "TestEnum", Enum, AttributeObjectTest::TEST_B);
-  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestEnum", Enum (5)));
+  CHECK_GET_PARAM (p, "TestEnum", EnumValue, AttributeObjectTest::TEST_B);
+  NS_TEST_ASSERT (!p->SetAttributeFailSafe("TestEnum", EnumValue (5)));
   CHECK_GET_STR (p, "TestEnum", "TestB");
-  CHECK_GET_PARAM (p, "TestEnum", Enum, AttributeObjectTest::TEST_B);
+  CHECK_GET_PARAM (p, "TestEnum", EnumValue, AttributeObjectTest::TEST_B);
 
-  RandomVariable ran = p->GetAttribute ("TestRandom");
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestRandom", UniformVariable (0.0, 1.0)));
-  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestRandom", ConstantVariable (10.0)));
+  RandomVariableValue ran;
+  p->GetAttribute ("TestRandom", ran);
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestRandom", RandomVariableValue (UniformVariable (0.0, 1.0))));
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("TestRandom", RandomVariableValue (ConstantVariable (10.0))));
 
   {
-    ObjectVector vector = p->GetAttribute ("TestVector1");
+    ObjectVectorValue vector;
+    p->GetAttribute ("TestVector1", vector);
     NS_TEST_ASSERT_EQUAL (vector.GetN (), 0);
     p->AddToVector1 ();
     NS_TEST_ASSERT_EQUAL (vector.GetN (), 0);
-    vector = p->GetAttribute ("TestVector1");
+    p->GetAttribute ("TestVector1", vector);
     NS_TEST_ASSERT_EQUAL (vector.GetN (), 1);
     Ptr<Object> a = vector.Get (0);
     NS_TEST_ASSERT_UNEQUAL (a, 0);
     p->AddToVector1 ();
     NS_TEST_ASSERT_EQUAL (vector.GetN (), 1);
-    vector = p->GetAttribute ("TestVector1");
+    p->GetAttribute ("TestVector1", vector);
     NS_TEST_ASSERT_EQUAL (vector.GetN (), 2);
   }
 
   {
-    ObjectVector vector = p->GetAttribute ("TestVector2");
+    ObjectVectorValue vector;
+    p->GetAttribute ("TestVector2", vector);
     NS_TEST_ASSERT_EQUAL (vector.GetN (), 0);
     p->AddToVector2 ();
     NS_TEST_ASSERT_EQUAL (vector.GetN (), 0);
-    vector = p->GetAttribute ("TestVector2");
+    p->GetAttribute ("TestVector2", vector);
     NS_TEST_ASSERT_EQUAL (vector.GetN (), 1);
     Ptr<Object> a = vector.Get (0);
     NS_TEST_ASSERT_UNEQUAL (a, 0);
     p->AddToVector2 ();
     NS_TEST_ASSERT_EQUAL (vector.GetN (), 1);
-    vector = p->GetAttribute ("TestVector2");
+    p->GetAttribute ("TestVector2", vector);
     NS_TEST_ASSERT_EQUAL (vector.GetN (), 2);
   }
 
-  NS_TEST_ASSERT (AttributeList::GetGlobal ()->SetFailSafe ("ns3::AttributeObjectTest::TestBoolName", String ("true")));
+  NS_TEST_ASSERT (AttributeList::GetGlobal ()->SetFailSafe ("ns3::AttributeObjectTest::TestBoolName", StringValue ("true")));
   p = CreateObject<AttributeObjectTest> ();
-  Boolean boolV = p->GetAttribute ("TestBoolName");
-  NS_TEST_ASSERT_EQUAL (boolV, Boolean (true));
+  BooleanValue boolV;
+  p->GetAttribute ("TestBoolName", boolV);
+  NS_TEST_ASSERT_EQUAL (boolV.Get (), true);
 
-  NS_TEST_ASSERT (AttributeList::GetGlobal ()->SetFailSafe ("ns3::AttributeObjectTest::TestBoolName", String ("false")));
+  NS_TEST_ASSERT (AttributeList::GetGlobal ()->SetFailSafe ("ns3::AttributeObjectTest::TestBoolName", StringValue ("false")));
   p = CreateObject<AttributeObjectTest> ();
-  boolV = p->GetAttribute ("TestBoolName");
-  NS_TEST_ASSERT_EQUAL (boolV, Boolean (false));
+  p->GetAttribute ("TestBoolName", boolV);
+  NS_TEST_ASSERT_EQUAL (boolV.Get (), false);
 
-  Integer i = p->GetAttribute ("IntegerTraceSource1");
+  IntegerValue i;
+  p->GetAttribute ("IntegerTraceSource1", i);
   NS_TEST_ASSERT_EQUAL (i.Get (), -2);
-  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", Integer (+5)));
-  i = p->GetAttribute ("IntegerTraceSource1");
+  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (+5)));
+  p->GetAttribute ("IntegerTraceSource1", i);
   NS_TEST_ASSERT_EQUAL (i.Get (), +5);
-  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", Integer (127)));
-  NS_TEST_ASSERT (!p->SetAttributeFailSafe ("IntegerTraceSource1", Integer (128)));
-  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", Integer (-128)));
-  NS_TEST_ASSERT (!p->SetAttributeFailSafe ("IntegerTraceSource1", Integer (-129)));
+  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (127)));
+  NS_TEST_ASSERT (!p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (128)));
+  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (-128)));
+  NS_TEST_ASSERT (!p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (-129)));
 
-  i = p->GetAttribute ("IntegerTraceSource2");
+  p->GetAttribute ("IntegerTraceSource2", i);
   NS_TEST_ASSERT_EQUAL (i.Get (), -2);
-  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource2", Integer (+5)));
-  i = p->GetAttribute ("IntegerTraceSource2");
+  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (+5)));
+  p->GetAttribute ("IntegerTraceSource2", i);
   NS_TEST_ASSERT_EQUAL (i.Get (), +5);
-  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource2", Integer (127)));
-  NS_TEST_ASSERT (!p->SetAttributeFailSafe ("IntegerTraceSource2", Integer (128)));
-  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource2", Integer (-128)));
-  NS_TEST_ASSERT (!p->SetAttributeFailSafe ("IntegerTraceSource2", Integer (-129)));
+  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (127)));
+  NS_TEST_ASSERT (!p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (128)));
+  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (-128)));
+  NS_TEST_ASSERT (!p->SetAttributeFailSafe ("IntegerTraceSource2", IntegerValue (-129)));
 
   m_got1 = -2;
-  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", Integer (-1)));
+  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (-1)));
   NS_TEST_ASSERT (p->TraceConnectWithoutContext ("Source1", MakeCallback (&AttributeTest::NotifySource1, this)));
-  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", Integer (0)));
+  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (0)));
   NS_TEST_ASSERT_EQUAL (m_got1, 0);
   NS_TEST_ASSERT (p->TraceDisconnectWithoutContext ("Source1", MakeCallback (&AttributeTest::NotifySource1, this)));
-  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", Integer (1)));
+  NS_TEST_ASSERT (p->SetAttributeFailSafe ("IntegerTraceSource1", IntegerValue (1)));
   NS_TEST_ASSERT_EQUAL (m_got1, 0);
 
   m_got2 = 4.3;
@@ -481,8 +467,29 @@
   NS_TEST_ASSERT_EQUAL (m_got2, 1.0);
 
   NS_TEST_ASSERT (p->TraceConnectWithoutContext ("ValueSource", MakeCallback (&AttributeTest::NotifySourceValue, this)));
-  
 
+  PointerValue ptr;
+  p->GetAttribute ("Pointer", ptr);
+  Ptr<Derived> derived = ptr.Get<Derived> ();
+  NS_TEST_ASSERT (derived == 0);
+  derived = Create<Derived> ();
+  NS_TEST_ASSERT (p->SetAttributeFailSafe("Pointer", PointerValue (derived)));
+  p->GetAttribute ("Pointer", ptr);
+  Ptr<Derived> stored = ptr.Get<Derived> ();
+  NS_TEST_ASSERT (stored == derived);
+  p->GetAttribute ("Pointer", ptr);
+  Ptr<Object> storedBase = ptr.Get<Object> ();
+  NS_TEST_ASSERT (stored == storedBase);
+  p->GetAttribute ("Pointer", ptr);
+  Ptr<AttributeObjectTest> x = ptr.Get<AttributeObjectTest> ();
+  NS_TEST_ASSERT (x == 0);
+
+  p = CreateObject<AttributeObjectTest> ("Pointer", PointerValue (Create<Derived> ()));
+  NS_TEST_ASSERT (p != 0);
+  derived = 0;
+  p->GetAttribute ("Pointer", ptr);
+  derived = ptr.Get<Derived> ();
+  NS_TEST_ASSERT (derived != 0);
 
   return result;
 }
--- a/src/core/attribute.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/attribute.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -27,164 +27,38 @@
 namespace ns3 {
 
 AttributeValue::AttributeValue ()
-  : m_count (1)
 {}
-AttributeValue::AttributeValue (const AttributeValue &o)
-  : m_count (1)
-{}
-AttributeValue &
-AttributeValue::operator = (const AttributeValue &o)
-{
-  return *this;
-}
 AttributeValue::~AttributeValue ()
 {}
 
-/***************************************************************
- *   Big interesting warning.
- *   ------------------------
- *
- * One might wonder why we re-implement a smart pointer below 
- * in the Attribute class. This is a very good question and the answer
- * is unfortunately pretty complicated.
- *
- * 1) We could have requested the user to use Ptr<AttributeValue> and save us
- *    a lot of pain. This, however, does not work because our smart 
- *    pointer needs a special constructor which can be used to convert
- *    objects of type Ptr<T> into a PtrValue<T> to hold the pointer.
- *
- * 2) We could have made the m_value member variable below a Ptr<AttributeValue>
- *    rather than store a raw pointer. This, however, does not work
- *    because this would mean that the constructor Attribute (AttributeValue *)
- *    should be morphed into Attribute (Ptr<AttributeValue>) which, unfortunately,
- *    would conflict with the template constructor Attribute (Ptr<T>)...
- *
- * This is definitely not fun.   
- */
-Attribute::Attribute ()
-  : m_value (0)
-{}
-Attribute::Attribute (const Attribute &o)
-  : m_value (o.m_value)
-{
-  if (m_value != 0)
-    {
-      m_value->m_count++;
-      NS_LOG_DEBUG ("this="<<m_value<<" ++count="<<m_value->m_count);
-    }
-}
-Attribute &
-Attribute::operator = (const Attribute &o)
-{
-  if (&o != this)
-    {
-      if (m_value != 0)
-	{
-	  m_value->m_count--;
-	  NS_LOG_DEBUG ("this="<<m_value<<" --count="<<m_value->m_count);
-	  if (m_value->m_count == 0)
-	    {
-	      delete m_value;
-	      m_value = 0;
-	    }
-	}
-      m_value = o.m_value;
-      if (m_value != 0)
-	{
-	  m_value->m_count++;
-	  NS_LOG_DEBUG ("this="<<m_value<<" ++count="<<m_value->m_count);
-	}
-    }
-  return *this;
-}
-Attribute::~Attribute ()
-{
-  if (m_value != 0) 
-    {
-      m_value->m_count--;
-      NS_LOG_DEBUG ("this="<<m_value<<" --count="<<m_value->m_count);
-      if (m_value->m_count == 0)
-	{
-	  delete m_value;
-	  m_value = 0;
-	}
-    }
-}
-Attribute::Attribute (AttributeValue *value)
-  : m_value (value)
-{
-  NS_LOG_DEBUG ("this="<<m_value<<" count="<<((m_value!=0)?m_value->m_count:666));
-}
-
-Attribute 
-Attribute::Copy (void) const
-{
-  return m_value->Copy ();
-}
-std::string 
-Attribute::SerializeToString (Ptr<const AttributeChecker> checker) const
-{
-  return m_value->SerializeToString (checker);
-}
-bool 
-Attribute::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker)
-{
-  return m_value->DeserializeFromString (value, checker);
-}
 
 AttributeAccessor::AttributeAccessor ()
-  : m_count (1)
 {}
-void 
-AttributeAccessor::Ref (void) const
-{
-  m_count++;
-}
-void 
-AttributeAccessor::Unref (void) const
-{
-  m_count--;
-  if (m_count == 0)
-    {
-      delete this;
-    }
-}
 AttributeAccessor::~AttributeAccessor ()
 {}
 
 AttributeChecker::AttributeChecker ()
-  : m_count (1)
 {}
-void 
-AttributeChecker::Ref (void) const
-{
-  m_count++;
-}
-void 
-AttributeChecker::Unref (void) const
-{
-  m_count--;
-  if (m_count == 0)
-    {
-      delete this;
-    }
-}
 AttributeChecker::~AttributeChecker ()
 {}
 
-std::string 
-PtrValueBase::SerializeToString (Ptr<const AttributeChecker> checker) const
+EmptyAttributeValue::EmptyAttributeValue ()
+{}
+Ptr<AttributeValue> 
+EmptyAttributeValue::Copy (void) const
 {
-  std::ostringstream oss;
-  oss << PeekObjectBase ();
-  return oss.str ();
+  return Create<EmptyAttributeValue> ();
+}
+std::string 
+EmptyAttributeValue::SerializeToString (Ptr<const AttributeChecker> checker) const
+{
+  return "";
+}
+bool 
+EmptyAttributeValue::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker)
+{
+  return true;
 }
 
-bool 
-PtrValueBase::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker)
-{
-  // XXX
-  return false;
-}
 
 } // namespace ns3
--- a/src/core/attribute.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/attribute.h	Tue Apr 22 21:19:39 2008 -0700
@@ -23,6 +23,7 @@
 #include <string>
 #include <stdint.h>
 #include "ptr.h"
+#include "ref-count-base.h"
 
 namespace ns3 {
 
@@ -34,23 +35,20 @@
 /**
  * \brief Hold a value for an Attribute.
  *
- * Instances of this class are usually created by Attribute::Create<> and
- * should always be wrapped into an Attribute object.
+ * Instances of this class should always be wrapped into an Attribute object.
  * Most subclasses of this base class are implemented by the 
  * ATTRIBUTE_HELPER_* macros.
  */
-class AttributeValue
+class AttributeValue : public RefCountBase
 {
 public:
   AttributeValue ();
-  AttributeValue (const AttributeValue &o);
-  AttributeValue &operator = (const AttributeValue &o);
   virtual ~AttributeValue ();
 
   /**
    * \returns a deep copy of this class, wrapped into an Attribute object.
    */
-  virtual Attribute Copy (void) const = 0;
+  virtual Ptr<AttributeValue> Copy (void) const = 0;
   /**
    * \param checker the checker associated to the attribute
    * \returns a string representation of this value.
@@ -75,80 +73,6 @@
    * the EnumValue::SerializeToString code.
    */
   virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker) = 0;
-private:
-  friend class Attribute;
-  uint32_t m_count;
-};
-
-/**
- * \brief an opaque wrapper around a value to set or retrieved
- *        from an attribute.
- *
- * This class is really a smart pointer to an instance of AttributeValue.
- * Of course, the question is "why not use a Ptr<AttributeValue>" ?. The 
- * answer is long and complicated but the crux of the issue is that if we
- * do not reproduce the smart pointer code in this class, we cannot provide
- * transparent handling of Ptr<T> values through the attribute system.
- */
-class Attribute
-{
-public:
-  Attribute ();
-  Attribute (const Attribute &o);
-  Attribute &operator = (const Attribute &o);
-  ~Attribute ();
-
-  /**
-   * Forward to AttributeValue::Copy
-   */
-  Attribute Copy (void) const;
-  /**
-   * Forward to AttributeValue::SerializeToString
-   */
-  std::string SerializeToString (Ptr<const AttributeChecker> checker) const;
-  /**
-   * Forward to AttributeValue::DeserializeFromString
-   */
-  bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker);
-
-  /**
-   * \returns a new Attribute object which wraps an instance of the requested
-   * subclass of AttributeValue.
-   */
-  template <typename T>
-  static Attribute Create (void);
-  /**
-   * \param a1 a value to pass through to the constructor of the class T.
-   * \returns a new Attribute object which wraps an instance of the requested
-   * subclass of AttributeValue.
-   */
-  template <typename T, typename T1>
-  static Attribute Create (T1 a1);
-
-  /**
-   * This method performs a dynamic_cast on the underlying AttributeValue.
-   * This method is typically used to implement conversion operators
-   * from the type Attribute. In most cases, these conversion operators
-   * will be generated for you by the ATTRIBUTE_HELPER_* macros.
-   * \returns the casted pointer.
-   */
-  template <typename T>
-  T DynCast (void) const;
-
-  /**
-   * \param pointer a pointer to convert into an Attribute.
-   */
-  template <typename T>
-  Attribute (Ptr<T> pointer);
-  /**
-   * \returns a pointer converted from this Attribute instance.
-   */
-  template <typename T>
-  operator Ptr<T> ();
-
-private:
-  Attribute (AttributeValue *value);
-  AttributeValue *m_value;
 };
 
 /**
@@ -159,12 +83,10 @@
  * of this base class are usually provided through the MakeAccessorHelper
  * template functions, hidden behind an ATTRIBUTE_HELPER_* macro.
  */
-class AttributeAccessor
+class AttributeAccessor : public RefCountBase
 {
 public:
   AttributeAccessor ();
-  void Ref (void) const;
-  void Unref (void) const;
   virtual ~AttributeAccessor ();
 
   /**
@@ -175,7 +97,7 @@
    * This method expects that the caller has checked that the input value is
    * valid with AttributeChecker::Check.
    */
-  virtual bool Set (ObjectBase * object, Attribute value) const = 0;
+  virtual bool Set (ObjectBase * object, const AttributeValue &value) const = 0;
   /**
    * \param object the object instance to get the value from
    * \param attribute a pointer to where the value should be set.
@@ -185,9 +107,18 @@
    * This method expects that the caller has checked that the input value is
    * valid with AttributeChecker::Check.
    */
-  virtual bool Get (const ObjectBase * object, Attribute attribute) const = 0;
-private:
-  mutable uint32_t m_count;
+  virtual bool Get (const ObjectBase * object, AttributeValue &attribute) const = 0;
+
+  /**
+   * \return true if this accessor supports the Get operation, false
+   *         otherwise.
+   */
+  virtual bool HasGetter (void) const = 0;
+  /**
+   * \return true if this accessor supports the Set operation, false
+   *         otherwise.
+   */
+  virtual bool HasSetter (void) const = 0;
 };
 
 /**
@@ -202,12 +133,10 @@
  * Most subclasses of this base class are implemented by the 
  * ATTRIBUTE_HELPER_* macros.
  */
-class AttributeChecker
+class AttributeChecker : public RefCountBase
 {
 public:
   AttributeChecker ();
-  void Ref (void) const;
-  void Unref (void) const;
   virtual ~AttributeChecker ();
   /**
    * \param value a pointer to the value to check
@@ -215,10 +144,29 @@
    *          and if its value is within the requested range. Returns
    *          false otherwise.
    */
-  virtual bool Check (Attribute value) const = 0;
-  virtual std::string GetType (void) const = 0;
-  virtual bool HasTypeConstraints (void) const = 0;
-  virtual std::string GetTypeConstraints (void) const = 0;
+  virtual bool Check (const AttributeValue &value) const = 0;
+  /**
+   * \returns the c++ fully-qualified typename of the subclass
+   *          of the ns3::AttributeValue base class which is associated
+   *          to this checker.
+   *
+   * A typical return value here is FooValue where Foo is the name of the
+   * type being wrapped.
+   */
+  virtual std::string GetValueTypeName (void) const = 0;
+  /**
+   * \returns true if this checker has information about the underlying
+   *          C++ type, false otherwise.
+   *
+   * If this method returns false, the return value of the GetUnderlyingTypeInformation
+   * method cannot be relied upon.
+   */
+  virtual bool HasUnderlyingTypeInformation (void) const = 0;
+  /**
+   * \returns a human-readable representation of information about
+   *          the underlying C++ type.
+   */
+  virtual std::string GetUnderlyingTypeInformation (void) const = 0;
   /**
    * \returns a new instance of an AttributeValue (wrapper in an Attribute 
    *          instance) which matches the type of the underlying attribute.
@@ -226,314 +174,22 @@
    * This method is typically used to create a temporary variable prior
    * to calling Attribute::DeserializeFromString.
    */
-  virtual Attribute Create (void) const = 0;
-private:
-  mutable uint32_t m_count;
+  virtual Ptr<AttributeValue> Create (void) const = 0;
+
+  virtual bool Copy (const AttributeValue &source, AttributeValue &destination) const = 0;
+
 };
 
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePtrAccessor (Ptr<U> T::*memberVariable);
-
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePtrAccessor (void (T::*setter) (Ptr<U>));
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePtrAccessor (Ptr<U> (T::*getter) (void) const);
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePtrAccessor (void (T::*setter) (Ptr<U>),
-                 Ptr<U> (T::*getter) (void) const);
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePtrAccessor (Ptr<U> (T::*getter) (void) const,
-                 void (T::*setter) (Ptr<U>));
-
-
-
-class PtrChecker : public AttributeChecker {};
-
-template <typename T>
-Ptr<AttributeChecker> MakePtrChecker (void);
-
-
-
-} // namespace ns3
-
-namespace ns3 {
-
-/********************************************************
- *   The class used to access the pointer stored in a
- *   PtrValue<T> AttributeValue instance.
- ********************************************************/
-
-class PtrValueBase : public AttributeValue
+class EmptyAttributeValue : public AttributeValue
 {
 public:
-  virtual ObjectBase *PeekObjectBase (void) const = 0;
-  virtual bool SetObjectBase (ObjectBase *object) = 0;
+  EmptyAttributeValue ();
+private:
+  virtual Ptr<AttributeValue> Copy (void) const;
   virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const;
   virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker);
 };
 
-/********************************************************
- *        Store the content of a Ptr<T> in a AttributeValue
- ********************************************************/
-
-namespace internal {
-
-template <typename T>
-class PtrValue : public PtrValueBase
-{
-public:
-  PtrValue () 
-    : m_pointer () {}
-  PtrValue (Ptr<T> pointer) 
-    : m_pointer (pointer) {}
-
-  virtual ObjectBase *PeekObjectBase (void) const {
-    return PeekPointer (m_pointer);
-  }
-  virtual bool SetObjectBase (ObjectBase *object) {
-    T *ptr = dynamic_cast<T *> (object);
-    if (ptr == 0)
-      {
-	return false;
-      }
-    m_pointer = ptr;
-    return true;
-  }
-  virtual Attribute Copy (void) const {
-    return Attribute::Create<PtrValue<T> > (*this);
-  }
-private:
-  Ptr<T> m_pointer;
-};
-
-template <typename T>
-class APtrChecker : public PtrChecker
-{
-  virtual bool Check (Attribute val) const {
-    const PtrValueBase *value = val.DynCast<const PtrValueBase *> ();
-    if (value == 0)
-      {
-	return false;
-      }
-    if (value->PeekObjectBase () == 0)
-      {
-	return true;
-      }
-    T *ptr = dynamic_cast<T*> (value->PeekObjectBase ());
-    if (ptr == 0)
-      {
-	return false;
-      }
-    return true;
-  }
-  virtual std::string GetType (void) const {
-    // XXX: we should be able to return better information
-    return "Ptr<>";
-  }
-  virtual bool HasTypeConstraints (void) const {
-    return false;
-  }
-  virtual std::string GetTypeConstraints (void) const {
-    return "";
-  }
-  virtual Attribute Create (void) const {
-    return Attribute::Create<PtrValue<T> > ();
-  }
-};
-
-/********************************************************
- *              The Accessor associated to 
- *               PtrValue<T>
- ********************************************************/
-
-template <typename T, typename U>
-class PtrAccessor : public AttributeAccessor
-{
-public:
-  virtual ~PtrAccessor () {}
-  virtual bool Set (ObjectBase * object, Attribute val) const {
-      T *obj = dynamic_cast<T *> (object);
-      if (obj == 0)
-        {
-          return false;
-        }
-      const PtrValueBase *value = val.DynCast<const PtrValueBase *> ();
-      if (value == 0)
-        {
-          return false;
-        }
-      Ptr<U> ptr = dynamic_cast<U*> (value->PeekObjectBase ());
-      if (ptr == 0)
-        {
-          return false;
-        }
-      DoSet (obj, ptr);
-      return true;
-    }
-  virtual bool Get (const ObjectBase * object, Attribute val) const {
-      const T *obj = dynamic_cast<const T *> (object);
-      if (obj == 0)
-        {
-          return false;
-        }
-      PtrValueBase *value = val.DynCast<PtrValueBase *> ();
-      if (value == 0)
-        {
-          return false;
-        }
-      return value->SetObjectBase (PeekPointer (DoGet (obj)));
-    }
-private:
-  virtual void DoSet (T *object, Ptr<U> value) const = 0;
-  virtual Ptr<U> DoGet (const T *object) const = 0;
-};
-
-} // namespace internal
-
-/********************************************************
- *        The implementation of the Attribute 
- *          class template methods.
- ********************************************************/
-
-template <typename T>
-Attribute 
-Attribute::Create (void)
-{
-  return Attribute (new T ());
-}
-template <typename T, typename T1>
-Attribute 
-Attribute::Create (T1 a1)
-{
-  return Attribute (new T (a1));
-}
-
-template <typename T>
-T
-Attribute::DynCast (void) const
-{
-  return dynamic_cast<T> (m_value);
-}
-
-template <typename T>
-Attribute::Attribute (Ptr<T> pointer)
-  : m_value (new internal::PtrValue<T> (pointer))
-{}
-template <typename T>
-Attribute::operator Ptr<T> ()
-{
-  PtrValueBase *value = DynCast<PtrValueBase *> ();
-  if (value == 0)
-    {
-      return 0;
-    }
-  ObjectBase *objectBase = value->PeekObjectBase ();
-  T *obj = dynamic_cast<T *> (objectBase);
-  if (obj == 0)
-    {
-      return 0;
-    }
-  return obj;
-}
-
-
-
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePtrAccessor (Ptr<U> T::*memberVariable)
-{
-  struct MemberVariable : public internal::PtrAccessor<T,U>
-  {
-    Ptr<U> T::*m_memberVariable;
-    virtual void DoSet (T *object, Ptr<U> value) const {
-      (object->*m_memberVariable) = value;
-    }
-    virtual Ptr<U> DoGet (const T *object) const {
-      return object->*m_memberVariable;
-    }
-  } *spec = new MemberVariable ();
-  spec->m_memberVariable = memberVariable;
-  return Ptr<const AttributeAccessor> (spec, false);
-}
-
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePtrAccessor (void (T::*setter) (Ptr<U>))
-{
-  struct MemberMethod : public internal::PtrAccessor<T,U>
-  {
-    void (T::*m_setter) (Ptr<U>);
-    virtual void DoSet (T *object, Ptr<U> value) const {
-      (object->*m_setter) (value);
-    }
-    virtual Ptr<U> DoGet (const T *object) const {
-      return 0;
-      //return (object->*m_getter) ();
-    }
-  } *spec = new MemberMethod ();
-  spec->m_setter = setter;
-  return Ptr<const AttributeAccessor> (spec, false);
-}
-
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePtrAccessor (Ptr<U> (T::*getter) (void) const)
-{
-  struct MemberMethod : public internal::PtrAccessor<T,U>
-  {
-    Ptr<U> (T::*m_getter) (void) const;
-    virtual void DoSet (T *object, Ptr<U> value) const {
-      //(object->*m_setter) (value);
-    }
-    virtual Ptr<U> DoGet (const T *object) const {
-      return (object->*m_getter) ();
-    }
-  } *spec = new MemberMethod ();
-  spec->m_getter = getter;
-  return Ptr<const AttributeAccessor> (spec, false);
-}
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePtrAccessor (void (T::*setter) (Ptr<U>),
-                 Ptr<U> (T::*getter) (void) const)
-{
-  return MakePtrAccessor (getter, setter);
-}
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePtrAccessor (Ptr<U> (T::*getter) (void) const,
-                 void (T::*setter) (Ptr<U>))
-{
-  struct MemberMethod : public internal::PtrAccessor<T,U>
-  {
-    void (T::*m_setter) (Ptr<U>);
-    Ptr<U> (T::*m_getter) (void) const;
-    virtual void DoSet (T *object, Ptr<U> value) const {
-      (object->*m_setter) (value);
-    }
-    virtual Ptr<U> DoGet (const T *object) const {
-      return (object->*m_getter) ();
-    }
-  } *spec = new MemberMethod ();
-  spec->m_setter = setter;
-  spec->m_getter = getter;
-  return Ptr<const AttributeAccessor> (spec, false);
-}
-
-
-
-template <typename T>
-Ptr<AttributeChecker>
-MakePtrChecker (void)
-{
-  return Create<internal::APtrChecker<T> > ();
-}
-
 } // namespace ns3
 
 #endif /* ATTRIBUTE_H */
--- a/src/core/boolean.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/boolean.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -22,28 +22,28 @@
 
 namespace ns3 {
 
-Boolean::Boolean ()
+BooleanValue::BooleanValue ()
   : m_value (false)
 {}
-Boolean::Boolean (bool value)
+BooleanValue::BooleanValue (bool value)
   : m_value (value)
 {}
 void 
-Boolean::Set (bool value)
+BooleanValue::Set (bool value)
 {
   m_value = value;
 }
 bool 
-Boolean::Get (void) const
+BooleanValue::Get (void) const
 {
   return m_value;
 }
-Boolean::operator bool () const
+BooleanValue::operator bool () const
 {
   return m_value;
 }
 
-std::ostream & operator << (std::ostream &os, const Boolean &value)
+std::ostream & operator << (std::ostream &os, const BooleanValue &value)
 {
   if (value.Get ())
     {
@@ -55,31 +55,48 @@
     }
   return os;
 }
-std::istream & operator >> (std::istream &is, Boolean &value)
+
+Ptr<AttributeValue> 
+BooleanValue::Copy (void) const
 {
-  std::string v;
-  is >> v;
-  if (v == "true" ||
-      v == "1" ||
-      v == "t")
+  return Create<BooleanValue> (*this);
+}
+std::string 
+BooleanValue::SerializeToString (Ptr<const AttributeChecker> checker) const
+{
+  if (m_value)
+    {
+      return "true";
+    } 
+  else
     {
-      value.Set (true);
+      return "false";
     }
-  else if (v == "false" ||
-	   v == "0" ||
-	   v == "f")
+}
+bool 
+BooleanValue::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker)
+{
+  if (value == "true" ||
+      value == "1" ||
+      value == "t")
     {
-      value.Set (false);
+      m_value = true;
+      return true;
+    }
+  else if (value == "false" ||
+           value == "0" ||
+           value == "f")
+    {
+      m_value = false;
+      return true;
     }
   else
     {
-      is.setstate (std::ios_base::badbit);
+      return false;
     }  
-  return is;
 }
 
-ATTRIBUTE_CONVERTER_IMPLEMENT (Boolean);
-ATTRIBUTE_VALUE_IMPLEMENT (Boolean);
-ATTRIBUTE_CHECKER_IMPLEMENT (Boolean);
+
+ATTRIBUTE_CHECKER_IMPLEMENT_WITH_NAME (Boolean,"bool");
 
 } // namespace ns3
--- a/src/core/boolean.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/boolean.h	Tue Apr 22 21:19:39 2008 -0700
@@ -28,28 +28,30 @@
 /**
  * \brief Hold a bool native type
  *
+ * \anchor bool
+ *
  * This class can be used to hold bool variables
  * which must go through the Attribute system.
  */
-class Boolean
+class BooleanValue : public AttributeValue
 {
 public:
-  Boolean ();
-  Boolean (bool value);
+  BooleanValue ();
+  BooleanValue (bool value);
   void Set (bool value);
   bool Get (void) const;
-
+  
   operator bool () const;
 
-  ATTRIBUTE_CONVERTER_DEFINE (Boolean);
+  virtual Ptr<AttributeValue> Copy (void) const;
+  virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const;
+  virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker);
 private:
   bool m_value;
 };
 
-std::ostream & operator << (std::ostream &os, const Boolean &value);
-std::istream & operator >> (std::istream &is, Boolean &value);
+std::ostream & operator << (std::ostream &os, const BooleanValue &value);
 
-ATTRIBUTE_VALUE_DEFINE (Boolean);
 ATTRIBUTE_CHECKER_DEFINE (Boolean);
 ATTRIBUTE_ACCESSOR_DEFINE (Boolean);
 
--- a/src/core/command-line.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/command-line.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -21,6 +21,7 @@
 #include "log.h"
 #include "config.h"
 #include "global-value.h"
+#include "type-id.h"
 #include "string.h"
 #include <stdlib.h>
 
@@ -41,7 +42,7 @@
 {}
 
 void 
-CommandLine::Parse (int &iargc, char *argv[]) const
+CommandLine::Parse (int iargc, char *argv[]) const
 {
   int argc = iargc;
   for (argc--, argv++; argc > 0; argc--, argv++)
@@ -109,8 +110,9 @@
     {
       std::cout << "    --" << (*i)->GetName () << "=[";
       Ptr<const AttributeChecker> checker = (*i)->GetChecker ();
-      Attribute value = (*i)->GetValue ();
-      std::cout << value.SerializeToString (checker) << "]:  "
+      StringValue v;
+      (*i)->GetValue (v);
+      std::cout << v.Get () << "]:  "
 		<< (*i)->GetHelp () << std::endl;      
     }
   exit (0);
@@ -128,8 +130,8 @@
     {
       std::cout << "    --"<<tid.GetAttributeFullName (i)<<"=[";
       Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (i);
-      Attribute initial = tid.GetAttributeInitialValue (i);
-      std::cout << initial.SerializeToString (checker) << "]:  "
+      Ptr<const AttributeValue> initial = tid.GetAttributeInitialValue (i);
+      std::cout << initial->SerializeToString (checker) << "]:  "
 		<< tid.GetAttributeHelp (i) << std::endl;
     }
   exit (0);
@@ -243,8 +245,8 @@
 	    }
 	}
     }
-  if (!Config::SetGlobalFailSafe (name, String (value))
-      && !Config::SetDefaultFailSafe (name, String (value)))
+  if (!Config::SetGlobalFailSafe (name, StringValue (value))
+      && !Config::SetDefaultFailSafe (name, StringValue (value)))
     {
       std::cerr << "Invalid command-line arguments: --"<<name<<"="<<value<<std::endl;
       PrintHelp ();
--- a/src/core/command-line.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/command-line.h	Tue Apr 22 21:19:39 2008 -0700
@@ -64,7 +64,7 @@
    * Obviously, this method will parse the input command-line arguments and
    * will attempt to handle them all.
    */
-  void Parse (int &argc, char *argv[]) const;
+  void Parse (int argc, char *argv[]) const;
 private:
   class Item 
   {
--- a/src/core/config.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/config.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -22,6 +22,7 @@
 #include "object.h"
 #include "global-value.h"
 #include "object-vector.h"
+#include "pointer.h"
 #include "log.h"
 #include <sstream>
 
@@ -125,7 +126,7 @@
   void Resolve (Ptr<Object> root);
 private:
   void DoResolve (std::string path, Ptr<Object> root);
-  void DoArrayResolve (std::string path, const ObjectVector &vector);
+  void DoArrayResolve (std::string path, const ObjectVectorValue &vector);
   void DoResolveOne (Ptr<Object> object, std::string name);
   std::string GetResolvedPath (std::string name) const;
   virtual void DoOne (Ptr<Object> object, std::string path, std::string name) = 0;
@@ -213,14 +214,13 @@
 	  return;
 	}
       // attempt to cast to a pointer checker.
-      const PtrChecker *ptr = dynamic_cast<const PtrChecker *> (PeekPointer (info.checker));
+      const PointerChecker *ptr = dynamic_cast<const PointerChecker *> (PeekPointer (info.checker));
       if (ptr != 0)
 	{
 	  NS_LOG_DEBUG ("GetAttribute(ptr)="<<item<<" on path="<<GetResolvedPath (""));
-	  // XXX: This is not completely right because anything could be stored in a
-	  // Ptr<>. We really need to fix this by thinking seriously about our
-	  // object hierarchy.
-	  Ptr<Object> object = root->GetAttribute (item);
+          PointerValue ptr;
+          root->GetAttribute (item, ptr);
+	  Ptr<Object> object = ptr.Get<Object> ();
 	  if (object == 0)
 	    {
 	      NS_LOG_ERROR ("Requested object name=\""<<item<<
@@ -237,7 +237,8 @@
       if (vectorChecker != 0)
 	{
 	  NS_LOG_DEBUG ("GetAttribute(vector)="<<item<<" on path="<<GetResolvedPath (""));
-	  ObjectVector vector = root->GetAttribute (item);
+	  ObjectVectorValue vector;
+          root->GetAttribute (item, vector);
 	  m_workStack.push_back (item);
 	  DoArrayResolve (pathLeft, vector);
 	  m_workStack.pop_back ();
@@ -248,7 +249,7 @@
 }
 
 void 
-Resolver::DoArrayResolve (std::string path, const ObjectVector &vector)
+Resolver::DoArrayResolve (std::string path, const ObjectVectorValue &vector)
 {
   NS_ASSERT (path != "");
   std::string::size_type pos = path.find ("/");
@@ -284,7 +285,7 @@
 class ConfigImpl 
 {
 public:
-  void Set (std::string path, Attribute value);
+  void Set (std::string path, const AttributeValue &value);
   void ConnectWithoutContext (std::string path, const CallbackBase &cb);
   void Connect (std::string path, const CallbackBase &cb);
   void DisconnectWithoutContext (std::string path, const CallbackBase &cb);
@@ -292,6 +293,9 @@
 
   void RegisterRootNamespaceObject (Ptr<Object> obj);
   void UnregisterRootNamespaceObject (Ptr<Object> obj);
+
+  uint32_t GetRootNamespaceObjectN (void) const;
+  Ptr<Object> GetRootNamespaceObject (uint32_t i) const;
   
 private:
   typedef std::vector<Ptr<Object> > Roots;
@@ -299,19 +303,19 @@
 };
 
 void 
-ConfigImpl::Set (std::string path, Attribute value)
+ConfigImpl::Set (std::string path, const AttributeValue &value)
 {
   class SetResolver : public Resolver 
   {
   public:
-    SetResolver (std::string path, Attribute value)
+    SetResolver (std::string path, const AttributeValue &value)
       : Resolver (path),
-	m_value (value) {}
+	m_value (value.Copy ()) {}
   private:
     virtual void DoOne (Ptr<Object> object, std::string path, std::string name) {
-      object->SetAttribute (name, m_value);
+      object->SetAttribute (name, *m_value);
     }
-    Attribute m_value;
+    Ptr<const AttributeValue> m_value;
   } resolver = SetResolver (path, value);
   for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++)
     {
@@ -417,26 +421,36 @@
     }
 }
 
+uint32_t 
+ConfigImpl::GetRootNamespaceObjectN (void) const
+{
+  return m_roots.size ();
+}
+Ptr<Object> 
+ConfigImpl::GetRootNamespaceObject (uint32_t i) const
+{
+  return m_roots[i];
+}
 
 namespace Config {
 
-void Set (std::string path, Attribute value)
+void Set (std::string path, const AttributeValue &value)
 {
   Singleton<ConfigImpl>::Get ()->Set (path, value);
 }
-void SetDefault (std::string name, Attribute value)
+void SetDefault (std::string name, const AttributeValue &value)
 {
   AttributeList::GetGlobal ()->Set (name, value);
 }
-bool SetDefaultFailSafe (std::string name, Attribute value)
+bool SetDefaultFailSafe (std::string name, const AttributeValue &value)
 {
   return AttributeList::GetGlobal ()->SetFailSafe (name, value);
 }
-void SetGlobal (std::string name, Attribute value)
+void SetGlobal (std::string name, const AttributeValue &value)
 {
   GlobalValue::Bind (name, value);
 }
-bool SetGlobalFailSafe (std::string name, Attribute value)
+bool SetGlobalFailSafe (std::string name, const AttributeValue &value)
 {
   return GlobalValue::BindFailSafe (name, value);
 }
@@ -469,6 +483,17 @@
   Singleton<ConfigImpl>::Get ()->UnregisterRootNamespaceObject (obj);
 }
 
+uint32_t GetRootNamespaceObjectN (void)
+{
+  return Singleton<ConfigImpl>::Get ()->GetRootNamespaceObjectN ();
+}
+
+Ptr<Object> GetRootNamespaceObject (uint32_t i)
+{
+  return Singleton<ConfigImpl>::Get ()->GetRootNamespaceObject (i);
+}
+
+
 } // namespace Config
 
 } // namespace ns3
@@ -512,31 +537,31 @@
   static TypeId tid = TypeId ("MyNode")
     .SetParent<Object> ()
     .AddAttribute ("NodesA", "",
-		   ObjectVector (),
+		   ObjectVectorValue (),
 		   MakeObjectVectorAccessor (&MyNode::m_nodesA),
-		   MakeObjectVectorChecker ())
+		   MakeObjectVectorChecker<MyNode> ())
     .AddAttribute ("NodesB", "",
-		   ObjectVector (),
+		   ObjectVectorValue (),
 		   MakeObjectVectorAccessor (&MyNode::m_nodesB),
-		   MakeObjectVectorChecker ())
+		   MakeObjectVectorChecker<MyNode> ())
     .AddAttribute ("NodeA", "",
-		   Ptr<MyNode> (0),
-		   MakePtrAccessor (&MyNode::m_nodeA),
-		   MakePtrChecker<MyNode> ())
+                   PointerValue (),
+		   MakePointerAccessor (&MyNode::m_nodeA),
+		   MakePointerChecker<MyNode> ())
     .AddAttribute ("NodeB", "",
-		   Ptr<MyNode> (0),
-		   MakePtrAccessor (&MyNode::m_nodeB),
-		   MakePtrChecker<MyNode> ())
+                   PointerValue (),
+		   MakePointerAccessor (&MyNode::m_nodeB),
+		   MakePointerChecker<MyNode> ())
     .AddAttribute ("A", "",
-		   Integer (10),
+		   IntegerValue (10),
 		   MakeIntegerAccessor (&MyNode::m_a),
 		   MakeIntegerChecker<int8_t> ())
     .AddAttribute ("B", "",
-		   Integer (9),
+		   IntegerValue (9),
 		   MakeIntegerAccessor (&MyNode::m_b),
 		   MakeIntegerChecker<int8_t> ())
     .AddAttribute ("Source", "XX",
-		   Integer (-1),
+		   IntegerValue (-1),
 		   MakeIntegerAccessor (&MyNode::m_trace),
 		   MakeIntegerChecker<int16_t> ())
     .AddTraceSource ("Source", "XX",
@@ -615,44 +640,45 @@
 
   Ptr<MyNode> root = CreateObject<MyNode> ();
   Config::RegisterRootNamespaceObject (root);
-  Config::Set ("/A", Integer (1));
-  Config::Set ("/B", Integer (-1));
-  Integer v = root->GetAttribute ("A");
+  Config::Set ("/A", IntegerValue (1));
+  Config::Set ("/B", IntegerValue (-1));
+  IntegerValue v;
+  root->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), 1);
-  v = root->GetAttribute ("B");
+  root->GetAttribute ("B", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -1);
 
   Ptr<MyNode> a = CreateObject<MyNode> ();
   root->SetNodeA (a);
-  Config::Set ("/NodeA/A", Integer (2));
-  Config::Set ("/NodeA/B", Integer (-2));
-  v = a->GetAttribute ("A");
+  Config::Set ("/NodeA/A", IntegerValue (2));
+  Config::Set ("/NodeA/B", IntegerValue (-2));
+  a->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), 2);
-  v = a->GetAttribute ("B");
+  a->GetAttribute ("B", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -2);
-  Config::Set ("/NodeB/A", Integer (3));
-  Config::Set ("/NodeB/B", Integer (-3));
-  v = a->GetAttribute ("A");
+  Config::Set ("/NodeB/A", IntegerValue (3));
+  Config::Set ("/NodeB/B", IntegerValue (-3));
+  a->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), 2);
-  v = a->GetAttribute ("B");
+  a->GetAttribute ("B", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -2);
 
   Ptr<MyNode> b = CreateObject<MyNode> ();
   a->SetNodeB (b);
-  Config::Set ("/NodeA/NodeB/A", Integer (4));
-  Config::Set ("/NodeA/NodeB/B", Integer (-4));
-  v = b->GetAttribute ("A");
+  Config::Set ("/NodeA/NodeB/A", IntegerValue (4));
+  Config::Set ("/NodeA/NodeB/B", IntegerValue (-4));
+  b->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), 4);
-  v = b->GetAttribute ("B");
+  b->GetAttribute ("B", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -4);
 
   Ptr<MyNode> c = CreateObject<MyNode> ();
   root->SetNodeB (c);
-  Config::Set ("/NodeB/A", Integer (5));
-  Config::Set ("/NodeB/B", Integer (-5));
-  v = c->GetAttribute ("A");
+  Config::Set ("/NodeB/A", IntegerValue (5));
+  Config::Set ("/NodeB/B", IntegerValue (-5));
+  c->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), 5);
-  v = c->GetAttribute ("B");
+  c->GetAttribute ("B", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -5);
 
 
@@ -664,49 +690,49 @@
   b->AddNodeB (d1);
   b->AddNodeB (d2);
   b->AddNodeB (d3);
-  Config::Set ("/NodeA/NodeB/NodesB/0/A", Integer (-11));
-  v = d0->GetAttribute ("A");
+  Config::Set ("/NodeA/NodeB/NodesB/0/A", IntegerValue (-11));
+  d0->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -11);
-  v = d0->GetAttribute ("B");
+  d0->GetAttribute ("B", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), 9);
-  v = d1->GetAttribute ("A");
+  d1->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), 10);
-  v = d1->GetAttribute ("B");
+  d1->GetAttribute ("B", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), 9);
-  Config::Set ("/NodeA/NodeB/NodesB/0|1/A", Integer (-12));
-  v = d0->GetAttribute ("A");
+  Config::Set ("/NodeA/NodeB/NodesB/0|1/A", IntegerValue (-12));
+  d0->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -12);
-  v = d1->GetAttribute ("A");
+  d1->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -12);
-  Config::Set ("/NodeA/NodeB/NodesB/|0|1|/A", Integer (-13));
-  v = d0->GetAttribute ("A");
+  Config::Set ("/NodeA/NodeB/NodesB/|0|1|/A", IntegerValue (-13));
+  d0->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -13);
-  v = d1->GetAttribute ("A");
+  d1->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -13);
-  Config::Set ("/NodeA/NodeB/NodesB/[0-2]/A", Integer (-14));
-  v = d0->GetAttribute ("A");
+  Config::Set ("/NodeA/NodeB/NodesB/[0-2]/A", IntegerValue (-14));
+  d0->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -14);
-  v = d1->GetAttribute ("A");
+  d1->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -14);
-  v = d2->GetAttribute ("A");
+  d2->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -14);
-  Config::Set ("/NodeA/NodeB/NodesB/[1-3]/A", Integer (-15));
-  v = d0->GetAttribute ("A");
+  Config::Set ("/NodeA/NodeB/NodesB/[1-3]/A", IntegerValue (-15));
+  d0->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -14);
-  v = d1->GetAttribute ("A");
+  d1->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -15);
-  v = d2->GetAttribute ("A");
+  d2->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -15);
-  v = d3->GetAttribute ("A");
+  d3->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -15);
-  Config::Set ("/NodeA/NodeB/NodesB/[0-1]|3/A", Integer (-16));
-  v = d0->GetAttribute ("A");
+  Config::Set ("/NodeA/NodeB/NodesB/[0-1]|3/A", IntegerValue (-16));
+  d0->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -16);
-  v = d1->GetAttribute ("A");
+  d1->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -16);
-  v = d2->GetAttribute ("A");
+  d2->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -15);
-  v = d3->GetAttribute ("A");
+  d3->GetAttribute ("A", v);
   NS_TEST_ASSERT_EQUAL (v.Get (), -16);
 
 
@@ -714,17 +740,17 @@
 		   MakeCallback (&ConfigTest::ChangeNotification, this));
   m_traceNotification = 0;
   // this should trigger no notification
-  d2->SetAttribute ("Source", Integer (-2));
+  d2->SetAttribute ("Source", IntegerValue (-2));
   NS_TEST_ASSERT_EQUAL (m_traceNotification, 0);
   m_traceNotification = 0;
   // this should trigger a notification
-  d1->SetAttribute ("Source", Integer (-3));
+  d1->SetAttribute ("Source", IntegerValue (-3));
   NS_TEST_ASSERT_EQUAL (m_traceNotification, -3);
   Config::DisconnectWithoutContext ("/NodeA/NodeB/NodesB/[0-1]|3/Source", 
 		      MakeCallback (&ConfigTest::ChangeNotification, this));
   m_traceNotification = 0;
   // this should _not_ trigger a notification
-  d1->SetAttribute ("Source", Integer (-4));
+  d1->SetAttribute ("Source", IntegerValue (-4));
   NS_TEST_ASSERT_EQUAL (m_traceNotification, 0);
 
   
@@ -732,25 +758,25 @@
 			      MakeCallback (&ConfigTest::ChangeNotificationWithPath, this));
   m_traceNotification = 0;
   // this should trigger no notification
-  d2->SetAttribute ("Source", Integer (-2));
+  d2->SetAttribute ("Source", IntegerValue (-2));
   NS_TEST_ASSERT_EQUAL (m_traceNotification, 0);
   m_traceNotification = 0;
   m_tracePath = "";
   // this should trigger a notification
-  d1->SetAttribute ("Source", Integer (-3));
+  d1->SetAttribute ("Source", IntegerValue (-3));
   NS_TEST_ASSERT_EQUAL (m_traceNotification, -3);
   NS_TEST_ASSERT_EQUAL (m_tracePath, "/NodeA/NodeB/NodesB/1/Source")
   m_traceNotification = 0;
   m_tracePath = "";
   // this should trigger a notification
-  d3->SetAttribute ("Source", Integer (-3));
+  d3->SetAttribute ("Source", IntegerValue (-3));
   NS_TEST_ASSERT_EQUAL (m_traceNotification, -3);
   NS_TEST_ASSERT_EQUAL (m_tracePath, "/NodeA/NodeB/NodesB/3/Source");
   Config::Disconnect ("/NodeA/NodeB/NodesB/[0-1]|3/Source", 
 				 MakeCallback (&ConfigTest::ChangeNotificationWithPath, this));
   m_traceNotification = 0;
   // this should _not_ trigger a notification
-  d1->SetAttribute ("Source", Integer (-4));
+  d1->SetAttribute ("Source", IntegerValue (-4));
   NS_TEST_ASSERT_EQUAL (m_traceNotification, 0);
 
 
--- a/src/core/config.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/config.h	Tue Apr 22 21:19:39 2008 -0700
@@ -20,13 +20,15 @@
 #ifndef CONFIG_H
 #define CONFIG_H
 
-#include "attribute.h"
 #include "ptr.h"
-#include "object.h"
 #include <string>
 
 namespace ns3 {
 
+class AttributeValue;
+class Object;
+class CallbackBase;
+
 namespace Config {
 
 /**
@@ -37,7 +39,7 @@
  * match the input path and will then set their value to the input
  * value.
  */
-void Set (std::string path, Attribute value);
+void Set (std::string path, const AttributeValue &value);
 /**
  * \param name the full name of the attribute
  * \param value the value to set.
@@ -46,7 +48,7 @@
  * matching attribute. This method cannot fail: it will
  * crash if the input attribute name or value is invalid.
  */
-void SetDefault (std::string name, Attribute value);
+void SetDefault (std::string name, const AttributeValue &value);
 /**
  * \param name the full name of the attribute
  * \param value the value to set.
@@ -55,21 +57,21 @@
  * This method overrides the initial value of the 
  * matching attribute. 
  */
-bool SetDefaultFailSafe (std::string name, Attribute value);
+bool SetDefaultFailSafe (std::string name, const AttributeValue &value);
 /**
  * \param name the name of the requested GlobalValue.
  * \param value the value to set
  *
  * This method is equivalent to GlobalValue::Bind
  */
-void SetGlobal (std::string name, Attribute value);
+void SetGlobal (std::string name, const AttributeValue &value);
 /**
  * \param name the name of the requested GlobalValue.
  * \param value the value to set
  *
  * This method is equivalent to GlobalValue::BindFailSafe
  */
-bool SetGlobalFailSafe (std::string name, Attribute value);
+bool SetGlobalFailSafe (std::string name, const AttributeValue &value);
 /**
  * \param path a path to match trace sources.
  * \param cb the callback to connect to the matching trace sources.
@@ -118,6 +120,17 @@
  */
 void UnregisterRootNamespaceObject (Ptr<Object> obj);
 
+/**
+ * \returns the number of registered root namespace objects.
+ */
+uint32_t GetRootNamespaceObjectN (void);
+
+/**
+ * \param i the index of the requested object.
+ * \returns the requested root namespace object
+ */
+Ptr<Object> GetRootNamespaceObject (uint32_t i);
+
 } // namespace Config
 
 } // namespace ns3
--- a/src/core/double.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/double.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -23,40 +23,7 @@
 
 namespace ns3 {
 
-Double::Double ()
-{}
-Double::Double (double value)
-  : m_value (value)
-{}
-void 
-Double::Set (double value)
-{
-  m_value = value;
-}
-double 
-Double::Get (void) const
-{
-  return m_value;
-}
-Double::operator double () const
-{
-  return m_value;
-}
-std::ostream & operator << (std::ostream &os, const Double &value)
-{
-  os << value.Get ();
-  return os;
-}
-std::istream & operator >> (std::istream &is, Double &value)
-{
-  double v;
-  is >> v;
-  value.Set (v);
-  return is;
-}
-
-ATTRIBUTE_VALUE_IMPLEMENT (Double);
-ATTRIBUTE_CONVERTER_IMPLEMENT (Double);
+ATTRIBUTE_VALUE_IMPLEMENT_WITH_NAME (double, Double);
 
 namespace internal {
 
@@ -68,27 +35,37 @@
       : m_minValue (minValue),
         m_maxValue (maxValue),
         m_name (name) {}
-    virtual bool Check (Attribute value) const {
-      const DoubleValue *v = value.DynCast<const DoubleValue *> ();
+    virtual bool Check (const AttributeValue &value) const {
+      const DoubleValue *v = dynamic_cast<const DoubleValue *> (&value);
       if (v == 0)
 	{
 	  return false;
 	}
       return v->Get () >= m_minValue && v->Get () <= m_maxValue;
     }
-    virtual std::string GetType (void) const {
-      return m_name;
+    virtual std::string GetValueTypeName (void) const {
+      return "ns3::DoubleValue";
     }
-    virtual bool HasTypeConstraints (void) const {
+    virtual bool HasUnderlyingTypeInformation (void) const {
       return true;
     }
-    virtual std::string GetTypeConstraints (void) const {
+    virtual std::string GetUnderlyingTypeInformation (void) const {
       std::ostringstream oss;
-      oss << m_minValue << ":" << m_maxValue;
+      oss << m_name << " " << m_minValue << ":" << m_maxValue;
       return oss.str ();
     }
-    virtual Attribute Create (void) const {
-      return Attribute::Create<DoubleValue> ();
+    virtual Ptr<AttributeValue> Create (void) const {
+      return ns3::Create<DoubleValue> ();
+    }
+    virtual bool Copy (const AttributeValue &source, AttributeValue &destination) const {
+      const DoubleValue *src = dynamic_cast<const DoubleValue *> (&source);
+      DoubleValue *dst = dynamic_cast<DoubleValue *> (&destination);
+      if (src == 0 || dst == 0)
+        {
+          return false;
+        }
+      *dst = *src;
+      return true;
     }
     double m_minValue;
     double m_maxValue;
--- a/src/core/double.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/double.h	Tue Apr 22 21:19:39 2008 -0700
@@ -27,31 +27,15 @@
 namespace ns3 {
 
 /**
+ * \class ns3::DoubleValue
  * \brief Hold an floating point type
  *
+ * \anchor double
  * This class can be used to hold variables of floating point type
  * such as 'double' or 'float'. The internal format is 'double'.
  */
-class Double
-{
-public:
-  Double ();
-  Double (double value);
 
-  void Set (double value);
-  double Get (void) const;
-
-  operator double () const;
-
-  ATTRIBUTE_CONVERTER_DEFINE (Double);
-private:
-  double m_value;
-};
-
-std::ostream & operator << (std::ostream &os, const Double &value);
-std::istream & operator >> (std::istream &is, Double &value);
-
-ATTRIBUTE_VALUE_DEFINE (Double);
+ATTRIBUTE_VALUE_DEFINE_WITH_NAME (double, Double);
 ATTRIBUTE_ACCESSOR_DEFINE (Double);
 
 template <typename T>
--- a/src/core/enum.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/enum.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -23,30 +23,30 @@
 
 namespace ns3 {
 
-Enum::Enum ()
+EnumValue::EnumValue ()
   : m_v ()
 {}
-Enum::Enum (int v)
+EnumValue::EnumValue (int v)
   : m_v (v)
 {}
 void 
-Enum::Set (int v)
+EnumValue::Set (int v)
 {
   m_v = v;
 }
 int 
-Enum::Get (void) const
+EnumValue::Get (void) const
 {
   return m_v;
 }
 
-Attribute
-Enum::Copy (void) const
+Ptr<AttributeValue>
+EnumValue::Copy (void) const
 {
-  return Attribute::Create<Enum> (*this);
+  return ns3::Create<EnumValue> (*this);
 }
 std::string 
-Enum::SerializeToString (Ptr<const AttributeChecker> checker) const
+EnumValue::SerializeToString (Ptr<const AttributeChecker> checker) const
 {
   const EnumChecker *p = dynamic_cast<const EnumChecker *> (PeekPointer (checker));
   NS_ASSERT (p != 0);
@@ -63,7 +63,7 @@
   return "";
 }
 bool 
-Enum::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker)
+EnumValue::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker)
 {
   const EnumChecker *p = dynamic_cast<const EnumChecker *> (PeekPointer (checker));
   NS_ASSERT (p != 0);
@@ -78,22 +78,6 @@
   return false;
 }
 
-Enum::Enum (Attribute value)
-{
-  const Enum *v = value.DynCast<const Enum *> ();
-  if (v == 0)
-    {
-      NS_FATAL_ERROR ("assigning non-Enum value to Enum value.");
-    }
-  m_v = v->m_v;
-}
-Enum::operator Attribute () const
-{
-  return Attribute::Create<Enum> (*this);
-}
-
-
-
 EnumChecker::EnumChecker ()
 {}
 
@@ -108,9 +92,9 @@
   m_valueSet.push_back (std::make_pair (v, name));
 }
 bool 
-EnumChecker::Check (Attribute value) const
+EnumChecker::Check (const AttributeValue &value) const
 {
-  const Enum *p = value.DynCast<const Enum *> ();
+  const EnumValue *p = dynamic_cast<const EnumValue *> (&value);
   if (p == 0)
     {
       return false;
@@ -125,17 +109,17 @@
   return false;
 }
 std::string 
-EnumChecker::GetType (void) const
+EnumChecker::GetValueTypeName (void) const
 {
-  return "Enum";
+  return "ns3::EnumValue";
 }
 bool 
-EnumChecker::HasTypeConstraints (void) const
+EnumChecker::HasUnderlyingTypeInformation (void) const
 {
   return true;
 }
 std::string 
-EnumChecker::GetTypeConstraints (void) const
+EnumChecker::GetUnderlyingTypeInformation (void) const
 {
   std::ostringstream oss;
   for (ValueSet::const_iterator i = m_valueSet.begin (); i != m_valueSet.end ();)
@@ -149,10 +133,23 @@
     }
   return oss.str ();
 }
-Attribute 
+Ptr<AttributeValue>
 EnumChecker::Create (void) const
 {
-  return Attribute::Create<Enum> ();
+  return ns3::Create<EnumValue> ();
+}
+
+bool 
+EnumChecker::Copy (const AttributeValue &source, AttributeValue &destination) const
+{
+  const EnumValue *src = dynamic_cast<const EnumValue *> (&source);
+  EnumValue *dst = dynamic_cast<EnumValue *> (&destination);
+  if (src == 0 || dst == 0)
+    {
+      return false;
+    }
+  *dst = *src;
+  return true;
 }
 
 
--- a/src/core/enum.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/enum.h	Tue Apr 22 21:19:39 2008 -0700
@@ -32,20 +32,18 @@
  * This class can be used to hold variables of any kind
  * of enum.
  */
-class Enum : public AttributeValue
+class EnumValue : public AttributeValue
 {
 public:
-  Enum ();
-  Enum (int v);
+  EnumValue ();
+  EnumValue (int v);
   void Set (int v);
   int Get (void) const;
 
-  virtual Attribute Copy (void) const;
+  virtual Ptr<AttributeValue> Copy (void) const;
   virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const;
   virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker);
 
-  Enum (Attribute value);
-  operator Attribute () const;
 private:
   int m_v;
 };
@@ -58,14 +56,15 @@
   void AddDefault (int v, std::string name);
   void Add (int v, std::string name);
 
-  virtual bool Check (Attribute value) const;
-  virtual std::string GetType (void) const;
-  virtual bool HasTypeConstraints (void) const;
-  virtual std::string GetTypeConstraints (void) const;
-  virtual Attribute Create (void) const;
+  virtual bool Check (const AttributeValue &value) const;
+  virtual std::string GetValueTypeName (void) const;
+  virtual bool HasUnderlyingTypeInformation (void) const;
+  virtual std::string GetUnderlyingTypeInformation (void) const;
+  virtual Ptr<AttributeValue> Create (void) const;
+  virtual bool Copy (const AttributeValue &src, AttributeValue &dst) const;
 
 private:
-  friend class Enum;
+  friend class EnumValue;
   typedef std::list<std::pair<int,std::string> > ValueSet;
   ValueSet m_valueSet;
 };
@@ -97,13 +96,13 @@
 template <typename T1>
 Ptr<const AttributeAccessor> MakeEnumAccessor (T1 a1)
 {
-  return MakeAccessorHelper<Enum> (a1);
+  return MakeAccessorHelper<EnumValue> (a1);
 }
 
 template <typename T1, typename T2>
 Ptr<const AttributeAccessor> MakeEnumAccessor (T1 a1, T2 a2)
 {
-  return MakeAccessorHelper<Enum> (a1, a2);
+  return MakeAccessorHelper<EnumValue> (a1, a2);
 }
 
 } // namespace ns3
--- a/src/core/global-value.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/global-value.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -25,11 +25,11 @@
 namespace ns3 {
 
 GlobalValue::GlobalValue (std::string name, std::string help,
-			  Attribute initialValue,
+			  const AttributeValue &initialValue,
 			  Ptr<const AttributeChecker> checker)
   : m_name (name),
     m_help (help),
-    m_initialValue (initialValue),
+    m_initialValue (initialValue.Copy ()),
     m_checker (checker)
 {
   if (m_checker == 0)
@@ -49,10 +49,20 @@
 {
   return m_help;
 }
-Attribute 
-GlobalValue::GetValue (void) const
+void
+GlobalValue::GetValue (AttributeValue &value) const
 {
-  return m_initialValue;
+  bool ok = m_checker->Copy (*m_initialValue, value);
+  if (ok)
+    {
+      return;
+    }
+  StringValue *str = dynamic_cast<StringValue *> (&value);
+  if (str == 0)
+    {
+      NS_FATAL_ERROR ("GlobalValue name="<<m_name<<": input value is not a string");
+    }
+  str->Set (m_initialValue->SerializeToString (m_checker));
 }
 Ptr<const AttributeChecker> 
 GlobalValue::GetChecker (void) const
@@ -61,37 +71,37 @@
 }
   
 bool
-GlobalValue::SetValue (Attribute value)
+GlobalValue::SetValue (const AttributeValue &value)
 {
   if (m_checker->Check (value))
     {
-      m_initialValue = value;
+      m_initialValue = value.Copy ();
       return true;
     }
   // attempt to convert to string.
-  const StringValue *str = value.DynCast<const StringValue *> ();
+  const StringValue *str = dynamic_cast<const StringValue *> (&value);
   if (str == 0)
     {
       return false;
     }
   // attempt to convert back to value.
-  Attribute v = m_checker->Create ();
-  bool ok = v.DeserializeFromString (str->Get ().Get (), m_checker);
+  Ptr<AttributeValue> v = m_checker->Create ();
+  bool ok = v->DeserializeFromString (str->Get (), m_checker);
   if (!ok)
     {
       return false;
     }
-  ok = m_checker->Check (v);
+  ok = m_checker->Check (*v);
   if (!ok)
     {
       return false;
     }
-  m_initialValue = v;
+  m_checker->Copy (*v, *PeekPointer (m_initialValue));
   return true;
 }
 
 void 
-GlobalValue::Bind (std::string name, Attribute value)
+GlobalValue::Bind (std::string name, const AttributeValue &value)
 {
   for (Iterator i = Begin (); i != End (); i++)
     {
@@ -107,7 +117,7 @@
   NS_FATAL_ERROR ("Non-existant global value: "<<name);
 }
 bool 
-GlobalValue::BindFailSafe (std::string name, Attribute value)
+GlobalValue::BindFailSafe (std::string name, const AttributeValue &value)
 {
   for (Iterator i = Begin (); i != End (); i++)
     {
@@ -160,11 +170,13 @@
 {
   bool result = true;
   GlobalValue uint = GlobalValue ("TestUint", "help text",
-				  Uinteger (10),
+				  UintegerValue (10),
 				  MakeUintegerChecker<uint32_t> ());
 
 
-  NS_TEST_ASSERT_EQUAL (10, Uinteger (uint.GetValue ()).Get ());
+  UintegerValue v;
+  uint.GetValue (v);
+  NS_TEST_ASSERT_EQUAL (10, v.Get ());
 
   GlobalValue::Vector *vector = GlobalValue::GetVector ();
   for (GlobalValue::Vector::iterator i = vector->begin (); i != vector->end (); ++i)
--- a/src/core/global-value.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/global-value.h	Tue Apr 22 21:19:39 2008 -0700
@@ -51,8 +51,8 @@
    *        value matches the requested type constraints.
    */
   GlobalValue (std::string name, std::string help,
-		Attribute initialValue,
-		Ptr<const AttributeChecker> checker);
+               const AttributeValue &initialValue,
+               Ptr<const AttributeChecker> checker);
 
   /**
    * \returns the name of this GlobalValue.
@@ -65,7 +65,7 @@
   /**
    * \returns the current value of this GlobalValue.
    */
-  Attribute GetValue (void) const;
+  void GetValue (AttributeValue &value) const;
   /**
    * \returns the checker associated to this GlobalValue.
    */
@@ -73,7 +73,7 @@
   /**
    * \param value the new value to set in this GlobalValue.
    */
-  bool SetValue (Attribute value);
+  bool SetValue (const AttributeValue &value);
 
   /**
    * \param name the name of the global value
@@ -84,7 +84,7 @@
    *
    * This method cannot fail. It will crash if the input is not valid.
    */
-  static void Bind (std::string name, Attribute value);
+  static void Bind (std::string name, const AttributeValue &value);
   
   /**
    * \param name the name of the global value
@@ -94,7 +94,7 @@
    * Iterate over the set of GlobalValues until a matching name is found
    * and then set its value with GlobalValue::SetValue.
    */
-  static bool BindFailSafe (std::string name, Attribute value);
+  static bool BindFailSafe (std::string name, const AttributeValue &value);
 
   /**
    * \returns an iterator which represents a pointer to the first GlobalValue registered.
@@ -109,7 +109,7 @@
   static Vector *GetVector (void);
   std::string m_name;
   std::string m_help;
-  Attribute m_initialValue;
+  Ptr<AttributeValue> m_initialValue;
   Ptr<const AttributeChecker> m_checker;
 };
 
--- a/src/core/integer.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/integer.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -23,44 +23,7 @@
 
 namespace ns3 {
 
-Integer::Integer (int64_t value)
-  : m_value (value)
-{}
-Integer::Integer ()
-  : m_value (0)
-{}
-void 
-Integer::Set (int64_t value)
-{
-  m_value = value;
-}
-int64_t 
-Integer::Get (void) const
-{
-  return m_value;
-}
-
-Integer::operator int64_t () const
-{
-  return m_value;
-}
-
-ATTRIBUTE_VALUE_IMPLEMENT (Integer);
-
-std::ostream &operator << (std::ostream &os, const Integer &integer)
-{
-  os << integer.Get ();
-  return os;
-}
-std::istream &operator >> (std::istream &is, Integer &integer)
-{
-  int64_t v;
-  is >> v;
-  integer.Set (v);
-  return is;
-}
-
-ATTRIBUTE_CONVERTER_IMPLEMENT (Integer);
+ATTRIBUTE_VALUE_IMPLEMENT_WITH_NAME (int64_t, Integer);
 
 namespace internal {
 
@@ -73,27 +36,37 @@
       : m_minValue (minValue),
         m_maxValue (maxValue),
         m_name (name) {}
-    virtual bool Check (Attribute value) const {
-      const IntegerValue *v = value.DynCast<const IntegerValue *> ();
+    virtual bool Check (const AttributeValue &value) const {
+      const IntegerValue *v = dynamic_cast<const IntegerValue *> (&value);
       if (v == 0)
 	{
 	  return false;
 	}
-      return v->Get ().Get () >= m_minValue && v->Get ().Get() <= m_maxValue;
+      return v->Get () >= m_minValue && v->Get () <= m_maxValue;
     }
-    virtual std::string GetType (void) const {
-      return m_name;
+    virtual std::string GetValueTypeName (void) const {
+      return "ns3::IntegerValue";
     }
-    virtual bool HasTypeConstraints (void) const {
+    virtual bool HasUnderlyingTypeInformation (void) const {
       return true;
     }
-    virtual std::string GetTypeConstraints (void) const {
+    virtual std::string GetUnderlyingTypeInformation (void) const {
       std::ostringstream oss;
-      oss << m_minValue << ":" << m_maxValue;
+      oss << m_name << " " << m_minValue << ":" << m_maxValue;
       return oss.str ();
     }
-    virtual Attribute Create (void) const {
-      return Attribute::Create<IntegerValue> ();
+    virtual Ptr<AttributeValue> Create (void) const {
+      return ns3::Create<IntegerValue> ();
+    }
+    virtual bool Copy (const AttributeValue &src, AttributeValue &dst) const {
+      const IntegerValue *source = dynamic_cast<const IntegerValue *> (&src);
+      IntegerValue *destination = dynamic_cast<IntegerValue *> (&dst);
+      if (source == 0 || destination == 0)
+        {
+          return false;
+        }
+      *destination = *source;
+      return true;
     }
     int64_t m_minValue;
     int64_t m_maxValue;
--- a/src/core/integer.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/integer.h	Tue Apr 22 21:19:39 2008 -0700
@@ -27,30 +27,20 @@
 namespace ns3 {
 
 /**
+ * \class ns3::IntegerValue
  * \brief Hold a signed integer type
  *
+ * \anchor int8_t
+ * \anchor int16_t
+ * \anchor int32_t
+ * \anchor int64_t
+ *
  * This class can be used to hold variables of signed integer
  * type such as int8_t, int16_t, int32_t, int64_t, or,
  * int, etc.
  */
-class Integer
-{
-public:
-  Integer (int64_t value);
-  Integer ();
-  void Set (int64_t value);
-  int64_t Get (void) const;
 
-  operator int64_t () const;
-  ATTRIBUTE_CONVERTER_DEFINE (Integer);
-private:
-  int64_t m_value;
-};
-
-std::ostream &operator << (std::ostream &os, const Integer &integer);
-std::istream &operator >> (std::istream &is, Integer &integer);
-
-ATTRIBUTE_VALUE_DEFINE(Integer);
+ATTRIBUTE_VALUE_DEFINE_WITH_NAME(int64_t, Integer);
 ATTRIBUTE_ACCESSOR_DEFINE(Integer);
 
 template <typename T>
--- a/src/core/log.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/log.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -18,8 +18,6 @@
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 
-// What about print-list!!!!!!???????
-
 #ifdef NS3_LOG_ENABLE
 
 #include <list>
@@ -36,6 +34,8 @@
 
 namespace ns3 {
 
+LogTimePrinter g_logTimePrinter = 0;
+
 typedef std::list<std::pair <std::string, LogComponent *> > ComponentList;
 typedef std::list<std::pair <std::string, LogComponent *> >::iterator ComponentListI;
 
@@ -67,7 +67,7 @@
   std::string::size_type next = 0;
   while (next != std::string::npos)
     {
-      next = env.find_first_of (";", cur);
+      next = env.find_first_of (":", cur);
       std::string tmp = std::string (env, cur, next-cur);
       if (tmp == "print-list")
         {
@@ -115,7 +115,7 @@
   std::string::size_type next = 0;
   while (next != std::string::npos)
     {
-      next = env.find_first_of (";", cur);
+      next = env.find_first_of (":", cur);
       std::string tmp = std::string (env, cur, next-cur);
       std::string::size_type equal = tmp.find ("=");
       std::string component;
@@ -124,7 +124,8 @@
           component = tmp;
           if (component == myName || component == "*")
             {
-              Enable (LOG_DEBUG);
+              int level = LOG_ALL | LOG_PREFIX_TIME | LOG_PREFIX_FUNC;
+              Enable ((enum LogLevel)level);
               return;
             }
         }
@@ -161,10 +162,6 @@
                     {
                       level |= LOG_FUNCTION;
                     }
-                  else if (lev == "param")
-                    {
-                      level |= LOG_PARAM;
-                    }
                   else if (lev == "logic")
                     {
                       level |= LOG_LOGIC;
@@ -173,9 +170,13 @@
                     {
                       level |= LOG_ALL;
                     }
-                  else if (lev == "prefix")
+                  else if (lev == "prefix_func")
                     {
-                      level |= LOG_PREFIX_ALL;
+                      level |= LOG_PREFIX_FUNC;
+                    }
+                  else if (lev == "prefix_time")
+                    {
+                      level |= LOG_PREFIX_TIME;
                     }
                   else if (lev == "level_error")
                     {
@@ -197,10 +198,6 @@
                     {
                       level |= LOG_LEVEL_FUNCTION;
                     }
-                  else if (lev == "level_param")
-                    {
-                      level |= LOG_LEVEL_PARAM;
-                    }
                   else if (lev == "level_logic")
                     {
                       level |= LOG_LEVEL_LOGIC;
@@ -342,10 +339,6 @@
         {
           std::cout << "|function";
         }
-      if (i->second->IsEnabled (LOG_PARAM))
-        {
-          std::cout << "|param";
-        }
       if (i->second->IsEnabled (LOG_LOGIC))
         {
           std::cout << "|logic";
@@ -358,10 +351,20 @@
     }
 }
 
+void LogRegisterTimePrinter (LogTimePrinter printer)
+{
+  g_logTimePrinter = printer;
+}
+LogTimePrinter LogGetTimePrinter(void)
+{
+  return g_logTimePrinter;
+}
 
-ParameterLogger g_parameterLogger;
-EndParameterListStruct EndParameterList;
 
+ParameterLogger::ParameterLogger (std::ostream &os)
+  : m_itemNumber (0),
+    m_os (os)
+{}
 
 } // namespace ns3
 
--- a/src/core/log.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/log.h	Tue Apr 22 21:19:39 2008 -0700
@@ -24,6 +24,9 @@
 #include <string>
 #include <iostream>
 
+#ifdef NS3_LOG_ENABLE
+
+
 /**
  * \ingroup core
  * \defgroup logging Logging
@@ -35,22 +38,20 @@
  * messages, use the ns3::LogComponentEnable
  * function or use the NS_LOG environment variable 
  *
- * Use the environment variable NS_LOG to define a ';'-separated list of
+ * Use the environment variable NS_LOG to define a ':'-separated list of
  * logging components to enable. For example (using bash syntax), 
- * NS_LOG="OlsrAgent" would enable one component; 
- * NS_LOG="OlsrAgent;Ipv4L3Protocol" would enable two
- * components, etc.  NS_LOG="*" will enable all available log components.
- * For each component, the "debug" log level is enabled by default.
+ * NS_LOG="OlsrAgent" would enable one component at all log levels. 
+ * NS_LOG="OlsrAgent:Ipv4L3Protocol" would enable two components, 
+ * at all log levels, etc.  
+ * NS_LOG="*" will enable all available log components at all levels.
  *
- * To obtain more components than just debug log level, more components 
- * can be enabled selectively with the following
- * syntax: NS_LOG='Component1=func|param|warn;Component2=error|debug'
- * This example would enable the 'func', 'param', and 'warn' log
+ * To control more selectively the log levels for each component, use
+ * this syntax: NS_LOG='Component1=func|warn:Component2=error|debug'
+ * This example would enable the 'func', and 'warn' log
  * levels for 'Component1' and the 'error' and 'debug' log levels
  * for 'Component2'.  The wildcard can be used here as well.  For example
  * NS_LOG='*=level_all|prefix' would enable all log levels and prefix all
  * prints with the component and function names.
- *
  */
 
 /**
@@ -65,111 +66,30 @@
  * ns3::LogComponentDisable functions or with the NS_LOG
  * environment variable.
  */
-
-#ifdef NS3_LOG_ENABLE
-
-#define NS_LOG_COMPONENT_DEFINE(name)                                \
+#define NS_LOG_COMPONENT_DEFINE(name)                           \
   static ns3::LogComponent g_log = ns3::LogComponent (name)
 
-#else
+#define APPEND_TIME_PREFIX                                      \
+  if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME))                   \
+    {                                                           \
+      LogTimePrinter printer = LogGetTimePrinter ();            \
+      if (printer != 0)                                         \
+        {                                                       \
+          (*printer) (std::clog);                               \
+          std::clog << " ";                                     \
+        }                                                       \
+    }
 
-#define NS_LOG_COMPONENT_DEFINE(name)
-
-#endif
+#define APPEND_FUNC_PREFIX                                      \
+  if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC))                   \
+    {                                                           \
+      std::clog << g_log.Name () << ":" <<                      \
+        __FUNCTION__ << "(): ";                                 \
+    }                                                           \
 
 
 /**
  * \ingroup logging
- * \param msg message to output
- *
- * Generate logging output in the "log component" of the 
- * current file. i.e., every call to NS_LOG from within
- * a file implicitely generates out within the component
- * defined with the NS_LOG_COMPONENT_DEFINE macro in the
- * same file.
- */
-
-#ifdef NS3_LOG_ENABLE
-
-
-namespace ns3 {
-
-struct EndParameterListStruct {};
-extern EndParameterListStruct EndParameterList;
-
-struct ParameterName
-{
-  const char *name;
-  ParameterName (const char *name_) : name (name_) {}
-};
-
-class ParameterLogger : public std::ostream
-{
-  int m_itemNumber;
-  const char *m_parameterName;
-public:
-  ParameterLogger ()
-    : m_itemNumber (0)
-  {}
-
-  template<typename T>
-  ParameterLogger& operator<< (T param)
-  {
-    switch (m_itemNumber)
-      {
-      case 0: // first item is actually the function name
-        std::clog << param << " (";
-        break;
-      case 1: // first parameter
-        if (m_parameterName)
-          {
-            std::clog << m_parameterName << "=" << param;
-            m_parameterName = 0;
-          }
-        else
-          {
-            std::clog << param;
-          }
-        break;
-      default: // parameter following a previous parameter
-        if (m_parameterName)
-          {
-            std::clog << ", " << m_parameterName << "=" << param;
-            m_parameterName = 0;
-          }
-        else
-          {
-            std::clog << ", " << param;
-          }
-        break;
-      }
-    m_itemNumber++;
-    return *this;
-  }
-
-  ParameterLogger&
-  operator << (ParameterName paramName)
-  {
-    m_parameterName = paramName.name;
-    return *this;
-  }
-  
-  ParameterLogger&
-  operator << (EndParameterListStruct dummy)
-  {
-    std::clog << ")" << std::endl;
-    m_itemNumber = 0;
-    return *this;
-  }
-};
-
-extern ParameterLogger g_parameterLogger;
-
-}
-
-
-
-/**
  * \param level the log level
  * \param msg the message to log
  *
@@ -187,73 +107,113 @@
     {                                                           \
       if (g_log.IsEnabled (level))                              \
         {                                                       \
-          if (g_log.IsEnabled (ns3::LOG_PREFIX_ALL))            \
-            {                                                   \
-              std::clog << g_log.Name () << ":" <<              \
-                __FUNCTION__ << "(): ";                         \
-            }                                                   \
+          APPEND_TIME_PREFIX;                                   \
+          APPEND_FUNC_PREFIX;                                   \
           std::clog << msg << std::endl;                        \
         }                                                       \
     }                                                           \
   while (false)
 
-#define NS_LOG_F(level)                                         \
+/**
+ * \ingroup logging
+ * \param msg the message to log
+ *
+ * Use \ref NS_LOG to output a message of level LOG_ERROR.
+ */
+#define NS_LOG_ERROR(msg) \
+  NS_LOG(ns3::LOG_ERROR, msg)
+
+/**
+ * \ingroup logging
+ * \param msg the message to log
+ *
+ * Use \ref NS_LOG to output a message of level LOG_WARN.
+ */
+#define NS_LOG_WARN(msg) \
+  NS_LOG(ns3::LOG_WARN, msg)
+
+/**
+ * \ingroup logging
+ * \param msg the message to log
+ *
+ * Use \ref NS_LOG to output a message of level LOG_DEBUG.
+ */
+#define NS_LOG_DEBUG(msg) \
+  NS_LOG(ns3::LOG_DEBUG, msg)
+
+/**
+ * \ingroup logging
+ * \param msg the message to log
+ *
+ * Use \ref NS_LOG to output a message of level LOG_INFO.
+ */
+#define NS_LOG_INFO(msg) \
+  NS_LOG(ns3::LOG_INFO, msg)
+
+/**
+ * \ingroup logging
+ *
+ * Output the name of the function.
+ */
+#define NS_LOG_FUNCTION_NOARGS()                                \
   do                                                            \
     {                                                           \
-      if (g_log.IsEnabled (level))                              \
+      if (g_log.IsEnabled (ns3::LOG_FUNCTION))                  \
         {                                                       \
-          std::clog << g_log.Name () << ":" << __FUNCTION__ <<  \
-            "()" << std::endl;                                \
+          APPEND_TIME_PREFIX;                                   \
+          std::clog << g_log.Name () << ":"                     \
+                    << __FUNCTION__ << "()" << std::endl;       \
         }                                                       \
     }                                                           \
   while (false)
 
-#define NS_LOG_ERROR(msg) \
-  NS_LOG(ns3::LOG_ERROR, msg)
 
-#define NS_LOG_WARN(msg) \
-  NS_LOG(ns3::LOG_WARN, msg)
-
-#define NS_LOG_DEBUG(msg) \
-  NS_LOG(ns3::LOG_DEBUG, msg)
-
-#define NS_LOG_INFO(msg) \
-  NS_LOG(ns3::LOG_INFO, msg)
-
-#define NS_LOG_FUNCTION \
-  NS_LOG_F(ns3::LOG_FUNCTION)
-
-
-
-#define NS_LOG_PARAMS(parameters)                       \
+/**
+ * \ingroup logging
+ * \param parameters the parameters to output.
+ *
+ * If log level LOG_FUNCTION is enabled, this macro will output
+ * all input parameters separated by ", ".
+ *
+ * Typical usage looks like:
+ * \code
+ * NS_LOG_FUNCTION (aNumber<<anotherNumber);
+ * \endcode
+ * And the output will look like:
+ * \code
+ * Component:Function (aNumber, anotherNumber)
+ * \endcode
+ */
+#define NS_LOG_FUNCTION(parameters)                     \
   do                                                    \
     {                                                   \
-      if (g_log.IsEnabled (ns3::LOG_PARAM))             \
+      if (g_log.IsEnabled (ns3::LOG_FUNCTION))          \
         {                                               \
-          g_parameterLogger << __PRETTY_FUNCTION__      \
-                            << parameters               \
-                            << EndParameterList;        \
+          APPEND_TIME_PREFIX;                           \
+          std::clog << g_log.Name () << ":"             \
+                    << __FUNCTION__ << "(";             \
+          ParameterLogger (std::clog)  << parameters;   \
+          std::clog << ")" << std::endl;                \
         }                                               \
     }                                                   \
   while (false)
 
 
-#define NS_LOG_PARAMS_BEGIN()                           \
-      if (g_log.IsEnabled (ns3::LOG_PARAM))             \
-        {                                               \
-          g_parameterLogger << __PRETTY_FUNCTION__;
-
-#define NS_LOG_PARAM(param) \
-          g_parameterLogger << ParameterName (#param) << param;
-
-#define NS_LOG_PARAMS_END()                             \
-          g_parameterLogger << EndParameterList;        \
-        }
-
-
+/**
+ * \ingroup logging
+ * \param msg the message to log
+ *
+ * Use \ref NS_LOG to output a message of level LOG_LOGIC
+ */
 #define NS_LOG_LOGIC(msg) \
   NS_LOG(ns3::LOG_LOGIC, msg)
 
+/**
+ * \ingroup logging
+ * \param msg the message to log
+ *
+ * Output the requested message unconditionaly.
+ */
 #define NS_LOG_UNCOND(msg)              \
   do                                    \
     {                                   \
@@ -261,28 +221,8 @@
     }                                   \
   while (false)
 
-#else
-
-#define NS_LOG(level, msg)
-#define NS_LOG_F(level)
-#define NS_LOG_ERROR(msg)
-#define NS_LOG_WARN(msg)
-#define NS_LOG_DEBUG(msg)
-#define NS_LOG_INFO(msg)
-#define NS_LOG_FUNCTION
-#define NS_LOG_PARAMS(parameters)
-#define NS_LOG_PARAMS_BEGIN()
-#define NS_LOG_PARAM(param)
-#define NS_LOG_PARAMS_END()
-#define NS_LOG_LOGIC(msg)
-#define NS_LOG_UNCOND(msg)
-
-#endif
-
 namespace ns3 {
 
-#ifdef NS3_LOG_ENABLE
-
 enum LogLevel {
   LOG_NONE           = 0x00000000, // no logging
 
@@ -301,21 +241,16 @@
   LOG_FUNCTION       = 0x00000010, // function tracing
   LOG_LEVEL_FUNCTION = 0x0000001f, 
 
-  LOG_PARAM          = 0x00000020, // parameters to functions
-  LOG_LEVEL_PARAM    = 0x0000003f,
+  LOG_LOGIC          = 0x00000020, // control flow tracing within functions
+  LOG_LEVEL_LOGIC    = 0x0000003f,
 
-  LOG_LOGIC          = 0x00000040, // control flow tracing within functions
-  LOG_LEVEL_LOGIC    = 0x0000007f,
-
-  LOG_ALL            = 0x7fffffff, // print everything
+  LOG_ALL            = 0x3fffffff, // print everything
   LOG_LEVEL_ALL      = LOG_ALL,
 
-  LOG_PREFIX_ALL     = 0x80000000  // prefix all trace prints with function
+  LOG_PREFIX_FUNC    = 0x80000000, // prefix all trace prints with function
+  LOG_PREFIX_TIME    = 0x40000000  // prefix all trace prints with simulation time
 };
 
-#endif
-
-#ifdef NS3_LOG_ENABLE
 /**
  * \param name a log component name
  * \param level a logging level
@@ -324,22 +259,24 @@
  * Enable the logging output associated with that log component.
  * The logging output can be later disabled with a call
  * to ns3::LogComponentDisable.
+ *
+ * Same as running your program with the NS_LOG environment
+ * variable set as NS_LOG='name=level'
  */
-  void LogComponentEnable (char const *name, enum LogLevel level);
+void LogComponentEnable (char const *name, enum LogLevel level);
 
 /**
  * \param level a logging level
  * \ingroup logging
  *
  * Enable the logging output for all registered log components.
+ *
+ * Same as running your program with the NS_LOG environment
+ * variable set as NS_LOG='*=level'
  */
-  void LogComponentEnableAll (enum LogLevel level);
-#else
-#define LogComponentEnable(a,b)
-#define LogComponentEnableAll(a)
-#endif
+void LogComponentEnableAll (enum LogLevel level);
 
-#ifdef NS3_LOG_ENABLE
+
 /**
  * \param name a log component name
  * \param level a logging level
@@ -359,23 +296,21 @@
  */
 void LogComponentDisableAll (enum LogLevel level);
 
-#else
-#define LogComponentDisable(a,b)
-#define LogComponentDisableAll(a)
-#endif
 
 /**
  * \ingroup logging
  *
  * Print the list of logging messages available.
+ * Same as running your program with the NS_LOG environment
+ * variable set as NS_LOG=print-list
  */
-#ifdef NS3_LOG_ENABLE
 void LogComponentPrintList (void);
-#else
-#define LogComponentPrintList()
-#endif
+
+typedef void (*LogTimePrinter) (std::ostream &os);
 
-#ifdef NS3_LOG_ENABLE
+void LogRegisterTimePrinter (LogTimePrinter);
+LogTimePrinter LogGetTimePrinter(void);
+
 
 class LogComponent {
 public:
@@ -393,8 +328,52 @@
   bool        m_decorate;
 };
 
-#endif
+class ParameterLogger : public std::ostream
+{
+  int m_itemNumber;
+  std::ostream &m_os;
+public:
+  ParameterLogger (std::ostream &os);
+
+  template<typename T>
+  ParameterLogger& operator<< (T param)
+  {
+    switch (m_itemNumber)
+      {
+      case 0: // first parameter
+        m_os << param;
+        break;
+      default: // parameter following a previous parameter
+        m_os << ", " << param;
+        break;
+      }
+    m_itemNumber++;
+    return *this;
+  }
+};
 
 } // namespace ns3
 
+#else /* LOG_ENABLE */
+
+#define NS_LOG_COMPONENT_DEFINE(component)
+#define NS_LOG(level, msg)
+#define NS_LOG_ERROR(msg)
+#define NS_LOG_WARN(msg)
+#define NS_LOG_DEBUG(msg)
+#define NS_LOG_INFO(msg)
+#define NS_LOG_FUNCTION_NOARGS()
+#define NS_LOG_FUNCTION(msg)
+#define NS_LOG_LOGIC(msg)
+#define NS_LOG_UNCOND(msg)
+
+#define LogComponentPrintList
+#define LogComponentEnable(name,level)
+#define LogComponentDisable(name,level)
+#define LogComponentEnableAll(level)
+#define LogComponentDisableAll(level)
+#define LogRegisterTimePrinter(printer)
+
+#endif /* LOG_ENABLE */
+
 #endif // __LOG_H__
--- a/src/core/object-base.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/object-base.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -20,6 +20,7 @@
 #include "object-base.h"
 #include "log.h"
 #include "trace-source-accessor.h"
+#include "attribute-list.h"
 #include "string.h"
 
 NS_LOG_COMPONENT_DEFINE ("ObjectBase");
@@ -58,8 +59,8 @@
     NS_LOG_DEBUG ("construct tid="<<tid.GetName ()<<", params="<<tid.GetAttributeN ());
     for (uint32_t i = 0; i < tid.GetAttributeN (); i++)
       {
-        Ptr<const AttributeAccessor> paramSpec = tid.GetAttributeAccessor (i);
-        Attribute initial = tid.GetAttributeInitialValue (i);
+        Ptr<const AttributeAccessor> accessor = tid.GetAttributeAccessor (i);
+        Ptr<const AttributeValue> initial = tid.GetAttributeInitialValue (i);
         Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (i);
         NS_LOG_DEBUG ("try to construct \""<< tid.GetName ()<<"::"<<
                       tid.GetAttributeName (i)<<"\"");
@@ -75,7 +76,7 @@
             if (j->checker == checker)
               {
                 // We have a matching attribute value.
-                DoSet (paramSpec, initial, checker, j->value);
+                DoSet (accessor, checker, *j->value);
                 NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
                               tid.GetAttributeName (i)<<"\"");
                 found = true;
@@ -91,7 +92,7 @@
                 if (j->checker == checker)
                   {
                     // We have a matching attribute value.
-                    DoSet (paramSpec, initial, checker, j->value);
+                    DoSet (accessor, checker, *j->value);
                     NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
                                   tid.GetAttributeName (i)<<"\" from global");
                     found = true;
@@ -102,7 +103,7 @@
         if (!found)
           {
             // No matching attribute value so we set the default value.
-            paramSpec->Set (this, initial);
+            DoSet (accessor, checker, *initial);
             NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
                           tid.GetAttributeName (i)<<"\" from initial value.");
           }
@@ -113,70 +114,39 @@
 }
 
 bool
-ObjectBase::DoSet (Ptr<const AttributeAccessor> spec, Attribute initialValue, 
-		   Ptr<const AttributeChecker> checker, Attribute value)
+ObjectBase::DoSet (Ptr<const AttributeAccessor> spec, 
+		   Ptr<const AttributeChecker> checker, 
+                   const AttributeValue &value)
 {
   bool ok = checker->Check (value);
+  if (ok)
+    {
+      ok = spec->Set (this, value);
+      return ok;
+    }
+  // attempt to convert to string
+  const StringValue *str = dynamic_cast<const StringValue *> (&value);
+  if (str == 0)
+    {
+      return false;
+    }
+  // attempt to convert back from string.
+  Ptr<AttributeValue> v = checker->Create ();
+  ok = v->DeserializeFromString (str->Get (), checker);
   if (!ok)
     {
-      // attempt to convert to string
-      const StringValue *str = value.DynCast<const StringValue *> ();
-      if (str == 0)
-        {
-          return false;
-        }
-      // attempt to convert back from string.
-      Attribute v = checker->Create ();
-      ok = v.DeserializeFromString (str->Get ().Get (), checker);
-      if (!ok)
-        {
-          return false;
-        }
-      ok = checker->Check (v);
-      if (!ok)
-        {
-          return false;
-        }
-      value = v;
+      return false;
     }
-  ok = spec->Set (this, value);
+  ok = checker->Check (*v);
+  if (!ok)
+    {
+      return false;
+    }
+  ok = spec->Set (this, *v);
   return ok;
 }
 void
-ObjectBase::SetAttribute (std::string name, Attribute value)
-{
-  struct TypeId::AttributeInfo info;
-  TypeId tid = GetInstanceTypeId ();
-  if (!tid.LookupAttributeByName (name, &info))
-    {
-      NS_FATAL_ERROR ("Attribute name="<<name<<" does not exist for this object: tid="<<tid.GetName ());
-    }
-  if (!(info.flags & TypeId::ATTR_SET))
-    {
-      NS_FATAL_ERROR ("Attribute name="<<name<<" is not settable for this object: tid="<<tid.GetName ());
-    }
-  if (!DoSet (info.accessor, info.initialValue, info.checker, value))
-    {
-      NS_FATAL_ERROR ("Attribute name="<<name<<" could not be set for this object: tid="<<tid.GetName ());
-    }
-}
-bool 
-ObjectBase::SetAttributeFailSafe (std::string name, Attribute value)
-{
-  struct TypeId::AttributeInfo info;
-  TypeId tid = GetInstanceTypeId ();
-  if (!tid.LookupAttributeByName (name, &info))
-    {
-      return false;
-    }
-  if (!(info.flags & TypeId::ATTR_SET))
-    {
-      return false;
-    }
-  return DoSet (info.accessor, info.initialValue, info.checker, value);
-}
-std::string
-ObjectBase::GetAttributeAsString (std::string name) const
+ObjectBase::SetAttribute (std::string name, const AttributeValue &value)
 {
   struct TypeId::AttributeInfo info;
   TypeId tid = GetInstanceTypeId ();
@@ -184,44 +154,18 @@
     {
       NS_FATAL_ERROR ("Attribute name="<<name<<" does not exist for this object: tid="<<tid.GetName ());
     }
-  if (!(info.flags & TypeId::ATTR_GET))
+  if (!(info.flags & TypeId::ATTR_SET) ||
+      !info.accessor->HasSetter ())
     {
-      NS_FATAL_ERROR ("Attribute name="<<name<<" is not gettable for this object: tid="<<tid.GetName ());
+      NS_FATAL_ERROR ("Attribute name="<<name<<" is not settable for this object: tid="<<tid.GetName ());
     }
-  Attribute v = info.checker->Create ();
-  bool ok = info.accessor->Get (this, v);
-  if (!ok)
+  if (!DoSet (info.accessor, info.checker, value))
     {
-      NS_FATAL_ERROR ("Attribute name="<<name<<" is not gettable for this object: tid="<<tid.GetName ());
+      NS_FATAL_ERROR ("Attribute name="<<name<<" could not be set for this object: tid="<<tid.GetName ());
     }
-  std::string value = v.SerializeToString (info.checker);
-  return value;
 }
-
-Attribute
-ObjectBase::GetAttribute (std::string name) const
-{
-  struct TypeId::AttributeInfo info;
-  TypeId tid = GetInstanceTypeId ();
-  if (!tid.LookupAttributeByName (name, &info))
-    {
-      return Attribute ();
-    }
-  if (!(info.flags & TypeId::ATTR_GET))
-    {
-      return Attribute ();
-    }
-  Attribute value = info.checker->Create ();
-  bool ok = info.accessor->Get (this, value);
-  if (!ok)
-    {
-      return Attribute ();
-    }
-  return value;
-}
-
-bool
-ObjectBase::GetAttributeAsStringFailSafe (std::string name, std::string &value) const
+bool 
+ObjectBase::SetAttributeFailSafe (std::string name, const AttributeValue &value)
 {
   struct TypeId::AttributeInfo info;
   TypeId tid = GetInstanceTypeId ();
@@ -229,21 +173,50 @@
     {
       return false;
     }
-  if (!(info.flags & TypeId::ATTR_GET))
+  if (!(info.flags & TypeId::ATTR_SET) ||
+      !info.accessor->HasSetter ())
     {
       return false;
     }
-  Attribute v = info.checker->Create ();
-  bool ok = info.accessor->Get (this, v);
+  return DoSet (info.accessor, info.checker, value);
+}
+
+void
+ObjectBase::GetAttribute (std::string name, AttributeValue &value) const
+{
+  struct TypeId::AttributeInfo info;
+  TypeId tid = GetInstanceTypeId ();
+  if (!tid.LookupAttributeByName (name, &info))
+    {
+      NS_FATAL_ERROR ("Attribute name="<<name<<" does not exist for this object: tid="<<tid.GetName ());
+    }
+  if (!(info.flags & TypeId::ATTR_GET) || 
+      !info.accessor->HasGetter ())
+    {
+      NS_FATAL_ERROR ("Attribute name="<<name<<" is not gettable for this object: tid="<<tid.GetName ());
+    }
+  bool ok = info.accessor->Get (this, value);
   if (ok)
     {
-      value = v.SerializeToString (info.checker);
+      return;
+    }
+  StringValue *str = dynamic_cast<StringValue *> (&value);
+  if (str == 0)
+    {
+      NS_FATAL_ERROR ("Attribute name="<<name<<" tid="<<tid.GetName () << ": input value is not a string");
     }
-  return ok;
+  Ptr<AttributeValue> v = info.checker->Create ();
+  ok = info.accessor->Get (this, *PeekPointer (v));
+  if (!ok)
+    {
+      NS_FATAL_ERROR ("Attribute name="<<name<<" tid="<<tid.GetName () << ": could not get value");
+    }
+  str->Set (v->SerializeToString (info.checker));
 }
 
+
 bool
-ObjectBase::GetAttributeFailSafe (std::string name, Attribute &value) const
+ObjectBase::GetAttributeFailSafe (std::string name, AttributeValue &value) const
 {
   struct TypeId::AttributeInfo info;
   TypeId tid = GetInstanceTypeId ();
@@ -251,13 +224,29 @@
     {
       return false;
     }
-  if (!(info.flags & TypeId::ATTR_GET))
+  if (!(info.flags & TypeId::ATTR_GET) ||
+      !info.accessor->HasGetter ())
     {
       return false;
     }
-  value = info.checker->Create ();
   bool ok = info.accessor->Get (this, value);
-  return ok;
+  if (ok)
+    {
+      return true;
+    }
+  StringValue *str = dynamic_cast<StringValue *> (&value);
+  if (str == 0)
+    {
+      return false;
+    }
+  Ptr<AttributeValue> v = info.checker->Create ();
+  ok = info.accessor->Get (this, *PeekPointer (v));
+  if (!ok)
+    {
+      return false;
+    }
+  str->Set (v->SerializeToString (info.checker));
+  return true;
 }
 
 bool 
--- a/src/core/object-base.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/object-base.h	Tue Apr 22 21:19:39 2008 -0700
@@ -22,7 +22,6 @@
 
 #include "type-id.h"
 #include "callback.h"
-#include "attribute-list.h"
 #include <string>
 
 /**
@@ -40,6 +39,8 @@
 
 namespace ns3 {
 
+class AttributeList;
+
 /**
  * \brief implement the ns-3 type and attribute system
  *
@@ -72,35 +73,22 @@
    * Set a single attribute. This cannot fail: if the input is invalid,
    * it will crash immediately.
    */
-  void SetAttribute (std::string name, Attribute value);
+  void SetAttribute (std::string name, const AttributeValue &value);
   /**
    * \param name the name of the attribute to set
    * \param value the name of the attribute to set
    * \returns true if the requested attribute exists and could be set, 
    * false otherwise.
    */
-  bool SetAttributeFailSafe (std::string name, Attribute value);
+  bool SetAttributeFailSafe (std::string name, const AttributeValue &value);
   /**
    * \param name the name of the attribute to read
-   * \returns true if the requested attribute was found, false otherwise.
-   *
-   * If the input attribute name does not exist, this method crashes.
-   */
-  std::string GetAttributeAsString (std::string name) const;
-  /**
-   * \param name the name of the attribute to read
+   * \param value a reference to the value where the result should be stored.
    * \returns the attribute read.
    *
    * If the input attribute name does not exist, this method crashes.
    */
-  Attribute GetAttribute (std::string name) const;
-
-  /**
-   * \param name the name of the attribute to read
-   * \param value the string where the result value should be stored
-   * \returns true if the requested attribute was found, false otherwise.
-   */
-  bool GetAttributeAsStringFailSafe (std::string name, std::string &value) const;
+  void GetAttribute (std::string name, AttributeValue &value) const;
   /**
    * \param name the name of the attribute to read
    * \param attribute the attribute where the result value should be stored
@@ -108,7 +96,7 @@
    *
    * If the input attribute name does not exist, this method crashes.
    */
-  bool GetAttributeFailSafe (std::string name, Attribute &attribute) const;
+  bool GetAttributeFailSafe (std::string name, AttributeValue &attribute) const;
 
   /**
    * \param name the name of the targetted trace source
@@ -163,8 +151,9 @@
   void ConstructSelf (const AttributeList &attributes);
 
 private:
-  bool DoSet (Ptr<const AttributeAccessor> spec, Attribute intialValue, 
-              Ptr<const AttributeChecker> checker, Attribute value);
+  bool DoSet (Ptr<const AttributeAccessor> spec,
+              Ptr<const AttributeChecker> checker, 
+              const AttributeValue &value);
 
 };
 
--- a/src/core/object-factory.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/object-factory.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -41,7 +41,7 @@
   m_tid = TypeId::LookupByName (tid);
 }
 void 
-ObjectFactory::Set (std::string name, Attribute value)
+ObjectFactory::Set (std::string name, const AttributeValue &value)
 {
   if (name == "")
     {
@@ -70,12 +70,22 @@
 
 std::ostream & operator << (std::ostream &os, const ObjectFactory &factory)
 {
-  // XXX
+  os << factory.m_tid.GetName () << "[" << factory.m_parameters.SerializeToString () << "]";
   return os;
 }
 std::istream & operator >> (std::istream &is, ObjectFactory &factory)
 {
-  // XXX
+  std::string v;
+  is >> v;
+  std::string::size_type lbracket, rbracket;
+  lbracket = v.find ("[");
+  rbracket = v.find ("]");
+  NS_ASSERT (lbracket != std::string::npos);
+  NS_ASSERT (rbracket != std::string::npos);
+  std::string tid = v.substr (0, lbracket);
+  std::string parameters = v.substr (lbracket+1,rbracket-(lbracket+1));
+  factory.SetTypeId (tid);
+  factory.m_parameters.DeserializeFromString (parameters);
   return is;
 }
 
--- a/src/core/object-factory.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/object-factory.h	Tue Apr 22 21:19:39 2008 -0700
@@ -20,11 +20,14 @@
 #ifndef OBJECT_FACTORY_H
 #define OBJECT_FACTORY_H
 
-#include "attribute.h"
+#include "attribute-list.h"
 #include "object.h"
+#include "type-id.h"
 
 namespace ns3 {
 
+class AttributeValue;
+
 /**
  * \brief instantiate subclasses of ns3::Object.
  *
@@ -52,7 +55,7 @@
    * \param name the name of the attribute to set during object construction
    * \param value the value of the attribute to set during object construction
    */
-  void Set (std::string name, Attribute value);
+  void Set (std::string name, const AttributeValue &value);
 
   /**
    * \returns the currently-selected TypeId to use to create an object
@@ -76,6 +79,9 @@
 
   ATTRIBUTE_HELPER_HEADER_1 (ObjectFactory);
 private:
+  friend std::ostream & operator << (std::ostream &os, const ObjectFactory &factory);
+  friend std::istream & operator >> (std::istream &is, ObjectFactory &factory);
+
   TypeId m_tid;
   AttributeList m_parameters;
 };
@@ -83,6 +89,11 @@
 std::ostream & operator << (std::ostream &os, const ObjectFactory &factory);
 std::istream & operator >> (std::istream &is, ObjectFactory &factory);
 
+/**
+ * \class ns3::ObjectFactoryValue
+ * \brief hold objects of type ns3::ObjectFactory
+ */
+
 ATTRIBUTE_HELPER_HEADER_2 (ObjectFactory);
 
 } // namespace ns3
--- a/src/core/object-vector.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/object-vector.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -2,63 +2,34 @@
 
 namespace ns3 {
 
-ObjectVector::ObjectVector ()
+ObjectVectorValue::ObjectVectorValue ()
 {}
 
-ObjectVector::Iterator 
-ObjectVector::Begin (void) const
+ObjectVectorValue::Iterator 
+ObjectVectorValue::Begin (void) const
 {
   return m_objects.begin ();
 }
-ObjectVector::Iterator 
-ObjectVector::End (void) const
+ObjectVectorValue::Iterator 
+ObjectVectorValue::End (void) const
 {
   return m_objects.end ();
 }
 uint32_t 
-ObjectVector::GetN (void) const
+ObjectVectorValue::GetN (void) const
 {
   return m_objects.size ();
 }
 Ptr<Object> 
-ObjectVector::Get (uint32_t i) const
+ObjectVectorValue::Get (uint32_t i) const
 {
   return m_objects[i];
 }
 
-ObjectVector::ObjectVector (Attribute value)
-{
-  const ObjectVectorValue *v = value.DynCast<const ObjectVectorValue *> ();
-  if (v == 0)
-    {
-      NS_FATAL_ERROR ("Expected value of type ObjectVectorValue.");
-    }
-  *this = v->Get ();
-}
-
-ObjectVector::operator Attribute () const
-{
-  return Attribute::Create<ObjectVectorValue> ();
-}
-
-ObjectVectorValue::ObjectVectorValue ()
-  : m_vector ()
-{}
-
-ObjectVectorValue::ObjectVectorValue (const ObjectVector &vector)
-  : m_vector (vector)
-{}
-
-ObjectVector 
-ObjectVectorValue::Get (void) const
-{
-  return m_vector;
-}
-
-Attribute 
+Ptr<AttributeValue>
 ObjectVectorValue::Copy (void) const
 {
-  return Attribute::Create<ObjectVectorValue> (*this);
+  return ns3::Create<ObjectVectorValue> (*this);
 }
 std::string 
 ObjectVectorValue::SerializeToString (Ptr<const AttributeChecker> checker) const
@@ -69,25 +40,25 @@
 bool 
 ObjectVectorValue::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker)
 {
-  // XXX ?? Can we implement this correctly ?? I doubt it very much.
+  NS_FATAL_ERROR ("cannot deserialize a vector of object pointers.");
   return true;
 }
 
 bool 
-ObjectVectorAccessor::Set (ObjectBase * object, Attribute value) const
+ObjectVectorAccessor::Set (ObjectBase * object, const AttributeValue & value) const
 {
   // not allowed.
   return false;
 }
 bool 
-ObjectVectorAccessor::Get (const ObjectBase * object, Attribute value) const
+ObjectVectorAccessor::Get (const ObjectBase * object, AttributeValue &value) const
 {
-  ObjectVectorValue *v = value.DynCast<ObjectVectorValue *> ();
+  ObjectVectorValue *v = dynamic_cast<ObjectVectorValue *> (&value);
   if (v == 0)
     {
       return false;
     }
-  v->m_vector.m_objects.clear ();
+  v->m_objects.clear ();
   uint32_t n;
   bool ok = DoGetN (object, &n);
   if (!ok)
@@ -97,11 +68,19 @@
   for (uint32_t i = 0; i < n; i++)
     {
       Ptr<Object> o = DoGet (object, i);
-      v->m_vector.m_objects.push_back (o);
+      v->m_objects.push_back (o);
     }
   return true;
 }
-
-ATTRIBUTE_CHECKER_IMPLEMENT (ObjectVector);
+bool 
+ObjectVectorAccessor::HasGetter (void) const
+{
+  return true;
+}
+bool 
+ObjectVectorAccessor::HasSetter (void) const
+{
+  return false;
+}
 
 } // name
--- a/src/core/object-vector.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/object-vector.h	Tue Apr 22 21:19:39 2008 -0700
@@ -5,24 +5,44 @@
 #include "object.h"
 #include "ptr.h"
 #include "attribute.h"
-#include "attribute-helper.h"
 
 namespace ns3 {
 
-class ObjectVector
+/**
+ * \brief contain a vector of ns3::Object pointers.
+ *
+ * This class it used to get attribute access to an array of
+ * ns3::Object pointers.
+ */
+class ObjectVectorValue : public AttributeValue
 {
 public:
   typedef std::vector<Ptr<Object> >::const_iterator Iterator;
 
-  ObjectVector ();
+  ObjectVectorValue ();
 
+  /**
+   * \returns an iterator to the first object contained in this vector
+   */
   Iterator Begin (void) const;
+  /**
+   * \returns an iterator to the last object contained in this vector
+   */
   Iterator End (void) const;
+  /**
+   * \returns the number of objects contained in this vector.
+   */
   uint32_t GetN (void) const;
+  /**
+   * \param i the index of the requested object.
+   * \returns the requested object
+   */
   Ptr<Object> Get (uint32_t i) const;
 
-  ObjectVector (Attribute value);
-  operator Attribute () const;
+  virtual Ptr<AttributeValue> Copy (void) const;
+  virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const;
+  virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker);
+
 private:
   friend class ObjectVectorAccessor;
   std::vector<Ptr<Object> > m_objects;
@@ -42,35 +62,65 @@
 MakeObjectVectorAccessor (INDEX (T::*getN) (void) const,
 			  Ptr<U> (T::*get) (INDEX) const);
 
+class ObjectVectorChecker : public AttributeChecker
+{
+public:
+  virtual TypeId GetItemTypeId (void) const = 0;
+};
 
-ATTRIBUTE_CHECKER_DEFINE (ObjectVector);
+template <typename T>
+Ptr<const AttributeChecker> MakeObjectVectorChecker (void);
 
 } // namespace ns3
 
 namespace ns3 {
 
-class ObjectVectorValue : public AttributeValue
+namespace internal {
+
+template <typename T>
+class AnObjectVectorChecker : public ObjectVectorChecker
 {
 public:
-  ObjectVectorValue ();
-  ObjectVectorValue (const ObjectVector &vector);
-
-  ObjectVector Get (void) const;
+  virtual TypeId GetItemTypeId (void) const {
+    return T::GetTypeId ();
+  }
+  virtual bool Check (const AttributeValue &value) const {
+    return dynamic_cast<const ObjectVectorValue *> (&value) != 0;
+  }
+  virtual std::string GetValueTypeName (void) const {
+    return "ns3::ObjectVectorValue";
+  }
+  virtual bool HasUnderlyingTypeInformation (void) const {
+    return true;
+  }
+  virtual std::string GetUnderlyingTypeInformation (void) const {
+    return "ns3::Ptr< " + T::GetTypeId ().GetName () + " >";
+  }
+  virtual Ptr<AttributeValue> Create (void) const {
+    return ns3::Create<ObjectVectorValue> ();
+  }
+  virtual bool Copy (const AttributeValue &source, AttributeValue &destination) const {
+    const ObjectVectorValue *src = dynamic_cast<const ObjectVectorValue *> (&source);
+    ObjectVectorValue *dst = dynamic_cast<ObjectVectorValue *> (&destination);
+    if (src == 0 || dst == 0)
+      {
+	return false;
+      }
+    *dst = *src;
+    return true;    
+  }
+};
 
-  virtual Attribute Copy (void) const;
-  virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const;
-  virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker);
+} // namespace internal
 
-private:
-  friend class ObjectVectorAccessor;
-  ObjectVector m_vector;
-};
 
 class ObjectVectorAccessor : public AttributeAccessor
 {
 public:
-  virtual bool Set (ObjectBase * object, Attribute value) const;
-  virtual bool Get (const ObjectBase * object, Attribute value) const;
+  virtual bool Set (ObjectBase * object, const AttributeValue &value) const;
+  virtual bool Get (const ObjectBase * object, AttributeValue &value) const;
+  virtual bool HasGetter (void) const;
+  virtual bool HasSetter (void) const;
 private:
   virtual bool DoGetN (const ObjectBase *object, uint32_t *n) const = 0;
   virtual Ptr<Object> DoGet (const ObjectBase *object, uint32_t i) const = 0;
@@ -150,6 +200,13 @@
   return MakeObjectVectorAccessor (get, getN);
 }
 
+template <typename T>
+Ptr<const AttributeChecker> MakeObjectVectorChecker (void)
+{
+  return Create<internal::AnObjectVectorChecker<T> > ();
+}
+
+
 } // namespace ns3
 
 #endif /* OBJECT_VECTOR_H */
--- a/src/core/object.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/object.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -37,6 +37,32 @@
 
 NS_OBJECT_ENSURE_REGISTERED (Object);
 
+Object::AggregateIterator::AggregateIterator ()
+  : m_first (0),
+    m_current (0)
+{}
+
+bool 
+Object::AggregateIterator::HasNext (void) const
+{
+  if (m_current != 0 && m_current->m_next != PeekPointer (m_first))
+    {
+      return true;
+    }
+  return false;
+}
+Ptr<const Object> 
+Object::AggregateIterator::Next (void)
+{
+  m_current = m_current->m_next;
+  return m_current;
+}
+Object::AggregateIterator::AggregateIterator (Ptr<const Object> first)
+  : m_first (first),
+    m_current (first)
+{}
+
+
 TypeId 
 Object::GetInstanceTypeId (void) const
 {
@@ -129,6 +155,12 @@
   NS_ASSERT (o->CheckLoose ());
 }
 
+Object::AggregateIterator 
+Object::GetAggregateIterator (void) const
+{
+  return AggregateIterator (this);
+}
+
 void 
 Object::SetTypeId (TypeId tid)
 {
--- a/src/core/object.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/object.h	Tue Apr 22 21:19:39 2008 -0700
@@ -47,6 +47,36 @@
 public:
   static TypeId GetTypeId (void);
 
+  /**
+   * \brief Iterate over the objects aggregated to an ns3::Object.
+   *
+   * This iterator does not allow you to iterate over the initial
+   * object used to call Object::GetAggregateIterator. 
+   *
+   * Note: this is a java-style iterator.
+   */
+  class AggregateIterator
+  {
+  public:
+    AggregateIterator ();
+
+    /**
+     * \returns true if HasNext can be called and return a non-null
+     *          pointer, false otherwise.
+     */
+    bool HasNext (void) const;
+
+    /**
+     * \returns the next aggregated object.
+     */
+    Ptr<const Object> Next (void);
+  private:
+    friend class Object;
+    AggregateIterator (Ptr<const Object> first);
+    Ptr<const Object> m_first;
+    Ptr<const Object> m_current;
+  };
+
   Object ();
   virtual ~Object ();
 
@@ -100,6 +130,16 @@
    */
   void AggregateObject (Ptr<Object> other);
 
+  /**
+   * \returns an iterator to the first object aggregated to this
+   *          object.
+   *
+   * If no objects are aggregated to this object, then, the returned
+   * iterator will be empty and AggregateIterator::HasNext will
+   * always return false.
+   */
+  AggregateIterator GetAggregateIterator (void) const;
+
 protected:
   /**
    * This method is called by Object::Dispose or by the object's 
@@ -137,8 +177,11 @@
   friend Ptr<T> CreateObject (const AttributeList &attributes);
   template <typename T>
   friend Ptr<T> CopyObject (Ptr<T> object);
+  template <typename T>
+  friend Ptr<T> CopyObject (Ptr<const T> object);
 
   friend class ObjectFactory;
+  friend class AggregateIterator;
 
   Ptr<Object> DoGetObject (TypeId tid) const;
   bool Check (void) const;
@@ -203,8 +246,11 @@
  * and returns the new instance.
  */
 template <typename T>
+Ptr<T> CopyObject (Ptr<const T> object);
+template <typename T>
 Ptr<T> CopyObject (Ptr<T> object);
 
+
 /**
  * \param attributes a list of attributes to set on the 
  *        object during construction.
@@ -242,15 +288,15 @@
  */
 template <typename T>
 Ptr<T> 
-CreateObject (std::string n1 = "", Attribute v1 = Attribute (),
-              std::string n2 = "", Attribute v2 = Attribute (),
-              std::string n3 = "", Attribute v3 = Attribute (),
-              std::string n4 = "", Attribute v4 = Attribute (),
-              std::string n5 = "", Attribute v5 = Attribute (),
-              std::string n6 = "", Attribute v6 = Attribute (),
-              std::string n7 = "", Attribute v7 = Attribute (),
-              std::string n8 = "", Attribute v8 = Attribute (),
-              std::string n9 = "", Attribute v9 = Attribute ());
+CreateObject (std::string n1 = "", const AttributeValue & v1 = EmptyAttributeValue (),
+              std::string n2 = "", const AttributeValue & v2 = EmptyAttributeValue (),
+              std::string n3 = "", const AttributeValue & v3 = EmptyAttributeValue (),
+              std::string n4 = "", const AttributeValue & v4 = EmptyAttributeValue (),
+              std::string n5 = "", const AttributeValue & v5 = EmptyAttributeValue (),
+              std::string n6 = "", const AttributeValue & v6 = EmptyAttributeValue (),
+              std::string n7 = "", const AttributeValue & v7 = EmptyAttributeValue (),
+              std::string n8 = "", const AttributeValue & v8 = EmptyAttributeValue (),
+              std::string n9 = "", const AttributeValue & v9 = EmptyAttributeValue ());
   
 
 
@@ -314,6 +360,14 @@
   return p;
 }
 
+template <typename T>
+Ptr<T> CopyObject (Ptr<const T> object)
+{
+  Ptr<T> p = Ptr<T> (new T (*PeekPointer (object)), false);
+  NS_ASSERT (p->m_tid == object->m_tid);
+  return p;
+}
+
 
 template <typename T>
 Ptr<T> CreateObject (const AttributeList &attributes)
@@ -326,16 +380,15 @@
 
 template <typename T>
 Ptr<T> 
-CreateObject (std::string n1 = "", Attribute v1 = Attribute (),
-              std::string n2 = "", Attribute v2 = Attribute (),
-              std::string n3 = "", Attribute v3 = Attribute (),
-              std::string n4 = "", Attribute v4 = Attribute (),
-              std::string n5 = "", Attribute v5 = Attribute (),
-              std::string n6 = "", Attribute v6 = Attribute (),
-              std::string n7 = "", Attribute v7 = Attribute (),
-              std::string n8 = "", Attribute v8 = Attribute (),
-              std::string n9 = "", Attribute v9 = Attribute ())
-  
+CreateObject (std::string n1 = "", const AttributeValue & v1 = EmptyAttributeValue (),
+              std::string n2 = "", const AttributeValue & v2 = EmptyAttributeValue (),
+              std::string n3 = "", const AttributeValue & v3 = EmptyAttributeValue (),
+              std::string n4 = "", const AttributeValue & v4 = EmptyAttributeValue (),
+              std::string n5 = "", const AttributeValue & v5 = EmptyAttributeValue (),
+              std::string n6 = "", const AttributeValue & v6 = EmptyAttributeValue (),
+              std::string n7 = "", const AttributeValue & v7 = EmptyAttributeValue (),
+              std::string n8 = "", const AttributeValue & v8 = EmptyAttributeValue (),
+              std::string n9 = "", const AttributeValue & v9 = EmptyAttributeValue ())
 {
   AttributeList attributes;
   if (n1 == "")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/pointer.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -0,0 +1,64 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "pointer.h"
+
+namespace ns3 {
+
+PointerValue::PointerValue ()
+  : m_value ()
+{}
+
+PointerValue::PointerValue (Ptr<Object> object)
+  : m_value (object)
+{}
+
+void 
+PointerValue::SetObject (Ptr<Object> object)
+{
+  m_value = object;
+}
+
+Ptr<Object> 
+PointerValue::GetObject (void) const
+{
+  return m_value;
+}
+
+Ptr<AttributeValue> 
+PointerValue::Copy (void) const
+{
+  return Create<PointerValue> (*this);
+}
+std::string 
+PointerValue::SerializeToString (Ptr<const AttributeChecker> checker) const
+{
+  std::ostringstream oss;
+  oss << m_value;
+  return oss.str ();
+}
+
+bool 
+PointerValue::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker)
+{
+  NS_FATAL_ERROR ("It is not possible to deserialize a pointer.");
+  return false;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/pointer.h	Tue Apr 22 21:19:39 2008 -0700
@@ -0,0 +1,338 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef NS_POINTER_H
+#define NS_POINTER_H
+
+#include "attribute.h"
+#include "object.h"
+
+namespace ns3 {
+
+/**
+ * \brief hold objects of type Ptr<T>
+ */
+class PointerValue : public AttributeValue
+{
+public:
+  PointerValue ();
+
+  PointerValue (Ptr<Object> object);
+
+  void SetObject (Ptr<Object> object);
+
+  Ptr<Object> GetObject (void) const;
+
+  template <typename T>
+  PointerValue (const Ptr<T> &object);
+
+  template <typename T>
+  void Set (const Ptr<T> &object);
+
+  template <typename T>
+  Ptr<T> Get (void) const;
+
+  template <typename T>
+  operator Ptr<T> () const;
+
+  virtual Ptr<AttributeValue> Copy (void) const;
+  virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const;
+  virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker);
+
+private:
+  Ptr<Object> m_value;
+};
+
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (Ptr<U> T::*memberVariable);
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (void (T::*setter) (Ptr<U>));
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (Ptr<U> (T::*getter) (void) const);
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (void (T::*setter) (Ptr<U>),
+		     Ptr<U> (T::*getter) (void) const);
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (Ptr<U> (T::*getter) (void) const,
+		     void (T::*setter) (Ptr<U>));
+
+class PointerChecker : public AttributeChecker 
+{
+public:
+  virtual TypeId GetPointeeTypeId (void) const = 0;
+};
+template <typename T>
+Ptr<AttributeChecker> MakePointerChecker (void);
+
+} // namespace ns3
+
+namespace ns3 {
+
+
+namespace internal {
+
+template <typename T>
+class APointerChecker : public PointerChecker
+{
+  virtual bool Check (const AttributeValue &val) const {
+    const PointerValue *value = dynamic_cast<const PointerValue *> (&val);
+    if (value == 0)
+      {
+	return false;
+      }
+    if (value->GetObject () == 0)
+      {
+	return true;
+      }
+    T *ptr = dynamic_cast<T*> (PeekPointer (value->GetObject ()));
+    if (ptr == 0)
+      {
+	return false;
+      }
+    return true;
+  }
+  virtual std::string GetValueTypeName (void) const {
+    return "ns3::PointerValue";
+  }
+  virtual bool HasUnderlyingTypeInformation (void) const {
+    return true;
+  }
+  virtual std::string GetUnderlyingTypeInformation (void) const {
+    TypeId tid = T::GetTypeId ();
+    return "ns3::Ptr< " + tid.GetName () + " >";
+  }
+  virtual Ptr<AttributeValue> Create (void) const {
+    return ns3::Create<PointerValue> ();
+  }
+  virtual bool Copy (const AttributeValue &source, AttributeValue &destination) const {
+    const PointerValue *src = dynamic_cast<const PointerValue *> (&source);
+    PointerValue *dst = dynamic_cast<PointerValue *> (&destination);
+    if (src == 0 || dst == 0)
+      {
+        return false;
+      }
+    *dst = *src;
+    return true;
+  }
+  virtual TypeId GetPointeeTypeId (void) const {
+    return T::GetTypeId ();
+  }
+};
+
+/********************************************************
+ *              The Accessor associated to 
+ *               PointerValue
+ ********************************************************/
+
+template <typename T, typename U>
+class PointerAccessor : public AttributeAccessor
+{
+public:
+  virtual ~PointerAccessor () {}
+  virtual bool Set (ObjectBase * object, const AttributeValue &val) const {
+      T *obj = dynamic_cast<T *> (object);
+      if (obj == 0)
+        {
+          return false;
+        }
+      const PointerValue *value = dynamic_cast<const PointerValue *> (&val);
+      if (value == 0)
+        {
+          return false;
+        }
+      Ptr<U> ptr = dynamic_cast<U*> (PeekPointer (value->GetObject ()));
+      if (ptr == 0)
+        {
+          return false;
+        }
+      DoSet (obj, ptr);
+      return true;
+    }
+  virtual bool Get (const ObjectBase * object, AttributeValue &val) const {
+      const T *obj = dynamic_cast<const T *> (object);
+      if (obj == 0)
+        {
+          return false;
+        }
+      PointerValue *value = dynamic_cast<PointerValue *> (&val);
+      if (value == 0)
+        {
+          return false;
+        }
+      value->Set (DoGet (obj));
+      return true;
+    }
+private:
+  virtual void DoSet (T *object, Ptr<U> value) const = 0;
+  virtual Ptr<U> DoGet (const T *object) const = 0;
+};
+
+} // namespace internal
+
+
+template <typename T>
+PointerValue::PointerValue (const Ptr<T> &object)
+{
+  m_value = object;
+}
+
+template <typename T>
+void 
+PointerValue::Set (const Ptr<T> &object)
+{
+  m_value = object;
+}
+
+template <typename T>
+Ptr<T> 
+PointerValue::Get (void) const
+{
+  T *v = dynamic_cast<T *> (PeekPointer (m_value));
+  return v;
+}
+
+template <typename T>
+PointerValue::operator Ptr<T> () const
+{
+  return Get<T> ();
+}
+
+
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (Ptr<U> T::*memberVariable)
+{
+  struct MemberVariable : public internal::PointerAccessor<T,U>
+  {
+    Ptr<U> T::*m_memberVariable;
+    virtual void DoSet (T *object, Ptr<U> value) const {
+      (object->*m_memberVariable) = value;
+    }
+    virtual Ptr<U> DoGet (const T *object) const {
+      return object->*m_memberVariable;
+    }
+    virtual bool HasGetter (void) const {
+      return true;
+    }
+    virtual bool HasSetter (void) const {
+      return true;
+    }
+  } *spec = new MemberVariable ();
+  spec->m_memberVariable = memberVariable;
+  return Ptr<const AttributeAccessor> (spec, false);
+}
+
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (void (T::*setter) (Ptr<U>))
+{
+  struct MemberMethod : public internal::PointerAccessor<T,U>
+  {
+    void (T::*m_setter) (Ptr<U>);
+    virtual void DoSet (T *object, Ptr<U> value) const {
+      (object->*m_setter) (value);
+    }
+    virtual Ptr<U> DoGet (const T *object) const {
+      return 0;
+      //return (object->*m_getter) ();
+    }
+    virtual bool HasGetter (void) const {
+      return false;
+    }
+    virtual bool HasSetter (void) const {
+      return true;
+    }
+  } *spec = new MemberMethod ();
+  spec->m_setter = setter;
+  return Ptr<const AttributeAccessor> (spec, false);
+}
+
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (Ptr<U> (T::*getter) (void) const)
+{
+  struct MemberMethod : public internal::PointerAccessor<T,U>
+  {
+    Ptr<U> (T::*m_getter) (void) const;
+    virtual void DoSet (T *object, Ptr<U> value) const {
+      //(object->*m_setter) (value);
+    }
+    virtual Ptr<U> DoGet (const T *object) const {
+      return (object->*m_getter) ();
+    }
+    virtual bool HasGetter (void) const {
+      return true;
+    }
+    virtual bool HasSetter (void) const {
+      return false;
+    }
+  } *spec = new MemberMethod ();
+  spec->m_getter = getter;
+  return Ptr<const AttributeAccessor> (spec, false);
+}
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (void (T::*setter) (Ptr<U>),
+		     Ptr<U> (T::*getter) (void) const)
+{
+  return MakePointerAccessor (getter, setter);
+}
+template <typename T, typename U>
+Ptr<const AttributeAccessor>
+MakePointerAccessor (Ptr<U> (T::*getter) (void) const,
+		     void (T::*setter) (Ptr<U>))
+{
+  struct MemberMethod : public internal::PointerAccessor<T,U>
+  {
+    void (T::*m_setter) (Ptr<U>);
+    Ptr<U> (T::*m_getter) (void) const;
+    virtual void DoSet (T *object, Ptr<U> value) const {
+      (object->*m_setter) (value);
+    }
+    virtual Ptr<U> DoGet (const T *object) const {
+      return (object->*m_getter) ();
+    }
+    virtual bool HasGetter (void) const {
+      return true;
+    }
+    virtual bool HasSetter (void) const {
+      return true;
+    }
+  } *spec = new MemberMethod ();
+  spec->m_setter = setter;
+  spec->m_getter = getter;
+  return Ptr<const AttributeAccessor> (spec, false);
+}
+
+template <typename T>
+Ptr<AttributeChecker>
+MakePointerChecker (void)
+{
+  return Create<internal::APointerChecker<T> > ();
+}
+
+
+} // namespace ns3
+
+#endif /* NS_POINTER_H */
--- a/src/core/ptr.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/ptr.h	Tue Apr 22 21:19:39 2008 -0700
@@ -447,7 +447,6 @@
   return *m_ptr;
 }
 
-
 template <typename T>
 bool 
 Ptr<T>::operator! () 
--- a/src/core/random-variable.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/random-variable.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -299,20 +299,6 @@
 {
   return m_variable;
 }
-RandomVariable::RandomVariable (Attribute value)
-  : m_variable (0)
-{
-  const RandomVariableValue *v = value.DynCast<const RandomVariableValue *> ();
-  if (v == 0)
-    {
-      NS_FATAL_ERROR ("Unexpected type of value. Expected \"RandomVariableValue\"");
-    }
-  *this = v->Get ();
-}
-RandomVariable::operator Attribute () const
-{
-  return Attribute::Create<RandomVariableValue> (*this);
-}
 
 ATTRIBUTE_VALUE_IMPLEMENT (RandomVariable);
 ATTRIBUTE_CHECKER_IMPLEMENT (RandomVariable);
@@ -1267,7 +1253,7 @@
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-// Integer EmpiricalVariableImpl methods
+// IntegerValue EmpiricalVariableImpl methods
 class IntEmpiricalVariableImpl : public EmpiricalVariableImpl {
 public:
 
--- a/src/core/random-variable.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/random-variable.h	Tue Apr 22 21:19:39 2008 -0700
@@ -163,10 +163,6 @@
    */
   static void SetRunNumber(uint32_t n);
 
-
-  RandomVariable (Attribute value);
-  operator Attribute () const;
-
 private:
   friend std::ostream &operator << (std::ostream &os, const RandomVariable &var);
   friend std::istream &operator >> (std::istream &os, RandomVariable &var);
@@ -666,6 +662,11 @@
 std::ostream &operator << (std::ostream &os, const RandomVariable &var);
 std::istream &operator >> (std::istream &os, RandomVariable &var);
 
+/**
+ * \class ns3::RandomVariableValue
+ * \brief hold objects of type ns3::RandomVariable
+ */
+
 ATTRIBUTE_VALUE_DEFINE (RandomVariable);
 ATTRIBUTE_CHECKER_DEFINE (RandomVariable);
 ATTRIBUTE_ACCESSOR_DEFINE (RandomVariable);
--- a/src/core/ref-count-base.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/ref-count-base.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -30,6 +30,15 @@
 {
 }
 
+RefCountBase::RefCountBase (const RefCountBase &o)
+ : m_count (1)
+{}
+RefCountBase &
+RefCountBase::operator = (const RefCountBase &o)
+{
+  return *this;
+}
+
 RefCountBase::~RefCountBase () 
 {
 }
--- a/src/core/ref-count-base.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/ref-count-base.h	Tue Apr 22 21:19:39 2008 -0700
@@ -41,6 +41,8 @@
 { 
 public:
   RefCountBase();
+  RefCountBase (const RefCountBase &o);
+  RefCountBase &operator = (const RefCountBase &o);
   virtual ~RefCountBase ();
   /**
    * Increment the reference count. This method should not be called
--- a/src/core/string.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/string.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -2,44 +2,8 @@
 
 namespace ns3 {
 
-String::String ()
-  : m_value ()
-{}
-String::String (const char *value)
-  : m_value (value)
-{}
-String::String (std::string value)
-  : m_value (value)
-{}
-void 
-String::Set (std::string value)
-{
-  m_value = value;
-}
-void 
-String::Set (const char *value)
-{
-  m_value = value;
-}
-std::string 
-String::Get (void) const
-{
-  return m_value;
-}
-
-std::ostream & operator << (std::ostream &os, const String &value)
-{
-  os << value.Get ();
-  return os;
-}
-std::istream &operator >> (std::istream &is, String &value)
-{
-  std::string str;
-  is >> str;
-  value = String (str);
-  return is;
-}
-
-ATTRIBUTE_HELPER_CPP (String);
+ATTRIBUTE_CHECKER_IMPLEMENT_WITH_NAME (String, "std::string");
+ATTRIBUTE_CONVERTER_IMPLEMENT (String);
+ATTRIBUTE_VALUE_IMPLEMENT_WITH_NAME (std::string, String);
 
 } // namespace ns3
--- a/src/core/string.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/string.h	Tue Apr 22 21:19:39 2008 -0700
@@ -7,30 +7,16 @@
 namespace ns3 {
 
 /**
+ * \class ns3::StringValue
  * \brief hold variables of type string
  *
  * This class can be used to hold variables of type string,
  * that is, either char * or std::string.
  */
-class String
-{
-public:
-  String ();
-  String (const char *value);
-  String (std::string value);
-  void Set (std::string value);
-  void Set (const char *value);
-  std::string Get (void) const;
 
-  ATTRIBUTE_HELPER_HEADER_1 (String);
-private:
-  std::string m_value;
-};
-
-std::ostream & operator << (std::ostream &os, const String &value);
-std::istream &operator >> (std::istream &is, String &value);
-
-ATTRIBUTE_HELPER_HEADER_2 (String);
+ATTRIBUTE_VALUE_DEFINE_WITH_NAME (std::string, String);
+ATTRIBUTE_ACCESSOR_DEFINE (String);
+ATTRIBUTE_CHECKER_DEFINE (String);
 
 } // namespace ns3
 
--- a/src/core/traced-value.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/traced-value.h	Tue Apr 22 21:19:39 2008 -0700
@@ -1,3 +1,22 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
 #ifndef TRACED_VALUE_H
 #define TRACED_VALUE_H
 
@@ -41,25 +60,25 @@
     Set (o.m_v);
     return *this;
   }
-  TracedValue (const Integer &value) 
+  TracedValue (const IntegerValue &value) 
     : m_v (value.Get ()) {}
-  operator Integer () const {
-    return Integer (m_v);
+  operator IntegerValue () const {
+    return IntegerValue (m_v);
   }
-  TracedValue (const Uinteger &value)
+  TracedValue (const UintegerValue &value)
     : m_v (value.Get ()) {}
-  operator Uinteger () const {
-    return Uinteger (m_v);
+  operator UintegerValue () const {
+    return UintegerValue (m_v);
   }
-  TracedValue (const Boolean &value)
+  TracedValue (const BooleanValue &value)
     : m_v (value.Get ()) {}
-  operator Boolean () const {
-    return Boolean (m_v);
+  operator BooleanValue () const {
+    return BooleanValue (m_v);
   }
-  TracedValue (const Enum &value)
+  TracedValue (const EnumValue &value)
     : m_v (value.Get ()) {}
-  operator Enum () const {
-    return Enum (m_v);
+  operator EnumValue () const {
+    return EnumValue (m_v);
   }
   void ConnectWithoutContext (const CallbackBase &cb) {
     m_cb.ConnectWithoutContext (cb);
--- a/src/core/type-id.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/type-id.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -50,14 +50,14 @@
                      std::string name,
                      std::string help, 
                      uint32_t flags,
-                     ns3::Attribute initialValue,
+                     ns3::Ptr<const ns3::AttributeValue> initialValue,
                      ns3::Ptr<const ns3::AttributeAccessor> spec,
                      ns3::Ptr<const ns3::AttributeChecker> checker);
   uint32_t GetAttributeN (uint16_t uid) const;
   std::string GetAttributeName (uint16_t uid, uint32_t i) const;
   std::string GetAttributeHelp (uint16_t uid, uint32_t i) const;
   uint32_t GetAttributeFlags (uint16_t uid, uint32_t i) const;
-  ns3::Attribute GetAttributeInitialValue (uint16_t uid, uint32_t i) const;
+  ns3::Ptr<const ns3::AttributeValue> GetAttributeInitialValue (uint16_t uid, uint32_t i) const;
   ns3::Ptr<const ns3::AttributeAccessor> GetAttributeAccessor (uint16_t uid, uint32_t i) const;
   ns3::Ptr<const ns3::AttributeChecker> GetAttributeChecker (uint16_t uid, uint32_t i) const;
   void AddTraceSource (uint16_t uid,
@@ -75,7 +75,7 @@
     std::string name;
     std::string help;
     uint32_t flags;
-    ns3::Attribute initialValue;
+    ns3::Ptr<const ns3::AttributeValue> initialValue;
     ns3::Ptr<const ns3::AttributeAccessor> param;
     ns3::Ptr<const ns3::AttributeChecker> checker;
   };
@@ -236,7 +236,7 @@
                           std::string name,
                           std::string help, 
                           uint32_t flags,
-                          ns3::Attribute initialValue,
+                          ns3::Ptr<const ns3::AttributeValue> initialValue,
                           ns3::Ptr<const ns3::AttributeAccessor> spec,
                           ns3::Ptr<const ns3::AttributeChecker> checker)
 {
@@ -288,7 +288,7 @@
   NS_ASSERT (i < information->attributes.size ());
   return information->attributes[i].flags;
 }
-ns3::Attribute 
+ns3::Ptr<const ns3::AttributeValue> 
 IidManager::GetAttributeInitialValue (uint16_t uid, uint32_t i) const
 {
   struct IidInformation *information = LookupInformation (uid);
@@ -480,7 +480,7 @@
     {
       tmp = tmp.GetParent ();
     }
-  return tmp == other;
+  return tmp == other && *this != other;
 }
 std::string 
 TypeId::GetGroupName (void) const
@@ -512,11 +512,11 @@
 TypeId 
 TypeId::AddAttribute (std::string name,
                       std::string help, 
-                      Attribute initialValue,
+                      const AttributeValue &initialValue,
                       Ptr<const AttributeAccessor> param,
                       Ptr<const AttributeChecker> checker)
 {
-  Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, ATTR_SGC, initialValue, param, checker);
+  Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, ATTR_SGC, initialValue.Copy (), param, checker);
   return *this;
 }
 
@@ -524,11 +524,11 @@
 TypeId::AddAttribute (std::string name,
                       std::string help, 
                       uint32_t flags,
-                      Attribute initialValue,
+                      const AttributeValue &initialValue,
                       Ptr<const AttributeAccessor> param,
                       Ptr<const AttributeChecker> checker)
 {
-  Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, flags, initialValue, param, checker);
+  Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, flags, initialValue.Copy (), param, checker);
   return *this;
 }
 
@@ -569,10 +569,10 @@
 {
   return GetName () + "::" + GetAttributeName (i);
 }
-Attribute 
+Ptr<const AttributeValue>
 TypeId::GetAttributeInitialValue (uint32_t i) const
 {
-  Attribute value = Singleton<IidManager>::Get ()->GetAttributeInitialValue (m_tid, i);
+  Ptr<const AttributeValue> value = Singleton<IidManager>::Get ()->GetAttributeInitialValue (m_tid, i);
   return value;
 }
 Ptr<const AttributeAccessor>
@@ -696,4 +696,9 @@
   return a.m_tid != b.m_tid;
 }
 
+bool operator < (TypeId a, TypeId b)
+{
+  return a.m_tid < b.m_tid;
+}
+
 } // namespace ns3
--- a/src/core/type-id.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/type-id.h	Tue Apr 22 21:19:39 2008 -0700
@@ -163,7 +163,7 @@
    * \returns the value with which the associated attribute 
    *          is initialized.
    */
-  Attribute GetAttributeInitialValue (uint32_t i) const;
+  Ptr<const AttributeValue> GetAttributeInitialValue (uint32_t i) const;
   /**
    * \param i index into attribute array.
    * \returns the flags associated to the requested attribute.
@@ -264,7 +264,7 @@
    */
   TypeId AddAttribute (std::string name,
                        std::string help, 
-                       Attribute initialValue,
+                       const AttributeValue &initialValue,
                        Ptr<const AttributeAccessor> accessor,
                        Ptr<const AttributeChecker> checker);
 
@@ -283,7 +283,7 @@
   TypeId AddAttribute (std::string name,
                        std::string help, 
                        uint32_t flags,
-                       Attribute initialValue,
+                       const AttributeValue &initialValue,
                        Ptr<const AttributeAccessor> accessor,
                        Ptr<const AttributeChecker> checker);
 
@@ -308,7 +308,7 @@
     // The accessor associated to the attribute.
     Ptr<const AttributeAccessor> accessor;
     // The initial value associated to the attribute.
-    Attribute initialValue;
+    Ptr<const AttributeValue> initialValue;
     // The set of access control flags associated to the attribute.
     uint32_t flags;
     // The checker associated to the attribute.
@@ -357,6 +357,7 @@
   friend class AttributeList;
   friend bool operator == (TypeId a, TypeId b);
   friend bool operator != (TypeId a, TypeId b);
+  friend bool operator <  (TypeId a, TypeId b);
 
 
   /**
@@ -375,6 +376,15 @@
 
 std::ostream & operator << (std::ostream &os, TypeId tid);
 std::istream & operator >> (std::istream &is, TypeId &tid);
+bool operator == (TypeId a, TypeId b);
+bool operator != (TypeId a, TypeId b);
+bool operator <  (TypeId a, TypeId b);
+
+/**
+ * \class ns3::TypeIdValue
+ * \brief hold objects of type ns3::TypeId
+ */
+
 
 ATTRIBUTE_HELPER_HEADER_2 (TypeId);
 
--- a/src/core/uinteger.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/uinteger.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -23,40 +23,7 @@
 
 namespace ns3 {
 
-Uinteger::Uinteger (uint64_t value)
-  : m_value (value)
-{}
-Uinteger::Uinteger ()
-{}
-void 
-Uinteger::Set (uint64_t value)
-{
-  m_value = value;
-}
-uint64_t 
-Uinteger::Get (void) const
-{
-  return m_value;
-}
-Uinteger::operator uint64_t () const
-{
-  return m_value;
-}
-std::ostream & operator << (std::ostream &os, const Uinteger &uinteger)
-{
-  os << uinteger.Get ();
-  return os;
-}
-std::istream & operator >> (std::istream &is, Uinteger &uinteger)
-{
-  uint64_t v;
-  is >> v;
-  uinteger.Set (v);
-  return is;
-}
-
-ATTRIBUTE_CONVERTER_IMPLEMENT(Uinteger);
-ATTRIBUTE_VALUE_IMPLEMENT(Uinteger);
+ATTRIBUTE_VALUE_IMPLEMENT_WITH_NAME(uint64_t,Uinteger);
 
 namespace internal {
 
@@ -68,27 +35,37 @@
       : m_minValue (minValue),
         m_maxValue (maxValue),
         m_name (name) {}
-    virtual bool Check (Attribute value) const {
-      const UintegerValue *v = value.DynCast<const UintegerValue *> ();
+    virtual bool Check (const AttributeValue &value) const {
+      const UintegerValue *v = dynamic_cast<const UintegerValue *> (&value);
       if (v == 0)
 	{
 	  return false;
 	}
-      return v->Get ().Get () >= m_minValue && v->Get ().Get () <= m_maxValue;
+      return v->Get () >= m_minValue && v->Get () <= m_maxValue;
     }
-    virtual std::string GetType (void) const {
-      return m_name;
+    virtual std::string GetValueTypeName (void) const {
+      return "ns3::UintegerValue";
     }
-    virtual bool HasTypeConstraints (void) const {
+    virtual bool HasUnderlyingTypeInformation (void) const {
       return true;
     }
-    virtual std::string GetTypeConstraints (void) const {
+    virtual std::string GetUnderlyingTypeInformation (void) const {
       std::ostringstream oss;
-      oss << m_minValue << ":" << m_maxValue;
+      oss << m_name << " " << m_minValue << ":" << m_maxValue;
       return oss.str ();
     }
-    virtual Attribute Create (void) const {
-      return Attribute::Create<UintegerValue> ();
+    virtual Ptr<AttributeValue> Create (void) const {
+      return ns3::Create<UintegerValue> ();
+    }
+    virtual bool Copy (const AttributeValue &source, AttributeValue &destination) const {
+      const UintegerValue *src = dynamic_cast<const UintegerValue *> (&source);
+      UintegerValue *dst = dynamic_cast<UintegerValue *> (&destination);
+      if (src == 0 || dst == 0)
+        {
+          return false;
+        }
+      *dst = *src;
+      return true;
     }
     uint64_t m_minValue;
     uint64_t m_maxValue;
--- a/src/core/uinteger.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/uinteger.h	Tue Apr 22 21:19:39 2008 -0700
@@ -27,32 +27,20 @@
 namespace ns3 {
 
 /**
+ * \class ns3::UintegerValue
  * \brief Hold an unsigned integer type
  *
+ * \anchor uint8_t
+ * \anchor uint16_t
+ * \anchor uint32_t
+ * \anchor uint64_t
+ *
  * This class can be used to hold variables of unsigned integer
  * type such as uint8_t, uint16_t, uint32_t, uint64_t, or,
  * unsigned int, etc.
  */
-class Uinteger
-{
-public:
-  Uinteger (uint64_t value);
-  Uinteger ();
 
-  void Set (uint64_t value);
-  uint64_t Get (void) const;
-
-  operator uint64_t () const;
-
-  ATTRIBUTE_CONVERTER_DEFINE (Uinteger);
-private:
-  uint64_t m_value;
-};
-
-std::ostream & operator << (std::ostream &os, const Uinteger &uinteger);
-std::istream & operator >> (std::istream &is, Uinteger &uinteger);
-
-ATTRIBUTE_VALUE_DEFINE (Uinteger);
+ATTRIBUTE_VALUE_DEFINE_WITH_NAME (uint64_t, Uinteger);
 ATTRIBUTE_ACCESSOR_DEFINE (Uinteger);
 
 template <typename T>
--- a/src/core/wscript	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/core/wscript	Tue Apr 22 21:19:39 2008 -0700
@@ -46,14 +46,15 @@
         'type-traits-test.cc',
         'attribute.cc',
         'boolean.cc',
-        'attribute-test.cc',
         'integer.cc',
         'uinteger.cc',
         'enum.cc',
         'double.cc',
         'string.cc',
+        'pointer.cc',
+        'object-vector.cc',
+        'attribute-test.cc',
         'object-factory.cc',
-        'object-vector.cc',
         'global-value.cc',
         'traced-callback.cc',
         'trace-source-accessor.cc',
@@ -100,6 +101,7 @@
         'double.h',
         'enum.h',
         'string.h',
+        'pointer.h',
         'object-factory.h',
         'attribute-helper.h',
         'global-value.h',
--- a/src/devices/csma/csma-channel.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/csma/csma-channel.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -53,11 +53,11 @@
     .SetParent<Channel> ()
     .AddConstructor<CsmaChannel> ()
     .AddAttribute ("BitRate", "The maximum bitrate of the channel",
-                   DataRate (0xffffffff),
+                   DataRateValue (DataRate (0xffffffff)),
                    MakeDataRateAccessor (&CsmaChannel::m_bps),
                    MakeDataRateChecker ())
     .AddAttribute ("Delay", "Transmission delay through the channel",
-                   Seconds (0),
+                   TimeValue (Seconds (0)),
                    MakeTimeAccessor (&CsmaChannel::m_delay),
                    MakeTimeChecker ())
     ;
@@ -71,7 +71,7 @@
 : 
   Channel ("Csma Channel")
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_state = IDLE;
   m_deviceList.clear();
 }
@@ -79,8 +79,7 @@
 int32_t
 CsmaChannel::Attach(Ptr<CsmaNetDevice> device)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << device);
+  NS_LOG_FUNCTION (this << device);
   NS_ASSERT(device != 0);
 
   CsmaDeviceRec rec(device);
@@ -92,8 +91,7 @@
 bool
 CsmaChannel::Reattach(Ptr<CsmaNetDevice> device)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << device);
+  NS_LOG_FUNCTION (this << device);
   NS_ASSERT(device != 0);
 
   std::vector<CsmaDeviceRec>::iterator it;
@@ -118,8 +116,7 @@
 bool
 CsmaChannel::Reattach(uint32_t deviceId)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << deviceId);
+  NS_LOG_FUNCTION (this << deviceId);
 
   if (deviceId < m_deviceList.size())
     {
@@ -140,8 +137,7 @@
 bool
 CsmaChannel::Detach(uint32_t deviceId)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << deviceId);
+  NS_LOG_FUNCTION (this << deviceId);
 
   if (deviceId < m_deviceList.size())
     {
@@ -171,8 +167,7 @@
 bool
 CsmaChannel::Detach(Ptr<CsmaNetDevice> device)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << device);
+  NS_LOG_FUNCTION (this << device);
   NS_ASSERT(device != 0);
 
   std::vector<CsmaDeviceRec>::iterator it;
@@ -190,8 +185,7 @@
 bool
 CsmaChannel::TransmitStart(Ptr<Packet> p, uint32_t srcId)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << p << srcId);
+  NS_LOG_FUNCTION (this << p << srcId);
   NS_LOG_INFO ("UID is " << p->GetUid () << ")");
 
   if (m_state != IDLE)
@@ -222,8 +216,7 @@
 bool
 CsmaChannel::TransmitEnd()
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << m_currentPkt << m_currentSrc);
+  NS_LOG_FUNCTION (this << m_currentPkt << m_currentSrc);
   NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")");
 
   NS_ASSERT(m_state == TRANSMITTING);
@@ -248,8 +241,7 @@
 void
 CsmaChannel::PropagationCompleteEvent()
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << m_currentPkt);
+  NS_LOG_FUNCTION (this << m_currentPkt);
   NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")");
 
   NS_ASSERT(m_state == PROPAGATING);
--- a/src/devices/csma/csma-net-device.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/csma/csma-net-device.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -27,6 +27,7 @@
 #include "ns3/error-model.h"
 #include "ns3/enum.h"
 #include "ns3/boolean.h"
+#include "ns3/pointer.h"
 #include "ns3/trace-source-accessor.h"
 #include "csma-net-device.h"
 #include "csma-channel.h"
@@ -45,36 +46,36 @@
     .SetParent<NetDevice> ()
     .AddConstructor<CsmaNetDevice> ()
     .AddAttribute ("Address", "The address of this device.",
-                   Mac48Address ("ff:ff:ff:ff:ff:ff"),
+                   Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
                    MakeMac48AddressAccessor (&CsmaNetDevice::m_address),
                    MakeMac48AddressChecker ())
     .AddAttribute ("EncapsulationMode", "The mode of link-layer encapsulation to use.",
-                   Enum (LLC),
+                   EnumValue (LLC),
                    MakeEnumAccessor (&CsmaNetDevice::m_encapMode),
                    MakeEnumChecker (ETHERNET_V1, "EthernetV1",
                                     IP_ARP, "IpArp",
                                     RAW, "Raw",
                                     LLC, "Llc"))
     .AddAttribute ("SendEnable", "should tx be enabled ?",
-                   Boolean (true),
+                   BooleanValue (true),
                    MakeBooleanAccessor (&CsmaNetDevice::m_sendEnable),
                    MakeBooleanChecker ())
     .AddAttribute ("ReceiveEnable", "should rx be enabled ?",
-                   Boolean (true),
+                   BooleanValue (true),
                    MakeBooleanAccessor (&CsmaNetDevice::m_receiveEnable),
                    MakeBooleanChecker ())
     .AddAttribute ("DataRate", "XXX",
-                   DataRate (0xffffffff),
+                   DataRateValue (DataRate (0xffffffff)),
                    MakeDataRateAccessor (&CsmaNetDevice::m_bps),
                    MakeDataRateChecker ())
     .AddAttribute ("RxErrorModel", "XXX",
-                   Ptr<ErrorModel> (0),
-                   MakePtrAccessor (&CsmaNetDevice::m_receiveErrorModel),
-                   MakePtrChecker<ErrorModel> ())
+                   PointerValue (),
+                   MakePointerAccessor (&CsmaNetDevice::m_receiveErrorModel),
+                   MakePointerChecker<ErrorModel> ())
     .AddAttribute ("TxQueue", "XXX",
-                   Ptr<Queue> (0),
-                   MakePtrAccessor (&CsmaNetDevice::m_queue),
-                   MakePtrChecker<Queue> ())
+                   PointerValue (),
+                   MakePointerAccessor (&CsmaNetDevice::m_queue),
+                   MakePointerChecker<Queue> ())
     .AddTraceSource ("Rx", "Receive MAC packet.",
                      MakeTraceSourceAccessor (&CsmaNetDevice::m_rxTrace))
     .AddTraceSource ("Drop", "Drop MAC packet.",
@@ -88,8 +89,7 @@
     m_linkUp (false),
     m_mtu (0xffff)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this);
+  NS_LOG_FUNCTION (this);
   m_txMachineState = READY;
   m_tInterframeGap = Seconds(0);
   m_channel = 0; 
@@ -97,14 +97,14 @@
 
 CsmaNetDevice::~CsmaNetDevice()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_queue = 0;
 }
 
 void 
 CsmaNetDevice::DoDispose ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_channel = 0;
   m_node = 0;
   NetDevice::DoDispose ();
@@ -119,35 +119,35 @@
 void
 CsmaNetDevice::SetSendEnable (bool sendEnable)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_sendEnable = sendEnable;
 }
 
 void
 CsmaNetDevice::SetReceiveEnable (bool receiveEnable)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_receiveEnable = receiveEnable;
 }
 
 bool
 CsmaNetDevice::IsSendEnabled (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return (m_sendEnable);
 }
 
 bool
 CsmaNetDevice::IsReceiveEnabled (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return (m_receiveEnable);
 }
 
 void 
 CsmaNetDevice::SetDataRate (DataRate bps)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (!m_channel || bps <= m_channel->GetDataRate ())
     {
       m_bps = bps;
@@ -157,7 +157,7 @@
 void 
 CsmaNetDevice::SetInterframeGap (Time t)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_tInterframeGap = t;
 }
 
@@ -166,7 +166,7 @@
                                  uint32_t maxSlots, uint32_t ceiling, 
                                  uint32_t maxRetries)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_backoff.m_slotTime = slotTime;
   m_backoff.m_minSlots = minSlots;
   m_backoff.m_maxSlots = maxSlots;
@@ -178,7 +178,7 @@
 CsmaNetDevice::AddHeader (Ptr<Packet> p, Mac48Address dest,
                             uint16_t protocolNumber)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_encapMode == RAW)
     {
       return;
@@ -217,7 +217,7 @@
 bool 
 CsmaNetDevice::ProcessHeader (Ptr<Packet> p, uint16_t & param)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_encapMode == RAW)
     {
       return true;
@@ -256,7 +256,7 @@
 void
 CsmaNetDevice::TransmitStart ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
   NS_LOG_LOGIC ("UID is " << m_currentPkt->GetUid ());
 //
@@ -323,7 +323,7 @@
 void
 CsmaNetDevice::TransmitAbort (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
 
   // Try to transmit a new packet
@@ -337,7 +337,7 @@
 void
 CsmaNetDevice::TransmitCompleteEvent (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 //
 // This function is called to finish the  process of transmitting a packet.
 // We need to tell the channel that we've stopped wiggling the wire and
@@ -363,7 +363,7 @@
 void
 CsmaNetDevice::TransmitReadyEvent (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 //
 // This function is called to enable the transmitter after the interframe
 // gap has passed.  If there are pending transmissions, we use this opportunity
@@ -388,8 +388,7 @@
 bool
 CsmaNetDevice::Attach (Ptr<CsmaChannel> ch)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << &ch);
+  NS_LOG_FUNCTION (this << &ch);
 
   m_channel = ch;
 
@@ -407,16 +406,14 @@
 void
 CsmaNetDevice::AddQueue (Ptr<Queue> q)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << q);
+  NS_LOG_FUNCTION (this << q);
 
   m_queue = q;
 }
 
 void CsmaNetDevice::AddReceiveErrorModel (Ptr<ErrorModel> em)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << em << ")");
+  NS_LOG_FUNCTION (em);
   
   m_receiveErrorModel = em; 
 }
@@ -424,7 +421,7 @@
 void
 CsmaNetDevice::Receive (Ptr<Packet> packet)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   EthernetHeader header (false);
   EthernetTrailer trailer;
@@ -522,7 +519,7 @@
 Ptr<Queue>
 CsmaNetDevice::GetQueue(void) const 
 { 
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_queue;
 }
 
@@ -610,8 +607,7 @@
 Address 
 CsmaNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << multicastGroup);
+  NS_LOG_FUNCTION (this << multicastGroup);
 //
 // First, get the generic multicast address.
 //
@@ -667,7 +663,7 @@
 bool 
 CsmaNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC ("p=" << packet);
   NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")");
 
--- a/src/devices/point-to-point/point-to-point-channel.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/point-to-point/point-to-point-channel.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -37,11 +37,11 @@
     .SetParent<Channel> ()
     .AddConstructor<PointToPointChannel> ()
     .AddAttribute ("BitRate", "The maximum bitrate of the channel",
-                   DataRate (0xffffffff),
+                   DataRateValue (DataRate (0xffffffff)),
                    MakeDataRateAccessor (&PointToPointChannel::m_bps),
                    MakeDataRateChecker ())
     .AddAttribute ("Delay", "Transmission delay through the channel",
-                   Seconds (0),
+                   TimeValue (Seconds (0)),
                    MakeTimeAccessor (&PointToPointChannel::m_delay),
                    MakeTimeChecker ())
     ;
@@ -56,14 +56,13 @@
   Channel ("PointToPoint Channel"), 
   m_nDevices(0)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 void
 PointToPointChannel::Attach(Ptr<PointToPointNetDevice> device)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << device);
+  NS_LOG_FUNCTION (this << device);
   NS_ASSERT(m_nDevices < N_DEVICES && "Only two devices permitted");
   NS_ASSERT(device != 0);
 
@@ -86,8 +85,7 @@
                                    Ptr<PointToPointNetDevice> src,
                                    const Time& txTime)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << p << src);
+  NS_LOG_FUNCTION (this << p << src);
   NS_LOG_LOGIC ("UID is " << p->GetUid () << ")");
 
   NS_ASSERT(m_link[0].m_state != INITIALIZING);
@@ -107,14 +105,14 @@
 uint32_t 
 PointToPointChannel::GetNDevices (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_nDevices;
 }
 
 Ptr<PointToPointNetDevice>
 PointToPointChannel::GetPointToPointDevice (uint32_t i) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_ASSERT(i < 2);
   return m_link[i].m_src;
 }
@@ -122,21 +120,21 @@
 const DataRate&
 PointToPointChannel::GetDataRate (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_bps;
 }
 
 const Time&
 PointToPointChannel::GetDelay (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_delay;
 }
 
 Ptr<NetDevice>
 PointToPointChannel::GetDevice (uint32_t i) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return GetPointToPointDevice (i);
 }
 
--- a/src/devices/point-to-point/point-to-point-net-device.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/point-to-point/point-to-point-net-device.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -26,6 +26,7 @@
 #include "ns3/llc-snap-header.h"
 #include "ns3/error-model.h"
 #include "ns3/trace-source-accessor.h"
+#include "ns3/pointer.h"
 #include "point-to-point-net-device.h"
 #include "point-to-point-channel.h"
 
@@ -42,23 +43,23 @@
     .SetParent<NetDevice> ()
     .AddConstructor<PointToPointNetDevice> ()
     .AddAttribute ("Address", "The address of this device.",
-                   Mac48Address ("ff:ff:ff:ff:ff:ff"),
+                   Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
                    MakeMac48AddressAccessor (&PointToPointNetDevice::m_address),
                    MakeMac48AddressChecker ())
     .AddAttribute ("DataRate", "The default data rate for point to point links",
-                   DataRate ("10Mb/s"),
+                   DataRateValue (DataRate ("10Mb/s")),
                    MakeDataRateAccessor (&PointToPointNetDevice::m_bps),
                    MakeDataRateChecker ())
     .AddAttribute ("ReceiveErrorModel", "XXX",
-                   Ptr<ErrorModel> (0),
-                   MakePtrAccessor (&PointToPointNetDevice::m_receiveErrorModel),
-                   MakePtrChecker<ErrorModel> ())
+                   PointerValue (),
+                   MakePointerAccessor (&PointToPointNetDevice::m_receiveErrorModel),
+                   MakePointerChecker<ErrorModel> ())
     .AddAttribute ("TxQueue", "XXX",
-                   Ptr<Queue> (0),
-                   MakePtrAccessor (&PointToPointNetDevice::m_queue),
-                   MakePtrChecker<Queue> ())
+                   PointerValue (),
+                   MakePointerAccessor (&PointToPointNetDevice::m_queue),
+                   MakePointerChecker<Queue> ())
     .AddAttribute ("InterframeGap", "XXX",
-                   Seconds (0.0),
+                   TimeValue (Seconds (0.0)),
                    MakeTimeAccessor (&PointToPointNetDevice::m_tInterframeGap),
                    MakeTimeChecker ())
     .AddTraceSource ("Rx", "Receive MAC packet.",
@@ -79,8 +80,7 @@
   m_linkUp (false),
   m_mtu (0xffff)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this);
+  NS_LOG_FUNCTION (this);
 }
 
 PointToPointNetDevice::~PointToPointNetDevice ()
@@ -95,7 +95,7 @@
 void 
 PointToPointNetDevice::AddHeader(Ptr<Packet> p, uint16_t protocolNumber)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   LlcSnapHeader llc;
   llc.SetType (protocolNumber);
   p->AddHeader (llc);
@@ -104,7 +104,7 @@
 bool 
 PointToPointNetDevice::ProcessHeader(Ptr<Packet> p, uint16_t& param)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   LlcSnapHeader llc;
   p->RemoveHeader (llc);
 
@@ -115,7 +115,7 @@
 
 void PointToPointNetDevice::DoDispose()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_node = 0;
   m_channel = 0;
   m_receiveErrorModel = 0;
@@ -124,7 +124,7 @@
 
 void PointToPointNetDevice::SetDataRate(const DataRate& bps)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (!m_channel || bps <= m_channel->GetDataRate ())
     {
       m_bps = bps;
@@ -133,15 +133,14 @@
 
 void PointToPointNetDevice::SetInterframeGap(const Time& t)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_tInterframeGap = t;
 }
 
 bool
 PointToPointNetDevice::TransmitStart (Ptr<Packet> p)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << p);
+  NS_LOG_FUNCTION (this << p);
   NS_LOG_LOGIC ("UID is " << p->GetUid () << ")");
 //
 // This function is called to start the process of transmitting a packet.
@@ -164,7 +163,7 @@
 
 void PointToPointNetDevice::TransmitComplete (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 //
 // This function is called to finish the  process of transmitting a packet.
 // We need to tell the channel that we've stopped wiggling the wire and
@@ -184,8 +183,7 @@
 bool 
 PointToPointNetDevice::Attach (Ptr<PointToPointChannel> ch)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << &ch);
+  NS_LOG_FUNCTION (this << &ch);
 
   m_channel = ch;
 
@@ -211,24 +209,21 @@
 
 void PointToPointNetDevice::AddQueue (Ptr<Queue> q)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << q);
+  NS_LOG_FUNCTION (this << q);
 
   m_queue = q;
 }
 
 void PointToPointNetDevice::AddReceiveErrorModel (Ptr<ErrorModel> em)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS ("(" << em << ")");
+  NS_LOG_FUNCTION ("(" << em << ")");
 
   m_receiveErrorModel = em;
 }
 
 void PointToPointNetDevice::Receive (Ptr<Packet> packet)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << packet);
+  NS_LOG_FUNCTION (this << packet);
   uint16_t protocol = 0;
 
   if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) ) 
@@ -246,7 +241,7 @@
 
 Ptr<Queue> PointToPointNetDevice::GetQueue(void) const 
 { 
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_queue;
 }
 
@@ -344,7 +339,7 @@
 bool 
 PointToPointNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
 {
-    NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC ("p=" << packet << ", dest=" << &dest);
   NS_LOG_LOGIC ("UID is " << packet->GetUid ());
 
--- a/src/devices/wifi/aarf-wifi-manager.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/aarf-wifi-manager.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -37,27 +37,27 @@
     .SetParent<ArfWifiManager> ()
     .AddConstructor<AarfWifiManager> ()
     .AddAttribute ("SuccessK", "Multiplication factor for the success threshold in the AARF algorithm.",
-                   Double (2.0),
+                   DoubleValue (2.0),
                    MakeDoubleAccessor (&AarfWifiManager::m_successK),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("TimerK",
                    "Multiplication factor for the timer threshold in the AARF algorithm.",
-                   Double (2.0),
+                   DoubleValue (2.0),
                    MakeDoubleAccessor (&AarfWifiManager::m_timerK),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("MaxSuccessThreshold",
                    "Maximum value of the success threshold in the AARF algorithm.",
-                   Uinteger (60),
+                   UintegerValue (60),
                    MakeUintegerAccessor (&AarfWifiManager::m_maxSuccessThreshold),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("MinTimerThreshold",
                    "The minimum value for the 'timer' threshold in the AARF algorithm.",
-                   Uinteger (15),
+                   UintegerValue (15),
                    MakeUintegerAccessor (&AarfWifiManager::m_minTimerThreshold),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("MinSuccessThreshold",
                    "The minimum value for the success threshold in the AARF algorithm.",
-                   Uinteger (10),
+                   UintegerValue (10),
                    MakeUintegerAccessor (&AarfWifiManager::m_minSuccessThreshold),
                    MakeUintegerChecker<uint32_t> ())
     ;
--- a/src/devices/wifi/amrr-wifi-manager.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/amrr-wifi-manager.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -38,27 +38,27 @@
     .AddConstructor<AmrrWifiManager> ()
     .AddAttribute ("UpdatePeriod",
                    "The interval between decisions about rate control changes",
-                   Seconds (1.0),
+                   TimeValue (Seconds (1.0)),
                    MakeTimeAccessor (&AmrrWifiManager::m_updatePeriod),
                    MakeTimeChecker ())
     .AddAttribute ("FailureRatio",
                    "Ratio of minimum erronous transmissions needed to switch to a lower rate",
-                   Double (1.0/3.0),
+                   DoubleValue (1.0/3.0),
                    MakeDoubleAccessor (&AmrrWifiManager::m_failureRatio),
                    MakeDoubleChecker<double> (0.0, 1.0))
     .AddAttribute ("SuccessRatio",
                    "Ratio of maximum erronous transmissions needed to switch to a higher rate",
-                   Double (1.0/10.0),
+                   DoubleValue (1.0/10.0),
                    MakeDoubleAccessor (&AmrrWifiManager::m_successRatio),
                    MakeDoubleChecker<double> (0.0, 1.0))
     .AddAttribute ("MaxSuccessThreshold",
                    "Maximum number of consecutive success periods needed to switch to a higher rate",
-                   Uinteger (10),
+                   UintegerValue (10),
                    MakeUintegerAccessor (&AmrrWifiManager::m_maxSuccessThreshold),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("MinSuccessThreshold",
                    "Minimum number of consecutive success periods needed to switch to a higher rate",
-                   Uinteger (1),
+                   UintegerValue (1),
                    MakeUintegerAccessor (&AmrrWifiManager::m_minSuccessThreshold),
                    MakeUintegerChecker<uint32_t> ())
     ;
--- a/src/devices/wifi/amrr-wifi-manager.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/amrr-wifi-manager.h	Tue Apr 22 21:19:39 2008 -0700
@@ -25,6 +25,14 @@
 
 namespace ns3 {
 
+/**
+ * \brief AMRR Rate control algorithm
+ *
+ * This class implements the AMRR rate control algorithm which
+ * was initially described in <i>IEEE 802.11 Rate Adaptation:
+ * A Practical Approach</i>, by M. Lacage, M.H. Manshaei, and 
+ * T. Turletti.
+ */
 class AmrrWifiManager : public WifiRemoteStationManager
 {
 public:
--- a/src/devices/wifi/arf-wifi-manager.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/arf-wifi-manager.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -228,12 +228,12 @@
     .SetParent<WifiRemoteStationManager> ()
     .AddConstructor<ArfWifiManager> ()
     .AddAttribute ("TimerThreshold", "The 'timer' threshold in the ARF algorithm.",
-                   Uinteger (15),
+                   UintegerValue (15),
                    MakeUintegerAccessor (&ArfWifiManager::m_timerThreshold),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("SuccessThreshold",
                    "The minimum number of sucessfull transmissions to try a new rate.",
-                   Uinteger (10),
+                   UintegerValue (10),
                    MakeUintegerAccessor (&ArfWifiManager::m_successThreshold),
                    MakeUintegerChecker<uint32_t> ())
     ;
--- a/src/devices/wifi/constant-rate-wifi-manager.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/constant-rate-wifi-manager.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -78,11 +78,11 @@
     .SetParent<WifiRemoteStationManager> ()
     .AddConstructor<ConstantRateWifiManager> ()
     .AddAttribute ("DataMode", "XXX",
-                   String ("wifia-6mbs"),
+                   StringValue ("wifia-6mbs"),
                    MakeWifiModeAccessor (&ConstantRateWifiManager::m_dataMode),
                    MakeWifiModeChecker ())
     .AddAttribute ("ControlMode", "XXX",
-                   String ("wifia-6mbs"),
+                   StringValue ("wifia-6mbs"),
                    MakeWifiModeAccessor (&ConstantRateWifiManager::m_ctlMode),
                    MakeWifiModeChecker ())
     ;
--- a/src/devices/wifi/dca-txop.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/dca-txop.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -37,7 +37,7 @@
 NS_LOG_COMPONENT_DEFINE ("DcaTxop");
 
 #define MY_DEBUG(x) \
-  NS_LOG_DEBUG (Simulator::Now () << " " << m_low->GetMac ()->GetAddress () << " " << x)
+  NS_LOG_DEBUG (m_low->GetMac ()->GetAddress () << " " << x)
 
 
 namespace ns3 {
@@ -100,17 +100,17 @@
     .SetParent<Object> ()
     .AddConstructor<DcaTxop> ()
     .AddAttribute ("MinCw", "XXX",
-                   Uinteger (15),
+                   UintegerValue (15),
                    MakeUintegerAccessor (&DcaTxop::SetMinCw,
                                          &DcaTxop::GetMinCw),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("MaxCw", "XXX",
-                   Uinteger (1023),
+                   UintegerValue (1023),
                    MakeUintegerAccessor (&DcaTxop::SetMaxCw,
                                          &DcaTxop::GetMaxCw),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("Aifsn", "XXX",
-                   Uinteger (2),
+                   UintegerValue (2),
                    MakeUintegerAccessor (&DcaTxop::SetAifsn,
                                          &DcaTxop::GetAifsn),
                    MakeUintegerChecker<uint32_t> ())
@@ -122,6 +122,7 @@
   : m_manager (0),
     m_currentPacket (0)
 {
+  NS_LOG_FUNCTION (this);
   m_transmissionListener = new DcaTxop::TransmissionListener (this);
   m_dcf = new DcaTxop::Dcf (this);
   m_queue = CreateObject<WifiMacQueue> ();
@@ -130,11 +131,14 @@
 }
 
 DcaTxop::~DcaTxop ()
-{}
+{
+  NS_LOG_FUNCTION (this);
+}
 
 void
 DcaTxop::DoDispose (void)
 {
+  NS_LOG_FUNCTION (this);
   delete m_transmissionListener;
   delete m_dcf;
   delete m_rng;
@@ -151,6 +155,7 @@
 void
 DcaTxop::SetManager (DcfManager *manager)
 {
+  NS_LOG_FUNCTION (this << manager);
   m_manager = manager;
   m_manager->Add (m_dcf);
 }
@@ -158,11 +163,13 @@
 void 
 DcaTxop::SetLow (Ptr<MacLow> low)
 {
+  NS_LOG_FUNCTION (this << low);
   m_low = low;
 }
 void 
 DcaTxop::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> remoteManager)
 {
+  NS_LOG_FUNCTION (this << remoteManager);
   m_stationManager = remoteManager;
 }
 void 
@@ -179,26 +186,31 @@
 void 
 DcaTxop::SetMaxQueueSize (uint32_t size)
 {
+  NS_LOG_FUNCTION (this << size);
   m_queue->SetMaxSize (size);
 }
 void 
 DcaTxop::SetMaxQueueDelay (Time delay)
 {
+  NS_LOG_FUNCTION (this << delay);
   m_queue->SetMaxDelay (delay);
 }
 void 
 DcaTxop::SetMinCw (uint32_t minCw)
 {
+  NS_LOG_FUNCTION (this << minCw);
   m_dcf->SetCwMin (minCw);
 }
 void 
 DcaTxop::SetMaxCw (uint32_t maxCw)
 {
+  NS_LOG_FUNCTION (this << maxCw);
   m_dcf->SetCwMax (maxCw);
 }
 void 
 DcaTxop::SetAifsn (uint32_t aifsn)
 {
+  NS_LOG_FUNCTION (this << aifsn);
   m_dcf->SetAifsn (aifsn);
 }
 uint32_t 
@@ -220,6 +232,7 @@
 void 
 DcaTxop::Queue (Ptr<const Packet> packet, WifiMacHeader const &hdr)
 {
+  NS_LOG_FUNCTION (this << packet << &hdr);
   WifiMacTrailer fcs;
   uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.GetSerializedSize ();
   WifiRemoteStation *station = GetStation (hdr.GetAddr1 ());
@@ -237,6 +250,7 @@
 void
 DcaTxop::RestartAccessIfNeeded (void)
 {
+  NS_LOG_FUNCTION (this);
   if ((m_currentPacket != 0 ||
        !m_queue->IsEmpty ()) &&
       !m_dcf->IsAccessRequested ())
@@ -248,6 +262,7 @@
 void
 DcaTxop::StartAccessIfNeeded (void)
 {
+  NS_LOG_FUNCTION (this);
   if (m_currentPacket == 0 &&
       !m_queue->IsEmpty () &&
       !m_dcf->IsAccessRequested ())
@@ -350,6 +365,7 @@
 void 
 DcaTxop::NotifyAccessGranted (void)
 {
+  NS_LOG_FUNCTION (this);
   if (m_currentPacket == 0) 
     {
       if (m_queue->IsEmpty ()) 
@@ -383,6 +399,7 @@
       m_currentPacket = 0;
       m_dcf->ResetCw ();
       m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+      StartAccessIfNeeded ();
       MY_DEBUG ("tx broadcast");
     } 
   else 
@@ -429,11 +446,13 @@
 void 
 DcaTxop::NotifyInternalCollision (void)
 {
+  NS_LOG_FUNCTION (this);
   NotifyCollision ();
 }
 void 
 DcaTxop::NotifyCollision (void)
 {
+  NS_LOG_FUNCTION (this);
   MY_DEBUG ("collision");
   m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
   RestartAccessIfNeeded ();
@@ -442,11 +461,13 @@
 void 
 DcaTxop::GotCts (double snr, WifiMode txMode)
 {
+  NS_LOG_FUNCTION (this << snr << txMode);
   MY_DEBUG ("got cts");
 }
 void 
 DcaTxop::MissedCts (void)
 {
+  NS_LOG_FUNCTION (this);
   MY_DEBUG ("missed cts");
   if (!NeedRtsRetransmission ())
     {
@@ -467,6 +488,7 @@
 void 
 DcaTxop::GotAck (double snr, WifiMode txMode)
 {
+  NS_LOG_FUNCTION (this << snr << txMode);
   if (!NeedFragmentation () ||
       IsLastFragment ()) 
     {
@@ -492,6 +514,7 @@
 void 
 DcaTxop::MissedAck (void)
 {
+  NS_LOG_FUNCTION (this);
   MY_DEBUG ("missed ack");
   if (!NeedDataRetransmission ()) 
     {
@@ -518,6 +541,7 @@
 void 
 DcaTxop::StartNext (void)
 {
+  NS_LOG_FUNCTION (this);
   MY_DEBUG ("start next packet fragment");
   /* this callback is used only for fragments. */
   NextFragment ();
@@ -541,6 +565,7 @@
 void
 DcaTxop::Cancel (void)
 {
+  NS_LOG_FUNCTION (this);
   MY_DEBUG ("transmission cancelled");
   /**
    * This happens in only one case: in an AP, you have two DcaTxop:
--- a/src/devices/wifi/ideal-wifi-manager.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/ideal-wifi-manager.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -23,17 +23,6 @@
 #include "ns3/double.h"
 #include <math.h>
 
-#define noIDEAL_DEBUG 1
-
-#ifdef IDEAL_DEBUG
-#include <iostream>
-#  define TRACE(x) \
-std::cout << "IDEAL TRACE " << x << std::endl;
-#else
-#  define TRACE(x)
-#endif
-
-
 namespace ns3 {
 
 NS_OBJECT_ENSURE_REGISTERED (IdealWifiManager);
@@ -46,7 +35,7 @@
     .AddConstructor<IdealWifiManager> ()
     .AddAttribute ("BerThreshold",
                    "The maximum Bit Error Rate acceptable at any transmission mode",
-                   Double (10e-6),
+                   DoubleValue (10e-6),
                    MakeDoubleAccessor (&IdealWifiManager::m_ber),
                    MakeDoubleChecker<double> ())
     ;
@@ -115,13 +104,11 @@
 void 
 IdealWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
 {
-  TRACE ("got cts for rts snr="<<rtsSnr);
   m_lastSnr = rtsSnr;
 }
 void 
 IdealWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
 {
-  TRACE ("got cts for rts snr="<<dataSnr);
   m_lastSnr = dataSnr;
 }
 void 
--- a/src/devices/wifi/jakes-propagation-loss-model.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/jakes-propagation-loss-model.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -131,22 +131,22 @@
     .AddConstructor<JakesPropagationLossModel> ()
     .AddAttribute ("NumberOfRaysPerPath",
                    "The number of rays to use by default for compute the fading coeficent for a given path (default is 1)",
-                   Uinteger (1),
+                   UintegerValue (1),
 		   MakeUintegerAccessor (&JakesPropagationLossModel::m_nRays),
 		   MakeUintegerChecker<uint8_t> ())
     .AddAttribute ("NumberOfOscillatorsPerRay",
                    "The number of oscillators to use by default for compute the coeficent for a given ray of a given path (default is 4)",
-                   Uinteger (4),
+                   UintegerValue (4),
 		   MakeUintegerAccessor (&JakesPropagationLossModel::m_nOscillators),
 		   MakeUintegerChecker<uint8_t> ())
     .AddAttribute ("DopplerFreq",
                    "The doppler frequency in Hz (f_d = v / lambda = v * f / c, the defualt is 0)",
-                   Double(0.0),
+                   DoubleValue (0.0),
 		   MakeDoubleAccessor (&JakesPropagationLossModel::m_fd),
 		   MakeDoubleChecker<double> ())
     .AddAttribute ("Distribution",
                    "The distribution to choose the initial phases.",
-                   ConstantVariable (1.0),
+                   RandomVariableValue (ConstantVariable (1.0)),
                    MakeRandomVariableAccessor (&JakesPropagationLossModel::m_variable),
                    MakeRandomVariableChecker ())
     ;
--- a/src/devices/wifi/mac-low.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/mac-low.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -33,7 +33,7 @@
 NS_LOG_COMPONENT_DEFINE ("MacLow");
 
 #define MY_DEBUG(x) \
-  NS_LOG_DEBUG (Simulator::Now () << " " << m_mac->GetAddress () << " " << x)
+  NS_LOG_DEBUG (m_mac->GetAddress () << " " << x)
 
 namespace ns3 {
 
@@ -215,7 +215,30 @@
   return m_nextSize;
 }
 
-
+std::ostream &operator << (std::ostream &os, const MacLowTransmissionParameters &params)
+{
+  os << "[" 
+     << "send rts=" << params.m_sendRts << ", "
+     << "next size=" << params.m_nextSize << ", "
+     << "dur=" << params.m_overrideDurationId << ", "
+     << "ack=";
+  switch (params.m_waitAck) {
+  case MacLowTransmissionParameters::ACK_NONE:
+    os << "none";
+    break;
+  case MacLowTransmissionParameters::ACK_NORMAL:
+    os << "normal";
+    break;
+  case MacLowTransmissionParameters::ACK_FAST:
+    os << "fast";
+    break;
+  case MacLowTransmissionParameters::ACK_SUPER_FAST:
+    os << "super-fast";
+    break;
+  }
+  os << "]";
+  return os;
+}
 
 MacLow::MacLow ()
   : m_normalAckTimeoutEvent (),
@@ -230,16 +253,20 @@
     m_currentPacket (0),
     m_listener (0)
 {
+  NS_LOG_FUNCTION (this);
   m_lastNavDuration = Seconds (0);
   m_lastNavStart = Seconds (0);
 }
 
 MacLow::~MacLow ()
-{}
+{
+  NS_LOG_FUNCTION (this);
+}
 
 void 
 MacLow::DoDispose (void)
 {
+  NS_LOG_FUNCTION (this);
   CancelAllEvents ();
   m_phy = 0;
   m_mac = 0;
@@ -249,6 +276,7 @@
 void
 MacLow::CancelAllEvents (void)
 {
+  NS_LOG_FUNCTION (this);
   bool oneRunning = false;
   if (m_normalAckTimeoutEvent.IsRunning ()) 
     {
@@ -339,9 +367,10 @@
 void 
 MacLow::StartTransmission (Ptr<const Packet> packet, 
                            WifiMacHeader const*hdr, 
-                           MacLowTransmissionParameters parameters,
+                           MacLowTransmissionParameters params,
                            MacLowTransmissionListener *listener)
 {
+  NS_LOG_FUNCTION (this << packet << hdr << params << listener);
   /* m_currentPacket is not NULL because someone started
    * a transmission and was interrupted before one of:
    *   - ctsTimeout
@@ -360,7 +389,7 @@
   m_currentHdr = *hdr;
   CancelAllEvents ();
   m_listener = listener;
-  m_txParams = parameters;
+  m_txParams = params;
 
   //NS_ASSERT (m_phy->IsStateIdle ());
 
@@ -383,6 +412,7 @@
 void
 MacLow::ReceiveError (Ptr<Packet> packet, double rxSnr)
 {
+  NS_LOG_FUNCTION (this << packet << rxSnr);
   MY_DEBUG ("rx failed ");
   if (m_txParams.MustWaitFastAck ()) 
     {
@@ -396,6 +426,7 @@
 void 
 MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamble preamble)
 {
+  NS_LOG_FUNCTION (this << packet << rxSnr << txMode << preamble);
   /* A packet is received from the PHY.
    * When we have handled this packet,
    * we handle any packet present in the
@@ -754,6 +785,7 @@
 MacLow::ForwardDown (Ptr<const Packet> packet, WifiMacHeader const* hdr, 
                      WifiMode txMode)
 {
+  NS_LOG_FUNCTION (this << packet << hdr << txMode);
   MY_DEBUG ("send " << hdr->GetTypeString () <<
             ", to=" << hdr->GetAddr1 () <<
             ", size=" << packet->GetSize () <<
@@ -773,6 +805,7 @@
 void
 MacLow::CtsTimeout (void)
 {
+  NS_LOG_FUNCTION (this);
   MY_DEBUG ("cts timeout");
   // XXX: should check that there was no rx start before now.
   // we should restart a new cts timeout now until the expected
@@ -787,6 +820,7 @@
 void
 MacLow::NormalAckTimeout (void)
 {
+  NS_LOG_FUNCTION (this);
   MY_DEBUG ("normal ack timeout");
   // XXX: should check that there was no rx start before now.
   // we should restart a new ack timeout now until the expected
@@ -800,6 +834,7 @@
 void
 MacLow::FastAckTimeout (void)
 {
+  NS_LOG_FUNCTION (this);
   WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
   station->ReportDataFailed ();
   MacLowTransmissionListener *listener = m_listener;
@@ -817,6 +852,7 @@
 void
 MacLow::SuperFastAckTimeout ()
 {
+  NS_LOG_FUNCTION (this);
   WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
   station->ReportDataFailed ();
   MacLowTransmissionListener *listener = m_listener;
@@ -836,6 +872,7 @@
 void
 MacLow::SendRtsForPacket (void)
 {
+  NS_LOG_FUNCTION (this);
   /* send an RTS for this packet. */
   WifiMacHeader rts;
   rts.SetType (WIFI_MAC_CTL_RTS);
@@ -917,6 +954,7 @@
 void
 MacLow::SendDataPacket (void)
 {
+  NS_LOG_FUNCTION (this);
   /* send this packet directly. No RTS is needed. */
   StartDataTxTimers ();
 
@@ -977,6 +1015,7 @@
 void
 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode, double rtsSnr)
 {
+  NS_LOG_FUNCTION (this);
   /* send a CTS when you receive a RTS 
    * right after SIFS.
    */
@@ -1007,6 +1046,7 @@
 void
 MacLow::SendDataAfterCts (Mac48Address source, Time duration, WifiMode txMode)
 {
+  NS_LOG_FUNCTION (this);
   /* send the third step in a 
    * RTS/CTS/DATA/ACK hanshake 
    */
@@ -1043,6 +1083,7 @@
 void
 MacLow::FastAckFailedTimeout (void)
 {
+  NS_LOG_FUNCTION (this);
   MacLowTransmissionListener *listener = m_listener;
   m_listener = 0;
   listener->MissedAck ();
@@ -1052,6 +1093,7 @@
 void
 MacLow::SendAckAfterData (Mac48Address source, Time duration, WifiMode dataTxMode, double dataSnr)
 {
+  NS_LOG_FUNCTION (this);
   /* send an ACK when you receive 
    * a packet after SIFS. 
    */
--- a/src/devices/wifi/mac-low.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/mac-low.h	Tue Apr 22 21:19:39 2008 -0700
@@ -22,6 +22,7 @@
 
 #include <vector>
 #include <stdint.h>
+#include <ostream>
 
 #include "wifi-mac-header.h"
 #include "wifi-mode.h"
@@ -252,6 +253,7 @@
   uint32_t GetNextPacketSize (void) const;
 
 private:
+  friend std::ostream &operator << (std::ostream &os, const MacLowTransmissionParameters &params);
   uint32_t m_nextSize;
   enum {
     ACK_NONE,
@@ -263,6 +265,8 @@
   Time m_overrideDurationId;
 };
 
+std::ostream &operator << (std::ostream &os, const MacLowTransmissionParameters &params);
+
 
 /**
  * \brief handle RTS/CTS/DATA/ACK transactions.
--- a/src/devices/wifi/mac-rx-middle.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/mac-rx-middle.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -29,8 +29,6 @@
 
 NS_LOG_COMPONENT_DEFINE ("MacRxMiddle");
 
-#define TRACE(x) NS_LOG_DEBUG(Simulator::Now () << " " << x)
-
 namespace ns3 {
 
 
@@ -99,10 +97,13 @@
 
 
 MacRxMiddle::MacRxMiddle ()
-{}
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
 
 MacRxMiddle::~MacRxMiddle ()
 {
+  NS_LOG_FUNCTION_NOARGS ();
   for (OriginatorsI i = m_originatorStatus.begin ();
        i != m_originatorStatus.end (); i++) 
     {
@@ -122,16 +123,18 @@
 void 
 MacRxMiddle::SetForwardCallback (ForwardUpCallback callback)
 {
+  NS_LOG_FUNCTION_NOARGS ();
   m_callback = callback;
 }
 
 bool
 MacRxMiddle::SequenceControlSmaller (int seqca, int seqcb)
 {
+  NS_LOG_FUNCTION (seqca << seqcb);
   int seqa = seqca >> 4;
   int seqb = seqcb >> 4;
   int delta = seqb - seqa;
-  TRACE ("seqb="<<seqb<<", seqa="<<seqa<<", delta="<<delta);
+  NS_LOG_DEBUG ("seqb="<<seqb<<", seqa="<<seqa<<", delta="<<delta);
   if (delta <= 0 && delta < -2048) 
     {
       return true;
@@ -150,6 +153,7 @@
 OriginatorRxStatus *
 MacRxMiddle::Lookup (WifiMacHeader const *hdr)
 {
+  NS_LOG_FUNCTION (hdr);
   OriginatorRxStatus *originator;
   Mac48Address source = hdr->GetAddr2 ();
   if (hdr->IsQosData () &&
@@ -184,6 +188,7 @@
 MacRxMiddle::IsDuplicate (WifiMacHeader const*hdr, 
                           OriginatorRxStatus *originator) const
 {
+  NS_LOG_FUNCTION (hdr << originator);
   if (hdr->IsRetry () &&
       originator->GetLastSequenceControl () == hdr->GetSequenceControl ()) 
     {
@@ -196,13 +201,14 @@
 MacRxMiddle::HandleFragments (Ptr<Packet> packet, WifiMacHeader const*hdr,
                               OriginatorRxStatus *originator)
 {
+  NS_LOG_FUNCTION (packet << hdr << originator);
   if (originator->IsDeFragmenting ()) 
     {
       if (hdr->IsMoreFragments ()) 
         {
           if (originator->IsNextFragment (hdr->GetSequenceControl ())) 
             {
-              TRACE ("accumulate fragment seq="<<hdr->GetSequenceNumber ()<<
+              NS_LOG_DEBUG ("accumulate fragment seq="<<hdr->GetSequenceNumber ()<<
                      ", frag="<<hdr->GetFragmentNumber ()<<
                      ", size="<<packet->GetSize ());
               originator->AccumulateFragment (packet);
@@ -210,7 +216,7 @@
             } 
           else 
             {
-              TRACE ("non-ordered fragment");
+              NS_LOG_DEBUG ("non-ordered fragment");
             }
           return 0;
         } 
@@ -218,7 +224,7 @@
         {
           if (originator->IsNextFragment (hdr->GetSequenceControl ())) 
             {
-              TRACE ("accumulate last fragment seq="<<hdr->GetSequenceNumber ()<<
+              NS_LOG_DEBUG ("accumulate last fragment seq="<<hdr->GetSequenceNumber ()<<
                      ", frag="<<hdr->GetFragmentNumber ()<<
                      ", size="<<hdr->GetSize ());
               Ptr<Packet> p = originator->AccumulateLastFragment (packet);
@@ -227,7 +233,7 @@
             } 
           else 
             {
-              TRACE ("non-ordered fragment");
+              NS_LOG_DEBUG ("non-ordered fragment");
               return 0;
             }
         }
@@ -236,7 +242,7 @@
     {
       if (hdr->IsMoreFragments ()) 
         {
-          TRACE ("accumulate first fragment seq="<<hdr->GetSequenceNumber ()<<
+          NS_LOG_DEBUG ("accumulate first fragment seq="<<hdr->GetSequenceNumber ()<<
                  ", frag="<<hdr->GetFragmentNumber ()<<
                  ", size="<<packet->GetSize ());
           originator->AccumulateFirstFragment (packet);
@@ -253,6 +259,7 @@
 void
 MacRxMiddle::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
 {
+  NS_LOG_FUNCTION (packet << hdr);
   OriginatorRxStatus *originator = Lookup (hdr);
   if (hdr->IsData ()) 
     {
@@ -272,7 +279,7 @@
       // filter duplicates.
       if (IsDuplicate (hdr, originator)) 
         {
-          TRACE ("duplicate from="<<hdr->GetAddr2 ()<<
+          NS_LOG_DEBUG ("duplicate from="<<hdr->GetAddr2 ()<<
                  ", seq="<<hdr->GetSequenceNumber ()<<
                  ", frag="<<hdr->GetFragmentNumber ());
           return;
@@ -282,7 +289,7 @@
         {
           return;
         }
-      TRACE ("forwarding data from="<<hdr->GetAddr2 ()<<
+      NS_LOG_DEBUG ("forwarding data from="<<hdr->GetAddr2 ()<<
              ", seq="<<hdr->GetSequenceNumber ()<<
              ", frag="<<hdr->GetFragmentNumber ());
       if (!hdr->GetAddr1 ().IsBroadcast ())
@@ -293,7 +300,7 @@
     } 
   else 
     {
-      TRACE ("forwarding "<<hdr->GetTypeString ()<<
+      NS_LOG_DEBUG ("forwarding "<<hdr->GetTypeString ()<<
              ", from="<<hdr->GetAddr2 ()<<
              ", seq="<<hdr->GetSequenceNumber ()<<
              ", frag="<<hdr->GetFragmentNumber ());
--- a/src/devices/wifi/nqap-wifi-mac.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/nqap-wifi-mac.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -33,9 +33,6 @@
 
 NS_LOG_COMPONENT_DEFINE ("NqapWifiMac");
 
-#define TRACE(x) \
-  NS_LOG_DEBUG(Simulator::Now () << " " << GetAddress () << " " << x);
-
 namespace ns3 {
 
 NS_OBJECT_ENSURE_REGISTERED (NqapWifiMac);
@@ -47,11 +44,11 @@
     .SetParent<WifiMac> ()
     .AddConstructor<NqapWifiMac> ()
     .AddAttribute ("BeaconInterval", "Delay between two beacons",
-                   Seconds (1.0),
+                   TimeValue (Seconds (1.0)),
                    MakeTimeAccessor (&NqapWifiMac::m_beaconInterval),
                    MakeTimeChecker ())
     .AddAttribute ("BeaconGeneration", "Whether or not beacons are generated.",
-                   Boolean (false),
+                   BooleanValue (false),
                    MakeBooleanAccessor (&NqapWifiMac::SetBeaconGeneration,
                                         &NqapWifiMac::GetBeaconGeneration),
                    MakeBooleanChecker ())
@@ -61,6 +58,7 @@
 
 NqapWifiMac::NqapWifiMac ()
 {
+  NS_LOG_FUNCTION (this);
   m_rxMiddle = new MacRxMiddle ();
   m_rxMiddle->SetForwardCallback (MakeCallback (&NqapWifiMac::Receive, this));
 
@@ -82,11 +80,14 @@
   m_beaconDca->SetManager (m_dcfManager);
 }
 NqapWifiMac::~NqapWifiMac ()
-{}
+{
+  NS_LOG_FUNCTION (this);
+}
 
 void
 NqapWifiMac::DoDispose (void)
 {
+  NS_LOG_FUNCTION (this);
   delete m_rxMiddle;
   delete m_dcfManager;
   m_rxMiddle = 0;
@@ -102,6 +103,7 @@
 void
 NqapWifiMac::SetBeaconGeneration (bool enable)
 {
+  NS_LOG_FUNCTION (this << enable);
   if (enable)
     {
       m_beaconEvent = Simulator::ScheduleNow (&NqapWifiMac::SendOneBeacon, this);
@@ -121,18 +123,21 @@
 void 
 NqapWifiMac::SetSlot (Time slotTime)
 {
+  NS_LOG_FUNCTION (this << slotTime);
   m_dcfManager->SetSlot (slotTime);
   m_slot = slotTime;
 }
 void 
 NqapWifiMac::SetSifs (Time sifs)
 {
+  NS_LOG_FUNCTION (this << sifs);
   m_dcfManager->SetSifs (sifs);
   m_sifs = sifs;
 }
 void 
 NqapWifiMac::SetEifsNoDifs (Time eifsNoDifs)
 {
+  NS_LOG_FUNCTION (this << eifsNoDifs);
   m_dcfManager->SetEifsNoDifs (eifsNoDifs);
   m_eifsNoDifs = eifsNoDifs;
 }
@@ -156,6 +161,7 @@
 void 
 NqapWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
 {
+  NS_LOG_FUNCTION (this << phy);
   m_phy = phy;
   m_dcfManager->SetupPhyListener (phy);
   m_low->SetPhy (phy);
@@ -163,6 +169,7 @@
 void 
 NqapWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
 {
+  NS_LOG_FUNCTION (this << stationManager);
   m_stationManager = stationManager;
   m_dca->SetWifiRemoteStationManager (stationManager);
   m_beaconDca->SetWifiRemoteStationManager (stationManager);
@@ -171,11 +178,13 @@
 void 
 NqapWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, const Mac48Address &> upCallback)
 {
+  NS_LOG_FUNCTION (this);
   m_upCallback = upCallback;
 }
 void 
 NqapWifiMac::SetLinkUpCallback (Callback<void> linkUp)
 {
+  NS_LOG_FUNCTION (this);
   if (!linkUp.IsNull ())
     {
       linkUp ();
@@ -183,7 +192,9 @@
 }
 void 
 NqapWifiMac::SetLinkDownCallback (Callback<void> linkDown)
-{}
+{
+  NS_LOG_FUNCTION (this);
+}
 Mac48Address 
 NqapWifiMac::GetAddress (void) const
 {
@@ -202,11 +213,13 @@
 void 
 NqapWifiMac::SetAddress (Mac48Address address)
 {
+  NS_LOG_FUNCTION (address);
   m_address = address;
 }
 void 
 NqapWifiMac::SetSsid (Ssid ssid)
 {
+  NS_LOG_FUNCTION (ssid);
   m_ssid = ssid;
 }
 
@@ -214,21 +227,25 @@
 void 
 NqapWifiMac::SetBeaconInterval (Time interval)
 {
+  NS_LOG_FUNCTION (this << interval);
   m_beaconInterval = interval;
 }
 void
 NqapWifiMac::StartBeaconing (void)
 {
+  NS_LOG_FUNCTION (this);
   SendOneBeacon ();
 }
 void 
 NqapWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from)
 {
+  NS_LOG_FUNCTION (this << packet << from);
   m_upCallback (packet, from);
 }
 void 
 NqapWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
 {
+  NS_LOG_FUNCTION (this << packet << from << to);
   WifiMacHeader hdr;
   hdr.SetTypeData ();
   hdr.SetAddr1 (to);
@@ -241,6 +258,7 @@
 void 
 NqapWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
 {
+  NS_LOG_FUNCTION (this << packet << to);
   ForwardDown (packet, GetAddress (), to);
 }
 SupportedRates
@@ -265,7 +283,7 @@
 void
 NqapWifiMac::SendProbeResp (Mac48Address to)
 {
-  TRACE ("send probe response to="<<to);
+  NS_LOG_FUNCTION (this << to);
   WifiMacHeader hdr;
   hdr.SetProbeResp ();
   hdr.SetAddr1 (to);
@@ -285,7 +303,7 @@
 void
 NqapWifiMac::SendAssocResp (Mac48Address to, bool success)
 {
-  TRACE ("send assoc response to="<<to);
+  NS_LOG_FUNCTION (this << to << success);
   WifiMacHeader hdr;
   hdr.SetAssocResp ();
   hdr.SetAddr1 (to);
@@ -313,7 +331,7 @@
 void
 NqapWifiMac::SendOneBeacon (void)
 {
-  TRACE ("send beacon to="<<Mac48Address::GetBroadcast ());
+  NS_LOG_FUNCTION (this);
   WifiMacHeader hdr;
   hdr.SetBeacon ();
   hdr.SetAddr1 (Mac48Address::GetBroadcast ());
@@ -334,28 +352,32 @@
 void 
 NqapWifiMac::TxOk (WifiMacHeader const &hdr)
 {
+  NS_LOG_FUNCTION (this);
   WifiRemoteStation *station = m_stationManager->Lookup (hdr.GetAddr1 ());
   if (hdr.IsAssocResp () && 
       station->IsWaitAssocTxOk ()) 
     {
-      TRACE ("associated with sta="<<hdr.GetAddr1 ());
+      NS_LOG_DEBUG ("associated with sta="<<hdr.GetAddr1 ());
       station->RecordGotAssocTxOk ();
     }
 }
 void 
 NqapWifiMac::TxFailed (WifiMacHeader const &hdr)
 {
+  NS_LOG_FUNCTION (this);
   WifiRemoteStation *station = m_stationManager->Lookup (hdr.GetAddr1 ());
   if (hdr.IsAssocResp () && 
       station->IsWaitAssocTxOk ()) 
     {
-      TRACE ("assoc failed with sta="<<hdr.GetAddr1 ());
+      NS_LOG_DEBUG ("assoc failed with sta="<<hdr.GetAddr1 ());
       station->RecordGotAssocTxFailed ();
     }
 }
 void 
 NqapWifiMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
 {
+  NS_LOG_FUNCTION (this << packet << hdr);
+
   WifiRemoteStation *station = m_stationManager->Lookup (hdr->GetAddr2 ());
 
   if (hdr->IsData ()) 
@@ -367,12 +389,12 @@
         {
           if (hdr->GetAddr3 () == GetAddress ()) 
             {
-              TRACE ("frame for me from="<<hdr->GetAddr2 ());
+              NS_LOG_DEBUG ("frame for me from="<<hdr->GetAddr2 ());
               ForwardUp (packet, hdr->GetAddr2 ());
             } 
           else 
             {
-              TRACE ("forwarding frame from="<<hdr->GetAddr2 ()<<", to="<<hdr->GetAddr3 ());
+              NS_LOG_DEBUG ("forwarding frame from="<<hdr->GetAddr2 ()<<", to="<<hdr->GetAddr3 ());
               Ptr<Packet> copy = packet->Copy ();
               ForwardDown (packet,
                            hdr->GetAddr2 (), 
--- a/src/devices/wifi/nqsta-wifi-mac.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/nqsta-wifi-mac.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -36,9 +36,6 @@
 
 NS_LOG_COMPONENT_DEFINE ("NqstaWifiMac");
 
-#define TRACE(x) \
-  NS_LOG_DEBUG (Simulator::Now () << " " << GetAddress () << " " << x);
-
 /*
  * The state machine for this NQSTA is:
  --------------            -----------
@@ -66,21 +63,21 @@
     .SetParent<WifiMac> ()
     .AddConstructor<NqstaWifiMac> ()
     .AddAttribute ("ProbeRequestTimeout", "XXX",
-                   Seconds (0.5),
+                   TimeValue (Seconds (0.5)),
                    MakeTimeAccessor (&NqstaWifiMac::m_probeRequestTimeout),
                    MakeTimeChecker ())
     .AddAttribute ("AssocRequestTimeout", "XXX",
-                   Seconds (0.5),
+                   TimeValue (Seconds (0.5)),
                    MakeTimeAccessor (&NqstaWifiMac::m_assocRequestTimeout),
                    MakeTimeChecker ())
     .AddAttribute ("MaxMissedBeacons", 
                    "Number of beacons which much be consecutively missed before "
                    "we attempt to restart association.",
-                   Uinteger (10),
+                   UintegerValue (10),
                    MakeUintegerAccessor (&NqstaWifiMac::m_maxMissedBeacons),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("ActiveProbing", "XXX",
-                   Boolean (false),
+                   BooleanValue (false),
                    MakeBooleanAccessor (&NqstaWifiMac::SetActiveProbing),
                    MakeBooleanChecker ())
     ;
@@ -94,6 +91,7 @@
     m_assocRequestEvent (),
     m_beaconWatchdogEnd (Seconds (0.0))
 {
+  NS_LOG_FUNCTION (this);
   m_rxMiddle = new MacRxMiddle ();
   m_rxMiddle->SetForwardCallback (MakeCallback (&NqstaWifiMac::Receive, this));
 
@@ -110,11 +108,14 @@
 }
 
 NqstaWifiMac::~NqstaWifiMac ()
-{}
+{
+  NS_LOG_FUNCTION (this);
+}
 
 void
 NqstaWifiMac::DoDispose (void)
 {
+  NS_LOG_FUNCTION (this);
   delete m_rxMiddle;
   delete m_dcfManager;
   m_rxMiddle = 0;
@@ -128,18 +129,21 @@
 void 
 NqstaWifiMac::SetSlot (Time slotTime)
 {
+  NS_LOG_FUNCTION (this << slotTime);
   m_dcfManager->SetSlot (slotTime);
   m_slot = slotTime;
 }
 void 
 NqstaWifiMac::SetSifs (Time sifs)
 {
+  NS_LOG_FUNCTION (this << sifs);
   m_dcfManager->SetSifs (sifs);
   m_sifs = sifs;
 }
 void 
 NqstaWifiMac::SetEifsNoDifs (Time eifsNoDifs)
 {
+  NS_LOG_FUNCTION (this << eifsNoDifs);
   m_dcfManager->SetEifsNoDifs (eifsNoDifs);
   m_eifsNoDifs = eifsNoDifs;
 }
@@ -206,33 +210,39 @@
 void 
 NqstaWifiMac::SetAddress (Mac48Address address)
 {
+  NS_LOG_FUNCTION (this << address);
   m_address = address;
 }
 void 
 NqstaWifiMac::SetSsid (Ssid ssid)
 {
+  NS_LOG_FUNCTION (this << ssid);
   m_ssid = ssid;
 }
 
 void 
 NqstaWifiMac::SetMaxMissedBeacons (uint32_t missed)
 {
+  NS_LOG_FUNCTION (this << missed);
   m_maxMissedBeacons = missed;
 }
 void 
 NqstaWifiMac::SetProbeRequestTimeout (Time timeout)
 {
+  NS_LOG_FUNCTION (this << timeout);
   m_probeRequestTimeout = timeout;
 }
 void 
 NqstaWifiMac::SetAssocRequestTimeout (Time timeout)
 {
+  NS_LOG_FUNCTION (this << timeout);
   m_assocRequestTimeout = timeout;
 }
 
 void 
 NqstaWifiMac::StartActiveAssociation (void)
 {
+  NS_LOG_FUNCTION (this);
   TryToEnsureAssociated ();
 }
 
@@ -245,11 +255,13 @@
 void 
 NqstaWifiMac::SetBssid (Mac48Address bssid)
 {
+  NS_LOG_FUNCTION (this << bssid);
   m_bssid = bssid;
 }
 void 
 NqstaWifiMac::SetActiveProbing (bool enable)
 {
+  NS_LOG_FUNCTION (this << enable);
   if (enable)
     {
       TryToEnsureAssociated ();
@@ -262,12 +274,13 @@
 void 
 NqstaWifiMac::ForwardUp (Ptr<Packet> packet, const Mac48Address &address)
 {
+  NS_LOG_FUNCTION (this << packet << address);
   m_forwardUp (packet, address);
 }
 void
 NqstaWifiMac::SendProbeRequest (void)
 {
-  TRACE ("send probe request");
+  NS_LOG_FUNCTION (this);
   WifiMacHeader hdr;
   hdr.SetProbeReq ();
   hdr.SetAddr1 (GetBroadcastBssid ());
@@ -290,7 +303,7 @@
 void
 NqstaWifiMac::SendAssociationRequest (void)
 {
-  TRACE ("send assoc request to=" << GetBssid ());
+  NS_LOG_FUNCTION (this << GetBssid ());
   WifiMacHeader hdr;
   hdr.SetAssocReq ();
   hdr.SetAddr1 (GetBssid ());
@@ -312,6 +325,7 @@
 void
 NqstaWifiMac::TryToEnsureAssociated (void)
 {
+  NS_LOG_FUNCTION (this);
   switch (m_state) {
   case ASSOCIATED:
     return;
@@ -351,37 +365,40 @@
 void
 NqstaWifiMac::AssocRequestTimeout (void)
 {
-  TRACE ("assoc request timeout");
+  NS_LOG_FUNCTION (this);
   m_state = WAIT_ASSOC_RESP;
   SendAssociationRequest ();
 }
 void
 NqstaWifiMac::ProbeRequestTimeout (void)
 {
-  TRACE ("probe request timeout");
+  NS_LOG_FUNCTION (this);
   m_state = WAIT_PROBE_RESP;
   SendProbeRequest ();
 }
 void 
 NqstaWifiMac::MissedBeacons (void)
 {
+  NS_LOG_FUNCTION (this);
   if (m_beaconWatchdogEnd > Simulator::Now ())
     {
       m_beaconWatchdog = Simulator::Schedule (m_beaconWatchdogEnd - Simulator::Now (),
                                               &NqstaWifiMac::MissedBeacons, this);
       return;
     }
-  TRACE ("beacon missed");
+  NS_LOG_DEBUG ("beacon missed");
   m_state = BEACON_MISSED;
   TryToEnsureAssociated ();
 }
 void 
 NqstaWifiMac::RestartBeaconWatchdog (Time delay)
 {
+  NS_LOG_FUNCTION (this << delay);
   m_beaconWatchdogEnd = std::max (Simulator::Now () + delay, m_beaconWatchdogEnd);
   if (Simulator::GetDelayLeft (m_beaconWatchdog) < delay &&
       m_beaconWatchdog.IsExpired ())
     {
+      NS_LOG_DEBUG ("really restart watchdog.");
       m_beaconWatchdog = Simulator::Schedule (delay, &NqstaWifiMac::MissedBeacons, this);
     }
 }
@@ -394,12 +411,13 @@
 void 
 NqstaWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
 {
+  NS_LOG_FUNCTION (this << packet << to);
   if (!IsAssociated ()) 
     {
       TryToEnsureAssociated ();
       return;
     }
-  //TRACE ("enqueue size="<<packet->GetSize ()<<", to="<<to);
+  //NS_LOG_DEBUG ("enqueue size="<<packet->GetSize ()<<", to="<<to);
   WifiMacHeader hdr;
   hdr.SetTypeData ();
   hdr.SetAddr1 (GetBssid ());
@@ -413,6 +431,7 @@
 void 
 NqstaWifiMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
 {
+  NS_LOG_FUNCTION (this << packet << hdr);
   NS_ASSERT (!hdr->IsCtl ());
   if (hdr->GetAddr1 () != GetAddress () &&
       !hdr->GetAddr1 ().IsBroadcast ()) 
@@ -487,7 +506,7 @@
           if (assocResp.GetStatusCode ().IsSuccess ()) 
             {
               m_state = ASSOCIATED;
-              TRACE ("assoc completed"); 
+              NS_LOG_DEBUG ("assoc completed"); 
               SupportedRates rates = assocResp.GetSupportedRates ();
               WifiRemoteStation *ap = m_stationManager->Lookup (hdr->GetAddr2 ());
               for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
@@ -509,7 +528,7 @@
             } 
           else 
             {
-              TRACE ("assoc refused");
+              NS_LOG_DEBUG ("assoc refused");
               m_state = REFUSED;
             }
         }
--- a/src/devices/wifi/onoe-wifi-manager.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/onoe-wifi-manager.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -37,15 +37,15 @@
     .AddConstructor<OnoeWifiManager> ()
     .AddAttribute ("UpdatePeriod",
                    "The interval between decisions about rate control changes",
-                   Seconds (1.0),
+                   TimeValue (Seconds (1.0)),
                    MakeTimeAccessor (&OnoeWifiManager::m_updatePeriod),
                    MakeTimeChecker ())
     .AddAttribute ("RaiseThreshold", "XXX",
-                   Uinteger (10),
+                   UintegerValue (10),
                    MakeUintegerAccessor (&OnoeWifiManager::m_raiseThreshold),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("AddCreditThreshold", "Add credit threshold",
-                   Uinteger (10),
+                   UintegerValue (10),
                    MakeUintegerAccessor (&OnoeWifiManager::m_addCreditThreshold),
                    MakeUintegerChecker<uint32_t> ())
     ;
--- a/src/devices/wifi/onoe-wifi-manager.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/onoe-wifi-manager.h	Tue Apr 22 21:19:39 2008 -0700
@@ -25,6 +25,15 @@
 
 namespace ns3 {
 
+/**
+ * \brief an implementation of rate control algorithm developed 
+ *        by Atsushi Onoe
+ *
+ * This algorithm is well known because it has been used as the default
+ * rate control algorithm for the madwifi driver. I am not aware of
+ * any publication or reference about this algorithm beyond the madwifi
+ * source code.
+ */
 class OnoeWifiManager : public WifiRemoteStationManager
 {
 public:
@@ -41,15 +50,6 @@
   uint32_t m_raiseThreshold;
 };
 
-/**
- * \brief an implementation of rate control algorithm developed 
- *        by Atsushi Onoe
- *
- * This algorithm is well known because it has been used as the default
- * rate control algorithm for the madwifi driver. I am not aware of
- * any publication or reference about this algorithm beyond the madwifi
- * source code.
- */
 class OnoeWifiRemoteStation : public WifiRemoteStation
 {
 public:
--- a/src/devices/wifi/propagation-delay-model.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/propagation-delay-model.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -24,6 +24,17 @@
 
 namespace ns3 {
 
+NS_OBJECT_ENSURE_REGISTERED (PropagationDelayModel);
+
+TypeId 
+PropagationDelayModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::PropagationDelayModel")
+    .SetParent<Object> ()
+    ;
+  return tid;
+}
+
 PropagationDelayModel::~PropagationDelayModel ()
 {}
 
@@ -37,7 +48,7 @@
     .AddConstructor<RandomPropagationDelayModel> ()
     .AddAttribute ("Variable",
                    "The random variable which generates random delays (s).",
-                   UniformVariable (0.0, 1.0),
+                   RandomVariableValue (UniformVariable (0.0, 1.0)),
                    MakeRandomVariableAccessor (&RandomPropagationDelayModel::m_variable),
                    MakeRandomVariableChecker ())
     ;
@@ -63,7 +74,7 @@
     .SetParent<PropagationDelayModel> ()
     .AddConstructor<ConstantSpeedPropagationDelayModel> ()
     .AddAttribute ("Speed", "The speed (m/s)",
-                   Double (300000000.0),
+                   DoubleValue (300000000.0),
                    MakeDoubleAccessor (&ConstantSpeedPropagationDelayModel::m_speed),
                    MakeDoubleChecker<double> ())
     ;
--- a/src/devices/wifi/propagation-delay-model.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/propagation-delay-model.h	Tue Apr 22 21:19:39 2008 -0700
@@ -35,6 +35,7 @@
 class PropagationDelayModel : public Object
 {
 public:
+  static TypeId GetTypeId (void);
   virtual ~PropagationDelayModel ();
   /**
    * \param a the source
--- a/src/devices/wifi/propagation-loss-model.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/propagation-loss-model.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -22,6 +22,7 @@
 #include "ns3/mobility-model.h"
 #include "ns3/static-mobility-model.h"
 #include "ns3/double.h"
+#include "ns3/pointer.h"
 #include <math.h>
 
 NS_LOG_COMPONENT_DEFINE ("PropagationLossModel");
@@ -31,17 +32,31 @@
 
 const double FriisPropagationLossModel::PI = 3.1415;
 
+NS_OBJECT_ENSURE_REGISTERED (PropagationLossModel);
+
+TypeId 
+PropagationLossModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::PropagationLossModel")
+    .SetParent<Object> ()
+    ;
+  return tid;
+}
+
+
 PropagationLossModel::~PropagationLossModel ()
 {}
 
+NS_OBJECT_ENSURE_REGISTERED (RandomPropagationLossModel);
+
 TypeId 
 RandomPropagationLossModel::GetTypeId (void)
 {
-  static TypeId tid = TypeId ("RandomPropagationLossModel")
+  static TypeId tid = TypeId ("ns3::RandomPropagationLossModel")
     .SetParent<PropagationLossModel> ()
     .AddConstructor<RandomPropagationLossModel> ()
     .AddAttribute ("Variable", "XXX",
-                   ConstantVariable (1.0),
+                   RandomVariableValue (ConstantVariable (1.0)),
                    MakeRandomVariableAccessor (&RandomPropagationLossModel::m_variable),
                    MakeRandomVariableChecker ())
     ;
@@ -62,24 +77,26 @@
   return rxc;
 }
 
+NS_OBJECT_ENSURE_REGISTERED (FriisPropagationLossModel);
+
 TypeId 
 FriisPropagationLossModel::GetTypeId (void)
 {
-  static TypeId tid = TypeId ("FriisPropagationLossModel")
+  static TypeId tid = TypeId ("ns3::FriisPropagationLossModel")
     .SetParent<PropagationLossModel> ()
     .AddConstructor<FriisPropagationLossModel> ()
     .AddAttribute ("Lambda", 
                    "The wavelength  (default is 5.15 GHz at 300 000 km/s).",
-                   Double (300000000.0 / 5.150e9),
+                   DoubleValue (300000000.0 / 5.150e9),
                    MakeDoubleAccessor (&FriisPropagationLossModel::m_lambda),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("SystemLoss", "The system loss",
-                   Double (1.0),
+                   DoubleValue (1.0),
                    MakeDoubleAccessor (&FriisPropagationLossModel::m_systemLoss),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("MinDistance", 
                    "The distance under which the propagation model refuses to give results (m)",
-                   Double (0.5),
+                   DoubleValue (0.5),
                    MakeDoubleAccessor (&FriisPropagationLossModel::m_minDistance),
                    MakeDoubleChecker<double> ())
     ;
@@ -174,27 +191,29 @@
   return pr;
 }
 
+NS_OBJECT_ENSURE_REGISTERED (LogDistancePropagationLossModel);
+
 TypeId
 LogDistancePropagationLossModel::GetTypeId (void)
 {
-  static TypeId tid = TypeId ("LogDistancePropagationLossModel")
+  static TypeId tid = TypeId ("ns3::LogDistancePropagationLossModel")
     .SetParent<PropagationLossModel> ()
     .AddConstructor<LogDistancePropagationLossModel> ()
     .AddAttribute ("Exponent",
                    "The exponent of the Path Loss propagation model",
-                   Double (3.0),
+                   DoubleValue (3.0),
                    MakeDoubleAccessor (&LogDistancePropagationLossModel::m_exponent),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("ReferenceDistance",
                    "The distance at which the reference loss is calculated (m)",
-                   Double (1.0),
+                   DoubleValue (1.0),
                    MakeDoubleAccessor (&LogDistancePropagationLossModel::m_referenceDistance),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("ReferenceModel",
                    "The reference model at the reference distance.",
-                   Ptr<PropagationLossModel> (0),
-                   MakePtrAccessor (&LogDistancePropagationLossModel::m_reference),
-                   MakePtrChecker<PropagationLossModel> ())
+                   PointerValue (),
+                   MakePointerAccessor (&LogDistancePropagationLossModel::m_reference),
+                   MakePointerChecker<PropagationLossModel> ())
     ;
   return tid;
                    
@@ -249,10 +268,10 @@
    */
   static Ptr<StaticMobilityModel> zero = 
     CreateObject<StaticMobilityModel> ("Position", 
-                                       Vector (0.0, 0.0, 0.0));
+                                       VectorValue (Vector (0.0, 0.0, 0.0)));
   static Ptr<StaticMobilityModel> reference = 
     CreateObject<StaticMobilityModel> ("Position", 
-                                       Vector (m_referenceDistance, 0.0, 0.0));
+                                       VectorValue (Vector (m_referenceDistance, 0.0, 0.0)));
   double ref = m_reference->GetLoss (zero, reference);
   double pathLossDb = 10 * m_exponent * log10 (distance / m_referenceDistance);
   double rxc = ref - pathLossDb;
--- a/src/devices/wifi/propagation-loss-model.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/propagation-loss-model.h	Tue Apr 22 21:19:39 2008 -0700
@@ -36,6 +36,8 @@
 class PropagationLossModel : public Object
 {
 public:
+  static TypeId GetTypeId (void);
+
   virtual ~PropagationLossModel ();
   /**
    * \param a the mobility model of the source
--- a/src/devices/wifi/rraa-wifi-manager.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/rraa-wifi-manager.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -193,122 +193,122 @@
     .AddConstructor<RraaWifiManager> ()
     .AddAttribute ("Basic",
                    "If true the RRAA-BASIC algorithm will be used, otherwise the RRAA wil be used",
-                   Boolean (false),
+                   BooleanValue (false),
                    MakeBooleanAccessor (&RraaWifiManager::m_basic),
                    MakeBooleanChecker ())
     .AddAttribute ("Timeout",
                    "Timeout for the RRAA BASIC loss estimaton block (s)",
-                   Seconds (0.05),
+                   TimeValue (Seconds (0.05)),
                    MakeTimeAccessor (&RraaWifiManager::m_timeout),
                    MakeTimeChecker ())
     .AddAttribute ("ewndFor54mbps",
                    "ewnd parameter for 54 Mbs data mode",
-                   Uinteger (40),
+                   UintegerValue (40),
                    MakeUintegerAccessor (&RraaWifiManager::m_ewndfor54),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("ewndFor48mbps",
                    "ewnd parameter for 48 Mbs data mode",
-                   Uinteger (40),
+                   UintegerValue (40),
                    MakeUintegerAccessor (&RraaWifiManager::m_ewndfor48),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("ewndFor36mbps",
                    "ewnd parameter for 36 Mbs data mode",
-                   Uinteger (40),
+                   UintegerValue (40),
                    MakeUintegerAccessor (&RraaWifiManager::m_ewndfor36),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("ewndFor24mbps",
                    "ewnd parameter for 24 Mbs data mode",
-                   Uinteger (40),
+                   UintegerValue (40),
                    MakeUintegerAccessor (&RraaWifiManager::m_ewndfor24),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("ewndFor18mbps",
                    "ewnd parameter for 18 Mbs data mode",
-                   Uinteger (20),
+                   UintegerValue (20),
                    MakeUintegerAccessor (&RraaWifiManager::m_ewndfor18),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("ewndFor12mbps",
                    "ewnd parameter for 12 Mbs data mode",
-                   Uinteger (20),
+                   UintegerValue (20),
                    MakeUintegerAccessor (&RraaWifiManager::m_ewndfor12),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("ewndFor9mbps",
                    "ewnd parameter for 9 Mbs data mode",
-                   Uinteger (10),
+                   UintegerValue (10),
                    MakeUintegerAccessor (&RraaWifiManager::m_ewndfor9),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("ewndFor6mbps",
                    "ewnd parameter for 6 Mbs data mode",
-                   Uinteger (6),
+                   UintegerValue (6),
                    MakeUintegerAccessor (&RraaWifiManager::m_ewndfor6),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("poriFor48mbps",
                    "Pori parameter for 48 Mbs data mode",
-                   Double (0.047),
+                   DoubleValue (0.047),
                    MakeDoubleAccessor (&RraaWifiManager::m_porifor48),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("poriFor36mbps",
                    "Pori parameter for 36 Mbs data mode",
-                   Double (0.115),
+                   DoubleValue (0.115),
                    MakeDoubleAccessor (&RraaWifiManager::m_porifor36),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("poriFor24mbps",
                    "Pori parameter for 24 Mbs data mode",
-                   Double (0.1681),
+                   DoubleValue (0.1681),
                    MakeDoubleAccessor (&RraaWifiManager::m_porifor24),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("poriFor18mbps",
                    "Pori parameter for 18 Mbs data mode",
-                   Double (0.1325),
+                   DoubleValue (0.1325),
                    MakeDoubleAccessor (&RraaWifiManager::m_porifor18),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("poriFor12mbps",
                    "Pori parameter for 12 Mbs data mode",
-                   Double (0.1861),
+                   DoubleValue (0.1861),
                    MakeDoubleAccessor (&RraaWifiManager::m_porifor12),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("poriFor9mbps",
                    "Pori parameter for 9 Mbs data mode",
-                   Double (0.1434),
+                   DoubleValue (0.1434),
                    MakeDoubleAccessor (&RraaWifiManager::m_porifor9),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("poriFor6mbps",
                    "Pori parameter for 6 Mbs data mode",
-                   Double (0.5),
+                   DoubleValue (0.5),
                    MakeDoubleAccessor (&RraaWifiManager::m_porifor6),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("pmtlFor54mbps",
                    "Pmtl parameter for 54 Mbs data mode",
-                   Double (0.094),
+                   DoubleValue (0.094),
                    MakeDoubleAccessor (&RraaWifiManager::m_pmtlfor54),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("pmtlFor48mbps",
                    "Pmtl parameter for 48 Mbs data mode",
-                   Double (0.23),
+                   DoubleValue (0.23),
                    MakeDoubleAccessor (&RraaWifiManager::m_pmtlfor48),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("pmtlFor36mbps",
                    "Pmtl parameter for 36 Mbs data mode",
-                   Double (0.3363),
+                   DoubleValue (0.3363),
                    MakeDoubleAccessor (&RraaWifiManager::m_pmtlfor36),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("pmtlFor24mbps",
                    "Pmtl parameter for 24 Mbs data mode",
-                   Double (0.265),
+                   DoubleValue (0.265),
                    MakeDoubleAccessor (&RraaWifiManager::m_pmtlfor24),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("pmtlFor18mbps",
                    "Pmtl parameter for 18 Mbs data mode",
-                   Double (0.3722),
+                   DoubleValue (0.3722),
                    MakeDoubleAccessor (&RraaWifiManager::m_pmtlfor18),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("pmtlFor12mbps",
                    "Pmtl parameter for 12 Mbs data mode",
-                   Double(0.2868),
+                   DoubleValue (0.2868),
                    MakeDoubleAccessor (&RraaWifiManager::m_pmtlfor12),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("pmtlFor9mbps",
                    "Pmtl parameter for 9 Mbs data mode",
-                   Double (0.3932),
+                   DoubleValue (0.3932),
                    MakeDoubleAccessor (&RraaWifiManager::m_pmtlfor9),
                    MakeDoubleChecker<double> ())
     ;
--- a/src/devices/wifi/ssid.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/ssid.h	Tue Apr 22 21:19:39 2008 -0700
@@ -26,6 +26,10 @@
 
 namespace ns3 {
 
+/**
+ * \brief a IEEE 802.11 SSID
+ *
+ */
 class Ssid 
 {
 public:
@@ -54,6 +58,11 @@
 std::ostream &operator << (std::ostream &os, const Ssid &ssid);
 std::istream &operator >> (std::istream &is, Ssid &ssid);
 
+/**
+ * \class ns3::SsidValue
+ * \brief hold objects of type ns3::Ssid
+ */
+
 ATTRIBUTE_HELPER_HEADER_2 (Ssid);
 
 } // namespace ns3
--- a/src/devices/wifi/wifi-channel.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/wifi-channel.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -23,6 +23,7 @@
 #include "ns3/net-device.h"
 #include "ns3/node.h"
 #include "ns3/log.h"
+#include "ns3/pointer.h"
 #include "wifi-channel.h"
 #include "propagation-loss-model.h"
 #include "propagation-delay-model.h"
@@ -32,19 +33,19 @@
 namespace ns3 {
 
 TypeId 
-WifiChannel::GetTypdId (void)
+WifiChannel::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::WifiChannel")
-    .SetParent<WifiChannel> ()
+    .SetParent<Channel> ()
     .AddConstructor<WifiChannel> ()
     .AddAttribute ("PropagationLossModel", "XXX",
-                   Ptr<PropagationLossModel> (0),
-                   MakePtrAccessor (&WifiChannel::m_loss),
-                   MakePtrChecker<PropagationLossModel> ())
+                   PointerValue (),
+                   MakePointerAccessor (&WifiChannel::m_loss),
+                   MakePointerChecker<PropagationLossModel> ())
     .AddAttribute ("PropagationDelayModel", "XXX",
-                   Ptr<PropagationDelayModel> (0),
-                   MakePtrAccessor (&WifiChannel::m_delay),
-                   MakePtrChecker<PropagationDelayModel> ())
+                   PointerValue (),
+                   MakePointerAccessor (&WifiChannel::m_delay),
+                   MakePointerChecker<PropagationDelayModel> ())
     ;
   return tid;
 }
--- a/src/devices/wifi/wifi-channel.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/wifi-channel.h	Tue Apr 22 21:19:39 2008 -0700
@@ -47,7 +47,7 @@
 class WifiChannel : public Channel
 {
 public:
-  static TypeId GetTypdId (void);
+  static TypeId GetTypeId (void);
 
   WifiChannel ();
   virtual ~WifiChannel ();
--- a/src/devices/wifi/wifi-mac-header.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/wifi-mac-header.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -21,17 +21,6 @@
 #include "ns3/address-utils.h"
 #include "wifi-mac-header.h"
 
-#define MAC80211HEADER_DEBUG 1
-
-#ifdef MAC80211HEADER_DEBUG
-#include <iostream>
-#  define TRACE(x) \
-std::Cout << "MAC80211HEADER " << x << std::Endl;
-#else
-#  define TRACE(x)
-#endif
-
-
 namespace ns3 {
 
 NS_OBJECT_ENSURE_REGISTERED (WifiMacHeader);
--- a/src/devices/wifi/wifi-mac-queue.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/wifi-mac-queue.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -40,12 +40,12 @@
   static TypeId tid = TypeId ("WifiMacQueue")
     .SetParent<Object> ()
     .AddConstructor<WifiMacQueue> ()
-    .AddAttribute ("MaxPacketNumber", "XXX",
-                   Uinteger (400),
+    .AddAttribute ("MaxPacketNumber", "If a packet arrives when there are already this number of packets, it is dropped.",
+                   UintegerValue (400),
                    MakeUintegerAccessor (&WifiMacQueue::m_maxSize),
                    MakeUintegerChecker<uint32_t> ())
-    .AddAttribute ("MaxDelay", "XXX",
-                   Seconds (10.0),
+    .AddAttribute ("MaxDelay", "If a packet stays longer than this delay in the queue, it is dropped.",
+                   TimeValue (Seconds (10.0)),
                    MakeTimeAccessor (&WifiMacQueue::m_maxDelay),
                    MakeTimeChecker ())
     ;
--- a/src/devices/wifi/wifi-mac.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/wifi-mac.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -74,42 +74,42 @@
   static TypeId tid = TypeId ("ns3::WifiMac")
     .SetParent<Object> ()
     .AddAttribute ("CtsTimeout", "XXX",
-                   GetDefaultCtsAckTimeout (),
+                   TimeValue (GetDefaultCtsAckTimeout ()),
                    MakeTimeAccessor (&WifiMac::m_ctsTimeout),
                    MakeTimeChecker ())
     .AddAttribute ("AckTimeout", "XXX",
-                   GetDefaultCtsAckTimeout (),
+                   TimeValue (GetDefaultCtsAckTimeout ()),
                    MakeTimeAccessor (&WifiMac::m_ackTimeout),
                    MakeTimeChecker ())
     .AddAttribute ("Sifs", "XXX",
-                   GetDefaultSifs (),
+                   TimeValue (GetDefaultSifs ()),
                    MakeTimeAccessor (&WifiMac::SetSifs,
 				     &WifiMac::GetSifs),
                    MakeTimeChecker ())
     .AddAttribute ("EifsNoDifs", "XXX",
-		   GetDefaultEifsNoDifs (),
+		   TimeValue (GetDefaultEifsNoDifs ()),
 		   MakeTimeAccessor (&WifiMac::SetEifsNoDifs,
 				     &WifiMac::GetEifsNoDifs),
 		   MakeTimeChecker ())
     .AddAttribute ("Slot", "XXX",
-                   GetDefaultSlot (),
+                   TimeValue (GetDefaultSlot ()),
                    MakeTimeAccessor (&WifiMac::SetSlot,
 				     &WifiMac::GetSlot),
                    MakeTimeChecker ())
     .AddAttribute ("Pifs", "XXX",
-                   GetDefaultSifs () + GetDefaultSlot (),
+                   TimeValue (GetDefaultSifs () + GetDefaultSlot ()),
                    MakeTimeAccessor (&WifiMac::m_pifs),
                    MakeTimeChecker ())
     .AddAttribute ("MaxPropagationDelay", "XXX",
-                   GetDefaultMaxPropagationDelay (),
+                   TimeValue (GetDefaultMaxPropagationDelay ()),
                    MakeTimeAccessor (&WifiMac::m_maxPropagationDelay),
                    MakeTimeChecker ())
     .AddAttribute ("MaxMsduSize", "XXX",
-		   Uinteger (2304),
+		   UintegerValue (2304),
 		   MakeUintegerAccessor (&WifiMac::m_maxMsduSize),
 		   MakeUintegerChecker<uint16_t> (1,2304))
     .AddAttribute ("Ssid", "XXX",
-		   Ssid ("default"),
+		   SsidValue (Ssid ("default")),
 		   MakeSsidAccessor (&WifiMac::GetSsid,
 				     &WifiMac::SetSsid),
 		   MakeSsidChecker ())
--- a/src/devices/wifi/wifi-mode.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/wifi-mode.h	Tue Apr 22 21:19:39 2008 -0700
@@ -118,6 +118,11 @@
 std::ostream & operator << (std::ostream & os, const WifiMode &mode);
 std::istream & operator >> (std::istream &is, WifiMode &mode);
 
+/**
+ * \class ns3::WifiModeValue
+ * \brief hold objects of type ns3::WifiMode
+ */
+
 ATTRIBUTE_HELPER_HEADER_2 (WifiMode);
 
 /**
--- a/src/devices/wifi/wifi-net-device.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/wifi-net-device.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -25,39 +25,42 @@
 #include "ns3/llc-snap-header.h"
 #include "ns3/packet.h"
 #include "ns3/uinteger.h"
+#include "ns3/pointer.h"
 #include "ns3/node.h"
 #include "ns3/trace-source-accessor.h"
 
 namespace ns3 {
 
+NS_OBJECT_ENSURE_REGISTERED (WifiNetDevice);
+
 TypeId 
 WifiNetDevice::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::WifiNetDevice")
     .SetParent<NetDevice> ()
-    .AddAttribute ("Channel", "XXX",
-                   Ptr<Channel> (0),
-                   MakePtrAccessor (&WifiNetDevice::DoGetChannel,
-                                    &WifiNetDevice::SetChannel),
-                   MakePtrChecker<Channel> ())
-    .AddAttribute ("Phy", "XXX",
-                   Ptr<WifiPhy> (0),
-                   MakePtrAccessor (&WifiNetDevice::GetPhy,
-                                    &WifiNetDevice::SetPhy),
-                   MakePtrChecker<WifiPhy> ())
-    .AddAttribute ("Mac", "XXX",
-                   Ptr<WifiMac> (0),
-                   MakePtrAccessor (&WifiNetDevice::GetMac,
-                                    &WifiNetDevice::SetMac),
-                   MakePtrChecker<WifiMac> ())
-    .AddAttribute ("RemoteStationManager", "XXX",
-                   Ptr<WifiRemoteStationManager> (0),
-                   MakePtrAccessor (&WifiNetDevice::SetRemoteStationManager,
-                                    &WifiNetDevice::GetRemoteStationManager),
-                   MakePtrChecker<WifiRemoteStationManager> ())
-    .AddTraceSource ("Rx", "XXX",
+    .AddAttribute ("Channel", "The channel attached to this device",
+                   PointerValue (),
+                   MakePointerAccessor (&WifiNetDevice::DoGetChannel,
+                                        &WifiNetDevice::SetChannel),
+                   MakePointerChecker<WifiChannel> ())
+    .AddAttribute ("Phy", "The PHY layer attached to this device.",
+                   PointerValue (),
+                   MakePointerAccessor (&WifiNetDevice::GetPhy,
+                                        &WifiNetDevice::SetPhy),
+                   MakePointerChecker<WifiPhy> ())
+    .AddAttribute ("Mac", "The MAC layer attached to this device.",
+                   PointerValue (),
+                   MakePointerAccessor (&WifiNetDevice::GetMac,
+                                        &WifiNetDevice::SetMac),
+                   MakePointerChecker<WifiMac> ())
+    .AddAttribute ("RemoteStationManager", "The station manager attached to this device.",
+                   PointerValue (),
+                   MakePointerAccessor (&WifiNetDevice::SetRemoteStationManager,
+                                        &WifiNetDevice::GetRemoteStationManager),
+                   MakePointerChecker<WifiRemoteStationManager> ())
+    .AddTraceSource ("Rx", "Received payload from the MAC layer.",
                      MakeTraceSourceAccessor (&WifiNetDevice::m_rxLogger))
-    .AddTraceSource ("Tx", "XXX",
+    .AddTraceSource ("Tx", "Send payload to the MAC layer.",
                      MakeTraceSourceAccessor (&WifiNetDevice::m_txLogger))
     ;
   return tid;
@@ -204,8 +207,9 @@
 bool 
 WifiNetDevice::SetMtu (const uint16_t mtu)
 {
-  Uinteger maxMsduSize = m_mac->GetAttribute ("MaxMsduSize");
-  if (mtu > maxMsduSize && mtu > 0)
+  UintegerValue maxMsduSize;
+  m_mac->GetAttribute ("MaxMsduSize", maxMsduSize);
+  if (mtu > maxMsduSize.Get () || mtu == 0)
     {
       return false;
     }
@@ -217,8 +221,9 @@
 {
   if (m_mtu == 0)
     {
-      Uinteger maxMsduSize = m_mac->GetAttribute ("MaxMsduSize");
-      m_mtu = maxMsduSize;
+      UintegerValue maxMsduSize;
+      m_mac->GetAttribute ("MaxMsduSize", maxMsduSize);
+      m_mtu = maxMsduSize.Get ();
     }
   return m_mtu;
 }
--- a/src/devices/wifi/wifi-phy.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/wifi-phy.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -187,48 +187,48 @@
     .AddAttribute ("EnergyDetectionThreshold",
                    "The energy of a received signal should be higher than "
                    "this threshold (dbm) to allow the PHY layer to detect the signal.",
-                   Double (-140.0),
+                   DoubleValue (-140.0),
                    MakeDoubleAccessor (&WifiPhy::SetEdThreshold,
                                        &WifiPhy::GetEdThreshold),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("TxGain",
                    "Transmission gain (dB).",
-                   Double (1.0),
+                   DoubleValue (1.0),
                    MakeDoubleAccessor (&WifiPhy::SetTxGain,
                                        &WifiPhy::GetTxGain),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("RxGain",
                    "Reception gain (dB).",
-                   Double (1.0),
+                   DoubleValue (1.0),
                    MakeDoubleAccessor (&WifiPhy::SetRxGain,
                                        &WifiPhy::GetRxGain),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("TxPowerLevels",
                    "Number of transmission power levels available between "
                    "TxPowerBase and TxPowerEnd included.",
-                   Uinteger (1),
+                   UintegerValue (1),
                    MakeUintegerAccessor (&WifiPhy::m_nTxPower),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("TxPowerEnd",
                    "Maximum available transmission level (dbm).",
-                   Double (16.0206),
+                   DoubleValue (16.0206),
                    MakeDoubleAccessor (&WifiPhy::SetTxPowerEnd, 
                                        &WifiPhy::GetTxPowerEnd),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("TxPowerStart",
                    "Minimum available transmission level (dbm).",
-                   Double (16.0206),
+                   DoubleValue (16.0206),
                    MakeDoubleAccessor (&WifiPhy::SetTxPowerStart, 
                                        &WifiPhy::GetTxPowerStart),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("RxNoise",
                    "Ratio of energy lost by receiver (dB).",
-                   Double (7),
+                   DoubleValue (7),
                    MakeDoubleAccessor (&WifiPhy::SetRxNoise,
                                        &WifiPhy::GetRxNoise),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("Standard", "XXX",
-                   Enum (WIFI_PHY_STANDARD_80211a),
+                   EnumValue (WIFI_PHY_STANDARD_80211a),
                    MakeEnumAccessor (&WifiPhy::SetStandard),
                    MakeEnumChecker (WIFI_PHY_STANDARD_80211a, "802.11a",
                                     WIFI_PHY_STANDARD_holland, "holland"))
@@ -258,14 +258,19 @@
     m_previousStateChangeTime (Seconds (0)),
     m_endSyncEvent (),
     m_random (0.0, 1.0)
-{}
+{
+  NS_LOG_FUNCTION (this);
+}
 
 WifiPhy::~WifiPhy ()
-{}
+{
+  NS_LOG_FUNCTION (this);
+}
 
 void
 WifiPhy::DoDispose (void)
 {
+  NS_LOG_FUNCTION (this);
   m_channel = 0;
   m_events.clear ();
   m_modes.clear ();
@@ -274,6 +279,7 @@
 void
 WifiPhy::SetStandard (enum WifiPhyStandard standard)
 {
+  NS_LOG_FUNCTION (this << standard);
   m_standard = standard;
   switch (standard) {
   case WIFI_PHY_STANDARD_80211a:
@@ -292,36 +298,43 @@
 void 
 WifiPhy::SetRxNoise (double db)
 {
+  NS_LOG_FUNCTION (this << db);
   m_rxNoiseRatio = DbToRatio (db);
 }
 void 
 WifiPhy::SetTxPowerStart (double start)
 {
+  NS_LOG_FUNCTION (this << start);
   m_txPowerBaseDbm = start;
 }
 void 
 WifiPhy::SetTxPowerEnd (double end)
 {
+  NS_LOG_FUNCTION (this << end);
   m_txPowerEndDbm = end;
 }
 void 
 WifiPhy::SetNTxPower (uint32_t n)
 {
+  NS_LOG_FUNCTION (this << n);
   m_nTxPower = n;
 }
 void 
 WifiPhy::SetTxGain (double gain)
 {
+  NS_LOG_FUNCTION (this << gain);
   m_txGainDb = gain;
 }
 void 
 WifiPhy::SetRxGain (double gain)
 {
+  NS_LOG_FUNCTION (this << gain);
   m_rxGainDb = gain;
 }
 void 
 WifiPhy::SetEdThreshold (double threshold)
 {
+  NS_LOG_FUNCTION (this << threshold);
   m_edThresholdW = DbmToW (threshold);
 }
 double 
@@ -384,6 +397,7 @@
                              WifiMode txMode,
                              enum WifiPreamble preamble)
 {
+  NS_LOG_FUNCTION (this << packet << rxPowerDbm << txMode << preamble);
   rxPowerDbm += m_rxGainDb;
   double rxPowerW = DbmToW (rxPowerDbm);
   Time rxDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
@@ -472,6 +486,7 @@
 void 
 WifiPhy::SendPacket (Ptr<const Packet> packet, WifiMode txMode, WifiPreamble preamble, uint8_t txPower)
 {
+  NS_LOG_FUNCTION (this << packet << txMode << preamble << txPower);
   /* Transmission can happen if:
    *  - we are syncing on a packet. It is the responsability of the
    *    MAC layer to avoid doing this but the PHY does nothing to 
@@ -529,6 +544,7 @@
 void
 WifiPhy::Configure80211aParameters (void)
 {
+  NS_LOG_FUNCTION (this);
   m_plcpLongPreambleDelayUs = 16;
   m_plcpShortPreambleDelayUs = 16;
   m_longPlcpHeaderMode = g_6mba;
@@ -558,6 +574,7 @@
 void
 WifiPhy::Configure80211a (void)
 {
+  NS_LOG_FUNCTION (this);
   Configure80211aParameters ();
   m_modes.push_back (g_6mba);
   m_modes.push_back (g_9mba);
@@ -574,6 +591,7 @@
 void
 WifiPhy::ConfigureHolland (void)
 {
+  NS_LOG_FUNCTION (this);
   Configure80211aParameters ();
   m_modes.push_back (g_6mba);
   m_modes.push_back (g_12mba);
@@ -1329,6 +1347,7 @@
 void
 WifiPhy::EndSync (Ptr<Packet> packet, Ptr<RxEvent> event)
 {
+  NS_LOG_FUNCTION (this << packet << event);
   NS_ASSERT (IsStateSync ());
   NS_ASSERT (event->GetEndTime () == Simulator::Now ());
 
--- a/src/devices/wifi/wifi-remote-station-manager.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/wifi-remote-station-manager.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -127,23 +127,23 @@
   static TypeId tid = TypeId ("ns3::WifiRemoteStationManager")
     .SetParent<Object> ()
     .AddAttribute ("IsLowLatency", "XXX",
-                   Boolean (true),
+                   BooleanValue (true),
                    MakeBooleanAccessor (&WifiRemoteStationManager::m_isLowLatency),
                    MakeBooleanChecker ())
     .AddAttribute ("MaxSsrc", "XXX",
-                   Uinteger (7),
+                   UintegerValue (7),
                    MakeUintegerAccessor (&WifiRemoteStationManager::m_maxSsrc),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("MaxSlrc", "XXX",
-                   Uinteger (7),
+                   UintegerValue (7),
                    MakeUintegerAccessor (&WifiRemoteStationManager::m_maxSlrc),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("RtsCtsThreshold", "XXX",
-                   Uinteger (1500),
+                   UintegerValue (1500),
                    MakeUintegerAccessor (&WifiRemoteStationManager::m_rtsCtsThreshold),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("FragmentationThreshold", "XXX",
-                   Uinteger (1500),
+                   UintegerValue (1500),
                    MakeUintegerAccessor (&WifiRemoteStationManager::m_fragmentationThreshold),
                    MakeUintegerChecker<uint32_t> ())
     ;
--- a/src/devices/wifi/wifi-trace.cc	Tue Apr 22 21:18:04 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +0,0 @@
-/* -*-	Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Federico Maguolo <maguolof@dei.unipd.it>
- */
-#include "wifi-trace.h"
-
-#include "ns3/trace-context.h"
-#include "ns3/simulator.h"
-#include "ns3/node.h"
-#include "ns3/node-list.h"
-#include "ns3/packet.h"
-#include "ns3/queue.h"
-
-namespace ns3 {
-
-WifiTrace::WifiTrace (std::string filename)
-{
-  m_os.open (filename.c_str ());
-}
-
-WifiTrace::WifiTrace ()
-{}
-
-WifiTrace::~WifiTrace ()
-{
-  if (m_os.is_open ())
-    m_os.close ();
-}
-
-void
-WifiTrace::TraceAllNetDeviceRx (void)
-{
-  Packet::EnableMetadata ();
-  NodeList::ConnectWithoutContext ("/nodes/*/devices/*/rx",
-                     MakeCallback (&WifiTrace::LogDevRx, this));
-}
-
-void
-WifiTrace::TraceAllNetDeviceTx (void)
-{
-  Packet::EnableMetadata ();
-  NodeList::ConnectWithoutContext ("/nodes/*/devices/*/tx",
-                     MakeCallback (&WifiTrace::LogDevTx, this));
-}
-
-void
-WifiTrace::TraceAllPhy (void)
-{
-  Packet::EnableMetadata ();
-  NodeList::ConnectWithoutContext ("/nodes/*/devices/*/*/state",
-                     MakeCallback (&WifiTrace::LogPhy, this));
-}
-
-void
-WifiTrace::TraceAllErrors (void)
-{
-  Packet::EnableMetadata ();
-  NodeList::ConnectWithoutContext ("/nodes/*/devices/*/*/error",
-                     MakeCallback (&WifiTrace::LogErrors, this));
-}
-
-void
-WifiTrace::TraceAckTimeouts (void)
-{
-  Packet::EnableMetadata ();
-  NodeList::ConnectWithoutContext ("/nodes/*/devices/*/*/ackTimeout",
-                     MakeCallback (&WifiTrace::LogAckTimeout, this));
-}
-
-void
-WifiTrace::TraceCtsTimeouts (void)
-{
-  Packet::EnableMetadata ();
-  NodeList::ConnectWithoutContext ("/nodes/*/devices/*/*/ctsTimeout",
-                     MakeCallback (&WifiTrace::LogCtsTimeout, this));
-}
-
-void 
-WifiTrace::LogDevRx (TraceContext const &context, Ptr<const Packet> p, Mac48Address addr)
-{
-  if (!m_os.is_open ())
-    return;
-  m_os << "r " << Simulator::Now ().GetSeconds () << " ";
-  uint8_t buf[6];
-  addr.CopyTo (buf);
-  for (uint8_t i = 0; i < 6; i++) {
-    m_os << (buf[i] + 0);
-    if (i < 5)
-      m_os << ".";
-  }
-  m_os << " ";
-  context.Print (m_os);
-  m_os << " pkt-uid=" << p->GetUid () << " ";
-  p->Print (m_os);
-  m_os << std::endl;  
-}
-
-void 
-WifiTrace::LogDevTx (TraceContext const &context, Ptr<const Packet> p, Mac48Address addr)
-{
-  if (!m_os.is_open ())
-    return;
-  m_os << "s " << Simulator::Now ().GetSeconds () << " ";
-  uint8_t buf[6];
-  addr.CopyTo (buf);
-  for (uint8_t i = 0; i < 6; i++) {
-    m_os << (buf[i] + 0);
-    if (i < 5)
-      m_os << ".";
-  }
-  m_os << " ";
-  context.Print (m_os);
-  m_os << " pkt-uid=" << p->GetUid () << " ";
-  p->Print (m_os);
-  m_os << std::endl;  
-}
-
-void
-WifiTrace::LogErrors (TraceContext const &context, Ptr<const Packet> p)
-{
-  if (!m_os.is_open ())
-    return;
-  m_os << "d " << Simulator::Now ().GetSeconds () << " ";
-  context.Print (m_os);
-  m_os << " pkt-uid=" << p->GetUid () << " ";
-  p->Print (m_os);
-  m_os << std::endl;  
-}
-
-void 
-WifiTrace::LogPhy (TraceContext const &context, Time s, Time d, WifiPhy::State state)
-{
-  if (!m_os.is_open ())
-    return;
-  int prec = m_os.precision ();
-  m_os.precision (9);
-  m_os << "PHY " << Simulator::Now ().GetSeconds () << " ";
-  context.Print (m_os);
-  switch(state)
-  {
-    case WifiPhy::SYNC:
-      m_os << " SYNC";
-      break;
-    case WifiPhy::TX:
-      m_os << " TX";
-      break;
-    case WifiPhy::CCA_BUSY:
-      m_os << " CCA_BUSY";
-      break;
-    case WifiPhy::IDLE:
-      m_os << " IDLE";
-      break;
-  }
-  m_os << " t=" << s.GetSeconds () << " d=" << d.GetMicroSeconds ();
-  m_os << std::endl; 
-  m_os.precision (prec);
-}
-
-void 
-WifiTrace::LogAckTimeout (TraceContext const &context, uint32_t a)
-{
-  if (!m_os.is_open ())
-    return;
-  m_os << "ACK timeout " << Simulator::Now ().GetSeconds () << " ";
-  context.Print (m_os);
-  m_os << " attemps=" << (a+0);
-  m_os << std::endl;  
-}
-
-void 
-WifiTrace::LogCtsTimeout (TraceContext const &context, uint32_t a)
-{
-  if (!m_os.is_open ())
-    return;
-  m_os << "CTS timeout " << Simulator::Now ().GetSeconds () << " ";
-  context.Print (m_os);
-  m_os << " attemps=" << (a+0);
-  m_os << std::endl;  
-}
-
-}//namespace ns3
--- a/src/devices/wifi/wifi-trace.h	Tue Apr 22 21:18:04 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/* -*-	Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Federico Maguolo <maguolof@dei.unipd.it>
- */
-#ifndef WIFI_TRACE_H
-#define WIFI_TRACE_H
-
-#include <string>
-#include <fstream>
-#include "ns3/wifi-phy.h"
-#include "ns3/mac48-address.h"
-//#include "ns3/ptr.h"
-
-namespace ns3 {
-
-class Packet;
-class TraceContext;
-
-class WifiTrace 
-{
-public:
-  WifiTrace (std::string filename);
-  WifiTrace ();
-  virtual ~WifiTrace ();
-  void TraceAllNetDeviceRx (void);
-  void TraceAllNetDeviceTx (void);
-  void TraceAllPhy (void);
-  void TraceAllErrors (void);
-  void TraceAckTimeouts (void);
-  void TraceCtsTimeouts (void);
-protected:
-  virtual void LogErrors (TraceContext const &context, Ptr<const Packet> p);
-  virtual void LogDevRx (TraceContext const &context, Ptr<const Packet> p, Mac48Address addr);
-  virtual void LogDevTx (TraceContext const &context, Ptr<const Packet> p, Mac48Address addr);
-  virtual void LogPhy (TraceContext const &context, Time s, Time d, WifiPhy::State state);
-  virtual void LogAckTimeout (TraceContext const &context, uint32_t a);
-  virtual void LogCtsTimeout (TraceContext const &context, uint32_t a);
-private:
-  std::ofstream m_os;
-};
-
-}//namespace ns3
-
-#endif /* ASCII_TRACE_H */
--- a/src/devices/wifi/wscript	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/devices/wifi/wscript	Tue Apr 22 21:19:39 2008 -0700
@@ -54,7 +54,6 @@
         'wifi-preamble.h',
 	'wifi-phy-standard.h',
         'wifi-phy.h',
-	'wifi-trace.h',
         'wifi-remote-station-manager.h',
         'arf-wifi-manager.h',
         'aarf-wifi-manager.h',
--- a/src/helper/csma-helper.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/csma-helper.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -39,10 +39,10 @@
 
 void 
 CsmaHelper::SetQueue (std::string type,
-		      std::string n1, Attribute v1,
-		      std::string n2, Attribute v2,
-		      std::string n3, Attribute v3,
-		      std::string n4, Attribute v4)
+		      std::string n1, const AttributeValue &v1,
+		      std::string n2, const AttributeValue &v2,
+		      std::string n3, const AttributeValue &v3,
+		      std::string n4, const AttributeValue &v4)
 {
   m_queueFactory.SetTypeId (type);
   m_queueFactory.Set (n1, v1);
@@ -52,13 +52,13 @@
 }
 
 void 
-CsmaHelper::SetDeviceParameter (std::string n1, Attribute v1)
+CsmaHelper::SetDeviceParameter (std::string n1, const AttributeValue &v1)
 {
   m_deviceFactory.Set (n1, v1);
 }
 
 void 
-CsmaHelper::SetChannelParameter (std::string n1, Attribute v1)
+CsmaHelper::SetChannelParameter (std::string n1, const AttributeValue &v1)
 {
   m_channelFactory.Set (n1, v1);
 }
--- a/src/helper/csma-helper.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/csma-helper.h	Tue Apr 22 21:19:39 2008 -0700
@@ -56,10 +56,10 @@
    * CsmaNetDevice created through CsmaHelper::Install.
    */
   void SetQueue (std::string type,
-		 std::string n1 = "", Attribute v1 = Attribute (),
-		 std::string n2 = "", Attribute v2 = Attribute (),
-		 std::string n3 = "", Attribute v3 = Attribute (),
-		 std::string n4 = "", Attribute v4 = Attribute ());
+		 std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+		 std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+		 std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+		 std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue ());
 
   /**
    * \param n1 the name of the attribute to set
@@ -68,7 +68,7 @@
    * Set these parameters on each ns3::CsmaNetDevice created
    * by CsmaHelper::Install
    */
-  void SetDeviceParameter (std::string n1, Attribute v1);
+  void SetDeviceParameter (std::string n1, const AttributeValue &v1);
 
   /**
    * \param n1 the name of the attribute to set
@@ -77,7 +77,7 @@
    * Set these parameters on each ns3::CsmaChannel created
    * by CsmaHelper::Install
    */
-  void SetChannelParameter (std::string n1, Attribute v1);
+  void SetChannelParameter (std::string n1, const AttributeValue &v1);
 
   /**
    * \param filename filename prefix to use for pcap files.
--- a/src/helper/ipv4-address-helper.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/ipv4-address-helper.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -31,7 +31,7 @@
 
 Ipv4AddressHelper::Ipv4AddressHelper () 
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
 //
 // Set the default values to an illegal state.  Do this so the client is 
@@ -52,7 +52,7 @@
   const Ipv4Mask mask,
   const Ipv4Address address)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   m_network = network.GetHostOrder ();
   m_mask = mask.GetHostOrder ();
@@ -114,7 +114,7 @@
   Ipv4Address
 Ipv4AddressHelper::NewNetwork (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   ++m_network;
   m_address = m_base;
   return Ipv4Address (m_network << m_shift);
@@ -123,7 +123,7 @@
 Ipv4InterfaceContainer
 Ipv4AddressHelper::Assign (const NetDeviceContainer &c)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Ipv4InterfaceContainer retval;
   for (uint32_t i = 0; i < c.GetN (); ++i) {
     Ptr<NetDevice> device = c.Get (i);
@@ -156,7 +156,7 @@
   uint32_t
 Ipv4AddressHelper::NumAddressBits (uint32_t maskbits) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for (uint32_t i = 0; i < N_BITS; ++i)
     {
       if (maskbits & 1)
--- a/src/helper/mobility-helper.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/mobility-helper.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -23,6 +23,7 @@
 #include "ns3/position-allocator.h"
 #include "ns3/hierarchical-mobility-model.h"
 #include "ns3/log.h"
+#include "ns3/pointer.h"
 
 namespace ns3 {
 
@@ -31,8 +32,9 @@
 MobilityHelper::MobilityHelper ()
   : m_notifierEnabled (false)
 {
-  m_position = CreateObject<RandomRectanglePositionAllocator> ("X", ConstantVariable (0.0),
-								   "Y", ConstantVariable (0.0));
+  m_position = CreateObject<RandomRectanglePositionAllocator> 
+    ("X", RandomVariableValue (ConstantVariable (0.0)),
+     "Y", RandomVariableValue (ConstantVariable (0.0)));
   m_mobility.SetTypeId ("ns3::StaticMobilityModel");
 }
 MobilityHelper::~MobilityHelper ()
@@ -54,15 +56,15 @@
 }
 void 
 MobilityHelper::SetPositionAllocator (std::string type,
-				      std::string n1, Attribute v1,
-				      std::string n2, Attribute v2,
-				      std::string n3, Attribute v3,
-				      std::string n4, Attribute v4,
-				      std::string n5, Attribute v5,
-				      std::string n6, Attribute v6,
-				      std::string n7, Attribute v7,
-				      std::string n8, Attribute v8,
-				      std::string n9, Attribute v9)
+				      std::string n1, const AttributeValue &v1,
+				      std::string n2, const AttributeValue &v2,
+				      std::string n3, const AttributeValue &v3,
+				      std::string n4, const AttributeValue &v4,
+				      std::string n5, const AttributeValue &v5,
+				      std::string n6, const AttributeValue &v6,
+				      std::string n7, const AttributeValue &v7,
+				      std::string n8, const AttributeValue &v8,
+				      std::string n9, const AttributeValue &v9)
 {
   ObjectFactory pos;
   pos.SetTypeId (type);
@@ -80,15 +82,15 @@
 
 void 
 MobilityHelper::SetMobilityModel (std::string type,
-				  std::string n1, Attribute v1,
-				  std::string n2, Attribute v2,
-				  std::string n3, Attribute v3,
-				  std::string n4, Attribute v4,
-				  std::string n5, Attribute v5,
-				  std::string n6, Attribute v6,
-				  std::string n7, Attribute v7,
-				  std::string n8, Attribute v8,
-				  std::string n9, Attribute v9)
+				  std::string n1, const AttributeValue &v1,
+				  std::string n2, const AttributeValue &v2,
+				  std::string n3, const AttributeValue &v3,
+				  std::string n4, const AttributeValue &v4,
+				  std::string n5, const AttributeValue &v5,
+				  std::string n6, const AttributeValue &v6,
+				  std::string n7, const AttributeValue &v7,
+				  std::string n8, const AttributeValue &v8,
+				  std::string n9, const AttributeValue &v9)
 {
   m_mobility.SetTypeId (type);
   m_mobility.Set (n1, v1);
@@ -146,8 +148,8 @@
 	      // we need to setup a hierarchical mobility model
 	      Ptr<MobilityModel> parent = m_mobilityStack.back ();
 	      Ptr<MobilityModel> hierarchical = 
-		CreateObject<HierarchicalMobilityModel> ("Child", model,
-							 "Parent", parent);
+		CreateObject<HierarchicalMobilityModel> ("Child", PointerValue (model),
+							 "Parent", PointerValue (parent));
 	      object->AggregateObject (hierarchical);
 	      NS_LOG_DEBUG ("node="<<object<<", mob="<<hierarchical);
 	    }
--- a/src/helper/mobility-helper.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/mobility-helper.h	Tue Apr 22 21:19:39 2008 -0700
@@ -86,15 +86,15 @@
    * \param v9 the value of the attribute to set in the mobility model.
    */
   void SetPositionAllocator (std::string type,
-			     std::string n1 = "", Attribute v1 = Attribute (),
-			     std::string n2 = "", Attribute v2 = Attribute (),
-			     std::string n3 = "", Attribute v3 = Attribute (),
-			     std::string n4 = "", Attribute v4 = Attribute (),
-			     std::string n5 = "", Attribute v5 = Attribute (),
-			     std::string n6 = "", Attribute v6 = Attribute (),
-			     std::string n7 = "", Attribute v7 = Attribute (),
-			     std::string n8 = "", Attribute v8 = Attribute (),
-			     std::string n9 = "", Attribute v9 = Attribute ());
+			     std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+			     std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+			     std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+			     std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+			     std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+			     std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+			     std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue (),
+			     std::string n8 = "", const AttributeValue &v8 = EmptyAttributeValue (),
+			     std::string n9 = "", const AttributeValue &v9 = EmptyAttributeValue ());
 
   /**
    * \param type the type of mobility model to use.
@@ -121,15 +121,15 @@
    * mobility model for each node.
    */
   void SetMobilityModel (std::string type,
-			 std::string n1 = "", Attribute v1 = Attribute (),
-			 std::string n2 = "", Attribute v2 = Attribute (),
-			 std::string n3 = "", Attribute v3 = Attribute (),
-			 std::string n4 = "", Attribute v4 = Attribute (),
-			 std::string n5 = "", Attribute v5 = Attribute (),
-			 std::string n6 = "", Attribute v6 = Attribute (),
-			 std::string n7 = "", Attribute v7 = Attribute (),
-			 std::string n8 = "", Attribute v8 = Attribute (),
-			 std::string n9 = "", Attribute v9 = Attribute ());
+			 std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+			 std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+			 std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+			 std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+			 std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+			 std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+			 std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue (),
+			 std::string n8 = "", const AttributeValue &v8 = EmptyAttributeValue (),
+			 std::string n9 = "", const AttributeValue &v9 = EmptyAttributeValue ());
 
   /**
    * \param reference item to push.
--- a/src/helper/olsr-helper.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/olsr-helper.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -30,14 +30,14 @@
 
 void 
 OlsrHelper::SetAgent (std::string tid,
-		      std::string n0, Attribute v0,
-		      std::string n1, Attribute v1,
-		      std::string n2, Attribute v2,
-		      std::string n3, Attribute v3,
-		      std::string n4, Attribute v4,
-		      std::string n5, Attribute v5,
-		      std::string n6, Attribute v6,
-		      std::string n7, Attribute v7)
+		      std::string n0, const AttributeValue &v0,
+		      std::string n1, const AttributeValue &v1,
+		      std::string n2, const AttributeValue &v2,
+		      std::string n3, const AttributeValue &v3,
+		      std::string n4, const AttributeValue &v4,
+		      std::string n5, const AttributeValue &v5,
+		      std::string n6, const AttributeValue &v6,
+		      std::string n7, const AttributeValue &v7)
 {
   m_agentFactory.SetTypeId (tid);
   m_agentFactory.Set (n0, v0);
--- a/src/helper/olsr-helper.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/olsr-helper.h	Tue Apr 22 21:19:39 2008 -0700
@@ -32,14 +32,14 @@
   OlsrHelper ();
 
   void SetAgent (std::string tid,
-		 std::string n0 = "", Attribute v0 = Attribute (),
-		 std::string n1 = "", Attribute v2 = Attribute (),
-		 std::string n2 = "", Attribute v2 = Attribute (),
-		 std::string n3 = "", Attribute v3 = Attribute (),
-		 std::string n4 = "", Attribute v4 = Attribute (),
-		 std::string n5 = "", Attribute v5 = Attribute (),
-		 std::string n6 = "", Attribute v6 = Attribute (),
-		 std::string n7 = "", Attribute v7 = Attribute ());
+		 std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+		 std::string n1 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+		 std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+		 std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+		 std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+		 std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+		 std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+		 std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
 
   void Install (NodeContainer container);
   void Install (Ptr<Node> node);
--- a/src/helper/on-off-helper.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/on-off-helper.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -27,12 +27,12 @@
 OnOffHelper::OnOffHelper (std::string protocol, Address address)
 {
   m_factory.SetTypeId ("ns3::OnOffApplication");
-  m_factory.Set ("Protocol", String(protocol));
-  m_factory.Set ("Remote", address);
+  m_factory.Set ("Protocol", StringValue (protocol));
+  m_factory.Set ("Remote", AddressValue (address));
 }
 
 void 
-OnOffHelper::SetAttribute (std::string name, Attribute value)
+OnOffHelper::SetAttribute (std::string name, const AttributeValue &value)
 {
   m_factory.Set (name, value);
 }
--- a/src/helper/on-off-helper.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/on-off-helper.h	Tue Apr 22 21:19:39 2008 -0700
@@ -36,7 +36,7 @@
 public:
   OnOffHelper (std::string protocol, Address address);
 
-  void SetAttribute (std::string name, Attribute value);
+  void SetAttribute (std::string name, const AttributeValue &value);
 
   ApplicationContainer Install (NodeContainer c);
 
--- a/src/helper/packet-sink-helper.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/packet-sink-helper.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -26,12 +26,12 @@
 PacketSinkHelper::PacketSinkHelper (std::string protocol, Address address)
 {
   m_factory.SetTypeId ("ns3::PacketSink");
-  m_factory.Set ("Protocol", String(protocol));
-  m_factory.Set ("Local", address);
+  m_factory.Set ("Protocol", StringValue (protocol));
+  m_factory.Set ("Local", AddressValue (address));
 }
 
 void 
-PacketSinkHelper::SetAttribute (std::string name, Attribute value)
+PacketSinkHelper::SetAttribute (std::string name, const AttributeValue &value)
 {
   m_factory.Set (name, value);
 }
--- a/src/helper/packet-sink-helper.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/packet-sink-helper.h	Tue Apr 22 21:19:39 2008 -0700
@@ -32,7 +32,7 @@
 public:
   PacketSinkHelper (std::string protocol, Address address);
 
-  void SetAttribute (std::string name, Attribute value);
+  void SetAttribute (std::string name, const AttributeValue &value);
 
   ApplicationContainer Install (NodeContainer c);
 private:
--- a/src/helper/point-to-point-helper.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/point-to-point-helper.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -39,10 +39,10 @@
 
 void 
 PointToPointHelper::SetQueue (std::string type,
-			      std::string n1, Attribute v1,
-			      std::string n2, Attribute v2,
-			      std::string n3, Attribute v3,
-			      std::string n4, Attribute v4)
+			      std::string n1, const AttributeValue &v1,
+			      std::string n2, const AttributeValue &v2,
+			      std::string n3, const AttributeValue &v3,
+			      std::string n4, const AttributeValue &v4)
 {
   m_queueFactory.SetTypeId (type);
   m_queueFactory.Set (n1, v1);
@@ -52,13 +52,13 @@
 }
 
 void 
-PointToPointHelper::SetDeviceParameter (std::string n1, Attribute v1)
+PointToPointHelper::SetDeviceParameter (std::string n1, const AttributeValue &v1)
 {
   m_deviceFactory.Set (n1, v1);
 }
 
 void 
-PointToPointHelper::SetChannelParameter (std::string n1, Attribute v1)
+PointToPointHelper::SetChannelParameter (std::string n1, const AttributeValue &v1)
 {
   m_channelFactory.Set (n1, v1);
 }
--- a/src/helper/point-to-point-helper.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/point-to-point-helper.h	Tue Apr 22 21:19:39 2008 -0700
@@ -56,10 +56,10 @@
    * PointToPointNetDevice created through PointToPointHelper::Install.
    */
   void SetQueue (std::string type,
-		 std::string n1 = "", Attribute v1 = Attribute (),
-		 std::string n2 = "", Attribute v2 = Attribute (),
-		 std::string n3 = "", Attribute v3 = Attribute (),
-		 std::string n4 = "", Attribute v4 = Attribute ());
+		 std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+		 std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+		 std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+		 std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue ());
 
   /**
    * \param name the name of the attribute to set
@@ -68,7 +68,7 @@
    * Set these parameters on each ns3::PointToPointNetDevice created
    * by PointToPointHelper::Install
    */
-  void SetDeviceParameter (std::string name, Attribute value);
+  void SetDeviceParameter (std::string name, const AttributeValue &value);
   /**
    * \param name the name of the attribute to set
    * \param value the value of the attribute to set
@@ -76,7 +76,7 @@
    * Set these parameters on each ns3::PointToPointChannel created
    * by PointToPointHelper::Install
    */
-  void SetChannelParameter (std::string name, Attribute value);
+  void SetChannelParameter (std::string name, const AttributeValue &value);
 
   /**
    * \param filename filename prefix to use for pcap files.
--- a/src/helper/udp-echo-helper.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/udp-echo-helper.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -40,7 +40,7 @@
   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
     {
       Ptr<Node> node = *i;
-      Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> ("Port", Uinteger (m_port));
+      Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> ("Port", UintegerValue (m_port));
       node->AddApplication (server);
       apps.Add (server);
     }
@@ -58,7 +58,7 @@
   m_remotePort = port;
 }
 void 
-UdpEchoClientHelper::SetAppAttribute (std::string name, Attribute value)
+UdpEchoClientHelper::SetAppAttribute (std::string name, const AttributeValue &value)
 {
   m_factory.Set (name, value);
 }
--- a/src/helper/udp-echo-helper.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/udp-echo-helper.h	Tue Apr 22 21:19:39 2008 -0700
@@ -44,7 +44,7 @@
   UdpEchoClientHelper ();
 
   void SetRemote (Ipv4Address ip, uint16_t port);
-  void SetAppAttribute (std::string name, Attribute value);
+  void SetAppAttribute (std::string name, const AttributeValue &value);
   ApplicationContainer Install (NodeContainer c);
  private:
   ObjectFactory m_factory;
--- a/src/helper/wifi-helper.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/wifi-helper.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -78,14 +78,14 @@
 
 void 
 WifiHelper::SetRemoteStationManager (std::string type,
-				     std::string n0, Attribute v0,
-				     std::string n1, Attribute v1,
-				     std::string n2, Attribute v2,
-				     std::string n3, Attribute v3,
-				     std::string n4, Attribute v4,
-				     std::string n5, Attribute v5,
-				     std::string n6, Attribute v6,
-				     std::string n7, Attribute v7)
+				     std::string n0, const AttributeValue &v0,
+				     std::string n1, const AttributeValue &v1,
+				     std::string n2, const AttributeValue &v2,
+				     std::string n3, const AttributeValue &v3,
+				     std::string n4, const AttributeValue &v4,
+				     std::string n5, const AttributeValue &v5,
+				     std::string n6, const AttributeValue &v6,
+				     std::string n7, const AttributeValue &v7)
 {
   m_stationManager = ObjectFactory ();
   m_stationManager.SetTypeId (type);
@@ -101,14 +101,14 @@
 
 void 
 WifiHelper::SetMac (std::string type,
-		    std::string n0, Attribute v0,
-		    std::string n1, Attribute v1,
-		    std::string n2, Attribute v2,
-		    std::string n3, Attribute v3,
-		    std::string n4, Attribute v4,
-		    std::string n5, Attribute v5,
-		    std::string n6, Attribute v6,
-		    std::string n7, Attribute v7)
+		    std::string n0, const AttributeValue &v0,
+		    std::string n1, const AttributeValue &v1,
+		    std::string n2, const AttributeValue &v2,
+		    std::string n3, const AttributeValue &v3,
+		    std::string n4, const AttributeValue &v4,
+		    std::string n5, const AttributeValue &v5,
+		    std::string n6, const AttributeValue &v6,
+		    std::string n7, const AttributeValue &v7)
 {
   m_mac = ObjectFactory ();
   m_mac.SetTypeId (type);
@@ -124,14 +124,14 @@
 
 void 
 WifiHelper::SetPhy (std::string type,
-		    std::string n0, Attribute v0,
-		    std::string n1, Attribute v1,
-		    std::string n2, Attribute v2,
-		    std::string n3, Attribute v3,
-		    std::string n4, Attribute v4,
-		    std::string n5, Attribute v5,
-		    std::string n6, Attribute v6,
-		    std::string n7, Attribute v7)
+		    std::string n0, const AttributeValue &v0,
+		    std::string n1, const AttributeValue &v1,
+		    std::string n2, const AttributeValue &v2,
+		    std::string n3, const AttributeValue &v3,
+		    std::string n4, const AttributeValue &v4,
+		    std::string n5, const AttributeValue &v5,
+		    std::string n6, const AttributeValue &v6,
+		    std::string n7, const AttributeValue &v7)
 {
   m_phy = ObjectFactory ();
   m_phy.SetTypeId (type);
--- a/src/helper/wifi-helper.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/helper/wifi-helper.h	Tue Apr 22 21:19:39 2008 -0700
@@ -65,14 +65,14 @@
    * in the requested station manager.
    */
   void SetRemoteStationManager (std::string type,
-				std::string n0 = "", Attribute v0 = Attribute (),
-				std::string n1 = "", Attribute v1 = Attribute (),
-				std::string n2 = "", Attribute v2 = Attribute (),
-				std::string n3 = "", Attribute v3 = Attribute (),
-				std::string n4 = "", Attribute v4 = Attribute (),
-				std::string n5 = "", Attribute v5 = Attribute (),
-				std::string n6 = "", Attribute v6 = Attribute (),
-				std::string n7 = "", Attribute v7 = Attribute ());
+				std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+				std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+				std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+				std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+				std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+				std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+				std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+				std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
 
   /**
    * \param type the type of ns3::WifiMac to create.
@@ -97,14 +97,14 @@
    * in the requested mac.
    */
   void SetMac (std::string type,
-	       std::string n0 = "", Attribute v0 = Attribute (),
-	       std::string n1 = "", Attribute v1 = Attribute (),
-	       std::string n2 = "", Attribute v2 = Attribute (),
-	       std::string n3 = "", Attribute v3 = Attribute (),
-	       std::string n4 = "", Attribute v4 = Attribute (),
-	       std::string n5 = "", Attribute v5 = Attribute (),
-	       std::string n6 = "", Attribute v6 = Attribute (),
-	       std::string n7 = "", Attribute v7 = Attribute ());
+	       std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+	       std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+	       std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+	       std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+	       std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+	       std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+	       std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+	       std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
 
   /**
    * \param phyType the type of ns3::WifiPhy to create.
@@ -129,14 +129,14 @@
    * in the requested phy.
    */
   void SetPhy (std::string phyType,
-	       std::string n0 = "", Attribute v0 = Attribute (),
-	       std::string n1 = "", Attribute v1 = Attribute (),
-	       std::string n2 = "", Attribute v2 = Attribute (),
-	       std::string n3 = "", Attribute v3 = Attribute (),
-	       std::string n4 = "", Attribute v4 = Attribute (),
-	       std::string n5 = "", Attribute v5 = Attribute (),
-	       std::string n6 = "", Attribute v6 = Attribute (),
-	       std::string n7 = "", Attribute v7 = Attribute ());
+	       std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+	       std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+	       std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+	       std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+	       std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+	       std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+	       std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+	       std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
 
 
 
--- a/src/internet-node/arp-ipv4-interface.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/arp-ipv4-interface.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -35,12 +35,12 @@
 
 ArpIpv4Interface::ArpIpv4Interface ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 ArpIpv4Interface::~ArpIpv4Interface ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 void 
@@ -70,8 +70,7 @@
 void 
 ArpIpv4Interface::SendTo (Ptr<Packet> p, Ipv4Address dest)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << p << dest);
+  NS_LOG_FUNCTION (this << p << dest);
 
   NS_ASSERT (GetDevice () != 0);
   if (GetDevice ()->NeedsArp ())
--- a/src/internet-node/arp-l3-protocol.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/arp-l3-protocol.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -47,12 +47,12 @@
 
 ArpL3Protocol::ArpL3Protocol ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 ArpL3Protocol::~ArpL3Protocol ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 void 
@@ -64,7 +64,7 @@
 void 
 ArpL3Protocol::DoDispose (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++)
     {
       delete *i;
@@ -77,7 +77,7 @@
 ArpCache *
 ArpL3Protocol::FindCache (Ptr<NetDevice> device)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++)
     {
       if ((*i)->GetDevice () == device)
@@ -97,7 +97,7 @@
 void 
 ArpL3Protocol::Receive(Ptr<NetDevice> device, Ptr<Packet> packet, uint16_t protocol, const Address &from)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   ArpCache *cache = FindCache (device);
   ArpHeader arp;
   packet->RemoveHeader (arp);
@@ -108,6 +108,11 @@
             arp.GetDestinationIpv4Address () << "; we have address " <<
             cache->GetInterface ()->GetAddress ());
 
+  /**
+   * Note: we do not update the ARP cache when we receive an ARP request
+   * from an unknown node. See bug #107
+   */
+
   if (arp.IsRequest () && 
       arp.GetDestinationIpv4Address () == cache->GetInterface ()->GetAddress ()) 
     {
@@ -161,7 +166,7 @@
                        Ptr<NetDevice> device,
                        Address *hardwareDestination)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   ArpCache *cache = FindCache (device);
   ArpCache::Entry *entry = cache->Lookup (destination);
   if (entry != 0)
@@ -230,7 +235,7 @@
 void
 ArpL3Protocol::SendArpRequest (ArpCache const *cache, Ipv4Address to)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   ArpHeader arp;
   NS_LOG_LOGIC ("ARP: sending request from node "<<m_node->GetId ()<<
             " || src: " << cache->GetDevice ()->GetAddress () <<
@@ -249,7 +254,7 @@
 void
 ArpL3Protocol::SendArpReply (ArpCache const *cache, Ipv4Address toIp, Address toMac)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   ArpHeader arp;
   NS_LOG_LOGIC ("ARP: sending reply from node "<<m_node->GetId ()<<
             "|| src: " << cache->GetDevice ()->GetAddress () << 
--- a/src/internet-node/ipv4-end-point-demux.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/ipv4-end-point-demux.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -29,12 +29,12 @@
 Ipv4EndPointDemux::Ipv4EndPointDemux ()
   : m_ephemeral (49152)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 Ipv4EndPointDemux::~Ipv4EndPointDemux ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
     {
       Ipv4EndPoint *endPoint = *i;
@@ -46,7 +46,7 @@
 bool
 Ipv4EndPointDemux::LookupPortLocal (uint16_t port)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
     {
       if ((*i)->GetLocalPort  () == port) 
@@ -60,7 +60,7 @@
 bool
 Ipv4EndPointDemux::LookupLocal (Ipv4Address addr, uint16_t port)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
     {
       if ((*i)->GetLocalPort () == port &&
@@ -75,7 +75,7 @@
 Ipv4EndPoint *
 Ipv4EndPointDemux::Allocate (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   uint16_t port = AllocateEphemeralPort ();
   if (port == 0) 
     {
@@ -91,8 +91,7 @@
 Ipv4EndPoint *
 Ipv4EndPointDemux::Allocate (Ipv4Address address)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << address);
+  NS_LOG_FUNCTION (this << address);
   uint16_t port = AllocateEphemeralPort ();
   if (port == 0) 
     {
@@ -108,8 +107,7 @@
 Ipv4EndPoint *
 Ipv4EndPointDemux::Allocate (uint16_t port)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this <<  port);
+  NS_LOG_FUNCTION (this <<  port);
 
   return Allocate (Ipv4Address::GetAny (), port);
 }
@@ -117,8 +115,7 @@
 Ipv4EndPoint *
 Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << address << port);
+  NS_LOG_FUNCTION (this << address << port);
   if (LookupLocal (address, port)) 
     {
       NS_LOG_WARN ("Duplicate address/port; failing.");
@@ -134,8 +131,7 @@
 Ipv4EndPointDemux::Allocate (Ipv4Address localAddress, uint16_t localPort,
 			     Ipv4Address peerAddress, uint16_t peerPort)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << localAddress << localPort << peerAddress << peerPort);
+  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
   for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
     {
       if ((*i)->GetLocalPort () == localPort &&
@@ -160,7 +156,7 @@
 void 
 Ipv4EndPointDemux::DeAllocate (Ipv4EndPoint *endPoint)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
     {
       if (*i == endPoint)
@@ -182,21 +178,13 @@
                            Ipv4Address saddr, uint16_t sport,
                            Ptr<Ipv4Interface> incomingInterface)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   EndPoints retval1; // Matches exact on local port, wildcards on others
   EndPoints retval2; // Matches exact on local port/adder, wildcards on others
   EndPoints retval3; // Matches all but local address
   EndPoints retval4; // Exact match on all 4
   
-  //NS_LOG_PARAMS (this << daddr << dport << saddr << sport);
-  NS_LOG_PARAMS_BEGIN ();
-  NS_LOG_PARAM (this);
-  NS_LOG_PARAM (daddr);
-  NS_LOG_PARAM (dport);
-  NS_LOG_PARAM (saddr);
-  NS_LOG_PARAM (sport);
-  NS_LOG_PARAM (incomingInterface);
-  NS_LOG_PARAMS_END ();
+  NS_LOG_FUNCTION (this << daddr << dport << saddr << sport << incomingInterface);
   NS_LOG_DEBUG ("Looking up endpoint for destination address " << daddr);
   for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
     {
@@ -284,7 +272,7 @@
 uint16_t
 Ipv4EndPointDemux::AllocateEphemeralPort (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   uint16_t port = m_ephemeral;
   do 
     {
--- a/src/internet-node/ipv4-interface.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/ipv4-interface.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -28,6 +28,15 @@
 
 namespace ns3 {
 
+TypeId 
+Ipv4Interface::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Ipv4Interface")
+    .SetParent<Object> ()
+    ;
+  return tid;
+}
+
   /**
    * By default, Ipv4 interface are created in the "down" state
    * with ip address 192.168.0.1 and a matching mask. Before
@@ -38,42 +47,39 @@
   : m_ifup(false),
     m_metric(1)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this);
+  NS_LOG_FUNCTION (this);
 }
 
 Ipv4Interface::~Ipv4Interface ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 void
 Ipv4Interface::DoDispose (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Object::DoDispose ();
 }
 
 void 
 Ipv4Interface::SetAddress (Ipv4Address a)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << a);
+  NS_LOG_FUNCTION (this << a);
   m_address = a;
 }
 
 void 
 Ipv4Interface::SetNetworkMask (Ipv4Mask mask)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << mask);
+  NS_LOG_FUNCTION (this << mask);
   m_netmask = mask;
 }
 
 Ipv4Address
 Ipv4Interface::GetBroadcast (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   uint32_t mask = m_netmask.GetHostOrder ();
   uint32_t address = m_address.GetHostOrder ();
   Ipv4Address broadcast = Ipv4Address (address | (~mask));
@@ -83,36 +89,35 @@
 Ipv4Mask 
 Ipv4Interface::GetNetworkMask (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_netmask;
 }
 
 void
 Ipv4Interface::SetMetric (uint16_t metric)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS ("(" << metric << ")");
+  NS_LOG_FUNCTION (metric);
   m_metric = metric;
 }
 
 uint16_t
 Ipv4Interface::GetMetric (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_metric;
 }
 
 Ipv4Address 
 Ipv4Interface::GetAddress (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_address;
 }
 
 uint16_t 
 Ipv4Interface::GetMtu (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (GetDevice () == 0)
     {
       uint32_t mtu = (1<<16) - 1;
@@ -129,28 +134,28 @@
 bool 
 Ipv4Interface::IsUp (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_ifup;
 }
 
 bool 
 Ipv4Interface::IsDown (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return !m_ifup;
 }
 
 void 
 Ipv4Interface::SetUp (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_ifup = true;
 }
 
 void 
 Ipv4Interface::SetDown (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_ifup = false;
 }
 
@@ -158,7 +163,7 @@
 void 
 Ipv4Interface::Send(Ptr<Packet> p, Ipv4Address dest)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (IsUp()) {
     NS_LOG_LOGIC ("SendTo");
     SendTo(p, dest);
--- a/src/internet-node/ipv4-interface.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/ipv4-interface.h	Tue Apr 22 21:19:39 2008 -0700
@@ -63,6 +63,8 @@
 class Ipv4Interface  : public Object
 {
 public:
+  static TypeId GetTypeId (void);
+
   Ipv4Interface ();
   virtual ~Ipv4Interface();
 
--- a/src/internet-node/ipv4-l3-protocol.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/ipv4-l3-protocol.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -52,7 +52,7 @@
     .SetParent<Object> ()
     .AddConstructor<Ipv4L3Protocol> ()
     .AddAttribute ("DefaultTtl", "The TTL value set by default on all outgoing packets generated on this node.",
-                   Uinteger (64),
+                   UintegerValue (64),
                    MakeUintegerAccessor (&Ipv4L3Protocol::m_defaultTtl),
                    MakeUintegerChecker<uint8_t> ())
     .AddTraceSource ("Tx", "Send ipv4 packet to outgoing interface.",
@@ -62,9 +62,9 @@
     .AddTraceSource ("Drop", "Drop ipv4 packet",
                      MakeTraceSourceAccessor (&Ipv4L3Protocol::m_dropTrace))
     .AddAttribute ("InterfaceList", "The set of Ipv4 interfaces associated to this Ipv4 stack.",
-                   ObjectVector (),
+                   ObjectVectorValue (),
                    MakeObjectVectorAccessor (&Ipv4L3Protocol::m_interfaces),
-                   MakeObjectVectorChecker ())
+                   MakeObjectVectorChecker<Ipv4Interface> ())
     ;
   return tid;
 }
@@ -73,14 +73,14 @@
   : m_nInterfaces (0),
     m_identification (0)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_staticRouting = CreateObject<Ipv4StaticRouting> ();
   AddRoutingProtocol (m_staticRouting, 0);
 }
 
 Ipv4L3Protocol::~Ipv4L3Protocol ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 void
@@ -93,7 +93,7 @@
 void 
 Ipv4L3Protocol::DoDispose (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_interfaces.clear ();
   m_node = 0;
   m_staticRouting->Dispose ();
@@ -104,7 +104,7 @@
 void
 Ipv4L3Protocol::SetupLoopback (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   Ptr<Ipv4LoopbackInterface> interface = CreateObject<Ipv4LoopbackInterface> ();
   interface->SetNode (m_node);
@@ -118,7 +118,7 @@
 void 
 Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_defaultTtl = ttl;
 }
     
@@ -128,8 +128,7 @@
                       Ipv4Address nextHop, 
                       uint32_t interface)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << dest << nextHop << interface);
+  NS_LOG_FUNCTION (this << dest << nextHop << interface);
   m_staticRouting->AddHostRouteTo (dest, nextHop, interface);
 }
 
@@ -137,8 +136,7 @@
 Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, 
 				uint32_t interface)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << dest << interface);
+  NS_LOG_FUNCTION (this << dest << interface);
   m_staticRouting->AddHostRouteTo (dest, interface);
 }
 
@@ -148,8 +146,7 @@
 				   Ipv4Address nextHop, 
 				   uint32_t interface)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << network << networkMask << nextHop << interface);
+  NS_LOG_FUNCTION (this << network << networkMask << nextHop << interface);
   m_staticRouting->AddNetworkRouteTo (network, networkMask, nextHop, interface);
 }
 
@@ -158,8 +155,7 @@
 				   Ipv4Mask networkMask, 
 				   uint32_t interface)
 {
-  NS_LOG_FUNCTION; 
-  NS_LOG_PARAMS (this << network << networkMask << interface);
+  NS_LOG_FUNCTION (this << network << networkMask << interface);
   m_staticRouting->AddNetworkRouteTo (network, networkMask, interface);
 }
 
@@ -167,8 +163,7 @@
 Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop, 
 				 uint32_t interface)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << nextHop << interface);
+  NS_LOG_FUNCTION (this << nextHop << interface);
   m_staticRouting->SetDefaultRoute (nextHop, interface);
 }
 
@@ -178,8 +173,7 @@
   Ptr<Packet> packet,
   Ipv4RoutingProtocol::RouteReplyCallback routeReply)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << &ipHeader << packet << &routeReply);
+  NS_LOG_FUNCTION (this << &ipHeader << packet << &routeReply);
 
   Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
 }
@@ -191,8 +185,7 @@
   Ptr<Packet> packet,
   Ipv4RoutingProtocol::RouteReplyCallback routeReply)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << ifIndex << &ipHeader << packet << &routeReply);
+  NS_LOG_FUNCTION (this << ifIndex << &ipHeader << packet << &routeReply);
 
   for (Ipv4RoutingProtocolList::const_iterator rprotoIter = 
          m_routingProtocols.begin ();
@@ -240,8 +233,7 @@
 Ipv4L3Protocol::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
                                     int priority)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << &routingProtocol << priority);
+  NS_LOG_FUNCTION (this << &routingProtocol << priority);
   m_routingProtocols.push_back
     (std::pair<int, Ptr<Ipv4RoutingProtocol> > (-priority, routingProtocol));
   m_routingProtocols.sort ();
@@ -250,22 +242,21 @@
 uint32_t 
 Ipv4L3Protocol::GetNRoutes (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_staticRouting->GetNRoutes ();
 }
 
 Ipv4Route *
 Ipv4L3Protocol::GetRoute (uint32_t index)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_staticRouting->GetRoute (index);
 }
 
 void 
 Ipv4L3Protocol::RemoveRoute (uint32_t index)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << index);
+  NS_LOG_FUNCTION (this << index);
   m_staticRouting->RemoveRoute (index);
 }
 
@@ -275,8 +266,7 @@
                                    uint32_t inputInterface,
                                    std::vector<uint32_t> outputInterfaces)
 {
-  NS_LOG_FUNCTION; 
-  NS_LOG_PARAMS (this << origin << group << inputInterface << &outputInterfaces);
+  NS_LOG_FUNCTION (this << origin << group << inputInterface << &outputInterfaces);
 
   m_staticRouting->AddMulticastRoute (origin, group, inputInterface,
     outputInterfaces);
@@ -285,8 +275,7 @@
 void 
 Ipv4L3Protocol::SetDefaultMulticastRoute (uint32_t outputInterface)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << outputInterface);
+  NS_LOG_FUNCTION (this << outputInterface);
 
   m_staticRouting->SetDefaultMulticastRoute (outputInterface);
 }
@@ -294,15 +283,14 @@
 uint32_t 
 Ipv4L3Protocol::GetNMulticastRoutes (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_staticRouting->GetNMulticastRoutes ();
 }
 
 Ipv4MulticastRoute *
 Ipv4L3Protocol::GetMulticastRoute (uint32_t index) const
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << index);
+  NS_LOG_FUNCTION (this << index);
   return m_staticRouting->GetMulticastRoute (index);
 }
 
@@ -311,24 +299,21 @@
                                        Ipv4Address group,
                                        uint32_t inputInterface)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << origin << group << inputInterface);
+  NS_LOG_FUNCTION (this << origin << group << inputInterface);
   m_staticRouting->RemoveMulticastRoute (origin, group, inputInterface);
 }
 
 void 
 Ipv4L3Protocol::RemoveMulticastRoute (uint32_t index)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << index);
+  NS_LOG_FUNCTION (this << index);
   m_staticRouting->RemoveMulticastRoute (index);
 }
 
 uint32_t 
 Ipv4L3Protocol::AddInterface (Ptr<NetDevice> device)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << &device);
+  NS_LOG_FUNCTION (this << &device);
   Ptr<ArpIpv4Interface> interface = CreateObject<ArpIpv4Interface> ();
   interface->SetNode (m_node);
   interface->SetDevice (device);
@@ -338,8 +323,7 @@
 uint32_t 
 Ipv4L3Protocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << interface);
+  NS_LOG_FUNCTION (this << interface);
   uint32_t index = m_nInterfaces;
   m_interfaces.push_back (interface);
   m_nInterfaces++;
@@ -349,8 +333,7 @@
 Ptr<Ipv4Interface>
 Ipv4L3Protocol::GetInterface (uint32_t index) const
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << index);
+  NS_LOG_FUNCTION (this << index);
   uint32_t tmp = 0;
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
     {
@@ -366,15 +349,14 @@
 uint32_t 
 Ipv4L3Protocol::GetNInterfaces (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_nInterfaces;
 }
 
 uint32_t 
 Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr) const
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << addr);
+  NS_LOG_FUNCTION (this << addr);
 
   uint32_t ifIndex = 0;
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
@@ -395,8 +377,7 @@
 uint32_t 
 Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << addr << mask);
+  NS_LOG_FUNCTION (this << addr << mask);
 
   uint32_t ifIndex = 0;
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
@@ -417,8 +398,7 @@
 int32_t 
 Ipv4L3Protocol::FindInterfaceIndexForDevice (Ptr<NetDevice> device) const
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << device);
+  NS_LOG_FUNCTION (this << device);
 
   uint32_t ifIndex = 0;
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
@@ -437,8 +417,7 @@
 Ptr<Ipv4Interface>
 Ipv4L3Protocol::FindInterfaceForDevice (Ptr<const NetDevice> device)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << &device);
+  NS_LOG_FUNCTION (this << &device);
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
     {
       if ((*i)->GetDevice () == device)
@@ -452,8 +431,7 @@
 void 
 Ipv4L3Protocol::Receive( Ptr<NetDevice> device, Ptr<Packet> packet, uint16_t protocol, const Address &from)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << &device << packet << protocol <<  from);
+  NS_LOG_FUNCTION (this << &device << packet << protocol <<  from);
 
   NS_LOG_LOGIC ("Packet from " << from << " received on node " << m_node->GetId ());
 
@@ -494,8 +472,7 @@
             Ipv4Address destination,
             uint8_t protocol)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << packet << source << destination << protocol);
+  NS_LOG_FUNCTION (this << packet << source << destination << protocol);
 
   Ipv4Header ipHeader;
 
@@ -545,8 +522,7 @@
                              Ptr<Packet> packet,
                              Ipv4Header const &ipHeader)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << found << &route << packet << &ipHeader);
+  NS_LOG_FUNCTION (this << found << &route << packet << &ipHeader);
 
   packet->AddHeader (ipHeader);
   if (!found)
@@ -580,8 +556,7 @@
   Ipv4Header &ipHeader, 
   Ptr<NetDevice> device)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (ifIndex << packet << &ipHeader<< device);
+  NS_LOG_FUNCTION (ifIndex << packet << &ipHeader<< device);
   NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
 
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
@@ -661,8 +636,7 @@
 Ipv4L3Protocol::ForwardUp (Ptr<Packet> p, Ipv4Header const&ip,
                            Ptr<Ipv4Interface> incomingInterface)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << p << &ip);
+  NS_LOG_FUNCTION (this << p << &ip);
 
   Ptr<Ipv4L4Demux> demux = m_node->GetObject<Ipv4L4Demux> ();
   Ptr<Ipv4L4Protocol> protocol = demux->GetProtocol (ip.GetProtocol ());
@@ -672,8 +646,7 @@
 void 
 Ipv4L3Protocol::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << origin << group);
+  NS_LOG_FUNCTION (this << origin << group);
   m_multicastGroups.push_back(
     std::pair<Ipv4Address, Ipv4Address> (origin, group));
 }
@@ -681,8 +654,7 @@
 void
 Ipv4L3Protocol::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << origin << group);
+  NS_LOG_FUNCTION (this << origin << group);
 
   for (Ipv4MulticastGroupList::iterator i = m_multicastGroups.begin ();
        i != m_multicastGroups.end (); 
@@ -699,8 +671,7 @@
 void 
 Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << i << address);
+  NS_LOG_FUNCTION (this << i << address);
   Ptr<Ipv4Interface> interface = GetInterface (i);
   interface->SetAddress (address);
 }
@@ -708,8 +679,7 @@
 void 
 Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << i << mask);
+  NS_LOG_FUNCTION (this << i << mask);
   Ptr<Ipv4Interface> interface = GetInterface (i);
   interface->SetNetworkMask (mask);
 }
@@ -717,8 +687,7 @@
 Ipv4Mask 
 Ipv4L3Protocol::GetNetworkMask (uint32_t i) const
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << i);
+  NS_LOG_FUNCTION (this << i);
   Ptr<Ipv4Interface> interface = GetInterface (i);
   return interface->GetNetworkMask ();
 }
@@ -726,8 +695,7 @@
 Ipv4Address 
 Ipv4L3Protocol::GetAddress (uint32_t i) const
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << i);
+  NS_LOG_FUNCTION (this << i);
   Ptr<Ipv4Interface> interface = GetInterface (i);
   return interface->GetAddress ();
 }
@@ -735,8 +703,7 @@
 void 
 Ipv4L3Protocol::SetMetric (uint32_t i, uint16_t metric)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS ("(" << i << ", " << metric << ")");
+  NS_LOG_FUNCTION (i << metric);
   Ptr<Ipv4Interface> interface = GetInterface (i);
   interface->SetMetric (metric);
 }
@@ -744,8 +711,7 @@
 uint16_t
 Ipv4L3Protocol::GetMetric (uint32_t i) const
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS ("(" << i << ")");
+  NS_LOG_FUNCTION (i);
   Ptr<Ipv4Interface> interface = GetInterface (i);
   return interface->GetMetric ();
 }
@@ -754,8 +720,7 @@
 Ipv4L3Protocol::GetIfIndexForDestination (
   Ipv4Address destination, uint32_t& ifIndex) const
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << destination << &ifIndex);
+  NS_LOG_FUNCTION (this << destination << &ifIndex);
 //
 // The first thing we do in trying to determine a source address is to 
 // consult the routing protocols.  These will also check for a default route
@@ -824,8 +789,7 @@
 uint16_t 
 Ipv4L3Protocol::GetMtu (uint32_t i) const
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << i);
+  NS_LOG_FUNCTION (this << i);
   Ptr<Ipv4Interface> interface = GetInterface (i);
   return interface->GetMtu ();
 }
@@ -833,8 +797,7 @@
 bool 
 Ipv4L3Protocol::IsUp (uint32_t i) const
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << i);
+  NS_LOG_FUNCTION (this << i);
   Ptr<Ipv4Interface> interface = GetInterface (i);
   return interface->IsUp ();
 }
@@ -842,8 +805,7 @@
 void 
 Ipv4L3Protocol::SetUp (uint32_t i)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << i);
+  NS_LOG_FUNCTION (this << i);
   Ptr<Ipv4Interface> interface = GetInterface (i);
   interface->SetUp ();
 
@@ -861,8 +823,7 @@
 void 
 Ipv4L3Protocol::SetDown (uint32_t ifaceIndex)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << ifaceIndex);
+  NS_LOG_FUNCTION (this << ifaceIndex);
   Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
   interface->SetDown ();
 
--- a/src/internet-node/ipv4-l3-protocol.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/ipv4-l3-protocol.h	Tue Apr 22 21:19:39 2008 -0700
@@ -41,6 +41,9 @@
 class Node;
 
 
+/**
+ * \brief Implement the Ipv4 layer.
+ */
 class Ipv4L3Protocol : public Object
 {
 public:
--- a/src/internet-node/ipv4-l4-demux.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/ipv4-l4-demux.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -37,9 +37,9 @@
   static TypeId tid = TypeId ("ns3::Ipv4L4Demux")
     .SetParent<Object> ()
     .AddAttribute ("Protocols", "The set of protocols registered with this demux.",
-                   ObjectVector (),
+                   ObjectVectorValue (),
                    MakeObjectVectorAccessor (&Ipv4L4Demux::m_protocols),
-                   MakeObjectVectorChecker ())
+                   MakeObjectVectorChecker<Ipv4L4Protocol> ())
     ;
   return tid;
 }
--- a/src/internet-node/ipv4-l4-protocol.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/ipv4-l4-protocol.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -34,11 +34,11 @@
   static TypeId tid = TypeId ("ns3::Ipv4L4Protocol")
     .SetParent<Object> ()
     .AddAttribute ("ProtocolNumber", "The Ipv4 protocol number.",
-                   Uinteger (0),
+                   UintegerValue (0),
                    MakeUintegerAccessor (&Ipv4L4Protocol::GetProtocolNumber),
                    MakeUintegerChecker<int> ())
     .AddAttribute ("Version", "The version of the protocol.",
-                   Uinteger (0),
+                   UintegerValue (0),
                    MakeUintegerAccessor (&Ipv4L4Protocol::GetVersion),
                    MakeUintegerChecker<int> ())
     ;
--- a/src/internet-node/ipv4-loopback-interface.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/ipv4-loopback-interface.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -34,12 +34,12 @@
 Ipv4LoopbackInterface::Ipv4LoopbackInterface ()
   : m_node (0)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 Ipv4LoopbackInterface::~Ipv4LoopbackInterface ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_ASSERT (m_node != 0);
 }
 
@@ -58,8 +58,7 @@
 void 
 Ipv4LoopbackInterface::SendTo (Ptr<Packet> packet, Ipv4Address dest)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << packet << dest);
+  NS_LOG_FUNCTION (this << packet << dest);
 
   Ptr<Ipv4L3Protocol> ipv4 = 
     m_node->GetObject<Ipv4L3Protocol> ();
--- a/src/internet-node/ipv4-static-routing.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/ipv4-static-routing.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -29,7 +29,7 @@
 Ipv4StaticRouting::Ipv4StaticRouting () 
 : m_defaultRoute (0), m_defaultMulticastRoute (0)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 void 
@@ -37,7 +37,7 @@
                                    Ipv4Address nextHop, 
                                    uint32_t interface)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Ipv4Route *route = new Ipv4Route ();
   *route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface);
   m_hostRoutes.push_back (route);
@@ -47,7 +47,7 @@
 Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, 
                                    uint32_t interface)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Ipv4Route *route = new Ipv4Route ();
   *route = Ipv4Route::CreateHostRouteTo (dest, interface);
   m_hostRoutes.push_back (route);
@@ -59,7 +59,7 @@
                                       Ipv4Address nextHop, 
                                       uint32_t interface)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Ipv4Route *route = new Ipv4Route ();
   *route = Ipv4Route::CreateNetworkRouteTo (network,
                                             networkMask,
@@ -73,7 +73,7 @@
                                       Ipv4Mask networkMask, 
                                       uint32_t interface)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Ipv4Route *route = new Ipv4Route ();
   *route = Ipv4Route::CreateNetworkRouteTo (network,
                                             networkMask,
@@ -85,7 +85,7 @@
 Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop, 
                                     uint32_t interface)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Ipv4Route *route = new Ipv4Route ();
   *route = Ipv4Route::CreateDefaultRoute (nextHop, interface);
   delete m_defaultRoute;
@@ -98,7 +98,7 @@
                                      uint32_t inputInterface,
                                      std::vector<uint32_t> outputInterfaces)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Ipv4MulticastRoute *route = new Ipv4MulticastRoute ();
   *route = Ipv4MulticastRoute::CreateMulticastRoute (origin, group, 
     inputInterface, outputInterfaces);
@@ -108,7 +108,7 @@
 void 
 Ipv4StaticRouting::SetDefaultMulticastRoute(uint32_t outputInterface)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Ipv4Address origin = Ipv4Address::GetAny ();
   Ipv4Address group = Ipv4Address::GetAny ();
   uint32_t inputInterface = Ipv4RoutingProtocol::IF_INDEX_ANY;
@@ -127,14 +127,14 @@
 uint32_t 
 Ipv4StaticRouting::GetNMulticastRoutes (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_multicastRoutes.size () + m_defaultMulticastRoute ? 1 : 0;
 }
 
 Ipv4MulticastRoute *
 Ipv4StaticRouting::GetMulticastRoute (uint32_t index) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_ASSERT_MSG(index < m_multicastRoutes.size (),
     "Ipv4StaticRouting::GetMulticastRoute ():  Index out of range");
 //
@@ -182,7 +182,7 @@
 Ipv4MulticastRoute *
 Ipv4StaticRouting::GetDefaultMulticastRoute () const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_defaultMulticastRoute != 0)
     {
       return m_defaultMulticastRoute;
@@ -195,7 +195,7 @@
                                         Ipv4Address group,
                                         uint32_t inputInterface)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for (MulticastRoutesI i = m_multicastRoutes.begin (); 
        i != m_multicastRoutes.end (); 
        i++) 
@@ -216,7 +216,7 @@
 void 
 Ipv4StaticRouting::RemoveMulticastRoute(uint32_t index)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 //
 // From an external point of view the default route appears to be in slot 0
 // of the routing table.  The implementation, however, puts it in a separate 
@@ -261,7 +261,7 @@
 Ipv4Route *
 Ipv4StaticRouting::LookupStatic (Ipv4Address dest)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for (HostRoutesCI i = m_hostRoutes.begin (); 
        i != m_hostRoutes.end (); 
        i++) 
@@ -298,7 +298,7 @@
   Ipv4Address group,
   uint32_t    ifIndex)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 //
 // We treat the "any" address (typically 0.0.0.0) as a wildcard in our matching
 // scheme.
@@ -400,7 +400,7 @@
 uint32_t 
 Ipv4StaticRouting::GetNRoutes (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   uint32_t n = 0;
   if (m_defaultRoute != 0)
     {
@@ -414,7 +414,7 @@
 Ipv4Route *
 Ipv4StaticRouting::GetDefaultRoute ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_defaultRoute != 0)
     {
       return m_defaultRoute;
@@ -428,7 +428,7 @@
 Ipv4Route *
 Ipv4StaticRouting::GetRoute (uint32_t index)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (index == 0 && m_defaultRoute != 0)
     {
       return m_defaultRoute;
@@ -470,7 +470,7 @@
 void 
 Ipv4StaticRouting::RemoveRoute (uint32_t index)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (index == 0 && m_defaultRoute != 0)
     {
       delete m_defaultRoute;
@@ -520,8 +520,7 @@
   Ptr<Packet> packet,
   RouteReplyCallback routeReply)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << ifIndex << &ipHeader << packet << &routeReply);
+  NS_LOG_FUNCTION (this << ifIndex << &ipHeader << packet << &routeReply);
 
   NS_LOG_LOGIC ("source = " << ipHeader.GetSource ());
 
@@ -573,8 +572,7 @@
 bool
 Ipv4StaticRouting::RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << destination << &ifIndex);
+  NS_LOG_FUNCTION (this << destination << &ifIndex);
 //
 // First, see if this is a multicast packet we have a route for.  If we
 // have a route, then send the packet down each of the specified interfaces.
@@ -621,7 +619,7 @@
 void
 Ipv4StaticRouting::DoDispose (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for (HostRoutesI i = m_hostRoutes.begin (); 
        i != m_hostRoutes.end (); 
        i = m_hostRoutes.erase (i)) 
--- a/src/internet-node/rtt-estimator.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/rtt-estimator.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -43,12 +43,12 @@
     .SetParent<Object> ()
     .AddAttribute ("MaxMultiplier", 
                    "XXX",
-                   Double (64.0),
+                   DoubleValue (64.0),
                    MakeDoubleAccessor (&RttEstimator::m_maxMultiplier),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("InitialEstimation", 
                    "XXX",
-                   Seconds (1.0),
+                   TimeValue (Seconds (1.0)),
                    MakeTimeAccessor (&RttEstimator::est),
                    MakeTimeChecker ())
     ;
@@ -74,12 +74,9 @@
   //note next=1 everywhere since first segment will have sequence 1
 }
 
-RttEstimator::RttEstimator (Time e) : next (1), history (), est (e),
-    nSamples (0), multiplier (1.0) 
-{ }
-
 RttEstimator::RttEstimator(const RttEstimator& c)
-  : next(c.next), history(c.history), est(c.est), nSamples(c.nSamples),
+  : Object (c), next(c.next), history(c.history), 
+    m_maxMultiplier (c.m_maxMultiplier), est(c.est), nSamples(c.nSamples),
     multiplier(c.multiplier)
 {}
 
@@ -144,6 +141,10 @@
 
 void RttEstimator::IncreaseMultiplier ()
 {
+  double a;
+  a = multiplier * 2.0;
+  double b;
+  b = m_maxMultiplier * 2.0;
   multiplier = std::min (multiplier * 2.0, m_maxMultiplier);
 }
 
@@ -177,7 +178,7 @@
     .AddConstructor<RttMeanDeviation> ()
     .AddAttribute ("Gain",
                    "XXX",
-                   Double (0.1),
+                   DoubleValue (0.1),
                    MakeDoubleAccessor (&RttMeanDeviation::gain),
                    MakeDoubleChecker<double> ())
     ;
@@ -223,7 +224,7 @@
 
 Ptr<RttEstimator> RttMeanDeviation::Copy () const
 {
-  return Create<RttMeanDeviation> (*this);
+  return CopyObject<RttMeanDeviation> (this);
 }
 
 void RttMeanDeviation::Reset ()
--- a/src/internet-node/rtt-estimator.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/rtt-estimator.h	Tue Apr 22 21:19:39 2008 -0700
@@ -51,7 +51,6 @@
   static TypeId GetTypeId (void);
 
   RttEstimator();
-  RttEstimator(Time e);
   RttEstimator(const RttEstimator&); // Copy constructor
   virtual ~RttEstimator();
 
@@ -71,7 +70,6 @@
   SequenceNumber        next;    // Next expected sequence to be sent
   RttHistory_t history; // List of sent packet
   double m_maxMultiplier;
-  Time m_initialEstimate;
 public:
   Time       est;     // Current estimate
   uint32_t      nSamples;// Number of samples
--- a/src/internet-node/tcp-l4-protocol.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/tcp-l4-protocol.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -49,7 +49,7 @@
   : aT (LAST_STATE, StateActionVec_t(LAST_EVENT)),
        eV (MAX_FLAGS)
 { 
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   // Create the state table
   // Closed state
@@ -290,15 +290,13 @@
 
 SA TcpStateMachine::Lookup (States_t s, Events_t e)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << s << e);
+  NS_LOG_FUNCTION (this << s << e);
   return aT[s][e];
 }
 
 Events_t TcpStateMachine::FlagsEvent (uint8_t f)
 { 
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << f);
+  NS_LOG_FUNCTION (this << f);
   // Lookup event from flags
   if (f >= MAX_FLAGS) return BAD_FLAGS;
   return eV[f]; // Look up flags event
@@ -327,7 +325,7 @@
     .SetParent<Ipv4L4Protocol> ()
     .AddAttribute ("RttEstimatorFactory",
                    "How RttEstimator objects are created.",
-                   GetDefaultRttEstimatorFactory (),
+                   ObjectFactoryValue (GetDefaultRttEstimatorFactory ()),
                    MakeObjectFactoryAccessor (&TcpL4Protocol::m_rttFactory),
                    MakeObjectFactoryChecker ())
     ;
@@ -337,13 +335,13 @@
 TcpL4Protocol::TcpL4Protocol ()
   : m_endPoints (new Ipv4EndPointDemux ())
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC("Made a TcpL4Protocol "<<this);
 }
 
 TcpL4Protocol::~TcpL4Protocol ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 void 
@@ -366,7 +364,7 @@
 void
 TcpL4Protocol::DoDispose (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_endPoints != 0)
     {
       delete m_endPoints;
@@ -379,7 +377,7 @@
 Ptr<Socket>
 TcpL4Protocol::CreateSocket (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Ptr<RttEstimator> rtt = m_rttFactory.Create<RttEstimator> ();
   Ptr<TcpSocket> socket = CreateObject<TcpSocket> ();
   socket->SetNode (m_node);
@@ -391,31 +389,28 @@
 Ipv4EndPoint *
 TcpL4Protocol::Allocate (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_endPoints->Allocate ();
 }
 
 Ipv4EndPoint *
 TcpL4Protocol::Allocate (Ipv4Address address)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << address);
+  NS_LOG_FUNCTION (this << address);
   return m_endPoints->Allocate (address);
 }
 
 Ipv4EndPoint *
 TcpL4Protocol::Allocate (uint16_t port)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << port);
+  NS_LOG_FUNCTION (this << port);
   return m_endPoints->Allocate (port);
 }
 
 Ipv4EndPoint *
 TcpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << address << port);
+  NS_LOG_FUNCTION (this << address << port);
   return m_endPoints->Allocate (address, port);
 }
 
@@ -423,8 +418,7 @@
 TcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
                          Ipv4Address peerAddress, uint16_t peerPort)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << localAddress << localPort << peerAddress << peerPort);
+  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
   return m_endPoints->Allocate (localAddress, localPort,
                                 peerAddress, peerPort);
 }
@@ -432,8 +426,7 @@
 void 
 TcpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << endPoint);
+  NS_LOG_FUNCTION (this << endPoint);
   m_endPoints->DeAllocate (endPoint);
 }
 
@@ -443,8 +436,7 @@
              Ipv4Address const &destination,
              Ptr<Ipv4Interface> incomingInterface)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << packet << source << destination << incomingInterface);
+  NS_LOG_FUNCTION (this << packet << source << destination << incomingInterface);
 
   TcpHeader tcpHeader;
   //these two do a peek, so that the packet can be forwarded up
@@ -481,8 +473,7 @@
            Ipv4Address saddr, Ipv4Address daddr, 
            uint16_t sport, uint16_t dport)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << packet << saddr << daddr << sport << dport);
+  NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport);
 
   TcpHeader tcpHeader;
   tcpHeader.SetDestinationPort (dport);
@@ -512,8 +503,7 @@
               << " ack " << outgoingHeader.GetAckNumber()
               << " flags " << std::hex << (int)outgoingHeader.GetFlags() << std::dec
               << " data size " << packet->GetSize());
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << packet << saddr << daddr);
+  NS_LOG_FUNCTION (this << packet << saddr << daddr);
   // XXX outgoingHeader cannot be logged
 
   outgoingHeader.SetLength (5); //header length in units of 32bit words
--- a/src/internet-node/tcp-socket.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/tcp-socket.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -80,8 +80,7 @@
     m_rtt (0),
     m_lastMeasuredRtt (Seconds(0.0))
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this);
+  NS_LOG_FUNCTION (this);
   
 }
 
@@ -125,7 +124,7 @@
     m_cnTimeout (sock.m_cnTimeout),
     m_cnCount (sock.m_cnCount)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC("Invoked the copy constructor");
   //copy the pending data if necessary
   if(sock.m_pendingData)
@@ -143,8 +142,7 @@
 
 TcpSocket::~TcpSocket ()
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS(this);
+  NS_LOG_FUNCTION(this);
   m_node = 0;
   if (m_endPoint != 0)
     {
@@ -198,21 +196,21 @@
 enum Socket::SocketErrno
 TcpSocket::GetErrno (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_errno;
 }
 
 Ptr<Node>
 TcpSocket::GetNode (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_node;
 }
 
 void 
 TcpSocket::Destroy (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_node = 0;
   m_endPoint = 0;
   m_tcp = 0;
@@ -221,7 +219,7 @@
 int
 TcpSocket::FinishBind (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_endPoint == 0)
     {
       return -1;
@@ -236,15 +234,14 @@
 int
 TcpSocket::Bind (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_endPoint = m_tcp->Allocate ();
   return FinishBind ();
 }
 int 
 TcpSocket::Bind (const Address &address)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this<<address);
+  NS_LOG_FUNCTION (this<<address);
   if (!InetSocketAddress::IsMatchingType (address))
     {
       return ERROR_INVAL;
@@ -279,14 +276,14 @@
 int 
 TcpSocket::ShutdownSend (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_shutdownSend = true;
   return 0;
 }
 int 
 TcpSocket::ShutdownRecv (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_shutdownRecv = false;
   return 0;
 }
@@ -294,7 +291,7 @@
 int
 TcpSocket::Close (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_state == CLOSED) 
     {
       return -1;
@@ -316,8 +313,7 @@
 int
 TcpSocket::Connect (const Address & address)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << address);
+  NS_LOG_FUNCTION (this << address);
   if (m_endPoint == 0)
     {
       if (Bind () == -1)
@@ -360,8 +356,7 @@
 
 int TcpSocket::Send (const uint8_t* buf, uint32_t size)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << buf << size);
+  NS_LOG_FUNCTION (this << buf << size);
   if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
     { // Ok to buffer some data to send
       if (!m_pendingData)
@@ -390,8 +385,7 @@
 
 int TcpSocket::DoSendTo (Ptr<Packet> p, const Address &address)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << p << address);
+  NS_LOG_FUNCTION (this << p << address);
   InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
   Ipv4Address ipv4 = transport.GetIpv4 ();
   uint16_t port = transport.GetPort ();
@@ -400,8 +394,7 @@
 
 int TcpSocket::DoSendTo (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << p << ipv4 << port);
+  NS_LOG_FUNCTION (this << p << ipv4 << port);
   if (m_endPoint == 0)
     {
       if (Bind () == -1)
@@ -425,8 +418,7 @@
 int 
 TcpSocket::SendTo (const Address &address, Ptr<Packet> p)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << address << p);
+  NS_LOG_FUNCTION (this << address << p);
   if (!m_connected)
     {
       m_errno = ERROR_NOTCONN;
@@ -441,8 +433,7 @@
 int
 TcpSocket::Listen (uint32_t q)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << q);
+  NS_LOG_FUNCTION (this << q);
   Actions_t action = ProcessEvent (APP_LISTEN);
   ProcessAction (action);
   return 0;
@@ -457,8 +448,7 @@
                " sport " << m_endPoint->GetPeerPort() <<
                " saddr " << m_endPoint->GetPeerAddress());
 
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << packet << ipv4 << port);
+  NS_LOG_FUNCTION (this << packet << ipv4 << port);
   if (m_shutdownRecv)
     {
       return;
@@ -486,8 +476,7 @@
 
 Actions_t TcpSocket::ProcessEvent (Events_t e)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << e);
+  NS_LOG_FUNCTION (this << e);
   States_t saveState = m_state;
   NS_LOG_LOGIC ("TcpSocket " << this << " processing event " << e);
   // simulation singleton is a way to get a single global static instance of a
@@ -538,8 +527,7 @@
 
 void TcpSocket::SendEmptyPacket (uint8_t flags)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << flags);
+  NS_LOG_FUNCTION (this << flags);
   Ptr<Packet> p = Create<Packet> ();
   TcpHeader header;
 
@@ -569,8 +557,7 @@
 
 bool TcpSocket::ProcessAction (Actions_t a)
 { // These actions do not require a packet or any TCP Headers
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << a);
+  NS_LOG_FUNCTION (this << a);
   switch (a)
   {
     case NO_ACT:
@@ -648,8 +635,7 @@
                                      const TcpHeader& tcpHeader,
                                      const Address& fromAddress)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << a << p  << fromAddress);
+  NS_LOG_FUNCTION (this << a << p  << fromAddress);
   uint32_t localIfIndex;
   Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
   switch (a)
@@ -695,6 +681,7 @@
       // TCP SYN consumes one byte
       m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
       m_nextTxSequence = tcpHeader.GetAckNumber ();
+      m_firstPendingSequence = m_nextTxSequence;  //bug 166
       NS_LOG_DEBUG ("TcpSocket " << this << " ACK_TX_1" <<
                     " nextRxSeq " << m_nextRxSequence);
       SendEmptyPacket (TcpHeader::ACK);
@@ -813,8 +800,7 @@
 
 bool TcpSocket::SendPendingData (bool withAck)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << withAck);
+  NS_LOG_FUNCTION (this << withAck);
   NS_LOG_LOGIC ("ENTERING SendPendingData");
   if (!m_pendingData)
     {
@@ -900,26 +886,26 @@
 
 uint32_t  TcpSocket::UnAckDataCount ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_nextTxSequence - m_highestRxAck;
 }
 
 uint32_t  TcpSocket::BytesInFlight ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_highTxMark - m_highestRxAck;
 }
 
 uint32_t  TcpSocket::Window ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC ("TcpSocket::Window() "<<this);
   return std::min (m_rxWindowSize, m_cWnd.Get());
 }
 
 uint32_t  TcpSocket::AvailableWindow ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   uint32_t unack = UnAckDataCount (); // Number of outstanding bytes
   uint32_t win = Window ();
   if (win < unack) 
@@ -933,8 +919,7 @@
                         const TcpHeader& tcpHeader, 
                         const Address& fromAddress)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << p << "tcpHeader " << fromAddress);
+  NS_LOG_FUNCTION (this << p << "tcpHeader " << fromAddress);
   NS_LOG_LOGIC ("TcpSocket " << this << " NewRx,"
                 << " seq " << tcpHeader.GetSequenceNumber()
                 << " ack " << tcpHeader.GetAckNumber()
@@ -1077,8 +1062,7 @@
 { // CommonNewAck is called only for "New" (non-duplicate) acks
   // and MUST be called by any subclass, from the NewAck function
   // Always cancel any pending re-tx timer on new acknowledgement
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << ack << skipTimer); 
+  NS_LOG_FUNCTION (this << ack << skipTimer); 
   //DEBUG(1,(cout << "TCP " << this << "Cancelling retx timer " << endl));
   if (!skipTimer)
     {
@@ -1121,8 +1105,7 @@
 void TcpSocket::NewAck (SequenceNumber seq)
 { // New acknowledgement up to sequence number "seq"
   // Adjust congestion window in response to new ack's received
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << seq);
+  NS_LOG_FUNCTION (this << seq);
   NS_LOG_LOGIC ("TcpSocket " << this << " NewAck "
            << " seq " << seq
            << " cWnd " << m_cWnd
@@ -1149,8 +1132,7 @@
 
 void TcpSocket::DupAck (const TcpHeader& t, uint32_t count)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << "t " << count);
+  NS_LOG_FUNCTION (this << "t " << count);
   NS_LOG_LOGIC ("TcpSocket " << this << " DupAck " <<  t.GetAckNumber ()
       << ", count " << count
       << ", time " << Simulator::Now ());
@@ -1172,15 +1154,14 @@
 
 void TcpSocket::ReTxTimeout ()
 { // Retransmit timeout
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this);
+  NS_LOG_FUNCTION (this);
   m_ssThresh = Window () / 2; // Per RFC2581
   m_ssThresh = std::max (m_ssThresh, 2 * m_segmentSize);
   // Set cWnd to segSize on timeout,  per rfc2581
   // Collapse congestion window (re-enter slowstart)
   m_cWnd = m_segmentSize;           
   m_nextTxSequence = m_highestRxAck; // Start from highest Ack
-  m_rtt->IncreaseMultiplier (); // Double timeout value for next retx timer
+  m_rtt->IncreaseMultiplier (); // DoubleValue timeout value for next retx timer
   Retransmit ();             // Retransmit the packet
 }
 
@@ -1200,8 +1181,7 @@
 
 void TcpSocket::Retransmit ()
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this);
+  NS_LOG_FUNCTION (this);
   uint8_t flags = TcpHeader::NONE;
   if (m_state == SYN_SENT) 
     {
--- a/src/internet-node/udp-l4-protocol.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/udp-l4-protocol.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -52,12 +52,12 @@
 UdpL4Protocol::UdpL4Protocol ()
   : m_endPoints (new Ipv4EndPointDemux ())
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 UdpL4Protocol::~UdpL4Protocol ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 void 
@@ -81,7 +81,7 @@
 void
 UdpL4Protocol::DoDispose (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_endPoints != 0)
     {
       delete m_endPoints;
@@ -94,7 +94,7 @@
 Ptr<Socket>
 UdpL4Protocol::CreateSocket (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Ptr<UdpSocket> socket = CreateObject<UdpSocket> ();
   socket->SetNode (m_node);
   socket->SetUdp (this);
@@ -104,39 +104,35 @@
 Ipv4EndPoint *
 UdpL4Protocol::Allocate (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_endPoints->Allocate ();
 }
 
 Ipv4EndPoint *
 UdpL4Protocol::Allocate (Ipv4Address address)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << address);
+  NS_LOG_FUNCTION (this << address);
   return m_endPoints->Allocate (address);
 }
 
 Ipv4EndPoint *
 UdpL4Protocol::Allocate (uint16_t port)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << port);
+  NS_LOG_FUNCTION (this << port);
   return m_endPoints->Allocate (port);
 }
 
 Ipv4EndPoint *
 UdpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << address << port);
+  NS_LOG_FUNCTION (this << address << port);
   return m_endPoints->Allocate (address, port);
 }
 Ipv4EndPoint *
 UdpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
                          Ipv4Address peerAddress, uint16_t peerPort)
 {
-  NS_LOG_FUNCTION; 
-  NS_LOG_PARAMS (this << localAddress << localPort << peerAddress << peerPort);
+  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
   return m_endPoints->Allocate (localAddress, localPort,
                                 peerAddress, peerPort);
 }
@@ -144,8 +140,7 @@
 void 
 UdpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
 {
-  NS_LOG_FUNCTION; 
-  NS_LOG_PARAMS (this << endPoint);
+  NS_LOG_FUNCTION (this << endPoint);
   m_endPoints->DeAllocate (endPoint);
 }
 
@@ -155,8 +150,7 @@
                        Ipv4Address const &destination,
                        Ptr<Ipv4Interface> interface)
 {
-  NS_LOG_FUNCTION; 
-  NS_LOG_PARAMS (this << packet << source << destination);
+  NS_LOG_FUNCTION (this << packet << source << destination);
 
   UdpHeader udpHeader;
   packet->RemoveHeader (udpHeader);
@@ -175,8 +169,7 @@
                      Ipv4Address saddr, Ipv4Address daddr, 
                      uint16_t sport, uint16_t dport)
 {
-  NS_LOG_FUNCTION; 
-  NS_LOG_PARAMS (this << packet << saddr << daddr << sport << dport);
+  NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport);
 
   UdpHeader udpHeader;
   udpHeader.SetDestination (dport);
--- a/src/internet-node/udp-socket.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/internet-node/udp-socket.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -42,12 +42,12 @@
     m_shutdownRecv (false),
     m_connected (false)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 UdpSocket::~UdpSocket ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   m_node = 0;
   if (m_endPoint != 0)
@@ -83,21 +83,21 @@
 enum Socket::SocketErrno
 UdpSocket::GetErrno (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_errno;
 }
 
 Ptr<Node>
 UdpSocket::GetNode (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_node;
 }
 
 void 
 UdpSocket::Destroy (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_node = 0;
   m_endPoint = 0;
   m_udp = 0;
@@ -106,7 +106,7 @@
 int
 UdpSocket::FinishBind (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_endPoint == 0)
     {
       return -1;
@@ -119,7 +119,7 @@
 int
 UdpSocket::Bind (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_endPoint = m_udp->Allocate ();
   return FinishBind ();
 }
@@ -127,8 +127,7 @@
 int 
 UdpSocket::Bind (const Address &address)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << address);
+  NS_LOG_FUNCTION (this << address);
 
   if (!InetSocketAddress::IsMatchingType (address))
     {
@@ -161,7 +160,7 @@
 int 
 UdpSocket::ShutdownSend (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_shutdownSend = true;
   return 0;
 }
@@ -169,7 +168,7 @@
 int 
 UdpSocket::ShutdownRecv (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_shutdownRecv = false;
   return 0;
 }
@@ -177,7 +176,7 @@
 int
 UdpSocket::Close(void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NotifyCloseCompleted ();
   return 0;
 }
@@ -185,8 +184,7 @@
 int
 UdpSocket::Connect(const Address & address)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << address);
+  NS_LOG_FUNCTION (this << address);
   Ipv4Route routeToDest;
   InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
   m_defaultAddress = transport.GetIpv4 ();
@@ -200,8 +198,7 @@
 int 
 UdpSocket::Send (Ptr<Packet> p)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << p);
+  NS_LOG_FUNCTION (this << p);
 
   if (!m_connected)
     {
@@ -214,7 +211,7 @@
 int 
 UdpSocket::DoSend (Ptr<Packet> p)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_endPoint == 0)
     {
       if (Bind () == -1)
@@ -236,8 +233,7 @@
 int
 UdpSocket::DoSendTo (Ptr<Packet> p, const Address &address)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << p << address);
+  NS_LOG_FUNCTION (this << p << address);
 
   if (!m_connected)
     {
@@ -258,8 +254,7 @@
 int
 UdpSocket::DoSendTo (Ptr<Packet> p, Ipv4Address dest, uint16_t port)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << p << dest << port);
+  NS_LOG_FUNCTION (this << p << dest << port);
 
   Ipv4Route routeToDest;
 
@@ -300,14 +295,15 @@
           NotifyDataSent (p->GetSize ());
         }
       NS_LOG_LOGIC ("Limited broadcast end.");
+      return p->GetSize();
     }
   else if (ipv4->GetIfIndexForDestination(dest, localIfIndex))
     {
       NS_LOG_LOGIC ("Route exists");
-      m_udp->Send (p, ipv4->GetAddress (localIfIndex), dest,
+      m_udp->Send (p->Copy (), ipv4->GetAddress (localIfIndex), dest,
 		   m_endPoint->GetLocalPort (), port);
       NotifyDataSent (p->GetSize ());
-      return 0;
+      return p->GetSize();;
     }
   else
    {
@@ -322,8 +318,7 @@
 int 
 UdpSocket::SendTo(const Address &address, Ptr<Packet> p)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << address << p);
+  NS_LOG_FUNCTION (this << address << p);
   InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
   Ipv4Address ipv4 = transport.GetIpv4 ();
   uint16_t port = transport.GetPort ();
@@ -333,8 +328,7 @@
 void 
 UdpSocket::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << packet << ipv4 << port);
+  NS_LOG_FUNCTION (this << packet << ipv4 << port);
 
   if (m_shutdownRecv)
     {
@@ -478,7 +472,7 @@
   m_receivedPacket = Create<Packet> ();
   m_receivedPacket2 = Create<Packet> ();
   NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress (Ipv4Address("10.0.0.1"), 1234),
-                                          Create<Packet> (123)), 0);
+                                          Create<Packet> (123)), 123);
   Simulator::Run ();
   NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
   NS_TEST_ASSERT_EQUAL (m_receivedPacket2->GetSize (), 0); // second interface should receive it
@@ -489,7 +483,7 @@
   m_receivedPacket = Create<Packet> ();
   m_receivedPacket2 = Create<Packet> ();
   NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress (Ipv4Address("255.255.255.255"), 1234),
-                                          Create<Packet> (123)), 0);
+                                          Create<Packet> (123)), 123);
   Simulator::Run ();
   NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
   // second socket should not receive it (it is bound specifically to the second interface's address
@@ -509,7 +503,7 @@
   m_receivedPacket = Create<Packet> ();
   m_receivedPacket2 = Create<Packet> ();
   NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress (Ipv4Address("255.255.255.255"), 1234),
-                                          Create<Packet> (123)), 0);
+                                          Create<Packet> (123)), 123);
   Simulator::Run ();
   NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
   NS_TEST_ASSERT_EQUAL (m_receivedPacket2->GetSize (), 123);
--- a/src/mobility/hierarchical-mobility-model.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/mobility/hierarchical-mobility-model.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -19,6 +19,7 @@
  */
 #include "hierarchical-mobility-model.h"
 #include "mobility-model-notifier.h"
+#include "ns3/pointer.h"
 
 namespace ns3 {
 
@@ -31,13 +32,13 @@
     .SetParent<MobilityModel> ()
     .AddConstructor<HierarchicalMobilityModel> ()
     .AddAttribute ("Child", "The child mobility model.",
-                   Ptr<MobilityModel> (0),
-                   MakePtrAccessor (&HierarchicalMobilityModel::SetChild),
-                   MakePtrChecker<MobilityModel> ())
+                   PointerValue (),
+                   MakePointerAccessor (&HierarchicalMobilityModel::SetChild),
+                   MakePointerChecker<MobilityModel> ())
     .AddAttribute ("Parent", "The parent mobility model.",
-                   Ptr<MobilityModel> (0),
-                   MakePtrAccessor (&HierarchicalMobilityModel::SetParent),
-                   MakePtrChecker<MobilityModel> ())
+                   PointerValue (),
+                   MakePointerAccessor (&HierarchicalMobilityModel::SetParent),
+                   MakePointerChecker<MobilityModel> ())
     ;
   return tid;
 }
--- a/src/mobility/mobility-model.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/mobility/mobility-model.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -30,13 +30,13 @@
     .SetParent<Object> ()
     .AddAttribute ("Position", "The current position of the mobility model.",
                    TypeId::ATTR_SGC,
-                   Vector (0.0, 0.0, 0.0),
+                   VectorValue (Vector (0.0, 0.0, 0.0)),
                    MakeVectorAccessor (&MobilityModel::SetPosition,
                                         &MobilityModel::GetPosition),
                    MakeVectorChecker ())
     .AddAttribute ("Velocity", "The current velocity of the mobility model.",
                    TypeId::ATTR_GET,
-                   Vector (0.0, 0.0, 0.0), // ignored initial value.
+                   VectorValue (Vector (0.0, 0.0, 0.0)), // ignored initial value.
                    MakeVectorAccessor (&MobilityModel::GetVelocity),
                    MakeVectorChecker ())
     ;
--- a/src/mobility/position-allocator.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/mobility/position-allocator.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -83,27 +83,27 @@
     .SetGroupName ("Mobility")
     .AddConstructor<GridPositionAllocator> ()
     .AddAttribute ("GridWidth", "The number of objects layed out on a line.",
-                   Uinteger (10),
+                   UintegerValue (10),
                    MakeUintegerAccessor (&GridPositionAllocator::m_n),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("MinX", "The x coordinate where the grid starts.",
-                   Double (1.0),
+                   DoubleValue (1.0),
                    MakeDoubleAccessor (&GridPositionAllocator::m_xMin),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("MinY", "The y coordinate where the grid starts.",
-                   Double (0.0),
+                   DoubleValue (0.0),
                    MakeDoubleAccessor (&GridPositionAllocator::m_yMin),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("DeltaX", "The x space between objects.",
-                   Double (1.0),
+                   DoubleValue (1.0),
                    MakeDoubleAccessor (&GridPositionAllocator::m_deltaX),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("DeltaY", "The y space between objects.",
-                   Double (1.0),
+                   DoubleValue (1.0),
                    MakeDoubleAccessor (&GridPositionAllocator::m_deltaY),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("LayoutType", "The type of layout.",
-                   Enum (ROW_FIRST),
+                   EnumValue (ROW_FIRST),
                    MakeEnumAccessor (&GridPositionAllocator::m_layoutType),
                    MakeEnumChecker (ROW_FIRST, "RowFirst",
                                     COLUMN_FIRST, "ColumnFirst"))
@@ -206,12 +206,12 @@
     .AddConstructor<RandomRectanglePositionAllocator> ()
     .AddAttribute ("X",
                    "A random variable which represents the x coordinate of a position in a random rectangle.",
-                   UniformVariable (0.0, 1.0),
+                   RandomVariableValue (UniformVariable (0.0, 1.0)),
                    MakeRandomVariableAccessor (&RandomRectanglePositionAllocator::m_x),
                    MakeRandomVariableChecker ())
     .AddAttribute ("Y",
                    "A random variable which represents the y coordinate of a position in a random rectangle.",
-                   UniformVariable (0.0, 1.0),
+                   RandomVariableValue (UniformVariable (0.0, 1.0)),
                    MakeRandomVariableAccessor (&RandomRectanglePositionAllocator::m_y),
                    MakeRandomVariableChecker ());
   return tid;
@@ -252,22 +252,22 @@
     .AddConstructor<RandomDiscPositionAllocator> ()
     .AddAttribute ("Theta",
                    "A random variable which represents the angle (gradients) of a position in a random disc.",
-                   UniformVariable (0.0, 6.2830),
+                   RandomVariableValue (UniformVariable (0.0, 6.2830)),
                    MakeRandomVariableAccessor (&RandomDiscPositionAllocator::m_theta),
                    MakeRandomVariableChecker ())
     .AddAttribute ("Rho",
                    "A random variable which represents the radius of a position in a random disc.",
-                   UniformVariable (0.0, 200.0),
+                   RandomVariableValue (UniformVariable (0.0, 200.0)),
                    MakeRandomVariableAccessor (&RandomDiscPositionAllocator::m_rho),
                    MakeRandomVariableChecker ())
     .AddAttribute ("X",
                    "The x coordinate of the center of the random position disc.",
-                   Double (0.0),
+                   DoubleValue (0.0),
                    MakeDoubleAccessor (&RandomDiscPositionAllocator::m_x),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("Y",
                    "The y coordinate of the center of the random position disc.",
-                   Double (0.0),
+                   DoubleValue (0.0),
                    MakeDoubleAccessor (&RandomDiscPositionAllocator::m_y),
                    MakeDoubleChecker<double> ())
     ;
--- a/src/mobility/random-direction-2d-mobility-model.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/mobility/random-direction-2d-mobility-model.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -40,15 +40,15 @@
     .SetGroupName ("Mobility")
     .AddConstructor<RandomDirection2dMobilityModel> ()
     .AddAttribute ("Bounds", "The 2d bounding area",
-                   Rectangle (-100, 100, -100, 100),
+                   RectangleValue (Rectangle (-100, 100, -100, 100)),
                    MakeRectangleAccessor (&RandomDirection2dMobilityModel::m_bounds),
                    MakeRectangleChecker ())
     .AddAttribute ("Speed", "A random variable to control the speed (m/s).",
-                   UniformVariable (1.0, 2.0),
+                   RandomVariableValue (UniformVariable (1.0, 2.0)),
                    MakeRandomVariableAccessor (&RandomDirection2dMobilityModel::m_speed),
                    MakeRandomVariableChecker ())
     .AddAttribute ("Pause", "A random variable to control the pause (s).",
-                   ConstantVariable (2.0),
+                   RandomVariableValue (ConstantVariable (2.0)),
                    MakeRandomVariableAccessor (&RandomDirection2dMobilityModel::m_pause),
                    MakeRandomVariableChecker ())
     ;
@@ -85,7 +85,7 @@
 void
 RandomDirection2dMobilityModel::SetDirectionAndSpeed (double direction)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   double speed = m_speed.GetValue ();
   const Vector vector (std::cos (direction) * speed,
                        std::sin (direction) * speed,
--- a/src/mobility/random-walk-2d-mobility-model.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/mobility/random-walk-2d-mobility-model.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -19,6 +19,7 @@
  */
 #include "random-walk-2d-mobility-model.h"
 #include "ns3/enum.h"
+#include "ns3/double.h"
 #include "ns3/simulator.h"
 #include "ns3/log.h"
 #include <cmath>
@@ -38,34 +39,34 @@
     .AddConstructor<RandomWalk2dMobilityModel> ()
     .AddAttribute ("Bounds",
                    "Bounds of the area to cruise.",
-                   Rectangle (0.0, 0.0, 100.0, 100.0),
+                   RectangleValue (Rectangle (0.0, 0.0, 100.0, 100.0)),
                    MakeRectangleAccessor (&RandomWalk2dMobilityModel::m_bounds),
                    MakeRectangleChecker ())
     .AddAttribute ("Time",
                    "Change current direction and speed after moving for this delay.",
-                   Seconds (1.0),
+                   TimeValue (Seconds (1.0)),
                    MakeTimeAccessor (&RandomWalk2dMobilityModel::m_modeTime),
                    MakeTimeChecker ())
     .AddAttribute ("Distance",
                    "Change current direction and speed after moving for this distance.",
-                   Seconds (1.0),
-                   MakeTimeAccessor (&RandomWalk2dMobilityModel::m_modeTime),
-                   MakeTimeChecker ())
+                   DoubleValue (1.0),
+                   MakeDoubleAccessor (&RandomWalk2dMobilityModel::m_modeDistance),
+                   MakeDoubleChecker<double> ())
     .AddAttribute ("Mode",
                    "The mode indicates the condition used to "
                    "change the current speed and direction",
-                   Enum (RandomWalk2dMobilityModel::MODE_DISTANCE),
+                   EnumValue (RandomWalk2dMobilityModel::MODE_DISTANCE),
                    MakeEnumAccessor (&RandomWalk2dMobilityModel::m_mode),
                    MakeEnumChecker (RandomWalk2dMobilityModel::MODE_DISTANCE, "Distance",
                                     RandomWalk2dMobilityModel::MODE_TIME, "Time"))
     .AddAttribute ("Direction",
                    "A random variable used to pick the direction (gradients).",
-                   UniformVariable (0.0, 6.283184),
+                   RandomVariableValue (UniformVariable (0.0, 6.283184)),
                    MakeRandomVariableAccessor (&RandomWalk2dMobilityModel::m_direction),
                    MakeRandomVariableChecker ())
     .AddAttribute ("Speed",
                    "A random variable used to pick the speed (m/s).",
-                   UniformVariable (2.0, 4.0),
+                   RandomVariableValue (UniformVariable (2.0, 4.0)),
                    MakeRandomVariableAccessor (&RandomWalk2dMobilityModel::m_speed),
                    MakeRandomVariableChecker ());
   return tid;
--- a/src/mobility/random-waypoint-mobility-model.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/mobility/random-waypoint-mobility-model.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -20,6 +20,7 @@
 #include <cmath>
 #include "ns3/simulator.h"
 #include "ns3/random-variable.h"
+#include "ns3/pointer.h"
 #include "random-waypoint-mobility-model.h"
 #include "position-allocator.h"
 
@@ -36,19 +37,19 @@
     .AddConstructor<RandomWaypointMobilityModel> ()
     .AddAttribute ("Speed",
                    "A random variable used to pick the speed of a random waypoint model.",
-                   UniformVariable (0.3, 0.7),
+                   RandomVariableValue (UniformVariable (0.3, 0.7)),
                    MakeRandomVariableAccessor (&RandomWaypointMobilityModel::m_speed),
                    MakeRandomVariableChecker ())
     .AddAttribute ("Pause",
                    "A random variable used to pick the pause of a random waypoint model.",
-                   ConstantVariable (2.0),
+                   RandomVariableValue (ConstantVariable (2.0)),
                    MakeRandomVariableAccessor (&RandomWaypointMobilityModel::m_pause),
                    MakeRandomVariableChecker ())
     .AddAttribute ("Position",
                    "The position model used to pick a destination point.",
-                   Ptr<PositionAllocator> (0),
-                   MakePtrAccessor (&RandomWaypointMobilityModel::m_position),
-                   MakePtrChecker<PositionAllocator> ());
+                   PointerValue (),
+                   MakePointerAccessor (&RandomWaypointMobilityModel::m_position),
+                   MakePointerChecker<PositionAllocator> ());
   
   return tid;
 }
--- a/src/mobility/rectangle.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/mobility/rectangle.h	Tue Apr 22 21:19:39 2008 -0700
@@ -68,6 +68,11 @@
 std::ostream &operator << (std::ostream &os, const Rectangle &rectangle);
 std::istream &operator >> (std::istream &is, Rectangle &rectangle);
 
+/**
+ * \class ns3::RectangleValue
+ * \brief hold objects of type ns3::Rectangle
+ */
+
 ATTRIBUTE_HELPER_HEADER_2 (Rectangle);
 
 } // namespace ns3
--- a/src/mobility/vector.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/mobility/vector.h	Tue Apr 22 21:19:39 2008 -0700
@@ -63,6 +63,11 @@
 
 double CalculateDistance (const Vector &a, const Vector &b);
 
+/**
+ * \class ns3::VectorValue
+ * \brief hold objects of type ns3::Vector
+ */
+
 ATTRIBUTE_HELPER_HEADER_2 (Vector);
 
 std::ostream &operator << (std::ostream &os, const Vector &vector);
--- a/src/node/address.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/node/address.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -109,12 +109,28 @@
 
 ATTRIBUTE_HELPER_CPP (Address);
 
+
 bool operator == (const Address &a, const Address &b)
 {
-  NS_ASSERT (a.m_type == b.m_type || 
-	     a.m_type == 0 || 
-	     b.m_type == 0);
-  NS_ASSERT (a.GetLength() == b.GetLength());  
+  /* Two addresses can be equal even if their types are 
+   * different if one of the two types is zero. a type of 
+   * zero identifies an Address which might contain meaningful 
+   * payload but for which the type field could not be set because
+   * we did not know it. This can typically happen in the ARP
+   * layer where we receive an address from an ArpHeader but
+   * we do not know its type: we really want to be able to
+   * compare addresses without knowing their real type.
+   */
+  if (a.m_type != b.m_type &&
+      a.m_type != 0 && 
+      b.m_type != 0)
+    {
+      return false;
+    }
+  if (a.m_len != b.m_len)
+    {
+      return false;
+    }
   return memcmp (a.m_data, b.m_data, a.m_len) == 0;
 }
 bool operator != (const Address &a, const Address &b)
@@ -123,9 +139,16 @@
 }
 bool operator < (const Address &a, const Address &b)
 {
-  NS_ASSERT (a.m_type == b.m_type  || 
-	     a.m_type == 0 || 
-	     b.m_type == 0);
+  // XXX: it is not clear to me how to order based on type.
+  // so, we do not compare the types here but we should.
+  if (a.m_len < b.m_len)
+    {
+      return true;
+    }
+  else if (a.m_len > b.m_len)
+    {
+      return false;
+    }
   NS_ASSERT (a.GetLength() == b.GetLength());
   for (uint8_t i = 0; i < a.GetLength(); i++) 
     {
@@ -143,27 +166,63 @@
 
 std::ostream& operator<< (std::ostream& os, const Address & address)
 {
-  if (address.m_len == 0) 
-    {
-      os << "NULL-ADDRESS";
-      return os;
-    }
   os.setf (std::ios::hex, std::ios::basefield);
   os.fill('0');
-  for (uint8_t i=0; i < (address.m_len-1); i++) 
+  os << std::setw(2) << (uint32_t) address.m_type << "-" << std::setw(2) << (uint32_t) address.m_len << "-";
+  for (uint8_t i = 0; i < (address.m_len-1); ++i)
     {
       os << std::setw(2) << (uint32_t)address.m_data[i] << ":";
     }
   // Final byte not suffixed by ":"
-  os << std::setw(2) << (uint32_t)address.m_data[address.m_len-1];
+  os << std::setw(2) << (uint32_t) address.m_data[address.m_len-1];
   os.setf (std::ios::dec, std::ios::basefield);
   os.fill(' ');
   return os;
 }
 
+static uint8_t
+AsInt (std::string v)
+{
+  std::istringstream iss;
+  iss.str (v);
+  uint32_t retval;
+  iss >> std::hex >> retval >> std::dec;
+  return retval;
+}
+
 std::istream& operator>> (std::istream& is, Address & address)
 {
-  // XXX: need to be able to parse this.
+  std::string v;
+  is >> v;
+  std::string::size_type firstDash, secondDash;
+  firstDash = v.find ("-");
+  secondDash = v.find ("-", firstDash+1);
+  std::string type = v.substr (0, firstDash-0);
+  std::string len = v.substr (firstDash+1, secondDash-(firstDash+1));
+
+  address.m_type = AsInt (type);
+  address.m_len = AsInt (len);
+  NS_ASSERT (address.m_len <= Address::MAX_SIZE);
+
+  std::string::size_type col = secondDash + 1;
+  for (uint8_t i = 0; i < address.m_len; ++i)
+    {
+      std::string tmp;
+      std::string::size_type next;
+      next = v.find (":", col);
+      if (next == std::string::npos)
+	{
+	  tmp = v.substr (col, v.size ()-col);
+	  address.m_data[i] = AsInt (tmp);
+	  break;
+	}
+      else
+	{
+	  tmp = v.substr (col, next-col);
+	  address.m_data[i] = AsInt (tmp);
+	  col = next + 1;
+	}
+    }
   return is;
 }
 
--- a/src/node/address.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/node/address.h	Tue Apr 22 21:19:39 2008 -0700
@@ -159,12 +159,18 @@
   friend bool operator == (const Address &a, const Address &b);
   friend bool operator < (const Address &a, const Address &b);
   friend std::ostream& operator<< (std::ostream& os, const Address & address);
+  friend std::istream& operator>> (std::istream& is, Address & address);
 
   uint8_t m_type;
   uint8_t m_len;
   uint8_t m_data[MAX_SIZE];
 };
 
+/**
+ * \class ns3::AddressValue
+ * \brief hold objects of type ns3::Address
+ */
+
 ATTRIBUTE_HELPER_HEADER_2 (Address);
 
 bool operator == (const Address &a, const Address &b);
--- a/src/node/channel.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/node/channel.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -37,33 +37,31 @@
 Channel::Channel ()
   : m_name("Channel")
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 Channel::Channel (std::string name)
   : m_name(name)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << name);
+  NS_LOG_FUNCTION (this << name);
 }
 
 Channel::~Channel ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
   void
 Channel::SetName(std::string name)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << name);
+  NS_LOG_FUNCTION (this << name);
   m_name = name;
 }
 
   std::string
 Channel::GetName(void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_name;
 }
 
--- a/src/node/drop-tail-queue.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/node/drop-tail-queue.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -32,7 +32,7 @@
     .SetParent<Queue> ()
     .AddConstructor<DropTailQueue> ()
     .AddAttribute ("MaxPackets", "The maximum number of packets accepted by this DropTailQueue.",
-                   Uinteger (100),
+                   UintegerValue (100),
                    MakeUintegerAccessor (&DropTailQueue::m_maxPackets),
                    MakeUintegerChecker<uint32_t> ())
     ;
@@ -44,19 +44,18 @@
   Queue (),
   m_packets ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 DropTailQueue::~DropTailQueue ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 bool 
 DropTailQueue::DoEnqueue (Ptr<Packet> p)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << p);
+  NS_LOG_FUNCTION (this << p);
 
   if (m_packets.size () >= m_maxPackets)
     {
@@ -72,8 +71,7 @@
 Ptr<Packet>
 DropTailQueue::DoDequeue (void)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this);
+  NS_LOG_FUNCTION (this);
 
   if (m_packets.empty()) 
     {
@@ -92,8 +90,7 @@
 Ptr<Packet>
 DropTailQueue::DoPeek (void) const
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this);
+  NS_LOG_FUNCTION (this);
 
   if (m_packets.empty()) 
     {
@@ -132,7 +129,7 @@
   bool result = true;
 
   Ptr<DropTailQueue> queue = CreateObject<DropTailQueue> ();
-  NS_TEST_ASSERT (queue->SetAttributeFailSafe ("MaxPackets", Uinteger (3)));
+  NS_TEST_ASSERT (queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (3)));
   
   Ptr<Packet> p1, p2, p3, p4;
   p1 = Create<Packet> ();
--- a/src/node/ipv4-address-generator.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/node/ipv4-address-generator.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -78,14 +78,14 @@
 Ipv4AddressGeneratorImpl::Ipv4AddressGeneratorImpl () 
   : m_entries (), m_test (false)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Reset ();
 }
 
   void
 Ipv4AddressGeneratorImpl::Reset (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   uint32_t mask = 0;
 //
@@ -123,7 +123,7 @@
 
 Ipv4AddressGeneratorImpl::~Ipv4AddressGeneratorImpl ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
   void
@@ -132,7 +132,7 @@
   const Ipv4Mask mask,
   const Ipv4Address addr)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 //
 // We're going to be playing with the actual bits in the network and mask so
 // pull them out into ints.
@@ -170,7 +170,7 @@
 Ipv4AddressGeneratorImpl::GetNetwork (
   const Ipv4Mask mask) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   uint32_t index = MaskToIndex (mask);
   return Ipv4Address (m_netTable[index].network << m_netTable[index].shift);
@@ -180,7 +180,7 @@
 Ipv4AddressGeneratorImpl::NextNetwork (
   const Ipv4Mask mask)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 //
 // The way this is expected to be used is that an address and network prefix
 // are initialized, and then NextAddress() is called repeatedly to set the
@@ -200,7 +200,7 @@
   const Ipv4Address addr,
   const Ipv4Mask mask)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   uint32_t index = MaskToIndex (mask);
   uint32_t addrBits = addr.GetHostOrder ();
@@ -215,7 +215,7 @@
 Ipv4AddressGeneratorImpl::GetAddress (
   const Ipv4Mask mask) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   uint32_t index = MaskToIndex (mask);
 
@@ -227,7 +227,7 @@
   Ipv4Address
 Ipv4AddressGeneratorImpl::NextAddress (const Ipv4Mask mask)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 //
 // The way this is expected to be used is that an address and network prefix
 // are initialized, and then NextAddress() is called repeatedly to set the
@@ -256,7 +256,7 @@
   bool
 Ipv4AddressGeneratorImpl::AddAllocated (const Ipv4Address address)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   uint32_t addr = address.GetHostOrder ();
 
@@ -347,7 +347,7 @@
   void
 Ipv4AddressGeneratorImpl::TestMode (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_test = true;
 }
 
@@ -390,7 +390,7 @@
   const Ipv4Mask mask,
   const Ipv4Address addr)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   SimulationSingleton<Ipv4AddressGeneratorImpl>::Get ()
     ->Init (net, mask, addr);
@@ -399,7 +399,7 @@
   Ipv4Address
 Ipv4AddressGenerator::NextNetwork (const Ipv4Mask mask)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   return SimulationSingleton<Ipv4AddressGeneratorImpl>::Get ()
     ->NextNetwork (mask);
@@ -408,7 +408,7 @@
   Ipv4Address
 Ipv4AddressGenerator::GetNetwork (const Ipv4Mask mask)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   return SimulationSingleton<Ipv4AddressGeneratorImpl>::Get ()
     ->GetNetwork (mask);
@@ -419,7 +419,7 @@
   const Ipv4Address addr,
   const Ipv4Mask mask)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   SimulationSingleton<Ipv4AddressGeneratorImpl>::Get ()
     ->InitAddress (addr, mask);
@@ -428,7 +428,7 @@
   Ipv4Address
 Ipv4AddressGenerator::GetAddress (const Ipv4Mask mask)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   return SimulationSingleton<Ipv4AddressGeneratorImpl>::Get ()
     ->GetAddress (mask);
@@ -437,7 +437,7 @@
   Ipv4Address
 Ipv4AddressGenerator::NextAddress (const Ipv4Mask mask)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   return SimulationSingleton<Ipv4AddressGeneratorImpl>::Get ()
     ->NextAddress (mask);
@@ -446,7 +446,7 @@
   void
 Ipv4AddressGenerator::Reset (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   return SimulationSingleton<Ipv4AddressGeneratorImpl>::Get ()
     ->Reset ();
@@ -455,7 +455,7 @@
   bool
 Ipv4AddressGenerator::AddAllocated (const Ipv4Address addr)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   return SimulationSingleton<Ipv4AddressGeneratorImpl>::Get ()
     ->AddAllocated (addr);
@@ -464,7 +464,7 @@
   void
   Ipv4AddressGenerator::TestMode (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   SimulationSingleton<Ipv4AddressGeneratorImpl>::Get ()
     ->TestMode ();
--- a/src/node/ipv4-address.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/node/ipv4-address.h	Tue Apr 22 21:19:39 2008 -0700
@@ -185,6 +185,15 @@
   uint32_t m_mask;
 };
 
+/**
+ * \class ns3::Ipv4AddressValue
+ * \brief hold objects of type ns3::Ipv4Address
+ */
+/**
+ * \class ns3::Ipv4MaskValue
+ * \brief hold objects of type ns3::Ipv4Mask
+ */
+
 ATTRIBUTE_HELPER_HEADER_2 (Ipv4Address);
 ATTRIBUTE_HELPER_HEADER_2 (Ipv4Mask);
 
--- a/src/node/mac48-address.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/node/mac48-address.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -200,9 +200,40 @@
   return os;
 }
 
-std::istream& operator>> (std::istream& is, const Mac48Address & address)
+static uint8_t
+AsInt (std::string v)
+{
+  std::istringstream iss;
+  iss.str (v);
+  uint32_t retval;
+  iss >> std::hex >> retval >> std::dec;
+  return retval;
+}
+
+std::istream& operator>> (std::istream& is, Mac48Address & address)
 {
-  // XXX !
+  std::string v;
+  is >> v;
+
+  std::string::size_type col = 0;
+  for (uint8_t i = 0; i < 6; ++i)
+    {
+      std::string tmp;
+      std::string::size_type next;
+      next = v.find (":", col);
+      if (next == std::string::npos)
+	{
+	  tmp = v.substr (col, v.size ()-col);
+	  address.m_address[i] = AsInt (tmp);
+	  break;
+	}
+      else
+	{
+	  tmp = v.substr (col, next-col);
+	  address.m_address[i] = AsInt (tmp);
+	  col = next + 1;
+	}
+    }
   return is;
 }
 
--- a/src/node/mac48-address.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/node/mac48-address.h	Tue Apr 22 21:19:39 2008 -0700
@@ -107,17 +107,23 @@
   static uint8_t GetType (void);
   friend bool operator < (const Mac48Address &a, const Mac48Address &b);
   friend bool operator == (const Mac48Address &a, const Mac48Address &b);
+  friend std::istream& operator>> (std::istream& is, Mac48Address & address);
 
   uint8_t m_address[6];
 };
 
+/**
+ * \class ns3::Mac48AddressValue
+ * \brief hold objects of type ns3::Mac48Address
+ */
+
 ATTRIBUTE_HELPER_HEADER_2 (Mac48Address);
 
 bool operator == (const Mac48Address &a, const Mac48Address &b);
 bool operator != (const Mac48Address &a, const Mac48Address &b);
 bool operator < (const Mac48Address &a, const Mac48Address &b);
 std::ostream& operator<< (std::ostream& os, const Mac48Address & address);
-std::istream& operator>> (std::istream& is, const Mac48Address & address);
+std::istream& operator>> (std::istream& is, Mac48Address & address);
 
 } // namespace ns3
 
--- a/src/node/node-list.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/node/node-list.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -30,9 +30,8 @@
 
 NS_LOG_COMPONENT_DEFINE ("NodeList");
 
-
 /**
- * The private node list used by the static-based API
+ * \brief private implementation detail of the NodeList API.
  */
 class NodeListPriv : public Object
 {
@@ -55,15 +54,17 @@
   std::vector<Ptr<Node> > m_nodes;
 };
 
+NS_OBJECT_ENSURE_REGISTERED (NodeListPriv);
+
 TypeId 
 NodeListPriv::GetTypeId (void)
 {
-  static TypeId tid = TypeId ("NodeListPriv")
+  static TypeId tid = TypeId ("ns3::NodeListPriv")
     .SetParent<Object> ()
     .AddAttribute ("NodeList", "The list of all nodes created during the simulation.",
-                   ObjectVector (),
+                   ObjectVectorValue (),
                    MakeObjectVectorAccessor (&NodeListPriv::m_nodes),
-                   MakeObjectVectorChecker ())
+                   MakeObjectVectorChecker<Node> ())
     ;
   return tid;
 }
@@ -88,7 +89,7 @@
 void 
 NodeListPriv::Delete (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Config::UnregisterRootNamespaceObject (Get ());
   (*DoGet ()) = 0;
 }
@@ -96,11 +97,11 @@
 
 NodeListPriv::NodeListPriv ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 NodeListPriv::~NodeListPriv ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for (std::vector<Ptr<Node> >::iterator i = m_nodes.begin ();
        i != m_nodes.end (); i++)
     {
--- a/src/node/node.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/node/node.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -37,16 +37,16 @@
   static TypeId tid = TypeId ("ns3::Node")
     .SetParent<Object> ()
     .AddAttribute ("DeviceList", "The list of devices associated to this Node.",
-                   ObjectVector (),
+                   ObjectVectorValue (),
                    MakeObjectVectorAccessor (&Node::m_devices),
-                   MakeObjectVectorChecker ())
+                   MakeObjectVectorChecker<NetDevice> ())
     .AddAttribute ("ApplicationList", "The list of applications associated to this Node.",
-                   ObjectVector (),
+                   ObjectVectorValue (),
                    MakeObjectVectorAccessor (&Node::m_applications),
-                   MakeObjectVectorChecker ())
+                   MakeObjectVectorChecker<Application> ())
     .AddAttribute ("Id", "The id (unique integer) of this Node.",
                    TypeId::ATTR_GET, // allow only getting it.
-                   Uinteger (0),
+                   UintegerValue (0),
                    MakeUintegerAccessor (&Node::m_id),
                    MakeUintegerChecker<uint32_t> ())
     ;
--- a/src/node/packet-socket.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/node/packet-socket.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -31,8 +31,7 @@
 
 PacketSocket::PacketSocket ()
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_state = STATE_OPEN;
   m_shutdownSend = false;
   m_shutdownRecv = false;
@@ -47,34 +46,34 @@
 
 PacketSocket::~PacketSocket ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 void 
 PacketSocket::DoDispose (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_device = 0;
 }
 
 enum Socket::SocketErrno
 PacketSocket::GetErrno (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_errno;
 }
 
 Ptr<Node>
 PacketSocket::GetNode (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_node;
 }
 
 int
 PacketSocket::Bind (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   PacketSocketAddress address;
   address.SetProtocol (0);
   address.SetAllDevices ();
@@ -84,7 +83,7 @@
 int
 PacketSocket::Bind (const Address &address)
 { 
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (!PacketSocketAddress::IsMatchingType (address))
     {
       m_errno = ERROR_INVAL;
@@ -97,7 +96,7 @@
 int
 PacketSocket::DoBind (const PacketSocketAddress &address)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_state == STATE_BOUND ||
       m_state == STATE_CONNECTED)
     {
@@ -130,7 +129,7 @@
 int
 PacketSocket::ShutdownSend (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_state == STATE_CLOSED)
     {
       m_errno = ERROR_BADF;
@@ -143,7 +142,7 @@
 int
 PacketSocket::ShutdownRecv (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_state == STATE_CLOSED)
     {
       m_errno = ERROR_BADF;
@@ -156,7 +155,7 @@
 int
 PacketSocket::Close(void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_state == STATE_CLOSED)
     {
       m_errno = ERROR_BADF;
@@ -170,7 +169,7 @@
 int
 PacketSocket::Connect(const Address &ad)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   PacketSocketAddress address;
   if (m_state == STATE_CLOSED)
     {
@@ -205,7 +204,7 @@
 int
 PacketSocket::Send (Ptr<Packet> p)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_state == STATE_OPEN ||
       m_state == STATE_BOUND)
     {
@@ -218,7 +217,7 @@
 int
 PacketSocket::SendTo(const Address &address, Ptr<Packet> p)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   PacketSocketAddress ad;
   if (m_state == STATE_CLOSED)
     {
@@ -291,7 +290,7 @@
 PacketSocket::ForwardUp (Ptr<NetDevice> device, Ptr<Packet> packet, 
                          uint16_t protocol, const Address &from)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_shutdownRecv)
     {
       return;
--- a/src/node/queue.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/node/queue.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -31,11 +31,11 @@
 {
   static TypeId tid = TypeId ("ns3::Queue")
     .SetParent<Object> ()
-    .AddTraceSource ("Enqueue", "XXX",
+    .AddTraceSource ("Enqueue", "Enqueue a packet in the queue.",
                      MakeTraceSourceAccessor (&Queue::m_traceEnqueue))
-    .AddTraceSource ("Dequeue", "XXX",
+    .AddTraceSource ("Dequeue", "Dequeue a packet from the queue.",
                      MakeTraceSourceAccessor (&Queue::m_traceDequeue))
-    .AddTraceSource ("Drop", "XXX",
+    .AddTraceSource ("Drop", "Drop a packet stored in the queue.",
                      MakeTraceSourceAccessor (&Queue::m_traceDrop))
     ;
   return tid;
@@ -49,20 +49,19 @@
   m_nTotalDroppedBytes(0),
   m_nTotalDroppedPackets(0)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 Queue::~Queue()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 
 bool 
 Queue::Enqueue (Ptr<Packet> p)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << p);
+  NS_LOG_FUNCTION (this << p);
   NS_LOG_LOGIC ("m_traceEnqueue (p)");
 
   m_traceEnqueue (p);
@@ -79,8 +78,7 @@
 Ptr<Packet>
 Queue::Dequeue (void)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this);
+  NS_LOG_FUNCTION (this);
 
   Ptr<Packet> packet = DoDequeue ();
 
@@ -102,15 +100,14 @@
 void
 Queue::DequeueAll (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_ASSERT_MSG (0, "Don't know what to do with dequeued packets!");
 }
 
 Ptr<Packet>
 Queue::Peek (void) const
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this);
+  NS_LOG_FUNCTION (this);
   return DoPeek ();
 }
 
@@ -118,7 +115,7 @@
 uint32_t 
 Queue::GetNPackets (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC ("returns " << m_nPackets);
   return m_nPackets;
 }
@@ -126,7 +123,7 @@
 uint32_t
 Queue::GetNBytes (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC (" returns " << m_nBytes);
   return m_nBytes;
 }
@@ -134,7 +131,7 @@
 bool
 Queue::IsEmpty (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC ("returns " << (m_nPackets == 0));
   return m_nPackets == 0;
 }
@@ -142,7 +139,7 @@
 uint32_t
 Queue::GetTotalReceivedBytes (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC("returns " << m_nTotalReceivedBytes);
   return m_nTotalReceivedBytes;
 }
@@ -150,7 +147,7 @@
 uint32_t
 Queue::GetTotalReceivedPackets (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC ("returns " << m_nTotalReceivedPackets);
   return m_nTotalReceivedPackets;
 }
@@ -158,7 +155,7 @@
 uint32_t
 Queue:: GetTotalDroppedBytes (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC ("returns " << m_nTotalDroppedBytes);
   return m_nTotalDroppedBytes;
 }
@@ -166,7 +163,7 @@
 uint32_t
 Queue::GetTotalDroppedPackets (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC("returns " << m_nTotalDroppedPackets);
   return m_nTotalDroppedPackets;
 }
@@ -174,7 +171,7 @@
 void 
 Queue::ResetStatistics (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_nTotalReceivedBytes = 0;
   m_nTotalReceivedPackets = 0;
   m_nTotalDroppedBytes = 0;
@@ -184,8 +181,7 @@
 void
 Queue::Drop (Ptr<Packet> p)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << p);
+  NS_LOG_FUNCTION (this << p);
 
   m_nTotalDroppedPackets++;
   m_nTotalDroppedBytes += p->GetSize ();
--- a/src/node/socket.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/node/socket.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -30,13 +30,13 @@
 
 Socket::~Socket ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 void 
 Socket::SetCloseCallback (Callback<void,Ptr<Socket> > closeCompleted)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_closeCompleted = closeCompleted;
 }
 
@@ -46,7 +46,7 @@
   Callback<void, Ptr<Socket> > connectionFailed,
   Callback<void, Ptr<Socket> > halfClose)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_connectionSucceeded = connectionSucceeded;
   m_connectionFailed = connectionFailed;
   m_halfClose = halfClose;
@@ -58,7 +58,7 @@
   Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
   Callback<void, Ptr<Socket> > closeRequested)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_connectionRequest = connectionRequest;
   m_newConnectionCreated = newConnectionCreated;
   m_closeRequested = closeRequested;
@@ -67,20 +67,20 @@
 void 
 Socket::SetSendCallback (Callback<void, Ptr<Socket>, uint32_t> dataSent)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_dataSent = dataSent;
 }
 
 void 
 Socket::SetRecvCallback (Callback<void, Ptr<Socket>, Ptr<Packet>,const Address&> receivedData)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_receivedData = receivedData;
 }
 
 int Socket::Send (const uint8_t* buf, uint32_t size)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Ptr<Packet> p;
   if (buf)
     {
@@ -95,7 +95,7 @@
 
 int Socket::SendTo (const Address &address, const uint8_t* buf, uint32_t size)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Ptr<Packet> p;
   if(buf)
     {
@@ -117,7 +117,7 @@
 void 
 Socket::NotifyCloseCompleted (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (!m_closeCompleted.IsNull ())
     {
       m_closeCompleted (this);
@@ -127,7 +127,7 @@
 void 
 Socket::NotifyConnectionSucceeded (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (!m_connectionSucceeded.IsNull ())
     {
       m_connectionSucceeded (this);
@@ -137,7 +137,7 @@
 void 
 Socket::NotifyConnectionFailed (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (!m_connectionFailed.IsNull ())
     {
       m_connectionFailed (this);
@@ -147,7 +147,7 @@
 void 
 Socket::NotifyHalfClose (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (!m_halfClose.IsNull ())
     {
       m_halfClose (this);
@@ -157,7 +157,7 @@
 bool 
 Socket::NotifyConnectionRequest (const Address &from)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (!m_connectionRequest.IsNull ())
     {
       return m_connectionRequest (this, from);
@@ -175,7 +175,7 @@
 void 
 Socket::NotifyNewConnectionCreated (Ptr<Socket> socket, const Address &from)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (!m_newConnectionCreated.IsNull ())
     {
       m_newConnectionCreated (socket, from);
@@ -185,7 +185,7 @@
 void 
 Socket::NotifyCloseRequested (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (!m_closeRequested.IsNull ())
     {
       m_closeRequested (this);
@@ -195,7 +195,7 @@
 void 
 Socket::NotifyDataSent (uint32_t size)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (!m_dataSent.IsNull ())
     {
       m_dataSent (this, size);
@@ -205,7 +205,7 @@
 void 
 Socket::NotifyDataReceived (Ptr<Packet> p, const Address &from)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (!m_receivedData.IsNull ())
     {
       m_receivedData (this, p, from);
--- a/src/node/tcp.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/node/tcp.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -32,52 +32,52 @@
     .SetParent<SocketFactory> ()
     .AddAttribute ("DefaultSegmentSize",
                    "Default TCP maximum segment size in bytes (may be adjusted based on MTU discovery)",
-                   Uinteger (536),
+                   UintegerValue (536),
                    MakeUintegerAccessor (&Tcp::m_defaultSegSize),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("DefaultAdvertisedWindowSize",
                    "Default TCP advertised window size (bytes)",
-                   Uinteger (0xffff),
+                   UintegerValue (0xffff),
                    MakeUintegerAccessor (&Tcp::m_defaultAdvWin),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("DefaultSlowStartThreshold",
                    "Default TCP slow start threshold (bytes)",
-                   Uinteger (0xffff),
+                   UintegerValue (0xffff),
                    MakeUintegerAccessor (&Tcp::m_defaultSsThresh),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("DefaultTxBufferSize",
                    "Default TCP maximum transmit buffer size (bytes)",
-                   Uinteger (0xffffffffl),
+                   UintegerValue (0xffffffffl),
                    MakeUintegerAccessor (&Tcp::m_defaultTxBuffer),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("DefaultRxBufferSize",
                    "Default TCP maximum receive buffer size (bytes)",
-                   Uinteger (0xffffffffl),
+                   UintegerValue (0xffffffffl),
                    MakeUintegerAccessor (&Tcp::m_defaultRxBuffer),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("DefaultInitialCongestionWindowSize",
                    "Default TCP initial congestion window size (segments)",
-                   Uinteger (1),
+                   UintegerValue (1),
                    MakeUintegerAccessor (&Tcp::m_defaultInitialCwnd),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("DefaultConnTimeout",
                    "Default TCP retransmission timeout when opening connection (seconds)",
-                   Uinteger (3),
+                   UintegerValue (3),
                    MakeUintegerAccessor (&Tcp::m_defaultConnTimeout),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("DefaultConnCount",
                    "Default number of connection attempts (SYN retransmissions) before returning failure",
-                   Uinteger (6),
+                   UintegerValue (6),
                    MakeUintegerAccessor (&Tcp::m_defaultConnCount),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("DefaultDelAckTimeout",
                    "Default timeout value for TCP delayed acks, in seconds",
-                   Double (0.2),
+                   DoubleValue (0.2),
                    MakeDoubleAccessor (&Tcp::m_defaultDelAckTimeout),
                    MakeDoubleChecker<double> ())
     .AddAttribute ("DefaultDelAckCount",
                    "Default number of packets to wait before sending a TCP ack",
-                   Uinteger (2),
+                   UintegerValue (2),
                    MakeUintegerAccessor (&Tcp::m_defaultDelAckCount),
                    MakeUintegerChecker<uint32_t> ())
      ;
--- a/src/routing/global-routing/candidate-queue.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/routing/global-routing/candidate-queue.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -28,19 +28,19 @@
 CandidateQueue::CandidateQueue()
   : m_candidates ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 CandidateQueue::~CandidateQueue()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Clear ();
 }
 
   void
 CandidateQueue::Clear (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   while (!m_candidates.empty ())
     {
       SPFVertex *p = Pop ();
@@ -52,8 +52,7 @@
   void
 CandidateQueue::Push (SPFVertex *vNew)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << vNew);
+  NS_LOG_FUNCTION (this << vNew);
 
   CandidateList_t::iterator i = m_candidates.begin ();  
 
@@ -71,7 +70,7 @@
   SPFVertex *
 CandidateQueue::Pop (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_candidates.empty ())
     {
       return 0;
@@ -85,7 +84,7 @@
   SPFVertex *
 CandidateQueue::Top (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_candidates.empty ())
     {
       return 0;
@@ -97,21 +96,21 @@
   bool
 CandidateQueue::Empty (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_candidates.empty ();
 }
 
   uint32_t
 CandidateQueue::Size (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_candidates.size ();
 }
 
   SPFVertex *
 CandidateQueue::Find (const Ipv4Address addr) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   CandidateList_t::const_iterator i = m_candidates.begin ();
 
   for (; i != m_candidates.end (); i++)
@@ -129,7 +128,7 @@
   void
 CandidateQueue::Reorder (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   std::list<SPFVertex*> temp;
 
   while (!m_candidates.empty ()) {
--- a/src/routing/global-routing/global-route-manager-impl.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/routing/global-routing/global-route-manager-impl.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -54,7 +54,7 @@
   m_parent (0),
   m_children ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 SPFVertex::SPFVertex (GlobalRoutingLSA* lsa) : 
@@ -66,7 +66,7 @@
   m_parent (0),
   m_children ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (lsa->GetLSType () == GlobalRoutingLSA::RouterLSA) 
     {
       NS_LOG_LOGIC ("Setting m_vertexType to VertexRouter");
@@ -81,7 +81,7 @@
 
 SPFVertex::~SPFVertex ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for ( ListOfSPFVertex_t::iterator i = m_children.begin ();
         i != m_children.end ();
         i++)
@@ -97,112 +97,112 @@
   void 
 SPFVertex::SetVertexType (SPFVertex::VertexType type)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_vertexType = type;
 }
 
   SPFVertex::VertexType 
 SPFVertex::GetVertexType (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_vertexType;
 }
 
   void 
 SPFVertex::SetVertexId (Ipv4Address id)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_vertexId = id;
 }
 
   Ipv4Address
 SPFVertex::GetVertexId (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_vertexId;
 }
 
   void 
 SPFVertex::SetLSA (GlobalRoutingLSA* lsa)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_lsa = lsa;
 }
 
   GlobalRoutingLSA* 
 SPFVertex::GetLSA (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_lsa;
 }
 
   void 
 SPFVertex::SetDistanceFromRoot (uint32_t distance)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_distanceFromRoot = distance;
 }
 
   uint32_t
 SPFVertex::GetDistanceFromRoot (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_distanceFromRoot;
 }
 
   void 
 SPFVertex::SetOutgoingTypeId (uint32_t id)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_rootOif = id;
 }
 
   uint32_t 
 SPFVertex::GetOutgoingTypeId (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_rootOif;
 }
 
   void 
 SPFVertex::SetNextHop (Ipv4Address nextHop)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_nextHop = nextHop;
 }
 
   Ipv4Address
 SPFVertex::GetNextHop (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_nextHop;
 }
 
   void
 SPFVertex::SetParent (SPFVertex* parent)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_parent = parent;
 }
 
   SPFVertex* 
 SPFVertex::GetParent (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_parent;
 }
 
   uint32_t 
 SPFVertex::GetNChildren (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_children.size ();
 }
 
   SPFVertex* 
 SPFVertex::GetChild (uint32_t n) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   uint32_t j = 0;
 
   for ( ListOfSPFVertex_t::const_iterator i = m_children.begin ();
@@ -221,7 +221,7 @@
   uint32_t 
 SPFVertex::AddChild (SPFVertex* child)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_children.push_back (child);
   return m_children.size ();
 }
@@ -236,12 +236,12 @@
 :
   m_database ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   LSDBMap_t::iterator i;
   for (i= m_database.begin (); i!= m_database.end (); i++)
     {
@@ -256,7 +256,7 @@
   void
 GlobalRouteManagerLSDB::Initialize ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   LSDBMap_t::iterator i;
   for (i= m_database.begin (); i!= m_database.end (); i++)
     {
@@ -268,14 +268,14 @@
   void
 GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRoutingLSA* lsa)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_database.insert (LSDBPair_t (addr, lsa));
 }
 
   GlobalRoutingLSA*
 GlobalRouteManagerLSDB::GetLSA (Ipv4Address addr) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 //
 // Look up an LSA by its address.
 //
@@ -293,7 +293,7 @@
   GlobalRoutingLSA*
 GlobalRouteManagerLSDB::GetLSAByLinkData (Ipv4Address addr) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 //
 // Look up an LSA by its address.
 //
@@ -325,13 +325,13 @@
 : 
   m_spfroot (0) 
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_lsdb = new GlobalRouteManagerLSDB ();
 }
 
 GlobalRouteManagerImpl::~GlobalRouteManagerImpl ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_lsdb)
     {
       delete m_lsdb;
@@ -341,7 +341,7 @@
   void
 GlobalRouteManagerImpl::DebugUseLsdb (GlobalRouteManagerLSDB* lsdb)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   if (m_lsdb)
     {
       delete m_lsdb;
@@ -359,7 +359,7 @@
   void
 GlobalRouteManagerImpl::SelectRouterNodes () 
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); i++)
     {
       Ptr<Node> node = *i;
@@ -383,7 +383,7 @@
   void
 GlobalRouteManagerImpl::BuildGlobalRoutingDatabase () 
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 //
 // Walk the list of nodes looking for the GlobalRouter Interface.
 //
@@ -464,7 +464,7 @@
   void
 GlobalRouteManagerImpl::InitializeRoutes ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 //
 // Walk the list of nodes in the system.
 //
@@ -504,7 +504,7 @@
   void
 GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   SPFVertex* w = 0;
   GlobalRoutingLSA* w_lsa = 0;
@@ -706,7 +706,7 @@
   GlobalRoutingLinkRecord* l,
   uint32_t distance)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 //
 // If w is a NetworkVertex, l should be null
 /*
@@ -891,7 +891,7 @@
   SPFVertex* w,
   GlobalRoutingLinkRecord* prev_link) 
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   bool skip = true;
   bool found_prev_link = false;
@@ -966,7 +966,7 @@
   void
 GlobalRouteManagerImpl::DebugSPFCalculate (Ipv4Address root)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   SPFCalculate (root);
 }
 
@@ -974,8 +974,7 @@
   void
 GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << root);
+  NS_LOG_FUNCTION (this << root);
 
   SPFVertex *v;
 //
@@ -1124,7 +1123,7 @@
   uint32_t
 GlobalRouteManagerImpl::FindOutgoingTypeId (Ipv4Address a, Ipv4Mask amask)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 //
 // We have an IP address <a> and a vertex ID of the root of the SPF tree.  
 // The question is what interface index does this address correspond to.
@@ -1200,7 +1199,7 @@
   void
 GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   NS_ASSERT_MSG (m_spfroot, 
     "GlobalRouteManagerImpl::SPFIntraAddRouter (): Root pointer not set");
@@ -1317,7 +1316,7 @@
   void
 GlobalRouteManagerImpl::SPFIntraAddTransit (SPFVertex* v)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 
   NS_ASSERT_MSG (m_spfroot, 
     "GlobalRouteManagerImpl::SPFIntraAddTransit (): Root pointer not set");
@@ -1410,7 +1409,7 @@
   void
 GlobalRouteManagerImpl::SPFVertexAddParent (SPFVertex* v)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   v->GetParent ()->AddChild (v);
 }
 
--- a/src/routing/global-routing/global-router-interface.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/routing/global-routing/global-router-interface.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -43,7 +43,7 @@
   m_linkType (Unknown),
   m_metric (0)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 GlobalRoutingLinkRecord::GlobalRoutingLinkRecord (
@@ -57,47 +57,46 @@
   m_linkType (linkType),
   m_metric (metric)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << linkType << linkId << linkData << metric);
+  NS_LOG_FUNCTION (this << linkType << linkId << linkData << metric);
 }
 
 GlobalRoutingLinkRecord::~GlobalRoutingLinkRecord ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
   Ipv4Address
 GlobalRoutingLinkRecord::GetLinkId (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_linkId;
 }
 
   void
 GlobalRoutingLinkRecord::SetLinkId (Ipv4Address addr)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_linkId = addr;
 }
 
   Ipv4Address
 GlobalRoutingLinkRecord::GetLinkData (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_linkData;
 }
 
   void
 GlobalRoutingLinkRecord::SetLinkData (Ipv4Address addr)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_linkData = addr;
 }
 
   GlobalRoutingLinkRecord::LinkType
 GlobalRoutingLinkRecord::GetLinkType (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_linkType;
 }
 
@@ -105,21 +104,21 @@
 GlobalRoutingLinkRecord::SetLinkType (
   GlobalRoutingLinkRecord::LinkType linkType)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_linkType = linkType;
 }
 
   uint16_t
 GlobalRoutingLinkRecord::GetMetric (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_metric;
 }
 
   void
 GlobalRoutingLinkRecord::SetMetric (uint16_t metric)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_metric = metric;
 }
 
@@ -139,7 +138,7 @@
   m_attachedRouters(),
   m_status(GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
 GlobalRoutingLSA::GlobalRoutingLSA (
@@ -155,8 +154,7 @@
   m_attachedRouters(),
   m_status(status)
 {
-  NS_LOG_FUNCTION;
-  NS_LOG_PARAMS (this << status << linkStateId << advertisingRtr);
+  NS_LOG_FUNCTION (this << status << linkStateId << advertisingRtr);
 }
 
 GlobalRoutingLSA::GlobalRoutingLSA (GlobalRoutingLSA& lsa)
@@ -165,7 +163,7 @@
     m_networkLSANetworkMask(lsa.m_networkLSANetworkMask), 
     m_status(lsa.m_status)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_ASSERT_MSG(IsEmpty(), 
     "GlobalRoutingLSA::GlobalRoutingLSA (): Non-empty LSA in constructor");
   CopyLinkRecords (lsa);
@@ -174,7 +172,7 @@
   GlobalRoutingLSA&
 GlobalRoutingLSA::operator= (const GlobalRoutingLSA& lsa)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_lsType = lsa.m_lsType;
   m_linkStateId = lsa.m_linkStateId;
   m_advertisingRtr = lsa.m_advertisingRtr;
@@ -189,7 +187,7 @@
   void
 GlobalRoutingLSA::CopyLinkRecords (const GlobalRoutingLSA& lsa)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for (ListOfLinkRecords_t::const_iterator i = lsa.m_linkRecords.begin ();
        i != lsa.m_linkRecords.end (); 
        i++)
@@ -211,14 +209,14 @@
 
 GlobalRoutingLSA::~GlobalRoutingLSA()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   ClearLinkRecords ();
 }
 
   void
 GlobalRoutingLSA::ClearLinkRecords(void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin ();
         i != m_linkRecords.end (); 
         i++)
@@ -238,7 +236,7 @@
   uint32_t
 GlobalRoutingLSA::AddLinkRecord (GlobalRoutingLinkRecord* lr)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_linkRecords.push_back (lr);
   return m_linkRecords.size ();
 }
@@ -246,14 +244,14 @@
   uint32_t
 GlobalRoutingLSA::GetNLinkRecords (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_linkRecords.size ();
 }
 
   GlobalRoutingLinkRecord *
 GlobalRoutingLSA::GetLinkRecord (uint32_t n) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   uint32_t j = 0;
   for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
         i != m_linkRecords.end (); 
@@ -271,77 +269,77 @@
   bool
 GlobalRoutingLSA::IsEmpty (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_linkRecords.size () == 0;
 }
 
   GlobalRoutingLSA::LSType
 GlobalRoutingLSA::GetLSType (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_lsType;
 }
 
   void 
 GlobalRoutingLSA::SetLSType (GlobalRoutingLSA::LSType typ) 
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_lsType = typ;
 }
 
   Ipv4Address
 GlobalRoutingLSA::GetLinkStateId (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_linkStateId;
 }
 
   void
 GlobalRoutingLSA::SetLinkStateId (Ipv4Address addr)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_linkStateId = addr;
 }
 
   Ipv4Address
 GlobalRoutingLSA::GetAdvertisingRouter (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_advertisingRtr;
 }
 
   void
 GlobalRoutingLSA::SetAdvertisingRouter (Ipv4Address addr)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_advertisingRtr = addr;
 }
 
   void 
 GlobalRoutingLSA::SetNetworkLSANetworkMask (Ipv4Mask mask)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_networkLSANetworkMask = mask;
 }
 
   Ipv4Mask 
 GlobalRoutingLSA::GetNetworkLSANetworkMask (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_networkLSANetworkMask;
 }
 
   GlobalRoutingLSA::SPFStatus
 GlobalRoutingLSA::GetStatus (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_status;
 }
 
   uint32_t 
 GlobalRoutingLSA::AddAttachedRouter (Ipv4Address addr)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_attachedRouters.push_back (addr);
   return m_attachedRouters.size ();
 }
@@ -349,14 +347,14 @@
   uint32_t 
 GlobalRoutingLSA::GetNAttachedRouters (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_attachedRouters.size (); 
 }
 
   Ipv4Address 
 GlobalRoutingLSA::GetAttachedRouter (uint32_t n) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   uint32_t j = 0;
   for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin ();
         i != m_attachedRouters.end (); 
@@ -375,7 +373,7 @@
   void
 GlobalRoutingLSA::SetStatus (GlobalRoutingLSA::SPFStatus status)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_status = status;
 }
 
@@ -444,27 +442,27 @@
 GlobalRouter::GlobalRouter ()
   : m_LSAs()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_routerId.Set(GlobalRouteManager::AllocateRouterId ());
 }
 
 GlobalRouter::~GlobalRouter ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   ClearLSAs();
 }
 
 void
 GlobalRouter::DoDispose ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Object::DoDispose ();
 }
 
   void
 GlobalRouter::ClearLSAs ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   for ( ListOfLSAs_t::iterator i = m_LSAs.begin ();
         i != m_LSAs.end (); 
         i++)
@@ -484,7 +482,7 @@
   Ipv4Address
 GlobalRouter::GetRouterId (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_routerId;
 }
 
@@ -495,7 +493,7 @@
   uint32_t 
 GlobalRouter::DiscoverLSAs (void)
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Ptr<Node> node = GetObject<Node> ();
   NS_LOG_LOGIC("For node " << node->GetId () );
   NS_ASSERT_MSG(node, 
@@ -765,7 +763,7 @@
   uint32_t 
 GlobalRouter::GetNumLSAs (void) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   return m_LSAs.size ();
 }
 
@@ -775,7 +773,7 @@
   bool
 GlobalRouter::GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_ASSERT_MSG(lsa.IsEmpty(), "GlobalRouter::GetLSA (): Must pass empty LSA");
 //
 // All of the work was done in GetNumLSAs.  All we have to do here is to
@@ -805,7 +803,7 @@
   Ptr<NetDevice>
 GlobalRouter::GetAdjacent(Ptr<NetDevice> nd, Ptr<Channel> ch) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   NS_ASSERT_MSG(ch->GetNDevices() == 2, 
     "GlobalRouter::GetAdjacent (): Channel with other than two devices");
 //
@@ -841,7 +839,7 @@
   uint32_t
 GlobalRouter::FindIfIndexForDevice(Ptr<Node> node, Ptr<NetDevice> nd) const
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
   NS_ASSERT_MSG(ipv4, "QI for <Ipv4> interface failed");
   for (uint32_t i = 0; i < ipv4->GetNInterfaces(); ++i )
--- a/src/routing/olsr/olsr-agent-impl.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/routing/olsr/olsr-agent-impl.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -157,19 +157,19 @@
     .SetParent<Agent> ()
     .AddConstructor<AgentImpl> ()
     .AddAttribute ("HelloInterval", "XXX",
-                   OLSR_HELLO_INTERVAL,
+                   TimeValue (OLSR_HELLO_INTERVAL),
                    MakeTimeAccessor (&AgentImpl::m_helloInterval),
                    MakeTimeChecker ())
     .AddAttribute ("TcInterval", "XXX",
-                   OLSR_TC_INTERVAL,
+                   TimeValue (OLSR_TC_INTERVAL),
                    MakeTimeAccessor (&AgentImpl::m_tcInterval),
                    MakeTimeChecker ())
     .AddAttribute ("MidInterval", "XXX",
-                   OLSR_MID_INTERVAL,
+                   TimeValue (OLSR_MID_INTERVAL),
                    MakeTimeAccessor (&AgentImpl::m_midInterval),
                    MakeTimeChecker ())
     .AddAttribute ("Willingness", "XXX",
-                   Uinteger (OLSR_WILL_DEFAULT),
+                   UintegerValue (OLSR_WILL_DEFAULT),
                    MakeUintegerAccessor (&AgentImpl::m_willingness),
                    MakeUintegerChecker<uint8_t> ())
     .AddTraceSource ("Rx", "Receive OLSR packet.",
@@ -572,12 +572,15 @@
           // (not in RFC but I think is needed: remove the 2-hop
           // neighbors reachable by the MPR from N2)
           for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
-               twoHopNeigh != N2.end (); twoHopNeigh++)
+               twoHopNeigh != N2.end (); )
             {
               if (twoHopNeigh->neighborMainAddr == neighbor->neighborMainAddr)
                 {
                   twoHopNeigh = N2.erase (twoHopNeigh);
-                  twoHopNeigh--;
+                }
+              else
+                {
+                  twoHopNeigh++;
                 }
             }
         }
@@ -617,12 +620,15 @@
     }
   // Remove the nodes from N2 which are now covered by a node in the MPR set.
   for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
-       twoHopNeigh != N2.end (); twoHopNeigh++)
+       twoHopNeigh != N2.end (); )
     {
       if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
         {
           twoHopNeigh = N2.erase (twoHopNeigh);
-          twoHopNeigh--;
+        }
+      else
+        {
+          twoHopNeigh++;
         }
     }
 	
@@ -699,12 +705,15 @@
         {
           mprSet.insert (max->neighborMainAddr);
           for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
-               twoHopNeigh != N2.end (); twoHopNeigh++)
+               twoHopNeigh != N2.end (); )
             {
               if (twoHopNeigh->neighborMainAddr == max->neighborMainAddr)
                 {
                   twoHopNeigh = N2.erase (twoHopNeigh);
-                  twoHopNeigh--;
+                }
+              else
+                {
+                  twoHopNeigh++;
                 }
             }
         }
--- a/src/routing/olsr/olsr-state.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/routing/olsr/olsr-state.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -64,12 +64,15 @@
 OlsrState::EraseMprSelectorTuples (const Ipv4Address &mainAddr)
 {
   for (MprSelectorSet::iterator it = m_mprSelectorSet.begin ();
-       it != m_mprSelectorSet.end (); it++)
+       it != m_mprSelectorSet.end ();)
     {
       if (it->mainAddr == mainAddr)
         {
           it = m_mprSelectorSet.erase (it);
-          it--;
+        }
+      else
+        {
+          it++;
         }
     }
 }
@@ -203,15 +206,18 @@
                                       const Ipv4Address &twoHopNeighborAddr)
 {
   for (TwoHopNeighborSet::iterator it = m_twoHopNeighborSet.begin ();
-       it != m_twoHopNeighborSet.end (); it++)
+       it != m_twoHopNeighborSet.end ();)
     {
       if (it->neighborMainAddr == neighborMainAddr
           && it->twoHopNeighborAddr == twoHopNeighborAddr)
         {
           it = m_twoHopNeighborSet.erase (it);
-          it--; // FIXME: is this correct in the case 'it' pointed to the first element?
           m_modified = true;
         }
+      else
+        {
+          it++;
+        }
     }
 }
 
@@ -219,13 +225,17 @@
 OlsrState::EraseTwoHopNeighborTuples (const Ipv4Address &neighborMainAddr)
 {
   for (TwoHopNeighborSet::iterator it = m_twoHopNeighborSet.begin ();
-       it != m_twoHopNeighborSet.end (); it++)
+       it != m_twoHopNeighborSet.end ();)
     {
-      if (it->neighborMainAddr == neighborMainAddr) {
-        it = m_twoHopNeighborSet.erase (it);
-        it--;
-        m_modified = true;
-      }
+      if (it->neighborMainAddr == neighborMainAddr)
+        {
+          it = m_twoHopNeighborSet.erase (it);
+          m_modified = true;
+        }
+      else
+        {
+          it++;
+        }
     }
 }
 
@@ -385,14 +395,17 @@
 OlsrState::EraseOlderTopologyTuples (const Ipv4Address &lastAddr, uint16_t ansn)
 {
   for (TopologySet::iterator it = m_topologySet.begin();
-       it != m_topologySet.end(); it++)
+       it != m_topologySet.end();)
     {
       if (it->lastAddr == lastAddr && it->sequenceNumber < ansn)
         {
           it = m_topologySet.erase (it);
-          it--;
           m_modified = true;
         }
+      else
+        {
+          it++;
+        }
     }
 }
 
--- a/src/routing/olsr/routing-table.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/routing/olsr/routing-table.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -40,7 +40,7 @@
 void
 RoutingTable::Clear ()
 {
-  NS_LOG_FUNCTION;
+  NS_LOG_FUNCTION_NOARGS ();
   m_table.clear ();
 }
 
@@ -183,14 +183,7 @@
                         uint32_t interface,
                         uint32_t distance)
 {
-  NS_LOG_PARAMS_BEGIN ();
-  NS_LOG_PARAM (this);
-  NS_LOG_PARAM (dest);
-  NS_LOG_PARAM (next);
-  NS_LOG_PARAM (interface);
-  NS_LOG_PARAM (distance);
-  NS_LOG_PARAM (m_mainAddress);
-  NS_LOG_PARAMS_END ();
+  NS_LOG_FUNCTION (this << dest << next << interface << distance << m_mainAddress);
 
   NS_ASSERT (distance > 0);
 
@@ -209,14 +202,7 @@
                         Ipv4Address const &interfaceAddress,
                         uint32_t distance)
 {
-  NS_LOG_PARAMS_BEGIN ();
-  NS_LOG_PARAM (this);
-  NS_LOG_PARAM (dest);
-  NS_LOG_PARAM (next);
-  NS_LOG_PARAM (interfaceAddress);
-  NS_LOG_PARAM (distance);
-  NS_LOG_PARAM (m_mainAddress);
-  NS_LOG_PARAMS_END ();
+  NS_LOG_FUNCTION (this << dest << next << interfaceAddress << distance << m_mainAddress);
 
   NS_ASSERT (distance > 0);
   NS_ASSERT (m_ipv4);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/heap-scheduler.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -0,0 +1,263 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * Copyright (c) 2005 Mathieu Lacage
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ *
+ * This code started as a c++ translation of a java-based code written in 2005
+ * to implement a heap sort. Which explains the "Copyright Mathieu Lacage" at the
+ * top of this file.
+ *
+ * What is smart about this code ?
+ *  - it does not use the index 0 in the array to avoid having to convert
+ *    C-style array indexes (which start at zero) and heap-style indexes
+ *    (which start at 1). This is why _all_ indexes start at 1, and that
+ *    the index of the root is 1.
+ *  - It uses a slightly non-standard while loop for top-down heapify
+ *    to move one if statement out of the loop.
+ */
+
+#include "heap-scheduler.h"
+#include "event-impl.h"
+#include "ns3/assert.h"
+
+#include <string>
+#define noTRACE_HEAP 1
+
+#ifdef TRACE_HEAP
+#include <iostream>
+# define TRACE(x) \
+std::cout << "HEAP TRACE " << x << std::endl;
+#else /* TRACE_HEAP */
+# define TRACE(format,...)
+#endif /* TRACE_HEAP */
+
+
+
+
+namespace ns3 {
+
+
+HeapScheduler::HeapScheduler ()
+{
+  // we purposedly waste an item at the start of
+  // the array to make sure the indexes in the
+  // array start at one.
+  Scheduler::EventKey emptyKey = {0,0};
+  m_heap.push_back (std::make_pair (static_cast<EventImpl *>(0), emptyKey));
+}
+
+HeapScheduler::~HeapScheduler ()
+{}
+
+uint32_t 
+HeapScheduler::Parent (uint32_t id) const
+{
+  return id / 2;
+}
+uint32_t 
+HeapScheduler::Sibling (uint32_t id) const
+{
+  return id + 1;
+}
+uint32_t 
+HeapScheduler::LeftChild (uint32_t id) const
+{
+  return id * 2;
+}
+uint32_t 
+HeapScheduler::RightChild (uint32_t id) const
+{
+  return id * 2 + 1;
+}
+
+uint32_t
+HeapScheduler::Root (void) const
+{
+  return 1;
+}
+
+bool
+HeapScheduler::IsRoot (uint32_t id) const
+{
+  return (id == Root ())?true:false;
+}
+
+uint32_t
+HeapScheduler::Last (void) const
+{
+  return m_heap.size () - 1;
+}
+
+
+bool
+HeapScheduler::IsBottom (uint32_t id) const
+{
+  return (id >= m_heap.size ())?true:false;
+}
+
+void
+HeapScheduler::Exch (uint32_t a, uint32_t b) 
+{
+  NS_ASSERT (b < m_heap.size () && a < m_heap.size ());
+  TRACE ("Exch " << a << ", " << b);
+  std::pair<EventImpl*, Scheduler::EventKey> tmp (m_heap[a]);
+  m_heap[a] = m_heap[b];
+  m_heap[b] = tmp;
+}
+
+bool
+HeapScheduler::IsLowerStrictly (Scheduler::EventKey const*a, Scheduler::EventKey const*b) const
+{
+  if (a->m_ts < b->m_ts)
+    {
+      return true;
+    }
+  else if (a->m_ts > b->m_ts)
+    {
+      return false;
+    } 
+  else if (a->m_uid < b->m_uid)
+    {
+      return true;
+    }
+  else
+    {
+      return false;
+    }
+}
+
+bool
+HeapScheduler::IsLessStrictly (uint32_t a, uint32_t b) const
+{
+  return IsLowerStrictly (&m_heap[a].second, &m_heap[b].second);
+}
+
+uint32_t 
+HeapScheduler::Smallest (uint32_t a, uint32_t b) const
+{
+  return IsLessStrictly (a,b)?a:b;
+}
+
+bool
+HeapScheduler::IsEmpty (void) const
+{
+  return (m_heap.size () == 1)?true:false;
+}
+
+void
+HeapScheduler::BottomUp (void)
+{
+  uint32_t index = Last ();
+  while (!IsRoot (index) && 
+         IsLessStrictly (index, Parent (index))) 
+    { 
+      Exch(index, Parent (index)); 
+      index = Parent (index); 
+    }
+}
+
+void
+HeapScheduler::TopDown (uint32_t start)
+{
+  uint32_t index = start;
+  uint32_t right = RightChild (index);
+  while (!IsBottom (right)) 
+    {
+      uint32_t left = LeftChild (index);
+      uint32_t tmp = Smallest (left, right);
+      if (IsLessStrictly (index, tmp)) 
+        {
+          return;
+        }
+      Exch (index, tmp);
+      index = tmp;
+      right = RightChild (index);
+    }
+  if (IsBottom (index)) 
+    {
+      return;
+    }
+  NS_ASSERT (!IsBottom (index));
+  uint32_t left = LeftChild (index);
+  if (IsBottom (left)) 
+    {
+      return;
+    }
+  if (IsLessStrictly (index, left)) 
+    {
+      return;
+    }
+  Exch (index, left);
+}
+
+
+void
+HeapScheduler::Insert (const EventId &id)
+{
+  // acquire single ref
+  EventImpl *event = id.PeekEventImpl ();
+  event->Ref ();
+  Scheduler::EventKey key;
+  key.m_ts = id.GetTs ();
+  key.m_uid = id.GetUid ();
+  m_heap.push_back (std::make_pair (event, key));
+  BottomUp ();
+}
+
+EventId
+HeapScheduler::PeekNext (void) const
+{
+  std::pair<EventImpl *,Scheduler::EventKey> next = m_heap[Root ()];
+  return EventId (next.first, next.second.m_ts, next.second.m_uid);
+}
+EventId
+HeapScheduler::RemoveNext (void)
+{
+  std::pair<EventImpl *,Scheduler::EventKey> next = m_heap[Root ()];
+  Exch (Root (), Last ());
+  m_heap.pop_back ();
+  TopDown (Root ());
+  return EventId (Ptr<EventImpl> (next.first, false), next.second.m_ts, next.second.m_uid);
+}
+
+
+bool
+HeapScheduler::Remove (const EventId &id)
+{
+  uint32_t uid = id.GetUid ();
+  for (uint32_t i = 1; i < m_heap.size (); i++)
+    {
+      if (uid == m_heap[i].second.m_uid)
+        {
+          NS_ASSERT (m_heap[i].first == id.PeekEventImpl ());
+          std::pair<EventImpl *,Scheduler::EventKey> next = m_heap[i];
+          // release single ref
+          next.first->Unref ();
+          Exch (i, Last ());
+          m_heap.pop_back ();
+          TopDown (i);
+          return true;
+        }
+    }
+  NS_ASSERT (false);
+  // quiet compiler
+  return false;
+}
+
+}; // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/heap-scheduler.h	Tue Apr 22 21:19:39 2008 -0700
@@ -0,0 +1,69 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef SCHEDULER_HEAP_H
+#define SCHEDULER_HEAP_H
+
+#include "scheduler.h"
+#include <stdint.h>
+#include <vector>
+
+namespace ns3 {
+
+class EventHolder;
+
+class HeapScheduler : public Scheduler {
+public:
+  HeapScheduler ();
+  virtual ~HeapScheduler ();
+
+  virtual void Insert (const EventId &id);
+  virtual bool IsEmpty (void) const;
+  virtual EventId PeekNext (void) const;
+  virtual EventId RemoveNext (void);
+  virtual bool Remove (const EventId &ev);
+
+private:
+  typedef std::vector<std::pair<EventImpl *, Scheduler::EventKey> > BinaryHeap;
+
+  inline uint32_t Parent (uint32_t id) const;
+  uint32_t Sibling (uint32_t id) const;
+  inline uint32_t LeftChild (uint32_t id) const;
+  inline uint32_t RightChild (uint32_t id) const;
+  inline uint32_t Root (void) const;
+  /* Return the position in the array of the last element included in it. */
+  uint32_t Last (void) const;
+  inline bool IsRoot (uint32_t id) const;
+  inline bool IsBottom (uint32_t id) const;
+  inline bool IsLowerStrictly (Scheduler::EventKey const*a, Scheduler::EventKey const*b) const;
+  inline bool IsLessStrictly (uint32_t a, uint32_t b) const;
+  inline uint32_t Smallest (uint32_t a, uint32_t b) const;
+
+  inline void Exch (uint32_t a, uint32_t b);
+  void BottomUp (void);
+  void TopDown (uint32_t start);
+
+  BinaryHeap m_heap;
+};
+
+}; // namespace ns3
+
+
+#endif /* SCHEDULER_HEAP_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/list-scheduler.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -0,0 +1,110 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "list-scheduler.h"
+#include "event-impl.h"
+#include <utility>
+#include <string>
+#include "ns3/assert.h"
+
+namespace ns3 {
+
+
+ListScheduler::ListScheduler ()
+{}
+ListScheduler::~ListScheduler ()
+{}
+
+bool 
+ListScheduler::IsLower (Scheduler::EventKey const*a, Scheduler::EventKey const*b) const
+{
+  if (a->m_ts < b->m_ts)
+    {
+      return true;
+    }
+  else if (a->m_ts == b->m_ts &&
+           a->m_uid < b->m_uid)
+    {
+      return true;
+    }
+  else
+    {
+      return false;
+    }
+}
+
+void
+ListScheduler::Insert (const EventId &id)
+{
+  Scheduler::EventKey key;
+  // acquire refcount on EventImpl
+  EventImpl *event = id.PeekEventImpl ();
+  event->Ref ();
+  key.m_ts = id.GetTs ();
+  key.m_uid = id.GetUid ();
+  for (EventsI i = m_events.begin (); i != m_events.end (); i++) 
+    {
+      if (IsLower (&key, &i->second))
+        {
+          m_events.insert (i, std::make_pair (event, key));
+          return;
+        }
+    }
+  m_events.push_back (std::make_pair (event, key));
+}
+bool 
+ListScheduler::IsEmpty (void) const
+{
+  return m_events.empty ();
+}
+EventId
+ListScheduler::PeekNext (void) const
+{
+  std::pair<EventImpl *, EventKey> next = m_events.front ();
+  return EventId (next.first, next.second.m_ts, next.second.m_uid);
+}
+
+EventId
+ListScheduler::RemoveNext (void)
+{
+  std::pair<EventImpl *, EventKey> next = m_events.front ();
+  m_events.pop_front ();
+  return EventId (Ptr<EventImpl> (next.first,false), next.second.m_ts, next.second.m_uid);
+}
+
+bool
+ListScheduler::Remove (const EventId &id)
+{
+  for (EventsI i = m_events.begin (); i != m_events.end (); i++) 
+    {
+      if (i->second.m_uid == id.GetUid ())
+        {
+          NS_ASSERT (id.PeekEventImpl () == i->first);
+          // release single acquire ref.
+          i->first->Unref ();
+          m_events.erase (i);
+          return true;
+        }
+    }
+  NS_ASSERT (false);
+  return false;
+}
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/list-scheduler.h	Tue Apr 22 21:19:39 2008 -0700
@@ -0,0 +1,56 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef SCHEDULER_LIST_H
+#define SCHEDULER_LIST_H
+
+#include "scheduler.h"
+#include "event-id.h"
+#include <list>
+#include <utility>
+#include <stdint.h>
+
+namespace ns3 {
+
+class EventImpl;
+
+class ListScheduler : public Scheduler {
+ public:
+  ListScheduler ();
+  virtual ~ListScheduler ();
+
+  virtual void Insert (const EventId &id);
+  virtual bool IsEmpty (void) const;
+  virtual EventId PeekNext (void) const;
+  virtual EventId RemoveNext (void);
+  virtual bool Remove (const EventId &ev);
+
+ private:
+  inline bool IsLower (Scheduler::EventKey const*a, Scheduler::EventKey const*b) const;
+
+  typedef std::list<std::pair<EventImpl*, EventKey> > Events;
+  typedef std::list<std::pair<EventImpl*, EventKey> >::iterator EventsI;
+  Events m_events;
+};
+
+}; // namespace ns3
+
+
+#endif /* SCHEDULER_LIST_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/map-scheduler.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -0,0 +1,124 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * The idea to use a std c++ map came from GTNetS
+ */
+
+#include "map-scheduler.h"
+#include "event-impl.h"
+#include "ns3/assert.h"
+#include <string>
+
+#define noTRACE_MAP 1
+
+#ifdef TRACE_MAP
+#include <iostream>
+# define TRACE(x) \
+std::cout << "MAP TRACE " << x << std::endl;
+#else /* TRACE_MAP */
+# define TRACE(format,...)
+#endif /* TRACE_MAP */
+
+
+namespace ns3 {
+
+MapScheduler::MapScheduler ()
+{}
+MapScheduler::~MapScheduler ()
+{}
+
+/* Note the invariants which this function must provide:
+ * - irreflexibility: f (x,x) is false)
+ * - antisymmetry: f(x,y) = !f(y,x)
+ * - transitivity: f(x,y) and f(y,z) => f(x,z)
+ */
+bool
+MapScheduler::EventKeyCompare::operator () (struct EventKey const&a, struct EventKey const&b)
+{
+  if (a.m_ts < b.m_ts) 
+    {
+      return true;
+    } 
+  else if (a.m_ts > b.m_ts)
+    {
+      return false;
+    } 
+  else if (a.m_uid < b.m_uid)
+    {
+      return true;
+    }
+  else 
+    {
+      return false;
+    }
+}
+
+
+
+void
+MapScheduler::Insert (const EventId &id)
+{
+  // acquire a single ref
+  EventImpl *event = id.PeekEventImpl ();
+  event->Ref ();
+  Scheduler::EventKey key;
+  key.m_ts = id.GetTs ();
+  key.m_uid = id.GetUid ();
+  std::pair<EventMapI,bool> result;
+  result = m_list.insert (std::make_pair (key, event));
+  NS_ASSERT (result.second);
+}
+
+bool
+MapScheduler::IsEmpty (void) const
+{
+  return m_list.empty ();
+}
+
+EventId
+MapScheduler::PeekNext (void) const
+{
+  EventMapCI i = m_list.begin ();
+  NS_ASSERT (i != m_list.end ());
+  
+  return EventId (i->second, i->first.m_ts, i->first.m_uid);
+}
+EventId
+MapScheduler::RemoveNext (void)
+{
+  EventMapI i = m_list.begin ();
+  std::pair<Scheduler::EventKey, EventImpl*> next = *i;
+  m_list.erase (i);
+  return EventId (Ptr<EventImpl> (next.second, false), next.first.m_ts, next.first.m_uid);
+}
+
+bool
+MapScheduler::Remove (const EventId &id)
+{
+  Scheduler::EventKey key;
+  key.m_ts = id.GetTs ();
+  key.m_uid = id.GetUid ();
+  EventMapI i = m_list.find (key);
+  NS_ASSERT (i->second == id.PeekEventImpl ());
+  // release single ref.
+  i->second->Unref ();
+  m_list.erase (i);
+  return true;
+}
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/map-scheduler.h	Tue Apr 22 21:19:39 2008 -0700
@@ -0,0 +1,61 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef SCHEDULER_MAP_H
+#define SCHEDULER_MAP_H
+
+#include "scheduler.h"
+#include <stdint.h>
+#include <map>
+#include <utility>
+
+namespace ns3 {
+
+class EventImpl;
+
+class MapScheduler : public Scheduler {
+public:
+  MapScheduler ();
+  virtual ~MapScheduler ();
+
+  virtual void Insert (const EventId &id);
+  virtual bool IsEmpty (void) const;
+  virtual EventId PeekNext (void) const;
+  virtual EventId RemoveNext (void);
+  virtual bool Remove (const EventId &ev);
+private:
+
+  class EventKeyCompare {
+  public:
+    bool operator () (struct EventKey const&a, struct EventKey const&b);
+  };
+
+  typedef std::map<Scheduler::EventKey, EventImpl*, MapScheduler::EventKeyCompare> EventMap;
+  typedef std::map<Scheduler::EventKey, EventImpl*, MapScheduler::EventKeyCompare>::iterator EventMapI;
+  typedef std::map<Scheduler::EventKey, EventImpl*, MapScheduler::EventKeyCompare>::const_iterator EventMapCI;
+
+
+  EventMap m_list;
+};
+
+}; // namespace ns3
+
+
+#endif /* SCHEDULER_MAP_H */
--- a/src/simulator/nstime.h	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/simulator/nstime.h	Tue Apr 22 21:19:39 2008 -0700
@@ -274,6 +274,7 @@
 template <int N1, int N2>
 TimeUnit<N1-N2> operator / (TimeUnit<N1> const &lhs, TimeUnit<N2> const &rhs)
 {
+  NS_ASSERT (rhs.GetHighPrecision ().GetDouble () != 0);
   HighPrecision retval = lhs.GetHighPrecision ();
   retval.Div (rhs.GetHighPrecision ());
   return TimeUnit<N1-N2> (retval);
@@ -436,8 +437,6 @@
   static uint64_t UnitsToTimestep (uint64_t unitValue, 
                                    uint64_t unitFactor);
 
-  TimeUnit (Attribute value);
-  operator Attribute () const;
 private:
   HighPrecision m_data;
 
@@ -669,6 +668,12 @@
 typedef TimeUnit<-1> TimeInvert;
 typedef TimeUnit<2> TimeSquare;
 
+/**
+ * \class ns3::TimeValue
+ * \brief hold objects of type ns3::Time
+ */
+
+
 ATTRIBUTE_ACCESSOR_DEFINE (Time);
 ATTRIBUTE_VALUE_DEFINE (Time);
 ATTRIBUTE_CHECKER_DEFINE (Time);
--- a/src/simulator/scheduler-heap.cc	Tue Apr 22 21:18:04 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,263 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * Copyright (c) 2005 Mathieu Lacage
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- *
- * This code started as a c++ translation of a java-based code written in 2005
- * to implement a heap sort. Which explains the "Copyright Mathieu Lacage" at the
- * top of this file.
- *
- * What is smart about this code ?
- *  - it does not use the index 0 in the array to avoid having to convert
- *    C-style array indexes (which start at zero) and heap-style indexes
- *    (which start at 1). This is why _all_ indexes start at 1, and that
- *    the index of the root is 1.
- *  - It uses a slightly non-standard while loop for top-down heapify
- *    to move one if statement out of the loop.
- */
-
-#include "scheduler-heap.h"
-#include "event-impl.h"
-#include "ns3/assert.h"
-
-#include <string>
-#define noTRACE_HEAP 1
-
-#ifdef TRACE_HEAP
-#include <iostream>
-# define TRACE(x) \
-std::cout << "HEAP TRACE " << x << std::endl;
-#else /* TRACE_HEAP */
-# define TRACE(format,...)
-#endif /* TRACE_HEAP */
-
-
-
-
-namespace ns3 {
-
-
-SchedulerHeap::SchedulerHeap ()
-{
-  // we purposedly waste an item at the start of
-  // the array to make sure the indexes in the
-  // array start at one.
-  Scheduler::EventKey emptyKey = {0,0};
-  m_heap.push_back (std::make_pair (static_cast<EventImpl *>(0), emptyKey));
-}
-
-SchedulerHeap::~SchedulerHeap ()
-{}
-
-uint32_t 
-SchedulerHeap::Parent (uint32_t id) const
-{
-  return id / 2;
-}
-uint32_t 
-SchedulerHeap::Sibling (uint32_t id) const
-{
-  return id + 1;
-}
-uint32_t 
-SchedulerHeap::LeftChild (uint32_t id) const
-{
-  return id * 2;
-}
-uint32_t 
-SchedulerHeap::RightChild (uint32_t id) const
-{
-  return id * 2 + 1;
-}
-
-uint32_t
-SchedulerHeap::Root (void) const
-{
-  return 1;
-}
-
-bool
-SchedulerHeap::IsRoot (uint32_t id) const
-{
-  return (id == Root ())?true:false;
-}
-
-uint32_t
-SchedulerHeap::Last (void) const
-{
-  return m_heap.size () - 1;
-}
-
-
-bool
-SchedulerHeap::IsBottom (uint32_t id) const
-{
-  return (id >= m_heap.size ())?true:false;
-}
-
-void
-SchedulerHeap::Exch (uint32_t a, uint32_t b) 
-{
-  NS_ASSERT (b < m_heap.size () && a < m_heap.size ());
-  TRACE ("Exch " << a << ", " << b);
-  std::pair<EventImpl*, Scheduler::EventKey> tmp (m_heap[a]);
-  m_heap[a] = m_heap[b];
-  m_heap[b] = tmp;
-}
-
-bool
-SchedulerHeap::IsLowerStrictly (Scheduler::EventKey const*a, Scheduler::EventKey const*b) const
-{
-  if (a->m_ts < b->m_ts)
-    {
-      return true;
-    }
-  else if (a->m_ts > b->m_ts)
-    {
-      return false;
-    } 
-  else if (a->m_uid < b->m_uid)
-    {
-      return true;
-    }
-  else
-    {
-      return false;
-    }
-}
-
-bool
-SchedulerHeap::IsLessStrictly (uint32_t a, uint32_t b) const
-{
-  return IsLowerStrictly (&m_heap[a].second, &m_heap[b].second);
-}
-
-uint32_t 
-SchedulerHeap::Smallest (uint32_t a, uint32_t b) const
-{
-  return IsLessStrictly (a,b)?a:b;
-}
-
-bool
-SchedulerHeap::IsEmpty (void) const
-{
-  return (m_heap.size () == 1)?true:false;
-}
-
-void
-SchedulerHeap::BottomUp (void)
-{
-  uint32_t index = Last ();
-  while (!IsRoot (index) && 
-         IsLessStrictly (index, Parent (index))) 
-    { 
-      Exch(index, Parent (index)); 
-      index = Parent (index); 
-    }
-}
-
-void
-SchedulerHeap::TopDown (uint32_t start)
-{
-  uint32_t index = start;
-  uint32_t right = RightChild (index);
-  while (!IsBottom (right)) 
-    {
-      uint32_t left = LeftChild (index);
-      uint32_t tmp = Smallest (left, right);
-      if (IsLessStrictly (index, tmp)) 
-        {
-          return;
-        }
-      Exch (index, tmp);
-      index = tmp;
-      right = RightChild (index);
-    }
-  if (IsBottom (index)) 
-    {
-      return;
-    }
-  NS_ASSERT (!IsBottom (index));
-  uint32_t left = LeftChild (index);
-  if (IsBottom (left)) 
-    {
-      return;
-    }
-  if (IsLessStrictly (index, left)) 
-    {
-      return;
-    }
-  Exch (index, left);
-}
-
-
-void
-SchedulerHeap::Insert (const EventId &id)
-{
-  // acquire single ref
-  EventImpl *event = id.PeekEventImpl ();
-  event->Ref ();
-  Scheduler::EventKey key;
-  key.m_ts = id.GetTs ();
-  key.m_uid = id.GetUid ();
-  m_heap.push_back (std::make_pair (event, key));
-  BottomUp ();
-}
-
-EventId
-SchedulerHeap::PeekNext (void) const
-{
-  std::pair<EventImpl *,Scheduler::EventKey> next = m_heap[Root ()];
-  return EventId (next.first, next.second.m_ts, next.second.m_uid);
-}
-EventId
-SchedulerHeap::RemoveNext (void)
-{
-  std::pair<EventImpl *,Scheduler::EventKey> next = m_heap[Root ()];
-  Exch (Root (), Last ());
-  m_heap.pop_back ();
-  TopDown (Root ());
-  return EventId (Ptr<EventImpl> (next.first, false), next.second.m_ts, next.second.m_uid);
-}
-
-
-bool
-SchedulerHeap::Remove (const EventId &id)
-{
-  uint32_t uid = id.GetUid ();
-  for (uint32_t i = 1; i < m_heap.size (); i++)
-    {
-      if (uid == m_heap[i].second.m_uid)
-        {
-          NS_ASSERT (m_heap[i].first == id.PeekEventImpl ());
-          std::pair<EventImpl *,Scheduler::EventKey> next = m_heap[i];
-          // release single ref
-          next.first->Unref ();
-          Exch (i, Last ());
-          m_heap.pop_back ();
-          TopDown (i);
-          return true;
-        }
-    }
-  NS_ASSERT (false);
-  // quiet compiler
-  return false;
-}
-
-}; // namespace ns3
-
--- a/src/simulator/scheduler-heap.h	Tue Apr 22 21:18:04 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef SCHEDULER_HEAP_H
-#define SCHEDULER_HEAP_H
-
-#include "scheduler.h"
-#include <stdint.h>
-#include <vector>
-
-namespace ns3 {
-
-class EventHolder;
-
-class SchedulerHeap : public Scheduler {
-public:
-  SchedulerHeap ();
-  virtual ~SchedulerHeap ();
-
-  virtual void Insert (const EventId &id);
-  virtual bool IsEmpty (void) const;
-  virtual EventId PeekNext (void) const;
-  virtual EventId RemoveNext (void);
-  virtual bool Remove (const EventId &ev);
-
-private:
-  typedef std::vector<std::pair<EventImpl *, Scheduler::EventKey> > BinaryHeap;
-
-  inline uint32_t Parent (uint32_t id) const;
-  uint32_t Sibling (uint32_t id) const;
-  inline uint32_t LeftChild (uint32_t id) const;
-  inline uint32_t RightChild (uint32_t id) const;
-  inline uint32_t Root (void) const;
-  /* Return the position in the array of the last element included in it. */
-  uint32_t Last (void) const;
-  inline bool IsRoot (uint32_t id) const;
-  inline bool IsBottom (uint32_t id) const;
-  inline bool IsLowerStrictly (Scheduler::EventKey const*a, Scheduler::EventKey const*b) const;
-  inline bool IsLessStrictly (uint32_t a, uint32_t b) const;
-  inline uint32_t Smallest (uint32_t a, uint32_t b) const;
-
-  inline void Exch (uint32_t a, uint32_t b);
-  void BottomUp (void);
-  void TopDown (uint32_t start);
-
-  BinaryHeap m_heap;
-};
-
-}; // namespace ns3
-
-
-#endif /* SCHEDULER_HEAP_H */
--- a/src/simulator/scheduler-list.cc	Tue Apr 22 21:18:04 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "scheduler-list.h"
-#include "event-impl.h"
-#include <utility>
-#include <string>
-#include "ns3/assert.h"
-
-namespace ns3 {
-
-
-SchedulerList::SchedulerList ()
-{}
-SchedulerList::~SchedulerList ()
-{}
-
-bool 
-SchedulerList::IsLower (Scheduler::EventKey const*a, Scheduler::EventKey const*b) const
-{
-  if (a->m_ts < b->m_ts)
-    {
-      return true;
-    }
-  else if (a->m_ts == b->m_ts &&
-           a->m_uid < b->m_uid)
-    {
-      return true;
-    }
-  else
-    {
-      return false;
-    }
-}
-
-void
-SchedulerList::Insert (const EventId &id)
-{
-  Scheduler::EventKey key;
-  // acquire refcount on EventImpl
-  EventImpl *event = id.PeekEventImpl ();
-  event->Ref ();
-  key.m_ts = id.GetTs ();
-  key.m_uid = id.GetUid ();
-  for (EventsI i = m_events.begin (); i != m_events.end (); i++) 
-    {
-      if (IsLower (&key, &i->second))
-        {
-          m_events.insert (i, std::make_pair (event, key));
-          return;
-        }
-    }
-  m_events.push_back (std::make_pair (event, key));
-}
-bool 
-SchedulerList::IsEmpty (void) const
-{
-  return m_events.empty ();
-}
-EventId
-SchedulerList::PeekNext (void) const
-{
-  std::pair<EventImpl *, EventKey> next = m_events.front ();
-  return EventId (next.first, next.second.m_ts, next.second.m_uid);
-}
-
-EventId
-SchedulerList::RemoveNext (void)
-{
-  std::pair<EventImpl *, EventKey> next = m_events.front ();
-  m_events.pop_front ();
-  return EventId (Ptr<EventImpl> (next.first,false), next.second.m_ts, next.second.m_uid);
-}
-
-bool
-SchedulerList::Remove (const EventId &id)
-{
-  for (EventsI i = m_events.begin (); i != m_events.end (); i++) 
-    {
-      if (i->second.m_uid == id.GetUid ())
-        {
-          NS_ASSERT (id.PeekEventImpl () == i->first);
-          // release single acquire ref.
-          i->first->Unref ();
-          m_events.erase (i);
-          return true;
-        }
-    }
-  NS_ASSERT (false);
-  return false;
-}
-
-}; // namespace ns3
--- a/src/simulator/scheduler-list.h	Tue Apr 22 21:18:04 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef SCHEDULER_LIST_H
-#define SCHEDULER_LIST_H
-
-#include "scheduler.h"
-#include "event-id.h"
-#include <list>
-#include <utility>
-#include <stdint.h>
-
-namespace ns3 {
-
-class EventImpl;
-
-class SchedulerList : public Scheduler {
- public:
-  SchedulerList ();
-  virtual ~SchedulerList ();
-
-  virtual void Insert (const EventId &id);
-  virtual bool IsEmpty (void) const;
-  virtual EventId PeekNext (void) const;
-  virtual EventId RemoveNext (void);
-  virtual bool Remove (const EventId &ev);
-
- private:
-  inline bool IsLower (Scheduler::EventKey const*a, Scheduler::EventKey const*b) const;
-
-  typedef std::list<std::pair<EventImpl*, EventKey> > Events;
-  typedef std::list<std::pair<EventImpl*, EventKey> >::iterator EventsI;
-  Events m_events;
-};
-
-}; // namespace ns3
-
-
-#endif /* SCHEDULER_LIST_H */
--- a/src/simulator/scheduler-map.cc	Tue Apr 22 21:18:04 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- * The idea to use a std c++ map came from GTNetS
- */
-
-#include "scheduler-map.h"
-#include "event-impl.h"
-#include "ns3/assert.h"
-#include <string>
-
-#define noTRACE_MAP 1
-
-#ifdef TRACE_MAP
-#include <iostream>
-# define TRACE(x) \
-std::cout << "MAP TRACE " << x << std::endl;
-#else /* TRACE_MAP */
-# define TRACE(format,...)
-#endif /* TRACE_MAP */
-
-
-namespace ns3 {
-
-SchedulerMap::SchedulerMap ()
-{}
-SchedulerMap::~SchedulerMap ()
-{}
-
-/* Note the invariants which this function must provide:
- * - irreflexibility: f (x,x) is false)
- * - antisymmetry: f(x,y) = !f(y,x)
- * - transitivity: f(x,y) and f(y,z) => f(x,z)
- */
-bool
-SchedulerMap::EventKeyCompare::operator () (struct EventKey const&a, struct EventKey const&b)
-{
-  if (a.m_ts < b.m_ts) 
-    {
-      return true;
-    } 
-  else if (a.m_ts > b.m_ts)
-    {
-      return false;
-    } 
-  else if (a.m_uid < b.m_uid)
-    {
-      return true;
-    }
-  else 
-    {
-      return false;
-    }
-}
-
-
-
-void
-SchedulerMap::Insert (const EventId &id)
-{
-  // acquire a single ref
-  EventImpl *event = id.PeekEventImpl ();
-  event->Ref ();
-  Scheduler::EventKey key;
-  key.m_ts = id.GetTs ();
-  key.m_uid = id.GetUid ();
-  std::pair<EventMapI,bool> result;
-  result = m_list.insert (std::make_pair (key, event));
-  NS_ASSERT (result.second);
-}
-
-bool
-SchedulerMap::IsEmpty (void) const
-{
-  return m_list.empty ();
-}
-
-EventId
-SchedulerMap::PeekNext (void) const
-{
-  EventMapCI i = m_list.begin ();
-  NS_ASSERT (i != m_list.end ());
-  
-  return EventId (i->second, i->first.m_ts, i->first.m_uid);
-}
-EventId
-SchedulerMap::RemoveNext (void)
-{
-  EventMapI i = m_list.begin ();
-  std::pair<Scheduler::EventKey, EventImpl*> next = *i;
-  m_list.erase (i);
-  return EventId (Ptr<EventImpl> (next.second, false), next.first.m_ts, next.first.m_uid);
-}
-
-bool
-SchedulerMap::Remove (const EventId &id)
-{
-  Scheduler::EventKey key;
-  key.m_ts = id.GetTs ();
-  key.m_uid = id.GetUid ();
-  EventMapI i = m_list.find (key);
-  NS_ASSERT (i->second == id.PeekEventImpl ());
-  // release single ref.
-  i->second->Unref ();
-  m_list.erase (i);
-  return true;
-}
-
-}; // namespace ns3
--- a/src/simulator/scheduler-map.h	Tue Apr 22 21:18:04 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef SCHEDULER_MAP_H
-#define SCHEDULER_MAP_H
-
-#include "scheduler.h"
-#include <stdint.h>
-#include <map>
-#include <utility>
-
-namespace ns3 {
-
-class EventImpl;
-
-class SchedulerMap : public Scheduler {
-public:
-  SchedulerMap ();
-  virtual ~SchedulerMap ();
-
-  virtual void Insert (const EventId &id);
-  virtual bool IsEmpty (void) const;
-  virtual EventId PeekNext (void) const;
-  virtual EventId RemoveNext (void);
-  virtual bool Remove (const EventId &ev);
-private:
-
-  class EventKeyCompare {
-  public:
-    bool operator () (struct EventKey const&a, struct EventKey const&b);
-  };
-
-  typedef std::map<Scheduler::EventKey, EventImpl*, SchedulerMap::EventKeyCompare> EventMap;
-  typedef std::map<Scheduler::EventKey, EventImpl*, SchedulerMap::EventKeyCompare>::iterator EventMapI;
-  typedef std::map<Scheduler::EventKey, EventImpl*, SchedulerMap::EventKeyCompare>::const_iterator EventMapCI;
-
-
-  EventMap m_list;
-};
-
-}; // namespace ns3
-
-
-#endif /* SCHEDULER_MAP_H */
--- a/src/simulator/scheduler.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/simulator/scheduler.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -29,7 +29,7 @@
 TypeId 
 Scheduler::GetTypeId (void)
 {
-  static TypeId tid = TypeId ("Scheduler")
+  static TypeId tid = TypeId ("ns3::Scheduler")
     .SetParent<Object> ()
     ;
   return tid;
--- a/src/simulator/simulator.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/simulator/simulator.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -23,7 +23,9 @@
 #include "event-impl.h"
 
 #include "ns3/ptr.h"
+#include "ns3/pointer.h"
 #include "ns3/assert.h"
+#include "ns3/log.h"
 
 
 #include <math.h>
@@ -48,7 +50,9 @@
 
 namespace ns3 {
 
-
+/**
+ * \brief private implementation detail of the Simulator API.
+ */
 class SimulatorPrivate : public Object
 {
 public:
@@ -99,19 +103,21 @@
   int m_unscheduledEvents;
 };
 
+NS_OBJECT_ENSURE_REGISTERED (SimulatorPrivate);
+
 
 TypeId
 SimulatorPrivate::GetTypeId (void)
 {
-  static TypeId tid = TypeId ("SimulatorPrivate")
+  static TypeId tid = TypeId ("ns3::SimulatorPrivate")
     .SetParent<Object> ()
     .AddConstructor<SimulatorPrivate> ()
     .AddAttribute ("Scheduler",
-                   "XXX",
-                   Ptr<Scheduler> (0),
+                   "The Scheduler used to handle all simulation events.",
+                   PointerValue (),
                    // XXX: allow getting the scheduler too.
-                   MakePtrAccessor (&SimulatorPrivate::SetScheduler),
-                   MakePtrChecker<Scheduler> ())
+                   MakePointerAccessor (&SimulatorPrivate::SetScheduler),
+                   MakePointerChecker<Scheduler> ())
     ;
   return tid;
 }
@@ -393,9 +399,7 @@
 }; // namespace ns3
 
 
-#include "scheduler-list.h"
-#include "scheduler-heap.h"
-#include "scheduler-map.h"
+#include "map-scheduler.h"
 
 
 namespace ns3 {
@@ -411,14 +415,22 @@
   GetPriv ()->EnableLogTo (filename);
 }
 
+#ifdef NS3_LOG_ENABLE
+static void
+TimePrinter (std::ostream &os)
+{
+  os << Simulator::Now ();
+}
+#endif /* NS3_LOG_ENABLE */
 
 Ptr<SimulatorPrivate>
 Simulator::GetPriv (void)
 {
   if (m_priv == 0) 
     {
+      LogRegisterTimePrinter (&TimePrinter);
       m_priv = CreateObject<SimulatorPrivate> ();
-      Ptr<Scheduler> scheduler = CreateObject<SchedulerMap> ();
+      Ptr<Scheduler> scheduler = CreateObject<MapScheduler> ();
       m_priv->SetScheduler (scheduler);
     }
   TRACE_S ("priv " << m_priv);
@@ -564,6 +576,8 @@
 
 #include "ns3/test.h"
 #include "ns3/ptr.h"
+#include "list-scheduler.h"
+#include "heap-scheduler.h"
 
 namespace ns3 {
 
@@ -934,19 +948,19 @@
   bool result = true;
 
   Simulator::Destroy ();
-  Simulator::SetScheduler (CreateObject<SchedulerList> ());
+  Simulator::SetScheduler (CreateObject<ListScheduler> ());
   if (!RunOneTest ()) 
     {
       result = false;
     }
   Simulator::Destroy ();
-  Simulator::SetScheduler (CreateObject<SchedulerHeap> ());
+  Simulator::SetScheduler (CreateObject<HeapScheduler> ());
   if (!RunOneTest ()) 
     {
       result = false;
     }
   Simulator::Destroy ();
-  Simulator::SetScheduler (CreateObject<SchedulerMap> ());
+  Simulator::SetScheduler (CreateObject<MapScheduler> ());
   if (!RunOneTest ()) 
     {
       result = false;
--- a/src/simulator/time.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/simulator/time.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -41,7 +41,7 @@
 
 static GlobalValue g_precisionDefaultValue ("TimeStepPrecision", 
                                             "The time unit of the internal 64 bit integer time.",
-                                            Enum (NS),
+                                            EnumValue (NS),
                                             MakeEnumChecker (NS, "NS",
                                                              S, "S",
                                                              MS, "MS",
@@ -53,14 +53,15 @@
 precision_t
 Get (void)
 {
-  Enum v = g_precisionDefaultValue.GetValue ();
+  EnumValue v;
+  g_precisionDefaultValue.GetValue (v);
   return (precision_t) v.Get ();
 }
 
 void 
 Set (precision_t precision)
 {
-  g_precisionDefaultValue.SetValue (Enum (precision));
+  g_precisionDefaultValue.SetValue (EnumValue (precision));
   g_tsPrecFactor = (uint64_t)pow(10, precision);
 }
 
@@ -230,7 +231,7 @@
       is.setstate (std::ios_base::failbit);
       return is;
     }
-  std::string trailer = value.substr(n, value.size ()-1-n);
+  std::string trailer = value.substr(n, value.size ()-n);
   std::istringstream iss;
   iss.str (value.substr(0, n));
 
@@ -301,20 +302,6 @@
   return unitValue;
 }
 
-TimeUnit<1>::TimeUnit (Attribute value)
-{
-  const TimeValue *v = value.DynCast<const TimeValue *> ();
-  if (v == 0)
-    {
-      NS_FATAL_ERROR ("Unexpected type of value. Expected \"TimeValue\"");
-    }
-  *this = v->Get ();
-}
-TimeUnit<1>::operator Attribute () const
-{
-  return Attribute::Create<TimeValue> (*this);
-}
-
 ATTRIBUTE_VALUE_IMPLEMENT (Time);
 ATTRIBUTE_CHECKER_IMPLEMENT (Time);
 
@@ -491,12 +478,12 @@
 
   TimeStepPrecision::Set (TimeStepPrecision::NS);
 
-  Config::SetGlobal ("TimeStepPrecision", String ("S"));
-  Config::SetGlobal ("TimeStepPrecision", String ("MS"));
-  Config::SetGlobal ("TimeStepPrecision", String ("US"));
-  Config::SetGlobal ("TimeStepPrecision", String ("NS"));
-  Config::SetGlobal ("TimeStepPrecision", String ("PS"));
-  Config::SetGlobal ("TimeStepPrecision", String ("FS"));
+  Config::SetGlobal ("TimeStepPrecision", StringValue ("S"));
+  Config::SetGlobal ("TimeStepPrecision", StringValue ("MS"));
+  Config::SetGlobal ("TimeStepPrecision", StringValue ("US"));
+  Config::SetGlobal ("TimeStepPrecision", StringValue ("NS"));
+  Config::SetGlobal ("TimeStepPrecision", StringValue ("PS"));
+  Config::SetGlobal ("TimeStepPrecision", StringValue ("FS"));
 
 
   Time tooBig = TimeStep (0x8000000000000000LL);
--- a/src/simulator/wscript	Tue Apr 22 21:18:04 2008 -0700
+++ b/src/simulator/wscript	Tue Apr 22 21:19:39 2008 -0700
@@ -53,9 +53,9 @@
         'time.cc',
         'event-id.cc',
         'scheduler.cc',
-        'scheduler-list.cc',
-        'scheduler-heap.cc',
-        'scheduler-map.cc',
+        'list-scheduler.cc',
+        'map-scheduler.cc',
+        'heap-scheduler.cc',
         'event-impl.cc',
         'simulator.cc',
         'timer.cc',
@@ -71,9 +71,9 @@
         'event-impl.h',
         'simulator.h',
         'scheduler.h',
-        'scheduler-list.h',
-        'scheduler-map.h',
-        'scheduler-heap.h',
+        'list-scheduler.h',
+        'map-scheduler.h',
+        'heap-scheduler.h',
         'simulation-singleton.h',
         'timer.h',
         'timer-impl.h',
--- a/tutorial/tutorial-bus-network.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/tutorial/tutorial-bus-network.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -40,8 +40,8 @@
   internet.Install (n);
 
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", DataRate(10000000));
-  csma.SetChannelParameter ("Delay", MilliSeconds(20));
+  csma.SetChannelParameter ("BitRate", StringValue ("10Mbps"));
+  csma.SetChannelParameter ("Delay", StringValue ("10ms"));
   NetDeviceContainer nd = csma.Install (n);
 
   Ipv4AddressHelper ipv4;
@@ -51,9 +51,9 @@
   uint32_t port = 7;
   UdpEchoClientHelper client;
   client.SetRemote (i.GetAddress (1), port);
-  client.SetAppAttribute ("MaxPackets", Uinteger (1));
-  client.SetAppAttribute ("Interval", Seconds (1.0));
-  client.SetAppAttribute ("PacketSize", Uinteger (1024));
+  client.SetAppAttribute ("MaxPackets", UintegerValue (1));
+  client.SetAppAttribute ("Interval", StringValue ("1s"));
+  client.SetAppAttribute ("PacketSize", UintegerValue (1024));
   ApplicationContainer apps = client.Install (n.Get (0));
   apps.Start (Seconds (2.0));
   apps.Stop (Seconds (10.0));
--- a/tutorial/tutorial-csma-echo-ascii-trace.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/tutorial/tutorial-csma-echo-ascii-trace.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -38,8 +38,8 @@
   internet.Install (n);
 
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", DataRate (5000000));
-  csma.SetChannelParameter ("Delay", MilliSeconds (2));
+  csma.SetChannelParameter ("BitRate", StringValue ("5Mpbs"));
+  csma.SetChannelParameter ("Delay", StringValue ("2ms"));
   NetDeviceContainer nd = csma.Install (n);
 
   Ipv4AddressHelper ipv4;
@@ -50,9 +50,9 @@
 
   UdpEchoClientHelper client;
   client.SetRemote (i.GetAddress (1), port);
-  client.SetAppAttribute ("MaxPackets", Uinteger (1));
-  client.SetAppAttribute ("Interval", Seconds (1.0));
-  client.SetAppAttribute ("PacketSize", Uinteger (1024));
+  client.SetAppAttribute ("MaxPackets", UintegerValue (1));
+  client.SetAppAttribute ("Interval", StringValue ("1s"));
+  client.SetAppAttribute ("PacketSize", UintegerValue (1024));
   ApplicationContainer apps = client.Install (n.Get (0));
   apps.Start (Seconds (2.0));
   apps.Stop (Seconds (10.0));
--- a/tutorial/tutorial-csma-echo-pcap-trace.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/tutorial/tutorial-csma-echo-pcap-trace.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -36,8 +36,8 @@
   internet.Install (n);
 
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", DataRate (5000000));
-  csma.SetChannelParameter ("Delay", MilliSeconds (2));
+  csma.SetChannelParameter ("BitRate", StringValue ("5Mbps"));
+  csma.SetChannelParameter ("Delay", StringValue ("2ms"));
   NetDeviceContainer nd = csma.Install (n);
 
   Ipv4AddressHelper ipv4;
@@ -48,9 +48,9 @@
 
   UdpEchoClientHelper client;
   client.SetRemote (i.GetAddress (1), port);
-  client.SetAppAttribute ("MaxPackets", Uinteger (1));
-  client.SetAppAttribute ("Interval", Seconds (1.0));
-  client.SetAppAttribute ("PacketSize", Uinteger (1024));
+  client.SetAppAttribute ("MaxPackets", UintegerValue (1));
+  client.SetAppAttribute ("Interval", StringValue ("2s"));
+  client.SetAppAttribute ("PacketSize", UintegerValue (1024));
   ApplicationContainer apps = client.Install (n.Get (0));
   apps.Start (Seconds (2.0));
   apps.Stop (Seconds (10.0));
--- a/tutorial/tutorial-csma-echo.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/tutorial/tutorial-csma-echo.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -36,8 +36,8 @@
   internet.Install (n);
 
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", DataRate (5000000));
-  csma.SetChannelParameter ("Delay", MilliSeconds (2));
+  csma.SetChannelParameter ("BitRate", StringValue ("5Mbps"));
+  csma.SetChannelParameter ("Delay", StringValue ("2ms"));
   NetDeviceContainer nd = csma.Install (n);
 
   Ipv4AddressHelper ipv4;
@@ -48,9 +48,9 @@
 
   UdpEchoClientHelper client;
   client.SetRemote (i.GetAddress (1), port);
-  client.SetAppAttribute ("MaxPackets", Uinteger (1));
-  client.SetAppAttribute ("Interval", Seconds (1.0));
-  client.SetAppAttribute ("PacketSize", Uinteger (1024));
+  client.SetAppAttribute ("MaxPackets", UintegerValue (1));
+  client.SetAppAttribute ("Interval", StringValue ("1s"));
+  client.SetAppAttribute ("PacketSize", UintegerValue (1024));
   ApplicationContainer apps = client.Install (n.Get (0));
   apps.Start (Seconds (2.0));
   apps.Stop (Seconds (10.0));
--- a/tutorial/tutorial-linear-dumbbell.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/tutorial/tutorial-linear-dumbbell.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -53,8 +53,8 @@
   internet.Install (lan1);
 
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", DataRate (10000000));
-  csma.SetChannelParameter ("Delay", MilliSeconds (2));
+  csma.SetChannelParameter ("BitRate", StringValue ("10Mbps"));
+  csma.SetChannelParameter ("Delay", StringValue ("2ms"));
   NetDeviceContainer dev1 = csma.Install (lan1);
   Ipv4AddressHelper ipv4;
   ipv4.SetBase ("10.1.1.0", "255.255.255.0");
@@ -78,8 +78,8 @@
 //
   NodeContainer backbone = NodeContainer (lan1.Get (3), lan2.Get (0));
   PointToPointHelper p2p;
-  p2p.SetChannelParameter ("BitRate", DataRate (38400));
-  p2p.SetChannelParameter ("Delay", MilliSeconds (20));
+  p2p.SetChannelParameter ("BitRate", StringValue ("38400bps"));
+  p2p.SetChannelParameter ("Delay", StringValue ("20ms"));
   NetDeviceContainer dev3 = p2p.Install (backbone);
   ipv4.SetBase ("10.1.3.0", "255.255.255.0");
   ipv4.Assign (dev3);
@@ -95,9 +95,9 @@
 
   UdpEchoClientHelper client;
   client.SetRemote (i2.GetAddress (0), port);
-  client.SetAppAttribute ("MaxPackets", Uinteger (100));
-  client.SetAppAttribute ("Interval", Seconds (0.01));
-  client.SetAppAttribute ("PacketSize", Uinteger (1024));
+  client.SetAppAttribute ("MaxPackets", UintegerValue (100));
+  client.SetAppAttribute ("Interval", StringValue ("10ms"));
+  client.SetAppAttribute ("PacketSize", UintegerValue (1024));
   ApplicationContainer apps = client.Install (lan1.Get (0));
   apps.Start (Seconds(2.));
   apps.Stop (Seconds (10.0));
--- a/tutorial/tutorial-point-to-point.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/tutorial/tutorial-point-to-point.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -45,8 +45,8 @@
   internet.Install (n);
 
   PointToPointHelper p2p;
-  p2p.SetChannelParameter ("BitRate", DataRate (38400));
-  p2p.SetChannelParameter ("Delay", MilliSeconds (20));
+  p2p.SetChannelParameter ("BitRate", StringValue ("38400bps"));
+  p2p.SetChannelParameter ("Delay", StringValue ("20ms"));
   NetDeviceContainer nd = p2p.Install (n);
 
   Ipv4AddressHelper ipv4;
@@ -56,9 +56,9 @@
   uint16_t port = 7;
   UdpEchoClientHelper client;
   client.SetRemote (i.GetAddress (1), port);
-  client.SetAppAttribute ("MaxPackets", Uinteger (1));
-  client.SetAppAttribute ("Interval", Seconds (1.0));
-  client.SetAppAttribute ("PacketSize", Uinteger (1024));
+  client.SetAppAttribute ("MaxPackets", UintegerValue (1));
+  client.SetAppAttribute ("Interval", StringValue ("1s"));
+  client.SetAppAttribute ("PacketSize", UintegerValue (1024));
   ApplicationContainer apps = client.Install (n.Get (0));
   apps.Start (Seconds (2.0));
   apps.Stop (Seconds (10.0));
--- a/tutorial/tutorial-star-routing.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/tutorial/tutorial-star-routing.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -56,8 +56,8 @@
   internet.Install (n);
 
   PointToPointHelper p2p;
-  p2p.SetChannelParameter ("BitRate", DataRate (38400));
-  p2p.SetChannelParameter ("Delay", MilliSeconds (20));
+  p2p.SetChannelParameter ("BitRate", StringValue ("38400bps"));
+  p2p.SetChannelParameter ("Delay", StringValue ("20ms"));
 
   NetDeviceContainer d01 = p2p.Install (n01);
   NetDeviceContainer d02 = p2p.Install (n02);
@@ -90,9 +90,9 @@
 
   UdpEchoClientHelper client;
   client.SetRemote (i01.GetAddress (1), port);
-  client.SetAppAttribute ("MaxPackets", Uinteger (1));
-  client.SetAppAttribute ("Interval", Seconds (1.0));
-  client.SetAppAttribute ("PacketSize", Uinteger (1024));
+  client.SetAppAttribute ("MaxPackets", UintegerValue (1));
+  client.SetAppAttribute ("Interval", StringValue ("1s"));
+  client.SetAppAttribute ("PacketSize", UintegerValue (1024));
   apps = client.Install (n.Get (0));
   apps.Start (Seconds (2.0));
   apps.Stop (Seconds (10.0));
--- a/tutorial/tutorial-star.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/tutorial/tutorial-star.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -55,8 +55,8 @@
   internet.Install (n);
 
   PointToPointHelper p2p;
-  p2p.SetChannelParameter ("BitRate", DataRate (38400));
-  p2p.SetChannelParameter ("Delay", MilliSeconds (20));
+  p2p.SetChannelParameter ("BitRate", StringValue ("38400bps"));
+  p2p.SetChannelParameter ("Delay", StringValue ("20ms"));
 
   NetDeviceContainer d01 = p2p.Install (n01);
   NetDeviceContainer d02 = p2p.Install (n02);
@@ -89,9 +89,9 @@
 
   UdpEchoClientHelper client;
   client.SetRemote (i01.GetAddress (1), port);
-  client.SetAppAttribute ("MaxPackets", Uinteger (1));
-  client.SetAppAttribute ("Interval", Seconds (1.0));
-  client.SetAppAttribute ("PacketSize", Uinteger (1024));
+  client.SetAppAttribute ("MaxPackets", UintegerValue (1));
+  client.SetAppAttribute ("Interval", StringValue ("1s"));
+  client.SetAppAttribute ("PacketSize", UintegerValue (1024));
   apps = client.Install (n.Get (0));
   apps.Start (Seconds (2.0));
   apps.Stop (Seconds (10.0));
--- a/utils/bench-simulator.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/utils/bench-simulator.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -18,11 +18,8 @@
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 
-#include "ns3/simulator.h"
-#include "ns3/scheduler-list.h"
-#include "ns3/scheduler-map.h"
-#include "ns3/scheduler-heap.h"
-#include "ns3/system-wall-clock-ms.h"
+#include "ns3/simulator-module.h"
+#include "ns3/core-module.h"
 #include <iostream>
 #include <fstream>
 #include <vector>
@@ -161,15 +158,15 @@
     {
       if (strcmp ("--list", argv[0]) == 0) 
         {
-          Simulator::SetScheduler (CreateObject<SchedulerList> ());
+          Simulator::SetScheduler (CreateObject<ListScheduler> ());
         } 
       else if (strcmp ("--heap", argv[0]) == 0) 
         {
-          Simulator::SetScheduler (CreateObject<SchedulerHeap> ());
+          Simulator::SetScheduler (CreateObject<HeapScheduler> ());
         } 
       else if (strcmp ("--map", argv[0]) == 0) 
         {
-          Simulator::SetScheduler (CreateObject<SchedulerMap> ());
+          Simulator::SetScheduler (CreateObject<MapScheduler> ());
         } 
       else if (strcmp ("--debug", argv[0]) == 0) 
         {
--- a/utils/print-introspected-doxygen.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/utils/print-introspected-doxygen.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -1,8 +1,15 @@
 #include <iostream>
 #include "ns3/object.h"
+#include "ns3/pointer.h"
+#include "ns3/object-vector.h"
+#include "ns3/config.h"
+#include "ns3/log.h"
+#include "ns3/helper-module.h"
 
 using namespace ns3;
 
+NS_LOG_COMPONENT_DEFINE ("Main");
+
 void
 PrintAttributes (TypeId tid, std::ostream &os)
 {
@@ -12,35 +19,237 @@
       os << "<li><b>" << tid.GetAttributeName (j) << "</b>: "
 		<< tid.GetAttributeHelp (j) << std::endl;
       Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (j);
-      os << "  <ul>" << std::endl << "    <li>Type: " <<  checker->GetType ();
-      if (checker->HasTypeConstraints ())
+      os << "  <ul>" << std::endl 
+	 << "    <li>Set with class: \\ref " <<  checker->GetValueTypeName () << "</li>" << std::endl;
+      if (checker->HasUnderlyingTypeInformation ())
 	{
-	  os << " -> " << checker->GetTypeConstraints ();
+	  os << "    <li>Underlying type: \\ref " << checker->GetUnderlyingTypeInformation () << "</li>" << std::endl;
 	}
-      os << "</li>" << std::endl;
       uint32_t flags = tid.GetAttributeFlags (j);
-      os << "<li>Flags: ";
-      if (flags & TypeId::ATTR_SET)
+      Ptr<const AttributeAccessor> accessor = tid.GetAttributeAccessor (j);
+      if (flags & TypeId::ATTR_CONSTRUCT && accessor->HasSetter ())
+	{
+	  Ptr<const AttributeValue> initial = tid.GetAttributeInitialValue (j);
+	  os << "    <li>Initial value: " << initial->SerializeToString (checker) << "</li>" << std::endl;
+	}
+      os << "    <li>Flags: ";
+      if (flags & TypeId::ATTR_CONSTRUCT && accessor->HasSetter ())
+	{
+	  os << "construct ";
+	}
+      if (flags & TypeId::ATTR_SET && accessor->HasSetter ())
 	{
 	  os << "write ";
 	}
-      if (flags & TypeId::ATTR_GET)
+      if (flags & TypeId::ATTR_GET && accessor->HasGetter ())
 	{
 	  os << "read ";
 	}
-      if (flags & TypeId::ATTR_CONSTRUCT)
-	{
-	  os << "construct ";
-	}
+      os << "</li>" << std::endl;
       os << "  </ul> " << std::endl;
       
     }
   os << "</ul>" << std::endl;
 }
 
+void
+PrintTraceSources (TypeId tid, std::ostream &os)
+{
+  os << "<ul>"<<std::endl;
+  for (uint32_t i = 0; i < tid.GetTraceSourceN (); ++i)
+    {
+      os << "<li><b>" << tid.GetTraceSourceName (i) << "</b>: "
+	 << tid.GetTraceSourceHelp (i)
+	 << std::endl;
+      os << "</li>" << std::endl;
+    }
+  os << "</ul>"<<std::endl;
+}
+
+
+class StaticInformation
+{
+public:
+  void RecordAggregationInfo (std::string a, std::string b);
+  void Gather (TypeId tid);
+  void Print (void) const;
+
+  std::vector<std::string> Get (TypeId tid);
+
+private:
+  std::string GetCurrentPath (void) const;
+  void DoGather (TypeId tid);
+  void RecordOutput (TypeId tid);
+  bool HasAlreadyBeenProcessed (TypeId tid) const;
+  std::vector<std::pair<TypeId,std::string> > m_output;
+  std::vector<std::string> m_currentPath;
+  std::vector<TypeId> m_alreadyProcessed;
+  std::vector<std::pair<TypeId,TypeId> > m_aggregates;
+};
+
+void 
+StaticInformation::RecordAggregationInfo (std::string a, std::string b)
+{
+  m_aggregates.push_back (std::make_pair (TypeId::LookupByName (a), TypeId::LookupByName (b)));
+}
+
+void 
+StaticInformation::Print (void) const
+{
+  for (std::vector<std::pair<TypeId,std::string> >::const_iterator i = m_output.begin (); i != m_output.end (); ++i)
+    {
+      std::pair<TypeId,std::string> item = *i;
+      std::cout << item.first.GetName () << " -> " << item.second << std::endl;
+    }
+}
+
+std::string
+StaticInformation::GetCurrentPath (void) const
+{
+  std::ostringstream oss;
+  for (std::vector<std::string>::const_iterator i = m_currentPath.begin (); i != m_currentPath.end (); ++i)
+    {
+      std::string item = *i;
+      oss << "/" << item;
+    }
+  return oss.str ();
+}
+
+void
+StaticInformation::RecordOutput (TypeId tid)
+{
+  m_output.push_back (std::make_pair (tid, GetCurrentPath ()));
+}
+
+bool
+StaticInformation::HasAlreadyBeenProcessed (TypeId tid) const
+{
+  for (uint32_t i = 0; i < m_alreadyProcessed.size (); ++i)
+    {
+      if (m_alreadyProcessed[i] == tid)
+	{
+	  return true;
+	}
+    }
+  return false;
+}
+
+std::vector<std::string> 
+StaticInformation::Get (TypeId tid)
+{
+  std::vector<std::string> paths;
+  for (uint32_t i = 0; i < m_output.size (); ++i)
+    {
+      std::pair<TypeId,std::string> tmp = m_output[i];
+      if (tmp.first == tid)
+	{
+	  paths.push_back (tmp.second);
+	}
+    }
+  return paths;
+}
+
+void
+StaticInformation::Gather (TypeId tid)
+{
+  DoGather (tid);
+
+  std::sort (m_output.begin (), m_output.end ());
+  m_output.erase (std::unique (m_output.begin (), m_output.end ()), m_output.end ());
+}
+
+void 
+StaticInformation::DoGather (TypeId tid)
+{
+  NS_LOG_FUNCTION (this);
+  if (HasAlreadyBeenProcessed (tid))
+    {
+      return;
+    }
+  RecordOutput (tid);
+  for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
+    {
+      Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (i);
+      const PointerChecker *ptrChecker = dynamic_cast<const PointerChecker *> (PeekPointer (checker));
+      if (ptrChecker != 0)
+	{
+	  TypeId pointee = ptrChecker->GetPointeeTypeId ();
+	  m_currentPath.push_back (tid.GetAttributeName (i));
+	  m_alreadyProcessed.push_back (tid);
+	  DoGather (pointee);
+	  m_alreadyProcessed.pop_back ();
+	  m_currentPath.pop_back ();
+	  continue;
+	}
+      // attempt to cast to an object vector.
+      const ObjectVectorChecker *vectorChecker = dynamic_cast<const ObjectVectorChecker *> (PeekPointer (checker));
+      if (vectorChecker != 0)
+	{
+	  TypeId item = vectorChecker->GetItemTypeId ();
+	  m_currentPath.push_back (tid.GetAttributeName (i) + "/[i]");
+	  m_alreadyProcessed.push_back (tid);
+	  DoGather (item);
+	  m_alreadyProcessed.pop_back ();
+	  m_currentPath.pop_back ();
+	  continue;
+	}
+    }
+  for (uint32_t j = 0; j < TypeId::GetRegisteredN (); j++)
+    {
+      TypeId child = TypeId::GetRegistered (j);
+      if (child.IsChildOf (tid))
+	{
+	  m_currentPath.push_back ("$%" + child.GetName ());
+	  m_alreadyProcessed.push_back (tid);
+	  DoGather (child);
+	  m_alreadyProcessed.pop_back ();
+	  m_currentPath.pop_back ();
+	}
+    }
+  for (uint32_t k = 0; k < m_aggregates.size (); ++k)
+    {
+      std::pair<TypeId,TypeId> tmp = m_aggregates[k];
+      if (tmp.first == tid || tmp.second == tid)
+	{
+	  TypeId other;
+	  if (tmp.first == tid)
+	    {
+	      other = tmp.second;
+	    }
+	  if (tmp.second == tid)
+	    {
+	      other = tmp.first;
+	    }
+	  // Note: we insert a % in the path below to ensure that doxygen does not
+	  // attempt to resolve the typeid names included in the string.
+	  m_currentPath.push_back ("$%" + other.GetName ());
+	  m_alreadyProcessed.push_back (tid);
+	  DoGather (other);
+	  m_alreadyProcessed.pop_back ();
+	  m_currentPath.pop_back ();	  
+	}
+    }
+}
 
 int main (int argc, char *argv[])
 {
+  NodeContainer c; c.Create (1);
+
+  StaticInformation info;
+  info.RecordAggregationInfo ("ns3::Node", "ns3::Tcp");
+  info.RecordAggregationInfo ("ns3::Node", "ns3::Udp");
+  info.RecordAggregationInfo ("ns3::Node", "ns3::PacketSocketFactory");
+  info.RecordAggregationInfo ("ns3::Node", "ns3::olsr::Agent");
+  info.RecordAggregationInfo ("ns3::Node", "ns3::MobilityModel");
+  info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv4L4Demux");
+  info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv4L3Protocol");
+  info.RecordAggregationInfo ("ns3::Node", "ns3::ArpL3Protocol");
+
+  for (uint32_t i = 0; i < Config::GetRootNamespaceObjectN (); ++i)
+    {
+      Ptr<Object> object = Config::GetRootNamespaceObject (i);
+      info.Gather (object->GetInstanceTypeId ());
+    }
 
   for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++)
     {
@@ -51,43 +260,111 @@
 	  continue;
 	}
       std::cout << "\\fn static TypeId " << tid.GetName () << "::GetTypeId (void)" << std::endl;
-      std::cout << "\\brief This method returns the TypeId associated to \\ref " << tid.GetName () << std::endl << std::endl;
+      std::cout << "\\brief This method returns the TypeId associated to \\ref " << tid.GetName () 
+		<< std::endl << std::endl;
+      std::vector<std::string> paths = info.Get (tid);
+      if (!paths.empty ())
+	{
+	  std::cout << "This object is accessible through the following paths with Config::Set and Config::Connect:" 
+		    << std::endl;
+	  std::cout << "<ul>" << std::endl;
+	  for (uint32_t k = 0; k < paths.size (); ++k)
+	    {
+	      std::string path = paths[k];
+	      std::cout << "<li>" << path << "</li>" << std::endl;
+	    }
+	  std::cout << "</ul>" << std::endl;
+	}
       if (tid.GetAttributeN () == 0)
 	{
-	  std::cout << "No Attributes defined for this type." << std::endl;
+	  std::cout << "No Attributes defined for this type.<br>" << std::endl;
 	}
       else
 	{
-	  std::cout << "Attributes defined for this type:" << std::endl;
+	  std::cout << "Attributes defined for this type:<br>" << std::endl;
 	  PrintAttributes (tid, std::cout);
 	}
-      bool hasAttributesInParent = false;
-      TypeId tmp = tid.GetParent ();
-      while (tmp.GetParent () != tmp)
-	{
-	  if (tmp.GetAttributeN () != 0)
-	    {
-	      hasAttributesInParent = true;
-	    }
-	  tmp = tmp.GetParent ();
-	}
-      if (hasAttributesInParent)
+      {
+	TypeId tmp = tid.GetParent ();
+	while (tmp.GetParent () != tmp)
+	  {
+	    if (tmp.GetAttributeN () != 0)
+	      {
+		std::cout << "Attributes defined in parent class " << tmp.GetName () << ":<br>" << std::endl;
+		PrintAttributes (tmp, std::cout);
+	      }
+	    tmp = tmp.GetParent ();
+	  }
+      }
+      if (tid.GetTraceSourceN () == 0)
 	{
-	  std::cout << "Attributes defined in parent classes:<br>" << std::endl;
-	  tmp = tid.GetParent ();
-	  while (tmp.GetParent () != tmp)
-	    {
-	      if (tmp.GetAttributeN () != 0)
-		{
-		  std::cout << tmp.GetName () << std::endl;
-		  PrintAttributes (tmp, std::cout);
-		}
-	      tmp = tmp.GetParent ();
-	    }
+	  std::cout << "No TraceSources defined for this type.<br>" << std::endl;
+	}
+      else
+	{
+	  std::cout << "TraceSources defined for this type:<br>" << std::endl;
+	  PrintTraceSources (tid, std::cout);
 	}
+      {
+	TypeId tmp = tid.GetParent ();
+	while (tmp.GetParent () != tmp)
+	  {
+	    if (tmp.GetTraceSourceN () != 0)
+	      {
+		std::cout << "TraceSources defined in parent class " << tmp.GetName () << ":<br>" << std::endl;
+		PrintTraceSources (tmp, std::cout);
+	      }
+	    tmp = tmp.GetParent ();
+	  }
+      }
       std::cout << "*/" << std::endl;
     }
 
 
+  std::cout << "/*!" << std::endl
+	    << "\\ingroup core" << std::endl
+	    << "\\defgroup TraceSourceList The list of all trace sources." << std::endl;
+  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
+    {
+      TypeId tid = TypeId::GetRegistered (i);
+      if (tid.GetTraceSourceN () == 0 ||
+	  tid.MustHideFromDocumentation ())
+	{
+	  continue;
+	}
+      std::cout << "<b>" << tid.GetName () << "</b><br>" << std::endl
+		<< "<ul>" << std::endl;
+      for (uint32_t j = 0; j < tid.GetTraceSourceN (); ++j)
+	{
+	  std::cout << "<li>" << tid.GetTraceSourceName (j) << ": " << tid.GetTraceSourceHelp (j) << "</li>" << std::endl;
+	}
+      std::cout << "</ul>" << std::endl;
+    }
+  std::cout << "*/" << std::endl;
+
+
+  std::cout << "/*!" << std::endl
+	    << "\\ingroup core" << std::endl
+	    << "\\defgroup AttributeList The list of all attributes." << std::endl;
+  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
+    {
+      TypeId tid = TypeId::GetRegistered (i);
+      if (tid.GetAttributeN () == 0 ||
+	  tid.MustHideFromDocumentation ())
+	{
+	  continue;
+	}
+      std::cout << "<b>" << tid.GetName () << "</b><br>" << std::endl
+		<< "<ul>" << std::endl;
+      for (uint32_t j = 0; j < tid.GetAttributeN (); ++j)
+	{
+	  std::cout << "<li>" << tid.GetAttributeName (j) << ": " << tid.GetAttributeHelp (j) << "</li>" << std::endl;
+	}
+      std::cout << "</ul>" << std::endl;
+    }
+  std::cout << "*/" << std::endl;
+
+
+
   return 0;
 }
--- a/utils/replay-simulation.cc	Tue Apr 22 21:18:04 2008 -0700
+++ b/utils/replay-simulation.cc	Tue Apr 22 21:19:39 2008 -0700
@@ -18,12 +18,8 @@
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 
-#include "ns3/simulator.h"
-#include "ns3/scheduler-list.h"
-#include "ns3/scheduler-map.h"
-#include "ns3/scheduler-heap.h"
-#include "ns3/nstime.h"
-#include "ns3/system-wall-clock-ms.h"
+#include "ns3/simulator-module.h"
+#include "ns3/core-module.h"
 #include <vector>
 #include <deque>
 #include <fstream>
@@ -317,15 +313,15 @@
     {
       if (is_map)
         {
-          Simulator::SetScheduler (CreateObject<SchedulerMap> ());
+          Simulator::SetScheduler (CreateObject<MapScheduler> ());
         }
       else if (is_list)
         {
-          Simulator::SetScheduler (CreateObject<SchedulerList> ());
+          Simulator::SetScheduler (CreateObject<ListScheduler> ());
         }
       else if (is_heap)
         {
-          Simulator::SetScheduler (CreateObject<SchedulerHeap> ());
+          Simulator::SetScheduler (CreateObject<HeapScheduler> ());
         }
       log.Run ();
       Simulator::Destroy ();
--- a/wscript	Tue Apr 22 21:18:04 2008 -0700
+++ b/wscript	Tue Apr 22 21:19:39 2008 -0700
@@ -340,9 +340,6 @@
         run_program(Params.g_options.run, get_command_template())
         raise SystemExit(0)
 
-    if Params.g_options.command_template:
-        Params.fatal("Option --command-template requires the option --run to be given")
-
 def _run_waf_check():
     ## generate the trace sources list docs
     env = Params.g_build.env_of_name('default')
@@ -755,9 +752,11 @@
             _dir = os.getcwd()
             os.chdir(REGRESSION_TRACES_DIR_NAME)
             try:
-                os.system("hg pull " + REGRESSION_TRACES_REPO + REGRESSION_TRACES_DIR_NAME + " > /dev/null 2>&1")
+                result = os.system("hg -q pull %s && hg -q update" % (REGRESSION_TRACES_REPO + REGRESSION_TRACES_DIR_NAME))
             finally:
                 os.chdir("..")
+            if result:
+                Params.fatal("Synchronizing reference traces using Mercurial failed.")
     else:
         print "Synchronizing reference traces from web."
         urllib.urlretrieve(REGRESSION_TRACES_URL + REGRESSION_TRACES_TAR_NAME, REGRESSION_TRACES_TAR_NAME)