use Ptr<> everywhere Object or NsUnknown are used
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Thu, 10 May 2007 20:19:26 +0200
changeset 568 e1660959ecbb
parent 567 6fb98941c36f
child 569 31a7c6fc511e
use Ptr<> everywhere Object or NsUnknown are used
examples/simple-p2p.cc
samples/main-simple.cc
src/applications/onoff-application.cc
src/applications/onoff-application.h
src/core/ns-unknown-manager.cc
src/core/ns-unknown-manager.h
src/core/ns-unknown.cc
src/core/ns-unknown.h
src/devices/p2p/p2p-channel.cc
src/devices/p2p/p2p-channel.h
src/devices/p2p/p2p-net-device.cc
src/devices/p2p/p2p-net-device.h
src/devices/p2p/p2p-topology.cc
src/devices/p2p/p2p-topology.h
src/internet-node/arp-cache.cc
src/internet-node/arp-cache.h
src/internet-node/arp-ipv4-interface.cc
src/internet-node/arp-ipv4-interface.h
src/internet-node/arp.cc
src/internet-node/arp.h
src/internet-node/i-arp-private.cc
src/internet-node/i-arp-private.h
src/internet-node/i-ipv4-impl.cc
src/internet-node/i-ipv4-impl.h
src/internet-node/i-ipv4-private.cc
src/internet-node/i-ipv4-private.h
src/internet-node/i-udp-impl.cc
src/internet-node/i-udp-impl.h
src/internet-node/internet-node.cc
src/internet-node/internet-node.h
src/internet-node/ipv4-interface.cc
src/internet-node/ipv4-interface.h
src/internet-node/ipv4-l4-demux.cc
src/internet-node/ipv4-l4-demux.h
src/internet-node/ipv4-loopback-interface.cc
src/internet-node/ipv4.cc
src/internet-node/ipv4.h
src/internet-node/l3-demux.cc
src/internet-node/l3-demux.h
src/internet-node/l3-protocol.h
src/internet-node/udp-socket.cc
src/internet-node/udp-socket.h
src/internet-node/udp.cc
src/internet-node/udp.h
src/node/channel.h
src/node/i-ipv4.h
src/node/i-udp.h
src/node/net-device.cc
src/node/net-device.h
src/node/node.cc
src/node/node.h
src/node/socket.cc
src/node/socket.h
--- a/examples/simple-p2p.cc	Thu May 10 18:33:52 2007 +0200
+++ b/examples/simple-p2p.cc	Thu May 10 20:19:26 2007 +0200
@@ -107,15 +107,15 @@
   Ptr<Node> n3 = new 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));
   
@@ -123,17 +123,14 @@
   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 ();
 
   // Create the OnOff application to send UDP datagrams of size
   // 210 bytes at a rate of 448 Kb/s
@@ -146,10 +143,8 @@
     DataRate(448000), 
     210);
   // Add to Node's ApplicationList (takes ownership of pointer)
-  ApplicationList *apl0 = n0->QueryInterface<ApplicationList> 
-    (ApplicationList::iid);
+  Ptr<ApplicationList> apl0 = n0->QueryInterface<ApplicationList> (ApplicationList::iid);
   apl0->Add(ooff0);
-  apl0->Unref ();
 
   // Start the application
   ooff0->Start(Seconds(1.0));
@@ -165,22 +160,19 @@
     DataRate(448000), 
     210);
   // Add to Node's ApplicationList (takes ownership of pointer)
-  ApplicationList *apl3 = n3->QueryInterface<ApplicationList> (ApplicationList::iid);
+  Ptr<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));
 
   // 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 = 0;
   n1 = 0;
--- a/samples/main-simple.cc	Thu May 10 18:33:52 2007 +0200
+++ b/samples/main-simple.cc	Thu May 10 20:19:26 2007 +0200
@@ -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,13 +24,13 @@
 }
 
 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));
 }
@@ -40,17 +40,14 @@
 {
   Ptr<InternetNode> a = new 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);
 
@@ -58,11 +55,6 @@
   Simulator::Run ();
 
   Simulator::Destroy ();
-
-  sink->Unref ();
-  source->Unref ();
-
-  std::cout << "o" << std::endl;
 }
 
 int main (int argc, char *argv[])
--- a/src/applications/onoff-application.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/applications/onoff-application.cc	Thu May 10 20:19:26 2007 +0200
@@ -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 = GetNode ()->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
@@ -263,13 +258,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	Thu May 10 18:33:52 2007 +0200
+++ b/src/applications/onoff-application.h	Thu May 10 20:19:26 2007 +0200
@@ -71,7 +71,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
@@ -97,9 +97,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/core/ns-unknown-manager.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/core/ns-unknown-manager.cc	Thu May 10 20:19:26 2007 +0200
@@ -49,10 +49,10 @@
   return a.m_classId == b.m_classId;
 }
 
-NsUnknown *
+Ptr<NsUnknown>
 NsUnknownManager::Create (ClassId classId)
 {
-  Callback<NsUnknown *> callback = DoGetCallback<empty,empty,empty,empty,empty> (classId);
+  Callback<Ptr<NsUnknown> > callback = DoGetCallback<empty,empty,empty,empty,empty> (classId);
   return callback ();
 }
 
@@ -141,9 +141,8 @@
     m_oneBoolInvoked (false),
     m_oneUi32Invoked (false)
 {
-  B *b = new B ();
+  ns3::Ptr<B> b = new B ();
   AddInterface (b);
-  b->Unref ();
 }
 
 A::A (bool bo)
@@ -153,9 +152,8 @@
     m_oneUi32Invoked (false),
     m_bool (bo)
 {
-  B *b = new B ();
+  ns3::Ptr<B> b = new B ();
   AddInterface (b);
-  b->Unref ();
 }
 
 A::A (uint32_t i)
