merge with HEAD
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Mon, 21 Apr 2008 09:04:08 -0700
changeset 2989 b7eb3929096c
parent 2988 8774a8c9526f (current diff)
parent 2974 30ed185e0364 (diff)
child 2990 69ddc1c42130
child 2991 9a3ed582d153
merge with HEAD
doc/tracing.h
src/applications/onoff/onoff-application.cc
src/applications/udp-echo/udp-echo-client.cc
src/applications/udp-echo/udp-echo-server.cc
src/common/error-model.cc
src/devices/csma/csma-channel.cc
src/devices/csma/csma-net-device.cc
src/devices/point-to-point/point-to-point-channel.cc
src/devices/point-to-point/point-to-point-net-device.cc
src/devices/wifi/dca-txop.cc
src/devices/wifi/ideal-wifi-manager.cc
src/devices/wifi/nqap-wifi-mac.cc
src/devices/wifi/nqsta-wifi-mac.cc
src/devices/wifi/wifi-phy.cc
src/internet-node/ipv4-interface.cc
src/internet-node/ipv4-l3-protocol.cc
src/internet-node/tcp-l4-protocol.cc
src/internet-node/tcp-socket.cc
src/mobility/random-direction-2d-mobility-model.cc
src/node/drop-tail-queue.cc
src/node/node-list.cc
src/node/queue.cc
src/simulator/simulator.cc
utils/print-introspected-doxygen.cc
--- a/doc/doxygen.conf	Mon Apr 21 08:58:23 2008 -0700
+++ b/doc/doxygen.conf	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/doc/modules	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/examples/csma-broadcast.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/examples/csma-multicast.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/examples/csma-one-subnet.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/examples/csma-packet-socket.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/examples/mixed-global-routing.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/examples/mixed-wireless.cc	Mon Apr 21 09:04:08 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,9 +163,9 @@
   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));
+                             "Bounds", RectangleValue (Rectangle (0, 1000, 0, 1000)),
+                             "Speed", RandomVariableValue (ConstantVariable (2000)),
+                             "Pause", RandomVariableValue (ConstantVariable (0.2)));
   mobility.Layout (backbone);
 
   /////////////////////////////////////////////////////////////////////////// 
@@ -194,8 +194,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 nodes in our container
@@ -269,9 +269,9 @@
       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));
+                                 "Bounds", RectangleValue (Rectangle (-25, 25, -25, 25)),
+                                 "Speed", RandomVariableValue (ConstantVariable (30)),
+                                 "Pause", RandomVariableValue (ConstantVariable (0.4)));
       mobility.Layout (infra);
     }
   /////////////////////////////////////////////////////////////////////////// 
@@ -304,8 +304,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	Mon Apr 21 08:58:23 2008 -0700
+++ b/examples/simple-alternate-routing.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/examples/simple-error-model.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/examples/simple-global-routing.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/examples/simple-point-to-point-olsr.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/examples/tcp-large-transfer.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/examples/udp-echo.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/examples/wifi-adhoc.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/examples/wifi-ap.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/samples/main-attribute-value.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/samples/main-grid-topology.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/samples/main-propagation-loss.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/samples/main-random-topology.cc	Mon Apr 21 09:04:08 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.Layout (c);
 
--- a/samples/main-random-walk.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/samples/main-random-walk.cc	Mon Apr 21 09:04:08 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"));
+                             "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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/applications/onoff/onoff-application.cc	Mon Apr 21 09:04:08 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",
--- a/src/applications/packet-sink/packet-sink.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/applications/packet-sink/packet-sink.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/applications/udp-echo/udp-echo-client.cc	Mon Apr 21 09:04:08 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> ())
     ;
--- a/src/applications/udp-echo/udp-echo-client.h	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/applications/udp-echo/udp-echo-client.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/applications/udp-echo/udp-echo-server.cc	Mon Apr 21 09:04:08 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> ())
     ;
--- a/src/applications/udp-echo/udp-echo-server.h	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/applications/udp-echo/udp-echo-server.h	Mon Apr 21 09:04:08 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/data-rate.h	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/common/data-rate.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/common/error-model.cc	Mon Apr 21 09:04:08 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 ())
     ;
@@ -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 ())
     ;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/config-store.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/contrib/wscript	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/attribute-accessor-helper.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/attribute-helper.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/attribute-list.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/attribute-list.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/attribute-test.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/attribute.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/attribute.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/boolean.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/boolean.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/command-line.cc	Mon Apr 21 09:04:08 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>
 
