merge
authorGustavo J. A. M. Carneiro <gjcarneiro@gmail.com>
Sun, 13 May 2007 12:52:38 +0100
changeset 601 776f776d10d9
parent 600 fd944dbf33c6 (current diff)
parent 599 7b7012218291 (diff)
child 602 dda9e3976114
merge
src/applications/application-list.cc
src/applications/application-list.h
src/applications/application.cc
src/applications/application.h
src/applications/wscript
src/core/ns-unknown-manager.cc
src/core/ns-unknown-manager.h
src/core/ns-unknown.cc
src/core/ns-unknown.h
src/core/wscript
src/devices/p2p-gfr/p2p-channel.cc
src/devices/p2p-gfr/p2p-channel.h
src/devices/p2p-gfr/p2p-net-device.cc
src/devices/p2p-gfr/p2p-net-device.h
src/devices/p2p-gfr/wscript
src/node/wscript
--- a/SConstruct	Sun May 13 12:46:18 2007 +0100
+++ b/SConstruct	Sun May 13 12:52:38 2007 +0100
@@ -25,12 +25,12 @@
     'test.cc',
     'random-variable.cc',
     'rng-stream.cc',
-    'ns-unknown.cc',
+    'interface.cc',
     'uid-manager.cc',
     'default-value.cc',
     'command-line.cc',
     'type-name.cc',
-    'ns-unknown-manager.cc',
+    'component-manager.cc',
     ])
 env = Environment()
 if env['PLATFORM'] == 'posix' or env['PLATFORM'] == 'darwin' or env['PLATFORM'] == 'cygwin':
@@ -58,11 +58,11 @@
     'test.h',
     'random-variable.h',
     'rng-stream.h',
-    'ns-unknown.h',
+    'interface.h',
     'default-value.h',
     'command-line.h',
     'type-name.h',
-    'ns-unknown-manager.h',
+    'component-manager.h',
     ])
 
 def config_core (env, config):
@@ -209,6 +209,7 @@
     'socket.cc',
     'i-udp.cc',
     'i-ipv4.cc',
+    'application.cc',
     ])
 node.add_inst_headers ([
     'node.h',
@@ -224,25 +225,22 @@
     'socket.h',
     'i-udp.h',
     'i-ipv4.h',
+    'application.h',
     ])
 
 applications = build.Ns3Module ('applications', 'src/applications')
 ns3.add (applications)
 applications.add_deps (['node'])
 applications.add_sources ([
-    'application-list.cc',
-    'application.cc',
     'onoff-application.cc',
 ])
 applications.add_inst_headers ([
-    'application-list.h',
-    'application.h',
     'onoff-application.h',
 ])
 
 inode = build.Ns3Module ('internet-node', 'src/internet-node')
 ns3.add (inode)