@@ -165,9 +163,8 @@
     m_oneUi32Invoked (true),
     m_ui32 (i)
 {
-  B *b = new B ();
+  ns3::Ptr<B> b = new B ();
   AddInterface (b);
-  b->Unref ();
 }
 
 }
@@ -189,14 +186,13 @@
 {
   bool ok = true;
 
-  A *a = 0;
+  Ptr<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 ||
@@ -205,7 +201,6 @@
     {
       ok = false;
     }
-  a->Unref ();
 
   a = NsUnknownManager::Create<A,bool> (A::cidOneBool, A::iid, false);
   if (a == 0 ||
@@ -214,7 +209,6 @@
     {
       ok = false;
     }
-  a->Unref ();
 
   a = NsUnknownManager::Create<A,uint32_t> (A::cidOneUi32, A::iid, 10);
   if (a == 0 ||
@@ -223,7 +217,6 @@
     {
       ok = false;
     }
-  a->Unref ();
 
   a = NsUnknownManager::Create<A> (A::cidOneUi32, A::iid, (uint32_t)10);
   if (a == 0 ||
@@ -232,14 +225,12 @@
     {
       ok = false;
     }
-  a->Unref ();
 
-  B *b = NsUnknownManager::Create<B,uint32_t> (A::cidOneUi32, B::iid, 10);
+  Ptr<B> b = NsUnknownManager::Create<B,uint32_t> (A::cidOneUi32, B::iid, 10);
   if (b == 0)
     {
       ok = false;
     }
-  b->Unref ();
 
   return ok;
 }
--- a/src/core/ns-unknown-manager.h	Thu May 10 18:33:52 2007 +0200
+++ b/src/core/ns-unknown-manager.h	Thu May 10 20:19:26 2007 +0200
@@ -27,6 +27,7 @@
 #include "callback.h"
 #include "ns-unknown.h"
 #include "fatal-error.h"
+#include "ptr.h"
 
 namespace ns3 {
 
@@ -82,51 +83,51 @@
    * Create an instance of the object identified by its
    * ClassId. This method invokes the default constructor.
    */
-  static NsUnknown *Create (ClassId classId);
+  static Ptr<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)
+   * \overload Create (ClassId)
    *
    * Create an instance of the object identified by its
    * ClassId.
    */
   template <typename T1>
-  static NsUnknown *Create (ClassId classId, T1 a1);
+  static Ptr<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)
+   * \overload 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);
+  static Ptr<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)
+   * \overload 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);
+  static Ptr<T> Create (ClassId classId, Iid iid);
 
   template <typename T, typename T1>