@@ -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/config.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/config.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/config.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/double.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/double.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/enum.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/enum.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/global-value.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/global-value.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/integer.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/integer.h	Mon Apr 21 09:04:08 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/object-base.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/object-base.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/object-base.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/object-factory.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/object-factory.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/object-vector.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/object-vector.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/object.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/object.h	Mon Apr 21 09:04:08 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 
@@ -141,6 +181,7 @@
   friend Ptr<T> CopyObject (Ptr<const T> object);
 
   friend class ObjectFactory;
+  friend class AggregateIterator;
 
   Ptr<Object> DoGetObject (TypeId tid) const;
   bool Check (void) const;
@@ -247,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 ());
   
 
 
@@ -339,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	Mon Apr 21 09:04:08 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	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/ptr.h	Mon Apr 21 09:04:08 2008 -0700
@@ -447,7 +447,6 @@
   return *m_ptr;
 }
 
-
 template <typename T>
 bool 
 Ptr<T>::operator! () 
--- a/src/core/random-variable.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/random-variable.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/random-variable.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/ref-count-base.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/ref-count-base.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/string.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/string.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/traced-value.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/type-id.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/type-id.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/uinteger.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/uinteger.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/core/wscript	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/csma/csma-channel.cc	Mon Apr 21 09:04:08 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 ())
     ;
--- a/src/devices/csma/csma-net-device.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/csma/csma-net-device.cc	Mon Apr 21 09:04:08 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.",
--- a/src/devices/point-to-point/point-to-point-channel.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/point-to-point/point-to-point-channel.cc	Mon Apr 21 09:04:08 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 ())
     ;
--- a/src/devices/point-to-point/point-to-point-net-device.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/point-to-point/point-to-point-net-device.cc	Mon Apr 21 09:04:08 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.",
--- a/src/devices/wifi/aarf-wifi-manager.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/aarf-wifi-manager.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/amrr-wifi-manager.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/amrr-wifi-manager.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/arf-wifi-manager.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/constant-rate-wifi-manager.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/dca-txop.cc	Mon Apr 21 09:04:08 2008 -0700
@@ -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> ())
--- a/src/devices/wifi/ideal-wifi-manager.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/ideal-wifi-manager.cc	Mon Apr 21 09:04:08 2008 -0700
@@ -35,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> ())
     ;
--- a/src/devices/wifi/jakes-propagation-loss-model.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/jakes-propagation-loss-model.cc	Mon Apr 21 09:04:08 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/nqap-wifi-mac.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/nqap-wifi-mac.cc	Mon Apr 21 09:04:08 2008 -0700
@@ -44,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 ())
--- a/src/devices/wifi/nqsta-wifi-mac.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/nqsta-wifi-mac.cc	Mon Apr 21 09:04:08 2008 -0700
@@ -63,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 ())
     ;
--- a/src/devices/wifi/onoe-wifi-manager.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/onoe-wifi-manager.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/onoe-wifi-manager.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/propagation-delay-model.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/propagation-delay-model.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/propagation-loss-model.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/propagation-loss-model.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/rraa-wifi-manager.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/ssid.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/wifi-channel.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/wifi-channel.h	Mon Apr 21 09:04:08 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-queue.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/wifi-mac-queue.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/wifi-mac.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/wifi-mode.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/wifi-net-device.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/wifi-phy.cc	Mon Apr 21 09:04:08 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"))
--- a/src/devices/wifi/wifi-remote-station-manager.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/devices/wifi/wifi-remote-station-manager.cc	Mon Apr 21 09:04:08 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/helper/csma-helper.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/csma-helper.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/csma-helper.h	Mon Apr 21 09:04:08 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/mobility-helper.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/mobility-helper.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/mobility-helper.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/olsr-helper.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/olsr-helper.h	Mon Apr 21 09:04:08 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 Enable (NodeContainer container);
   void Enable (Ptr<Node> node);
--- a/src/helper/on-off-helper.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/on-off-helper.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/on-off-helper.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/packet-sink-helper.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/packet-sink-helper.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/point-to-point-helper.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/point-to-point-helper.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/udp-echo-helper.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/udp-echo-helper.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/wifi-helper.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/helper/wifi-helper.h	Mon Apr 21 09:04:08 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/ipv4-interface.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/internet-node/ipv4-interface.cc	Mon Apr 21 09:04:08 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
--- a/src/internet-node/ipv4-interface.h	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/internet-node/ipv4-interface.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/internet-node/ipv4-l3-protocol.cc	Mon Apr 21 09:04:08 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;
 }