-inode.add_deps (['node', 'applications'])
+inode.add_deps (['node'])
 inode.add_sources ([
     'internet-node.cc',
     'l3-demux.cc',
@@ -418,7 +416,7 @@
 example_simple_p2p = build.Ns3Module('simple-p2p', 'examples')
 example_simple_p2p.set_executable()
 ns3.add(example_simple_p2p)
-example_simple_p2p.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node'])
+example_simple_p2p.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node', 'applications'])
 example_simple_p2p.add_source('simple-p2p.cc')
 
 ns3.generate_dependencies()
--- a/examples/simple-p2p.cc	Sun May 13 12:46:18 2007 +0100
+++ b/examples/simple-p2p.cc	Sun May 13 12:52:38 2007 +0100
@@ -45,6 +45,7 @@
 #include "ns3/debug.h"
 #include "ns3/command-line.h"
 #include "ns3/default-value.h"
+#include "ns3/ptr.h"
 
 #include "ns3/simulator.h"
 #include "ns3/nstime.h"
@@ -65,7 +66,6 @@
 #include "ns3/trace-root.h"
 #include "ns3/p2p-topology.h"
 #include "ns3/onoff-application.h"
-#include "ns3/application-list.h"
 #include "ns3/random-variable.h"
 
 using namespace ns3;
@@ -100,21 +100,21 @@
 
   // Here, we will explicitly create four nodes.  In more sophisticated
   // topologies, we could configure a node factory.
-  Node* n0 = new InternetNode ();
-  Node* n1 = new InternetNode (); 
-  Node* n2 = new InternetNode (); 
-  Node* n3 = new InternetNode ();
+  Ptr<Node> n0 = MakeNewObject<InternetNode> ();
+  Ptr<Node> n1 = MakeNewObject<InternetNode> (); 
+  Ptr<Node> n2 = MakeNewObject<InternetNode> (); 
+  Ptr<Node> n3 = MakeNewObject<InternetNode> ();
 
   // We create the channels first without any IP addressing information
-  PointToPointChannel *channel0 = 
+  Ptr<PointToPointChannel> channel0 = 
     PointToPointTopology::AddPointToPointLink (
       n0, n2, DataRate(5000000), MilliSeconds(2));
 
-  PointToPointChannel *channel1 = 
+  Ptr<PointToPointChannel> channel1 = 
     PointToPointTopology::AddPointToPointLink (
       n1, n2, DataRate(5000000), MilliSeconds(2));
   
-  PointToPointChannel *channel2 = 
+  Ptr<PointToPointChannel> channel2 = 
     PointToPointTopology::AddPointToPointLink (
       n2, n3, DataRate(1500000), MilliSeconds(10));
   
@@ -122,21 +122,27 @@
   PointToPointTopology::AddIpv4Addresses (
       channel0, n0, Ipv4Address("10.1.1.1"),
       n2, Ipv4Address("10.1.1.2"));
-  channel0->Unref ();
   
   PointToPointTopology::AddIpv4Addresses (
       channel1, n1, Ipv4Address("10.1.2.1"),
       n2, Ipv4Address("10.1.2.2"));
-  channel1->Unref ();
   
   PointToPointTopology::AddIpv4Addresses (
       channel2, n2, Ipv4Address("10.1.3.1"),
       n3, Ipv4Address("10.1.3.2"));
-  channel2->Unref ();
+
+  // Finally, we add static routes.  These three steps (Channel and
+  // NetDevice creation, IP Address assignment, and routing) are 
+  // separated because there may be a need to postpone IP Address
+  // assignment (emulation) or modify to use dynamic routing
+  PointToPointTopology::AddIpv4Routes(n0, n2, channel0);
+  PointToPointTopology::AddIpv4Routes(n1, n2, channel1);
+  PointToPointTopology::AddIpv4Routes(n2, n3, channel2);
+
 
   // Create the OnOff application to send UDP datagrams of size
   // 210 bytes at a rate of 448 Kb/s
-  OnOffApplication* ooff0 = new OnOffApplication(
+  Ptr<OnOffApplication> ooff = MakeNewObject<OnOffApplication> (
     n0, 
     Ipv4Address("10.1.3.2"), 
     80, 
@@ -144,19 +150,12 @@
     ConstantVariable(0), 
     DataRate(448000), 
     210);
-  // Add to Node's ApplicationList (takes ownership of pointer)
-  ApplicationList *apl0 = n0->QueryInterface<ApplicationList> 
-    (ApplicationList::iid);
-  apl0->Add(ooff0);
-  apl0->Unref ();
-
   // Start the application
-  ooff0->Start(Seconds(1.0));
-  ooff0->Stop (Seconds(10.0));
-  ooff0->Unref ();
+  ooff->Start(Seconds(1.0));
+  ooff->Stop (Seconds(10.0));
 
   // Create a similar flow from n3 to n1, starting at time 1.1 seconds
-  OnOffApplication* ooff1 = new OnOffApplication(
+  ooff = MakeNewObject<OnOffApplication> (
     n3, 
     Ipv4Address("10.1.2.1"), 
     80, 
@@ -164,30 +163,18 @@
     ConstantVariable(0), 
     DataRate(448000), 
     210);
-  // Add to Node's ApplicationList (takes ownership of pointer)
-  ApplicationList *apl3 = n3->QueryInterface<ApplicationList> (ApplicationList::iid);
-  apl3->Add(ooff1);
-  apl3->Unref ();
   // Start the application
-  ooff1->Start(Seconds(1.1));
-  ooff1->Stop (Seconds(10.0));
-  ooff1->Unref ();
+  ooff->Start(Seconds(1.1));
+  ooff->Stop (Seconds(10.0));
 
   // Here, finish off packet routing configuration
   // This will likely set by some global StaticRouting object in the future
-  IIpv4 *ipv4;
+  Ptr<IIpv4> ipv4;
   ipv4 = n0->QueryInterface<IIpv4> (IIpv4::iid);
   ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1);
-  ipv4->Unref ();
   ipv4 = n3->QueryInterface<IIpv4> (IIpv4::iid);
   ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1);
-  ipv4->Unref ();
-
-  n0->Unref ();
-  n1->Unref ();
-  n2->Unref ();
-  n3->Unref ();
-
+  
   // Configure tracing of all enqueue, dequeue, and NetDevice receive events
   // Trace output will be sent to the simple-p2p.tr file
   AsciiTrace asciitrace ("simple-p2p.tr");
@@ -196,7 +183,8 @@
 
   // Also configure some tcpdump traces; each interface will be traced
   // The output files will be named simple-p2p.pcap-<nodeId>-<interfaceId>
-  // and can be read by the "tcpdump -r" command
+  // and can be read by the "tcpdump -r" command (use "-tt" option to
+  // display timestamps correctly)
   PcapTrace pcaptrace ("simple-p2p.pcap");
   pcaptrace.TraceAllIp ();
 
--- a/samples/main-ptr.cc	Sun May 13 12:46:18 2007 +0100
+++ b/samples/main-ptr.cc	Sun May 13 12:52:38 2007 +0100
@@ -1,10 +1,11 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 #include "ns3/ptr.h"
+#include "ns3/object.h"
 #include <iostream>
 
 using namespace ns3;
 
-class A 
+class A : public Object
 {
 public:
   A ();
@@ -48,7 +49,7 @@
   {
     // Create a new object of type A, store it in global 
     // variable g_a
-    Ptr<A> a = new A ();
+    Ptr<A> a = MakeNewObject<A> ();
     a->Method ();
     Ptr<A> prev = StoreA (a);
     NS_ASSERT (prev == 0);
@@ -57,18 +58,17 @@
   {
     // Create a new object of type A, store it in global 
     // variable g_a, get a hold on the previous A object.
-    Ptr<A> a = new A ();
+    Ptr<A> a = MakeNewObject<A> ();
     Ptr<A> prev = StoreA (a);
     // call method on object
     prev->Method ();
     // Clear the currently-stored object
     ClearA ();
-    // remove the raw pointer from its smart pointer.
-    // we can do this because the refcount is exactly one
-    // here
-    A *raw = prev.Remove ();
+    // get the raw pointer and release it.
+    A *raw = GetPointer (prev);
+    prev = 0;
     raw->Method ();
-    delete raw;
+    raw->Unref ();
   }
 
 
--- a/samples/main-simple.cc	Sun May 13 12:46:18 2007 +0100
+++ b/samples/main-simple.cc	Sun May 13 12:52:38 2007 +0100
@@ -9,7 +9,7 @@
 using namespace ns3;
 
 static void
-GenerateTraffic (Socket *socket, uint32_t size)
+GenerateTraffic (Ptr<Socket> socket, uint32_t size)
 {
   std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, tx bytes=" << size << std::endl;
   socket->Send (0, size);
@@ -24,32 +24,30 @@
 }
 
 static void
-SocketPrinter (Socket *socket, uint32_t size, const Ipv4Address &from, uint16_t fromPort)
+SocketPrinter (Ptr<Socket> socket, uint32_t size, const Ipv4Address &from, uint16_t fromPort)
 {
   std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << size << std::endl;
 }
 
 static void
-PrintTraffic (Socket *socket)
+PrintTraffic (Ptr<Socket> socket)
 {
   socket->RecvDummy (MakeCallback (&SocketPrinter));
 }
 
-int main (int argc, char *argv[])
+void
+RunSimulation (void)
 {
-  InternetNode *a = new InternetNode ();
+  Ptr<InternetNode> a = MakeNewObject<InternetNode> ();
 
-  IUdp *udp;
-  udp = a->QueryInterface<IUdp> (IUdp::iid);
+  Ptr<IUdp> udp = a->QueryInterface<IUdp> (IUdp::iid);
 
-  Socket *sink = udp->CreateSocket ();
+  Ptr<Socket> sink = udp->CreateSocket ();
   sink->Bind (80);
 
-  Socket *source = udp->CreateSocket ();
+  Ptr<Socket> source = udp->CreateSocket ();
   source->Connect (Ipv4Address::GetLoopback (), 80);
 
-  udp->Unref ();
-
   GenerateTraffic (source, 500);
   PrintTraffic (sink);
 
@@ -57,10 +55,11 @@
   Simulator::Run ();
 
   Simulator::Destroy ();
+}
 
-  sink->Unref ();
-  source->Unref ();
-  a->Unref ();
+int main (int argc, char *argv[])
+{
+  RunSimulation ();
 
   return 0;
 }
--- a/src/applications/application-list.cc	Sun May 13 12:46:18 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-// -*- Mode:NS3 -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-// Implement the application list capability for NS3 nodes
-// George F. Riley, Georgia Tech, Spring 2007
-
-#include "application.h"
-#include "application-list.h"
-
-namespace ns3{
-
-const Iid ApplicationList::iid ("ApplicationList");
-
-ApplicationList::ApplicationList(Node* n)
-  : NsUnknown (ApplicationList::iid)
-{}
-
-void 
-ApplicationList::DoDispose (void)
-{
-  for (std::vector<Application*>::const_iterator i = m_apps.begin();
-       i != m_apps.end(); ++i)
-    {
-      Application *app = *i;
-      app->Dispose ();
-      app->Unref ();
-    }
-  m_apps.clear ();
-  NsUnknown::DoDispose ();
-}
-  
-ApplicationList::~ApplicationList()
-{}
-
-ApplicationList* ApplicationList::Copy(Node * n) const 
-{ // Copy this app list
-  ApplicationList* r = new ApplicationList(n);
-  return r;
-}
-
-void
-ApplicationList::Add(Application* a)
-{
-  a->Ref ();
-  m_apps.push_back(a);
-}
-
-void ApplicationList::SetNode(Node * n)
-{
-  // Set the node pointer in each application
-  for (std::vector<Application *>::const_iterator i = m_apps.begin();
-       i != m_apps.end(); ++i)
-    { // Set correct node pointer in each app
-      (*i)->SetNode(n);
-    }
-}
-  
-
-uint32_t ApplicationList::Count() const
-{
-  return m_apps.size();
-}
-
-Application* ApplicationList::Get(uint32_t i) const
-{ // Get the i'th application. Note, this is linear time in N
-  if (m_apps.empty()) return 0;        // List is empty
-  return m_apps[i];
-}
-  
-}//namespace ns3
--- a/src/applications/application-list.h	Sun May 13 12:46:18 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-// -*- Mode:NS3 -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-// Manages the list of applications associated with a node.
-// George F. Riley, Georgia Tech, Spring 2007
-
-#ifndef __APPLICATION_LIST_H__
-#define __APPLICATION_LIST_H__
-
-#include "application.h"
-#include "ns3/ns-unknown.h"
-#include <vector>
-
-namespace ns3 {
-
-class ApplicationList : public NsUnknown
-{
-public:
-  static const Iid iid;
-  ApplicationList(Node*);
-  // Copy constructor not needed, default one is correct
-  virtual ~ApplicationList();
-  // Inherited from Capabilty
-  virtual ApplicationList* Copy(Node*) const;
-  virtual void SetNode(Node *);              // Sets the node for all apps
-  virtual void Add(Application*);      // Add an already new'ed app
-  // Manage the list
-  template <typename T> T* AddCopy(const T& t)  // Add a new application
-  {
-    T* a = t.Copy();
-    m_apps.push_back(a);
-    return a;
-  }
-  void Remove(Application*);                // Application has finished
-  uint32_t Count() const;  // Number of applications
-  Application* Get(uint32_t i) const; // Get app by index
-  
-protected:
-  virtual void DoDispose (void);
-private:
-  std::vector<Application*> m_apps;
-};
-
-}//namespace ns3
-#endif
-
--- a/src/applications/application.cc	Sun May 13 12:46:18 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 Georgia Tech Research Corporation
- *
- * 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: George F. Riley<riley@ece.gatech.edu>
- */
-
-// Implementation for ns3 Application base class.
-// George F. Riley, Georgia Tech, Fall 2006
-
-#include "application.h"
-#include "ns3/node.h"
-#include "ns3/nstime.h"
-#include "ns3/random-variable.h"
-#include "ns3/simulator.h"
-
-using namespace std;
-
-namespace ns3 {
-
-// Application Methods
-
-// \brief Application Constructor
-Application::Application(Node * n) 
-    : m_node (n),
-      m_startVar(0), m_stopVar(0),
-      m_start(false), m_stop(false)
-{
-  m_node->Ref ();
-}
-
-Application::Application(const Application& o)
-    : m_node(0), m_startVar(0), m_stopVar(0),
-      m_start(false), m_stop(false)
-{ // Copy constructor
-  m_node = o.m_node;
-  m_node->Ref ();
-  // Copy the start and stop random variables if they exist
-  if (o.m_startVar) m_startVar = o.m_startVar->Copy();
-  if (o.m_stopVar)  m_stopVar  = o.m_stopVar->Copy();
-  if (o.m_start)    ScheduleStart();
-  if (o.m_stop)     ScheduleStop();
-}
-
-  
-// \brief Application Destructor
-Application::~Application()
-{}
-
-void
-Application::DoDispose (void)
-{
-  if (m_node != 0)
-    {
-      m_node->Unref ();
-      m_node = 0;
-    }
-  if (m_start) 
-    {
-      Simulator::Cancel(m_startEvent);
-      m_start = false;
-    }
-  if (m_stop) 
-    {
-      Simulator::Cancel(m_stopEvent);
-      m_stop = false;
-    }
-  delete m_startVar;
-  m_startVar = 0;
-  delete m_stopVar;
-  m_stopVar = 0;
-}
-  
-Application& Application::operator=(const Application& rhs)
-{
-  if (this == &rhs) return *this; // Self assignment
-  m_node->Unref ();
-  m_node = 0;
-  m_node = rhs.m_node;
-  m_node->Ref ();
-
-  delete m_startVar;
-  m_startVar = 0;
-  if (rhs.m_startVar) m_startVar = rhs.m_startVar->Copy();
-  
-  delete m_stopVar;
-  m_stopVar = 0;
-  if (rhs.m_stopVar) m_stopVar = rhs.m_stopVar->Copy();
-  
-  m_start = false;
-  if (rhs.m_start) ScheduleStart();
-  if (rhs.m_stop)  ScheduleStop();
-  return *this;
-}
-  
-   
-// \brief Specify application start time
-// The virtual method STartApp will be called at the time
-// specified by startTime.
-// \param Time to start application (absolute time, from start of simulation)
-void Application::Start(const Time& startTime)
-{
-  delete m_startVar;
-  m_startVar = new ConstantVariable(startTime.GetSeconds());
-  ScheduleStart();
-}
-
-void Application::Start(const RandomVariable& startVar)
-{ // Start at random time
-  delete m_startVar;
-  m_startVar = startVar.Copy();
-  ScheduleStart();
-}
-
-   
-// \brief Specify application stop time
-// The virtual method StopApp will be called at the time
-// specified by stopTime.
-// \param Time to stop application (absolute time, from start of simulation)
-void Application::Stop(const Time& stopTime)
-{
-  delete m_stopVar;
-  m_stopVar = new ConstantVariable(stopTime.GetSeconds());
-  ScheduleStop();
-}
-
-void Application::Stop(const RandomVariable& stopVar)
-{ // Stop at random time
-  delete m_stopVar;
-  m_stopVar = stopVar.Copy();
-  ScheduleStop();
-}
-
-// \brief Assign this application to a given node
-// Called by the application manager capability when adding
-// an application to a node.
-void Application::SetNode(Node * n)
-{
-  if (m_node != 0)
-    {
-      m_node->Unref ();
-    }
-  m_node = n;
-  m_node->Ref ();
-}
-  
-Node* Application::PeekNode() const
-{
-  return m_node;
-}
-
-// Protected methods
-// StartApp and StopApp will likely be overridden by application subclasses
-void Application::StartApplication()
-{ // Provide null functionality in case subclass is not interested
-}
-
-void Application::StopApplication()
-{ // Provide null functionality in case subclass is not interested
-}
-
-
-// Private helpers
-void Application::ScheduleStart()
-{
-  m_startEvent = Simulator::Schedule(Seconds(m_startVar->GetValue()) -
-                                     Simulator::Now(),
-                                     &Application::StartApplication, this);
-  m_start = true;
-}
-
-void Application::ScheduleStop()
-{
-  m_stopEvent = Simulator::Schedule(Seconds(m_stopVar->GetValue()) -
-                                     Simulator::Now(),
-                                     &Application::StopApplication, this);
-  m_stop = true;
-}
-
-} //namespace ns3
-      
-  
--- a/src/applications/application.h	Sun May 13 12:46:18 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 Georgia Tech Research Corporation
- *
- * 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: George F. Riley<riley@ece.gatech.edu>
- */
-
-#ifndef __APPLICATION_H__
-#define __APPLICATION_H__
-
-#include "ns3/event-id.h"
-#include "ns3/nstime.h"
-#include "ns3/object.h"
-
-namespace ns3 {
-
-class Node;
-class RandomVariable;
-  
-/**
- * \brief The base class for all ns3 applicationes
- * 
- * Class Application is the base class for all ns3 applications.
- * Applications are associated with individual nodes, and are created
- * using the AddApplication method in the ApplicationManager capability.
- * 
- * Conceptually, an application has zero or more Socket
- * objects associated with it, that are created using the Socket
- * creation API of the Kernel capability.  The Socket object
- * API is modeled after the
- * well-known BSD sockets interface, although it is somewhat 
- * simplified for use with ns3.  Further, any socket call that
- * would normally "block" in normal sockets will return immediately
- * in ns3.  A set of "upcalls" are defined that will be called when
- * the previous blocking call would normally exit.  THis is documented
- * in more detail Socket class in socket.h.
- * 
- * There is a second application class in ns3, called "ThreadedApplication"
- * that implements a true sockets interface, which should be used
- * when porting existing sockets code to ns3.  The true
- * sockets approach is significantly
- * less memory--efficient using private stacks for each defined application,
- * so that approach should be used with care.  The design and implementation
- * of the ThreadedApplication are still being discussed.
- */
-class Application : public Object
-{
-public:
-  Application(Node *);
-  Application(const Application&);  // Copy constructor
-  Application& operator=(const Application&); // Assignment operator
-  virtual ~Application();
-  
-  virtual Application* Copy() const = 0; // All applications must provide
-  
-  /**
-   * \brief Specify application start time
-   *
-   * Applications start at various times in the simulation scenario.
-   * The Start method specifies when the application should be
-   * started.  The application subclasses should override the
-   * private "StartApplication" method defined below, which is called at the
-   * time specified, to cause the application to begin.
-   * \param Start time for this application, relative to the
-   * current simulation time.
-   */
-  void Start(const Time&);
-
-  /**
-   * \brief Same as above, but uses a random variable for start time
-   *
-   * The random variable returns the desired start time in units of
-   * Seconds.
-   */
-  
-void Start(const RandomVariable&);
-  
-  /**
-   * \brief Specify application stop time
-   *
-   * Once an application has started, it is sometimes useful
-   * to stop the application.  The Stop method specifies when an
-   * application is to stop.  The application subclasses should override
-   * the private StopApplication method defined below, to cause the application
-   * to stop.
-   * \param Stop time for this application, relative to the
-   * current simulation time.
-   */
-  void Stop(const Time&);
-
-  /**
-   * \brief Same as above, but uses a random variable for stop time
-   *
-   * The random variable returns the desired stop time in units of
-   * Seconds.
-   */
-  void Stop(const RandomVariable&);
-  
-  /**
-   * \brief Attaches an application to a specific node
-   *
-   * Specifies which node object this application is associated with.
-   * \param Node object to associate with this application.
-   */
-  void SetNode(Node *);
-
-  /**
-   * \brief Returns the pointer to the attached node.
-   */
-  Node* PeekNode() const;
-  
-  // Members
-  Node          * m_node;      // All applications have an associated node
-  RandomVariable* m_startVar;  // Random variable for start time
-  RandomVariable* m_stopVar;   // Random variable for stop time
-  EventId         m_startEvent;// Event identifier for start event
-  EventId         m_stopEvent; // Event identifier for the stop event
-  bool            m_start;     // True if start event scheduled
-  bool            m_stop;      // True if stop event scheduled
-  
-protected:
-  // \brief Application specific startup code
-  // The StartApplication method is called at the start time specifed by Start
-  // This method should be overridden by all or most application
-  // subclasses.
-  virtual void StartApplication();
-
-  // \brief Application specific shutdown code
-  // The StopApplication method is called at the stop time specifed by Stop
-  // This method should be overridden by all or most application
-  // subclasses.
-  virtual void StopApplication();
-
-  virtual void DoDispose (void);
-private:
-  // Helpers
-  void ScheduleStart();
-  void ScheduleStop();
-};
-
-} //namespace ns3
-#endif
--- a/src/applications/onoff-application.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/applications/onoff-application.cc	Sun May 13 12:52:38 2007 +0100
@@ -42,7 +42,7 @@
 
 // Constructors
 
-  OnOffApplication::OnOffApplication(Node * n, 
+  OnOffApplication::OnOffApplication(Ptr<Node> n, 
                                      const Ipv4Address  rip,   // Remote IP addr
                                      uint16_t       rport, // Remote port
                                      const  RandomVariable& ontime,
@@ -67,7 +67,7 @@
 {
 }
 
-OnOffApplication::OnOffApplication(Node * n, const OnOffApplication& c)
+OnOffApplication::OnOffApplication(Ptr<Node> n, const OnOffApplication& c)
   : Application(n), 
     m_socket(0),
     m_peerIP(c.m_peerIP),
@@ -92,11 +92,7 @@
 void
 OnOffApplication::DoDispose (void)
 {
-  if (m_socket != 0)
-    {
-      m_socket->Unref ();
-      m_socket = 0;
-    }
+  m_socket = 0;
   delete m_onTime;
   delete m_offTime;
 
@@ -170,9 +166,8 @@
                                      this));
 #endif
       
-      IUdp *udp = PeekNode ()->QueryInterface<IUdp> (IUdp::iid);
+      Ptr<IUdp> udp = GetNode ()->QueryInterface<IUdp> (IUdp::iid);
       m_socket = udp->CreateSocket ();
-      udp->Unref ();
       m_socket->Connect (m_peerIP, m_peerPort);
     }
   StopApplication();                         // Insure no pending event
@@ -199,11 +194,6 @@
     }
 }
 
-OnOffApplication* OnOffApplication::Copy() const
-{
-  return new OnOffApplication(*this);
-}
-
 // Event handlers
 void OnOffApplication::StartSending()
 {
@@ -263,13 +253,13 @@
   ScheduleNextTx();
 }
 
-void OnOffApplication::ConnectionSucceeded(Socket*)
+void OnOffApplication::ConnectionSucceeded(Ptr<Socket>)
 {
   m_connected = true;
   ScheduleStartEvent();
 }
   
-void OnOffApplication::ConnectionFailed(Socket*)
+void OnOffApplication::ConnectionFailed(Ptr<Socket>)
 {
   cout << "OnOffApplication, Connection Failed" << endl;
 }
--- a/src/applications/onoff-application.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/applications/onoff-application.h	Sun May 13 12:52:38 2007 +0100
@@ -27,8 +27,9 @@
 #ifndef __onoff_application_h__
 #define __onoff_application_h__
 
-#include "application.h"
+#include "ns3/application.h"
 #include "ns3/event-id.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -40,7 +41,7 @@
 class OnOffApplication : public Application {
 
 public:
-  OnOffApplication(Node * n,
+  OnOffApplication(Ptr<Node> n,
                    const Ipv4Address,  // Peer IP address
                    uint16_t,           // Peer port
                    const RandomVariable&,     // Random variable for On time
@@ -48,11 +49,10 @@
                    DataRate  = g_defaultRate,  // Data rate when on
                    uint32_t = g_defaultSize);  // Size of packets
 
-  OnOffApplication(Node * n, const OnOffApplication&); // Copy constructor
+  OnOffApplication(Ptr<Node> n, const OnOffApplication&); // Copy constructor
   virtual ~OnOffApplication();               // Destructor
   virtual void StartApplication();    // Called at time specified by Start
   virtual void StopApplication();     // Called at time specified by Stop
-  virtual OnOffApplication* Copy() const;// Make a copy of the application
 
   // Event handlers
   void StartSending();
@@ -70,7 +70,7 @@
   static void DefaultSize(uint32_t s) { g_defaultSize = s;}
 
 public:
-  Socket        * m_socket;       // Associated socket
+  Ptr<Socket>     m_socket;       // Associated socket
   Ipv4Address     m_peerIP;       // Peer IP address
   uint16_t        m_peerPort;     // Peer port
   bool            m_connected;    // True if connected
@@ -96,9 +96,9 @@
   void ScheduleNextTx();
   void ScheduleStartEvent();
   void ScheduleStopEvent();
-  void ConnectionSucceeded(Socket*);
-  void ConnectionFailed(Socket*);
-  void Ignore(Socket*);
+  void ConnectionSucceeded(Ptr<Socket>);
+  void ConnectionFailed(Ptr<Socket>);
+  void Ignore(Ptr<Socket>);
 protected:
 };
 
--- a/src/applications/wscript	Sun May 13 12:46:18 2007 +0100
+++ b/src/applications/wscript	Sun May 13 12:52:38 2007 +0100
@@ -7,14 +7,10 @@
     obj.target = obj.name
     obj.uselib_local = ['ns3-node']
     obj.source = [
-        'application-list.cc',
-        'application.cc',
         'onoff-application.cc',
         ]
 
     headers = bld.create_obj('ns3header')
     headers.source = [
-        'application-list.h',
-        'application.h',
         'onoff-application.h',
         ]
--- a/src/common/array-trace-resolver.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/common/array-trace-resolver.h	Sun May 13 12:52:38 2007 +0100
@@ -87,7 +87,6 @@
   Callback<uint32_t> m_getSize;
   Callback<T *, uint32_t> m_get;
 };
-
 }//namespace ns3
 
 namespace ns3 {
@@ -108,8 +107,8 @@
 
 template <typename T>
 ArrayTraceResolver<T>::ArrayTraceResolver (TraceContext const &context,
-                                                   Callback<uint32_t> getSize, 
-						   Callback<T *, uint32_t> get)
+                                           Callback<uint32_t> getSize, 
+                                           Callback<T *, uint32_t> get)
   : TraceResolver (context),
     m_getSize (getSize),
     m_get (get)
@@ -120,15 +119,15 @@
 {
   TraceResolverList list;
   if (id == "*")
+  {
+    for (uint32_t i = 0; i < m_getSize (); i++)
     {
-      for (uint32_t i = 0; i < m_getSize (); i++)
-	{
 	  TraceContext context = GetContext ();
-          typename ArrayTraceResolver<T>::Index index = typename ArrayTraceResolver<T>::Index (i);
+      typename ArrayTraceResolver<T>::Index index = typename ArrayTraceResolver<T>::Index (i);
 	  context.Add (index);
 	  list.push_back (m_get (i)->CreateTraceResolver (context));
-	}
     }
+  }
   return list;
 }
 
--- a/src/core/command-line.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/core/command-line.cc	Sun May 13 12:52:38 2007 +0100
@@ -1,4 +1,23 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech University, 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: Raj Bhattacharjea <raj.b@gatech.edu>,
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
 
 #include "command-line.h"
 #include <unistd.h>
--- a/src/core/command-line.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/core/command-line.h	Sun May 13 12:52:38 2007 +0100
@@ -1,4 +1,23 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech University, 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: Raj Bhattacharjea <raj.b@gatech.edu>,
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
 #ifndef COMMAND_LINE_H
 #define COMMAND_LINE_H
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/component-manager.cc	Sun May 13 12:52:38 2007 +0100
@@ -0,0 +1,243 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "component-manager.h"
+#include "uid-manager.h"
+#include "singleton.h"
+
+namespace ns3 {
+
+// we redefine a UidManager type for the class id singleton below.
+// otherwise, we would have to share the same id singleton instance
+// with the Iids.
+class CidManager : public UidManager
+{};
+
+ClassId::ClassId (std::string name)
+  : m_classId (Singleton<CidManager>::Get ()->Allocate (name))
+{}
+
+ClassId::ClassId (uint32_t classId)
+  : m_classId (classId)
+{}
+
+std::string 
+ClassId::GetName (void)
+{
+  return Singleton<CidManager>::Get ()->LookupByUid (m_classId);
+}
+
+bool operator == (const ClassId &a, const ClassId &b)
+{
+  return a.m_classId == b.m_classId;
+}
+
+Ptr<Interface>
+ComponentManager::Create (ClassId classId)
+{
+  Callback<Ptr<Interface> > callback = DoGetCallback<empty,empty,empty,empty,empty> (classId);
+  return callback ();
+}
+
+CallbackBase *
+ComponentManager::Lookup (ClassId classId)
+{
+  List *list = Singleton<List>::Get ();
+  for (List::const_iterator i = list->begin (); i != list->end (); i++)
+    {
+      if (i->first == classId)
+	{
+	  return i->second;
+	}
+    }
+  return 0;
+}
+
+ClassId 
+ComponentManager::LookupByName (std::string name)
+{
+  return ClassId (Singleton<CidManager>::Get ()->LookupByName (name));
+}
+
+ClassId
+ComponentManager::Register (std::string name, CallbackBase *callback)
+{
+  ClassId classId = ClassId (name);
+  List *list = Singleton<List>::Get ();
+  list->push_back (std::make_pair (classId, callback));
+  return classId;
+}
+
+
+} // namespace ns3
+
+#ifdef RUN_SELF_TESTS
+
+#include "test.h"
+#include "interface.h"
+
+namespace {
+
+
+class B : public ns3::Interface
+{
+public:
+  static const ns3::InterfaceId iid;
+  B ();
+};
+
+const ns3::InterfaceId B::iid ("IB");
+
+B::B ()
+  : Interface (B::iid)
+{}
+
+
+class A : public ns3::Interface
+{
+public:
+  static const ns3::ClassId cidZero;
+  static const ns3::ClassId cidOneBool;
+  static const ns3::ClassId cidOneUi32;
+  static const ns3::InterfaceId iid;
+
+  A ();
+  A (bool);
+  A (uint32_t);
+
+  bool m_zeroInvoked;
+  bool m_oneBoolInvoked;
+  bool m_oneUi32Invoked;
+
+  bool m_bool;
+  int m_ui32;
+};
+
+const ns3::ClassId A::cidZero = ns3::ComponentManager::RegisterConstructor <A> ("A");
+const ns3::ClassId A::cidOneBool = ns3::ComponentManager::RegisterConstructor <A,bool> ("ABool");
+const ns3::ClassId A::cidOneUi32 = ns3::ComponentManager::RegisterConstructor <A,uint32_t> ("AUi32");
+const ns3::InterfaceId A::iid ("IA");
+
+A::A ()
+  : Interface (A::iid),
+    m_zeroInvoked (true),
+    m_oneBoolInvoked (false),
+    m_oneUi32Invoked (false)
+{
+  ns3::Ptr<B> b = ns3::MakeNewObject<B> ();
+  AddInterface (b);
+}
+
+A::A (bool bo)
+  : Interface (A::iid),
+    m_zeroInvoked (false),
+    m_oneBoolInvoked (true),
+    m_oneUi32Invoked (false),
+    m_bool (bo)
+{
+  ns3::Ptr<B> b = ns3::MakeNewObject<B> ();
+  AddInterface (b);
+}
+
+A::A (uint32_t i)
+  : Interface (A::iid),
+    m_zeroInvoked (false),
+    m_oneBoolInvoked (false),
+    m_oneUi32Invoked (true),
+    m_ui32 (i)
+{
+  ns3::Ptr<B> b = ns3::MakeNewObject<B> ();
+  AddInterface (b);
+}
+
+}
+
+namespace ns3 {
+
+class ComponentManagerTest : public Test
+{
+public:
+  ComponentManagerTest ();
+  virtual bool RunTests (void);
+};
+
+ComponentManagerTest::ComponentManagerTest ()
+  : Test ("ComponentManager")
+{}
+bool 
+ComponentManagerTest::RunTests (void)
+{
+  bool ok = true;
+
+  Ptr<A> a = 0;
+  a = ComponentManager::Create<A> (A::cidZero, A::iid);
+  if (a == 0 ||
+      !a->m_zeroInvoked)
+    {
+      ok = false;
+    }
+
+  a = ComponentManager::Create<A,bool> (A::cidOneBool, A::iid, true);
+  if (a == 0 ||
+      !a->m_oneBoolInvoked ||
+      !a->m_bool)
+    {
+      ok = false;
+    }
+
+  a = ComponentManager::Create<A,bool> (A::cidOneBool, A::iid, false);
+  if (a == 0 ||
+      !a->m_oneBoolInvoked ||
+      a->m_bool)
+    {
+      ok = false;
+    }
+
+  a = ComponentManager::Create<A,uint32_t> (A::cidOneUi32, A::iid, 10);
+  if (a == 0 ||
+      !a->m_oneUi32Invoked ||
+      a->m_ui32 != 10)
+    {
+      ok = false;
+    }
+
+  a = ComponentManager::Create<A> (A::cidOneUi32, A::iid, (uint32_t)10);
+  if (a == 0 ||
+      !a->m_oneUi32Invoked ||
+      a->m_ui32 != 10)
+    {
+      ok = false;
+    }
+
+  Ptr<B> b = ComponentManager::Create<B,uint32_t> (A::cidOneUi32, B::iid, 10);
+  if (b == 0)
+    {
+      ok = false;
+    }
+
+  return ok;
+}
+
+
+static ComponentManagerTest g_unknownManagerTest;
+
+} // namespace ns3
+
+#endif /* RUN_SELF_TESTS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/component-manager.h	Sun May 13 12:52:38 2007 +0100
@@ -0,0 +1,274 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef NS_UNKNOWN_MANAGER_H
+#define NS_UNKNOWN_MANAGER_H
+
+#include <string>
+#include <vector>
+#include <stdint.h>
+#include "callback.h"
+#include "interface.h"
+#include "fatal-error.h"
+#include "ptr.h"
+
+namespace ns3 {
+
+/**
+ * \brief Unique Identifier for class constructors.
+ *
+ * Instances of this type must be allocated through
+ * the ns3::Ns3UnknownManager::RegisterConstructor methods
+ */
+class ClassId
+{
+public:
+  /**
+   * \returns the symbolic name associated to this class id
+   *
+   * This name is the name which was associated to this class id
+   * by the ns3::Ns3UnknownManager::RegisterConstructor methods.
+   * This name is also the name which is expected to be input
+   * to ns3::UnknownManager::LookupByName.
+   */
+  std::string GetName (void);
+private:
+  ClassId (std::string name);
+  ClassId (uint32_t classId);
+  friend class ComponentManager;
+  friend bool operator == (const ClassId &a, const ClassId &b);
+  uint32_t m_classId;
+};
+
+/**
+ * \brief Create any Interface
+ *
+ * This class keeps track of a set of ClassId, each
+ * of which uniquely identifies the constructor of an
+ * object which derives from the Interface base class.
+ * This class can also create an instance of any of
+ * the objects tracked through any of their tracked
+ * constructor/ClassId.
+ */
+class ComponentManager
+{
+public:
+  /**
+   * \param name the symbolic name to lookup
+   * \returns the ClassId associated to the input name.
+   */
+  static ClassId LookupByName (std::string name);
+
+  /**
+   * \param classId class id of the constructor to invoke.
+   * \return a pointer to the instance created.
+   *
+   * Create an instance of the object identified by its
+   * ClassId. This method invokes the default constructor.
+   */
+  static Ptr<Interface> Create (ClassId classId);
+
+  /**
+   * \param classId class id of the constructor to invoke.
+   * \param a1 argument to pass to the constructor.
+   * \return a pointer to the instance created.
+   *
+   * Create an instance of the object identified by its
+   * ClassId.
+   */
+  template <typename T1>
+  static Ptr<Interface> Create (ClassId classId, T1 a1);
+
+  /**
+   * \param classId class id of the constructor to invoke.
+   * \param a1 first argument to pass to the constructor.
+   * \param a2 second argument to pass to the constructor.
+   * \return a pointer to the instance created.
+   *
+   * Create an instance of the object identified by its
+   * ClassId.
+   */
+  template <typename T1, typename T2>
+  static Ptr<Interface> Create (ClassId classId, T1 a1, T2 a2);
+
+  /**
+   * \param classId class id of the constructor to invoke.
+   * \param iid interface id to query for
+   * \return a pointer to the instance created.
+   *
+   * Create an instance of the object identified by its
+   * ClassId, call QueryInterface on it, and return the 
+   * result.
+   */
+  template <typename T>
+  static Ptr<T> Create (ClassId classId, InterfaceId iid);
+
+  template <typename T, typename T1>
+  static Ptr<T> Create (ClassId classId, InterfaceId iid, T1 a1);
+
+  template <typename T, typename T1, typename T2>
+  static Ptr<T> Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2);
+
+  /**
+   * \param name the symbolic name to associate to this
+   *        constructor
+   * \returns a ClassId which uniquely identifies this constructor.
+   */
+  template <typename T>
+  static ClassId RegisterConstructor (std::string name)
+  {
+    static Callback<Ptr<Interface> > callback = 
+      MakeCallback (&ComponentManager::MakeObjectZero<T>);
+    return ComponentManager::Register (name, &callback);
+  }
+
+  /**
+   * \param name the symbolic name to associate to this
+   *        constructor
+   * \returns a ClassId which uniquely identifies this constructor.
+   */
+  template <typename T, typename T1>
+  static ClassId RegisterConstructor (std::string name)
+  {
+    static Callback<Ptr<Interface> ,T1> callback = MakeCallback (&ComponentManager::MakeObjectOne<T,T1>);
+    return ComponentManager::Register (name, &callback);
+  }
+
+  /**
+   * \param name the symbolic name to associate to this
+   *        constructor
+   * \returns a ClassId which uniquely identifies this constructor.
+   */
+  template <typename T, typename T1, typename T2>
+  static ClassId RegisterConstructor (std::string name)
+  {
+    static Callback<Ptr<Interface>,T1,T2> callback = MakeCallback (&ComponentManager::MakeObjectTwo<T,T1,T2>);
+    return ComponentManager::Register (name, &callback);
+  }
+private:
+  static ClassId Register (std::string name, CallbackBase *callback);
+
+  template <typename T1, typename T2,
+            typename T3, typename T4,
+            typename T5>
+  static Callback<Ptr<Interface>,T1,T2,T3,T4,T5> DoGetCallback (ClassId classId);
+
+  template <typename T>
+  static Ptr<Interface> MakeObjectZero (void);
+
+  template <typename T, typename T1>
+  static Ptr<Interface> MakeObjectOne (T1 a1);
+
+  template <typename T, typename T1, typename T2>
+  static Ptr<Interface> MakeObjectTwo (T1 a1, T2 a2);
+
+  typedef std::vector<std::pair<ClassId, CallbackBase *> > List;
+  static List *GetList (void);
+  static CallbackBase *Lookup (ClassId classId);
+};
+
+} // namespace ns3 
+
+
+namespace ns3 {
+
+template <typename T1, typename T2,
+          typename T3, typename T4,
+          typename T5>
+Callback<Ptr<Interface>,T1,T2,T3,T4,T5>
+ComponentManager::DoGetCallback (ClassId classId)
+{
+  CallbackBase *callback = Lookup (classId);
+  if (callback == 0)
+    {
+      NS_FATAL_ERROR ("Invalid Class Id.");
+    }
+  Callback<Ptr<Interface>, T1,T2,T3,T4,T5> reference;
+  reference.Assign (*callback);
+  return reference;
+}
+
+
+template <typename T1>
+Ptr<Interface>
+ComponentManager::Create (ClassId classId, T1 a1)
+{
+  Callback<Ptr<Interface>, T1> callback = DoGetCallback<T1,empty,empty,empty,empty> (classId);
+  return callback (a1);
+}
+
+template <typename T1, typename T2>
+Ptr<Interface> 
+ComponentManager::Create (ClassId classId, T1 a1, T2 a2)
+{
+  Callback<Ptr<Interface> , T1,T2> callback = DoGetCallback<T1,T2,empty,empty,empty> (classId);
+  return callback (a1, a2);
+}
+
+template <typename T>
+Ptr<T>
+ComponentManager::Create (ClassId classId, InterfaceId iid)
+{
+  Ptr<Interface> obj = Create (classId);
+  Ptr<T> i = obj->QueryInterface<T> (iid);
+  return i;
+}
+
+template <typename T, typename T1>
+Ptr<T>
+ComponentManager::Create (ClassId classId, InterfaceId iid, T1 a1)
+{
+  Ptr<Interface> obj = Create (classId, a1);
+  Ptr<T> i = obj->QueryInterface<T> (iid);
+  return i;
+}
+
+template <typename T, typename T1, typename T2>
+Ptr<T>
+ComponentManager::Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2)
+{
+  Ptr<Interface> obj = Create (classId, a1, a2);
+  Ptr<T> i = obj->QueryInterface<T> (iid);
+  return i;
+}
+
+
+template <typename T>
+Ptr<Interface> 
+ComponentManager::MakeObjectZero (void)
+{
+  return MakeNewObject<T> ();
+}
+template <typename T, typename T1>
+Ptr<Interface> 
+ComponentManager::MakeObjectOne (T1 a1)
+{
+  return MakeNewObject<T> (a1);
+}
+template <typename T, typename T1, typename T2>
+Ptr<Interface> 
+ComponentManager::MakeObjectTwo (T1 a1, T2 a2)
+{
+  return MakeNewObject<T> (a1, a2);
+}
+
+} // namespace ns3
+
+#endif /* NS_UNKNOWN_MANAGER_H */
--- a/src/core/debug.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/core/debug.cc	Sun May 13 12:52:38 2007 +0100
@@ -48,7 +48,7 @@
 DebugComponentEnableEnvVar (void)
 {
 #ifdef HAVE_GETENV
-  char *envVar = getenv("NS3_DEBUG");
+  char *envVar = getenv("NS_DEBUG");
   if (envVar == 0)
     {
       return;
--- a/src/core/default-value.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/core/default-value.cc	Sun May 13 12:52:38 2007 +0100
@@ -1,4 +1,22 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
 
 #include "default-value.h"
 #include "fatal-error.h"
--- a/src/core/default-value.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/core/default-value.h	Sun May 13 12:52:38 2007 +0100
@@ -1,4 +1,22 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
 #ifndef DEFAULT_VALUE_H
 #define DEFAULT_VALUE_H
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/interface.cc	Sun May 13 12:52:38 2007 +0100
@@ -0,0 +1,386 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "interface.h"
+#include "singleton.h"
+#include "uid-manager.h"
+#include <string>
+#include <list>
+#include <stdint.h>
+#include "assert.h"
+#include "debug.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("Interface");
+
+namespace ns3 {
+
+class IidManager : public UidManager
+{};
+
+InterfaceId::InterfaceId (std::string name)
+  : m_iid (Singleton<IidManager>::Get ()->Allocate (name))
+{}
+
+bool operator == (const InterfaceId &a, const InterfaceId &b)
+{
+  return a.m_iid == b.m_iid;
+}
+
+
+class InterfaceImpl
+{
+public:
+  InterfaceImpl (InterfaceId iid, Interface *interface);
+  ~InterfaceImpl ();
+  void Ref (void);
+  void RefAll (InterfaceImpl *other);
+  void Unref (void);
+  void UnrefAll (void);
+  Interface *PeekQueryInterface (InterfaceId iid) const;
+  void DoDisposeAll (void);
+  void AddInterface (Interface * interface);
+  void AddSelfInterface (InterfaceId iid, Interface *interface);
+private:
+  typedef std::list<std::pair<InterfaceId,Interface *> > List;
+  uint32_t m_ref;
+  List m_list;
+  bool m_disposed;
+};
+
+InterfaceImpl::InterfaceImpl (InterfaceId iid, Interface * interface)
+  : m_ref (1),
+    m_disposed (false)
+{
+  NS_DEBUG ("new " << this << " ref=" << m_ref);
+  m_list.push_back (std::make_pair (iid, interface));
+}
+InterfaceImpl::~InterfaceImpl ()
+{
+  for (List::const_iterator i = m_list.begin ();
+       i != m_list.end (); i++)
+    {
+      i->second->UnrefInternal ();
+    }
+  m_list.clear ();
+}
+void 
+InterfaceImpl::Ref (void)
+{
+  m_ref++;
+  NS_DEBUG ("inc " << this << " ref=" << m_ref);
+}
+void 
+InterfaceImpl::RefAll (InterfaceImpl *other)
+{
+  m_ref += other->m_ref;
+  NS_DEBUG ("inc all " << this << " o=" << other->m_ref << " ref=" << m_ref);
+}
+void 
+InterfaceImpl::Unref (void)
+{
+  NS_ASSERT (m_ref > 0);
+  m_ref--;
+  NS_DEBUG ("dec " << this << " ref=" << m_ref);
+  if (m_ref == 0)
+    {
+      delete this;
+    }
+}
+void
+InterfaceImpl::UnrefAll (void)
+{
+  NS_ASSERT (m_ref > 0);
+  m_ref = 0;
+  delete this;
+  NS_DEBUG ("dec all " << this);
+}
+void
+InterfaceImpl::DoDisposeAll (void)
+{
+  NS_ASSERT (!m_disposed);
+  for (List::const_iterator i = m_list.begin ();
+       i != m_list.end (); i++)
+    {
+      Interface *interface = i->second;
+      interface->DoDispose ();
+    }
+  m_disposed = true;
+}
+Interface *
+InterfaceImpl::PeekQueryInterface (InterfaceId iid) const
+{
+  for (List::const_iterator i = m_list.begin ();
+       i != m_list.end (); i++)
+    {
+      if (i->first == iid)
+	{
+	  return i->second;
+	}
+    }
+  return 0;
+}
+void 
+InterfaceImpl::AddInterface (Interface *interface)
+{
+  for (List::const_iterator i = interface->m_impl->m_list.begin ();
+       i != interface->m_impl->m_list.end (); i++)
+    {
+      // XXX here, we should check that we have only one 
+      // instance of each interface
+      i->second->RefInternal ();
+      m_list.push_back (std::make_pair (i->first, i->second));
+    }
+}
+void 
+InterfaceImpl::AddSelfInterface (InterfaceId iid, Interface *interface)
+{
+  interface->RefInternal ();
+  m_list.push_back (std::make_pair (iid, interface));
+}
+
+
+Interface::Interface (InterfaceId iid)
+  : m_impl (new InterfaceImpl (iid, this)),
+    m_ref (1)
+{}
+Interface::~Interface ()
+{
+  m_impl = 0;
+  m_ref = -1;
+}
+void 
+Interface::Ref (void) const
+{
+  m_impl->Ref ();
+}
+void 
+Interface::Unref (void) const
+{
+  m_impl->Unref ();
+}
+
+void 
+Interface::Dispose (void)
+{
+  m_impl->DoDisposeAll ();
+}
+
+void 
+Interface::DoDispose (void)
+{
+  // we do not do anything by default.
+}
+
+void
+Interface::RefInternal (void)
+{
+  m_ref++;
+}
+
+void
+Interface::UnrefInternal (void)
+{
+  NS_ASSERT (m_ref != 0);
+  m_ref--;
+  if (m_ref == 0)
+    {
+      delete this;
+    }
+}
+
+Ptr<Interface>
+Interface::DoQueryInterface (InterfaceId iid) const
+{
+  return m_impl->PeekQueryInterface (iid);
+}
+
+void 
+Interface::AddInterface (Ptr<Interface> interface)
+{
+  Interface *p = PeekPointer (interface);
+  m_impl->AddInterface (p);
+  m_impl->RefAll (p->m_impl);
+  p->m_impl->UnrefAll ();
+  p->m_impl = m_impl;
+}
+
+void
+Interface::AddSelfInterface (InterfaceId iid, Ptr<Interface> interface)
+{
+  m_impl->AddSelfInterface (iid, PeekPointer (interface));
+}
+
+
+}//namespace ns3
+
+#ifdef RUN_SELF_TESTS
+
+#include "test.h"
+
+namespace {
+
+class A : public ns3::Interface
+{
+public:
+  static const ns3::InterfaceId iid;
+  A ()
+    : Interface (A::iid)
+  {}
+};
+class B : public ns3::Interface
+{
+public:
+  static const ns3::InterfaceId iid;
+  B ()
+    : Interface (B::iid)
+  {}
+};
+class BaseA : public ns3::Interface
+{
+public:
+  static const ns3::InterfaceId iid;
+  BaseA ()
+    : Interface (BaseA::iid)
+  {}
+};
+class BaseB : public ns3::Interface
+{
+public:
+  static const ns3::InterfaceId iid;
+  BaseB ()
+    : Interface (BaseB::iid)
+  {}
+};
+class Base : public ns3::Interface
+{
+public:
+  static const ns3::InterfaceId iid;
+  Base ()
+    : Interface (Base::iid)
+  {}
+};
+class Derived : public Base
+{
+public:
+  static const ns3::InterfaceId iid;
+  Derived ()
+  {
+    AddSelfInterface (Derived::iid, this);
+  }
+};
+
+const ns3::InterfaceId A::iid ("A");
+const ns3::InterfaceId B::iid ("B");
+const ns3::InterfaceId BaseA::iid ("BaseA");
+const ns3::InterfaceId BaseB::iid ("BaseB");
+const ns3::InterfaceId Base::iid ("Base");
+const ns3::InterfaceId Derived::iid ("Derived");
+
+}//namespace
+
+
+namespace ns3 {
+
+class InterfaceTest : public Test
+{
+public:
+  InterfaceTest ();
+  virtual bool RunTests (void);
+};
+
+InterfaceTest::InterfaceTest ()
+  : Test ("Interface")
+{}
+bool 
+InterfaceTest::RunTests (void)
+{
+  bool ok = true;
+
+  //DerivedAB *derivedAB;
+
+
+  Ptr<A> a = MakeNewObject<A> ();
+
+  a = MakeNewObject<A> ();
+  Ptr<A> a1 = a->QueryInterface<A> (A::iid);
+  if (a1 == 0 || a1 != a)
+    {
+      ok = false;
+    }
+  a1 = a->QueryInterface<A> (A::iid);
+  if (a1 == 0 || a1 != a)
+    {
+      ok = false;
+    }
+
+  Ptr<B> b = MakeNewObject<B> ();
+  Ptr<B> b1 = b->QueryInterface<B> (B::iid);
+  if (b1 == 0 || b1 != b)
+    {
+      ok = false;
+    }
+  
+  a = MakeNewObject<A> ();
+  a->AddInterface (b);
+  b1 = b->QueryInterface<B> (B::iid);
+  if (b1 == 0 || b1 != b)
+    {
+      ok = false;
+    }
+  a1 = b->QueryInterface<A> (A::iid);
+  if (a1 == 0 || a1 != a)
+    {
+      ok = false;
+    }
+  a1 = a->QueryInterface<A> (A::iid);
+  if (a1 == 0 || a1 != a)
+    {
+      ok = false;
+    }
+  b1 = a->QueryInterface<B> (B::iid);
+  if (b1 == 0 || b1 != b)
+    {
+      ok = false;
+    }
+
+  Ptr<Derived> derived = MakeNewObject<Derived> ();
+  Ptr<Base> base = derived->QueryInterface<Base> (Base::iid);
+  if (base == 0)
+    {
+      ok = false;
+    }
+  Ptr<Derived> derived1 = base->QueryInterface<Derived> (Derived::iid);
+  if (derived1 == 0 || derived1 != derived)
+    {
+      ok = false;
+    }
+
+  // the following cannot work and it is on purpose
+  // delete derived;
+
+  return ok;
+}
+
+
+static InterfaceTest g_interface_test;
+
+}// namespace ns3
+
+#endif /* RUN_SELF_TESTS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/interface.h	Sun May 13 12:52:38 2007 +0100
@@ -0,0 +1,128 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef INTERFACE_H
+#define INTERFACE_H
+
+#include <string>
+#include "ptr.h"
+
+namespace ns3 {
+
+class InterfaceImpl;
+
+class InterfaceId
+{
+public:
+  InterfaceId (std::string name);
+private:
+  friend bool operator == (const InterfaceId &a, const InterfaceId &b);
+  uint32_t m_iid;
+};
+
+/**
+ * \brief COM-like IUnknown
+ *
+ * This class should be used as a base class for every object which
+ * wishes to provide a COM-like QueryInterface API. Multiple 
+ * inheritance where this base class is at the top of the dreaded 
+ * "diamond" shape is not allowed.
+ */
+class Interface
+{
+public:
+  virtual ~Interface ();
+  void Ref (void) const;
+  void Unref (void) const;
+
+  /**
+   * \param iid the Interface id of the requested interface
+   */
+  template <typename T>
+  Ptr<T> QueryInterface (InterfaceId iid) const;
+
+  /**
+   * \param interface another interface
+   * 
+   * Aggregate together the two interfaces. After this call,
+   * the two interface objects are tied together: each of them
+   * will be able to perform QI on each other and their lifetimes
+   * will be found by the same reference count.
+   */
+  void AddInterface (Ptr<Interface> interface);
+
+  void Dispose (void);
+protected:
+  /**
+   * \param iid the Interface Id of the interface defined by a direct subclass
+   * of this base class
+   *
+   * If you are a direct subclass of this class, you _must_ register
+   * the name of your interface with this constructor.
+   */
+  Interface (InterfaceId iid);
+  /**
+   * \param iid the Interface id of the interface
+   * \param interface a pointer to the interface object
+   *
+   * If you are not a direct subclass of the ns3::Interface base class,
+   * and if you want to register yourself as another accessible interface
+   * (typically, your subclass has added API), you need to call
+   * this method to associate an interface id to your interface.
+   */
+  void AddSelfInterface (InterfaceId iid, Ptr<Interface> interface);
+protected:
+  /**
+   * Subclasses who want to handle the "dispose" event should
+   * override this method. They are also responsible for
+   * "chaining up" to their parent class' DoDispose method
+   * once they have done their own "dispose".
+   */
+  virtual void DoDispose (void);
+private:
+  friend class InterfaceImpl;
+  Interface ();
+  Ptr<Interface> DoQueryInterface (InterfaceId iid) const;
+  void RefInternal (void);
+  void UnrefInternal (void);
+  InterfaceImpl *m_impl;
+  uint32_t m_ref;
+};
+
+}//namespace ns3
+
+namespace ns3 {
+
+template <typename T>
+Ptr<T>
+Interface::QueryInterface (InterfaceId iid) const
+{
+  Ptr<Interface> found = DoQueryInterface (iid);
+  if (found != 0)
+    {
+      return Ptr<T> (dynamic_cast<T *> (PeekPointer (found)));
+    }
+  return 0;
+}
+
+
+}//namespace ns3
+
+#endif /* INTERFACE_H */
--- a/src/core/ns-unknown-manager.cc	Sun May 13 12:46:18 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,252 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "ns-unknown-manager.h"
-#include "uid-manager.h"
-#include "singleton.h"
-
-namespace ns3 {
-
-// we redefine a UidManager type for the class id singleton below.
-// otherwise, we would have to share the same id singleton instance
-// with the Iids.
-class CidManager : public UidManager
-{};
-
-ClassId::ClassId (std::string name)
-  : m_classId (Singleton<CidManager>::Get ()->Allocate (name))
-{}
-
-ClassId::ClassId (uint32_t classId)
-  : m_classId (classId)
-{}
-
-std::string 
-ClassId::GetName (void)
-{
-  return Singleton<CidManager>::Get ()->LookupByUid (m_classId);
-}
-
-bool operator == (const ClassId &a, const ClassId &b)
-{
-  return a.m_classId == b.m_classId;
-}
-
-NsUnknown *
-NsUnknownManager::Create (ClassId classId)
-{
-  Callback<NsUnknown *> callback = DoGetCallback<empty,empty,empty,empty,empty> (classId);
-  return callback ();
-}
-
-CallbackBase *
-NsUnknownManager::Lookup (ClassId classId)
-{
-  List *list = Singleton<List>::Get ();
-  for (List::const_iterator i = list->begin (); i != list->end (); i++)
-    {
-      if (i->first == classId)
-	{
-	  return i->second;
-	}
-    }
-  return 0;
-}
-
-ClassId 
-NsUnknownManager::LookupByName (std::string name)
-{
-  return ClassId (Singleton<CidManager>::Get ()->LookupByName (name));
-}
-
-ClassId
-NsUnknownManager::Register (std::string name, CallbackBase *callback)
-{
-  ClassId classId = ClassId (name);
-  List *list = Singleton<List>::Get ();
-  list->push_back (std::make_pair (classId, callback));
-  return classId;
-}
-
-
-} // namespace ns3
-
-#ifdef RUN_SELF_TESTS
-
-#include "test.h"
-#include "ns-unknown.h"
-
-namespace {
-
-
-class B : public ns3::NsUnknown
-{
-public:
-  static const ns3::Iid iid;
-  B ();
-};
-
-const ns3::Iid B::iid ("IB");
-
-B::B ()
-  : NsUnknown (B::iid)
-{}
-
-
-class A : public ns3::NsUnknown
-{
-public:
-  static const ns3::ClassId cidZero;
-  static const ns3::ClassId cidOneBool;
-  static const ns3::ClassId cidOneUi32;
-  static const ns3::Iid iid;
-
-  A ();
-  A (bool);
-  A (uint32_t);
-
-  bool m_zeroInvoked;
-  bool m_oneBoolInvoked;
-  bool m_oneUi32Invoked;
-
-  bool m_bool;
-  int m_ui32;
-};
-
-const ns3::ClassId A::cidZero = ns3::NsUnknownManager::RegisterConstructor <A> ("A");
-const ns3::ClassId A::cidOneBool = ns3::NsUnknownManager::RegisterConstructor <A,bool> ("ABool");
-const ns3::ClassId A::cidOneUi32 = ns3::NsUnknownManager::RegisterConstructor <A,uint32_t> ("AUi32");
-const ns3::Iid A::iid ("IA");
-
-A::A ()
-  : NsUnknown (A::iid),
-    m_zeroInvoked (true),
-    m_oneBoolInvoked (false),
-    m_oneUi32Invoked (false)
-{
-  B *b = new B ();
-  AddInterface (b);
-  b->Unref ();
-}
-
-A::A (bool bo)
-  : NsUnknown (A::iid),
-    m_zeroInvoked (false),
-    m_oneBoolInvoked (true),
-    m_oneUi32Invoked (false),
-    m_bool (bo)
-{
-  B *b = new B ();
-  AddInterface (b);
-  b->Unref ();
-}
-
-A::A (uint32_t i)
-  : NsUnknown (A::iid),
-    m_zeroInvoked (false),
-    m_oneBoolInvoked (false),
-    m_oneUi32Invoked (true),
-    m_ui32 (i)
-{
-  B *b = new B ();
-  AddInterface (b);
-  b->Unref ();
-}
-
-}
-
-namespace ns3 {
-
-class NsUnknownManagerTest : public Test
-{
-public:
-  NsUnknownManagerTest ();
-  virtual bool RunTests (void);
-};
-
-NsUnknownManagerTest::NsUnknownManagerTest ()
-  : Test ("NsUnknownManager")
-{}
-bool 
-NsUnknownManagerTest::RunTests (void)
-{
-  bool ok = true;
-
-  A *a = 0;
-  a = NsUnknownManager::Create<A> (A::cidZero, A::iid);
-  if (a == 0 ||
-      !a->m_zeroInvoked)
-    {
-      ok = false;
-    }
-  a->Unref ();
-
-  a = NsUnknownManager::Create<A,bool> (A::cidOneBool, A::iid, true);
-  if (a == 0 ||
-      !a->m_oneBoolInvoked ||
-      !a->m_bool)
-    {
-      ok = false;
-    }
-  a->Unref ();
-
-  a = NsUnknownManager::Create<A,bool> (A::cidOneBool, A::iid, false);
-  if (a == 0 ||
-      !a->m_oneBoolInvoked ||
-      a->m_bool)
-    {
-      ok = false;
-    }
-  a->Unref ();
-
-  a = NsUnknownManager::Create<A,uint32_t> (A::cidOneUi32, A::iid, 10);
-  if (a == 0 ||
-      !a->m_oneUi32Invoked ||
-      a->m_ui32 != 10)
-    {
-      ok = false;
-    }
-  a->Unref ();
-
-  a = NsUnknownManager::Create<A> (A::cidOneUi32, A::iid, (uint32_t)10);
-  if (a == 0 ||
-      !a->m_oneUi32Invoked ||
-      a->m_ui32 != 10)
-    {
-      ok = false;
-    }
-  a->Unref ();
-
-  B *b = NsUnknownManager::Create<B,uint32_t> (A::cidOneUi32, B::iid, 10);
-  if (b == 0)
-    {
-      ok = false;
-    }
-  b->Unref ();
-
-  return ok;
-}
-
-
-static NsUnknownManagerTest g_unknownManagerTest;
-
-} // namespace ns3
-
-#endif /* RUN_SELF_TESTS */
--- a/src/core/ns-unknown-manager.h	Sun May 13 12:46:18 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,281 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef NS_UNKNOWN_MANAGER_H
-#define NS_UNKNOWN_MANAGER_H
-
-#include <string>
-#include <vector>
-#include <stdint.h>
-#include "callback.h"
-#include "ns-unknown.h"
-#include "fatal-error.h"
-
-namespace ns3 {
-
-/**
- * \brief Unique Identifier for class constructors.
- *
- * Instances of this type must be allocated through
- * the ns3::Ns3UnknownManager::RegisterConstructor methods
- */
-class ClassId
-{
-public:
-  /**
-   * \returns the symbolic name associated to this class id
-   *
-   * This name is the name which was associated to this class id
-   * by the ns3::Ns3UnknownManager::RegisterConstructor methods.
-   * This name is also the name which is expected to be input
-   * to ns3::UnknownManager::LookupByName.
-   */
-  std::string GetName (void);
-private:
-  ClassId (std::string name);
-  ClassId (uint32_t classId);
-  friend class NsUnknownManager;
-  friend bool operator == (const ClassId &a, const ClassId &b);
-  uint32_t m_classId;
-};
-
-/**
- * \brief Create any NsUnknown
- *
- * This class keeps track of a set of ClassId, each
- * of which uniquely identifies the constructor of an
- * object which derives from the NsUnknown base class.
- * This class can also create an instance of any of
- * the objects tracked through any of their tracked
- * constructor/ClassId.
- */
-class NsUnknownManager
-{
-public:
-  /**
-   * \param name the symbolic name to lookup
-   * \returns the ClassId associated to the input name.
-   */
-  static ClassId LookupByName (std::string name);
-
-  /**
-   * \param classId class id of the constructor to invoke.
-   * \return a pointer to the instance created.
-   *
-   * Create an instance of the object identified by its
-   * ClassId. This method invokes the default constructor.
-   */
-  static NsUnknown *Create (ClassId classId);
-
-  /**
-   * \param classId class id of the constructor to invoke.
-   * \param a1 argument to pass to the constructor.
-   * \return a pointer to the instance created.
-   * \overload NsUnknown *Create (ClassId)
-   *
-   * Create an instance of the object identified by its
-   * ClassId.
-   */
-  template <typename T1>
-  static NsUnknown *Create (ClassId classId, T1 a1);
-
-  /**
-   * \param classId class id of the constructor to invoke.
-   * \param a1 first argument to pass to the constructor.
-   * \param a2 second argument to pass to the constructor.
-   * \return a pointer to the instance created.
-   * \overload NsUnknown *Create (ClassId)
-   *
-   * Create an instance of the object identified by its
-   * ClassId.
-   */
-  template <typename T1, typename T2>
-  static NsUnknown *Create (ClassId classId, T1 a1, T2 a2);
-
-  /**
-   * \param classId class id of the constructor to invoke.
-   * \param iid interface id to query for
-   * \return a pointer to the instance created.
-   * \overload NsUnknown *Create (ClassId)
-   *
-   * Create an instance of the object identified by its
-   * ClassId, call QueryInterface on it, and return the 
-   * result.
-   */
-  template <typename T>
-  static T *Create (ClassId classId, Iid iid);
-
-  template <typename T, typename T1>
-  static T *Create (ClassId classId, Iid iid, T1 a1);
-
-  template <typename T, typename T1, typename T2>
-  static T *Create (ClassId classId, Iid iid, T1 a1, T2 a2);
-
-  /**
-   * \param name the symbolic name to associate to this
-   *        constructor
-   * \returns a ClassId which uniquely identifies this constructor.
-   */
-  template <typename T>
-  static ClassId RegisterConstructor (std::string name)
-  {
-    static Callback<NsUnknown *> callback = 
-      MakeCallback (&NsUnknownManager::MakeObjectZero<T>);
-    return NsUnknownManager::Register (name, &callback);
-  }
-
-  /**
-   * \param name the symbolic name to associate to this
-   *        constructor
-   * \returns a ClassId which uniquely identifies this constructor.
-   * \overload ClassId RegisterConstructor (std::string)
-   */
-  template <typename T, typename T1>
-  static ClassId RegisterConstructor (std::string name)
-  {
-    static Callback<NsUnknown *,T1> callback = MakeCallback (&NsUnknownManager::MakeObjectOne<T,T1>);
-    return NsUnknownManager::Register (name, &callback);
-  }
-
-  /**
-   * \param name the symbolic name to associate to this
-   *        constructor
-   * \returns a ClassId which uniquely identifies this constructor.
-   * \overload ClassId RegisterConstructor (std::string)
-   */
-  template <typename T, typename T1, typename T2>
-  static ClassId RegisterConstructor (std::string name)
-  {
-    static Callback<NsUnknown *,T1,T2> callback = MakeCallback (&NsUnknownManager::MakeObjectTwo<T,T1,T2>);
-    return NsUnknownManager::Register (name, &callback);
-  }
-private:
-  static ClassId Register (std::string name, CallbackBase *callback);
-
-  template <typename T1, typename T2,
-            typename T3, typename T4,
-            typename T5>
-  static Callback<NsUnknown *,T1,T2,T3,T4,T5> DoGetCallback (ClassId classId);
-
-  template <typename T>
-  static NsUnknown *MakeObjectZero (void);
-
-  template <typename T, typename T1>
-  static NsUnknown *MakeObjectOne (T1 a1);
-
-  template <typename T, typename T1, typename T2>
-  static NsUnknown *MakeObjectTwo (T1 a1, T2 a2);
-
-  typedef std::vector<std::pair<ClassId, CallbackBase *> > List;
-  static List *GetList (void);
-  static CallbackBase *Lookup (ClassId classId);
-};
-
-} // namespace ns3 
-
-
-namespace ns3 {
-
-template <typename T1, typename T2,
-          typename T3, typename T4,
-          typename T5>
-Callback<NsUnknown *,T1,T2,T3,T4,T5>
-NsUnknownManager::DoGetCallback (ClassId classId)
-{
-  CallbackBase *callback = Lookup (classId);
-  if (callback == 0)
-    {
-      NS_FATAL_ERROR ("Invalid Class Id.");
-    }
-  Callback<NsUnknown *, T1,T2,T3,T4,T5> reference;
-  reference.Assign (*callback);
-  return reference;
-}
-
-
-template <typename T1>
-NsUnknown *
-NsUnknownManager::Create (ClassId classId, T1 a1)
-{
-  Callback<NsUnknown *, T1> callback = DoGetCallback<T1,empty,empty,empty,empty> (classId);
-  return callback (a1);
-}
-
-template <typename T1, typename T2>
-NsUnknown *
-NsUnknownManager::Create (ClassId classId, T1 a1, T2 a2)
-{
-  Callback<NsUnknown *, T1,T2> callback = DoGetCallback<T1,T2,empty,empty,empty> (classId);
-  return callback (a1, a2);
-}
-
-template <typename T>
-T *
-NsUnknownManager::Create (ClassId classId, Iid iid)
-{
-  NsUnknown *obj = Create (classId);
-  T *i = obj->QueryInterface<T> (iid);
-  obj->Unref ();
-  return i;
-}
-
-template <typename T, typename T1>
-T *
-NsUnknownManager::Create (ClassId classId, Iid iid, T1 a1)
-{
-  NsUnknown *obj = Create (classId, a1);
-  T *i = obj->QueryInterface<T> (iid);
-  obj->Unref ();
-  return i;
-}
-
-template <typename T, typename T1, typename T2>
-T *
-NsUnknownManager::Create (ClassId classId, Iid iid, T1 a1, T2 a2)
-{
-  NsUnknown *obj = Create (classId, a1, a2);
-  T *i = obj->QueryInterface<T> (iid);
-  obj->Unref ();
-  return i;
-}
-
-
-template <typename T>
-NsUnknown *
-NsUnknownManager::MakeObjectZero (void)
-{
-  return new T ();
-}
-template <typename T, typename T1>
-NsUnknown *
-NsUnknownManager::MakeObjectOne (T1 a1)
-{
-  return new T (a1);
-}
-template <typename T, typename T1, typename T2>
-NsUnknown *
-NsUnknownManager::MakeObjectTwo (T1 a1, T2 a2)
-{
-  return new T (a1, a2);
-}
-
-} // namespace ns3
-
-#endif /* NS_UNKNOWN_MANAGER_H */
--- a/src/core/ns-unknown.cc	Sun May 13 12:46:18 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,387 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "ns-unknown.h"
-#include "singleton.h"
-#include "uid-manager.h"
-#include <string>
-#include <list>
-#include <stdint.h>
-#include "assert.h"
-
-namespace ns3 {
-
-class IidManager : public UidManager
-{};
-
-Iid::Iid (std::string name)
-  : m_iid (Singleton<IidManager>::Get ()->Allocate (name))
-{}
-
-bool operator == (const Iid &a, const Iid &b)
-{
-  return a.m_iid == b.m_iid;
-}
-
-
-class NsUnknownImpl
-{
-public:
-  NsUnknownImpl (Iid iid, NsUnknown *interface);
-  ~NsUnknownImpl ();
-  void Ref (void);
-  void RefAll (NsUnknownImpl *other);
-  void Unref (void);
-  void UnrefAll (void);
-  NsUnknown *DoQueryInterface (Iid iid) const;
-  void DoDisposeAll (void);
-  void AddInterface (NsUnknown *interface);
-  void AddSelfInterface (Iid iid, NsUnknown *interface);
-private:
-  typedef std::list<std::pair<Iid,NsUnknown *> > List;
-  uint32_t m_ref;
-  List m_list;
-  bool m_disposed;
-};
-
-NsUnknownImpl::NsUnknownImpl (Iid iid, NsUnknown *interface)
-  : m_ref (1),
-    m_disposed (false)
-{
-  m_list.push_back (std::make_pair (iid, interface));
-}
-NsUnknownImpl::~NsUnknownImpl ()
-{
-  for (List::const_iterator i = m_list.begin ();
-       i != m_list.end (); i++)
-    {
-      i->second->UnrefInternal ();
-    }
-  m_list.clear ();
-}
-void 
-NsUnknownImpl::Ref (void)
-{
-  m_ref++;
-}
-void 
-NsUnknownImpl::RefAll (NsUnknownImpl *other)
-{
-  m_ref += other->m_ref;
-}
-void 
-NsUnknownImpl::Unref (void)
-{
-  m_ref--;
-  if (m_ref == 0)
-    {
-      delete this;
-    }
-}
-void
-NsUnknownImpl::UnrefAll (void)
-{
-  m_ref = 0;
-  delete this;
-}
-void
-NsUnknownImpl::DoDisposeAll (void)
-{
-  NS_ASSERT (!m_disposed);
-  for (List::const_iterator i = m_list.begin ();
-       i != m_list.end (); i++)
-    {
-      NsUnknown *interface = i->second;
-      interface->DoDispose ();
-    }
-  m_disposed = true;
-}
-NsUnknown *
-NsUnknownImpl::DoQueryInterface (Iid iid) const
-{
-  for (List::const_iterator i = m_list.begin ();
-       i != m_list.end (); i++)
-    {
-      if (i->first == iid)
-	{
-	  i->second->Ref ();
-	  return i->second;
-	}
-    }
-  return 0;
-}
-void 
-NsUnknownImpl::AddInterface (NsUnknown *interface)
-{
-  for (List::const_iterator i = interface->m_impl->m_list.begin ();
-       i != interface->m_impl->m_list.end (); i++)
-    {
-      // XXX here, we should check that we have only one 
-      // instance of each interface
-      i->second->RefInternal ();
-      m_list.push_back (std::make_pair (i->first, i->second));
-    }
-}
-void 
-NsUnknownImpl::AddSelfInterface (Iid iid, NsUnknown *interface)
-{
-  interface->RefInternal ();
-  m_list.push_back (std::make_pair (iid, interface));
-}
-
-
-NsUnknown::NsUnknown (Iid iid)
-  : m_impl (new NsUnknownImpl (iid, this)),
-    m_ref (1)
-{}
-NsUnknown::~NsUnknown ()
-{
-  m_impl = 0;
-}
-void 
-NsUnknown::Ref (void)
-{
-  m_impl->Ref ();
-}
-void 
-NsUnknown::Unref (void)
-{
-  m_impl->Unref ();
-}
-
-void 
-NsUnknown::Dispose (void)
-{
-  m_impl->DoDisposeAll ();
-}
-
-void 
-NsUnknown::DoDispose (void)
-{
-  // we do not do anything by default.
-}
-
-void
-NsUnknown::RefInternal (void)
-{
-  m_ref++;
-}
-
-void
-NsUnknown::UnrefInternal (void)
-{
-  NS_ASSERT (m_ref != 0);
-  m_ref--;
-  if (m_ref == 0)
-    {
-      delete this;
-    }
-}
-
-NsUnknown *
-NsUnknown::DoQueryInterface (Iid iid) const
-{
-  return m_impl->DoQueryInterface (iid);
-}
-
-void 
-NsUnknown::AddInterface (NsUnknown *interface)
-{
-  m_impl->AddInterface (interface);
-  m_impl->RefAll (interface->m_impl);
-  interface->m_impl->UnrefAll ();
-  interface->m_impl = m_impl;
-}
-
-void
-NsUnknown::AddSelfInterface (Iid iid, NsUnknown *interface)
-{
-  m_impl->AddSelfInterface (iid, interface);
-}
-
-
-}//namespace ns3
-
-#ifdef RUN_SELF_TESTS
-
-#include "test.h"
-
-namespace {
-
-class A : public ns3::NsUnknown
-{
-public:
-  static const ns3::Iid iid;
-  A ()
-    : NsUnknown (A::iid)
-  {}
-};
-class B : public ns3::NsUnknown
-{
-public:
-  static const ns3::Iid iid;
-  B ()
-    : NsUnknown (B::iid)
-  {}
-};
-class BaseA : public ns3::NsUnknown
-{
-public:
-  static const ns3::Iid iid;
-  BaseA ()
-    : NsUnknown (BaseA::iid)
-  {}
-};
-class BaseB : public ns3::NsUnknown
-{
-public:
-  static const ns3::Iid iid;
-  BaseB ()
-    : NsUnknown (BaseB::iid)
-  {}
-};
-class Base : public ns3::NsUnknown
-{
-public:
-  static const ns3::Iid iid;
-  Base ()
-    : NsUnknown (Base::iid)
-  {}
-};
-class Derived : public Base
-{
-public:
-  static const ns3::Iid iid;
-  Derived ()
-  {
-    AddSelfInterface (Derived::iid, this);
-  }
-};
-
-const ns3::Iid A::iid ("A");
-const ns3::Iid B::iid ("B");
-const ns3::Iid BaseA::iid ("BaseA");
-const ns3::Iid BaseB::iid ("BaseB");
-const ns3::Iid Base::iid ("Base");
-const ns3::Iid Derived::iid ("Derived");
-
-}//namespace
-
-
-namespace ns3 {
-
-class InterfaceTest : public Test
-{
-public:
-  InterfaceTest ();
-  virtual bool RunTests (void);
-};
-
-InterfaceTest::InterfaceTest ()
-  : Test ("NsUnknown")
-{}
-bool 
-InterfaceTest::RunTests (void)
-{
-  bool ok = true;
-
-  //DerivedAB *derivedAB;
-
-
-  A *a = new A ();
-  a->Unref ();
-
-  a = new A ();
-  A *a1 = a->QueryInterface<A> (A::iid);
-  if (a1 == 0 || a1 != a)
-    {
-      ok = false;
-    }
-  a1->Unref ();
-  a1 = a->QueryInterface<A> (A::iid);
-  if (a1 == 0 || a1 != a)
-    {
-      ok = false;
-    }
-  a1->Unref ();
-  a->Unref ();
-
-  B *b = new B ();
-  B *b1 = b->QueryInterface<B> (B::iid);
-  if (b1 == 0 || b1 != b)
-    {
-      ok = false;
-    }
-  b1->Unref ();
-  
-  a = new A ();
-  a->AddInterface (b);
-  b1 = b->QueryInterface<B> (B::iid);
-  if (b1 == 0 || b1 != b)
-    {
-      ok = false;
-    }
-  b1->Unref ();
-  a1 = b->QueryInterface<A> (A::iid);
-  if (a1 == 0 || a1 != a)
-    {
-      ok = false;
-    }
-  a1->Unref ();
-  a1 = a->QueryInterface<A> (A::iid);
-  if (a1 == 0 || a1 != a)
-    {
-      ok = false;
-    }
-  a1->Unref ();
-  b1 = a->QueryInterface<B> (B::iid);
-  if (b1 == 0 || b1 != b)
-    {
-      ok = false;
-    }
-  b1->Unref ();
-  
-  a->Unref ();
-  b->Unref ();
-
-  Derived *derived = new Derived ();
-  Base *base = derived->QueryInterface<Base> (Base::iid);
-  if (base == 0)
-    {
-      ok = false;
-    }
-  Derived *derived1 = base->QueryInterface<Derived> (Derived::iid);
-  if (derived1 == 0 || derived1 != derived)
-    {
-      ok = false;
-    }
-  derived1->Unref ();
-  base->Unref ();
-  derived->Unref ();
-
-  return ok;
-}
-
-
-static InterfaceTest g_interface_test;
-
-}// namespace ns3
-
-#endif /* RUN_SELF_TESTS */
--- a/src/core/ns-unknown.h	Sun May 13 12:46:18 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef INTERFACE_H
-#define INTERFACE_H
-
-#include <string>
-
-
-namespace ns3 {
-
-class NsUnknownImpl;
-
-class Iid
-{
-public:
-  Iid (std::string name);
-private:
-  friend bool operator == (const Iid &a, const Iid &b);
-  uint32_t m_iid;
-};
-
-/**
- * \brief COM-like IUnknown
- *
- * This class should be used as a base class for every object which
- * wishes to provide a COM-like QueryInterface API. Multiple 
- * inheritance where this base class is at the top of the dreaded 
- * "diamond" shape is not allowed.
- */
-class NsUnknown
-{
-public:
-  virtual ~NsUnknown ();
-  void Ref (void);
-  void Unref (void);
-
-  /**
-   * \param iid the NsUnknown id of the requested interface
-   */
-  template <typename T>
-  T *QueryInterface (Iid iid) const;
-
-  /**
-   * \param interface another interface
-   * 
-   * Aggregate together the two interfaces. After this call,
-   * the two interface objects are tied together: each of them
-   * will be able to perform QI on each other and their lifetimes
-   * will be found by the same reference count.
-   */
-  void AddInterface (NsUnknown *interface);
-
-  void Dispose (void);
-protected:
-  /**
-   * \param iid the Interface Id of the interface defined by a direct subclass
-   * of this base class
-   *
-   * If you are a direct subclass of this class, you _must_ register
-   * the name of your interface with this constructor.
-   */
-  NsUnknown (Iid iid);
-  /**
-   * \param iid the Interface id of the interface
-   * \param a pointer to the interface object
-   *
-   * If you are not a direct subclass of the ns3::NsUnknown base class,
-   * and if you want to register yourself as another accessible interface
-   * (typically, your subclass has added API), you need to call
-   * this method to associate an interface id to your interface.
-   */
-  void AddSelfInterface (Iid iid, NsUnknown *interface);
-protected:
-  /**
-   * Subclasses who want to handle the "dispose" event should
-   * override this method. They are also responsible for
-   * "chaining up" to their parent class' DoDispose method
-   * once they have done their own "dispose".
-   */
-  virtual void DoDispose (void);
-private:
-  friend class NsUnknownImpl;
-  NsUnknown ();
-  NsUnknown *DoQueryInterface (Iid iid) const;
-  void RefInternal (void);
-  void UnrefInternal (void);
-  NsUnknownImpl *m_impl;
-  uint32_t m_ref;
-};
-
-}//namespace ns3
-
-namespace ns3 {
-
-template <typename T>
-T *
-NsUnknown::QueryInterface (Iid iid) const
-{
-  NsUnknown *found = DoQueryInterface (iid);
-  if (found != 0)
-    {
-      return dynamic_cast<T *> (found);
-    }
-  return 0;
-}
-
-
-}//namespace ns3
-
-#endif /* INTERFACE_H */
--- a/src/core/object.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/core/object.cc	Sun May 13 12:52:38 2007 +0100
@@ -29,7 +29,9 @@
 Object::Object ()
   : m_count (1),
     m_disposed (false)
-{}
+{
+  NS_DEBUG ("Object::Object: m_count=0");
+}
 
 Object::~Object ()
 {}
@@ -37,17 +39,16 @@
 void 
 Object::Ref (void) const
 {
-  NS_DEBUG("Object::Ref (): this == 0x" << this);
   m_count++;
-  NS_DEBUG("Object::Ref (): m_count bumped to " << m_count);
+  NS_DEBUG("Object::Ref (): this == 0x" << this << " m_count=" << m_count);
 }
 
 void 
 Object::Unref (void) const
 {
-  NS_DEBUG("Object::Unref (): this == 0x" << this);
+  NS_ASSERT (m_count > 0);
   m_count--;
-  NS_DEBUG("Object::Ref (): m_count dropped to " << m_count);
+  NS_DEBUG("Object::Unref (): this == 0x" << this << " m_count=" << m_count);
 
   if (m_count == 0)
     {
--- a/src/core/ptr.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/core/ptr.cc	Sun May 13 12:52:38 2007 +0100
@@ -24,10 +24,11 @@
 
 #include "test.h"
 #include "callback.h"
+#include "object.h"
 
 namespace ns3 {
 
-class NoCount
+class NoCount : public Object
 {
 public:
   NoCount (Callback<void> cb);
@@ -92,7 +93,7 @@
   Callback<void> cb = MakeCallback (&PtrTest::DestroyNotify, this);
   m_nDestroyed = false;
   {
-    Ptr<NoCount> p = new NoCount (cb);
+    Ptr<NoCount> p = MakeNewObject<NoCount> (cb);
   }
   if (m_nDestroyed != 1)
     {
@@ -102,7 +103,7 @@
   m_nDestroyed = 0;
   {
     Ptr<NoCount> p;
-    p = new NoCount (cb);
+    p = MakeNewObject<NoCount> (cb);
     p = p;
   }
   if (m_nDestroyed != 1)
@@ -113,7 +114,7 @@
   m_nDestroyed = 0;
   {
     Ptr<NoCount> p1;
-    p1 = new NoCount (cb);
+    p1 = MakeNewObject<NoCount> (cb);
     Ptr<NoCount> p2 = p1;
   }
   if (m_nDestroyed != 1)
@@ -124,7 +125,7 @@
   m_nDestroyed = 0;
   {
     Ptr<NoCount> p1;
-    p1 = new NoCount (cb);
+    p1 = MakeNewObject<NoCount> (cb);
     Ptr<NoCount> p2;
     p2 = p1;
   }
@@ -136,8 +137,8 @@
   m_nDestroyed = 0;
   {
     Ptr<NoCount> p1;
-    p1 = new NoCount (cb);
-    Ptr<NoCount> p2 = new NoCount (cb);
+    p1 = MakeNewObject<NoCount> (cb);
+    Ptr<NoCount> p2 = MakeNewObject<NoCount> (cb);
     p2 = p1;
   }
   if (m_nDestroyed != 2)
@@ -148,9 +149,9 @@
   m_nDestroyed = 0;
   {
     Ptr<NoCount> p1;
-    p1 = new NoCount (cb);
+    p1 = MakeNewObject<NoCount> (cb);
     Ptr<NoCount> p2;
-    p2 = new NoCount (cb);
+    p2 = MakeNewObject<NoCount> (cb);
     p2 = p1;
   }
   if (m_nDestroyed != 2)
@@ -161,8 +162,8 @@
   m_nDestroyed = 0;
   {
     Ptr<NoCount> p1;
-    p1 = new NoCount (cb);
-    p1 = new NoCount (cb);
+    p1 = MakeNewObject<NoCount> (cb);
+    p1 = MakeNewObject<NoCount> (cb);
   }
   if (m_nDestroyed != 2)
     {
@@ -174,8 +175,8 @@
     Ptr<NoCount> p1;
     {
       Ptr<NoCount> p2;
-      p1 = new NoCount (cb);
-      p2 = new NoCount (cb);
+      p1 = MakeNewObject<NoCount> (cb);
+      p2 = MakeNewObject<NoCount> (cb);
       p2 = p1;
     }
     if (m_nDestroyed != 1)
@@ -193,8 +194,8 @@
     Ptr<NoCount> p1;
     {
       Ptr<NoCount> p2;
-      p1 = new NoCount (cb);
-      p2 = new NoCount (cb);
+      p1 = MakeNewObject<NoCount> (cb);
+      p2 = MakeNewObject<NoCount> (cb);
       p2 = CallTest (p1);
     }
     if (m_nDestroyed != 1)
@@ -236,11 +237,12 @@
   {
     NoCount *raw;
     {
-      Ptr<NoCount> p = new NoCount (cb);
+      Ptr<NoCount> p = MakeNewObject<NoCount> (cb);
       {
         Ptr<NoCount const> p1 = p;
       }
-      raw = p.Remove ();
+      raw = GetPointer (p);
+      p = 0;
     }
     if (m_nDestroyed != 0)
       {
@@ -252,16 +254,32 @@
 
   m_nDestroyed = 0;
   {
-    Ptr<NoCount> p = new NoCount (cb);
-    NoCount const&v1 = *p;
-    NoCount v2 = *p;
-    v1.Nothing ();
-    v2.Nothing ();
+    Ptr<NoCount> p = MakeNewObject<NoCount> (cb);
+    const NoCount *v1 = PeekPointer (p);
+    NoCount *v2 = PeekPointer (p);
+    v1->Nothing ();
+    v2->Nothing ();
   }
-  if (m_nDestroyed != 2)
+  if (m_nDestroyed != 1)
     {
       ok = false;
     }
+
+  {
+    Ptr<Object> p0 = MakeNewObject<NoCount> (cb);
+    Ptr<NoCount> p1 = MakeNewObject<NoCount> (cb);
+    if (p0 == p1)
+      {
+        ok = false;
+      }
+    if (p0 != p1)
+      {
+      }
+    else
+      {
+        ok = false;
+      }
+  }
   
 
   return ok;
--- a/src/core/ptr.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/core/ptr.h	Sun May 13 12:52:38 2007 +0100
@@ -28,32 +28,43 @@
 namespace ns3 {
 
 /**
- * \brief smart pointer class similar to boost::shared_ptr
+ * \brief smart pointer class similar to boost::intrusive_ptr
  *
- * This smart-pointer class is supposed to be used to manage
- * heap-allocated objects: when it decides it does not need
- * the object it references, it invokes operator delete on it.
+ * This smart-pointer class assumes that the underlying
+ * type provides a pair of Ref and Unref methods which are
+ * expected to increment and decrement the internal refcount
+ * of the object instance.
+ *
  * This implementation allows you to manipulate the smart pointer
  * as if it was a normal pointer: you can compare it with zero,
- * compare it against other pointers, etc. However, the only 
- * operation we are careful to avoid is the conversion back to
- * raw pointers: if you need to convert back, you need to invoke
- * the Ptr<T>::Remove method which returns a raw pointer and
- * makes the smart pointer forget about the raw pointer.
+ * compare it against other pointers, assign zero to it, etc.
+ *
+ * It is possible to extract the raw pointer from this
+ * smart pointer with the GetPointer and PeekPointer methods.
+ *
+ * If you want to store a newed object into a smart pointer,
+ * we recommend you to use the MakeNewObject template functions
+ * to create the object and store it in a smart pointer to avoid
+ * memory leaks. These functions are really small conveniance
+ * functions and their goal is just is save you a small
+ * bit of typing.
  */
 template <typename T>
 class Ptr 
 {
 private:
   T *m_ptr;
-  uint32_t *m_count;
   class Tester {
   private:
     void operator delete (void *);
   };
-  static uint32_t *AllocCount (void);
-  static void DeallocCount (uint32_t *count);
   friend class Ptr<const T>;
+  template <typename U>
+  friend U *GetPointer (const Ptr<U> &p);
+  template <typename U>
+  friend U *PeekPointer (const Ptr<U> &p);
+
+  void Acquire (void) const;
 public:
   /**
    * Create an empty smart pointer
@@ -75,100 +86,271 @@
   Ptr (Ptr<U> const &o);
   ~Ptr () ;
   Ptr<T> &operator = (Ptr const& o);
-  T const& operator * () const;
+
   T *operator -> () const;
   T *operator -> ();
   // allow if (!sp)
   bool operator! ();
   // allow if (sp)
+  // disable delete sp
   operator Tester * () const;
-  // allow if (sp == 0)
-  template <typename T1, typename T2>
-  inline friend bool operator == (Ptr<T1> const &lhs, T2 const *rhs);
-  // allow if (0 == sp)
-  template <typename T1, typename T2>
-  inline friend bool operator == (T1 const *lhs, Ptr<T2> &rhs);
-  // allow if (sp != 0)
-  template <typename T1, typename T2>
-  inline friend bool operator != (Ptr<T1> const &lhs, T2 const *rhs);
-  // allow if (0 != sp)
-  template <typename T1, typename T2>
-  inline friend bool operator != (T1 const *lhs, Ptr<T2> &rhs);
-
-  template <typename T1, typename T2>
-  inline friend Ptr<T1> const_pointer_cast (Ptr<T2> const&p);
-
-
-  /**
-   * \returns raw pointer
-   *
-   * It is a programming error to invoke this method when
-   * the reference count of the smart pointer is not one.
-   * If you try to do it anyway, an assert will be triggered.
-   * If asserts are disabled, bad things will happen.
-   * Once you have successfully called Ptr<T>::Remove on
-   * a smart pointer, the smart pointer will forget 
-   * about the raw pointer and will stop managing it. As such,
-   * you, as the caller, become responsible for invoking
-   * operator delete on the returned raw pointer.
-   */
-  T *Remove (void);
 };
 
 template <typename T>
-uint32_t *
-Ptr<T>::AllocCount (void)
+Ptr<T> MakeNewObject (void);
+
+template <typename T, typename T1>
+Ptr<T> MakeNewObject (T1 a1);
+
+template <typename T, typename T1, typename T2>
+Ptr<T> MakeNewObject (T1 a1, T2 a2);
+
+template <typename T, typename T1, typename T2, typename T3>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3);
+
+template <typename T, typename T1, typename T2, typename T3, typename T4>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4);
+
+template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
+
+template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6);
+
+template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7);
+
+/**
+ * \return the pointer managed by this smart pointer.
+ *
+ * The underlying refcount is not incremented prior
+ * to returning to the caller so the caller is not
+ * responsible for calling Unref himself.
+ */
+template <typename T>
+T * PeekPointer (const Ptr<T> &p);
+
+/**
+ * \return the pointer managed by this smart pointer.
+ *
+ * The underlying refcount is incremented prior
+ * to returning to the caller so the caller is
+ * responsible for calling Unref himself.
+ */
+template <typename T>
+T * GetPointer (const Ptr<T> &p);
+
+
+// allow if (sp == 0)
+template <typename T1, typename T2>
+bool operator == (Ptr<T1> const &lhs, T2 const *rhs);
+
+// allow if (0 == sp)
+template <typename T1, typename T2>
+bool operator == (T1 const *lhs, Ptr<T2> &rhs);
+
+// allow if (sp != 0)
+template <typename T1, typename T2>
+bool operator != (Ptr<T1> const &lhs, T2 const *rhs);
+
+// allow if (0 != sp)
+template <typename T1, typename T2>
+bool operator != (T1 const *lhs, Ptr<T2> &rhs);
+
+// allow if (sp0 == sp1)
+template <typename T1, typename T2>
+bool operator == (Ptr<T1> const &lhs, Ptr<T2> const &rhs);
+
+// allow if (sp0 != sp1)
+template <typename T1, typename T2>
+bool operator != (Ptr<T1> const &lhs, Ptr<T2> const &rhs);
+
+template <typename T1, typename T2>
+Ptr<T1> const_pointer_cast (Ptr<T2> const&p);
+
+} // namespace ns3
+
+
+namespace ns3 {
+
+  /*************************************************
+   *  friend non-member function implementations
+   ************************************************/
+
+template <typename T>
+Ptr<T> MakeNewObject (void)
+{
+  T *obj = new T ();
+  Ptr<T> p = obj;
+  obj->Unref ();
+  return p;
+}
+
+template <typename T, typename T1>
+Ptr<T> MakeNewObject (T1 a1)
+{
+  T *obj = new T (a1);
+  Ptr<T> p = obj;
+  obj->Unref ();
+  return p;
+}
+
+template <typename T, typename T1, typename T2>
+Ptr<T> MakeNewObject (T1 a1, T2 a2)
+{
+  T *obj = new T (a1, a2);
+  Ptr<T> p = obj;
+  obj->Unref ();
+  return p;
+}
+
+template <typename T, typename T1, typename T2, typename T3>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3)
 {
-  return new uint32_t [1] ();
+  T *obj = new T (a1, a2, a3);
+  Ptr<T> p = obj;
+  obj->Unref ();
+  return p;
+}
+
+template <typename T, typename T1, typename T2, typename T3, typename T4>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4)
+{
+  T *obj = new T (a1, a2, a3, a4);
+  Ptr<T> p = obj;
+  obj->Unref ();
+  return p;
+}
+
+template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
+{
+  T *obj = new T (a1, a2, a3, a4, a5);
+  Ptr<T> p = obj;
+  obj->Unref ();
+  return p;
+}
+
+template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
+{
+  T *obj = new T (a1, a2, a3, a4, a5, a6);
+  Ptr<T> p = obj;
+  obj->Unref ();
+  return p;
+}
+
+template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
+Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
+{
+  T *obj = new T (a1, a2, a3, a4, a5, a6, a7);
+  Ptr<T> p = obj;
+  obj->Unref ();
+  return p;
+}
+
+template <typename T>
+T * PeekPointer (const Ptr<T> &p)
+{
+  return p.m_ptr;
+}
+
+template <typename T>
+T * GetPointer (const Ptr<T> &p)
+{
+  p.Acquire ();
+  return p.m_ptr;
 }
+
+template <typename T1, typename T2>
+bool 
+operator == (Ptr<T1> const &lhs, T2 const *rhs)
+{
+  return PeekPointer (lhs) == rhs;
+}
+
+template <typename T1, typename T2>
+bool 
+operator == (T1 const *lhs, Ptr<T2> &rhs)
+{
+  return lhs == PeekPointer (rhs);
+}
+
+template <typename T1, typename T2>
+bool 
+operator != (Ptr<T1> const &lhs, T2 const *rhs)
+{
+  return PeekPointer (lhs) != rhs;
+}
+
+template <typename T1, typename T2>
+bool 
+operator != (T1 const *lhs, Ptr<T2> &rhs)
+{
+  return lhs != PeekPointer (rhs);
+}
+
+template <typename T1, typename T2>
+bool 
+operator == (Ptr<T1> const &lhs, Ptr<T2> const &rhs)
+{
+  return PeekPointer (lhs) == PeekPointer (rhs);
+}
+
+template <typename T1, typename T2>
+bool 
+operator != (Ptr<T1> const &lhs, Ptr<T2> const &rhs)
+{
+  return PeekPointer (lhs) != PeekPointer (rhs);
+}
+
+
+template <typename T1, typename T2>
+Ptr<T1>
+const_pointer_cast (Ptr<T2> const&p)
+{
+  return Ptr<T1> (const_cast<T1 *> (PeekPointer (p)));
+}
+
+
+/****************************************************
+ *      Member method implementations.
+ ***************************************************/
+
 template <typename T>
 void 
-Ptr<T>::DeallocCount (uint32_t *count)
+Ptr<T>::Acquire (void) const
 {
-  delete [] count;
+  if (m_ptr != 0)
+    {
+      m_ptr->Ref ();
+    }  
 }
 
 template <typename T>
 Ptr<T>::Ptr ()
-  : m_ptr (0),
-    m_count (0)
+  : m_ptr (0)
 {}
 
 template <typename T>
 Ptr<T>::Ptr (T *ptr) 
-  : m_ptr (ptr),
-    m_count (0)
+  : m_ptr (ptr)
 {
-  if (m_ptr != 0)
-    {
-      m_count = Ptr::AllocCount ();
-      *m_count = 1;
-    }
+  Acquire ();
 }
 
 template <typename T>
 Ptr<T>::Ptr (Ptr const&o) 
-  : m_ptr (o.m_ptr),
-    m_count (0)
+  : m_ptr (PeekPointer (o))
 {
-  if (m_ptr != 0) 
-    {
-      m_count = o.m_count;
-      (*m_count)++;
-    }
+  Acquire ();
 }
 template <typename T>
 template <typename U>
 Ptr<T>::Ptr (Ptr<U> const &o)
-  : m_ptr (o.m_ptr),
-    m_count (0)
+  : m_ptr (PeekPointer (o))
 {
-  if (m_ptr != 0) 
-    {
-      NS_ASSERT (o.m_ptr != 0);
-      m_count = o.m_count;
-      (*m_count)++;
-    }
+  Acquire ();
 }
 
 template <typename T>
@@ -176,12 +358,7 @@
 {
   if (m_ptr != 0) 
     {
-      (*m_count)--;
-      if ((*m_count) == 0) 
-        {
-          delete m_ptr;
-          Ptr::DeallocCount (m_count);
-        }
+      m_ptr->Unref();
     }
 }
 
@@ -190,33 +367,19 @@
 Ptr<T>::operator = (Ptr const& o) 
 {
   if (&o == this)
-    return *this;
+    {
+      return *this;
+    }
   if (m_ptr != 0) 
     {
-      (*m_count)--;
-      if ((*m_count) == 0) 
-        {
-          delete m_ptr;
-          Ptr::DeallocCount (m_count);
-        }
+      m_ptr->Unref();
     }
   m_ptr = o.m_ptr;
-  if (m_ptr != 0) 
-    {
-      m_count = o.m_count;
-      (*m_count)++;
-    }
+  Acquire ();
   return *this;
 }
 
 template <typename T>
-T const& 
-Ptr<T>::operator * () const
-{
-  return *m_ptr;
-}
-
-template <typename T>
 T *
 Ptr<T>::operator -> () 
 {
@@ -248,57 +411,6 @@
   return &test;
 }
 
-template <typename T>
-T *
-Ptr<T>::Remove (void) 
-{
-  if (m_ptr == 0)
-    {
-      return (T *) 0;
-    }
-  else
-    {
-      NS_ASSERT ((*m_count) == 1);
-      Ptr::DeallocCount (m_count);
-      T *retval = m_ptr;
-      m_ptr = 0;
-      return retval;
-    }
-}
-
-// non-member friend functions.
-template <typename T1, typename T2>
-bool 
-operator == (Ptr<T1> const &lhs, T2 const *rhs)
-{
-  return lhs.m_ptr == rhs;
-}
-template <typename T1, typename T2>
-bool 
-operator == (T1 const *lhs, Ptr<T2> &rhs)
-{
-  return lhs == rhs.m_ptr;
-}
-template <typename T1, typename T2>
-bool 
-operator != (Ptr<T1> const &lhs, T2 const *rhs)
-{
-  return lhs.m_ptr != rhs;
-}
-template <typename T1, typename T2>
-bool 
-operator != (T1 const *lhs, Ptr<T2> &rhs)
-{
-  return lhs != rhs.m_ptr;
-}
-
-template <typename T1, typename T2>
-Ptr<T1>
-const_pointer_cast (Ptr<T2> const&p)
-{
-  return Ptr<T1> (const_cast<T1 *> (p.m_ptr));
-}
-
 
 }; // namespace ns3
 
--- a/src/core/random-variable.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/core/random-variable.h	Sun May 13 12:52:38 2007 +0100
@@ -200,6 +200,7 @@
  * UniformVariable x(0,10);
  * x.GetValue();  //will always return numbers [0,10]
  * UniformVariable::GetSingleValue(100,1000); //returns a value [100,1000]
+ * \endcode
  */
 class UniformVariable : public RandomVariable {
 public:
--- a/src/core/uid-manager.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/core/uid-manager.h	Sun May 13 12:52:38 2007 +0100
@@ -27,6 +27,9 @@
 
 namespace ns3 {
 
+/**
+ * zero is never a valid uid value.
+ */
 class UidManager
 {
 public:
--- a/src/core/wscript	Sun May 13 12:46:18 2007 +0100
+++ b/src/core/wscript	Sun May 13 12:52:38 2007 +0100
@@ -33,12 +33,12 @@
         'test.cc',
         'random-variable.cc',
         'rng-stream.cc',
-        'ns-unknown.cc',
+        'interface.cc',
         'uid-manager.cc',
         'default-value.cc',
         'command-line.cc',
         'type-name.cc',
-        'ns-unknown-manager.cc',
+        'component-manager.cc',
         ]
 
     if sys.platform == 'win32':
@@ -63,10 +63,10 @@
         'test.h',
         'random-variable.h',
         'rng-stream.h',
-        'ns-unknown.h',
+        'interface.h',
         'default-value.h',
         'command-line.h',
         'type-name.h',
-        'ns-unknown-manager.h',
+        'component-manager.h',
         ]
 
--- a/src/devices/p2p-gfr/p2p-channel.cc	Sun May 13 12:46:18 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Implementation of simple point-to-point channel
-// George F. Riley, Georgia Tech, Spring 2007
-
-#include "ns3/simulator.h"
-#include "ns3/packet.h"
-#include "ns3/node.h"
-#include "p2p-channel.h"
-#include "p2p-net-device.h"
-
-namespace ns3 {
-
-P2PChannel::P2PChannel(const Time& delay, double maxRate) 
-  : m_nd1(0), m_nd2(0),
-    m_delay (delay),
-    m_maxRate (maxRate)
-{
-}
-
-P2PChannel::~P2PChannel ()
-{}
-
-// Channels create compatible net devices
-P2PNetDevice* P2PChannel::CreateNetDevice(Node *node, MacAddress address)
-{
-  // Create a new point-to-point network device
-  P2PNetDevice* nd = new P2PNetDevice(node, address);
-  nd->Connect (this);
-  // Add to list of peers
-  if (!m_nd1) m_nd1 = nd;
-  else m_nd2 = nd;
-  return nd;
-}
-
-void P2PChannel::RemoveNetDevice(NetDevice* nd)
-{
-  if (nd == m_nd1) m_nd1 = 0;
-  if (nd == m_nd2) m_nd2 = 0;
-  // Now if all removed, remove the channel as well
-  if (!m_nd1 && !m_nd2)
-    {
-      delete this;
-    }
-}
-
-void P2PChannel::Send(P2PNetDevice *device, Packet& p, double rate)
-{ // Schedule a receive event at receiver
-  // First calculate time in future
-  double maxRate;
-  if (rate < m_maxRate)
-    {
-      maxRate = rate;
-    } 
-  else
-    {
-      maxRate = m_maxRate;
-    }
-  Time txTime = Seconds (p.GetSize() * 8 / maxRate);
-  Time rxTime = m_delay + txTime;
-  P2PNetDevice *to, *from;
-  if (device == m_nd1)
-    {
-      from = m_nd1;
-      to = m_nd2;
-    }
-  else
-    {
-      from = m_nd2;
-      to = m_nd1;
-    }
-  // Schedule the receive event at receiver
-  Simulator::Schedule(rxTime, &P2PNetDevice::Receive, to, p);
-  // Schedule the link free event
-  Simulator::Schedule(txTime, &P2PNetDevice::TxComplete, from);
-
-}
-
-}//namespace ns3
--- a/src/devices/p2p-gfr/p2p-channel.h	Sun May 13 12:46:18 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Definition of a simple point-to-point channel
-// George F. Riley, Georgia Tech, Spring 2007
-
-#ifndef P2P_CHANNEL_H
-#define P2P_CHANNEL_H
-
-#include "ns3/nstime.h"
-#include "ns3/mac-address.h"
-
-namespace ns3 {
-
-class P2PNetDevice;
-class NetDevice;
-class Node;
-class Packet;
-
-class P2PChannel  {
-public:
-  P2PChannel(const Time& delay, double maxRate /* bits/s */);
-  ~P2PChannel();
-
-  P2PNetDevice* CreateNetDevice(Node *node, MacAddress address);
-  void       RemoveNetDevice (NetDevice *device);
-  void       Send (P2PNetDevice *device, Packet&p, double rate /* bits/s */);
-private:
-  // The two endpoints of this channel
-  P2PNetDevice* m_nd1;
-  P2PNetDevice* m_nd2;
-  Time          m_delay;
-  double        m_maxRate;
-};
-
-}//namespace ns3
-
-#endif
--- a/src/devices/p2p-gfr/p2p-net-device.cc	Sun May 13 12:46:18 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Implementation of a point-to-point network device
-// George F. Riley, Georgia Tech, Spring 2007
-
-#include "ns3/empty-trace-resolver.h"
-#include "p2p-net-device.h"
-#include "p2p-channel.h"
-
-namespace ns3 {
-
-P2PNetDevice::P2PNetDevice (Node *node, MacAddress const &addr)
-  : NetDevice (node, addr),
-    m_rate (1000000)
-{
-  SetMtu (2300);
-  EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff"));
-}
-
-P2PNetDevice::~P2PNetDevice()
-{ // Inform channel that we are destroyed
-  m_channel->RemoveNetDevice(this);
-}
-
-void 
-P2PNetDevice::SetRate (double rate)
-{
-  m_rate = rate;
-}
-
-void 
-P2PNetDevice::Connect (P2PChannel *channel)
-{
-  m_channel = channel;
-  NotifyLinkUp ();
-}
-
-bool 
-P2PNetDevice::SendTo (Packet& p, const MacAddress&)
-{
-  m_channel->Send (this, p, m_rate);
-  return true;
-}
-
-TraceResolver *
-P2PNetDevice::DoCreateTraceResolver (TraceContext const &context)
-{
-  return new EmptyTraceResolver (context);
-}
-
-void
-P2PNetDevice::Receive(Packet p)
-{
-  ForwardUp (p);
-}
-
-void 
-P2PNetDevice::TxComplete (void)
-{}
-
-}//namespace ns3  
--- a/src/devices/p2p-gfr/p2p-net-device.h	Sun May 13 12:46:18 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Definition for a Point-to-Point network device
-// George F. Riley, Georgia Tech, Spring 2007
-
-#ifndef P2P_NET_DEVICE_H
-#define P2P_NET_DEVICE_H
-
-#include "ns3/net-device.h"
-
-namespace ns3 {
-
-class P2PChannel;
-
-class P2PNetDevice : public NetDevice {
-public:
-  P2PNetDevice(Node *node, MacAddress const &addr);
-  virtual ~P2PNetDevice();
-
-  void SetRate (double rate);
-  void Connect (P2PChannel *channel);
-  void Receive(Packet p);
-  void TxComplete (void);
- private:
-  virtual bool SendTo (Packet& p, const MacAddress& dest);
-  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
-
-  double m_rate;
-  P2PChannel *m_channel;
-};
-
-}//namespace ns3
-
-#endif /* P2P_NET_DEVICE_H */
-
--- a/src/devices/p2p-gfr/wscript	Sun May 13 12:46:18 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-
-def build(bld):
-    p2p = bld.create_obj('cpp', 'objects')
-    p2p.name = 'ns3-p2p-gfr'
-    p2p.source = [
-        'p2p-net-device.cc',
-        'p2p-channel.cc',
-        'p2p-topology.cc',
-        'p2p-phy.cc',
-        'layer-connector.cc',
-        ]
-    headers = bld.create_obj('ns3header')
-    headers.name = 'ns3-p2p-gfr-headers'
-    headers.source = [
-        'p2p-net-device.h',
-        'p2p-channel.h',
-        'p2p-topology.h',
-        'p2p-phy.h',
-        'layer-connector.h',
-        ]
-
--- a/src/devices/p2p/p2p-channel.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/devices/p2p/p2p-channel.cc	Sun May 13 12:52:38 2007 +0100
@@ -70,11 +70,11 @@
 }
 
   void
-PointToPointChannel::Attach(PointToPointNetDevice *device)
+PointToPointChannel::Attach(Ptr<PointToPointNetDevice> device)
 {
   NS_DEBUG("PointToPointChannel::Attach (" << device << ")");
   NS_ASSERT(m_nDevices < N_DEVICES && "Only two devices permitted");
-  NS_ASSERT(device);
+  NS_ASSERT(device != 0);
 
   m_link[m_nDevices].m_src = device;
   ++m_nDevices;
@@ -92,7 +92,7 @@
 }
 
 bool
-PointToPointChannel::TransmitStart(Packet& p, PointToPointNetDevice* src)
+PointToPointChannel::TransmitStart(Packet& p, Ptr<PointToPointNetDevice> src)
 {
   NS_DEBUG ("PointToPointChannel::TransmitStart (" << &p << ", " << src << 
             ")");
@@ -117,7 +117,7 @@
 }
 
 bool
-PointToPointChannel::TransmitEnd(Packet& p, PointToPointNetDevice* src)
+PointToPointChannel::TransmitEnd(Packet& p, Ptr<PointToPointNetDevice> src)
 {
   NS_DEBUG("PointToPointChannel::TransmitEnd (" << &p << ", " << src << ")");
   NS_DEBUG ("PointToPointChannel::TransmitEnd (): UID is " << 
@@ -147,7 +147,7 @@
 void
 PointToPointChannel::PropagationCompleteEvent(
   Packet p, 
-  PointToPointNetDevice *src)
+  Ptr<PointToPointNetDevice> src)
 {
   NS_DEBUG("PointToPointChannel::PropagationCompleteEvent (" << &p << ", " << 
     src << ")");
@@ -169,7 +169,7 @@
   return m_nDevices;
 }
 
-NetDevice *
+Ptr<NetDevice>
 PointToPointChannel::GetDevice (uint32_t i) const
 {
   NS_ASSERT(i < 2);
--- a/src/devices/p2p/p2p-channel.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/devices/p2p/p2p-channel.h	Sun May 13 12:52:38 2007 +0100
@@ -21,6 +21,7 @@
 
 #include <list>
 #include "ns3/channel.h"
+#include "ns3/ptr.h"
 #include "ns3/packet.h"
 #include "ns3/nstime.h"
 #include "ns3/data-rate.h"
@@ -62,13 +63,13 @@
   PointToPointChannel (const std::string& name,
                  const DataRate& bps, const Time& delay);
 
-  void Attach (PointToPointNetDevice* device);
-  bool TransmitStart (Packet& p, PointToPointNetDevice *src);
-  bool TransmitEnd (Packet &p, PointToPointNetDevice *src);
-  void PropagationCompleteEvent(Packet p, PointToPointNetDevice *src);
+  void Attach (Ptr<PointToPointNetDevice> device);
+  bool TransmitStart (Packet& p, Ptr<PointToPointNetDevice> src);
+  bool TransmitEnd (Packet &p, Ptr<PointToPointNetDevice> src);
+  void PropagationCompleteEvent(Packet p, Ptr<PointToPointNetDevice> src);
 
   virtual uint32_t GetNDevices (void) const;
-  virtual NetDevice *GetDevice (uint32_t i) const;
+  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
 
   virtual DataRate GetDataRate (void);
   virtual Time GetDelay (void);
@@ -92,8 +93,8 @@
   public:
     Link() : m_state (INITIALIZING), m_src (0), m_dst (0) {}
     WireState              m_state;
-    PointToPointNetDevice *m_src;
-    PointToPointNetDevice *m_dst;
+    Ptr<PointToPointNetDevice> m_src;
+    Ptr<PointToPointNetDevice> m_dst;
   };
     
   Link    m_link[N_DEVICES];
--- a/src/devices/p2p/p2p-net-device.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/devices/p2p/p2p-net-device.cc	Sun May 13 12:52:38 2007 +0100
@@ -32,7 +32,7 @@
 
 namespace ns3 {
 
-PointToPointNetDevice::PointToPointNetDevice (Node* node) 
+PointToPointNetDevice::PointToPointNetDevice (Ptr<Node> node) 
 : 
   NetDevice(node, MacAddress ("00:00:00:00:00:00")), 
   m_txMachineState (READY),
@@ -55,8 +55,6 @@
 PointToPointNetDevice::~PointToPointNetDevice()
 {
   NS_DEBUG ("PointToPointNetDevice::~PointToPointNetDevice ()");
-
-  delete m_queue;
   m_queue = 0;
 }
 
@@ -81,18 +79,12 @@
   m_txMachineState(READY),
   m_bps (nd.m_bps),
   m_tInterframeGap (nd.m_tInterframeGap),
-  m_channel(0), 
+  m_channel(nd.m_channel), 
   m_queue(0),
   m_rxTrace ()
 {
   NS_DEBUG ("PointToPointNetDevice::PointToPointNetDevice (" << &nd << ")");
 
-  if (nd.m_channel)
-    {
-      m_channel = nd.m_channel;
-      m_channel->Ref ();
-    }
-
   if (nd.m_queue)
     {
       m_queue = nd.m_queue;
@@ -102,12 +94,8 @@
 
 void PointToPointNetDevice::DoDispose()
 {
- if (m_channel != 0)
- {
-   m_channel->Unref ();
-   m_channel = 0;
- }
- NetDevice::DoDispose ();
+  m_channel = 0;
+  NetDevice::DoDispose ();
 }
 
 //
@@ -296,7 +284,7 @@
 {
   CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
   resolver->Add ("queue", 
-                 MakeCallback (&Queue::CreateTraceResolver, m_queue),
+                 MakeCallback (&Queue::CreateTraceResolver, PeekPointer (m_queue)),
                  PointToPointNetDevice::QUEUE);
   resolver->Add ("rx",
                  m_rxTrace,
@@ -305,18 +293,11 @@
 }
 
 bool
-PointToPointNetDevice::Attach (PointToPointChannel* ch)
+PointToPointNetDevice::Attach (Ptr<PointToPointChannel> ch)
 {
   NS_DEBUG ("PointToPointNetDevice::Attach (" << &ch << ")");
 
-  if (m_channel)
-    {
-      m_channel->Unref ();
-      m_channel = 0;
-    }
-
   m_channel = ch;
-  m_channel->Ref ();
 
   m_channel->Attach(this);
   m_bps = m_channel->GetDataRate ();
@@ -335,7 +316,7 @@
 }
 
 void
-PointToPointNetDevice::AddQueue (Queue* q)
+PointToPointNetDevice::AddQueue (Ptr<Queue> q)
 {
   NS_DEBUG ("PointToPointNetDevice::AddQueue (" << q << ")");
 
@@ -352,16 +333,15 @@
   ForwardUp (p);
 }
 
-Queue* 
+Ptr<Queue>
 PointToPointNetDevice::GetQueue(void) const 
 { 
     return m_queue;
 }
 
-Channel* 
+Ptr<Channel>
 PointToPointNetDevice::DoGetChannel(void) const 
 { 
-    m_channel->Ref();
     return m_channel;
 }
 
--- a/src/devices/p2p/p2p-net-device.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/devices/p2p/p2p-net-device.h	Sun May 13 12:52:38 2007 +0100
@@ -30,6 +30,7 @@
 #include "ns3/callback-trace-source.h"
 #include "ns3/nstime.h"
 #include "ns3/data-rate.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -79,7 +80,7 @@
    * @see PointToPointTopology::AddPointToPointLink ()
    * @param node the Node to which this device is connected.
    */
-  PointToPointNetDevice (Node* node);
+  PointToPointNetDevice (Ptr<Node> node);
   /**
    * Copy Construct a PointToPointNetDevice
    *
@@ -139,7 +140,7 @@
    * @see SetInterframeGap ()
    * @param ch a pointer to the channel to which this object is being attached.
    */
-  bool Attach(PointToPointChannel* ch);
+  bool Attach(Ptr<PointToPointChannel> ch);
   /**
    * Attach a queue to the PointToPointNetDevice.
    *
@@ -154,7 +155,7 @@
    * @param queue a pointer to the queue for which object is assuming
    *        ownership.
    */
-  void AddQueue(Queue* queue);
+  void AddQueue(Ptr<Queue> queue);
   /**
    * Receive a packet from a connected PointToPointChannel.
    *
@@ -178,7 +179,7 @@
    * @see PointToPointTopology
    * @returns a pointer to the queue.
    */
-  Queue* GetQueue(void) const; 
+  Ptr<Queue> GetQueue(void) const; 
   /**
    * Get a copy of the attached Channel
    *
@@ -188,7 +189,7 @@
    * @see PointToPointChannel
    * @returns a pointer to the channel
    */
-  virtual Channel *DoGetChannel(void) const;
+  virtual Ptr<Channel> DoGetChannel(void) const;
 private:
   /**
    * Send a Packet Down the Wire.
@@ -287,7 +288,7 @@
    * attached.
    * @see class PointToPointChannel
    */
-  PointToPointChannel* m_channel;
+  Ptr<PointToPointChannel> m_channel;
   /**
    * The Queue which this PointToPointNetDevice uses as a packet source.
    * Management of this Queue has been delegated to the PointToPointNetDevice
@@ -295,7 +296,7 @@
    * @see class Queue
    * @see class DropTailQueue
    */
-  Queue* m_queue;
+  Ptr<Queue> m_queue;
   /**
    * The trace source for the packet reception events that the device can
    * fire.
--- a/src/devices/p2p/p2p-topology.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/devices/p2p/p2p-topology.cc	Sun May 13 12:52:38 2007 +0100
@@ -24,13 +24,13 @@
 
 #include <algorithm>
 #include "ns3/assert.h"
-
+#include "ns3/debug.h"
+#include "ns3/fatal-error.h"
 #include "ns3/nstime.h"
-
 #include "ns3/internet-node.h"
 #include "ns3/ipv4-address.h"
-#include "ns3/drop-tail.h"
 #include "ns3/i-ipv4.h"
+#include "ns3/queue.h"
 
 #include "p2p-channel.h"
 #include "p2p-net-device.h"
@@ -38,35 +38,35 @@
 
 namespace ns3 {
 
-PointToPointChannel *
+Ptr<PointToPointChannel>
 PointToPointTopology::AddPointToPointLink(
-  Node* n1,
-  Node* n2,
+  Ptr<Node> n1,
+  Ptr<Node> n2,
   const DataRate& bps,
   const Time& delay)
 {
-  PointToPointChannel* channel = new PointToPointChannel(bps, delay);
+  Ptr<PointToPointChannel> channel = MakeNewObject<PointToPointChannel> (bps, delay);
 
-  PointToPointNetDevice* net1 = new PointToPointNetDevice(n1);
-  net1->AddQueue(Queue::Default().Copy());
-  n1->AddDevice (net1);
+  Ptr<PointToPointNetDevice> net1 = MakeNewObject<PointToPointNetDevice> (n1);
+
+  Ptr<Queue> q = Queue::CreateDefault ();
+  net1->AddQueue(q);
   net1->Attach (channel);
-  net1->Unref ();
   
-  PointToPointNetDevice* net2 = new PointToPointNetDevice(n2);
-  net2->AddQueue(Queue::Default().Copy());
-  n2->AddDevice (net2);
+  Ptr<PointToPointNetDevice> net2 = MakeNewObject<PointToPointNetDevice> (n2);
+
+  q = Queue::CreateDefault ();
+  net2->AddQueue(q);
   net2->Attach (channel);
-  net2->Unref ();
 
   return channel;
 }
 
-bool
+void
 PointToPointTopology::AddIpv4Addresses(
-  const PointToPointChannel *chan,
-  Node* n1, const Ipv4Address& addr1,
-  Node* n2, const Ipv4Address& addr2)
+  Ptr<const PointToPointChannel> chan,
+  Ptr<Node> n1, const Ipv4Address& addr1,
+  Ptr<Node> n2, const Ipv4Address& addr2)
 {
 
   // Duplex link is assumed to be subnetted as a /30
@@ -76,148 +76,97 @@
 
   // The PointToPoint channel is used to find the relevant NetDevices
   NS_ASSERT (chan->GetNDevices () == 2);
-  NetDevice* nd1 = chan->GetDevice (0);
-  NetDevice* nd2 = chan->GetDevice (1);
+  Ptr<NetDevice> nd1 = chan->GetDevice (0);
+  Ptr<NetDevice> nd2 = chan->GetDevice (1);
   // Make sure that nd1 belongs to n1 and nd2 to n2
-  if ( (nd1->PeekNode ()->GetId () == n2->GetId () ) && 
-       (nd2->PeekNode ()->GetId () == n1->GetId () ) )
+  if ( (nd1->GetNode ()->GetId () == n2->GetId () ) && 
+       (nd2->GetNode ()->GetId () == n1->GetId () ) )
     {
       std::swap(nd1, nd2);
     }
-  NS_ASSERT (nd1->PeekNode ()->GetId () == n1->GetId ());
-  NS_ASSERT (nd2->PeekNode ()->GetId () == n2->GetId ());
+  NS_ASSERT (nd1->GetNode ()->GetId () == n1->GetId ());
+  NS_ASSERT (nd2->GetNode ()->GetId () == n2->GetId ());
   
-  IIpv4 *ip1 = n1->QueryInterface<IIpv4> (IIpv4::iid);
+  Ptr<IIpv4> ip1 = n1->QueryInterface<IIpv4> (IIpv4::iid);
   uint32_t index1 = ip1->AddInterface (nd1);
 
   ip1->SetAddress (index1, addr1);
   ip1->SetNetworkMask (index1, netmask);
   ip1->SetUp (index1);
 
-  IIpv4 *ip2 = n2->QueryInterface<IIpv4> (IIpv4::iid);
+  Ptr<IIpv4> ip2 = n2->QueryInterface<IIpv4> (IIpv4::iid);
   uint32_t index2 = ip2->AddInterface (nd2);
 
   ip2->SetAddress (index2, addr2);
   ip2->SetNetworkMask (index2, netmask);
   ip2->SetUp (index2);
   
-  ip1->AddHostRouteTo (addr2, index1);
-  ip2->AddHostRouteTo (addr1, index2);
-  
-  ip1->Unref ();
-  ip2->Unref ();
-  
-  return true;
-}
-
-#ifdef NOTYET
-
-// Get the net device connecting node n1 to n2.  For topologies where
-// there are possibly multiple devices connecting n1 and n2 (for example
-// wireless with two devices on different channels) this will return
-// the first one found.
-PointToPointNetDevice* PointToPointTopology::GetNetDevice(Node* n1, Node* n2)
-{
-  // First get the NetDeviceList capability from node 1
-  NetDeviceList* ndl1 = n1->GetNetDeviceList();
-  if (!ndl1) return 0; // No devices, return nil
-  // Get the list of devices
-  const NetDeviceList::NetDevices_t& dlist = ndl1->GetAll();
-  for (NetDeviceList::NetDevices_t::const_iterator i = dlist.Begin();
-       i != dlist.End(); ++i)
-    { // Check each device
-      NetDevice* nd = *i; // next device
-      Channel* c = nd->GetChannel();
-      if (!c) continue; // No channel
-      if (c->NodeIsPeer(n2)) return nd; // found it
-    }
-  return 0; // None found
-}
-  
-// Get the channel connecting node n1 to node n2
-PointToPointChannel* PointToPointTopology::GetChannel(
-  Node* n1, 
-  Node* n2
-)
-{
-  NetDevice* nd = GetNetDevice(n1, n2);
-  if (!nd) return 0; // No net device, so no channel
-  return nd->GetChannel();
-}
-
-Queue* PointToPointTopology::GetQueue(Node* n1, Node* n2)
-{
-  NetDevice* nd = GetNetDevice(n1, n2);
-  if (!nd) return 0; // No net device, so in queue
-  return nd->GetQueue();
-}
-
-Queue* PointToPointTopology::SetQueue(Node* n1, Node* n2, const Queue& q)
-{
-  NetDevice* nd = GetNetDevice(n1, n2);
-  if (!nd) return 0; // No net device, can't set queue
-  // Add the specified queue to the netdevice
-  return nd->SetQueue(q);
 }
 
-#endif
+void
+PointToPointTopology::AddIpv4Routes (
+  Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> chan)
+{ 
+  // The PointToPoint channel is used to find the relevant NetDevices
+  NS_ASSERT (chan->GetNDevices () == 2);
+  Ptr<NetDevice> nd1 = chan->GetDevice (0);
+  Ptr<NetDevice> nd2 = chan->GetDevice (1);
+
+  // Assert that n1 is the Node owning one of the two NetDevices
+  // and make sure that nd1 corresponds to it
+  if (nd1->GetNode ()->GetId () == n1->GetId ())
+    {
+      ; // Do nothing
+    }
+  else if (nd2->GetNode ()->GetId () == n1->GetId ())
+    {
+      std::swap(nd1, nd2);
+    }
+  else
+    {
+      NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
+    }
+
+   // Assert that n2 is the Node owning one of the two NetDevices
+   // and make sure that nd2 corresponds to it
+  if (nd2->GetNode ()->GetId () != n2->GetId ())
+    {
+      NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
+    }
 
-#ifdef GFR
-P2PChannel* Topology::AddDuplexLink(Node* n1, const IPAddr& ip1, 
-                                    Node* n2, const IPAddr& ip2,
-                                    const Rate& rate, const Time& delay)
-{
-  // First get the NetDeviceList capability from each node
-  NetDeviceList* ndl1 = n1->GetNetDeviceList();
-  NetDeviceList* ndl2 = n2->GetNetDeviceList();
-  if (!ndl1 || !ndl2) return nil;  // Both ends must have NetDeviceList
-  // Get the net devices
-  P2PNetDevice* nd1 = ndl1->Add(P2PNetDevice(n1, rate, nil));
-  P2PNetDevice* nd2 = ndl2->Add(P2PNetDevice(n1, rate, nd1->GetChannel()));
-  // Not implemented yet.  Add appropriate layer 2 protocol for
-  // the net devices.
-  // Get the L3 proto for node 1 and configure it with this device
-  L3Demux*    l3demux1 = n1->GetL3Demux();
-  L3Protocol* l3proto1 = nil;
-  // If the node 1 l3 demux exists, find the coresponding l3 protocol
-  if (l3demux1) l3proto1 = l3demux1->Lookup(ip1.L3Proto());
-  // If the l3 protocol exists, configure this net device.  Use a mask
-  // of all ones, since there is only one device on the remote end
-  // of this link
-  if (l3proto1) l3proto1->AddNetDevice(nd1, ip1, ip1.GetMask(ip1.Size()*8));
-  // Same for node 2
-  L3Demux*    l3demux2 = n2->GetL3Demux();
-  L3Protocol* l3proto2 = nil;
-  // If the node 2 l3 demux exists, find the coresponding l3 protocol
-  if (l3demux2) l3proto2 = l3demux2->Lookup(ip2.L3Proto());
-  if (l3proto2) l3proto2->AddNetDevice(nd2, ip2, ip2.GetMask(ip2.Size()*8));
-  return dynamic_cast<P2PChannel*>(nd1->GetChannel());  // Always succeeds
+  // Assert that both are Ipv4 nodes
+  Ptr<IIpv4> ip1 = nd1->GetNode ()->QueryInterface<IIpv4> (IIpv4::iid);
+  Ptr<IIpv4> ip2 = nd2->GetNode ()->QueryInterface<IIpv4> (IIpv4::iid);
+  NS_ASSERT(ip1 != 0 && ip2 != 0);
+
+  // Get interface indexes for both nodes corresponding to the right channel
+  uint32_t index1 = 0;
+  bool found = false;
+  for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++)
+    {
+      if (ip1 ->GetNetDevice (i) == nd1)
+        {
+          index1 = i;
+          found = true;
+        }
+    }
+  NS_ASSERT(found);
+
+  uint32_t index2 = 0;
+  found = false;
+  for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++)
+    {
+      if (ip2 ->GetNetDevice (i) == nd2)
+        {
+          index2 = i;
+          found = true;
+        }
+    }
+  NS_ASSERT(found);
+
+  ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1);
+  ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2); 
 }
 
-// Get the channel connecting node n1 to node n2
-Channel* Topology::GetChannel(Node* n1, Node* n2)
-{
-  NetDevice* nd = GetNetDevice(n1, n2);
-  if (!nd) return 0; // No net device, so no channel
-  return nd->GetChannel();
-}
-
-Queue* Topology::GetQueue(Node* n1, Node* n2)
-{
-  NetDevice* nd = GetNetDevice(n1, n2);
-  if (!nd) return 0; // No net device, so in queue
-  return nd->GetQueue();
-}
-
-Queue* Topology::SetQueue(Node* n1, Node* n2, const Queue& q)
-{
-  NetDevice* nd = GetNetDevice(n1, n2);
-  if (!nd) return 0; // No net device, can't set queue
-  // Add the specified queue to the netdevice
-  return nd->SetQueue(q);
-}
-
-#endif
-
 } // namespace ns3
  
--- a/src/devices/p2p/p2p-topology.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/devices/p2p/p2p-topology.h	Sun May 13 12:52:38 2007 +0100
@@ -19,10 +19,11 @@
 //
 // Topology helper for ns3.
 // George F. Riley, Georgia Tech, Spring 2007
-
 #ifndef __POINT_TO_POINT_TOPOLOGY_H__
 #define __POINT_TO_POINT_TOPOLOGY_H__
 
+#include "ns3/ptr.h"
+
 // The topology class consists of only static methods thar are used to
 // create the topology and data flows for an ns3 simulation
 
@@ -33,47 +34,51 @@
 class IPAddr;
 class DataRate;
 class Queue;
-//class Time;
 
 /**
- * \brief A helper class to create Topologies based on the ns3::PointToPointNetDevice and 
- *        ns3::PointToPointChannel objects.
- *
- * XXX ??
- * I think that some of the methods below are not implemented.
- * If so, remove them.
+ * \brief A helper class to create Topologies based on the 
+ * ns3::PointToPointNetDevice and  ns3::PointToPointChannel objects.
  */
 class PointToPointTopology {
 public:
   /** 
+   * \param n1 Node
+   * \param n2 Node
+   * \param rate Maximum transmission link rate 
+   * \param delay one-way propagation delay 
+   * \return Pointer to the underlying PointToPointChannel
+   * 
    * Add a full-duplex point-to-point link between two nodes
-   * with the specified IP addresses,  with specified maximum transmission rate
-   * and propagation delay.
+   * and attach PointToPointNetDevices to the resulting
+   * PointToPointChannel.  
    */
-  static PointToPointChannel* AddPointToPointLink(
-    Node*, Node*, const DataRate&, const Time&);
+  static Ptr<PointToPointChannel> AddPointToPointLink(
+    Ptr<Node> n1, Ptr<Node> n2, const DataRate& dataRate, const Time& delay);
 
-  static bool AddIpv4Addresses(
-    const PointToPointChannel*,
-    Node*, const Ipv4Address&,
-    Node*, const Ipv4Address&);
+  /** 
+   * \param chan PointToPointChannel to use
+   * \param n1 Node
+   * \param addr1 Ipv4 Address for n1
+   * \param n2 Node
+   * \param addr2 Ipv4 Address for n2
+   * 
+   * Add Ipv4Addresses to the Ipv4 interfaces associated with the 
+   * two PointToPointNetDevices on the provided PointToPointChannel
+   */
+  static void AddIpv4Addresses(
+    Ptr<const PointToPointChannel> chan,
+    Ptr<Node> n1, const Ipv4Address& addr1,
+    Ptr<Node> n2, const Ipv4Address& addr2);
 
   /**
-   * Get the connecting node n1 to node n2
-   */
-  static PointToPointChannel* GetChannel(Node*, Node*);
-  /**
-   * Get the NetDevice connecting node n1 to n2
+   * \param channel PointToPointChannel to use
+   * \param n1 Node
+   * \param n2 Node
+   * 
+   * For the given PointToPointChannel, for each Node, add an 
+   * IPv4 host route to the IPv4 address of the peer node.  
    */
-  static PointToPointNetDevice* GetNetDevice(Node*, Node*);
-  /**
-   * Get the queue associated with a link between two nodes
-   */
-  static Queue* GetQueue(Node*, Node*);
-  /**
-   * Set the queue associated with a link between two nodes
-   */
-  static Queue* SetQueue(Node*, Node*, const Queue&);
+  static void AddIpv4Routes (Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> channel);
 };
 
 } // namespace ns3
--- a/src/internet-node/arp-cache.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/arp-cache.cc	Sun May 13 12:52:38 2007 +0100
@@ -28,24 +28,21 @@
 
 namespace ns3 {
 
-ArpCache::ArpCache (NetDevice *device, Ipv4Interface *interface)
+ArpCache::ArpCache (Ptr<NetDevice> device, Ipv4Interface *interface)
   : m_device (device), 
     m_interface (interface),
     m_aliveTimeout (Seconds (120)),
     m_deadTimeout (Seconds (100)),
     m_waitReplyTimeout (Seconds (1))
-{
-  m_device->Ref ();
-}
+{}
 
 ArpCache::~ArpCache ()
 {
-  m_device->Unref ();
   Flush ();
 }
 
-NetDevice *
-ArpCache::PeekDevice (void) const
+Ptr<NetDevice>
+ArpCache::GetDevice (void) const
 {
   return m_device;
 }
--- a/src/internet-node/arp-cache.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/arp-cache.h	Sun May 13 12:52:38 2007 +0100
@@ -27,6 +27,7 @@
 #include "ns3/net-device.h"
 #include "ns3/ipv4-address.h"
 #include "ns3/mac-address.h"
+#include "ns3/ptr.h"
 #include "sgi-hashmap.h"
 
 namespace ns3 {
@@ -38,10 +39,10 @@
 public:
   class Entry;
 
-  ArpCache (NetDevice *device, Ipv4Interface *interface);
+  ArpCache (Ptr<NetDevice> device, Ipv4Interface *interface);
   ~ArpCache ();
 
-  NetDevice *PeekDevice (void) const;
+  Ptr<NetDevice> GetDevice (void) const;
   Ipv4Interface *GetInterface (void) const;
 
   void SetAliveTimeout (Time aliveTimeout);
@@ -91,7 +92,7 @@
   typedef sgi::hash_map<Ipv4Address, ArpCache::Entry *, Ipv4AddressHash> Cache;
   typedef sgi::hash_map<Ipv4Address, ArpCache::Entry *, Ipv4AddressHash>::iterator CacheI;
 
-  NetDevice *m_device;
+  Ptr<NetDevice> m_device;
   Ipv4Interface *m_interface;
   Time m_aliveTimeout;
   Time m_deadTimeout;
--- a/src/internet-node/arp-ipv4-interface.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/arp-ipv4-interface.cc	Sun May 13 12:52:38 2007 +0100
@@ -31,25 +31,21 @@
 
 namespace ns3 {
 
-ArpIpv4Interface::ArpIpv4Interface (Node *node, NetDevice *device)
+ArpIpv4Interface::ArpIpv4Interface (Ptr<Node> node, Ptr<NetDevice> device)
   : Ipv4Interface (device),
     m_node (node)
-{
-  m_node->Ref ();
-}
+{}
 ArpIpv4Interface::~ArpIpv4Interface ()
-{
-  m_node->Unref ();
-}
+{}
 
 TraceResolver *
 ArpIpv4Interface::DoCreateTraceResolver (TraceContext const &context)
 {
   CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
-  if (PeekDevice () != 0)
+  if (GetDevice () != 0)
     {
       resolver->Add ("netdevice",
-                     MakeCallback (&NetDevice::CreateTraceResolver, PeekDevice ()),
+                     MakeCallback (&NetDevice::CreateTraceResolver, PeekPointer (GetDevice ())),
                      ArpIpv4Interface::NETDEVICE);
     }
   
@@ -59,21 +55,20 @@
 void 
 ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest)
 {
-  NS_ASSERT (PeekDevice () != 0);
-  if (PeekDevice ()->NeedsArp ())
+  NS_ASSERT (GetDevice () != 0);
+  if (GetDevice ()->NeedsArp ())
     {
-      IArpPrivate * arp = m_node->QueryInterface<IArpPrivate> (IArpPrivate::iid);
+      Ptr<IArpPrivate> arp = m_node->QueryInterface<IArpPrivate> (IArpPrivate::iid);
       MacAddress hardwareDestination;
-      bool found = arp->Lookup (p, dest, PeekDevice (), &hardwareDestination);
+      bool found = arp->Lookup (p, dest, GetDevice (), &hardwareDestination);
       if (found)
         {
-          PeekDevice ()->Send (p, hardwareDestination, Ipv4::PROT_NUMBER);
+          GetDevice ()->Send (p, hardwareDestination, Ipv4::PROT_NUMBER);
         }
-      arp->Unref ();
     }
   else
     {
-      PeekDevice ()->Send (p, PeekDevice ()->GetBroadcast (), Ipv4::PROT_NUMBER);
+      GetDevice ()->Send (p, GetDevice ()->GetBroadcast (), Ipv4::PROT_NUMBER);
     }
 }
 
--- a/src/internet-node/arp-ipv4-interface.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/arp-ipv4-interface.h	Sun May 13 12:52:38 2007 +0100
@@ -23,6 +23,7 @@
 #define ARP_IPV4_INTERFACE_H
 
 #include "ipv4-interface.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -42,13 +43,13 @@
     NETDEVICE,
     ARP,
   };
-  ArpIpv4Interface (Node *node, NetDevice *device);
+  ArpIpv4Interface (Ptr<Node> node, Ptr<NetDevice> device);
   virtual ~ArpIpv4Interface ();
 
  private:
   virtual void SendTo (Packet p, Ipv4Address dest);
   virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
-  Node *m_node;
+  Ptr<Node> m_node;
 };
 
 }//namespace ns3
--- a/src/internet-node/arp.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/arp.cc	Sun May 13 12:52:38 2007 +0100
@@ -36,17 +36,13 @@
 
 const uint16_t Arp::PROT_NUMBER = 0x0806;
 
-Arp::Arp (Node *node)
+Arp::Arp (Ptr<Node> node)
   : L3Protocol (PROT_NUMBER, 0/* XXX: correct version number ? */ ),
     m_node (node)
-{
-  m_node->Ref ();
-}
+{}
 
 Arp::~Arp ()
-{
-  Dispose ();
-}
+{}
 
 void 
 Arp::DoDispose (void)
@@ -56,11 +52,7 @@
       delete *i;
     }
   m_cacheList.clear ();
-  if (m_node != 0)
-    {
-      m_node->Unref ();
-      m_node = 0;
-    }
+  m_node = 0;
   L3Protocol::DoDispose ();
 }
 
@@ -71,18 +63,17 @@
 }
 
 ArpCache *
-Arp::FindCache (NetDevice *device)
+Arp::FindCache (Ptr<NetDevice> device)
 {
   for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++)
     {
-      if ((*i)->PeekDevice () == device)
+      if ((*i)->GetDevice () == device)
 	{
 	  return *i;
 	}
     }
-  IIpv4Private *ipv4 = m_node->QueryInterface<IIpv4Private> (IIpv4Private::iid);
+  Ptr<IIpv4Private> ipv4 = m_node->QueryInterface<IIpv4Private> (IIpv4Private::iid);
   Ipv4Interface *interface = ipv4->FindInterfaceForDevice (device);
-  ipv4->Unref ();
   ArpCache * cache = new ArpCache (device, interface);
   NS_ASSERT (device->IsBroadcast ());
   device->SetLinkChangeCallback (MakeCallback (&ArpCache::Flush, cache));
@@ -91,7 +82,7 @@
 }
 
 void 
-Arp::Receive(Packet& packet, NetDevice *device)
+Arp::Receive(Packet& packet, Ptr<NetDevice> device)
 {
   ArpCache *cache = FindCache (device);
   ArpHeader arp;
@@ -140,7 +131,7 @@
 }
 bool 
 Arp::Lookup (Packet &packet, Ipv4Address destination, 
-	     NetDevice *device,
+	     Ptr<NetDevice> device,
 	     MacAddress *hardwareDestination)
 {
   ArpCache *cache = FindCache (device);
@@ -212,25 +203,25 @@
 Arp::SendArpRequest (ArpCache const *cache, Ipv4Address to)
 {
   ArpHeader arp;
-  arp.SetRequest (cache->PeekDevice ()->GetAddress (),
+  arp.SetRequest (cache->GetDevice ()->GetAddress (),
 		  cache->GetInterface ()->GetAddress (), 
-                  cache->PeekDevice ()->GetBroadcast (),
+                  cache->GetDevice ()->GetBroadcast (),
                   to);
   Packet packet;
   packet.AddHeader (arp);
-  cache->PeekDevice ()->Send (packet, cache->PeekDevice ()->GetBroadcast (), PROT_NUMBER);
+  cache->GetDevice ()->Send (packet, cache->GetDevice ()->GetBroadcast (), PROT_NUMBER);
 }
 
 void
 Arp::SendArpReply (ArpCache const *cache, Ipv4Address toIp, MacAddress toMac)
 {
   ArpHeader arp;
-  arp.SetReply (cache->PeekDevice ()->GetAddress (),
+  arp.SetReply (cache->GetDevice ()->GetAddress (),
                 cache->GetInterface ()->GetAddress (),
                 toMac, toIp);
   Packet packet;
   packet.AddHeader (arp);
-  cache->PeekDevice ()->Send (packet, toMac, PROT_NUMBER);
+  cache->GetDevice ()->Send (packet, toMac, PROT_NUMBER);
 }
 
 }//namespace ns3
--- a/src/internet-node/arp.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/arp.h	Sun May 13 12:52:38 2007 +0100
@@ -24,6 +24,7 @@
 #include <list>
 #include "ns3/ipv4-address.h"
 #include "ns3/mac-address.h"
+#include "ns3/ptr.h"
 #include "l3-protocol.h"
 
 namespace ns3 {
@@ -40,24 +41,24 @@
 public:
   static const uint16_t PROT_NUMBER;
 
-  Arp (Node *node);
+  Arp (Ptr<Node> node);
   ~Arp ();
 
   virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
 
-  virtual void Receive(Packet& p, NetDevice *device);
+  virtual void Receive(Packet& p, Ptr<NetDevice> device);
   bool Lookup (Packet &p, Ipv4Address destination, 
-	       NetDevice *device,
+	       Ptr<NetDevice> device,
 	       MacAddress *hardwareDestination);
 protected:
   virtual void DoDispose (void);
 private:
   typedef std::list<ArpCache *> CacheList;
-  ArpCache *FindCache (NetDevice *device);
+  ArpCache *FindCache (Ptr<NetDevice> device);
   void SendArpRequest (ArpCache const *cache, Ipv4Address to);
   void SendArpReply (ArpCache const *cache, Ipv4Address toIp, MacAddress toMac);
   CacheList m_cacheList;
-  Node *m_node;
+  Ptr<Node> m_node;
 };
 
 }//namespace ns3
--- a/src/internet-node/ascii-trace.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ascii-trace.cc	Sun May 13 12:52:38 2007 +0100
@@ -110,7 +110,7 @@
   m_os << Simulator::Now ().GetSeconds () << " ";
   NodeList::NodeIndex nodeIndex;
   context.Get (nodeIndex);
-  m_os << "node=" << NodeList::PeekNode (nodeIndex)->GetId () << " ";
+  m_os << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " ";
   Ipv4::InterfaceIndex interfaceIndex;
   context.Get (interfaceIndex);
   m_os << "interface=" << interfaceIndex << " ";
@@ -124,7 +124,7 @@
   m_os << "r " << Simulator::Now ().GetSeconds () << " ";
   NodeList::NodeIndex nodeIndex;
   context.Get (nodeIndex);
-  m_os << "node=" << NodeList::PeekNode (nodeIndex)->GetId () << " ";
+  m_os << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " ";
   Ipv4::InterfaceIndex interfaceIndex;
   context.Get (interfaceIndex);
   m_os << "interface=" << interfaceIndex << " ";
--- a/src/internet-node/i-arp-private.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-arp-private.cc	Sun May 13 12:52:38 2007 +0100
@@ -21,17 +21,16 @@
 #include "i-arp-private.h"
 #include "arp.h"
 #include "ns3/assert.h"
+#include "ns3/net-device.h"
 
 namespace ns3 {
 
-const Iid IArpPrivate::iid ("IArpPrivate");
+const InterfaceId IArpPrivate::iid ("IArpPrivate");
 
-IArpPrivate::IArpPrivate (Arp *arp)
-  : NsUnknown (IArpPrivate::iid),
+IArpPrivate::IArpPrivate (Ptr<Arp> arp)
+  : Interface (IArpPrivate::iid),
     m_arp (arp)
-{
-  m_arp->Ref ();
-}
+{}
 IArpPrivate::~IArpPrivate ()
 {
   NS_ASSERT (m_arp == 0);
@@ -39,7 +38,7 @@
 
 bool 
 IArpPrivate::Lookup (Packet &p, Ipv4Address destination, 
-		     NetDevice *device,
+		     Ptr<NetDevice> device,
 		     MacAddress *hardwareDestination)
 {
   return m_arp->Lookup (p, destination, device, hardwareDestination);
@@ -48,9 +47,8 @@
 void
 IArpPrivate::DoDispose (void)
 {
-  m_arp->Unref ();
   m_arp = 0;
-  NsUnknown::DoDispose ();
+  Interface::DoDispose ();
 }
 
 
--- a/src/internet-node/i-arp-private.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-arp-private.h	Sun May 13 12:52:38 2007 +0100
@@ -21,7 +21,7 @@
 #ifndef I_ARP_PRIVATE_H
 #define I_ARP_PRIVATE_H
 
-#include "ns3/ns-unknown.h"
+#include "ns3/interface.h"
 #include "ns3/ipv4-address.h"
 
 namespace ns3 {
@@ -31,19 +31,19 @@
 class Packet;
 class Arp;
 
-class IArpPrivate : public NsUnknown
+class IArpPrivate : public Interface
 {
 public:
-  static const Iid iid;
-  IArpPrivate (Arp *arp);
+  static const InterfaceId iid;
+  IArpPrivate (Ptr<Arp> arp);
   virtual ~IArpPrivate ();
   bool Lookup (Packet &p, Ipv4Address destination, 
-	       NetDevice *device,
+	       Ptr<NetDevice> device,
 	       MacAddress *hardwareDestination);
 protected:
   virtual void DoDispose (void);
 private:
-  Arp *m_arp;
+  Ptr<Arp> m_arp;
 };
 
 } // namespace ns3
--- a/src/internet-node/i-ipv4-impl.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-ipv4-impl.cc	Sun May 13 12:52:38 2007 +0100
@@ -20,15 +20,15 @@
  */
 #include "i-ipv4-impl.h"
 #include "ipv4.h"
+#include "ipv4-interface.h"
 #include "ns3/assert.h"
+#include "ns3/net-device.h"
 
 namespace ns3 {
 
-IIpv4Impl::IIpv4Impl (Ipv4 *ipv4)
+IIpv4Impl::IIpv4Impl (Ptr<Ipv4> ipv4)
   : m_ipv4 (ipv4)
-{
-  m_ipv4->Ref ();
-}
+{}
 IIpv4Impl::~IIpv4Impl ()
 {
   NS_ASSERT (m_ipv4 == 0);
@@ -36,7 +36,6 @@
 void 
 IIpv4Impl::DoDispose (void)
 {
-  m_ipv4->Unref ();
   m_ipv4 = 0;
 }
 
@@ -90,7 +89,7 @@
   return m_ipv4->RemoveRoute (i);
 }
 uint32_t 
-IIpv4Impl::AddInterface (NetDevice *device)
+IIpv4Impl::AddInterface (Ptr<NetDevice> device)
 {
   return m_ipv4->AddInterface (device);
 }
@@ -99,6 +98,11 @@
 {
   return m_ipv4->GetNInterfaces ();
 }
+Ptr<NetDevice>
+IIpv4Impl::GetNetDevice (uint32_t i)
+{
+  return m_ipv4->GetInterface (i)-> GetDevice ();
+}
 
 void 
 IIpv4Impl::SetAddress (uint32_t i, Ipv4Address address)
--- a/src/internet-node/i-ipv4-impl.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-ipv4-impl.h	Sun May 13 12:52:38 2007 +0100
@@ -22,6 +22,7 @@
 #define I_IPV4_IMPL_H
 
 #include "ns3/i-ipv4.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -30,7 +31,7 @@
 class IIpv4Impl : public IIpv4
 {
 public:
-  IIpv4Impl (Ipv4 *ipv4);
+  IIpv4Impl (Ptr<Ipv4> ipv4);
 
   virtual ~IIpv4Impl ();
 
@@ -51,8 +52,9 @@
   virtual uint32_t GetNRoutes (void);
   virtual Ipv4Route *GetRoute (uint32_t i);
   virtual void RemoveRoute (uint32_t i);
-  virtual uint32_t AddInterface (NetDevice *device);
+  virtual uint32_t AddInterface (Ptr<NetDevice> device);
   virtual uint32_t GetNInterfaces (void);  
+  virtual Ptr<NetDevice> GetNetDevice(uint32_t i);
 
   virtual void SetAddress (uint32_t i, Ipv4Address address);
   virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask);
@@ -65,7 +67,7 @@
 protected:
   virtual void DoDispose (void);
 private:
-  Ipv4 *m_ipv4;
+  Ptr<Ipv4> m_ipv4;
 };
 
 } // namespace ns3
--- a/src/internet-node/i-ipv4-private.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-ipv4-private.cc	Sun May 13 12:52:38 2007 +0100
@@ -21,17 +21,16 @@
 #include "i-ipv4-private.h"
 #include "ipv4.h"
 #include "ns3/assert.h"
+#include "ns3/net-device.h"
 
 namespace ns3 {
 
-const Iid IIpv4Private::iid ("IIpv4Private");
+const InterfaceId IIpv4Private::iid ("IIpv4Private");
 
-IIpv4Private::IIpv4Private (Ipv4 *ipv4)
-  : NsUnknown (IIpv4Private::iid),
+IIpv4Private::IIpv4Private (Ptr<Ipv4> ipv4)
+  : Interface (IIpv4Private::iid),
     m_ipv4 (ipv4)
-{
-  m_ipv4->Ref ();
-}
+{}
 IIpv4Private::~IIpv4Private ()
 {
   NS_ASSERT (m_ipv4 == 0);
@@ -48,21 +47,20 @@
   m_ipv4->Send (packet, source, destination, protocol);
 }
 Ipv4Interface *
-IIpv4Private::FindInterfaceForDevice (NetDevice const*device)
+IIpv4Private::FindInterfaceForDevice (Ptr<const NetDevice>device)
 {
   return m_ipv4->FindInterfaceForDevice (device);
 }
 void 
-IIpv4Private::Receive(Packet& p, NetDevice *device)
+IIpv4Private::Receive(Packet& p, Ptr<NetDevice> device)
 {
   m_ipv4->Receive (p, device);
 }
 void 
 IIpv4Private::DoDispose (void)
 {
-  m_ipv4->Unref ();
   m_ipv4 = 0;
-  NsUnknown::DoDispose ();
+  Interface::DoDispose ();
 }
 
 } // namespace ns3
--- a/src/internet-node/i-ipv4-private.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-ipv4-private.h	Sun May 13 12:52:38 2007 +0100
@@ -21,8 +21,9 @@
 #ifndef I_IPV4_PRIVATE_H
 #define I_IPV4_PRIVATE_H
 
-#include "ns3/ns-unknown.h"
+#include "ns3/interface.h"
 #include "ns3/ipv4-address.h"
+#include "ns3/ptr.h"
 #include <stdint.h>
 
 namespace ns3 {
@@ -34,22 +35,22 @@
 class Ipv4Interface;
 class NetDevice;
 
-class IIpv4Private : public NsUnknown
+class IIpv4Private : public Interface
 {
 public:
-  static const Iid iid;
-  IIpv4Private (Ipv4 *ipv4);
+  static const InterfaceId iid;
+  IIpv4Private (Ptr<Ipv4> ipv4);
   virtual ~IIpv4Private ();
 
   TraceResolver *CreateTraceResolver (TraceContext const &context);
   void Send (Packet const &packet, Ipv4Address source, 
 	     Ipv4Address destination, uint8_t protocol);
-  Ipv4Interface *FindInterfaceForDevice (NetDevice const*device);
-  void Receive(Packet& p, NetDevice *device);
+  Ipv4Interface *FindInterfaceForDevice (Ptr<const NetDevice>device);
+  void Receive(Packet& p, Ptr<NetDevice> device);
 protected:
   virtual void DoDispose (void);
 private:
-  Ipv4 *m_ipv4;
+  Ptr<Ipv4> m_ipv4;
 };
 
 } // namespace ns3
--- a/src/internet-node/i-udp-impl.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-udp-impl.cc	Sun May 13 12:52:38 2007 +0100
@@ -20,21 +20,20 @@
  */
 #include "i-udp-impl.h"
 #include "udp.h"
+#include "ns3/socket.h"
 #include "ns3/assert.h"
 
 namespace ns3 {
 
-IUdpImpl::IUdpImpl (Udp *udp)
+IUdpImpl::IUdpImpl (Ptr<Udp> udp)
   : m_udp (udp)
-{
-  m_udp->Ref ();
-}
+{}
 IUdpImpl::~IUdpImpl ()
 {
   NS_ASSERT (m_udp == 0);
 }
 
-Socket *
+Ptr<Socket>
 IUdpImpl::CreateSocket (void)
 {
   return m_udp->CreateSocket ();
@@ -43,11 +42,7 @@
 void 
 IUdpImpl::DoDispose (void)
 {
-  if (m_udp != 0)
-    {
-      m_udp->Unref ();
-      m_udp = 0;
-    }
+  m_udp = 0;
   IUdp::DoDispose ();
 }
 
--- a/src/internet-node/i-udp-impl.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/i-udp-impl.h	Sun May 13 12:52:38 2007 +0100
@@ -22,6 +22,7 @@
 #define I_UDP_IMPL_H
 
 #include "ns3/i-udp.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -30,15 +31,15 @@
 class IUdpImpl : public IUdp
 {
 public:
-  IUdpImpl (Udp *udp);
+  IUdpImpl (Ptr<Udp> udp);
   virtual ~IUdpImpl ();
 
-  virtual Socket *CreateSocket (void);
+  virtual Ptr<Socket> CreateSocket (void);
 
 protected:
   virtual void DoDispose (void);
 private:
-  Udp *m_udp;
+  Ptr<Udp> m_udp;
 };
 
 } // namespace ns3
--- a/src/internet-node/internet-node.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/internet-node.cc	Sun May 13 12:52:38 2007 +0100
@@ -22,7 +22,6 @@
 // George F. Riley, Georgia Tech, Fall 2006
 
 #include "ns3/composite-trace-resolver.h"
-#include "ns3/application-list.h"
 #include "ns3/net-device.h"
 
 #include "l3-demux.h"
@@ -41,42 +40,28 @@
 
 InternetNode::InternetNode()
 {
-  Ipv4 *ipv4 = new Ipv4 (this);
-  Arp *arp = new Arp (this);
-  Udp *udp = new Udp (this);
+  Ptr<Ipv4> ipv4 = MakeNewObject<Ipv4> (this);
+  Ptr<Arp> arp = MakeNewObject<Arp> (this);
+  Ptr<Udp> udp = MakeNewObject<Udp> (this);
 
-  ApplicationList *applicationList = new ApplicationList(this);
-  L3Demux *l3Demux = new L3Demux(this);
-  Ipv4L4Demux *ipv4L4Demux = new Ipv4L4Demux(this);
+  Ptr<L3Demux> l3Demux = MakeNewObject<L3Demux> (this);
+  Ptr<Ipv4L4Demux> ipv4L4Demux = MakeNewObject<Ipv4L4Demux> (this);
 
   l3Demux->Insert (ipv4);
   l3Demux->Insert (arp);
   ipv4L4Demux->Insert (udp);
 
-  IUdpImpl *udpImpl = new IUdpImpl (udp);
-  IArpPrivate *arpPrivate = new IArpPrivate (arp);
-  IIpv4Impl *ipv4Impl = new IIpv4Impl (ipv4);
-  IIpv4Private *ipv4Private = new IIpv4Private (ipv4);
+  Ptr<IUdpImpl> udpImpl = MakeNewObject<IUdpImpl> (udp);
+  Ptr<IArpPrivate> arpPrivate = MakeNewObject<IArpPrivate> (arp);
+  Ptr<IIpv4Impl> ipv4Impl = MakeNewObject<IIpv4Impl> (ipv4);
+  Ptr<IIpv4Private> ipv4Private = MakeNewObject<IIpv4Private> (ipv4);
 
-  NsUnknown::AddInterface (ipv4Private);
-  NsUnknown::AddInterface (ipv4Impl);
-  NsUnknown::AddInterface (arpPrivate);
-  NsUnknown::AddInterface (udpImpl);
-  NsUnknown::AddInterface (applicationList);
-  NsUnknown::AddInterface (l3Demux);
-  NsUnknown::AddInterface (ipv4L4Demux);
-
-
-  applicationList->Unref ();
-  l3Demux->Unref ();
-  ipv4L4Demux->Unref ();
-  arp->Unref ();
-  ipv4->Unref ();
-  udp->Unref ();
-  udpImpl->Unref ();
-  arpPrivate->Unref ();
-  ipv4Impl->Unref ();
-  ipv4Private->Unref ();
+  Interface::AddInterface (ipv4Private);
+  Interface::AddInterface (ipv4Impl);
+  Interface::AddInterface (arpPrivate);
+  Interface::AddInterface (udpImpl);
+  Interface::AddInterface (l3Demux);
+  Interface::AddInterface (ipv4L4Demux);
 }
 
 InternetNode::~InternetNode ()
@@ -89,14 +74,13 @@
 }
 
 TraceResolver *
-InternetNode::CreateTraceResolver (TraceContext const &context)
+InternetNode::DoCreateTraceResolver (TraceContext const &context)
 {
   CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
-  IIpv4Private *ipv4 = QueryInterface<IIpv4Private> (IIpv4Private::iid);
+  Ptr<IIpv4Private> ipv4 = QueryInterface<IIpv4Private> (IIpv4Private::iid);
   resolver->Add ("ipv4",
-                 MakeCallback (&IIpv4Private::CreateTraceResolver, ipv4),
+                 MakeCallback (&IIpv4Private::CreateTraceResolver, PeekPointer (ipv4)),
                  InternetNode::IPV4);
-  ipv4->Unref ();
 
   return resolver;
 }
@@ -108,17 +92,16 @@
 }
 
 void 
-InternetNode::DoAddDevice (NetDevice *device) const
+InternetNode::DoAddDevice (Ptr<NetDevice> device) const
 {
   device->SetReceiveCallback (MakeCallback (&InternetNode::ReceiveFromDevice, this));
 }
 
 bool
-InternetNode::ReceiveFromDevice (NetDevice *device, const Packet &p, uint16_t protocolNumber) const
+InternetNode::ReceiveFromDevice (Ptr<NetDevice> device, const Packet &p, uint16_t protocolNumber) const
 {
-  L3Demux *demux = QueryInterface<L3Demux> (L3Demux::iid);
-  L3Protocol *target = demux->PeekProtocol (protocolNumber);
-  demux->Unref ();
+  Ptr<L3Demux> demux = QueryInterface<L3Demux> (L3Demux::iid);
+  Ptr<L3Protocol> target = demux->GetProtocol (protocolNumber);
   if (target != 0) 
     {
       Packet packet = p;
--- a/src/internet-node/internet-node.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/internet-node.h	Sun May 13 12:52:38 2007 +0100
@@ -41,14 +41,14 @@
   };
   InternetNode();
   virtual ~InternetNode ();
-  virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
 
   void SetName(std::string name);
 protected:
   virtual void DoDispose(void);
 private:
-  virtual void DoAddDevice (NetDevice *device) const;
-  bool ReceiveFromDevice (NetDevice *device, const Packet &p, uint16_t protocolNumber) const;
+  virtual void DoAddDevice (Ptr<NetDevice> device) const;
+  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
+  bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &p, uint16_t protocolNumber) const;
   std::string      m_name;
 };
 
--- a/src/internet-node/ipv4-interface.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4-interface.cc	Sun May 13 12:52:38 2007 +0100
@@ -31,26 +31,16 @@
    * becoming useable, the user must invoke SetUp on them
    * once the final Ipv4 address and mask has been set.
    */
-Ipv4Interface::Ipv4Interface (NetDevice *nd) 
+Ipv4Interface::Ipv4Interface (Ptr<NetDevice> nd) 
   : m_netdevice (nd), 
     m_ifup(false)
-{
-  if (m_netdevice != 0)
-    {
-      m_netdevice->Ref ();
-    }
-}
+{}
 
 Ipv4Interface::~Ipv4Interface ()
-{
-  if (m_netdevice != 0)
-    {
-      m_netdevice->Unref ();
-    }
-}
+{}
 
-NetDevice*
-Ipv4Interface::PeekDevice (void) const
+Ptr<NetDevice>
+Ipv4Interface::GetDevice (void) const
 {
   return m_netdevice;
 }
--- a/src/internet-node/ipv4-interface.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4-interface.h	Sun May 13 12:52:38 2007 +0100
@@ -25,6 +25,7 @@
 
 #include <list>
 #include "ns3/ipv4-address.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -69,7 +70,7 @@
    *           This value can be zero in which case the MTU
    *           of this interface will be 2^(16-1).
    */
-  Ipv4Interface (NetDevice *nd);
+  Ipv4Interface (Ptr<NetDevice> nd);
   virtual ~Ipv4Interface();
 
   /**
@@ -87,7 +88,7 @@
    * \returns the underlying NetDevice. This method can return
    *          zero if this interface has no associated NetDevice.
    */
-  NetDevice *PeekDevice (void) const;
+  Ptr<NetDevice> GetDevice (void) const;
 
   /**
    * \param a set the ipv4 address of this interface.
@@ -153,7 +154,7 @@
  private:
   virtual void SendTo (Packet p, Ipv4Address dest) = 0;
   virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
-  NetDevice* m_netdevice;
+  Ptr<NetDevice> m_netdevice;
   bool m_ifup;
   Ipv4Address m_address;
   Ipv4Mask m_netmask;
--- a/src/internet-node/ipv4-l4-demux.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4-l4-demux.cc	Sun May 13 12:52:38 2007 +0100
@@ -30,14 +30,12 @@
 
 namespace ns3 {
 
-const Iid Ipv4L4Demux::iid ("Ipv4L4Demux");
+const InterfaceId Ipv4L4Demux::iid ("Ipv4L4Demux");
 
-Ipv4L4Demux::Ipv4L4Demux (Node *node)
-  : NsUnknown (Ipv4L4Demux::iid),
+Ipv4L4Demux::Ipv4L4Demux (Ptr<Node> node)
+  : Interface (Ipv4L4Demux::iid),
     m_node (node)
-{
-  m_node->Ref ();
-}
+{}
 
 Ipv4L4Demux::~Ipv4L4Demux()
 {}
@@ -45,18 +43,14 @@
 void
 Ipv4L4Demux::DoDispose (void)
 {
-  for (L4List_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
+  for (L4List_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
     {
       (*i)->Dispose ();
-      (*i)->Unref ();
+      *i = 0;
     }
   m_protocols.clear ();
-  if (m_node != 0)
-    {
-      m_node->Unref ();
-      m_node = 0;
-    }
-  NsUnknown::DoDispose ();
+  m_node = 0;
+  Interface::DoDispose ();
 }
 
 TraceResolver *
@@ -65,25 +59,24 @@
   CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
   for (L4List_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
     {
-      Ipv4L4Protocol *protocol = *i;
+      Ptr<Ipv4L4Protocol> protocol = *i;
       std::string protValue;
       std::ostringstream oss (protValue);
       oss << (*i)->GetProtocolNumber ();
       Ipv4L4ProtocolTraceType protocolNumber = (*i)->GetProtocolNumber ();
       resolver->Add (protValue,
-                     MakeCallback (&Ipv4L4Protocol::CreateTraceResolver, protocol),
+                     MakeCallback (&Ipv4L4Protocol::CreateTraceResolver, PeekPointer (protocol)),
                      protocolNumber);
     }
   return resolver;
 }
 void
-Ipv4L4Demux::Insert(Ipv4L4Protocol *protocol)
+Ipv4L4Demux::Insert(Ptr<Ipv4L4Protocol> protocol)
 {
-  protocol->Ref ();
   m_protocols.push_back (protocol);
 }
-Ipv4L4Protocol* 
-Ipv4L4Demux::PeekProtocol(int protocolNumber)
+Ptr<Ipv4L4Protocol>
+Ipv4L4Demux::GetProtocol(int protocolNumber)
 {
   for (L4List_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
     {
@@ -95,7 +88,7 @@
   return 0;
 }
 void
-Ipv4L4Demux::Erase(Ipv4L4Protocol*protocol)
+Ipv4L4Demux::Remove (Ptr<Ipv4L4Protocol> protocol)
 {
   m_protocols.remove (protocol);
 }
--- a/src/internet-node/ipv4-l4-demux.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4-l4-demux.h	Sun May 13 12:52:38 2007 +0100
@@ -26,7 +26,8 @@
 #define IPV4_L4_DEMUX_H
 
 #include <list>
-#include "ns3/ns-unknown.h"
+#include "ns3/interface.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -38,12 +39,12 @@
 /**
  * \brief L4 Ipv4 Demux
  */
-class Ipv4L4Demux : public NsUnknown
+class Ipv4L4Demux : public Interface
 {
 public:
-  static const Iid iid;
+  static const InterfaceId iid;
   typedef int Ipv4L4ProtocolTraceType;
-  Ipv4L4Demux (Node *node);
+  Ipv4L4Demux (Ptr<Node> node);
   virtual ~Ipv4L4Demux();
 
   /**
@@ -64,7 +65,7 @@
    * a working L4 Protocol and returned from this method.
    * The caller does not get ownership of the returned pointer.
    */
-  void Insert(Ipv4L4Protocol *protocol);
+  void Insert(Ptr<Ipv4L4Protocol> protocol);
   /**
    * \param protocolNumber number of protocol to lookup
    *        in this L4 Demux
@@ -74,19 +75,19 @@
    * to forward packets up the stack to the right protocol.
    * It is also called from InternetNode::GetUdp for example.
    */
-  Ipv4L4Protocol* PeekProtocol(int protocolNumber);
+  Ptr<Ipv4L4Protocol> GetProtocol(int protocolNumber);
   /**
    * \param protocol protocol to remove from this demux.
    *
    * The input value to this method should be the value
    * returned from the Ipv4L4Protocol::Insert method.
    */
-  void Erase(Ipv4L4Protocol*protocol);
+  void Remove (Ptr<Ipv4L4Protocol> protocol);
 private:
   virtual void DoDispose (void);
-  typedef std::list<Ipv4L4Protocol*> L4List_t;
+  typedef std::list<Ptr<Ipv4L4Protocol> > L4List_t;
   L4List_t m_protocols;
-  Node *m_node;
+  Ptr<Node> m_node;
 };
 
 } //namespace ns3
--- a/src/internet-node/ipv4-l4-protocol.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4-l4-protocol.h	Sun May 13 12:52:38 2007 +0100
@@ -29,7 +29,6 @@
 
 namespace ns3 {
 
-class Node;
 class Packet;
 class Ipv4Address;
 class TraceResolver;
--- a/src/internet-node/ipv4-loopback-interface.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4-loopback-interface.cc	Sun May 13 12:52:38 2007 +0100
@@ -27,16 +27,12 @@
 
 namespace ns3 {
 
-Ipv4LoopbackInterface::Ipv4LoopbackInterface (Node *node)
+Ipv4LoopbackInterface::Ipv4LoopbackInterface (Ptr<Node> node)
   : Ipv4Interface (0),
     m_node (node)
-{
-  m_node->Ref ();
-}
+{}
 Ipv4LoopbackInterface::~Ipv4LoopbackInterface ()
-{
-  m_node->Unref ();
-}
+{}
 
 TraceResolver *
 Ipv4LoopbackInterface::DoCreateTraceResolver (TraceContext const &context)
@@ -47,9 +43,8 @@
 void 
 Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest)
 {
-  IIpv4Private *ipv4 = m_node->QueryInterface<IIpv4Private> (IIpv4Private::iid);
-  ipv4->Receive (packet, PeekDevice ());
-  ipv4->Unref ();
+  Ptr<IIpv4Private> ipv4 = m_node->QueryInterface<IIpv4Private> (IIpv4Private::iid);
+  ipv4->Receive (packet, GetDevice ());
 }
 
 }//namespace ns3
--- a/src/internet-node/ipv4-loopback-interface.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4-loopback-interface.h	Sun May 13 12:52:38 2007 +0100
@@ -23,6 +23,7 @@
 #define IPV4_LOOPBACK_INTERFACE_H
 
 #include "ipv4-interface.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -31,14 +32,14 @@
 class Ipv4LoopbackInterface : public Ipv4Interface 
 {
  public:
-  Ipv4LoopbackInterface (Node *node);
+  Ipv4LoopbackInterface (Ptr<Node> node);
   virtual ~Ipv4LoopbackInterface ();
 
  private:
   virtual void SendTo (Packet p, Ipv4Address dest);
   virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
 
-  Node *m_node;
+  Ptr<Node> m_node;
 };
 
 }//namespace ns3
--- a/src/internet-node/ipv4.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4.cc	Sun May 13 12:52:38 2007 +0100
@@ -27,6 +27,7 @@
 #include "ns3/ipv4-address.h"
 #include "ns3/ipv4-route.h"
 #include "ns3/node.h"
+#include "ns3/net-device.h"
 
 #include "ipv4.h"
 #include "ipv4-l4-protocol.h"
@@ -42,7 +43,7 @@
 
 const uint16_t Ipv4::PROT_NUMBER = 0x0800;
 
-Ipv4::Ipv4(Node *node)
+Ipv4::Ipv4(Ptr<Node> node)
   : L3Protocol (PROT_NUMBER, 4),
     m_nInterfaces (0),
     m_defaultTtl (64),
@@ -51,12 +52,9 @@
     m_node (node)
 {
   SetupLoopback ();
-  m_node->Ref ();
 }
 Ipv4::~Ipv4 ()
-{
-  DoDispose ();
-}
+{}
 
 void 
 Ipv4::DoDispose (void)
@@ -83,11 +81,7 @@
       delete m_defaultRoute;
       m_defaultRoute = 0;
     }
-  if (m_node != 0)
-    {
-      m_node->Unref ();
-      m_node = 0;
-    }
+  m_node = 0;
   L3Protocol::DoDispose ();
 }
 
@@ -317,7 +311,7 @@
 
 
 uint32_t 
-Ipv4::AddInterface (NetDevice *device)
+Ipv4::AddInterface (Ptr<NetDevice> device)
 {
   Ipv4Interface *interface = new ArpIpv4Interface (m_node, device);
   return AddIpv4Interface (interface);
@@ -351,11 +345,11 @@
 }
 
 Ipv4Interface *
-Ipv4::FindInterfaceForDevice (NetDevice const*device)
+Ipv4::FindInterfaceForDevice (Ptr<const NetDevice> device)
 {
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
     {
-      if ((*i)->PeekDevice () == device)
+      if ((*i)->GetDevice () == device)
         {
           return *i;
         }
@@ -364,12 +358,12 @@
 }  
 
 void 
-Ipv4::Receive(Packet& packet, NetDevice *device)
+Ipv4::Receive(Packet& packet, Ptr<NetDevice> device)
 {
   uint32_t index = 0;
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
     {
-      if ((*i)->PeekDevice () == device)
+      if ((*i)->GetDevice () == device)
         {
           m_rxTrace (packet, index);
           break;
@@ -449,7 +443,7 @@
 
 
 bool
-Ipv4::Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice *device)
+Ipv4::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device)
 {
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
        i != m_interfaces.end (); i++) 
@@ -465,7 +459,7 @@
        i != m_interfaces.end (); i++) 
     {
       Ipv4Interface *interface = *i;
-      if (interface->PeekDevice () == device)
+      if (interface->GetDevice () == device)
 	{
 	  if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ())) 
 	    {
@@ -511,9 +505,8 @@
 void
 Ipv4::ForwardUp (Packet p, Ipv4Header const&ip)
 {
-  Ipv4L4Demux *demux = m_node->QueryInterface<Ipv4L4Demux> (Ipv4L4Demux::iid);
-  Ipv4L4Protocol *protocol = demux->PeekProtocol (ip.GetProtocol ());
-  demux->Unref ();
+  Ptr<Ipv4L4Demux> demux = m_node->QueryInterface<Ipv4L4Demux> (Ipv4L4Demux::iid);
+  Ptr<Ipv4L4Protocol> protocol = demux->GetProtocol (ip.GetProtocol ());
   protocol->Receive (p, ip.GetSource (), ip.GetDestination ());
 }
 
--- a/src/internet-node/ipv4.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/ipv4.h	Sun May 13 12:52:38 2007 +0100
@@ -27,6 +27,7 @@
 #include "ns3/callback-trace-source.h"
 #include "ns3/array-trace-resolver.h"
 #include "ns3/ipv4-address.h"
+#include "ns3/ptr.h"
 #include "l3-protocol.h"
 
 namespace ns3 {
@@ -58,7 +59,7 @@
   };
   typedef ArrayTraceResolver<Ipv4Interface>::Index InterfaceIndex;
 
-  Ipv4(Node *node);
+  Ipv4(Ptr<Node> node);
   virtual ~Ipv4 ();
 
   /**
@@ -164,7 +165,7 @@
    * to disable it, you can invoke Ipv4Interface::SetDown which will
    * make sure that it is never used during packet forwarding.
    */
-  uint32_t AddInterface (NetDevice *device);
+  uint32_t AddInterface (Ptr<NetDevice> device);
   /**
    * \param i index of interface to return
    * \returns the requested interface
@@ -181,7 +182,7 @@
    * Try to find an Ipv4Interface whose NetDevice is equal to
    * the input NetDevice.
    */
-  Ipv4Interface *FindInterfaceForDevice (NetDevice const*device);
+  Ipv4Interface *FindInterfaceForDevice (Ptr<const NetDevice> device);
   
 
   /**
@@ -191,7 +192,7 @@
    *    - implement a per-NetDevice ARP cache
    *    - send back arp replies on the right device
    */
-  virtual void Receive(Packet& p, NetDevice *device);
+  virtual void Receive(Packet& p, Ptr<NetDevice> device);
 
   /**
    * \param packet packet to send
@@ -219,7 +220,7 @@
   virtual void DoDispose (void);
 private:
   void SendRealOut (Packet const &packet, Ipv4Header const &ip, Ipv4Route const &route);
-  bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice *device);
+  bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device);
   void ForwardUp (Packet p, Ipv4Header const&ip);
   uint32_t AddIpv4Interface (Ipv4Interface *interface);
   void SetupLoopback (void);
@@ -240,7 +241,7 @@
   HostRoutes m_hostRoutes;
   NetworkRoutes m_networkRoutes;
   Ipv4Route *m_defaultRoute;
-  Node *m_node;
+  Ptr<Node> m_node;
   CallbackTraceSource<Packet const &, uint32_t> m_txTrace;
   CallbackTraceSource<Packet const &, uint32_t> m_rxTrace;
   CallbackTraceSource<Packet const &> m_dropTrace;
--- a/src/internet-node/l3-demux.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/l3-demux.cc	Sun May 13 12:52:38 2007 +0100
@@ -29,14 +29,12 @@
 
 namespace ns3 {
 
-const Iid L3Demux::iid ("L3Demux");
+const InterfaceId L3Demux::iid ("L3Demux");
 
-L3Demux::L3Demux (Node *node)
-  : NsUnknown (L3Demux::iid),
+L3Demux::L3Demux (Ptr<Node> node)
+  : Interface (L3Demux::iid),
     m_node (node)
-{
-  m_node->Ref ();
-}
+{}
 
 L3Demux::~L3Demux()
 {}
@@ -47,15 +45,11 @@
   for (L3Map_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
     {
       i->second->Dispose ();
-      i->second->Unref ();
+      i->second = 0;
     }
   m_protocols.clear ();
-  if (m_node != 0)
-    {
-      m_node->Unref ();
-      m_node = 0;
-    }
-  NsUnknown::DoDispose ();
+  m_node = 0;
+  Interface::DoDispose ();
 }
 
 TraceResolver *
@@ -69,23 +63,25 @@
       oss << i->second->GetProtocolNumber ();
       ProtocolTraceType context = i->second->GetProtocolNumber ();
       resolver->Add (protValue, 
-                     MakeCallback (&L3Protocol::CreateTraceResolver, i->second),
+                     MakeCallback (&L3Protocol::CreateTraceResolver, PeekPointer (i->second)),
                      context);
     }
   return resolver;
 }
   
-void L3Demux::Insert(L3Protocol *p)
+void L3Demux::Insert(Ptr<L3Protocol> p)
 {
-  p->Ref ();
   m_protocols.insert(L3Map_t::value_type(p->GetProtocolNumber (), p));
 }
 
-L3Protocol* 
-L3Demux::PeekProtocol (int p)
+Ptr<L3Protocol>
+L3Demux::GetProtocol (int p)
 { // Look up a protocol by protocol number
   L3Map_t::iterator i = m_protocols.find(p);
-  if (i == m_protocols.end()) return 0;  // Not found
+  if (i == m_protocols.end()) 
+    {
+      return 0;
+    }
   return i->second; // Return the protocol
 }
 
--- a/src/internet-node/l3-demux.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/l3-demux.h	Sun May 13 12:52:38 2007 +0100
@@ -28,7 +28,8 @@
 #define L3_DEMUX_H
 
 #include <map>
-#include "ns3/ns-unknown.h"
+#include "ns3/interface.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -40,12 +41,12 @@
 /**
  * \brief L3 Demux 
  */
-class L3Demux : public NsUnknown
+class L3Demux : public Interface
 {
 public:
-  static const Iid iid;
+  static const InterfaceId iid;
   typedef int ProtocolTraceType;
-  L3Demux(Node *node);
+  L3Demux(Ptr<Node> node);
   virtual ~L3Demux();
 
   /**
@@ -67,7 +68,7 @@
    * a working L3 Protocol and returned from this method.
    * The caller does not get ownership of the returned pointer.
    */
-  void Insert(ns3::L3Protocol * protocol);
+  void Insert(Ptr<L3Protocol> protocol);
   /**
    * \param protocolNumber number of protocol to lookup
    *        in this L4 Demux
@@ -77,20 +78,13 @@
    * to forward packets up the stack to the right protocol.
    * It is also called from InternetNode::GetIpv4 for example.
    */
-  ns3::L3Protocol* PeekProtocol (int protocolNumber);
-  /**
-   * \param protocol protocol to remove from this demux.
-   *
-   * The input value to this method should be the value
-   * returned from the L3Protocol::Insert method.
-   */
-  void Erase(ns3::L3Protocol*protocol);
+  Ptr<L3Protocol> GetProtocol (int protocolNumber);
 protected:
   virtual void DoDispose (void);
 private:
-  typedef std::map<int, ns3::L3Protocol*> L3Map_t;
+  typedef std::map<int, Ptr<ns3::L3Protocol> > L3Map_t;
 
-  Node *m_node;
+  Ptr<Node> m_node;
   L3Map_t m_protocols;
 };
 
--- a/src/internet-node/l3-protocol.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/l3-protocol.h	Sun May 13 12:52:38 2007 +0100
@@ -26,12 +26,12 @@
 #define L3_PROTOCOL_H
 
 #include "ns3/object.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
 class Packet;
 class NetDevice;
-class Node;
 class TraceResolver;
 class TraceContext;
 
@@ -54,7 +54,7 @@
    *    - implement a per-NetDevice ARP cache
    *    - send back arp replies on the right device
    */
-  virtual void Receive(Packet& p, NetDevice *device) = 0;
+  virtual void Receive(Packet& p, Ptr<NetDevice> device) = 0;
 
 protected:
   virtual void DoDispose (void);
--- a/src/internet-node/pcap-trace.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/pcap-trace.cc	Sun May 13 12:52:38 2007 +0100
@@ -84,7 +84,7 @@
 {
   NodeList::NodeIndex nodeIndex;
   context.Get (nodeIndex);
-  uint32_t nodeId = NodeList::PeekNode (nodeIndex)->GetId ();
+  uint32_t nodeId = NodeList::GetNode (nodeIndex)->GetId ();
   PcapWriter *writer = GetStream (nodeId, interfaceIndex);
   writer->WritePacket (p);
 }
--- a/src/internet-node/udp-socket.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/udp-socket.cc	Sun May 13 12:52:38 2007 +0100
@@ -26,7 +26,7 @@
 
 namespace ns3 {
 
-UdpSocket::UdpSocket (Node *node, Udp *udp)
+UdpSocket::UdpSocket (Ptr<Node> node, Ptr<Udp> udp)
   : m_endPoint (0),
     m_node (node),
     m_udp (udp),
@@ -34,17 +34,10 @@
     m_shutdownSend (false),
     m_shutdownRecv (false),
     m_connected (false)
-{
-  m_udp->Ref ();
-  m_node->Ref ();
-}
+{}
 UdpSocket::~UdpSocket ()
 {
-  if (m_node != 0)
-    {
-      m_node->Unref ();
-      m_node = 0;
-    }
+  m_node = 0;
   if (m_endPoint != 0)
     {
       NS_ASSERT (m_udp != 0);
@@ -60,15 +53,11 @@
       m_udp->DeAllocate (m_endPoint);
       NS_ASSERT (m_endPoint == 0);
     }
-  if (m_udp != 0)
-    {
-      m_udp->Unref ();
-      m_udp = 0;
-    }
+  m_udp = 0;
 }
 
-Node *
-UdpSocket::PeekNode (void) const
+Ptr<Node>
+UdpSocket::GetNode (void) const
 {
   return m_node;
 }
@@ -76,17 +65,9 @@
 void 
 UdpSocket::Destroy (void)
 {
-  if (m_node != 0)
-    {
-      m_node->Unref ();
-      m_node = 0;
-    }
+  m_node = 0;
   m_endPoint = 0;
-  if (m_udp != 0)
-    {
-      m_udp->Unref ();
-      m_udp = 0;
-    }
+  m_udp = 0;
 }
 int
 UdpSocket::FinishBind (void)
@@ -144,7 +125,7 @@
 }
 
 void 
-UdpSocket::DoClose(ns3::Callback<void, Socket*> closeCompleted)
+UdpSocket::DoClose(ns3::Callback<void, Ptr<Socket> > closeCompleted)
 {
   // XXX: we should set the close state and check it in all API methods.
   if (!closeCompleted.IsNull ())
@@ -155,9 +136,9 @@
 void 
 UdpSocket::DoConnect(const Ipv4Address & address,
                      uint16_t portNumber,
-                     ns3::Callback<void, Socket*> connectionSucceeded,
-                     ns3::Callback<void, Socket*> connectionFailed,
-                     ns3::Callback<void, Socket*> halfClose)
+                     ns3::Callback<void, Ptr<Socket> > connectionSucceeded,
+                     ns3::Callback<void, Ptr<Socket> > connectionFailed,
+                     ns3::Callback<void, Ptr<Socket> > halfClose)
 {
   m_defaultAddress = address;
   m_defaultPort = portNumber;
@@ -168,9 +149,9 @@
   m_connected = true;
 }
 int
-UdpSocket::DoAccept(ns3::Callback<bool, Socket*, const Ipv4Address&, uint16_t> connectionRequest,
-                    ns3::Callback<void, Socket*, const Ipv4Address&, uint16_t> newConnectionCreated,
-                    ns3::Callback<void, Socket*> closeRequested)
+UdpSocket::DoAccept(ns3::Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest,
+                    ns3::Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated,
+                    ns3::Callback<void, Ptr<Socket> > closeRequested)
 {
   // calling accept on a udp socket is a programming error.
   m_errno = EOPNOTSUPP;
@@ -179,7 +160,7 @@
 int 
 UdpSocket::DoSend (const uint8_t* buffer,
                    uint32_t size,
-                   ns3::Callback<void, Socket*, uint32_t> dataSent)
+                   ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
 {
   if (!m_connected)
     {
@@ -199,7 +180,7 @@
 }
 int
 UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport,
-                           ns3::Callback<void, Socket*, uint32_t> dataSent)
+                           ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
 {
   if (m_endPoint == 0)
     {
@@ -228,7 +209,7 @@
                     uint16_t port,
                     const uint8_t *buffer,
                     uint32_t size,
-                    ns3::Callback<void, Socket*, uint32_t> dataSent)
+                    ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
 {
   if (m_connected)
     {
@@ -247,12 +228,12 @@
   return DoSendPacketTo (p, address, port, dataSent);
 }
 void 
-UdpSocket::DoRecv(ns3::Callback<void, Socket*, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback)
+UdpSocket::DoRecv(ns3::Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback)
 {
   m_rxCallback = callback;
 }
 void 
-UdpSocket::DoRecvDummy(ns3::Callback<void, Socket*, uint32_t,const Ipv4Address&, uint16_t> callback)
+UdpSocket::DoRecvDummy(ns3::Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t> callback)
 {
   m_dummyRxCallback = callback;
 }
--- a/src/internet-node/udp-socket.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/udp-socket.h	Sun May 13 12:52:38 2007 +0100
@@ -24,6 +24,7 @@
 #include <stdint.h>
 #include "ns3/callback.h"
 #include "ns3/socket.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -38,11 +39,11 @@
   /**
    * Create an unbound udp socket.
    */
-  UdpSocket (Node *node, Udp *udp);
+  UdpSocket (Ptr<Node> node, Ptr<Udp> udp);
   virtual ~UdpSocket ();
 
   virtual enum SocketErrno GetErrno (void) const;
-  virtual Node *PeekNode (void) const;
+  virtual Ptr<Node> GetNode (void) const;
   virtual int Bind (void);
   virtual int Bind (Ipv4Address address);
   virtual int Bind (uint16_t port); 
@@ -51,25 +52,25 @@
   virtual int ShutdownRecv (void);
 
 private:
-  virtual void DoClose(ns3::Callback<void, Socket*> closeCompleted);
+  virtual void DoClose(ns3::Callback<void, Ptr<Socket> > closeCompleted);
   virtual void DoConnect(const Ipv4Address & address,
 			 uint16_t portNumber,
-			 ns3::Callback<void, Socket*> connectionSucceeded,
-			 ns3::Callback<void, Socket*> connectionFailed,
-			 ns3::Callback<void, Socket*> halfClose);
-  virtual int DoAccept(ns3::Callback<bool, Socket*, const Ipv4Address&, uint16_t> connectionRequest,
-		       ns3::Callback<void, Socket*, const Ipv4Address&, uint16_t> newConnectionCreated,
-		       ns3::Callback<void, Socket*> closeRequested);
+			 ns3::Callback<void, Ptr<Socket> > connectionSucceeded,
+			 ns3::Callback<void, Ptr<Socket> > connectionFailed,
+			 ns3::Callback<void, Ptr<Socket> > halfClose);
+  virtual int DoAccept(ns3::Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest,
+		       ns3::Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated,
+		       ns3::Callback<void, Ptr<Socket> > closeRequested);
   virtual int DoSend (const uint8_t* buffer,
                     uint32_t size,
-                    ns3::Callback<void, Socket*, uint32_t> dataSent);
+                    ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent);
   virtual int DoSendTo(const Ipv4Address &address,
                       uint16_t port,
                       const uint8_t *buffer,
                       uint32_t size,
-                      ns3::Callback<void, Socket*, uint32_t> dataSent);
-  virtual void DoRecv(ns3::Callback<void, Socket*, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t>);
-  virtual void DoRecvDummy(ns3::Callback<void, Socket*, uint32_t,const Ipv4Address&, uint16_t>);
+                      ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent);
+  virtual void DoRecv(ns3::Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t>);
+  virtual void DoRecvDummy(ns3::Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t>);
 
 private:
   friend class Udp;
@@ -78,15 +79,15 @@
   void ForwardUp (const Packet &p, Ipv4Address saddr, uint16_t sport);
   void Destroy (void);
   int DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport,
-		      ns3::Callback<void, Socket*, uint32_t> dataSent);
+		      ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent);
 
   Ipv4EndPoint *m_endPoint;
-  Node *m_node;
-  Udp *m_udp;
+  Ptr<Node> m_node;
+  Ptr<Udp> m_udp;
   Ipv4Address m_defaultAddress;
   uint16_t m_defaultPort;
-  Callback<void,Socket*,uint32_t,const Ipv4Address &,uint16_t> m_dummyRxCallback;
-  Callback<void,Socket*,uint8_t const*,uint32_t,const Ipv4Address &,uint16_t> m_rxCallback;
+  Callback<void,Ptr<Socket>,uint32_t,const Ipv4Address &,uint16_t> m_dummyRxCallback;
+  Callback<void,Ptr<Socket>,uint8_t const*,uint32_t,const Ipv4Address &,uint16_t> m_rxCallback;
   enum SocketErrno m_errno;
   bool m_shutdownSend;
   bool m_shutdownRecv;
--- a/src/internet-node/udp.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/udp.cc	Sun May 13 12:52:38 2007 +0100
@@ -38,13 +38,11 @@
 /* see http://www.iana.org/assignments/protocol-numbers */
 const uint8_t Udp::PROT_NUMBER = 17;
 
-Udp::Udp (Node *node)
+Udp::Udp (Ptr<Node> node)
   : Ipv4L4Protocol (PROT_NUMBER, 2),
     m_node (node),
     m_endPoints (new Ipv4EndPointDemux ())
-{
-  m_node->Ref ();
-}
+{}
 
 Udp::~Udp ()
 {}
@@ -63,18 +61,15 @@
       delete m_endPoints;
       m_endPoints = 0;
     }