-  static T *Create (ClassId classId, Iid iid, T1 a1);
+  static Ptr<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);
+  static Ptr<T> Create (ClassId classId, Iid iid, T1 a1, T2 a2);
 
   /**
    * \param name the symbolic name to associate to this
@@ -136,7 +137,7 @@
   template <typename T>
   static ClassId RegisterConstructor (std::string name)
   {
-    static Callback<NsUnknown *> callback = 
+    static Callback<Ptr<NsUnknown> > callback = 
       MakeCallback (&NsUnknownManager::MakeObjectZero<T>);
     return NsUnknownManager::Register (name, &callback);
   }
@@ -150,7 +151,7 @@
   template <typename T, typename T1>
   static ClassId RegisterConstructor (std::string name)
   {
-    static Callback<NsUnknown *,T1> callback = MakeCallback (&NsUnknownManager::MakeObjectOne<T,T1>);
+    static Callback<Ptr<NsUnknown> ,T1> callback = MakeCallback (&NsUnknownManager::MakeObjectOne<T,T1>);
     return NsUnknownManager::Register (name, &callback);
   }
 
@@ -163,7 +164,7 @@
   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>);
+    static Callback<Ptr<NsUnknown>,T1,T2> callback = MakeCallback (&NsUnknownManager::MakeObjectTwo<T,T1,T2>);
     return NsUnknownManager::Register (name, &callback);
   }
 private:
@@ -172,16 +173,16 @@
   template <typename T1, typename T2,
             typename T3, typename T4,
             typename T5>
-  static Callback<NsUnknown *,T1,T2,T3,T4,T5> DoGetCallback (ClassId classId);
+  static Callback<Ptr<NsUnknown>,T1,T2,T3,T4,T5> DoGetCallback (ClassId classId);
 
   template <typename T>
-  static NsUnknown *MakeObjectZero (void);
+  static Ptr<NsUnknown> MakeObjectZero (void);
 
   template <typename T, typename T1>
-  static NsUnknown *MakeObjectOne (T1 a1);
+  static Ptr<NsUnknown> MakeObjectOne (T1 a1);
 
   template <typename T, typename T1, typename T2>
-  static NsUnknown *MakeObjectTwo (T1 a1, T2 a2);
+  static Ptr<NsUnknown> MakeObjectTwo (T1 a1, T2 a2);
 
   typedef std::vector<std::pair<ClassId, CallbackBase *> > List;
   static List *GetList (void);
@@ -196,7 +197,7 @@
 template <typename T1, typename T2,
           typename T3, typename T4,
           typename T5>
-Callback<NsUnknown *,T1,T2,T3,T4,T5>
+Callback<Ptr<NsUnknown>,T1,T2,T3,T4,T5>
 NsUnknownManager::DoGetCallback (ClassId classId)
 {
   CallbackBase *callback = Lookup (classId);
@@ -204,73 +205,70 @@
     {
       NS_FATAL_ERROR ("Invalid Class Id.");
     }
-  Callback<NsUnknown *, T1,T2,T3,T4,T5> reference;
+  Callback<Ptr<NsUnknown>, T1,T2,T3,T4,T5> reference;
   reference.Assign (*callback);
   return reference;
 }
 
 
 template <typename T1>
-NsUnknown *
+Ptr<NsUnknown>
 NsUnknownManager::Create (ClassId classId, T1 a1)
 {
-  Callback<NsUnknown *, T1> callback = DoGetCallback<T1,empty,empty,empty,empty> (classId);
+  Callback<Ptr<NsUnknown>, T1> callback = DoGetCallback<T1,empty,empty,empty,empty> (classId);
   return callback (a1);
 }
 
 template <typename T1, typename T2>
-NsUnknown *
+Ptr<NsUnknown> 
 NsUnknownManager::Create (ClassId classId, T1 a1, T2 a2)
 {
-  Callback<NsUnknown *, T1,T2> callback = DoGetCallback<T1,T2,empty,empty,empty> (classId);
+  Callback<Ptr<NsUnknown> , T1,T2> callback = DoGetCallback<T1,T2,empty,empty,empty> (classId);
   return callback (a1, a2);
 }
 
 template <typename T>
-T *
+Ptr<T>
 NsUnknownManager::Create (ClassId classId, Iid iid)
 {
-  NsUnknown *obj = Create (classId);
-  T *i = obj->QueryInterface<T> (iid);
-  obj->Unref ();
+  Ptr<NsUnknown> obj = Create (classId);
+  Ptr<T> i = obj->QueryInterface<T> (iid);
   return i;
 }
 
 template <typename T, typename T1>
-T *
+Ptr<T>
 NsUnknownManager::Create (ClassId classId, Iid iid, T1 a1)
 {
-  NsUnknown *obj = Create (classId, a1);
-  T *i = obj->QueryInterface<T> (iid);
-  obj->Unref ();
+  Ptr<NsUnknown> obj = Create (classId, a1);
+  Ptr<T> i = obj->QueryInterface<T> (iid);
   return i;
 }
 
 template <typename T, typename T1, typename T2>
-T *
+Ptr<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 ();
+  Ptr<NsUnknown> obj = Create (classId, a1, a2);
+  Ptr<T> i = obj->QueryInterface<T> (iid);
   return i;
 }
 
 
 template <typename T>
-NsUnknown *
+Ptr<NsUnknown> 
 NsUnknownManager::MakeObjectZero (void)
 {
   return new T ();
 }
 template <typename T, typename T1>
-NsUnknown *
+Ptr<NsUnknown> 
 NsUnknownManager::MakeObjectOne (T1 a1)
 {
   return new T (a1);
 }
 template <typename T, typename T1, typename T2>
-NsUnknown *
+Ptr<NsUnknown> 
 NsUnknownManager::MakeObjectTwo (T1 a1, T2 a2)
 {
   return new T (a1, a2);
--- a/src/core/ns-unknown.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/core/ns-unknown.cc	Thu May 10 20:19:26 2007 +0200
@@ -53,9 +53,9 @@
   void RefAll (NsUnknownImpl *other);
   void Unref (void);
   void UnrefAll (void);
-  NsUnknown *DoQueryInterface (Iid iid) const;
+  NsUnknown *PeekQueryInterface (Iid iid) const;
   void DoDisposeAll (void);
-  void AddInterface (NsUnknown *interface);
+  void AddInterface (NsUnknown * interface);
   void AddSelfInterface (Iid iid, NsUnknown *interface);
 private:
   typedef std::list<std::pair<Iid,NsUnknown *> > List;
@@ -64,7 +64,7 @@
   bool m_disposed;
 };
 
-NsUnknownImpl::NsUnknownImpl (Iid iid, NsUnknown *interface)
+NsUnknownImpl::NsUnknownImpl (Iid iid, NsUnknown * interface)
   : m_ref (0),
     m_disposed (false)
 {
@@ -124,14 +124,13 @@
   m_disposed = true;
 }
 NsUnknown *
-NsUnknownImpl::DoQueryInterface (Iid iid) const
+NsUnknownImpl::PeekQueryInterface (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;
 	}
     }
@@ -206,25 +205,26 @@
     }
 }
 
-NsUnknown *
+Ptr<NsUnknown>
 NsUnknown::DoQueryInterface (Iid iid) const
 {
-  return m_impl->DoQueryInterface (iid);
+  return m_impl->PeekQueryInterface (iid);
 }
 
 void 
-NsUnknown::AddInterface (NsUnknown *interface)
+NsUnknown::AddInterface (Ptr<NsUnknown> interface)
 {
-  m_impl->AddInterface (interface);
-  m_impl->RefAll (interface->m_impl);
-  interface->m_impl->UnrefAll ();
-  interface->m_impl = m_impl;
+  NsUnknown *p = interface.Peek ();
+  m_impl->AddInterface (p);
+  m_impl->RefAll (p->m_impl);
+  p->m_impl->UnrefAll ();
+  p->m_impl = m_impl;
 }
 
 void
-NsUnknown::AddSelfInterface (Iid iid, NsUnknown *interface)
+NsUnknown::AddSelfInterface (Iid iid, Ptr<NsUnknown> interface)
 {
-  m_impl->AddSelfInterface (iid, interface);
+  m_impl->AddSelfInterface (iid, interface.Peek ());
 }
 
 
@@ -316,31 +316,26 @@
   //DerivedAB *derivedAB;
 
 
-  A *a = new A ();
-  a->Unref ();
+  Ptr<A> a = new A ();
 
   a = new A ();
-  A *a1 = a->QueryInterface<A> (A::iid);
+  Ptr<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);
+  Ptr<B> b = new B ();
+  Ptr<B> b1 = b->QueryInterface<B> (B::iid);
   if (b1 == 0 || b1 != b)
     {
       ok = false;
     }
-  b1->Unref ();
   
   a = new A ();
   a->AddInterface (b);
@@ -349,43 +344,33 @@
     {
       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);
+  Ptr<Derived> derived = new Derived ();
+  Ptr<Base> base = derived->QueryInterface<Base> (Base::iid);
   if (base == 0)
     {
       ok = false;
     }
-  Derived *derived1 = base->QueryInterface<Derived> (Derived::iid);
+  Ptr<Derived> derived1 = base->QueryInterface<Derived> (Derived::iid);
   if (derived1 == 0 || derived1 != derived)
     {
       ok = false;
     }
-  derived1->Unref ();
-  base->Unref ();
-  derived->Unref ();
 
   return ok;
 }
--- a/src/core/ns-unknown.h	Thu May 10 18:33:52 2007 +0200
+++ b/src/core/ns-unknown.h	Thu May 10 20:19:26 2007 +0200
@@ -22,7 +22,7 @@
 #define INTERFACE_H
 
 #include <string>
-
+#include "ptr.h"
 
 namespace ns3 {
 
@@ -56,7 +56,7 @@
    * \param iid the NsUnknown id of the requested interface
    */
   template <typename T>
