split code from object.h/object.cc
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Sun, 16 Mar 2008 20:55:18 +0100
changeset 2633 a0639de8cd8b
parent 2632 e7989e4c674a
child 2634 44a92f1d3728
split code from object.h/object.cc
src/core/attribute-helper.h
src/core/attribute-list.cc
src/core/attribute-list.h
src/core/attribute.h
src/core/callback.h
src/core/object-base.h
src/core/object.cc
src/core/object.h
src/core/type-id.cc
src/core/type-id.h
src/core/wscript
--- a/src/core/attribute-helper.h	Sun Mar 16 20:47:46 2008 +0100
+++ b/src/core/attribute-helper.h	Sun Mar 16 20:55:18 2008 +0100
@@ -21,7 +21,6 @@
 #define ATTRIBUTE_HELPER_H
 
 #include "attribute.h"
-#include "object-base.h"
 #include "attribute-accessor-helper.h"
 #include <sstream>
 #include "fatal-error.h"
@@ -57,8 +56,6 @@
 
 }
 
-
-
 /**
  * \defgroup AttributeHelper
  *
@@ -281,5 +278,4 @@
   ATTRIBUTE_VALUE_IMPLEMENT (type);
 
 
-
 #endif /* ATTRIBUTE_HELPER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/attribute-list.cc	Sun Mar 16 20:55:18 2008 +0100
@@ -0,0 +1,237 @@
+#include "attribute-list.h"
+#include "string.h"
+#include "singleton.h"
+
+namespace ns3 {
+
+/*********************************************************************
+ *         The AttributeList container implementation
+ *********************************************************************/
+
+AttributeList::AttributeList ()
+{}
+
+AttributeList::AttributeList (const AttributeList &o)
+{
+  for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++)
+    {
+      struct Attr attr;
+      attr.checker = i->checker;
+      attr.value = i->value.Copy ();
+      m_attributes.push_back (attr);
+    }
+}
+AttributeList &
+AttributeList::operator = (const AttributeList &o)
+{
+  Reset ();
+  for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++)
+    {
+      struct Attr attr;
+      attr.checker = i->checker;
+      attr.value = i->value.Copy ();
+      m_attributes.push_back (attr);
+    }
+  return *this;
+}
+AttributeList::~AttributeList ()
+{
+  Reset ();
+}
+
+void
+AttributeList::Set (std::string name, Attribute value)
+{
+  struct TypeId::AttributeInfo info;
+  bool ok = TypeId::LookupAttributeByFullName (name, &info);
+  if (!ok)
+    {
+      NS_FATAL_ERROR ("Could not find attribute "<<name);
+    }
+  ok = DoSet (&info, value);
+  if (!ok)
+    {
+      NS_FATAL_ERROR ("Could not set value for attribute "<<name);
+    }
+}
+bool 
+AttributeList::SetFailSafe (std::string name, Attribute value)
+{
+  struct TypeId::AttributeInfo info;
+  bool ok = TypeId::LookupAttributeByFullName (name, &info);
+  if (!ok)
+    {
+      return false;
+    }
+  ok = DoSet (&info, value);
+  return ok;
+}
+void
+AttributeList::SetWithTid (TypeId tid, std::string name, Attribute value)
+{
+  struct TypeId::AttributeInfo info;
+  bool ok = tid.LookupAttributeByName (name, &info);
+  if (!ok)
+    {
+      NS_FATAL_ERROR ("Could not find attribute "<<tid.GetName ()<<"::"<<name);
+    }
+  ok = DoSet (&info, value);
+  if (!ok)
+    {
+      NS_FATAL_ERROR ("Could not set value for attribute "<<tid.GetName ()<<"::"<<name);
+    }
+}
+
+void
+AttributeList::DoSetOne (Ptr<const AttributeChecker> checker, Attribute value)
+{
+  // get rid of any previous value stored in this
+  // vector of values.
+  for (Attrs::iterator k = m_attributes.begin (); k != m_attributes.end (); k++)
+    {
+      if (k->checker == checker)
+        {
+          m_attributes.erase (k);
+          break;
+        }
+    }
+  // store the new value.
+  struct Attr attr;
+  attr.checker = checker;
+  attr.value = value.Copy ();
+  m_attributes.push_back (attr);
+}
+bool
+AttributeList::DoSet (struct TypeId::AttributeInfo *info, Attribute value)
+{
+  if (info->checker == 0)
+    {
+      return false;
+    }
+  bool ok = info->checker->Check (value);
+  if (!ok)
+    {
+      // attempt to convert to string.
+      const StringValue *str = value.DynCast<const StringValue *> ();
+      if (str == 0)
+        {
+          return false;
+        }
+      // attempt to convert back to value.
+      Attribute v = info->checker->Create ();
+      ok = v.DeserializeFromString (str->Get ().Get (), info->checker);
+      if (!ok)
+        {
+          return false;
+        }
+      ok = info->checker->Check (v);
+      if (!ok)
+        {
+          return false;
+        }
+      value = v;
+    }
+  DoSetOne (info->checker, value);
+  return true;
+}
+void 
+AttributeList::Reset (void)
+{
+  m_attributes.clear ();
+}
+AttributeList *
+AttributeList::GetGlobal (void)
+{
+  return Singleton<AttributeList>::Get ();
+}
+
+std::string
+AttributeList::LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const
+{
+  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++)
+    {
+      TypeId tid = TypeId::GetRegistered (i);
+      for (uint32_t j = 0; j < tid.GetAttributeListN (); j++)
+        {
+          if (checker == tid.GetAttributeChecker (j))
+            {
+              return tid.GetAttributeFullName (j);
+            }
+        }
+    }
+  NS_FATAL_ERROR ("Could not find requested Accessor.");
+  // quiet compiler.
+  return "";
+}
+
+std::string 
+AttributeList::SerializeToString (void) const
+{
+  std::ostringstream oss;
+  for (Attrs::const_iterator i = m_attributes.begin (); i != m_attributes.end (); i++)
+    {
+      std::string name = LookupAttributeFullNameByChecker (i->checker);
+      oss << name << "=" << i->value.SerializeToString (i->checker);
+      if (i != m_attributes.end ())
+        {
+          oss << "|";
+        }
+    }  
+  return oss.str ();
+}
+bool 
+AttributeList::DeserializeFromString (std::string str)
+{
+  Reset ();
+
+  std::string::size_type cur;
+  cur = 0;
+  do {
+    std::string::size_type equal = str.find ("=", cur);
+    if (equal == std::string::npos)
+      {
+        // XXX: invalid attribute.
+        break;
+      }
+    else
+      {
+        std::string name = str.substr (cur, equal-cur);
+        struct TypeId::AttributeInfo info;
+        if (!TypeId::LookupAttributeByFullName (name, &info))
+          {
+            // XXX invalid name.
+            break;
+          }
+        else
+          {
+            std::string::size_type next = str.find ("|", cur);
+            std::string value;
+            if (next == std::string::npos)
+              {
+                value = str.substr (equal+1, str.size () - (equal+1));
+                cur = str.size ();
+              }
+            else
+              {
+                value = str.substr (equal+1, next - (equal+1));
+                cur++;
+              }
+            Attribute val = info.checker->Create ();
+            bool ok = val.DeserializeFromString (value, info.checker);
+            if (!ok)
+              {
+                // XXX invalid value
+                break;
+              }
+            else
+              {
+                DoSetOne (info.checker, val);
+              }
+          }
+      }
+  } while (cur != str.size ());
+
+  return true;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/attribute-list.h	Sun Mar 16 20:55:18 2008 +0100
@@ -0,0 +1,93 @@
+#ifndef ATTRIBUTE_LIST_H
+#define ATTRIBUTE_LIST_H
+
+#include <string>
+#include <vector>
+#include "attribute.h"
+#include "type-id.h"
+
+namespace ns3 {
+
+/**
+ * \brief a container of attributes to be used during object's construction
+ *        and in ns3::Object::Set.
+ *
+ */
+class AttributeList
+{
+public:
+  AttributeList ();
+  AttributeList (const AttributeList &o);
+  AttributeList &operator = (const AttributeList &o);
+  ~AttributeList ();
+  /**
+   * \param name the full name of the attribute to set
+   * \param value the value to set
+   *
+   * This method checks that a attribute with the requested
+   * name exists and that the value specified is an acceptable
+   * value of that attribute. If any of these checks fails,
+   * the program terminates with a message.
+   */
+  void Set (std::string name, Attribute value);
+  /**
+   * \param name the full name of the attribute to set
+   * \param value the value to set
+   * \returns true if the requested attribute exists and could be
+   *          stored, false otherwise.
+   */
+  bool SetFailSafe (std::string name, Attribute value);
+  /**
+   * \param tid the TypeId associated to this attribute
+   * \param name the name (not full!) of the attribute
+   * \param value the value to set
+   *
+   * This method checks that a attribute with the requested
+   * name exists and that the value specified is an acceptable
+   * value of that attribute. If any of these checks fails,
+   * the program terminates with a message.
+   */
+  void SetWithTid (TypeId tid, std::string name, Attribute value);
+
+  /**
+   * Clear the content of this instance.
+   */
+  void Reset (void);
+
+  /**
+   * \returns the global attribute container
+   *
+   * The global attribute container can be used to specify
+   * a set of attribute values without having to re-specify
+   * them for each object when it is created. This container
+   * is checked only during object construction and 
+   * it is always checked last, after any per-object
+   * container is checked.
+   */
+  static AttributeList *GetGlobal (void);
+
+  // XXX: untested.
+  std::string SerializeToString (void) const;
+  bool DeserializeFromString (std::string value);
+private:
+  friend class Object;
+  struct Attr {
+    Ptr<const AttributeChecker> checker;
+    Attribute value;
+  };
+  typedef std::vector<struct Attr> Attrs;
+  typedef Attrs::iterator Iterator;
+  typedef Attrs::const_iterator CIterator;
+
+
+
+  bool DoSet (struct TypeId::AttributeInfo *info, Attribute param);
+  void DoSetOne (Ptr<const AttributeChecker> checker, Attribute param);
+  std::string LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const;
+
+  Attrs m_attributes;
+};
+
+} // namespace ns3
+
+#endif /* ATTRIBUTE_LIST_H */
--- a/src/core/attribute.h	Sun Mar 16 20:47:46 2008 +0100
+++ b/src/core/attribute.h	Sun Mar 16 20:55:18 2008 +0100
@@ -23,13 +23,13 @@
 #include <string>
 #include <stdint.h>
 #include "ptr.h"
-#include "object-base.h"
 
 namespace ns3 {
 
 class AttributeAccessor;
 class AttributeChecker;
 class Attribute;
+class ObjectBase;
 
 /**
  * \brief Hold a value for an Attribute.
@@ -159,7 +159,7 @@
  * of this base class are usually provided through the MakeAccessorHelper
  * template functions, hidden behind an ATTRIBUTE_HELPER_* macro.
  */
-class AttributeAccessor : public ObjectBase
+class AttributeAccessor
 {
 public:
   AttributeAccessor ();
@@ -202,7 +202,7 @@
  * Most subclasses of this base class are implemented by the 
  * ATTRIBUTE_HELPER_* macros.
  */
-class AttributeChecker : public ObjectBase
+class AttributeChecker
 {
 public:
   AttributeChecker ();
--- a/src/core/callback.h	Sun Mar 16 20:47:46 2008 +0100
+++ b/src/core/callback.h	Sun Mar 16 20:55:18 2008 +0100
@@ -26,7 +26,6 @@
 #include "fatal-error.h"
 #include "empty.h"
 #include "type-traits.h"
-#include "object-base.h"
 
 namespace ns3 {
 
--- a/src/core/object-base.h	Sun Mar 16 20:47:46 2008 +0100
+++ b/src/core/object-base.h	Sun Mar 16 20:55:18 2008 +0100
@@ -1,6 +1,21 @@
 #ifndef OBJECT_BASE_H
 #define OBJECT_BASE_H
 
+#include "type-id.h"
+
+/**
+ * This macro should be invoked once for every class which
+ * defines a new GetTypeId method.
+ */
+#define NS_OBJECT_ENSURE_REGISTERED(type)       \
+  static struct X##type##RegistrationClass      \
+  {                                             \
+    X##type##RegistrationClass () {             \
+      ns3::TypeId tid = type::GetTypeId ();     \
+      tid.GetParent ();                         \
+    }                                           \
+} x_##type##RegistrationVariable
+
 namespace ns3 {
 
 /**
--- a/src/core/object.cc	Sun Mar 16 20:47:46 2008 +0100
+++ b/src/core/object.cc	Sun Mar 16 20:55:18 2008 +0100
@@ -30,918 +30,9 @@
 
 NS_LOG_COMPONENT_DEFINE ("Object");
 
-/*********************************************************************
- *         Helper code
- *********************************************************************/
-
-namespace {
-
-class IidManager
-{
-public:
-  IidManager ();
-  uint16_t AllocateUid (std::string name);
-  void SetParent (uint16_t uid, uint16_t parent);
-  void SetTypeName (uint16_t uid, std::string typeName);
-  void SetGroupName (uint16_t uid, std::string groupName);
-  void AddConstructor (uint16_t uid, ns3::Callback<ns3::ObjectBase *> callback);
-  void HideFromDocumentation (uint16_t uid);
-  uint16_t GetUid (std::string name) const;
-  std::string GetName (uint16_t uid) const;
-  uint16_t GetParent (uint16_t uid) const;
-  std::string GetTypeName (uint16_t uid) const;
-  std::string GetGroupName (uint16_t uid) const;
-  ns3::Callback<ns3::ObjectBase *> GetConstructor (uint16_t uid) const;
-  bool HasConstructor (uint16_t uid) const;
-  uint32_t GetRegisteredN (void) const;
-  uint16_t GetRegistered (uint32_t i) const;
-  void AddAttribute (uint16_t uid, 
-                     std::string name,
-                     std::string help, 
-                     uint32_t flags,
-                     ns3::Attribute initialValue,
-                     ns3::Ptr<const ns3::AttributeAccessor> spec,
-                     ns3::Ptr<const ns3::AttributeChecker> checker);
-  uint32_t GetAttributeListN (uint16_t uid) const;
-  std::string GetAttributeName (uint16_t uid, uint32_t i) const;
-  std::string GetAttributeHelp (uint16_t uid, uint32_t i) const;
-  uint32_t GetAttributeFlags (uint16_t uid, uint32_t i) const;
-  ns3::Attribute GetAttributeInitialValue (uint16_t uid, uint32_t i) const;
-  ns3::Ptr<const ns3::AttributeAccessor> GetAttributeAccessor (uint16_t uid, uint32_t i) const;
-  ns3::Ptr<const ns3::AttributeChecker> GetAttributeChecker (uint16_t uid, uint32_t i) const;
-  void AddTraceSource (uint16_t uid,
-                       std::string name, 
-                       std::string help,
-                       ns3::Ptr<const ns3::TraceSourceAccessor> accessor);
-  uint32_t GetTraceSourceN (uint16_t uid) const;
-  std::string GetTraceSourceName (uint16_t uid, uint32_t i) const;
-  std::string GetTraceSourceHelp (uint16_t uid, uint32_t i) const;
-  ns3::Ptr<const ns3::TraceSourceAccessor> GetTraceSourceAccessor (uint16_t uid, uint32_t i) const;
-  bool MustHideFromDocumentation (uint16_t uid) const;
-
-private:
-  struct AttributeInformation {
-    std::string name;
-    std::string help;
-    uint32_t flags;
-    ns3::Attribute initialValue;
-    ns3::Ptr<const ns3::AttributeAccessor> param;
-    ns3::Ptr<const ns3::AttributeChecker> checker;
-  };
-  struct TraceSourceInformation {
-    std::string name;
-    std::string help;
-    ns3::Ptr<const ns3::TraceSourceAccessor> accessor;
-  };
-  struct IidInformation {
-    std::string name;
-    uint16_t parent;
-    std::string typeName;
-    std::string groupName;
-    bool hasConstructor;
-    ns3::Callback<ns3::ObjectBase *> constructor;
-    bool mustHideFromDocumentation;
-    std::vector<struct AttributeInformation> attributes;
-    std::vector<struct TraceSourceInformation> traceSources;
-  };
-  typedef std::vector<struct IidInformation>::const_iterator Iterator;
-
-  struct IidManager::IidInformation *LookupInformation (uint16_t uid) const;
-
-  std::vector<struct IidInformation> m_information;
-};
-
-IidManager::IidManager ()
-{}
-
-uint16_t 
-IidManager::AllocateUid (std::string name)
-{
-  uint16_t j = 1;
-  for (Iterator i = m_information.begin (); i != m_information.end (); i++)
-    {
-      if (i->name == name)
-        {
-          NS_FATAL_ERROR ("Trying to allocate twice the same uid: " << name);
-          return 0;
-        }
-      j++;
-    }
-  struct IidInformation information;
-  information.name = name;
-  information.parent = 0;
-  information.typeName = "";
-  information.groupName = "";
-  information.hasConstructor = false;
-  information.mustHideFromDocumentation = false;
-  m_information.push_back (information);
-  uint32_t uid = m_information.size ();
-  NS_ASSERT (uid <= 0xffff);
-  return uid;
-}
-
-struct IidManager::IidInformation *
-IidManager::LookupInformation (uint16_t uid) const
-{
-  NS_ASSERT (uid <= m_information.size ());
-  return const_cast<struct IidInformation *> (&m_information[uid-1]);
-}
-
-void 
-IidManager::SetParent (uint16_t uid, uint16_t parent)
-{
-  NS_ASSERT (parent <= m_information.size ());
-  struct IidInformation *information = LookupInformation (uid);
-  information->parent = parent;
-}
-void 
-IidManager::SetTypeName (uint16_t uid, std::string typeName)
-{
-  struct IidInformation *information = LookupInformation (uid);
-  information->typeName = typeName;
-}
-void 
-IidManager::SetGroupName (uint16_t uid, std::string groupName)
-{
-  struct IidInformation *information = LookupInformation (uid);
-  information->groupName = groupName;
-}
-void
-IidManager::HideFromDocumentation (uint16_t uid)
-{
-  struct IidInformation *information = LookupInformation (uid);
-  information->mustHideFromDocumentation = true;
-}
-
-void 
-IidManager::AddConstructor (uint16_t uid, ns3::Callback<ns3::ObjectBase *> callback)
-{
-  struct IidInformation *information = LookupInformation (uid);
-  if (information->hasConstructor)
-    {
-      NS_FATAL_ERROR (information->name<<" already has a constructor.");
-    }
-  information->hasConstructor = true;
-  information->constructor = callback;
-}
-
-uint16_t 
-IidManager::GetUid (std::string name) const
-{
-  uint32_t j = 1;
-  for (Iterator i = m_information.begin (); i != m_information.end (); i++)
-    {
-      if (i->name == name)
-        {
-          NS_ASSERT (j <= 0xffff);
-          return j;
-        }
-      j++;
-    }
-  return 0;
-}
-std::string 
-IidManager::GetName (uint16_t uid) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  return information->name;
-}
-uint16_t 
-IidManager::GetParent (uint16_t uid) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  return information->parent;
-}
-std::string 
-IidManager::GetTypeName (uint16_t uid) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  return information->typeName;
-}
-std::string 
-IidManager::GetGroupName (uint16_t uid) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  return information->groupName;
-}
-
-ns3::Callback<ns3::ObjectBase *> 
-IidManager::GetConstructor (uint16_t uid) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  if (!information->hasConstructor)
-    {
-      NS_FATAL_ERROR ("Requested constructor for "<<information->name<<" but it does not have one.");
-    }
-  return information->constructor;
-}
-
-bool 
-IidManager::HasConstructor (uint16_t uid) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  return information->hasConstructor;
-}
-
-uint32_t 
-IidManager::GetRegisteredN (void) const
-{
-  return m_information.size ();
-}
-uint16_t 
-IidManager::GetRegistered (uint32_t i) const
-{
-  return i + 1;
-}
-
-void 
-IidManager::AddAttribute (uint16_t uid, 
-                          std::string name,
-                          std::string help, 
-                          uint32_t flags,
-                          ns3::Attribute initialValue,
-                          ns3::Ptr<const ns3::AttributeAccessor> spec,
-                          ns3::Ptr<const ns3::AttributeChecker> checker)
-{
-  struct IidInformation *information = LookupInformation (uid);
-  for (std::vector<struct AttributeInformation>::const_iterator j = information->attributes.begin ();
-       j != information->attributes.end (); j++)
-    {
-      if (j->name == name)
-        {
-          NS_FATAL_ERROR ("Registered the same attribute twice name=\""<<name<<"\" in TypeId=\""<<information->name<<"\"");
-          return;
-        }
-    }
-  struct AttributeInformation param;
-  param.name = name;
-  param.help = help;
-  param.flags = flags;
-  param.initialValue = initialValue;
-  param.param = spec;
-  param.checker = checker;
-  information->attributes.push_back (param);
-}
-
-
-uint32_t 
-IidManager::GetAttributeListN (uint16_t uid) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  return information->attributes.size ();
-}
-std::string 
-IidManager::GetAttributeName (uint16_t uid, uint32_t i) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  NS_ASSERT (i < information->attributes.size ());
-  return information->attributes[i].name;
-}
-std::string 
-IidManager::GetAttributeHelp (uint16_t uid, uint32_t i) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  NS_ASSERT (i < information->attributes.size ());
-  return information->attributes[i].help;
-}
-uint32_t
-IidManager::GetAttributeFlags (uint16_t uid, uint32_t i) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  NS_ASSERT (i < information->attributes.size ());
-  return information->attributes[i].flags;
-}
-ns3::Attribute 
-IidManager::GetAttributeInitialValue (uint16_t uid, uint32_t i) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  NS_ASSERT (i < information->attributes.size ());
-  return information->attributes[i].initialValue;
-}
-ns3::Ptr<const ns3::AttributeAccessor>
-IidManager::GetAttributeAccessor (uint16_t uid, uint32_t i) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  NS_ASSERT (i < information->attributes.size ());
-  return information->attributes[i].param;
-}
-ns3::Ptr<const ns3::AttributeChecker>
-IidManager::GetAttributeChecker (uint16_t uid, uint32_t i) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  NS_ASSERT (i < information->attributes.size ());
-  return information->attributes[i].checker;
-}
-
-void 
-IidManager::AddTraceSource (uint16_t uid,
-                            std::string name, 
-                            std::string help,
-                            ns3::Ptr<const ns3::TraceSourceAccessor> accessor)
-{
-  struct IidInformation *information  = LookupInformation (uid);
-  struct TraceSourceInformation source;
-  source.name = name;
-  source.help = help;
-  source.accessor = accessor;
-  information->traceSources.push_back (source);
-}
-uint32_t 
-IidManager::GetTraceSourceN (uint16_t uid) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  return information->traceSources.size ();
-}
-std::string 
-IidManager::GetTraceSourceName (uint16_t uid, uint32_t i) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  NS_ASSERT (i < information->traceSources.size ());
-  return information->traceSources[i].name;
-}
-std::string 
-IidManager::GetTraceSourceHelp (uint16_t uid, uint32_t i) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  NS_ASSERT (i < information->traceSources.size ());
-  return information->traceSources[i].help;
-}
-ns3::Ptr<const ns3::TraceSourceAccessor> 
-IidManager::GetTraceSourceAccessor (uint16_t uid, uint32_t i) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  NS_ASSERT (i < information->traceSources.size ());
-  return information->traceSources[i].accessor;
-}
-bool 
-IidManager::MustHideFromDocumentation (uint16_t uid) const
-{
-  struct IidInformation *information = LookupInformation (uid);
-  return information->mustHideFromDocumentation;
-}
-
-} // anonymous namespace
-
 namespace ns3 {
 
 /*********************************************************************
- *         The TypeId class
- *********************************************************************/
-
-TypeId::TypeId ()
-  : m_tid (0)
-{}
-
-TypeId::TypeId (const char *name)
-{
-  uint16_t uid = Singleton<IidManager>::Get ()->AllocateUid (name);
-  NS_ASSERT (uid != 0);
-  m_tid = uid;
-}
-
-
-TypeId::TypeId (uint16_t tid)
-  : m_tid (tid)
-{}
-TypeId::~TypeId ()
-{}
-TypeId 
-TypeId::LookupByName (std::string name)
-{
-  uint16_t uid = Singleton<IidManager>::Get ()->GetUid (name);
-  NS_ASSERT (uid != 0);
-  return TypeId (uid);
-}
-bool
-TypeId::LookupByNameFailSafe (std::string name, TypeId *tid)
-{
-  uint16_t uid = Singleton<IidManager>::Get ()->GetUid (name);
-  if (uid == 0)
-    {
-      return false;
-    }
-  *tid = TypeId (uid);
-  return true;
-}
-
-bool
-TypeId::LookupAttributeByFullName (std::string fullName, struct TypeId::AttributeInfo *info)
-{
-  std::string::size_type pos = fullName.rfind ("::");
-  if (pos == std::string::npos)
-    {
-      return 0;
-    }
-  std::string tidName = fullName.substr (0, pos);
-  std::string paramName = fullName.substr (pos+2, fullName.size () - (pos+2));
-  TypeId tid;
-  bool ok = LookupByNameFailSafe (tidName, &tid);
-  if (!ok)
-    {
-      return false;
-    }
-  return tid.LookupAttributeByName (paramName, info);
-}
-uint32_t 
-TypeId::GetRegisteredN (void)
-{
-  return Singleton<IidManager>::Get ()->GetRegisteredN ();
-}
-TypeId 
-TypeId::GetRegistered (uint32_t i)
-{
-  return TypeId (Singleton<IidManager>::Get ()->GetRegistered (i));
-}
-
-bool
-TypeId::LookupAttributeByName (std::string name, struct TypeId::AttributeInfo *info) const
-{
-  TypeId tid;
-  TypeId nextTid = *this;
-  do {
-    tid = nextTid;
-    for (uint32_t i = 0; i < tid.GetAttributeListN (); i++)
-      {
-        std::string paramName = tid.GetAttributeName (i);
-        if (paramName == name)
-          {
-            info->accessor = tid.GetAttributeAccessor (i);
-            info->flags = tid.GetAttributeFlags (i);
-            info->initialValue = tid.GetAttributeInitialValue (i);
-            info->checker = tid.GetAttributeChecker (i);
-            return true;
-          }
-      }
-    nextTid = tid.GetParent ();
-  } while (nextTid != tid);
-  return false;
-}
-
-TypeId 
-TypeId::SetParent (TypeId tid)
-{
-  Singleton<IidManager>::Get ()->SetParent (m_tid, tid.m_tid);
-  return *this;
-}
-TypeId 
-TypeId::SetGroupName (std::string groupName)
-{
-  Singleton<IidManager>::Get ()->SetGroupName (m_tid, groupName);
-  return *this;
-}
-TypeId 
-TypeId::SetTypeName (std::string typeName)
-{
-  Singleton<IidManager>::Get ()->SetTypeName (m_tid, typeName);
-  return *this;
-}
-TypeId 
-TypeId::GetParent (void) const
-{
-  uint16_t parent = Singleton<IidManager>::Get ()->GetParent (m_tid);
-  return TypeId (parent);
-}
-std::string 
-TypeId::GetGroupName (void) const
-{
-  std::string groupName = Singleton<IidManager>::Get ()->GetGroupName (m_tid);
-  return groupName;
-}
-std::string 
-TypeId::GetTypeName (void) const
-{
-  std::string typeName = Singleton<IidManager>::Get ()->GetTypeName (m_tid);
-  return typeName;
-}
-
-std::string 
-TypeId::GetName (void) const
-{
-  std::string name = Singleton<IidManager>::Get ()->GetName (m_tid);
-  return name;
-}
-
-bool 
-TypeId::HasConstructor (void) const
-{
-  bool hasConstructor = Singleton<IidManager>::Get ()->HasConstructor (m_tid);
-  return hasConstructor;
-}
-
-void
-TypeId::DoAddConstructor (Callback<ObjectBase *> cb)
-{
-  Singleton<IidManager>::Get ()->AddConstructor (m_tid, cb);
-}
-
-TypeId 
-TypeId::AddAttribute (std::string name,
-                      std::string help, 
-                      Attribute initialValue,
-                      Ptr<const AttributeAccessor> param,
-                      Ptr<const AttributeChecker> checker)
-{
-  Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, ATTR_SGC, initialValue, param, checker);
-  return *this;
-}
-
-TypeId 
-TypeId::AddAttribute (std::string name,
-                      std::string help, 
-                      uint32_t flags,
-                      Attribute initialValue,
-                      Ptr<const AttributeAccessor> param,
-                      Ptr<const AttributeChecker> checker)
-{
-  Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, flags, initialValue, param, checker);
-  return *this;
-}
-
-Callback<ObjectBase *> 
-TypeId::GetConstructor (void) const
-{
-  Callback<ObjectBase *>  cb = Singleton<IidManager>::Get ()->GetConstructor (m_tid);
-  return cb;
-}
-
-bool 
-TypeId::MustHideFromDocumentation (void) const
-{
-  bool mustHide = Singleton<IidManager>::Get ()->MustHideFromDocumentation (m_tid);
-  return mustHide;
-}
-
-uint32_t 
-TypeId::GetAttributeListN (void) const
-{
-  uint32_t n = Singleton<IidManager>::Get ()->GetAttributeListN (m_tid);
-  return n;
-}
-std::string 
-TypeId::GetAttributeName (uint32_t i) const
-{
-  std::string name = Singleton<IidManager>::Get ()->GetAttributeName (m_tid, i);
-  return name;
-}
-std::string 
-TypeId::GetAttributeHelp (uint32_t i) const
-{
-  std::string help = Singleton<IidManager>::Get ()->GetAttributeHelp (m_tid, i);
-  return help;
-}
-std::string 
-TypeId::GetAttributeFullName (uint32_t i) const
-{
-  return GetName () + "::" + GetAttributeName (i);
-}
-Attribute 
-TypeId::GetAttributeInitialValue (uint32_t i) const
-{
-  Attribute value = Singleton<IidManager>::Get ()->GetAttributeInitialValue (m_tid, i);
-  return value;
-}
-Ptr<const AttributeAccessor>
-TypeId::GetAttributeAccessor (uint32_t i) const
-{
-  // Used exclusively by the Object class.
-  Ptr<const AttributeAccessor> param = Singleton<IidManager>::Get ()->GetAttributeAccessor (m_tid, i);
-  return param;
-}
-uint32_t 
-TypeId::GetAttributeFlags (uint32_t i) const
-{
-  // Used exclusively by the Object class.
-  uint32_t flags = Singleton<IidManager>::Get ()->GetAttributeFlags (m_tid, i);
-  return flags;
-}
-Ptr<const AttributeChecker>
-TypeId::GetAttributeChecker (uint32_t i) const
-{
-  // Used exclusively by the Object class.
-  Ptr<const AttributeChecker> checker = Singleton<IidManager>::Get ()->GetAttributeChecker (m_tid, i);
-  return checker;
-}
-
-uint32_t 
-TypeId::GetTraceSourceN (void) const
-{
-  return Singleton<IidManager>::Get ()->GetTraceSourceN (m_tid);
-}
-std::string 
-TypeId::GetTraceSourceName (uint32_t i) const
-{
-  return Singleton<IidManager>::Get ()->GetTraceSourceName (m_tid, i);
-}
-std::string 
-TypeId::GetTraceSourceHelp (uint32_t i) const
-{
-  return Singleton<IidManager>::Get ()->GetTraceSourceHelp (m_tid, i);
-}
-Ptr<const TraceSourceAccessor> 
-TypeId::GetTraceSourceAccessor (uint32_t i) const
-{
-  return Singleton<IidManager>::Get ()->GetTraceSourceAccessor (m_tid, i);
-}
-
-TypeId 
-TypeId::AddTraceSource (std::string name,
-                        std::string help,
-                        Ptr<const TraceSourceAccessor> accessor)
-{
-  Singleton<IidManager>::Get ()->AddTraceSource (m_tid, name, help, accessor);
-  return *this;
-}
-
-TypeId 
-TypeId::HideFromDocumentation (void)
-{
-  Singleton<IidManager>::Get ()->HideFromDocumentation (m_tid);
-  return *this;
-}
-
-
-Ptr<const TraceSourceAccessor> 
-TypeId::LookupTraceSourceByName (std::string name) const
-{
-  TypeId tid;
-  TypeId nextTid = *this;
-  do {
-    tid = nextTid;
-    for (uint32_t i = 0; i < tid.GetTraceSourceN (); i++)
-      {
-        std::string srcName = tid.GetTraceSourceName (i);
-        if (srcName == name)
-          {
-            return tid.GetTraceSourceAccessor (i);
-          }
-      }
-    nextTid = tid.GetParent ();
-  } while (nextTid != tid);
-  return 0;
-}
-
-std::ostream & operator << (std::ostream &os, TypeId tid)
-{
-  os << tid.GetName ();
-  return os;
-}
-std::istream & operator >> (std::istream &is, TypeId &tid)
-{
-  std::string tidString;
-  is >> tidString;
-  bool ok = TypeId::LookupByNameFailSafe (tidString, &tid);
-  if (!ok)
-    {
-      is.setstate (std::ios_base::badbit);
-    }
-  return is;
-}
-
-
-ATTRIBUTE_HELPER_CPP (TypeId);
-
-bool operator == (TypeId a, TypeId b)
-{
-  return a.m_tid == b.m_tid;
-}
-
-bool operator != (TypeId a, TypeId b)
-{
-  return a.m_tid != b.m_tid;
-}
-
-/*********************************************************************
- *         The AttributeList container implementation
- *********************************************************************/
-
-AttributeList::AttributeList ()
-{}
-
-AttributeList::AttributeList (const AttributeList &o)
-{
-  for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++)
-    {
-      struct Attr attr;
-      attr.checker = i->checker;
-      attr.value = i->value.Copy ();
-      m_attributes.push_back (attr);
-    }
-}
-AttributeList &
-AttributeList::operator = (const AttributeList &o)
-{
-  Reset ();
-  for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++)
-    {
-      struct Attr attr;
-      attr.checker = i->checker;
-      attr.value = i->value.Copy ();
-      m_attributes.push_back (attr);
-    }
-  return *this;
-}
-AttributeList::~AttributeList ()
-{
-  Reset ();
-}
-
-void
-AttributeList::Set (std::string name, Attribute value)
-{
-  struct TypeId::AttributeInfo info;
-  bool ok = TypeId::LookupAttributeByFullName (name, &info);
-  if (!ok)
-    {
-      NS_FATAL_ERROR ("Could not find attribute "<<name);
-    }
-  ok = DoSet (&info, value);
-  if (!ok)
-    {
-      NS_FATAL_ERROR ("Could not set value for attribute "<<name);
-    }
-}
-bool 
-AttributeList::SetFailSafe (std::string name, Attribute value)
-{
-  struct TypeId::AttributeInfo info;
-  bool ok = TypeId::LookupAttributeByFullName (name, &info);
-  if (!ok)
-    {
-      return false;
-    }
-  ok = DoSet (&info, value);
-  return ok;
-}
-void
-AttributeList::SetWithTid (TypeId tid, std::string name, Attribute value)
-{
-  struct TypeId::AttributeInfo info;
-  bool ok = tid.LookupAttributeByName (name, &info);
-  if (!ok)
-    {
-      NS_FATAL_ERROR ("Could not find attribute "<<tid.GetName ()<<"::"<<name);
-    }
-  ok = DoSet (&info, value);
-  if (!ok)
-    {
-      NS_FATAL_ERROR ("Could not set value for attribute "<<tid.GetName ()<<"::"<<name);
-    }
-}
-
-void
-AttributeList::DoSetOne (Ptr<const AttributeChecker> checker, Attribute value)
-{
-  // get rid of any previous value stored in this
-  // vector of values.
-  for (Attrs::iterator k = m_attributes.begin (); k != m_attributes.end (); k++)
-    {
-      if (k->checker == checker)
-        {
-          m_attributes.erase (k);
-          break;
-        }
-    }
-  // store the new value.
-  struct Attr attr;
-  attr.checker = checker;
-  attr.value = value.Copy ();
-  m_attributes.push_back (attr);
-}
-bool
-AttributeList::DoSet (struct TypeId::AttributeInfo *info, Attribute value)
-{
-  if (info->checker == 0)
-    {
-      return false;
-    }
-  bool ok = info->checker->Check (value);
-  if (!ok)
-    {
-      // attempt to convert to string.
-      const StringValue *str = value.DynCast<const StringValue *> ();
-      if (str == 0)
-        {
-          return false;
-        }
-      // attempt to convert back to value.
-      Attribute v = info->checker->Create ();
-      ok = v.DeserializeFromString (str->Get ().Get (), info->checker);
-      if (!ok)
-        {
-          return false;
-        }
-      ok = info->checker->Check (v);
-      if (!ok)
-        {
-          return false;
-        }
-      value = v;
-    }
-  DoSetOne (info->checker, value);
-  return true;
-}
-void 
-AttributeList::Reset (void)
-{
-  m_attributes.clear ();
-}
-AttributeList *
-AttributeList::GetGlobal (void)
-{
-  return Singleton<AttributeList>::Get ();
-}
-
-std::string
-AttributeList::LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const
-{
-  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++)
-    {
-      TypeId tid = TypeId::GetRegistered (i);
-      for (uint32_t j = 0; j < tid.GetAttributeListN (); j++)
-        {
-          if (checker == tid.GetAttributeChecker (j))
-            {
-              return tid.GetAttributeFullName (j);
-            }
-        }
-    }
-  NS_FATAL_ERROR ("Could not find requested Accessor.");
-  // quiet compiler.
-  return "";
-}
-
-std::string 
-AttributeList::SerializeToString (void) const
-{
-  std::ostringstream oss;
-  for (Attrs::const_iterator i = m_attributes.begin (); i != m_attributes.end (); i++)
-    {
-      std::string name = LookupAttributeFullNameByChecker (i->checker);
-      oss << name << "=" << i->value.SerializeToString (i->checker);
-      if (i != m_attributes.end ())
-        {
-          oss << "|";
-        }
-    }  
-  return oss.str ();
-}
-bool 
-AttributeList::DeserializeFromString (std::string str)
-{
-  Reset ();
-
-  std::string::size_type cur;
-  cur = 0;
-  do {
-    std::string::size_type equal = str.find ("=", cur);
-    if (equal == std::string::npos)
-      {
-        // XXX: invalid attribute.
-        break;
-      }
-    else
-      {
-        std::string name = str.substr (cur, equal-cur);
-        struct TypeId::AttributeInfo info;
-        if (!TypeId::LookupAttributeByFullName (name, &info))
-          {
-            // XXX invalid name.
-            break;
-          }
-        else
-          {
-            std::string::size_type next = str.find ("|", cur);
-            std::string value;
-            if (next == std::string::npos)
-              {
-                value = str.substr (equal+1, str.size () - (equal+1));
-                cur = str.size ();
-              }
-            else
-              {
-                value = str.substr (equal+1, next - (equal+1));
-                cur++;
-              }
-            Attribute val = info.checker->Create ();
-            bool ok = val.DeserializeFromString (value, info.checker);
-            if (!ok)
-              {
-                // XXX invalid value
-                break;
-              }
-            else
-              {
-                DoSetOne (info.checker, val);
-              }
-          }
-      }
-  } while (cur != str.size ());
-
-  return true;
-}
-
-
-/*********************************************************************
  *         The Object implementation
  *********************************************************************/
 