-  if (m_node != 0)
-    {
-      m_node->Unref ();
-      m_node = 0;
-    }
+  m_node = 0;
   Ipv4L4Protocol::DoDispose ();
 }
 
-Socket *
+Ptr<Socket>
 Udp::CreateSocket (void)
 {
-  return new UdpSocket (m_node, this);
+  Ptr<Socket> socket = MakeNewObject<UdpSocket> (m_node, this);
+  return socket;
 }
 
 Ipv4EndPoint *
@@ -142,11 +137,10 @@
 
   packet.AddHeader (udpHeader);
 
-  IIpv4Private *ipv4 = m_node->QueryInterface<IIpv4Private> (IIpv4Private::iid);
+  Ptr<IIpv4Private> ipv4 = m_node->QueryInterface<IIpv4Private> (IIpv4Private::iid);
   if (ipv4 != 0)
     {
       ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
-      ipv4->Unref ();
     }
 }
 
--- a/src/internet-node/udp.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/internet-node/udp.h	Sun May 13 12:52:38 2007 +0100
@@ -26,6 +26,7 @@
 
 #include "ns3/packet.h"
 #include "ns3/ipv4-address.h"
+#include "ns3/ptr.h"
 #include "ipv4-end-point-demux.h"
 #include "ipv4-l4-protocol.h"
 