-  T *QueryInterface (Iid iid) const;
+  Ptr<T> QueryInterface (Iid iid) const;
 
   /**
    * \param interface another interface
@@ -66,7 +66,7 @@
    * 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 AddInterface (Ptr<NsUnknown> interface);
 
   void Dispose (void);
 protected:
@@ -87,7 +87,7 @@
    * (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);
+  void AddSelfInterface (Iid iid, Ptr<NsUnknown> interface);
 protected:
   /**
    * Subclasses who want to handle the "dispose" event should
@@ -99,7 +99,7 @@
 private:
   friend class NsUnknownImpl;
   NsUnknown ();
-  NsUnknown *DoQueryInterface (Iid iid) const;
+  Ptr<NsUnknown> DoQueryInterface (Iid iid) const;
   void RefInternal (void);
   void UnrefInternal (void);
   NsUnknownImpl *m_impl;
@@ -111,13 +111,13 @@
 namespace ns3 {
 
 template <typename T>
-T *
+Ptr<T>
 NsUnknown::QueryInterface (Iid iid) const
 {
-  NsUnknown *found = DoQueryInterface (iid);
+  Ptr<NsUnknown> found = DoQueryInterface (iid);
   if (found != 0)
     {
-      return dynamic_cast<T *> (found);
+      return Ptr<T> (dynamic_cast<T *> (found.Peek ()));
     }
   return 0;
 }
--- a/src/devices/p2p/p2p-channel.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/devices/p2p/p2p-channel.cc	Thu May 10 20:19:26 2007 +0200
@@ -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	Thu May 10 18:33:52 2007 +0200
+++ b/src/devices/p2p/p2p-channel.h	Thu May 10 20:19:26 2007 +0200
@@ -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	Thu May 10 18:33:52 2007 +0200
+++ b/src/devices/p2p/p2p-net-device.cc	Thu May 10 20:19:26 2007 +0200
@@ -81,18 +81,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 +96,8 @@
 
 void PointToPointNetDevice::DoDispose()
 {
- if (m_channel != 0)
- {
-   m_channel->Unref ();
-   m_channel = 0;
- }
- NetDevice::DoDispose ();
+  m_channel = 0;
+  NetDevice::DoDispose ();
 }
 
 //
@@ -305,18 +295,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 ();
@@ -358,10 +341,9 @@
     return m_queue;
 }
 
-Channel* 
+Ptr<Channel>
 PointToPointNetDevice::DoGetChannel(void) const 
 { 
-    m_channel->Ref();
     return m_channel;
 }
 
--- a/src/devices/p2p/p2p-net-device.h	Thu May 10 18:33:52 2007 +0200
+++ b/src/devices/p2p/p2p-net-device.h	Thu May 10 20:19:26 2007 +0200
@@ -140,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.
    *
@@ -189,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.
@@ -288,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
--- a/src/devices/p2p/p2p-topology.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/devices/p2p/p2p-topology.cc	Thu May 10 20:19:26 2007 +0200
@@ -38,38 +38,33 @@
 
 namespace ns3 {
 
-PointToPointChannel *
+Ptr<PointToPointChannel>
 PointToPointTopology::AddPointToPointLink(
   Ptr<Node> n1,
   Ptr<Node> n2,
   const DataRate& bps,
   const Time& delay)
 {
-  PointToPointChannel* channel = new PointToPointChannel(bps, delay);
-  channel->Ref ();
+  Ptr<PointToPointChannel> channel = new PointToPointChannel(bps, delay);
 
-  PointToPointNetDevice* net1 = new PointToPointNetDevice(n1);
-  net1->Ref ();
+  Ptr<PointToPointNetDevice> net1 = new PointToPointNetDevice(n1);
 
   net1->AddQueue(Queue::Default().Copy());
   n1->AddDevice (net1);
   net1->Attach (channel);
-  net1->Unref ();
   
-  PointToPointNetDevice* net2 = new PointToPointNetDevice(n2);
-  net2->Ref ();
+  Ptr<PointToPointNetDevice> net2 = new PointToPointNetDevice(n2);
 
   net2->AddQueue(Queue::Default().Copy());
   n2->AddDevice (net2);
   net2->Attach (channel);
-  net2->Unref ();
 
   return channel;
 }
 
 bool
 PointToPointTopology::AddIpv4Addresses(
-  const PointToPointChannel *chan,
+  Ptr<const PointToPointChannel> chan,
   Ptr<Node> n1, const Ipv4Address& addr1,
   Ptr<Node> n2, const Ipv4Address& addr2)
 {
@@ -81,8 +76,8 @@
 
   // 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->GetNode ()->GetId () == n2->GetId () ) && 
        (nd2->GetNode ()->GetId () == n1->GetId () ) )
@@ -92,14 +87,14 @@
   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);
@@ -108,10 +103,7 @@
   
   ip1->AddHostRouteTo (addr2, index1);
   ip2->AddHostRouteTo (addr1, index2);
-  
-  ip1->Unref ();
-  ip2->Unref ();
-  
+    
   return true;
 }
 
@@ -121,18 +113,13 @@
 // 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(Ptr<Node> n1, Ptr<Node> n2)
+Ptr<PointToPointNetDevice> PointToPointTopology::GetNetDevice(Ptr<Node> n1, Ptr<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();
+      Ptr<NetDevice> nd = *i; // next device
+      Ptr<Channel> c = nd->GetChannel();
       if (!c) continue; // No channel
       if (c->NodeIsPeer(n2)) return nd; // found it
     }
@@ -140,26 +127,26 @@
 }
   
 // Get the channel connecting node n1 to node n2
-PointToPointChannel* PointToPointTopology::GetChannel(
+Ptr<PointToPointChannel> PointToPointTopology::GetChannel(
   Ptr<Node> n1, 
   Ptr<Node> n2
 )
 {
-  NetDevice* nd = GetNetDevice(n1, n2);
+  Ptr<NetDevice> nd = GetNetDevice(n1, n2);
   if (!nd) return 0; // No net device, so no channel
   return nd->GetChannel();
 }
 
 Queue* PointToPointTopology::GetQueue(Ptr<Node> n1, Ptr<Node> n2)
 {
-  NetDevice* nd = GetNetDevice(n1, n2);
+  Ptr<NetDevice> nd = GetNetDevice(n1, n2);
   if (!nd) return 0; // No net device, so in queue
   return nd->GetQueue();
 }
 
 Queue* PointToPointTopology::SetQueue(Ptr<Node> n1, Ptr<Node> n2, const Queue& q)
 {
-  NetDevice* nd = GetNetDevice(n1, n2);
+  Ptr<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);
@@ -168,22 +155,18 @@
 #endif
 
 #ifdef GFR
-P2PChannel* Topology::AddDuplexLink(Ptr<Node> n1, const IPAddr& ip1, 
+P2PChannel Topology::AddDuplexLink(Ptr<Node> n1, const IPAddr& ip1, 
                                     Ptr<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;
+  Ptr<L3Demux>    l3demux1 = n1->GetL3Demux();
+  Ptr<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
@@ -191,8 +174,8 @@
   // 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;
+  Ptr<L3Demux>    l3demux2 = n2->GetL3Demux();
+  Ptr<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));
@@ -200,23 +183,23 @@
 }
 
 // Get the channel connecting node n1 to node n2
-Channel* Topology::GetChannel(Ptr<Node> n1, Ptr<Node> n2)
+Ptr<Channel> Topology::GetChannel(Ptr<Node> n1, Ptr<Node> n2)
 {
-  NetDevice* nd = GetNetDevice(n1, n2);
+  Ptr<NetDevice> nd = GetNetDevice(n1, n2);
   if (!nd) return 0; // No net device, so no channel
   return nd->GetChannel();
 }
 
 Queue* Topology::GetQueue(Ptr<Node> n1, Ptr<Node> n2)
 {
-  NetDevice* nd = GetNetDevice(n1, n2);
+  Ptr<NetDevice> nd = GetNetDevice(n1, n2);
   if (!nd) return 0; // No net device, so in queue
   return nd->GetQueue();
 }
 
 Queue* Topology::SetQueue(Ptr<Node> n1, Ptr<Node> n2, const Queue& q)
 {
-  NetDevice* nd = GetNetDevice(n1, n2);
+  Ptr<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);
--- a/src/devices/p2p/p2p-topology.h	Thu May 10 18:33:52 2007 +0200
+++ b/src/devices/p2p/p2p-topology.h	Thu May 10 20:19:26 2007 +0200
@@ -51,22 +51,22 @@
    * with the specified IP addresses,  with specified maximum transmission rate
    * and propagation delay.
    */