--- a/src/core/object.h	Sun Mar 16 20:47:46 2008 +0100
+++ b/src/core/object.h	Sun Mar 16 20:55:18 2008 +0100
@@ -29,19 +29,7 @@
 #include "attribute.h"
 #include "object-base.h"
 #include "attribute-helper.h"
-
-/**
- * This macro should be invoked once for every class which
- * defines a new GetTypeId method.
- */
-#define NS_OBJECT_ENSURE_REGISTERED(type)       \
-  static struct X##type##RegistrationClass      \
-  {                                             \
-    X##type##RegistrationClass () {             \
-      ns3::TypeId tid = type::GetTypeId ();     \
-      tid.GetParent ();                         \
-    }                                           \
-} x_##type##RegistrationVariable
+#include "attribute-list.h"
 
 
 namespace ns3 {
@@ -54,363 +42,6 @@
 class TraceSourceAccessor;
 
 /**
- * \brief a unique identifier for an interface.
- *
- * This class records a lot of meta-information about a 
- * subclass of the Object base class:
- *  - the base class of the subclass
- *  - the set of accessible constructors in the subclass
- *  - the set of 'attributes' accessible in the subclass
- */
-class TypeId
-{
-public:
-  enum {
-    /**
-     * The attribute can be read
-     */
-    ATTR_GET = 1<<0,
-    /**
-     * The attribute can be written
-     */
-    ATTR_SET = 1<<1,
-    /**
-     * The attribute can be written at construction-time.
-     */
-    ATTR_CONSTRUCT = 1<<2,
-    /**
-     * The attribute can be read, and written at any time.
-     */
-    ATTR_SGC = ATTR_GET | ATTR_SET | ATTR_CONSTRUCT,
-  };
-
-  /**
-   * \param name the name of the requested TypeId
-   * \returns the unique id associated with the requested
-   *          name. 
-   *
-   * This method cannot fail: it will crash if the input 
-   * name is not a valid TypeId name.
-   */
-  static TypeId LookupByName (std::string name);
-  /**
-   * \param name the name of the requested TypeId
-   * \param tid a pointer to the TypeId instance where the 
-   *        result of this function should be stored.
-   * \returns true if the requested name was found, false otherwise.
-   */
-  static bool LookupByNameFailSafe (std::string name, TypeId *tid);
-
-  /**
-   * \returns the number of TypeId instances registered.
-   */
-  static uint32_t GetRegisteredN (void);
-  /**
-   * \param i index
-   * \returns the TypeId instance whose index is i.
-   */
-  static TypeId GetRegistered (uint32_t i);
-
-  /**
-   * \param name the name of the interface to construct.
-   *
-   * No two instances can share the same name. The name is expected to be
-   * the full c++ typename of associated c++ object.
-   */
-  TypeId (const char * name);
-
-  /**
-   * \returns the parent of this TypeId
-   *
-   * This method cannot fail. It will return itself
-   * if this TypeId has no parent. i.e., it is at the top
-   * of the TypeId hierarchy. Currently, this is the
-   * case for the TypeId associated to the Object class 
-   * only.
-   */
-  TypeId GetParent (void) const;
-
-  /**
-   * \returns the name of the group associated to this TypeId.
-   */
-  std::string GetGroupName (void) const;
-  /**
-   * \returns the fully-qualified C++ typename of this TypeId.
-   */
-  std::string GetTypeName (void) const;
-
-  /**
-   * \returns the name of this interface.
-   */
-  std::string GetName (void) const;
-
-  /**
-   * \returns true if this TypeId has a constructor
-   */
-  bool HasConstructor (void) const;
-
-  /**
-   * \returns the number of attributes associated to this TypeId
-   */
-  uint32_t GetAttributeListN (void) const;
-  /**
-   * \param i index into attribute array
-   * \returns the name associated to the attribute whose
-   *          index is i.
-   */
-  std::string GetAttributeName (uint32_t i) const;
-  std::string GetAttributeHelp (uint32_t i) const;
-  /**
-   * \param i index into attribute array
-   * \returns the full name associated to the attribute whose
-   *          index is i.
-   */
-  std::string GetAttributeFullName (uint32_t i) const;
-
-  Attribute GetAttributeInitialValue (uint32_t i) const;
-  uint32_t GetAttributeFlags (uint32_t i) const;
-  Ptr<const AttributeChecker> GetAttributeChecker (uint32_t i) const;
-
-
-  uint32_t GetTraceSourceN (void) const;
-  std::string GetTraceSourceName (uint32_t i) const;
-  std::string GetTraceSourceHelp (uint32_t i) const;
-  Ptr<const TraceSourceAccessor> GetTraceSourceAccessor (uint32_t i) const;
-
-  Callback<ObjectBase *> GetConstructor (void) const;
-
-  bool MustHideFromDocumentation (void) const;
-
-  /**
-   * \param tid the TypeId of the base class.
-   * \return this TypeId instance.
-   *
-   * Record in this TypeId which TypeId is the TypeId
-   * of the base class of the subclass.
-   */
-  TypeId SetParent (TypeId tid);
-  /**
-   * \return this TypeId instance.
-   *
-   * Record in this TypeId which TypeId is the TypeId
-   * of the base class of the subclass.
-   */
-  template <typename T>
-  TypeId SetParent (void);
-
-  /**
-   * \param groupName the name of the group this TypeId belongs to.
-   * \returns this TypeId instance.
-   *
-   * The group name is purely an advisory information used to 
-   * group together types according to a user-specific grouping
-   * scheme.
-   */
-  TypeId SetGroupName (std::string groupName);
-  
-  /**
-   * \param typeName the fully-qualified C++ typename of this TypeId.
-   * \returns this TypeId instance.
-   */
-  TypeId SetTypeName (std::string typeName);
-
-  /**
-   * \returns this TypeId instance
-   *
-   * Record in this TypeId the fact that the default constructor
-   * is accessible.
-   */
-  template <typename T>
-  TypeId AddConstructor (void);
-
-  /**
-   * \param name the name of the new attribute
-   * \param help some help text which describes the purpose of this
-   *        attribute.
-   * \param initialValue the initial value for this attribute.
-   * \param accessor an instance of the associated AttributeAccessor subclass.
-   * \param checker an instance of the associated AttributeChecker subclass.
-   * \returns this TypeId instance
-   *
-   * Record in this TypeId the fact that a new attribute exists.
-   */
-  TypeId AddAttribute (std::string name,
-                       std::string help, 
-                       Attribute initialValue,
-                       Ptr<const AttributeAccessor> accessor,
-                       Ptr<const AttributeChecker> checker);
-
-  /**
-   * \param name the name of the new attribute
-   * \param help some help text which describes the purpose of this
-   *        attribute
-   * \param flags flags which describe how this attribute can be read and/or written.
-   * \param initialValue the initial value for this attribute.
-   * \param accessor an instance of the associated AttributeAccessor subclass.
-   * \param checker an instance of the associated AttributeChecker subclass.
-   * \returns this TypeId instance
-   *
-   * Record in this TypeId the fact that a new attribute exists.
-   */
-  TypeId AddAttribute (std::string name,
-                       std::string help, 
-                       uint32_t flags,
-                       Attribute initialValue,
-                       Ptr<const AttributeAccessor> accessor,
-                       Ptr<const AttributeChecker> checker);
-
-  /**
-   * \param name the name of the new trace source
-   * \param help some help text which describes the purpose of this
-   *        trace source.
-   * \param accessor a pointer to a TraceSourceAccessor which can be
-   *        used to connect/disconnect sinks to this trace source.
-   * \returns this TypeId instance.
-   */
-  TypeId AddTraceSource (std::string name,
-                         std::string help,
-                         Ptr<const TraceSourceAccessor> accessor);
-
-  TypeId HideFromDocumentation (void);
-
-  /**
-   * \brief store together a set of attribute properties.
-   */
-  struct AttributeInfo {
-    // The accessor associated to the attribute.
-    Ptr<const AttributeAccessor> accessor;
-    // The initial value associated to the attribute.
-    Attribute initialValue;
-    // The set of access control flags associated to the attribute.
-    uint32_t flags;
-    // The checker associated to the attribute.
-    Ptr<const AttributeChecker> checker;
-  };
-  /**
-   * \param name the name of the requested attribute
-   * \param info a pointer to the TypeId::AttributeInfo data structure
-   *        where the result value of this method will be stored.
-   * \returns true if the requested attribute could be found, false otherwise.
-   */
-  bool LookupAttributeByName (std::string name, struct AttributeInfo *info) const;
-
-
-  // construct an invalid TypeId.
-  TypeId ();
-  ~TypeId ();
-
-  ATTRIBUTE_HELPER_HEADER_1 (TypeId);
-private:
-  friend class Object;
-  friend class AttributeList;
-  friend bool operator == (TypeId a, TypeId b);
-  friend bool operator != (TypeId a, TypeId b);
-
-
-  Ptr<const TraceSourceAccessor> LookupTraceSourceByName (std::string name) const;
-
-  /**
-   * \param fullName the full name of the requested attribute
-   * \param info a pointer to the TypeId::AttributeInfo data structure
-   *        where the result value of this method will be stored.
-   * \returns the Accessor associated to the requested attribute
-   */
-  static bool LookupAttributeByFullName (std::string fullName, struct AttributeInfo *info);
-
-  explicit TypeId (uint16_t tid);
-  void DoAddConstructor (Callback<ObjectBase *> callback);
-  Ptr<const AttributeAccessor> GetAttributeAccessor (uint32_t i) const;
-  
-  uint16_t m_tid;
-};
-
-std::ostream & operator << (std::ostream &os, TypeId tid);
-std::istream & operator >> (std::istream &is, TypeId &tid);
-
-ATTRIBUTE_HELPER_HEADER_2 (TypeId);
-
-/**
- * \brief a container of attributes to be used during object's construction
- *        and in ns3::Object::Set.
- *
- */
-class AttributeList
-{
-public:
-  AttributeList ();
-  AttributeList (const AttributeList &o);
-  AttributeList &operator = (const AttributeList &o);
-  ~AttributeList ();
-  /**
-   * \param name the full name of the attribute to set
-   * \param value the value to set
-   *
-   * This method checks that a attribute with the requested
-   * name exists and that the value specified is an acceptable
-   * value of that attribute. If any of these checks fails,
-   * the program terminates with a message.
-   */
-  void Set (std::string name, Attribute value);
-  /**
-   * \param name the full name of the attribute to set
-   * \param value the value to set
-   * \returns true if the requested attribute exists and could be
-   *          stored, false otherwise.
-   */
-  bool SetFailSafe (std::string name, Attribute value);
-  /**
-   * \param tid the TypeId associated to this attribute
-   * \param name the name (not full!) of the attribute
-   * \param value the value to set
-   *
-   * This method checks that a attribute with the requested
-   * name exists and that the value specified is an acceptable
-   * value of that attribute. If any of these checks fails,
-   * the program terminates with a message.
-   */
-  void SetWithTid (TypeId tid, std::string name, Attribute value);
-
-  /**
-   * Clear the content of this instance.
-   */
-  void Reset (void);
-
-  /**
-   * \returns the global attribute container
-   *
-   * The global attribute container can be used to specify
-   * a set of attribute values without having to re-specify
-   * them for each object when it is created. This container
-   * is checked only during object construction and 
-   * it is always checked last, after any per-object
-   * container is checked.
-   */
-  static AttributeList *GetGlobal (void);
-
-  // XXX: untested.
-  std::string SerializeToString (void) const;
-  bool DeserializeFromString (std::string value);
-private:
-  friend class Object;
-  struct Attr {
-    Ptr<const AttributeChecker> checker;
-    Attribute value;
-  };
-  typedef std::vector<struct Attr> Attrs;
-  typedef Attrs::iterator Iterator;
-  typedef Attrs::const_iterator CIterator;
-
-
-
-  bool DoSet (struct TypeId::AttributeInfo *info, Attribute param);
-  void DoSetOne (Ptr<const AttributeChecker> checker, Attribute param);
-  std::string LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const;
-
-  Attrs m_attributes;
-};
-
-
-/**
  * \brief a base class which provides memory management and object aggregation
  *
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/type-id.cc	Sun Mar 16 20:55:18 2008 +0100
@@ -0,0 +1,687 @@
+#include "type-id.h"
+#include "singleton.h"
+#include "trace-source-accessor.h"
+#include <vector>
+#include <sstream>
+
+/*********************************************************************
+ *         Helper code
+ *********************************************************************/
+
+namespace {
+
+class IidManager
+{
+public:
+  IidManager ();
+  uint16_t AllocateUid (std::string name);
+  void SetParent (uint16_t uid, uint16_t parent);
+  void SetTypeName (uint16_t uid, std::string typeName);
+  void SetGroupName (uint16_t uid, std::string groupName);
+  void AddConstructor (uint16_t uid, ns3::Callback<ns3::ObjectBase *> callback);
+  void HideFromDocumentation (uint16_t uid);
+  uint16_t GetUid (std::string name) const;
+  std::string GetName (uint16_t uid) const;
+  uint16_t GetParent (uint16_t uid) const;
+  std::string GetTypeName (uint16_t uid) const;
+  std::string GetGroupName (uint16_t uid) const;
+  ns3::Callback<ns3::ObjectBase *> GetConstructor (uint16_t uid) const;
+  bool HasConstructor (uint16_t uid) const;
+  uint32_t GetRegisteredN (void) const;
+  uint16_t GetRegistered (uint32_t i) const;
+  void AddAttribute (uint16_t uid, 
+                     std::string name,
+                     std::string help, 
+                     uint32_t flags,
+                     ns3::Attribute initialValue,
+                     ns3::Ptr<const ns3::AttributeAccessor> spec,
+                     ns3::Ptr<const ns3::AttributeChecker> checker);
+  uint32_t GetAttributeListN (uint16_t uid) const;
+  std::string GetAttributeName (uint16_t uid, uint32_t i) const;
+  std::string GetAttributeHelp (uint16_t uid, uint32_t i) const;
+  uint32_t GetAttributeFlags (uint16_t uid, uint32_t i) const;
+  ns3::Attribute GetAttributeInitialValue (uint16_t uid, uint32_t i) const;
+  ns3::Ptr<const ns3::AttributeAccessor> GetAttributeAccessor (uint16_t uid, uint32_t i) const;
+  ns3::Ptr<const ns3::AttributeChecker> GetAttributeChecker (uint16_t uid, uint32_t i) const;
+  void AddTraceSource (uint16_t uid,
+                       std::string name, 
+                       std::string help,
+                       ns3::Ptr<const ns3::TraceSourceAccessor> accessor);
+  uint32_t GetTraceSourceN (uint16_t uid) const;
+  std::string GetTraceSourceName (uint16_t uid, uint32_t i) const;
+  std::string GetTraceSourceHelp (uint16_t uid, uint32_t i) const;
+  ns3::Ptr<const ns3::TraceSourceAccessor> GetTraceSourceAccessor (uint16_t uid, uint32_t i) const;
+  bool MustHideFromDocumentation (uint16_t uid) const;
+
+private:
+  struct AttributeInformation {
+    std::string name;
+    std::string help;
+    uint32_t flags;
+    ns3::Attribute initialValue;
+    ns3::Ptr<const ns3::AttributeAccessor> param;
+    ns3::Ptr<const ns3::AttributeChecker> checker;
+  };
+  struct TraceSourceInformation {
+    std::string name;
+    std::string help;
+    ns3::Ptr<const ns3::TraceSourceAccessor> accessor;
+  };
+  struct IidInformation {
+    std::string name;
+    uint16_t parent;
+    std::string typeName;
+    std::string groupName;
+    bool hasConstructor;
+    ns3::Callback<ns3::ObjectBase *> constructor;
+    bool mustHideFromDocumentation;
+    std::vector<struct AttributeInformation> attributes;
+    std::vector<struct TraceSourceInformation> traceSources;
+  };
+  typedef std::vector<struct IidInformation>::const_iterator Iterator;
+
+  struct IidManager::IidInformation *LookupInformation (uint16_t uid) const;
+
+  std::vector<struct IidInformation> m_information;
+};
+
+IidManager::IidManager ()
+{}
+
+uint16_t 
+IidManager::AllocateUid (std::string name)
+{
+  uint16_t j = 1;
+  for (Iterator i = m_information.begin (); i != m_information.end (); i++)
+    {
+      if (i->name == name)
+        {
+          NS_FATAL_ERROR ("Trying to allocate twice the same uid: " << name);
+          return 0;
+        }
+      j++;
+    }
+  struct IidInformation information;
+  information.name = name;
+  information.parent = 0;
+  information.typeName = "";
+  information.groupName = "";
+  information.hasConstructor = false;
+  information.mustHideFromDocumentation = false;
+  m_information.push_back (information);
+  uint32_t uid = m_information.size ();
+  NS_ASSERT (uid <= 0xffff);
+  return uid;
+}
+
+struct IidManager::IidInformation *
+IidManager::LookupInformation (uint16_t uid) const
+{
+  NS_ASSERT (uid <= m_information.size ());
+  return const_cast<struct IidInformation *> (&m_information[uid-1]);
+}
+
+void 
+IidManager::SetParent (uint16_t uid, uint16_t parent)
+{
+  NS_ASSERT (parent <= m_information.size ());
+  struct IidInformation *information = LookupInformation (uid);
+  information->parent = parent;
+}
+void 
+IidManager::SetTypeName (uint16_t uid, std::string typeName)
+{
+  struct IidInformation *information = LookupInformation (uid);
+  information->typeName = typeName;
+}
+void 
+IidManager::SetGroupName (uint16_t uid, std::string groupName)
+{
+  struct IidInformation *information = LookupInformation (uid);
+  information->groupName = groupName;
+}
+void
+IidManager::HideFromDocumentation (uint16_t uid)
+{
+  struct IidInformation *information = LookupInformation (uid);
+  information->mustHideFromDocumentation = true;
+}
+
+void 
+IidManager::AddConstructor (uint16_t uid, ns3::Callback<ns3::ObjectBase *> callback)
+{
+  struct IidInformation *information = LookupInformation (uid);
+  if (information->hasConstructor)
+    {
+      NS_FATAL_ERROR (information->name<<" already has a constructor.");
+    }
+  information->hasConstructor = true;
+  information->constructor = callback;
+}
+
+uint16_t 
+IidManager::GetUid (std::string name) const
+{
+  uint32_t j = 1;
+  for (Iterator i = m_information.begin (); i != m_information.end (); i++)
+    {
+      if (i->name == name)
+        {
+          NS_ASSERT (j <= 0xffff);
+          return j;
+        }
+      j++;
+    }
+  return 0;
+}
+std::string 
+IidManager::GetName (uint16_t uid) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  return information->name;
+}
+uint16_t 
+IidManager::GetParent (uint16_t uid) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  return information->parent;
+}
+std::string 
+IidManager::GetTypeName (uint16_t uid) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  return information->typeName;
+}
+std::string 
+IidManager::GetGroupName (uint16_t uid) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  return information->groupName;
+}
+
+ns3::Callback<ns3::ObjectBase *> 
+IidManager::GetConstructor (uint16_t uid) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  if (!information->hasConstructor)
+    {
+      NS_FATAL_ERROR ("Requested constructor for "<<information->name<<" but it does not have one.");
+    }
+  return information->constructor;
+}
+
+bool 
+IidManager::HasConstructor (uint16_t uid) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  return information->hasConstructor;
+}
+
+uint32_t 
+IidManager::GetRegisteredN (void) const
+{
+  return m_information.size ();
+}
+uint16_t 
+IidManager::GetRegistered (uint32_t i) const
+{
+  return i + 1;
+}
+
+void 
+IidManager::AddAttribute (uint16_t uid, 
+                          std::string name,
+                          std::string help, 
+                          uint32_t flags,
+                          ns3::Attribute initialValue,
+                          ns3::Ptr<const ns3::AttributeAccessor> spec,
+                          ns3::Ptr<const ns3::AttributeChecker> checker)
+{
+  struct IidInformation *information = LookupInformation (uid);
+  for (std::vector<struct AttributeInformation>::const_iterator j = information->attributes.begin ();
+       j != information->attributes.end (); j++)
+    {
+      if (j->name == name)
+        {
+          NS_FATAL_ERROR ("Registered the same attribute twice name=\""<<name<<"\" in TypeId=\""<<information->name<<"\"");
+          return;
+        }
+    }
+  struct AttributeInformation param;
+  param.name = name;
+  param.help = help;
+  param.flags = flags;
+  param.initialValue = initialValue;
+  param.param = spec;
+  param.checker = checker;
+  information->attributes.push_back (param);
+}
+
+
+uint32_t 
+IidManager::GetAttributeListN (uint16_t uid) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  return information->attributes.size ();
+}
+std::string 
+IidManager::GetAttributeName (uint16_t uid, uint32_t i) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->attributes.size ());
+  return information->attributes[i].name;
+}
+std::string 
+IidManager::GetAttributeHelp (uint16_t uid, uint32_t i) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->attributes.size ());
+  return information->attributes[i].help;
+}
+uint32_t
+IidManager::GetAttributeFlags (uint16_t uid, uint32_t i) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->attributes.size ());
+  return information->attributes[i].flags;
+}
+ns3::Attribute 
+IidManager::GetAttributeInitialValue (uint16_t uid, uint32_t i) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->attributes.size ());
+  return information->attributes[i].initialValue;
+}
+ns3::Ptr<const ns3::AttributeAccessor>
+IidManager::GetAttributeAccessor (uint16_t uid, uint32_t i) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->attributes.size ());
+  return information->attributes[i].param;
+}
+ns3::Ptr<const ns3::AttributeChecker>
+IidManager::GetAttributeChecker (uint16_t uid, uint32_t i) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->attributes.size ());
+  return information->attributes[i].checker;
+}
+
+void 
+IidManager::AddTraceSource (uint16_t uid,
+                            std::string name, 
+                            std::string help,
+                            ns3::Ptr<const ns3::TraceSourceAccessor> accessor)
+{
+  struct IidInformation *information  = LookupInformation (uid);
+  struct TraceSourceInformation source;
+  source.name = name;
+  source.help = help;
+  source.accessor = accessor;
+  information->traceSources.push_back (source);
+}
+uint32_t 
+IidManager::GetTraceSourceN (uint16_t uid) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  return information->traceSources.size ();
+}
+std::string 
+IidManager::GetTraceSourceName (uint16_t uid, uint32_t i) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->traceSources.size ());
+  return information->traceSources[i].name;
+}
+std::string 
+IidManager::GetTraceSourceHelp (uint16_t uid, uint32_t i) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->traceSources.size ());
+  return information->traceSources[i].help;
+}
+ns3::Ptr<const ns3::TraceSourceAccessor> 
+IidManager::GetTraceSourceAccessor (uint16_t uid, uint32_t i) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->traceSources.size ());
+  return information->traceSources[i].accessor;
+}
+bool 
+IidManager::MustHideFromDocumentation (uint16_t uid) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  return information->mustHideFromDocumentation;
+}
+
+} // anonymous namespace
+
+namespace ns3 {
+
+/*********************************************************************
+ *         The TypeId class
+ *********************************************************************/
+
+TypeId::TypeId ()
+  : m_tid (0)
+{}
+
+TypeId::TypeId (const char *name)
+{
+  uint16_t uid = Singleton<IidManager>::Get ()->AllocateUid (name);
+  NS_ASSERT (uid != 0);
+  m_tid = uid;
+}
+
+
+TypeId::TypeId (uint16_t tid)
+  : m_tid (tid)
+{}
+TypeId::~TypeId ()
+{}
+TypeId 
+TypeId::LookupByName (std::string name)
+{
+  uint16_t uid = Singleton<IidManager>::Get ()->GetUid (name);
+  NS_ASSERT (uid != 0);
+  return TypeId (uid);
+}
+bool
+TypeId::LookupByNameFailSafe (std::string name, TypeId *tid)
+{
+  uint16_t uid = Singleton<IidManager>::Get ()->GetUid (name);
+  if (uid == 0)
+    {
+      return false;
+    }
+  *tid = TypeId (uid);
+  return true;
+}
+
+bool
+TypeId::LookupAttributeByFullName (std::string fullName, struct TypeId::AttributeInfo *info)
+{
+  std::string::size_type pos = fullName.rfind ("::");
+  if (pos == std::string::npos)
+    {
+      return 0;
+    }
+  std::string tidName = fullName.substr (0, pos);
+  std::string paramName = fullName.substr (pos+2, fullName.size () - (pos+2));
+  TypeId tid;
+  bool ok = LookupByNameFailSafe (tidName, &tid);
+  if (!ok)
+    {
+      return false;
+    }
+  return tid.LookupAttributeByName (paramName, info);
+}
+uint32_t 
+TypeId::GetRegisteredN (void)
+{
+  return Singleton<IidManager>::Get ()->GetRegisteredN ();
+}
+TypeId 
+TypeId::GetRegistered (uint32_t i)
+{
+  return TypeId (Singleton<IidManager>::Get ()->GetRegistered (i));
+}
+
+bool
+TypeId::LookupAttributeByName (std::string name, struct TypeId::AttributeInfo *info) const
+{
+  TypeId tid;
+  TypeId nextTid = *this;
+  do {
+    tid = nextTid;
+    for (uint32_t i = 0; i < tid.GetAttributeListN (); i++)
+      {
+        std::string paramName = tid.GetAttributeName (i);
+        if (paramName == name)
+          {
+            info->accessor = tid.GetAttributeAccessor (i);
+            info->flags = tid.GetAttributeFlags (i);
+            info->initialValue = tid.GetAttributeInitialValue (i);
+            info->checker = tid.GetAttributeChecker (i);
+            return true;
+          }
+      }
+    nextTid = tid.GetParent ();
+  } while (nextTid != tid);
+  return false;
+}
+
+TypeId 
+TypeId::SetParent (TypeId tid)
+{
+  Singleton<IidManager>::Get ()->SetParent (m_tid, tid.m_tid);
+  return *this;
+}
+TypeId 
+TypeId::SetGroupName (std::string groupName)
+{
+  Singleton<IidManager>::Get ()->SetGroupName (m_tid, groupName);
+  return *this;
+}
+TypeId 
+TypeId::SetTypeName (std::string typeName)
+{
+  Singleton<IidManager>::Get ()->SetTypeName (m_tid, typeName);
+  return *this;
+}
+TypeId 
+TypeId::GetParent (void) const
+{
+  uint16_t parent = Singleton<IidManager>::Get ()->GetParent (m_tid);
+  return TypeId (parent);
+}
+std::string 
+TypeId::GetGroupName (void) const
+{
+  std::string groupName = Singleton<IidManager>::Get ()->GetGroupName (m_tid);
+  return groupName;
+}
+std::string 
+TypeId::GetTypeName (void) const
+{
+  std::string typeName = Singleton<IidManager>::Get ()->GetTypeName (m_tid);
+  return typeName;
+}
+
+std::string 
+TypeId::GetName (void) const
+{
+  std::string name = Singleton<IidManager>::Get ()->GetName (m_tid);
+  return name;
+}
+
+bool 
+TypeId::HasConstructor (void) const
+{
+  bool hasConstructor = Singleton<IidManager>::Get ()->HasConstructor (m_tid);
+  return hasConstructor;
+}
+
+void
+TypeId::DoAddConstructor (Callback<ObjectBase *> cb)
+{
+  Singleton<IidManager>::Get ()->AddConstructor (m_tid, cb);
+}
+
+TypeId 
+TypeId::AddAttribute (std::string name,
+                      std::string help, 
+                      Attribute initialValue,
+                      Ptr<const AttributeAccessor> param,
+                      Ptr<const AttributeChecker> checker)
+{
+  Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, ATTR_SGC, initialValue, param, checker);
+  return *this;
+}
+
+TypeId 
+TypeId::AddAttribute (std::string name,
+                      std::string help, 
+                      uint32_t flags,
+                      Attribute initialValue,
+                      Ptr<const AttributeAccessor> param,
+                      Ptr<const AttributeChecker> checker)
+{
+  Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, flags, initialValue, param, checker);
+  return *this;
+}
+
+Callback<ObjectBase *> 
+TypeId::GetConstructor (void) const
+{
+  Callback<ObjectBase *>  cb = Singleton<IidManager>::Get ()->GetConstructor (m_tid);
+  return cb;
+}
+
+bool 
+TypeId::MustHideFromDocumentation (void) const
+{
+  bool mustHide = Singleton<IidManager>::Get ()->MustHideFromDocumentation (m_tid);
+  return mustHide;
+}
+
+uint32_t 
+TypeId::GetAttributeListN (void) const
+{
+  uint32_t n = Singleton<IidManager>::Get ()->GetAttributeListN (m_tid);
+  return n;
+}
+std::string 
+TypeId::GetAttributeName (uint32_t i) const
+{
+  std::string name = Singleton<IidManager>::Get ()->GetAttributeName (m_tid, i);
+  return name;
+}
+std::string 
+TypeId::GetAttributeHelp (uint32_t i) const
+{
+  std::string help = Singleton<IidManager>::Get ()->GetAttributeHelp (m_tid, i);
+  return help;
+}
+std::string 
+TypeId::GetAttributeFullName (uint32_t i) const
+{
+  return GetName () + "::" + GetAttributeName (i);
+}
+Attribute 
+TypeId::GetAttributeInitialValue (uint32_t i) const
+{
+  Attribute value = Singleton<IidManager>::Get ()->GetAttributeInitialValue (m_tid, i);
+  return value;
+}
+Ptr<const AttributeAccessor>
+TypeId::GetAttributeAccessor (uint32_t i) const
+{
+  // Used exclusively by the Object class.
+  Ptr<const AttributeAccessor> param = Singleton<IidManager>::Get ()->GetAttributeAccessor (m_tid, i);
+  return param;
+}
+uint32_t 
+TypeId::GetAttributeFlags (uint32_t i) const
+{
+  // Used exclusively by the Object class.
+  uint32_t flags = Singleton<IidManager>::Get ()->GetAttributeFlags (m_tid, i);
+  return flags;
+}
+Ptr<const AttributeChecker>
+TypeId::GetAttributeChecker (uint32_t i) const
+{
+  // Used exclusively by the Object class.
+  Ptr<const AttributeChecker> checker = Singleton<IidManager>::Get ()->GetAttributeChecker (m_tid, i);
+  return checker;
+}
+
+uint32_t 
+TypeId::GetTraceSourceN (void) const
+{
+  return Singleton<IidManager>::Get ()->GetTraceSourceN (m_tid);
+}
+std::string 
+TypeId::GetTraceSourceName (uint32_t i) const
+{
+  return Singleton<IidManager>::Get ()->GetTraceSourceName (m_tid, i);
+}
+std::string 
+TypeId::GetTraceSourceHelp (uint32_t i) const
+{
+  return Singleton<IidManager>::Get ()->GetTraceSourceHelp (m_tid, i);
+}
+Ptr<const TraceSourceAccessor> 
+TypeId::GetTraceSourceAccessor (uint32_t i) const
+{
+  return Singleton<IidManager>::Get ()->GetTraceSourceAccessor (m_tid, i);
+}
+
+TypeId 
+TypeId::AddTraceSource (std::string name,
+                        std::string help,
+                        Ptr<const TraceSourceAccessor> accessor)
+{
+  Singleton<IidManager>::Get ()->AddTraceSource (m_tid, name, help, accessor);
+  return *this;
+}
+
+TypeId 
+TypeId::HideFromDocumentation (void)
+{
+  Singleton<IidManager>::Get ()->HideFromDocumentation (m_tid);
+  return *this;
+}
+
+
+Ptr<const TraceSourceAccessor> 
+TypeId::LookupTraceSourceByName (std::string name) const
+{
+  TypeId tid;
+  TypeId nextTid = *this;
+  do {
+    tid = nextTid;
+    for (uint32_t i = 0; i < tid.GetTraceSourceN (); i++)
+      {
+        std::string srcName = tid.GetTraceSourceName (i);
+        if (srcName == name)
+          {
+            return tid.GetTraceSourceAccessor (i);
+          }
+      }
+    nextTid = tid.GetParent ();
+  } while (nextTid != tid);
+  return 0;
+}
+
+std::ostream & operator << (std::ostream &os, TypeId tid)
+{
+  os << tid.GetName ();
+  return os;
+}
+std::istream & operator >> (std::istream &is, TypeId &tid)
+{
+  std::string tidString;
+  is >> tidString;
+  bool ok = TypeId::LookupByNameFailSafe (tidString, &tid);
+  if (!ok)
+    {
+      is.setstate (std::ios_base::badbit);
+    }
+  return is;
+}
+
+
+ATTRIBUTE_HELPER_CPP (TypeId);
+
+bool operator == (TypeId a, TypeId b)
+{
+  return a.m_tid == b.m_tid;
+}
+
+bool operator != (TypeId a, TypeId b)
+{
+  return a.m_tid != b.m_tid;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/type-id.h	Sun Mar 16 20:55:18 2008 +0100
@@ -0,0 +1,292 @@
+#ifndef TYPE_ID_H
+#define TYPE_ID_H
+
+#include "attribute.h"
+#include "attribute-accessor-helper.h"
+#include "attribute-helper.h"
+#include "callback.h"
+#include <string>
+#include <stdint.h>
+
+namespace ns3 {
+
+class ObjectBase;
+class TraceSourceAccessor;
+
+/**
+ * \brief a unique identifier for an interface.
+ *
+ * This class records a lot of meta-information about a 
+ * subclass of the Object base class:
+ *  - the base class of the subclass
+ *  - the set of accessible constructors in the subclass
+ *  - the set of 'attributes' accessible in the subclass
+ */
+class TypeId
+{
+public:
+  enum {
+    /**
+     * The attribute can be read
+     */
+    ATTR_GET = 1<<0,
+    /**
+     * The attribute can be written
+     */
+    ATTR_SET = 1<<1,
+    /**
+     * The attribute can be written at construction-time.
+     */
+    ATTR_CONSTRUCT = 1<<2,
+    /**
+     * The attribute can be read, and written at any time.
+     */
+    ATTR_SGC = ATTR_GET | ATTR_SET | ATTR_CONSTRUCT,
+  };
+
+  /**
+   * \param name the name of the requested TypeId
+   * \returns the unique id associated with the requested
+   *          name. 
+   *
+   * This method cannot fail: it will crash if the input 
+   * name is not a valid TypeId name.
+   */
+  static TypeId LookupByName (std::string name);
+  /**
+   * \param name the name of the requested TypeId
+   * \param tid a pointer to the TypeId instance where the 
+   *        result of this function should be stored.
+   * \returns true if the requested name was found, false otherwise.
+   */
+  static bool LookupByNameFailSafe (std::string name, TypeId *tid);
+
+  /**
+   * \returns the number of TypeId instances registered.
+   */
+  static uint32_t GetRegisteredN (void);
+  /**
+   * \param i index
+   * \returns the TypeId instance whose index is i.
+   */
+  static TypeId GetRegistered (uint32_t i);
+
+  /**
+   * \param name the name of the interface to construct.
+   *
+   * No two instances can share the same name. The name is expected to be
+   * the full c++ typename of associated c++ object.
+   */
+  TypeId (const char * name);
+
+  /**
+   * \returns the parent of this TypeId
+   *
+   * This method cannot fail. It will return itself
+   * if this TypeId has no parent. i.e., it is at the top
+   * of the TypeId hierarchy. Currently, this is the
+   * case for the TypeId associated to the Object class 
+   * only.
+   */
+  TypeId GetParent (void) const;
+
+  /**
+   * \returns the name of the group associated to this TypeId.
+   */
+  std::string GetGroupName (void) const;
+  /**
+   * \returns the fully-qualified C++ typename of this TypeId.
+   */
+  std::string GetTypeName (void) const;
+
+  /**
+   * \returns the name of this interface.
+   */
+  std::string GetName (void) const;
+
+  /**
+   * \returns true if this TypeId has a constructor
+   */
+  bool HasConstructor (void) const;
+
+  /**
+   * \returns the number of attributes associated to this TypeId
+   */
+  uint32_t GetAttributeListN (void) const;
+  /**
+   * \param i index into attribute array
+   * \returns the name associated to the attribute whose
+   *          index is i.
+   */
+  std::string GetAttributeName (uint32_t i) const;
+  std::string GetAttributeHelp (uint32_t i) const;
+  /**
+   * \param i index into attribute array
+   * \returns the full name associated to the attribute whose
+   *          index is i.
+   */
+  std::string GetAttributeFullName (uint32_t i) const;
+
+  Attribute GetAttributeInitialValue (uint32_t i) const;
+  uint32_t GetAttributeFlags (uint32_t i) const;
+  Ptr<const AttributeChecker> GetAttributeChecker (uint32_t i) const;
+
+
+  uint32_t GetTraceSourceN (void) const;
+  std::string GetTraceSourceName (uint32_t i) const;
+  std::string GetTraceSourceHelp (uint32_t i) const;
+  Ptr<const TraceSourceAccessor> GetTraceSourceAccessor (uint32_t i) const;
+  Ptr<const AttributeAccessor> GetAttributeAccessor (uint32_t i) const;
+
+  Callback<ObjectBase *> GetConstructor (void) const;
+
+  bool MustHideFromDocumentation (void) const;
+
+  /**
+   * \param tid the TypeId of the base class.
+   * \return this TypeId instance.
+   *
+   * Record in this TypeId which TypeId is the TypeId
+   * of the base class of the subclass.
+   */
+  TypeId SetParent (TypeId tid);
+  /**
+   * \return this TypeId instance.
+   *
+   * Record in this TypeId which TypeId is the TypeId
+   * of the base class of the subclass.
+   */
+  template <typename T>
+  TypeId SetParent (void);
+
+  /**
+   * \param groupName the name of the group this TypeId belongs to.
+   * \returns this TypeId instance.
+   *
+   * The group name is purely an advisory information used to 
+   * group together types according to a user-specific grouping
+   * scheme.
+   */
+  TypeId SetGroupName (std::string groupName);
+  
+  /**
+   * \param typeName the fully-qualified C++ typename of this TypeId.
+   * \returns this TypeId instance.
+   */
+  TypeId SetTypeName (std::string typeName);
+
+  /**
+   * \returns this TypeId instance
+   *
+   * Record in this TypeId the fact that the default constructor
+   * is accessible.
+   */
+  template <typename T>
+  TypeId AddConstructor (void);
+
+  /**
+   * \param name the name of the new attribute
+   * \param help some help text which describes the purpose of this
+   *        attribute.
+   * \param initialValue the initial value for this attribute.
+   * \param accessor an instance of the associated AttributeAccessor subclass.
+   * \param checker an instance of the associated AttributeChecker subclass.
+   * \returns this TypeId instance
+   *
+   * Record in this TypeId the fact that a new attribute exists.
+   */
+  TypeId AddAttribute (std::string name,
+                       std::string help, 
+                       Attribute initialValue,
+                       Ptr<const AttributeAccessor> accessor,
+                       Ptr<const AttributeChecker> checker);
+
+  /**
+   * \param name the name of the new attribute
+   * \param help some help text which describes the purpose of this
+   *        attribute
+   * \param flags flags which describe how this attribute can be read and/or written.
+   * \param initialValue the initial value for this attribute.
+   * \param accessor an instance of the associated AttributeAccessor subclass.
+   * \param checker an instance of the associated AttributeChecker subclass.
+   * \returns this TypeId instance
+   *
+   * Record in this TypeId the fact that a new attribute exists.
+   */
+  TypeId AddAttribute (std::string name,
+                       std::string help, 
+                       uint32_t flags,
+                       Attribute initialValue,
+                       Ptr<const AttributeAccessor> accessor,
+                       Ptr<const AttributeChecker> checker);
+
+  /**
+   * \param name the name of the new trace source
+   * \param help some help text which describes the purpose of this
+   *        trace source.
+   * \param accessor a pointer to a TraceSourceAccessor which can be
+   *        used to connect/disconnect sinks to this trace source.
+   * \returns this TypeId instance.
+   */
+  TypeId AddTraceSource (std::string name,
+                         std::string help,
+                         Ptr<const TraceSourceAccessor> accessor);
+
+  TypeId HideFromDocumentation (void);
+
+  /**
+   * \brief store together a set of attribute properties.
+   */
+  struct AttributeInfo {
+    // The accessor associated to the attribute.
+    Ptr<const AttributeAccessor> accessor;
+    // The initial value associated to the attribute.
+    Attribute initialValue;
+    // The set of access control flags associated to the attribute.
+    uint32_t flags;
+    // The checker associated to the attribute.
+    Ptr<const AttributeChecker> checker;
+  };
+  /**
+   * \param name the name of the requested attribute
+   * \param info a pointer to the TypeId::AttributeInfo data structure
+   *        where the result value of this method will be stored.
+   * \returns true if the requested attribute could be found, false otherwise.
+   */
+  bool LookupAttributeByName (std::string name, struct AttributeInfo *info) const;
+  Ptr<const TraceSourceAccessor> LookupTraceSourceByName (std::string name) const;
+
+
+  // construct an invalid TypeId.
+  TypeId ();
+  ~TypeId ();
+
+  ATTRIBUTE_HELPER_HEADER_1 (TypeId);
+private:
+  friend class AttributeList;
+  friend bool operator == (TypeId a, TypeId b);
+  friend bool operator != (TypeId a, TypeId b);
+
+
+  /**
+   * \param fullName the full name of the requested attribute
+   * \param info a pointer to the TypeId::AttributeInfo data structure
+   *        where the result value of this method will be stored.
+   * \returns the Accessor associated to the requested attribute
+   */
+  static bool LookupAttributeByFullName (std::string fullName, struct AttributeInfo *info);
+
+  explicit TypeId (uint16_t tid);
+  void DoAddConstructor (Callback<ObjectBase *> callback);
+  
+  uint16_t m_tid;
+};
+
+std::ostream & operator << (std::ostream &os, TypeId tid);
+std::istream & operator >> (std::istream &is, TypeId &tid);
+
+ATTRIBUTE_HELPER_HEADER_2 (TypeId);
+
+} // namespace ns3 
+
+#endif /* TYPE_ID_H */
--- a/src/core/wscript	Sun Mar 16 20:47:46 2008 +0100
+++ b/src/core/wscript	Sun Mar 16 20:55:18 2008 +0100
@@ -31,6 +31,8 @@
         'callback-test.cc',
         'log.cc',
         'breakpoint.cc',
+        'type-id.cc',
+        'attribute-list.cc',
         'object-base.cc',
         'ptr.cc',
         'object.cc',
@@ -73,6 +75,8 @@
         'empty.h',
         'callback.h',
         'object-base.h',
+        'type-id.h',
+        'attribute-list.h',
         'ptr.h',
         'object.h',
         'log.h',