@@ -40,12 +41,12 @@
 public:
   static const uint8_t PROT_NUMBER;
 
-  Udp (Node *node);
+  Udp (Ptr<Node> node);
   virtual ~Udp ();
 
   virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
 
-  Socket *CreateSocket (void);
+  Ptr<Socket> CreateSocket (void);
 
   Ipv4EndPoint *Allocate (void);
   Ipv4EndPoint *Allocate (Ipv4Address address);
@@ -67,7 +68,7 @@
 protected:
   virtual void DoDispose (void);
 private:
-  Node *m_node;
+  Ptr<Node> m_node;
   Ipv4EndPointDemux *m_endPoints;
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/application.cc	Sun May 13 12:52:38 2007 +0100
@@ -0,0 +1,113 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 Georgia Tech Research Corporation
+ *
+ * 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: George F. Riley<riley@ece.gatech.edu>
+ */
+
+// Implementation for ns3 Application base class.
+// George F. Riley, Georgia Tech, Fall 2006
+
+#include "application.h"
+#include "ns3/node.h"
+#include "ns3/nstime.h"
+#include "ns3/random-variable.h"
+#include "ns3/simulator.h"
+
+using namespace std;
+
+namespace ns3 {
+
+// Application Methods
+
+// \brief Application Constructor
+Application::Application(Ptr<Node> n) 
+    : m_node (n)
+{
+  m_node->AddApplication (this);
+}
+  
+// \brief Application Destructor
+Application::~Application()
+{}
+
+void
+Application::DoDispose (void)
+{
+  m_node = 0;
+  Simulator::Cancel(m_startEvent);
+  Simulator::Cancel(m_stopEvent);
+}  
+   
+void Application::Start(const Time& startTime)
+{
+  ScheduleStart (startTime);
+}
+
+void Application::Start(const RandomVariable& startVar)
+{
+  RandomVariable *v = startVar.Copy ();
+  ScheduleStart (Seconds (v->GetValue ()));
+  delete v;
+}
+
+   
+void Application::Stop(const Time& stopTime)
+{
+  ScheduleStop (stopTime);
+}
+
+void Application::Stop(const RandomVariable& stopVar)
+{
+  RandomVariable *v = stopVar.Copy ();
+  ScheduleStop (Seconds (v->GetValue ()));
+  delete v;
+}
+  
+Ptr<Node> Application::GetNode() const
+{
+  return m_node;
+}
+
+// Protected methods
+// StartApp and StopApp will likely be overridden by application subclasses
+void Application::StartApplication()
+{ // Provide null functionality in case subclass is not interested
+}
+
+void Application::StopApplication()
+{ // Provide null functionality in case subclass is not interested
+}
+
+
+// Private helpers
+void Application::ScheduleStart (const Time &startTime)
+{
+  m_startEvent = Simulator::Schedule(startTime -
+                                     Simulator::Now(),
+                                     &Application::StartApplication, this);
+}
+
+void Application::ScheduleStop (const Time &stopTime)
+{
+  m_stopEvent = Simulator::Schedule(stopTime -
+                                    Simulator::Now(),
+                                    &Application::StopApplication, this);
+}
+
+} //namespace ns3
+      
+  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/application.h	Sun May 13 12:52:38 2007 +0100
@@ -0,0 +1,135 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 Georgia Tech Research Corporation
+ *
+ * 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: George F. Riley<riley@ece.gatech.edu>
+ */
+
+#ifndef __APPLICATION_H__
+#define __APPLICATION_H__
+
+#include "ns3/event-id.h"
+#include "ns3/nstime.h"
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+#include "ns3/node.h"
+
+namespace ns3 {
+
+class Node;
+class RandomVariable;
+
+/**
+ * \brief The base class for all ns3 applicationes
+ * 
+ * Class Application is the base class for all ns3 applications.
+ * Applications are associated with individual nodes.
+ * 
+ * Conceptually, an application has zero or more Socket
+ * objects associated with it, that are created using the Socket
+ * creation API of the Kernel capability.  The Socket object
+ * API is modeled after the
+ * well-known BSD sockets interface, although it is somewhat 
+ * simplified for use with ns3.  Further, any socket call that
+ * would normally "block" in normal sockets will return immediately
+ * in ns3.  A set of "upcalls" are defined that will be called when
+ * the previous blocking call would normally exit.  THis is documented
+ * in more detail Socket class in socket.h.
+ */
+class Application : public Object
+{
+public:
+  Application(Ptr<Node>);
+  virtual ~Application();
+  
+  /**
+   * \brief Specify application start time
+   * \param startTime Start time for this application, absolute time,
+   *        relative to the start of the simulation.
+   *
+   * Applications start at various times in the simulation scenario.
+   * The Start method specifies when the application should be
+   * started.  The application subclasses should override the
+   * private "StartApplication" method defined below, which is called at the
+   * time specified, to cause the application to begin.
+   */
+  void Start(const Time& startTime);
+
+  /** 
+   * \brief Specify application start time.
+   * \param startVariable the random variable to use to pick
+   *        the real start time as an absolute time, in units of
+   *        seconds, relative to the start of the simulation.
+   */
+  void Start(const RandomVariable& startVariable);
+  
+  /**
+   * \brief Specify application stop time
+   * \param stopTime Stop time for this application, relative to the
+   *        start of the simulation.
+   *
+   * Once an application has started, it is sometimes useful
+   * to stop the application.  The Stop method specifies when an
+   * application is to stop.  The application subclasses should override
+   * the private StopApplication method, to be notified when that
+   * time has come.
+   */
+  void Stop(const Time& stopTime);
+
+  /**
+   * \brief Specify application stop time
+   * \param stopVariable the random variable to use to pick
+   *        the real stop time, in units of seconds, 
+   *        relative to the start of the simulation.
+   */
+  void Stop(const RandomVariable& stopVariable);
+
+  /**
+   * \returns the Node to which this Application object is attached.
+   */
+  Ptr<Node> GetNode() const;
+  
+private:
+  /**
+   * \brief Application specific startup code
+   *
+   * The StartApplication method is called at the start time specifed by Start
+   * This method should be overridden by all or most application
+   * subclasses.
+   */
+  virtual void StartApplication (void);
+
+  /**
+   * \brief Application specific shutdown code
+   *
+   * The StopApplication method is called at the stop time specifed by Stop
+   * This method should be overridden by all or most application
+   * subclasses.
+   */
+  virtual void StopApplication (void);
+protected:
+  virtual void DoDispose (void);
+private:
+  void ScheduleStart (const Time &time);
+  void ScheduleStop (const Time &time);
+
+  EventId         m_startEvent;
+  EventId         m_stopEvent;
+  Ptr<Node>       m_node;
+};
+
+} //namespace ns3
+#endif
--- a/src/node/channel.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/channel.cc	Sun May 13 12:52:38 2007 +0100
@@ -27,14 +27,18 @@
 
 namespace ns3 {
 
+const InterfaceId Channel::iid ("Channel");
+
 Channel::Channel ()
-  : m_name("Channel")
+  : Interface (Channel::iid),
+    m_name("Channel")
 {
   NS_DEBUG("Channel::Channel ()");
 }
 
 Channel::Channel (std::string name)
-  : m_name(name)
+  : Interface (Channel::iid),
+    m_name(name)
 {
   NS_DEBUG("Channel::Channel (" << name << ")");
 }
--- a/src/node/channel.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/channel.h	Sun May 13 12:52:38 2007 +0100
@@ -24,7 +24,8 @@
 
 #include <string>
 #include <stdint.h>
-#include "ns3/object.h"
+#include "ns3/interface.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -36,9 +37,10 @@
  * A channel is a logical path over which information flows.  The path can
  * be as simple as a short piece of wire, or as complicated as space-time.
  */
-class Channel : public Object
+class Channel : public Interface
 {
 public:
+  static const InterfaceId iid;
   Channel ();
   Channel (std::string name);
 
@@ -57,7 +59,7 @@
    *
    * This method must be implemented by subclasses.
    */
-  virtual NetDevice *GetDevice (uint32_t i) const = 0;
+  virtual Ptr<NetDevice> GetDevice (uint32_t i) const = 0;
 
 protected:
   virtual ~Channel ();
--- a/src/node/drop-tail.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/drop-tail.cc	Sun May 13 12:52:38 2007 +0100
@@ -27,12 +27,13 @@
 static class QueueStackInitializationClass {
 public:
   QueueStackInitializationClass () {
-    Queue::Default (DropTailQueue ());
-    static DropTailQueue queue;
-    Queue::AddDefault (queue, "DropTailQueue");
+    Queue::AddDefault ("DropTailQueue");
   }
 } queue_stack_initialization_class;
 
+const ClassId DropTailQueue::cid = 
+  ComponentManager::RegisterConstructor<DropTailQueue> ("DropTailQueue");
+
 
 DropTailQueue::DropTailQueue () :
   Queue (),
@@ -47,11 +48,6 @@
   NS_DEBUG("DropTailQueue::~DropTailQueue ()");
 }
 
-DropTailQueue* DropTailQueue::Copy() const
-{
-  return new DropTailQueue(*this);
-}
-
 void 
 DropTailQueue::SetMaxPackets (uint32_t npackets)
 {
--- a/src/node/drop-tail.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/drop-tail.h	Sun May 13 12:52:38 2007 +0100
@@ -23,6 +23,7 @@
 #include <queue>
 #include "ns3/packet.h"
 #include "ns3/queue.h"
+#include "ns3/component-manager.h"
 
 namespace ns3 {
 
@@ -32,10 +33,10 @@
 
 class DropTailQueue : public Queue {
 public:
+  static const ClassId cid;
   DropTailQueue ();
 
   virtual ~DropTailQueue();
-  virtual DropTailQueue* Copy() const;
 
   void SetMaxPackets (uint32_t npackets);
   uint32_t GetMaxPackets (void);
--- a/src/node/i-ipv4.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/i-ipv4.cc	Sun May 13 12:52:38 2007 +0100
@@ -22,10 +22,10 @@
 
 namespace ns3 {
 
-const Iid IIpv4::iid ("IIpv4");
+const InterfaceId IIpv4::iid ("IIpv4");
 
 IIpv4::IIpv4 ()
-  : NsUnknown (IIpv4::iid)
+  : Interface (IIpv4::iid)
 {}
 
 IIpv4::~IIpv4 ()
--- a/src/node/i-ipv4.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/i-ipv4.h	Sun May 13 12:52:38 2007 +0100
@@ -23,7 +23,7 @@
 
 #include <stdint.h>
 #include "ns3/ipv4-address.h"
-#include "ns3/ns-unknown.h"
+#include "ns3/interface.h"
 
 namespace ns3 {
 
@@ -31,10 +31,10 @@
 class Packet;
 class Ipv4Route;
 
-class IIpv4 : public NsUnknown
+class IIpv4 : public Interface
 {
 public:
-  static const Iid iid;
+  static const InterfaceId iid;
   IIpv4 ();
   virtual ~IIpv4 ();
     
@@ -116,12 +116,18 @@
    * to disable it, you can invoke Ipv4Interface::SetDown which will
    * make sure that it is never used during packet forwarding.
    */
-  virtual uint32_t AddInterface (NetDevice *device) = 0;
+  virtual uint32_t AddInterface (Ptr<NetDevice> device) = 0;
   /**
    * \returns the number of interfaces added by the user.
    */
   virtual uint32_t GetNInterfaces (void) = 0;  
 
+  /**
+   * \param index of interface
+   * \returns address of the NetDevice associated with the ipv4 interface
+   */
+  virtual Ptr<NetDevice> GetNetDevice (uint32_t i) = 0;
+
   virtual void SetAddress (uint32_t i, Ipv4Address address) = 0;
   virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask) = 0;
   virtual Ipv4Mask GetNetworkMask (uint32_t t) const = 0;
--- a/src/node/i-udp.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/i-udp.cc	Sun May 13 12:52:38 2007 +0100
@@ -22,10 +22,10 @@
 
 namespace ns3 {
 
-const Iid IUdp::iid ("IUdp");
+const InterfaceId IUdp::iid ("IUdp");
 
 IUdp::IUdp ()
-  : NsUnknown (IUdp::iid)
+  : Interface (IUdp::iid)
 {}
 
 } // namespace ns3
--- a/src/node/i-udp.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/i-udp.h	Sun May 13 12:52:38 2007 +0100
@@ -21,20 +21,21 @@
 #ifndef I_UDP_H
 #define I_UDP_H
 
-#include "ns3/ns-unknown.h"
+#include "ns3/interface.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
 class Socket;
 
-class IUdp : public NsUnknown
+class IUdp : public Interface
 {
 public:
-  static const Iid iid;
+  static const InterfaceId iid;
 
   IUdp ();
 
-  virtual Socket *CreateSocket (void) = 0;
+  virtual Ptr<Socket> CreateSocket (void) = 0;
 };
 
 } // namespace ns3
--- a/src/node/mac-address.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/mac-address.h	Sun May 13 12:52:38 2007 +0100
@@ -19,10 +19,6 @@
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 
-/*
- * This implementation borrowed from yans
- */
-
 #ifndef MAC_ADDRESS_H
 #define MAC_ADDRESS_H
 
--- a/src/node/net-device.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/net-device.cc	Sun May 13 12:52:38 2007 +0100
@@ -21,15 +21,19 @@
 
 #include <iostream>
 #include "ns3/assert.h"
+#include "ns3/interface.h"
 
+#include "channel.h"
 #include "net-device.h"
 #include "llc-snap-header.h"
 #include "node.h"
-#include "ns3/channel.h"
 
 namespace ns3 {
 
-NetDevice::NetDevice(Node *node, const MacAddress& addr) : 
+const InterfaceId NetDevice::iid ("NetDevice");
+
+NetDevice::NetDevice(Ptr<Node> node, const MacAddress& addr) : 
+  Interface (NetDevice::iid),
   m_node (node), 
   m_name(""), 
   m_ifIndex (0), 
@@ -40,14 +44,11 @@
   m_isMulticast (false), 
   m_isPointToPoint (false)
 {
-  m_node->Ref ();
+  m_node->AddDevice (this);
 }
 
 NetDevice::~NetDevice ()
-{
-  m_node->Unref ();
-  m_node = 0;
-}
+{}
 
 MacAddress 
 NetDevice::GetAddress (void) const
@@ -188,7 +189,7 @@
   return DoCreateTraceResolver (context);
 }
 
-Channel *
+Ptr<Channel>
 NetDevice::GetChannel (void) const
 {
   return DoGetChannel ();
@@ -228,8 +229,8 @@
     }
 }
 
-Node *
-NetDevice::PeekNode (void) const
+Ptr<Node>
+NetDevice::GetNode (void) const
 {
   return m_node;
 }
@@ -241,13 +242,15 @@
 }
 
 void 
-NetDevice::SetReceiveCallback (Callback<bool,NetDevice *,const Packet &,uint16_t> cb)
+NetDevice::SetReceiveCallback (Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> cb)
 {
   m_receiveCallback = cb;
 }
 
 void
 NetDevice::DoDispose()
-{}
+{
+  m_node = 0;
+}
 
 }; // namespace ns3
--- a/src/node/net-device.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/net-device.h	Sun May 13 12:52:38 2007 +0100
@@ -25,7 +25,8 @@
 #include <stdint.h>
 #include "ns3/callback.h"
 #include "ns3/packet.h"
-#include "ns3/object.h"
+#include "ns3/interface.h"
+#include "ns3/ptr.h"
 #include "mac-address.h"
 
 namespace ns3 {
@@ -54,14 +55,10 @@
  * this base class and implement your own version of the
  * NetDevice::SendTo method.
  */
-class NetDevice : public Object 
+class NetDevice : public Interface
 {
 public:
-  /**
-   * \param node base class node pointer of device's node 
-   * \param addr MAC address of this device.
-   */
-  NetDevice(Node* node, const MacAddress& addr);
+  static const InterfaceId iid;
   virtual ~NetDevice();
 
   /**
@@ -78,7 +75,7 @@
    *         returned can be zero if the NetDevice is not yet connected
    *         to any channel.
    */
-  Channel *GetChannel (void) const;
+  Ptr<Channel> GetChannel (void) const;
 
   /**
    * \return the current MacAddress of this interface.
@@ -109,7 +106,7 @@
   /**
    * \param index ifIndex of the device 
    */
-  void SetIfIndex(const uint32_t);
+  void SetIfIndex(const uint32_t index);
   /**
    * \return index ifIndex of the device 
    */
@@ -169,14 +166,29 @@
    * base class to print the nodeid for example, it can invoke
    * this method.
    */
-  Node* PeekNode (void) const;
+  Ptr<Node> GetNode (void) const;
 
+  /**
+   * \returns true if ARP is needed, false otherwise.
+   *
+   * Called by higher-layers to check if this NetDevice requires
+   * ARP to be used.
+   */
   bool NeedsArp (void) const;
 
-  void SetReceiveCallback (Callback<bool,NetDevice *,const Packet &,uint16_t> cb);
+  /**
+   * \param cb callback to invoke whenever a packet has been received and must
+   *        be forwarded to the higher layers.
+   */
+  void SetReceiveCallback (Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> cb);
 
  protected:
   /**
+   * \param node base class node pointer of device's node 
+   * \param addr MAC address of this device.
+   */
+  NetDevice(Ptr<Node> node, const MacAddress& addr);
+  /**
    * Enable broadcast support. This method should be
    * called by subclasses from their constructor
    */
@@ -224,6 +236,12 @@
    */
   bool ForwardUp (Packet& p);
 
+  /**
+   * The dispose method for this NetDevice class.
+   * Subclasses are expected to override this method _and_
+   * to chain up to it by calling NetDevice::DoDispose
+   * at the end of their own DoDispose method.
+   */
   virtual void DoDispose (void);
 
  private:
@@ -238,10 +256,30 @@
    * subclasses to forward packets. Subclasses MUST override this method.
    */
   virtual bool SendTo (Packet& p, const MacAddress& dest) = 0;
+  /**
+   * \returns true if this NetDevice needs the higher-layers
+   *          to perform ARP over it, false otherwise.
+   *
+   * Subclasses must implement this method.
+   */
   virtual bool DoNeedsArp (void) const = 0;
+  /**
+   * \param context the trace context to associated to the
+   *        trace resolver.
+   * \returns a trace resolver associated to the input context.
+   *          the caller takes ownership of the pointer returned.
+   *
+   * Subclasses must implement this method.
+   */
   virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
-  virtual Channel *DoGetChannel (void) const = 0;
-  Node*         m_node;
+  /**
+   * \returns the channel associated to this NetDevice.
+   *
+   * Subclasses must implement this method.
+   */
+  virtual Ptr<Channel> DoGetChannel (void) const = 0;
+
+  Ptr<Node>         m_node;
   std::string   m_name;
   uint16_t      m_ifIndex;
   MacAddress    m_address;
@@ -252,7 +290,7 @@
   bool          m_isMulticast;
   bool          m_isPointToPoint;
   Callback<void> m_linkChangeCallback;
-  Callback<bool,NetDevice *,const Packet &,uint16_t> m_receiveCallback;
+  Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> m_receiveCallback;
 };
 
 }; // namespace ns3
--- a/src/node/node-list.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/node-list.cc	Sun May 13 12:52:38 2007 +0100
@@ -49,37 +49,37 @@
   NodeListPriv ();
   ~NodeListPriv ();
 
-  uint32_t Add (Node *node);
+  uint32_t Add (Ptr<Node> node);
   NodeList::Iterator Begin (void);
   NodeList::Iterator End (void);
   TraceResolver *CreateTraceResolver (TraceContext const &context);
   Node *PeekNode (uint32_t n);
+  Ptr<Node> GetNode (uint32_t n);
   uint32_t GetNNodes (void);
 
 private:
-  std::vector<Node *> m_nodes;
+  std::vector<Ptr<Node> > m_nodes;
 };
 
 NodeListPriv::NodeListPriv ()
 {}
 NodeListPriv::~NodeListPriv ()
 {
-  for (std::vector<Node *>::iterator i = m_nodes.begin ();
+  for (std::vector<Ptr<Node> >::iterator i = m_nodes.begin ();
        i != m_nodes.end (); i++)
     {
-      Node *node = *i;
+      Ptr<Node> node = *i;
       node->Dispose ();
-      node->Unref ();
+      *i = 0;
     }
   m_nodes.erase (m_nodes.begin (), m_nodes.end ());
 }
 
 
 uint32_t
-NodeListPriv::Add (Node *node)
+NodeListPriv::Add (Ptr<Node> node)
 {
   uint32_t index = m_nodes.size ();
-  node->Ref ();
   m_nodes.push_back (node);
   return index;
   
@@ -102,9 +102,16 @@
 Node *
 NodeListPriv::PeekNode (uint32_t n)
 {
+  return PeekPointer (m_nodes[n]);
+}
+
+Ptr<Node>
+NodeListPriv::GetNode (uint32_t n)
+{
   return m_nodes[n];
 }
 
+
 TraceResolver *
 NodeListPriv::CreateTraceResolver (TraceContext const &context)
 {
@@ -126,7 +133,7 @@
 namespace ns3 {
 
 uint32_t
-NodeList::Add (Node *node)
+NodeList::Add (Ptr<Node> node)
 {
   return SimulationSingleton<NodeListPriv>::Get ()->Add (node);
 }
@@ -145,10 +152,10 @@
 {
   return SimulationSingleton<NodeListPriv>::Get ()->CreateTraceResolver (context);
 }
-Node *
-NodeList::PeekNode (uint32_t n)
+Ptr<Node>
+NodeList::GetNode (uint32_t n)
 {
-  return SimulationSingleton<NodeListPriv>::Get ()->PeekNode (n);
+  return SimulationSingleton<NodeListPriv>::Get ()->GetNode (n);
 }
 
 
--- a/src/node/node-list.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/node-list.h	Sun May 13 12:52:38 2007 +0100
@@ -24,6 +24,7 @@
 
 #include <vector>
 #include "ns3/array-trace-resolver.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -31,18 +32,48 @@
 class TraceResolver;
 class TraceContext;
 
+/**
+ * \brief the list of simulation nodes.
+ *
+ * Every Node created is automatically added to this list.
+ */
 class NodeList
 {
 public:
   typedef ArrayTraceResolver<Node>::Index NodeIndex;
-  typedef std::vector<Node *>::iterator Iterator;
+  typedef std::vector< Ptr<Node> >::iterator Iterator;
 
-  static uint32_t Add (Node *node);
+  /**
+   * \param node node to add
+   * \returns index of node in list.
+   *
+   * This method is called automatically from Node::Node so
+   * the user has little reason to call it himself.
+   */
+  static uint32_t Add (Ptr<Node> node);
+  /**
+   * \returns a C++ iterator located at the beginning of this
+   *          list.
+   */
   static Iterator Begin (void);
+  /**
+   * \returns a C++ iterator located at the end of this
+   *          list.
+   */
   static Iterator End (void);
+  /**
+   * \param context trace context to use for trace resolver
+   *        to create.
+   * \returns the requested trace resolver. The caller
+   *          takes ownership of the returned pointer.
+   */
   static TraceResolver *CreateTraceResolver (TraceContext const &context);
 
-  static Node *PeekNode (uint32_t n);
+  /**
+   * \param n index of requested node.
+   * \returns the Node associated to index n.
+   */
+  static Ptr<Node> GetNode (uint32_t n);
 };
 
 }//namespace ns3
--- a/src/node/node.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/node.cc	Sun May 13 12:52:38 2007 +0100
@@ -25,14 +25,15 @@
 #include "node.h"
 #include "node-list.h"
 #include "net-device.h"
+#include "application.h"
 #include "ns3/simulator.h"
 
 namespace ns3{
 
-const Iid Node::iid ("Node");
+const InterfaceId Node::iid ("Node");
 
 Node::Node()
-  : NsUnknown (Node::iid),
+  : Interface (Node::iid),
     m_id(0), 
     m_sid(0)
 {
@@ -40,7 +41,7 @@
 }
 
 Node::Node(uint32_t sid)
-  : NsUnknown (Node::iid),
+  : Interface (Node::iid),
     m_id(0), 
     m_sid(sid)
 { 
@@ -50,6 +51,12 @@
 Node::~Node ()
 {}
 
+TraceResolver *
+Node::CreateTraceResolver (TraceContext const &context)
+{
+  return DoCreateTraceResolver (context);
+}
+
 uint32_t 
 Node::GetId (void) const
 {
@@ -62,23 +69,16 @@
   return m_sid;
 }
 
-void   
-Node::SetSystemId(uint32_t s )
+uint32_t 
+Node::AddDevice (Ptr<NetDevice> device)
 {
-  m_sid = s;
-}
-
-uint32_t 
-Node::AddDevice (NetDevice *device)
-{
-  device->Ref ();
   uint32_t index = m_devices.size ();
   m_devices.push_back (device);
   DoAddDevice (device);
   device->SetIfIndex(index);
   return index;
 }
-NetDevice *
+Ptr<NetDevice>
 Node::GetDevice (uint32_t index) const
 {
   return m_devices[index];
@@ -89,17 +89,44 @@
   return m_devices.size ();
 }
 
+uint32_t 
+Node::AddApplication (Ptr<Application> application)
+{
+  uint32_t index = m_applications.size ();
+  m_applications.push_back (application);
+  return index;
+}
+Ptr<Application> 
+Node::GetApplication (uint32_t index) const
+{
+  return m_applications[index];
+}
+uint32_t 
+Node::GetNApplications (void) const
+{
+  return m_applications.size ();
+}
+
+
 void Node::DoDispose()
 {
-  for (std::vector<NetDevice *>::iterator i = m_devices.begin ();
+  for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
        i != m_devices.end (); i++)
     {
-      NetDevice *device = *i;
+      Ptr<NetDevice> device = *i;
       device->Dispose ();
-      device->Unref ();
+      *i = 0;
     }
   m_devices.clear ();
-  NsUnknown::DoDispose ();
+  for (std::vector<Ptr<Application> >::iterator i = m_applications.begin ();
+       i != m_applications.end (); i++)
+    {
+      Ptr<Application> application = *i;
+      application->Dispose ();
+      *i = 0;
+    }
+  m_applications.clear ();
+  Interface::DoDispose ();
 }
 
 }//namespace ns3
--- a/src/node/node.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/node.h	Sun May 13 12:52:38 2007 +0100
@@ -27,41 +27,145 @@
 
 #include <vector>
 
-#include "ns3/ns-unknown.h"
+#include "ns3/interface.h"
 
 namespace ns3 {
 
 class TraceContext;
 class TraceResolver;
 class NetDevice;
+class Application;
 
-class Node : public NsUnknown
+/**
+ * \brief A network Node.
+ *
+ * This class holds together:
+ *   - a list of NetDevice objects which represent the network interfaces
+ *     of this node which are connected to other Node instances through
+ *     Channel instances.
+ *   - a list of Application objects which represent the userspace
+ *     traffic generation applications which interact with the Node
+ *     through the Socket API.
+ *   - a node Id: a unique per-node identifier.
+ *   - a system Id: a unique Id used for parallel simulations.
+ *   - a trace resolver which can be used to connect user trace sinks
+ *     to the node's trace sources.
+ *
+ * Every Node created is added to the NodeList automatically.
+ */
+class Node : public Interface
 {
 public:
-  static const Iid iid;
+  static const InterfaceId iid;
 
-  Node();
-  Node(uint32_t); // Specify which system for a distributed simulation
   virtual ~Node();
 
-  virtual TraceResolver *CreateTraceResolver (TraceContext const &context) = 0;
+  /**
+   * \param context the trace context for the TraceResolver to create
+   * \returns a newly-created TraceResolver. The caller takes
+   *          ownership of the returned pointer.
+   *
+   * Request the Node to create a trace resolver. This method
+   * could be used directly by a user who needs access to very low-level
+   * trace configuration.
+   */
+  TraceResolver *CreateTraceResolver (TraceContext const &context);
 
+  /**
+   * \returns the unique id of this node.
+   * 
+   * This unique id happens to be also the index of the Node into
+   * the NodeList. 
+   */
   uint32_t GetId (void) const;
+
+  /**
+   * \returns the system id for parallel simulations associated
+   *          to this node.
+   */
   uint32_t GetSystemId (void) const;
-  void SetSystemId(uint32_t s);
 
-  uint32_t AddDevice (NetDevice *device);
-  NetDevice *GetDevice (uint32_t index) const;
+  /**
+   * \param device NetDevice to associate to this node.
+   * \returns the index of the NetDevice into the Node's list of
+   *          NetDevice.
+   *
+   * Associate this device to this node.
+   * This method is called automatically from NetDevice::NetDevice
+   * so the user has little reason to call this method himself.
+   */
+  uint32_t AddDevice (Ptr<NetDevice> device);
+  /**
+   * \param index the index of the requested NetDevice
+   * \returns the requested NetDevice associated to this Node.
+   */
+  Ptr<NetDevice> GetDevice (uint32_t index) const;
+  /**
+   * \returns the number of NetDevice instances associated
+   *          to this Node.
+   */
   uint32_t GetNDevices (void) const;
 
+  /**
+   * \param application Application to associate to this node.
+   * \returns the index of the Application within the Node's list
+   *          of Application.
+   *
+   * Associated this Application to this Node. This method is called
+   * automatically from Application::Application so the user
+   * has little reasons to call this method directly.
+   */
+  uint32_t AddApplication (Ptr<Application> application);
+  /**
+   * \param index
+   * \returns the application associated to this requested index
+   *          within this Node.
+   */
+  Ptr<Application> GetApplication (uint32_t index) const;
+  /**
+   * \returns the number of applications associated to this Node.
+   */
+  uint32_t GetNApplications (void) const;
+
 protected:
+  /**
+   * Must be invoked by subclasses only.
+   */
+  Node();
+  /**
+   * \param systemId a unique integer used for parallel simulations.
+   *
+   * Must be invoked by subclasses only.
+   */
+  Node(uint32_t systemId);
+  /**
+   * The dispose method. Subclasses must override this method
+   * and must chain up to it by calling Node::DoDispose at the
+   * end of their own DoDispose method.
+   */
   virtual void DoDispose (void);
 private:
-  virtual void DoAddDevice (NetDevice *device) const = 0;
+  /**
+   * \param context the trace context
+   * \returns a trace resolver to the user. The user must delete it.
+   *
+   * Subclasses must implement this method.
+   */
+  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
+  /**
+   * \param device the device added to this Node.
+   *
+   * This method is invoked whenever a user calls Node::AddDevice.
+   * Subclasses are expected to call NetDevice::SetReceiveCallback
+   * at this point to setup the node's receive function for
+   * the NetDevice packets.
+   */
+  virtual void DoAddDevice (Ptr<NetDevice> device) const = 0;
 
   uint32_t    m_id;         // Node id for this node
   uint32_t    m_sid;        // System id for this node
-  std::vector<NetDevice *> m_devices;
+  std::vector<Ptr<NetDevice> > m_devices;
+  std::vector<Ptr<Application> > m_applications;
 };
 
 } //namespace ns3
--- a/src/node/queue.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/queue.cc	Sun May 13 12:52:38 2007 +0100
@@ -19,16 +19,18 @@
 
 #include "ns3/debug.h"
 #include "ns3/composite-trace-resolver.h"
+#include "ns3/default-value.h"
+#include "ns3/component-manager.h"
 #include "queue.h"
-#include "ns3/default-value.h"
 
 NS_DEBUG_COMPONENT_DEFINE ("Queue");
 
 namespace ns3 {
 
-Queue* Queue::defaultQueue = 0;
+const InterfaceId Queue::iid ("Queue");
 
 Queue::Queue() : 
+  Interface (Queue::iid),
   m_nBytes(0), 
   m_nTotalReceivedBytes(0),
   m_nPackets(0), 
@@ -194,50 +196,23 @@
   m_traceDrop (p);
 }
 
-// Static methods for managing default queue
-
-// Set new default
-void Queue::Default(const Queue& q)
-{
-  delete defaultQueue;      // delete previous (if any)
-  defaultQueue = q.Copy();  // set new default
-}
-
-// Get current default
-Queue& Queue::Default()
-{
-  // ! Need to schedule an "at end" event to delete the default
-  return *defaultQueue;
-}
-
-
-Queue *
+Ptr<Queue>
 Queue::CreateDefault (void)
 {
   std::string defaultValue = GetDefault ()->GetValue ();
-  for (List::iterator i = GetList ()->begin ();
-       i != GetList ()->end (); i++)
-    {
-      if (i->second == defaultValue)
-        {
-          return i->first->Copy ();
-        }
-    }
-  NS_ASSERT (false);
-  // quiet compiler
-  return 0;
+  ClassId classId = ComponentManager::LookupByName (defaultValue);
+  Ptr<Queue> queue = ComponentManager::Create<Queue> (classId, Queue::iid);
+  return queue;
 }
 void 
-Queue::Add (Queue &queue, const std::string &name)
+Queue::Add (const std::string &name)
 {
   GetDefault ()->AddPossibleValue (name);
-  GetList ()->push_back (std::make_pair (&queue, name));
 }
 void 
-Queue::AddDefault (Queue &queue, const std::string &name)
+Queue::AddDefault (const std::string &name)
 {
   GetDefault ()->AddDefaultValue (name);
-  GetList ()->push_back (std::make_pair (&queue, name));
 }
 StringEnumDefaultValue *
 Queue::GetDefault (void)
@@ -245,12 +220,6 @@
   static StringEnumDefaultValue value ("Queue", "Packet Queue");
   return &value;
 }
-Queue::List *
-Queue::GetList (void)
-{
-  static List list;
-  return &list;
-}
 
 
 }; // namespace ns3
--- a/src/node/queue.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/queue.h	Sun May 13 12:52:38 2007 +0100
@@ -28,6 +28,7 @@
 #include <string>
 #include <list>
 #include "ns3/packet.h"
+#include "ns3/interface.h"
 #include "ns3/callback-trace-source.h"
 #include "ns3/trace-resolver.h"
 
@@ -35,9 +36,11 @@
 
 class StringEnumDefaultValue;
 
-class Queue
+class Queue : public Interface
 {
 public:
+  static const InterfaceId iid;
+
   enum TraceType {
     ENQUEUE,
     DEQUEUE,
@@ -46,8 +49,6 @@
   Queue ();
   virtual ~Queue ();
 
-  virtual Queue* Copy() const = 0;
-
   TraceResolver *CreateTraceResolver (TraceContext const &context);
 
   bool IsEmpty (void);
@@ -112,22 +113,13 @@
   uint32_t m_nTotalDroppedPackets;
 
 public:
-  static Queue *CreateDefault (void);
-  static void Add (Queue &queue, const std::string &name);
-  static void AddDefault (Queue &queue, const std::string &name);
+  static Ptr<Queue> CreateDefault (void);
+  static void Add (const std::string &name);
+  static void AddDefault (const std::string &name);
 private:
   typedef std::list<std::pair<Queue *,std::string> > List;
   static StringEnumDefaultValue *GetDefault (void);
   static List *GetList (void);
-
-public:
-  // Static methods to manage queue default
-  // Set desired queue default
-  static void    Default(const Queue& q);
-  // Return reference to the current default queue type
-  static Queue&  Default();
-  // Static variable pointing to current default queue
-  static Queue* defaultQueue;
 };
 
 }; // namespace ns3
--- a/src/node/socket.cc	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/socket.cc	Sun May 13 12:52:38 2007 +0100
@@ -6,7 +6,7 @@
 {}
 
 void 
-Socket::Close(Callback<void, Socket*> closeCompleted)
+Socket::Close(Callback<void, Ptr<Socket> > closeCompleted)
 {
   DoClose (closeCompleted);
 }
@@ -14,23 +14,23 @@
 void 
 Socket::Connect(const Ipv4Address & address,
                uint16_t portNumber,
-               Callback<void, Socket*> connectionSucceeded,
-               Callback<void, Socket*> connectionFailed,
-               Callback<void, Socket*> halfClose)
+               Callback<void, Ptr<Socket> > connectionSucceeded,
+               Callback<void, Ptr<Socket> > connectionFailed,
+               Callback<void, Ptr<Socket> > halfClose)
 {
   DoConnect (address, portNumber, connectionSucceeded, connectionFailed, halfClose);
 }
 int
-Socket::Accept(Callback<bool, Socket*, const Ipv4Address&, uint16_t> connectionRequest,
-	       Callback<void, Socket*, const Ipv4Address&, uint16_t> newConnectionCreated,
-	       Callback<void, Socket*> closeRequested)
+Socket::Accept(Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest,
+	       Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated,
+	       Callback<void, Ptr<Socket> > closeRequested)
 {
   return DoAccept (connectionRequest, newConnectionCreated, closeRequested);
 }
 int 
 Socket::Send (const uint8_t* buffer,
 	      uint32_t size,
-	      Callback<void, Socket*, uint32_t> dataSent)
+	      Callback<void, Ptr<Socket>, uint32_t> dataSent)
 {
   return DoSend (buffer, size, dataSent);
 }
@@ -39,42 +39,42 @@
 	       uint16_t port,
 	       const uint8_t *buffer,
 	       uint32_t size,
-	       Callback<void, Socket*, uint32_t> dataSent)
+	       Callback<void, Ptr<Socket>, uint32_t> dataSent)
 {
   return DoSendTo (address, port, buffer, size, dataSent);
 }
 void 