-  static PointToPointChannel* AddPointToPointLink(
+  static Ptr<PointToPointChannel> AddPointToPointLink(
     Ptr<Node>, Ptr<Node>, const DataRate&, const Time&);
 
   static bool AddIpv4Addresses(
-    const PointToPointChannel*,
+    Ptr<const PointToPointChannel>,
     Ptr<Node>, const Ipv4Address&,
     Ptr<Node>, const Ipv4Address&);
 
   /**
    * Get the connecting node n1 to node n2
    */
-  static PointToPointChannel* GetChannel(Ptr<Node>, Ptr<Node>);
+  static Ptr<PointToPointChannel> GetChannel(Ptr<Node>, Ptr<Node>);
   /**
    * Get the NetDevice connecting node n1 to n2
    */
-  static PointToPointNetDevice* GetNetDevice(Ptr<Node>, Ptr<Node>);
+  static Ptr<PointToPointNetDevice> GetNetDevice(Ptr<Node>, Ptr<Node>);
   /**
    * Get the queue associated with a link between two nodes
    */
--- a/src/internet-node/arp-cache.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/arp-cache.cc	Thu May 10 20:19:26 2007 +0200
@@ -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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/arp-cache.h	Thu May 10 20:19:26 2007 +0200
@@ -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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/arp-ipv4-interface.cc	Thu May 10 20:19:26 2007 +0200
@@ -31,7 +31,7 @@
 
 namespace ns3 {
 
-ArpIpv4Interface::ArpIpv4Interface (Ptr<Node> node, NetDevice *device)
+ArpIpv4Interface::ArpIpv4Interface (Ptr<Node> node, Ptr<NetDevice> device)
   : Ipv4Interface (device),
     m_node (node)
 {}
@@ -42,10 +42,10 @@
 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, GetDevice ().Peek ()),
                      ArpIpv4Interface::NETDEVICE);
     }
   