--- a/src/internet-node/ipv4-l3-protocol.h	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/internet-node/ipv4-l3-protocol.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/internet-node/ipv4-l4-demux.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/internet-node/ipv4-l4-protocol.cc	Mon Apr 21 09:04:08 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/rtt-estimator.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/internet-node/rtt-estimator.cc	Mon Apr 21 09:04:08 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 ())
     ;
@@ -178,7 +178,7 @@
     .AddConstructor<RttMeanDeviation> ()
     .AddAttribute ("Gain",
                    "XXX",
-                   Double (0.1),
+                   DoubleValue (0.1),
                    MakeDoubleAccessor (&RttMeanDeviation::gain),
                    MakeDoubleChecker<double> ())
     ;
--- a/src/internet-node/tcp-l4-protocol.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/internet-node/tcp-l4-protocol.cc	Mon Apr 21 09:04:08 2008 -0700
@@ -325,7 +325,7 @@
     .SetParent<Ipv4L4Protocol> ()
     .AddAttribute ("RttEstimatorFactory",
                    "How RttEstimator objects are created.",
-                   GetDefaultRttEstimatorFactory (),
+                   ObjectFactoryValue (GetDefaultRttEstimatorFactory ()),
                    MakeObjectFactoryAccessor (&TcpL4Protocol::m_rttFactory),
                    MakeObjectFactoryChecker ())
     ;
--- a/src/internet-node/tcp-socket.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/internet-node/tcp-socket.cc	Mon Apr 21 09:04:08 2008 -0700
@@ -1161,7 +1161,7 @@
   // 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
 }
 
--- a/src/mobility/hierarchical-mobility-model.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/mobility/hierarchical-mobility-model.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/mobility/mobility-model.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/mobility/position-allocator.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/mobility/random-direction-2d-mobility-model.cc	Mon Apr 21 09:04:08 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 ())
     ;
--- a/src/mobility/random-walk-2d-mobility-model.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/mobility/random-walk-2d-mobility-model.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/mobility/random-waypoint-mobility-model.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/mobility/rectangle.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/mobility/vector.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/node/address.cc	Mon Apr 21 09:04:08 2008 -0700
@@ -166,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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/node/address.h	Mon Apr 21 09:04:08 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/drop-tail-queue.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/node/drop-tail-queue.cc	Mon Apr 21 09:04:08 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> ())
     ;
@@ -129,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.h	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/node/ipv4-address.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/node/mac48-address.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/node/mac48-address.h	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/node/node-list.cc	Mon Apr 21 09:04:08 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;
 }
--- a/src/node/node.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/node/node.cc	Mon Apr 21 09:04:08 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/queue.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/node/queue.cc	Mon Apr 21 09:04:08 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;
--- a/src/node/tcp.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/node/tcp.cc	Mon Apr 21 09:04:08 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/olsr/olsr-agent-impl.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/routing/olsr/olsr-agent-impl.cc	Mon Apr 21 09:04:08 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.",
--- a/src/simulator/nstime.h	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/simulator/nstime.h	Mon Apr 21 09:04:08 2008 -0700
@@ -437,8 +437,6 @@
   static uint64_t UnitsToTimestep (uint64_t unitValue, 
                                    uint64_t unitFactor);
 
-  TimeUnit (Attribute value);
-  operator Attribute () const;
 private:
   HighPrecision m_data;
 
@@ -670,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.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/simulator/scheduler.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/simulator/simulator.cc	Mon Apr 21 09:04:08 2008 -0700
@@ -23,6 +23,7 @@
 #include "event-impl.h"
 
 #include "ns3/ptr.h"
+#include "ns3/pointer.h"
 #include "ns3/assert.h"
 #include "ns3/log.h"
 
@@ -49,6 +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;
 }
--- a/src/simulator/time.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/src/simulator/time.cc	Mon Apr 21 09:04:08 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/tutorial/tutorial-bus-network.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/tutorial/tutorial-bus-network.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/tutorial/tutorial-csma-echo-ascii-trace.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/tutorial/tutorial-csma-echo-pcap-trace.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/tutorial/tutorial-csma-echo.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/tutorial/tutorial-linear-dumbbell.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/tutorial/tutorial-point-to-point.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/tutorial/tutorial-star-routing.cc	Mon Apr 21 09:04:08 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	Mon Apr 21 08:58:23 2008 -0700
+++ b/tutorial/tutorial-star.cc	Mon Apr 21 09:04:08 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/print-introspected-doxygen.cc	Mon Apr 21 08:58:23 2008 -0700
+++ b/utils/print-introspected-doxygen.cc	Mon Apr 21 09:04:08 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;
 }