-Socket::Recv(Callback<void, Socket*, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback)
+Socket::Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback)
 {
   DoRecv (callback);
 }
 void 
-Socket::RecvDummy(Callback<void, Socket*, uint32_t,const Ipv4Address&, uint16_t> callback)
+Socket::RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t> callback)
 {
   DoRecvDummy (callback);
 }
 
 
 bool 
-Socket::RefuseAllConnections (Socket* socket, const Ipv4Address& address, uint16_t port)
+Socket::RefuseAllConnections (Ptr<Socket> socket, const Ipv4Address& address, uint16_t port)
 {
   return false;
 }
 void 
-Socket::DummyCallbackVoidSocket (Socket *socket)
+Socket::DummyCallbackVoidSocket (Ptr<Socket> socket)
 {}
 void
-Socket::DummyCallbackVoidSocketUi32 (Socket *socket, uint32_t)
+Socket::DummyCallbackVoidSocketUi32 (Ptr<Socket> socket, uint32_t)
 {}
 void 
-Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Socket *socket, uint32_t, const Ipv4Address &, uint16_t)
+Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Ptr<Socket> socket, uint32_t, const Ipv4Address &, uint16_t)
 {}
 void 
-Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Socket *socket, const uint8_t *, uint32_t,
+Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Ptr<Socket> socket, const uint8_t *, uint32_t,
 							  const Ipv4Address &, uint16_t)
 {}
 void 