@@ -55,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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/arp-ipv4-interface.h	Thu May 10 20:19:26 2007 +0200
@@ -43,7 +43,7 @@
     NETDEVICE,
     ARP,
   };
-  ArpIpv4Interface (Ptr<Node> node, NetDevice *device);
+  ArpIpv4Interface (Ptr<Node> node, Ptr<NetDevice> device);
   virtual ~ArpIpv4Interface ();
 
  private:
--- a/src/internet-node/arp.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/arp.cc	Thu May 10 20:19:26 2007 +0200
@@ -63,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));
@@ -83,7 +82,7 @@
 }
 
 void 
-Arp::Receive(Packet& packet, NetDevice *device)
+Arp::Receive(Packet& packet, Ptr<NetDevice> device)
 {
   ArpCache *cache = FindCache (device);
   ArpHeader arp;
@@ -132,7 +131,7 @@
 }
 bool 
 Arp::Lookup (Packet &packet, Ipv4Address destination, 
-	     NetDevice *device,
+	     Ptr<NetDevice> device,
 	     MacAddress *hardwareDestination)
 {
   ArpCache *cache = FindCache (device);
@@ -204,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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/arp.h	Thu May 10 20:19:26 2007 +0200
@@ -46,15 +46,15 @@
 
   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;
--- a/src/internet-node/i-arp-private.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/i-arp-private.cc	Thu May 10 20:19:26 2007 +0200
@@ -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");
 
-IArpPrivate::IArpPrivate (Arp *arp)
+IArpPrivate::IArpPrivate (Ptr<Arp> arp)
   : NsUnknown (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,7 +47,6 @@
 void
 IArpPrivate::DoDispose (void)
 {
-  m_arp->Unref ();
   m_arp = 0;
   NsUnknown::DoDispose ();
 }
--- a/src/internet-node/i-arp-private.h	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/i-arp-private.h	Thu May 10 20:19:26 2007 +0200
@@ -35,15 +35,15 @@
 {
 public:
   static const Iid iid;
-  IArpPrivate (Arp *arp);
+  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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/i-ipv4-impl.cc	Thu May 10 20:19:26 2007 +0200
@@ -21,14 +21,13 @@
 #include "i-ipv4-impl.h"
 #include "ipv4.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 +35,6 @@
 void 
 IIpv4Impl::DoDispose (void)
 {
-  m_ipv4->Unref ();
   m_ipv4 = 0;
 }
 
@@ -90,7 +88,7 @@
   return m_ipv4->RemoveRoute (i);
 }
 uint32_t 
-IIpv4Impl::AddInterface (NetDevice *device)
+IIpv4Impl::AddInterface (Ptr<NetDevice> device)
 {
   return m_ipv4->AddInterface (device);
 }
--- a/src/internet-node/i-ipv4-impl.h	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/i-ipv4-impl.h	Thu May 10 20:19:26 2007 +0200
@@ -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,7 +52,7 @@
   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 void SetAddress (uint32_t i, Ipv4Address address);
@@ -65,7 +66,7 @@
 protected:
   virtual void DoDispose (void);
 private:
-  Ipv4 *m_ipv4;
+  Ptr<Ipv4> m_ipv4;
 };
 
 } // namespace ns3
--- a/src/internet-node/i-ipv4-private.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/i-ipv4-private.cc	Thu May 10 20:19:26 2007 +0200
@@ -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");
 
-IIpv4Private::IIpv4Private (Ipv4 *ipv4)
+IIpv4Private::IIpv4Private (Ptr<Ipv4> ipv4)
   : NsUnknown (IIpv4Private::iid),
     m_ipv4 (ipv4)
-{
-  m_ipv4->Ref ();
-}
+{}
 IIpv4Private::~IIpv4Private ()
 {
   NS_ASSERT (m_ipv4 == 0);
@@ -48,19 +47,18 @@
   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 ();
 }
--- a/src/internet-node/i-ipv4-private.h	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/i-ipv4-private.h	Thu May 10 20:19:26 2007 +0200
@@ -23,6 +23,7 @@
 
 #include "ns3/ns-unknown.h"
 #include "ns3/ipv4-address.h"
+#include "ns3/ptr.h"
 #include <stdint.h>
 
 namespace ns3 {
@@ -38,18 +39,18 @@
 {
 public:
   static const Iid iid;
-  IIpv4Private (Ipv4 *ipv4);
+  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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/i-udp-impl.cc	Thu May 10 20:19:26 2007 +0200
@@ -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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/i-udp-impl.h	Thu May 10 20:19:26 2007 +0200
@@ -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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/internet-node.cc	Thu May 10 20:19:26 2007 +0200
@@ -41,35 +41,22 @@
 
 InternetNode::InternetNode()
 {
-  Ipv4 *ipv4 = new Ipv4 (this);
-  Arp *arp = new Arp (this);
-  Udp *udp = new Udp (this);
-
-  ipv4->Ref ();
-  arp->Ref ();
-  udp->Ref ();
+  Ptr<Ipv4> ipv4 = new Ipv4 (this);
+  Ptr<Arp> arp = new Arp (this);
+  Ptr<Udp> udp = new Udp (this);
 
-  ApplicationList *applicationList = new ApplicationList(this);
-  L3Demux *l3Demux = new L3Demux(this);
-  Ipv4L4Demux *ipv4L4Demux = new Ipv4L4Demux(this);
-
-  applicationList->Ref ();
-  l3Demux->Ref ();
-  ipv4L4Demux->Ref ();
+  Ptr<ApplicationList> applicationList = new ApplicationList(this);
+  Ptr<L3Demux> l3Demux = new L3Demux(this);
+  Ptr<Ipv4L4Demux> ipv4L4Demux = new 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);
-
-  udpImpl->Ref ();
-  arpPrivate->Ref ();
-  ipv4Impl->Ref ();
-  ipv4Private->Ref ();
+  Ptr<IUdpImpl> udpImpl = new IUdpImpl (udp);
+  Ptr<IArpPrivate> arpPrivate = new IArpPrivate (arp);
+  Ptr<IIpv4Impl> ipv4Impl = new IIpv4Impl (ipv4);
+  Ptr<IIpv4Private> ipv4Private = new IIpv4Private (ipv4);
 
   NsUnknown::AddInterface (ipv4Private);
   NsUnknown::AddInterface (ipv4Impl);
@@ -78,18 +65,6 @@
   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 ();
 }
 
 InternetNode::~InternetNode ()
@@ -105,11 +80,10 @@
 InternetNode::CreateTraceResolver (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, ipv4.Peek ()),
                  InternetNode::IPV4);
-  ipv4->Unref ();
 
   return resolver;
 }
@@ -121,17 +95,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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/internet-node.h	Thu May 10 20:19:26 2007 +0200
@@ -47,8 +47,8 @@
 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;
+  bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &p, uint16_t protocolNumber) const;
   std::string      m_name;
 };
 
--- a/src/internet-node/ipv4-interface.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/ipv4-interface.cc	Thu May 10 20:19:26 2007 +0200
@@ -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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/ipv4-interface.h	Thu May 10 20:19:26 2007 +0200
@@ -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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/ipv4-l4-demux.cc	Thu May 10 20:19:26 2007 +0200
@@ -43,10 +43,10 @@
 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 ();
   m_node = 0;
@@ -59,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, protocol.Peek ()),
                      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)
     {
@@ -89,7 +88,7 @@
   return 0;
 }
 void
-Ipv4L4Demux::Erase(Ipv4L4Protocol*protocol)
+Ipv4L4Demux::Erase(Ptr<Ipv4L4Protocol> protocol)
 {
   m_protocols.remove (protocol);
 }
--- a/src/internet-node/ipv4-l4-demux.h	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/ipv4-l4-demux.h	Thu May 10 20:19:26 2007 +0200
@@ -65,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
@@ -75,17 +75,17 @@
    * 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 Erase (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;
   Ptr<Node> m_node;
 };
--- a/src/internet-node/ipv4-loopback-interface.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/ipv4-loopback-interface.cc	Thu May 10 20:19:26 2007 +0200
@@ -43,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.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/ipv4.cc	Thu May 10 20:19:26 2007 +0200
@@ -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"
@@ -310,7 +311,7 @@
 
 
 uint32_t 
-Ipv4::AddInterface (NetDevice *device)
+Ipv4::AddInterface (Ptr<NetDevice> device)
 {
   Ipv4Interface *interface = new ArpIpv4Interface (m_node, device);
   return AddIpv4Interface (interface);
@@ -344,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;
         }
@@ -357,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;
@@ -442,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++) 
@@ -458,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 ())) 
 	    {
@@ -504,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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/ipv4.h	Thu May 10 20:19:26 2007 +0200
@@ -165,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
@@ -182,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);
   
 
   /**
@@ -192,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
@@ -220,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);
--- a/src/internet-node/l3-demux.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/l3-demux.cc	Thu May 10 20:19:26 2007 +0200
@@ -45,7 +45,7 @@
   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 ();
   m_node = 0;
@@ -63,23 +63,25 @@
       oss << i->second->GetProtocolNumber ();
       ProtocolTraceType context = i->second->GetProtocolNumber ();
       resolver->Add (protValue, 
-                     MakeCallback (&L3Protocol::CreateTraceResolver, i->second),
+                     MakeCallback (&L3Protocol::CreateTraceResolver, i->second.Peek ()),
                      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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/l3-demux.h	Thu May 10 20:19:26 2007 +0200
@@ -68,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
@@ -78,18 +78,18 @@
    * to forward packets up the stack to the right protocol.
    * It is also called from InternetNode::GetIpv4 for example.
    */
-  ns3::L3Protocol* PeekProtocol (int protocolNumber);
+  Ptr<L3Protocol> GetProtocol (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);
+  void Erase(Ptr<L3Protocol> protocol);
 protected:
   virtual void DoDispose (void);
 private:
-  typedef std::map<int, ns3::L3Protocol*> L3Map_t;
+  typedef std::map<int, Ptr<ns3::L3Protocol> > L3Map_t;
 
   Ptr<Node> m_node;
   L3Map_t m_protocols;
--- a/src/internet-node/l3-protocol.h	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/l3-protocol.h	Thu May 10 20:19:26 2007 +0200
@@ -26,6 +26,7 @@
 #define L3_PROTOCOL_H
 
 #include "ns3/object.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -53,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/udp-socket.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/udp-socket.cc	Thu May 10 20:19:26 2007 +0200
@@ -26,7 +26,7 @@
 
 namespace ns3 {
 
-UdpSocket::UdpSocket (Ptr<Node> node, Udp *udp)
+UdpSocket::UdpSocket (Ptr<Node> node, Ptr<Udp> udp)
   : m_endPoint (0),
     m_node (node),
     m_udp (udp),
@@ -34,9 +34,7 @@
     m_shutdownSend (false),
     m_shutdownRecv (false),
     m_connected (false)
-{
-  m_udp->Ref ();
-}
+{}
 UdpSocket::~UdpSocket ()
 {
   m_node = 0;
@@ -55,11 +53,7 @@
       m_udp->DeAllocate (m_endPoint);
       NS_ASSERT (m_endPoint == 0);
     }
-  if (m_udp != 0)
-    {
-      m_udp->Unref ();
-      m_udp = 0;
-    }
+  m_udp = 0;
 }
 
 Ptr<Node>
@@ -73,11 +67,7 @@
 {
   m_node = 0;
   m_endPoint = 0;
-  if (m_udp != 0)
-    {
-      m_udp->Unref ();
-      m_udp = 0;
-    }
+  m_udp = 0;
 }
 int
 UdpSocket::FinishBind (void)