-Socket::DummyCallbackVoidSocketIpv4AddressUi16 (Socket *socket, const Ipv4Address &, uint16_t)
+Socket::DummyCallbackVoidSocketIpv4AddressUi16 (Ptr<Socket> socket, const Ipv4Address &, uint16_t)
 {}
 
 
--- a/src/node/socket.h	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/socket.h	Sun May 13 12:52:38 2007 +0100
@@ -22,6 +22,7 @@
 #define __SOCKET_H__
 
 #include "ns3/callback.h"
+#include "ns3/ptr.h"
 #include "ipv4-address.h"
 #include "ns3/object.h"
 #include <stdint.h>
@@ -65,7 +66,7 @@
   /**
    * \returns the node this socket is associated with.
    */
-  virtual Node *PeekNode (void) const = 0;
+  virtual Ptr<Node> GetNode (void) const = 0;
 
   /** 
    * Allocate a free port number and
@@ -113,7 +114,7 @@
    * After the Close call, the socket is no longer valid, and cannot
    * safely be used for subsequent operations.
    */
-  void Close(Callback<void, Socket*> closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket));
+  void Close(Callback<void, Ptr<Socket> > closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket));
 
   /**
    * \returns zero on success, -1 on failure.
@@ -146,9 +147,9 @@
    */
   void Connect(const Ipv4Address & address,
                uint16_t portNumber,
-               Callback<void, Socket*> connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket),
-               Callback<void, Socket*> connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket),
-               Callback<void, Socket*> halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket));
+               Callback<void, Ptr<Socket> > connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket),
+               Callback<void, Ptr<Socket> > connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket),
+               Callback<void, Ptr<Socket> > halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket));
     
   /**
    * \brief Accept connection requests from remote hosts
@@ -169,11 +170,11 @@
    * \param closeRequested Callback for connection close request from peer.
    *        XXX: when is this callback invoked ?
    */