@@ -135,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 ())
@@ -146,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;
@@ -159,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;
@@ -170,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)
     {
@@ -190,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)
     {
@@ -219,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)
     {
@@ -238,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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/udp-socket.h	Thu May 10 20:19:26 2007 +0200
@@ -39,7 +39,7 @@
   /**
    * Create an unbound udp socket.
    */
-  UdpSocket (Ptr<Node> node, Udp *udp);
+  UdpSocket (Ptr<Node> node, Ptr<Udp> udp);
   virtual ~UdpSocket ();
 
   virtual enum SocketErrno GetErrno (void) const;
@@ -52,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;
@@ -79,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;
   Ptr<Node> m_node;
-  Udp *m_udp;
+  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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/udp.cc	Thu May 10 20:19:26 2007 +0200
@@ -65,11 +65,10 @@
   Ipv4L4Protocol::DoDispose ();
 }
 
-Socket *
+Ptr<Socket>
 Udp::CreateSocket (void)
 {
-  Socket *socket = new UdpSocket (m_node, this);
-  socket->Ref ();
+  Ptr<Socket> socket = new UdpSocket (m_node, this);
   return socket;
 }
 
@@ -138,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	Thu May 10 18:33:52 2007 +0200
+++ b/src/internet-node/udp.h	Thu May 10 20:19:26 2007 +0200
@@ -46,7 +46,7 @@
 
   virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
 
-  Socket *CreateSocket (void);
+  Ptr<Socket> CreateSocket (void);
 
   Ipv4EndPoint *Allocate (void);
   Ipv4EndPoint *Allocate (Ipv4Address address);
--- a/src/node/channel.h	Thu May 10 18:33:52 2007 +0200
+++ b/src/node/channel.h	Thu May 10 20:19:26 2007 +0200
@@ -25,6 +25,7 @@
 #include <string>
 #include <stdint.h>
 #include "ns3/object.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -57,7 +58,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/i-ipv4.h	Thu May 10 18:33:52 2007 +0200
+++ b/src/node/i-ipv4.h	Thu May 10 20:19:26 2007 +0200
@@ -116,7 +116,7 @@
    * 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.
    */
--- a/src/node/i-udp.h	Thu May 10 18:33:52 2007 +0200
+++ b/src/node/i-udp.h	Thu May 10 20:19:26 2007 +0200
@@ -22,6 +22,7 @@
 #define I_UDP_H
 
 #include "ns3/ns-unknown.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -34,7 +35,7 @@
 
   IUdp ();
 
-  virtual Socket *CreateSocket (void) = 0;
+  virtual Ptr<Socket> CreateSocket (void) = 0;
 };
 
 } // namespace ns3
--- a/src/node/net-device.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/node/net-device.cc	Thu May 10 20:19:26 2007 +0200
@@ -183,7 +183,7 @@
   return DoCreateTraceResolver (context);
 }
 
-Channel *
+Ptr<Channel>
 NetDevice::GetChannel (void) const
 {
   return DoGetChannel ();
@@ -236,7 +236,7 @@
 }
 
 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;
 }
--- a/src/node/net-device.h	Thu May 10 18:33:52 2007 +0200
+++ b/src/node/net-device.h	Thu May 10 20:19:26 2007 +0200
@@ -79,7 +79,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.
@@ -174,7 +174,7 @@
 
   bool NeedsArp (void) const;
 
-  void SetReceiveCallback (Callback<bool,NetDevice *,const Packet &,uint16_t> cb);
+  void SetReceiveCallback (Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> cb);
 
  protected:
   /**
@@ -241,7 +241,7 @@
   virtual bool SendTo (Packet& p, const MacAddress& dest) = 0;
   virtual bool DoNeedsArp (void) const = 0;
   virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
-  virtual Channel *DoGetChannel (void) const = 0;
+  virtual Ptr<Channel> DoGetChannel (void) const = 0;
   Ptr<Node>         m_node;
   std::string   m_name;
   uint16_t      m_ifIndex;
@@ -253,7 +253,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.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/node/node.cc	Thu May 10 20:19:26 2007 +0200
@@ -69,16 +69,15 @@
 }
 
 uint32_t 
-Node::AddDevice (NetDevice *device)
+Node::AddDevice (Ptr<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];
@@ -91,12 +90,12 @@
 
 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 ();
--- a/src/node/node.h	Thu May 10 18:33:52 2007 +0200
+++ b/src/node/node.h	Thu May 10 20:19:26 2007 +0200
@@ -50,18 +50,18 @@
   uint32_t GetSystemId (void) const;
   void SetSystemId(uint32_t s);
 
-  uint32_t AddDevice (NetDevice *device);
-  NetDevice *GetDevice (uint32_t index) const;
+  uint32_t AddDevice (Ptr<NetDevice> device);
+  Ptr<NetDevice> GetDevice (uint32_t index) const;
   uint32_t GetNDevices (void) const;
 
 protected:
   virtual void DoDispose (void);
 private:
-  virtual void DoAddDevice (NetDevice *device) const = 0;
+  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;
 };
 
 } //namespace ns3
--- a/src/node/socket.cc	Thu May 10 18:33:52 2007 +0200
+++ b/src/node/socket.cc	Thu May 10 20:19:26 2007 +0200
@@ -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	Thu May 10 18:33:52 2007 +0200
+++ b/src/node/socket.h	Thu May 10 20:19:26 2007 +0200
@@ -114,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.
@@ -147,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
@@ -170,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
@@ -186,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.
@@ -202,7 +202,7 @@
              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
@@ -213,7 +213,7 @@
    * 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> = 
             MakeCallback (&Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16));
   
   /**
@@ -223,38 +223,38 @@
    * 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> = 
                  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