-  int Accept(Callback<bool, Socket*, const Ipv4Address&, uint16_t> connectionRequest = 
+  int Accept(Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest = 
              MakeCallback(&Socket::RefuseAllConnections),
-             Callback<void, Socket*, const Ipv4Address&, uint16_t> newConnectionCreated = 
+             Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated = 
              MakeCallback (&Socket::DummyCallbackVoidSocketIpv4AddressUi16),
-             Callback<void, Socket*> closeRequested = MakeCallback (&Socket::DummyCallbackVoidSocket));
+             Callback<void, Ptr<Socket> > closeRequested = MakeCallback (&Socket::DummyCallbackVoidSocket));
 
   /**
    * \brief Send data (or dummy data) to the remote host
@@ -185,7 +186,7 @@
    */
   int Send (const uint8_t* buffer,
             uint32_t size,
-            Callback<void, Socket*, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
+            Callback<void, Ptr<Socket>, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
   
   /**
    * \brief Send data to a specified peer.
@@ -201,59 +202,59 @@
              uint16_t port,
              const uint8_t *buffer,
              uint32_t size,
-             Callback<void, Socket*, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
+             Callback<void, Ptr<Socket>, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
   
   /**
    * \brief Receive data
-   * \param Received data callback. Invoked whenever new data is received.
+   * \param receivedData Invoked whenever new data is received.
    *
    * If you wish to transport only dummy packets, this method is not a very
    * efficient way to receive these dummy packets: it will trigger a memory
    * allocation to hold the dummy memory into a buffer which can be passed
    * to the user. Instead, consider using the RecvDummy method.
    */
-  void Recv(Callback<void, Socket*, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> = 
+  void Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> receivedData = 
             MakeCallback (&Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16));
   
   /**
    * \brief Receive data
-   * \param Received data callback. Invoked whenever new data is received.
+   * \param receivedData Invoked whenever new data is received.
    *
    * This method is included because it is vastly more efficient than the 
    * Recv method when you use dummy payload.
    */
-  void RecvDummy(Callback<void, Socket*, uint32_t,const Ipv4Address&, uint16_t> = 
+  void RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t> receivedData =
                  MakeCallback (&Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16));
 
 private:
-  virtual void DoClose(Callback<void, Socket*> closeCompleted) = 0;
+  virtual void DoClose(Callback<void, Ptr<Socket> > closeCompleted) = 0;
   virtual void DoConnect(const Ipv4Address & address,
                          uint16_t portNumber,
-                         Callback<void, Socket*> connectionSucceeded,
-                         Callback<void, Socket*> connectionFailed,
-                         Callback<void, Socket*> halfClose) = 0;
-  virtual int DoAccept(Callback<bool, Socket*, const Ipv4Address&, uint16_t> connectionRequest,
-                       Callback<void, Socket*, const Ipv4Address&, uint16_t> newConnectionCreated,
-                       Callback<void, Socket*> closeRequested) = 0;
+                         Callback<void, Ptr<Socket> > connectionSucceeded,
+                         Callback<void, Ptr<Socket> > connectionFailed,
+                         Callback<void, Ptr<Socket> > halfClose) = 0;
+  virtual int DoAccept(Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest,
+                       Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated,
+                       Callback<void, Ptr<Socket> > closeRequested) = 0;
   virtual int DoSend (const uint8_t* buffer,
                     uint32_t size,
-                    Callback<void, Socket*, uint32_t> dataSent) = 0;
+                    Callback<void, Ptr<Socket>, uint32_t> dataSent) = 0;
   virtual int DoSendTo(const Ipv4Address &address,
                        uint16_t port,
                        const uint8_t *buffer,
                        uint32_t size,
-                       Callback<void, Socket*, uint32_t> dataSent) = 0;
-  virtual void DoRecv(Callback<void, Socket*, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> receive) = 0;
-  virtual void DoRecvDummy(Callback<void, Socket*, uint32_t,const Ipv4Address&, uint16_t>) = 0;
+                       Callback<void, Ptr<Socket>, uint32_t> dataSent) = 0;
+  virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> receive) = 0;
+  virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t>) = 0;
 
 
-  static bool RefuseAllConnections (Socket* socket, const Ipv4Address& address, uint16_t port);
-  static void DummyCallbackVoidSocket (Socket *socket);
-  static void DummyCallbackVoidSocketUi32 (Socket *socket, uint32_t);
-  static void DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Socket *socket, uint32_t, const Ipv4Address &, uint16_t);
-  static void DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Socket *socket, const uint8_t *, uint32_t, 
+  static bool RefuseAllConnections (Ptr<Socket> socket, const Ipv4Address& address, uint16_t port);
+  static void DummyCallbackVoidSocket (Ptr<Socket> socket);
+  static void DummyCallbackVoidSocketUi32 (Ptr<Socket> socket, uint32_t);
+  static void DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Ptr<Socket> socket, uint32_t, const Ipv4Address &, uint16_t);
+  static void DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Ptr<Socket> socket, const uint8_t *, uint32_t, 
                                                                 const Ipv4Address &, uint16_t);
-  static void DummyCallbackVoidSocketIpv4AddressUi16 (Socket *socket, const Ipv4Address &, uint16_t);
+  static void DummyCallbackVoidSocketIpv4AddressUi16 (Ptr<Socket> socket, const Ipv4Address &, uint16_t);
 };
 
 } //namespace ns3
--- a/src/node/wscript	Sun May 13 12:46:18 2007 +0100
+++ b/src/node/wscript	Sun May 13 12:52:38 2007 +0100
@@ -20,6 +20,7 @@
         'socket.cc',
         'i-udp.cc',
         'i-ipv4.cc',
+        'application.cc',
         ]
 
     headers = bld.create_obj('ns3header')
@@ -37,4 +38,5 @@
         'socket.h',
         'i-udp.h',
         'i-ipv4.h',
+        'application.h',
         ]