attempt to perform correctly automatic conversions.
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Wed, 30 Jan 2008 19:13:06 +0100
changeset 2372 bf4efb9359c6
parent 2371 2118204a86e6
child 2373 73983ba47afc
attempt to perform correctly automatic conversions.
src/core/boolean-value.cc
src/core/boolean-value.h
src/core/object.cc
src/core/object.h
src/core/param-spec-helper.h
src/core/wscript
--- a/src/core/boolean-value.cc	Wed Jan 30 17:28:18 2008 +0100
+++ b/src/core/boolean-value.cc	Wed Jan 30 19:13:06 2008 +0100
@@ -1,4 +1,5 @@
 #include "boolean-value.h"
+#include "fatal-error.h"
 
 namespace ns3 {
 
@@ -56,5 +57,22 @@
       return false;
     }  
 }
+BooleanValue::BooleanValue (Ptr<const Value> value)
+{
+  const BooleanValue *v = dynamic_cast<const BooleanValue *> (PeekPointer (value));
+  if (v == 0)
+    {
+      NS_FATAL_ERROR ("assigning non-Boolean value to Boolean value.");
+    }
+  m_value = v->m_value;
+}
+BooleanValue::operator Ptr<Value> () const
+{
+  return Create<BooleanValue> (*this);
+}
+BooleanValue::operator Ptr<const Value> () const
+{
+  return Create<BooleanValue> (*this);
+}
 
 } // namespace ns3
--- a/src/core/boolean-value.h	Wed Jan 30 17:28:18 2008 +0100
+++ b/src/core/boolean-value.h	Wed Jan 30 19:13:06 2008 +0100
@@ -18,6 +18,10 @@
   virtual Ptr<Value> Copy (void) const;
   virtual std::string SerializeToString (Ptr<const ParamSpec> spec) const;
   virtual bool DeserializeFromString (std::string value, Ptr<const ParamSpec> spec);
+
+  BooleanValue (Ptr<const Value> value);
+  operator Ptr<Value> () const;
+  operator Ptr<const Value> () const;
 private:
   bool m_value;
 };
--- a/src/core/object.cc	Wed Jan 30 17:28:18 2008 +0100
+++ b/src/core/object.cc	Wed Jan 30 19:13:06 2008 +0100
@@ -22,8 +22,11 @@
 #include "assert.h"
 #include "singleton.h"
 #include "trace-resolver.h"
+#include "value.h"
+#include "param-spec.h"
 #include "log.h"
 #include <vector>
+#include <sstream>
 
 NS_LOG_COMPONENT_DEFINE ("Object");
 
@@ -36,25 +39,51 @@
 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::CallbackBase callback, uint32_t nArguments);
   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::CallbackBase GetConstructor (uint16_t uid, uint32_t nArguments);
   bool HasConstructor (uint16_t uid);
   uint32_t GetRegisteredN (void);
   uint16_t GetRegistered (uint32_t i);
+  void AddParameter (uint16_t uid, 
+                     std::string name,
+                     std::string help, 
+                     uint32_t flags,
+                     ns3::Ptr<const ns3::ParamSpec> spec);
+  uint32_t GetParametersN (uint16_t uid) const;
+  std::string GetParameterName (uint16_t uid, uint32_t i) const;
+  uint32_t GetParameterFlags (uint16_t uid, uint32_t i) const;
+  const ns3::Value *GetParameterInitialValue (uint16_t uid, uint32_t i) const;
+  uint32_t GetParameterUid (uint16_t uid, uint32_t i) const;
+  ns3::Ptr<const ns3::ParamSpec> GetParameterParamSpec (uint16_t uid, uint32_t i) const;
 private:
   struct ConstructorInformation {
     ns3::CallbackBase cb;
     uint32_t nArguments;
   };
+  struct ParameterInformation {
+    std::string name;
+    std::string help;
+    uint32_t flags;
+    uint32_t uid;
+    ns3::Ptr<const ns3::ParamSpec> param;
+  };
   struct IidInformation {
     std::string name;
     uint16_t parent;
+    std::string typeName;
+    std::string groupName;
     std::vector<struct ConstructorInformation> constructors;
+    std::vector<struct ParameterInformation> parameters;
   };
   typedef std::vector<struct IidInformation>::const_iterator Iterator;
 
@@ -63,6 +92,9 @@
   std::vector<struct IidInformation> m_information;
 };
 
+IidManager::IidManager ()
+{}
+
 uint16_t 
 IidManager::AllocateUid (std::string name)
 {
@@ -79,6 +111,8 @@
   struct IidInformation information;
   information.name = name;
   information.parent = 0;
+  information.typeName = "";
+  information.groupName = "";
   m_information.push_back (information);
   uint32_t uid = m_information.size ();
   NS_ASSERT (uid <= 0xffff);
@@ -100,6 +134,19 @@
   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::AddConstructor (uint16_t uid, ns3::CallbackBase callback, uint32_t nArguments)
 {
   struct IidInformation *information = LookupInformation (uid);
@@ -145,6 +192,19 @@
   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::CallbackBase 
 IidManager::GetConstructor (uint16_t uid, uint32_t nArguments)
 {
@@ -179,6 +239,60 @@
   return i + 1;
 }
 
+void 
+IidManager::AddParameter (uint16_t uid, 
+                          std::string name,
+                          std::string help, 
+                          uint32_t flags,
+                          ns3::Ptr<const ns3::ParamSpec> spec)
+{
+  struct IidInformation *information = LookupInformation (uid);
+  for (std::vector<struct ParameterInformation>::const_iterator j = information->parameters.begin ();
+       j != information->parameters.end (); j++)
+    {
+      if (j->name == name)
+        {
+          NS_FATAL_ERROR ("Registered the same parameter twice name=\""<<name<<"\" in TypeId=\""<<information->name<<"\"");
+          return;
+        }
+    }
+  struct ParameterInformation param;
+  param.name = name;
+  param.help = help;
+  param.flags = flags;
+  param.param = spec;
+  information->parameters.push_back (param);
+}
+
+
+uint32_t 
+IidManager::GetParametersN (uint16_t uid) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  return information->parameters.size ();
+}
+std::string 
+IidManager::GetParameterName (uint16_t uid, uint32_t i) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->parameters.size ());
+  return information->parameters[i].name;
+}
+uint32_t
+IidManager::GetParameterFlags (uint16_t uid, uint32_t i) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->parameters.size ());
+  return information->parameters[i].flags;
+}
+ns3::Ptr<const ns3::ParamSpec>
+IidManager::GetParameterParamSpec (uint16_t uid, uint32_t i) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->parameters.size ());
+  return information->parameters[i].param;
+}
+
 
 } // anonymous namespace
 
@@ -273,6 +387,19 @@
   NS_ASSERT (uid != 0);
   return TypeId (uid);
 }
+Ptr<const ParamSpec>
+TypeId::LookupParamSpecByFullName (std::string fullName)
+{
+  std::string::size_type pos = fullName.find ("::");
+  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 = LookupByName (tidName);
+  return tid.LookupParamSpecByName (paramName);
+}
 uint32_t 
 TypeId::GetRegisteredN (void)
 {
@@ -284,6 +411,41 @@
   return TypeId (Singleton<IidManager>::Get ()->GetRegistered (i));
 }
 
+Ptr<const ParamSpec>
+TypeId::LookupParamSpecByName (std::string name) const
+{
+  for (uint32_t i = 0; i < GetParametersN (); i++)
+    {
+      std::string paramName = GetParameterName (i);
+      if (paramName == name)
+        {
+          return GetParameterParamSpec (i);
+        }
+    }
+  return 0;
+}
+Ptr<const ParamSpec>
+TypeId::LookupParamSpecByPosition (uint32_t i) const
+{
+  uint32_t cur = 0;
+  TypeId tid = TypeId (0);
+  TypeId nextTid = *this;
+  do {
+    tid = nextTid;
+    for (uint32_t j = 0; j < tid.GetParametersN (); j++)
+      {
+        if (cur == i)
+          {
+            return tid.GetParameterParamSpec (j);
+          }
+        cur++;
+      }
+    nextTid = tid.GetParent ();
+  } while (nextTid != tid);
+  return 0;
+}
+
+
 TypeId 
 TypeId::SetParent (TypeId tid)
 {
@@ -291,12 +453,37 @@
   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);
@@ -316,22 +503,73 @@
   Singleton<IidManager>::Get ()->AddConstructor (m_tid, cb, nArguments);
 }
 
+TypeId 
+TypeId::AddParameter (std::string name,
+                      std::string help, 
+                      Ptr<const ParamSpec> param)
+{
+  Singleton<IidManager>::Get ()->AddParameter (m_tid, name, help, 0, param);
+  return *this;
+}
+
+TypeId 
+TypeId::AddParameter (std::string name,
+                      std::string help, 
+                      uint32_t flags,
+                      Ptr<const ParamSpec> param)
+{
+  Singleton<IidManager>::Get ()->AddParameter (m_tid, name, help, flags, param);
+  return *this;
+}
+
+
 CallbackBase
-TypeId::LookupConstructor (uint32_t nArguments)
+TypeId::LookupConstructor (uint32_t nArguments) const
 {
   CallbackBase constructor = Singleton<IidManager>::Get ()->GetConstructor (m_tid, nArguments);
   return constructor;
 }
 
 Ptr<Object> 
-TypeId::CreateObject (void)
+TypeId::CreateObject (void) const
+{
+  return CreateObject (Parameters ());
+}
+Ptr<Object> 
+TypeId::CreateObject (const Parameters &parameters) const
 {
   CallbackBase cb = LookupConstructor (0);
-  Callback<Ptr<Object> > realCb;
+  Callback<Ptr<Object>,const Parameters &> realCb;
   realCb.Assign (cb);
-  Ptr<Object> object = realCb ();
-  return object;
+  Ptr<Object> object = realCb (parameters);
+  return object;  
+}
+
+uint32_t 
+TypeId::GetParametersN (void) const
+{
+  uint32_t n = Singleton<IidManager>::Get ()->GetParametersN (m_tid);
+  return n;
 }
+std::string 
+TypeId::GetParameterName (uint32_t i) const
+{
+  std::string name = Singleton<IidManager>::Get ()->GetParameterName (m_tid, i);
+  return name;
+}
+std::string 
+TypeId::GetParameterFullName (uint32_t i) const
+{
+  return GetName () + "::" + GetParameterName (i);
+}
+Ptr<const ParamSpec>
+TypeId::GetParameterParamSpec (uint32_t i) const
+{
+  // Used exclusively by the Object class.
+  Ptr<const ParamSpec> param = Singleton<IidManager>::Get ()->GetParameterParamSpec (m_tid, i);
+  return param;
+}
+
 
 bool operator == (TypeId a, TypeId b)
 {
@@ -344,6 +582,236 @@
 }
 
 /*********************************************************************
+ *         The Parameters container implementation
+ *********************************************************************/
+
+Parameters::Parameters ()
+{}
+
+Parameters::Parameters (const Parameters &o)
+{
+  for (Params::const_iterator i = o.m_parameters.begin (); i != o.m_parameters.end (); i++)
+    {
+      struct Param param;
+      param.spec = i->spec;
+      param.value = i->value->Copy ();
+      m_parameters.push_back (param);
+    }
+}
+Parameters &
+Parameters::operator = (const Parameters &o)
+{
+  Reset ();
+  for (Params::const_iterator i = o.m_parameters.begin (); i != o.m_parameters.end (); i++)
+    {
+      struct Param param;
+      param.spec = i->spec;
+      param.value = i->value->Copy ();
+      m_parameters.push_back (param);
+    }
+  return *this;
+}
+Parameters::~Parameters ()
+{
+  Reset ();
+}
+
+bool 
+Parameters::Set (std::string name, Ptr<const Value> value)
+{
+  Ptr<const ParamSpec> spec = TypeId::LookupParamSpecByFullName (name);
+  bool ok = DoSet (spec, value);
+  return ok;
+}
+bool 
+Parameters::Set (std::string name, std::string value)
+{
+  Ptr<const ParamSpec> spec = TypeId::LookupParamSpecByFullName (name);
+  bool ok = DoSet (spec,value);
+  return ok;
+}
+void 
+Parameters::SetWithTid (TypeId tid, std::string name, std::string value)
+{
+  Ptr<const ParamSpec> spec = tid.LookupParamSpecByName (name);
+  DoSet (spec, value);
+}
+void 
+Parameters::SetWithTid (TypeId tid, std::string name, Ptr<const Value> value)
+{
+  Ptr<const ParamSpec> spec = tid.LookupParamSpecByName (name);
+  DoSet (spec, value);
+}
+void 
+Parameters::SetWithTid (TypeId tid, uint32_t position, std::string value)
+{
+  Ptr<const ParamSpec> spec = tid.LookupParamSpecByPosition (position);
+  DoSet (spec, value);
+}
+void 
+Parameters::SetWithTid (TypeId tid, uint32_t position, Ptr<const Value> value)
+{
+  Ptr<const ParamSpec> spec = tid.LookupParamSpecByPosition (position);
+  DoSet (spec, value);
+}
+
+void
+Parameters::DoSetOne (Ptr<const ParamSpec> spec, Ptr<const Value> value)
+{
+  // get rid of any previous value stored in this
+  // vector of values.
+  for (Params::iterator k = m_parameters.begin (); k != m_parameters.end (); k++)
+    {
+      if (k->spec == spec)
+        {
+          m_parameters.erase (k);
+          break;
+        }
+    }
+  // store the new value.
+  struct Param p;
+  p.spec = spec;
+  p.value = value->Copy ();
+  m_parameters.push_back (p);
+}
+bool
+Parameters::DoSet (Ptr<const ParamSpec> spec, Ptr<const Value> value)
+{
+  if (spec == 0)
+    {
+      return false;
+    }
+  bool ok = spec->Check (value);
+  if (!ok)
+    {
+      return false;
+    }
+  DoSetOne (spec, value);
+  return true;
+}
+bool
+Parameters::DoSet (Ptr<const ParamSpec> spec, std::string value)
+{
+  if (spec == 0)
+    {
+      return false;
+    }
+  Ptr<Value> v = spec->CreateInitialValue ();
+  bool ok = v->DeserializeFromString (value, spec);
+  if (!ok)
+    {
+      return false;
+    }
+  ok = spec->Check (v);
+  if (!ok)
+    {
+      return false;
+    }
+  DoSetOne (spec, v);
+  return true;
+}
+void 
+Parameters::Reset (void)
+{
+  m_parameters.clear ();
+}
+Parameters *
+Parameters::GetGlobal (void)
+{
+  return Singleton<Parameters>::Get ();
+}
+
+std::string
+Parameters::LookupParameterFullNameByParamSpec (Ptr<const ParamSpec> spec) const
+{
+  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++)
+    {
+      TypeId tid = TypeId::GetRegistered (i);
+      for (uint32_t j = 0; j < tid.GetParametersN (); j++)
+        {
+          if (spec == tid.GetParameterParamSpec (j))
+            {
+              return tid.GetParameterFullName (j);
+            }
+        }
+    }
+  NS_FATAL_ERROR ("Could not find requested ParamSpec.");
+  // quiet compiler.
+  return "";
+}
+
+std::string 
+Parameters::SerializeToString (void) const
+{
+  std::ostringstream oss;
+  for (Params::const_iterator i = m_parameters.begin (); i != m_parameters.end (); i++)
+    {
+      std::string name = LookupParameterFullNameByParamSpec (i->spec);
+      oss << name << "=" << i->value->SerializeToString (PeekPointer (i->spec));
+      if (i != m_parameters.end ())
+        {
+          oss << "|";
+        }
+    }  
+  return oss.str ();
+}
+bool 
+Parameters::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 parameter.
+        break;
+      }
+    else
+      {
+        std::string name = str.substr (cur, equal-cur);
+        Ptr<const ParamSpec> spec = TypeId::LookupParamSpecByFullName (name);
+        if (spec == 0)
+          {
+            // 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++;
+              }
+            Ptr<Value> val = spec->CreateInitialValue ();
+            bool ok = val->DeserializeFromString (value, spec);
+            if (!ok)
+              {
+                // XXX invalid value
+                break;
+              }
+            else
+              {
+                DoSetOne (spec, val);
+              }
+          }
+      }
+  } while (cur != str.size ());
+
+  return true;
+}
+
+
+/*********************************************************************
  *         The Object implementation
  *********************************************************************/
 
@@ -376,6 +844,152 @@
 {
   m_next = 0;
 }
+void
+Object::Construct (const Parameters &parameters)
+{
+  // loop over the inheritance tree back to the Object base class.
+  TypeId tid = m_tid;
+  do {
+    // loop over all parameters in object type
+    NS_LOG_DEBUG ("construct tid="<<tid.GetName ()<<", params="<<tid.GetParametersN ());
+    for (uint32_t i = 0; i < tid.GetParametersN (); i++)
+      {
+        Ptr<const ParamSpec> paramSpec = tid.GetParameterParamSpec (i);
+        NS_LOG_DEBUG ("try to construct \""<< tid.GetName ()<<"::"<<
+                      tid.GetParameterName (i)<<"\"");
+        bool found = false;
+        // is this parameter stored in this Parameters instance ?
+        for (Parameters::Params::const_iterator j = parameters.m_parameters.begin ();
+             j != parameters.m_parameters.end (); j++)
+          {
+            if (j->spec == paramSpec)
+              {
+                // We have a matching parameter value.
+                paramSpec->Set (this, j->value);
+                NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
+                              tid.GetParameterName (i)<<"\"");
+                found = true;
+                break;
+              }
+          }
+        if (!found)
+          {
+            // is this parameter stored in the global instance instance ?
+            for (Parameters::Params::const_iterator j = Parameters::GetGlobal ()->m_parameters.begin ();
+                 j != Parameters::GetGlobal ()->m_parameters.end (); j++)
+              {
+                if (j->spec == paramSpec)
+                  {
+                    // We have a matching parameter value.
+                    paramSpec->Set (this, j->value);
+                    NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
+                                  tid.GetParameterName (i)<<"\" from global");
+                    found = true;
+                    break;
+                  }
+              }
+          }
+        if (!found)
+          {
+            // No matching parameter value so we set the default value.
+            Ptr<Value> initial = paramSpec->CreateInitialValue ();
+            paramSpec->Set (this, initial);
+            NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
+                          tid.GetParameterName (i)<<"\" from local");
+          }
+      }
+    tid = tid.GetParent ();
+  } while (tid != Object::GetTypeId ());
+  NotifyConstructionCompleted ();
+}
+bool
+Object::DoSet (std::string name, Ptr<const Value> value)
+{
+  Ptr<const ParamSpec> spec = m_tid.LookupParamSpecByName (name);
+  if (spec == 0)
+    {
+      return false;
+    }
+  bool ok = spec->Set (this, value);
+  if (!ok)
+    {
+      return false;
+    }
+  return true;
+}
+bool
+Object::Set (std::string name, Ptr<const Value> value)
+{
+  return DoSet (name, value);
+}
+bool
+Object::Set (std::string name, std::string value)
+{
+  Ptr<const ParamSpec> spec = m_tid.LookupParamSpecByName (name);
+  if (spec == 0)
+    {
+      return false;
+    }
+  Ptr<Value> parameter = spec->CreateInitialValue ();
+  bool ok = parameter->DeserializeFromString (value, spec);
+  if (!ok)
+    {
+      return false;
+    }
+  spec->Set (this, parameter);
+  if (!ok)
+    {
+      return false;
+    }
+  return true;
+}
+bool 
+Object::Get (std::string name, std::string &value) const
+{
+  Ptr<const ParamSpec> paramSpec = m_tid.LookupParamSpecByName (name);
+  if (paramSpec == 0)
+    {
+      return false;
+    }
+  Ptr<Value> parameter = paramSpec->CreateInitialValue ();
+  bool ok = paramSpec->Get (this, parameter);
+  if (ok)
+    {
+      value = parameter->SerializeToString (paramSpec);
+    }
+  return ok;
+}
+
+Ptr<const Value>
+Object::Get (std::string name) const
+{
+  Ptr<const ParamSpec> paramSpec = m_tid.LookupParamSpecByName (name);
+  if (paramSpec == 0)
+    {
+      return 0;
+    }
+  Ptr<Value> value = paramSpec->CreateInitialValue ();
+  bool ok = paramSpec->Get (this, value);
+  if (!ok)
+    {
+      return 0;
+    }
+  return value;
+}
+
+bool 
+Object::DoGet (std::string name, Ptr<Value> parameter) const
+{
+  Ptr<const ParamSpec> paramSpec = m_tid.LookupParamSpecByName (name);
+  if (paramSpec == 0)
+    {
+      return false;
+    }
+  bool ok = paramSpec->Get (this, parameter);
+  return ok;
+}
+
+
 Ptr<Object>
 Object::DoQueryInterface (TypeId tid) const
 {
@@ -408,7 +1022,9 @@
     current = current->m_next;
   } while (current != this);
 }
-
+void
+Object::NotifyConstructionCompleted (void)
+{}
 void 
 Object::AddInterface (Ptr<Object> o)
 {
@@ -619,10 +1235,10 @@
   static ns3::TypeId GetTypeId (void) {
     static ns3::TypeId tid = ns3::TypeId ("DerivedA")
       .SetParent (BaseA::GetTypeId ())
-      .AddConstructor<DerivedA,int> ();
+      .AddConstructor<DerivedA> ();
     return tid;
   }
-  DerivedA (int v)
+  DerivedA ()
   {}
   void DerivedGenerateTrace (int16_t v)
   { m_sourceDerived = v; }
@@ -671,13 +1287,10 @@
   static ns3::TypeId GetTypeId (void) {
     static ns3::TypeId tid = ns3::TypeId ("DerivedB")
       .SetParent (BaseB::GetTypeId ())
-      .AddConstructor<DerivedB,int> ()
-      .AddConstructor<DerivedB,int,int &> ();
+      .AddConstructor<DerivedB> ();
     return tid;
   }
-  DerivedB (int v)
-  {}
-  DerivedB (int v1, int &v2)
+  DerivedB ()
   {}
   void DerivedGenerateTrace (int16_t v)
   { m_sourceDerived = v; }
@@ -754,7 +1367,7 @@
   NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<BaseA> (), baseA);
   NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<BaseA> (DerivedA::GetTypeId ()), 0);
   NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<DerivedA> (), 0);
-  baseA = CreateObject<DerivedA> (10);
+  baseA = CreateObject<DerivedA> ();
   NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<BaseA> (), baseA);
   NS_TEST_ASSERT_EQUAL (baseA->QueryInterface<BaseA> (DerivedA::GetTypeId ()), baseA);
   NS_TEST_ASSERT_UNEQUAL (baseA->QueryInterface<DerivedA> (), 0);
@@ -773,8 +1386,8 @@
   NS_TEST_ASSERT_EQUAL (baseB->QueryInterface<DerivedA> (), 0);
   NS_TEST_ASSERT_UNEQUAL (baseBCopy->QueryInterface<BaseA> (), 0);
 
-  baseA = CreateObject<DerivedA> (1);
-  baseB = CreateObject<DerivedB> (1);
+  baseA = CreateObject<DerivedA> ();
+  baseB = CreateObject<DerivedB> ();
   baseBCopy = baseB;
   baseA->AddInterface (baseB);
   NS_TEST_ASSERT_UNEQUAL (baseA->QueryInterface<DerivedB> (), 0);
@@ -836,7 +1449,7 @@
   baseA->TraceDisconnect ("/$BaseA/basea-x", MakeCallback (&ObjectTest::BaseATrace, this));
 
   Ptr<DerivedA> derivedA;
-  derivedA = CreateObject<DerivedA> (1);
+  derivedA = CreateObject<DerivedA> ();
   baseB = CreateObject<BaseB> ();
   derivedA->AddInterface (baseB);
   baseB->TraceConnect ("/$DerivedA/deriveda-x", MakeCallback (&ObjectTest::DerivedATrace, this));
@@ -866,7 +1479,7 @@
   NS_TEST_ASSERT_EQUAL (a->QueryInterface<BaseA> (), a);
   NS_TEST_ASSERT_EQUAL (a->QueryInterface<BaseA> (DerivedA::GetTypeId ()), 0);
   NS_TEST_ASSERT_EQUAL (a->QueryInterface<DerivedA> (), 0);
-  a = DerivedA::GetTypeId ().CreateObject (10);
+  a = DerivedA::GetTypeId ().CreateObject ();
   NS_TEST_ASSERT_EQUAL (a->QueryInterface<BaseA> (), a);
   NS_TEST_ASSERT_EQUAL (a->QueryInterface<BaseA> (DerivedA::GetTypeId ()), a);
   NS_TEST_ASSERT_UNEQUAL (a->QueryInterface<DerivedA> (), 0);
--- a/src/core/object.h	Wed Jan 30 17:28:18 2008 +0100
+++ b/src/core/object.h	Wed Jan 30 19:13:06 2008 +0100
@@ -26,13 +26,14 @@
 #include "ptr.h"
 #include "trace-resolver.h"
 #include "callback.h"
-#include "empty.h"
+#include "value.h"
+#include "object-base.h"
 
 #define NS_OBJECT_ENSURE_REGISTERED(type)       \
   static struct X##type##RegistrationClass      \
   {                                             \
     X##type##RegistrationClass () {             \
-      ns3::TypeId tid = type::GetTypeId ();      \
+      ns3::TypeId tid = type::GetTypeId ();     \
       tid.GetParent ();                         \
     }                                           \
 } x_##type##RegistrationVariable
@@ -43,14 +44,32 @@
 class TraceContext;
 class CallbackBase;
 class Object;
+class ParamSpec;
+class Value;
+class Parameters;
 
 /**
  * \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 'parameters' accessible in the subclass
  */
 class TypeId
 {
 public:
+  enum {
+    PARAM_READ = 1<<0,
+    PARAM_WRITE = 1<<1,
+    PARAM_CONSTRUCT = 1<<2,
+    PARAM_RWC = PARAM_READ | PARAM_WRITE | PARAM_CONSTRUCT,
+    PARAM_NO_READ = 0,
+    PARAM_NO_WRITE = 0,
+    PARAM_NO_CONSTRUCT = 0,
+  };
+
   /**
    * \param name the name of the requested interface
    * \returns the unique id associated with the requested
@@ -60,11 +79,26 @@
    * name is not a valid interface name.
    */
   static TypeId LookupByName (std::string name);
+
+  /**
+   * \returns the number of TypeId instances constructed
+   */
   static uint32_t GetRegisteredN (void);
-  static TypeId GetRegistered (uint32_t i);
   /**
-   * \param tid a unique id 
-   * \returns the parent of the requested id
+   * \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.
+   */
+  TypeId (std::string name);
+
+  /**
+   * \returns the parent of this TypeId
    *
    * This method cannot fail: it will crash if the input
    * id is not a valid interface id.
@@ -72,6 +106,15 @@
   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;
@@ -81,56 +124,219 @@
    */
   bool HasConstructor (void) const;
 
-  TypeId (std::string);
+  /**
+   * \returns the number of parameters associated to this TypeId
+   */
+  uint32_t GetParametersN (void) const;
+  /**
+   * \param i index into parameter array
+   * \returns the name associated to the parameter whose
+   *          index is \i i.
+   */
+  std::string GetParameterName (uint32_t i) const;
+  /**
+   * \param i index into parameter array
+   * \returns the full name associated to the parameter whose
+   *          index is \i i.
+   */
+  std::string GetParameterFullName (uint32_t i) const;
+  /**
+   * \param i index into parameter array
+   * \param value the value to validate
+   * \returns true if the input value is a valid value
+   *          associated to the parameter whose index is \i i.
+   */
+  bool CheckParameterValue (uint32_t i, std::string value) const;
 
+  Ptr<Object> CreateObject (const Parameters &parameters) const;
+
+
+  Ptr<Object> CreateObject (void) const;
+  template <typename T1>
+  Ptr<Object> CreateObject (T1 a1) const;
+  template <typename T1, typename T2>
+  Ptr<Object> CreateObject (T1 a1, T2 a2) 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);
+
   template <typename T, typename T1>
   TypeId AddConstructor (void);
-  template <typename T, typename T1, typename T2>
-  TypeId AddConstructor (void);
-  template <typename T, typename T1, typename T2, typename T3>
-  TypeId AddConstructor (void);
-  template <typename T, typename T1, typename T2, typename T3, typename T4>
-  TypeId AddConstructor (void);
-  template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
-  TypeId AddConstructor (void);
 
+  template <typename T, typename T1, typename T2>
+  TypeId AddConstructor (void);
 
-  Ptr<Object> CreateObject (void);
-  template <typename T1>
-  Ptr<Object> CreateObject (T1 a1);
-  template <typename T1, typename T2>
-  Ptr<Object> CreateObject (T1 a1, T2 a2);
-  template <typename T1, typename T2, typename T3>
-  Ptr<Object> CreateObject (T1 a1, T2 a2, T3 a3);
-  template <typename T1, typename T2, typename T3, typename T4>
-  Ptr<Object> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4);
-  template <typename T1, typename T2, typename T3, typename T4, typename T5>
-  Ptr<Object> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
+  /**
+   * \param name the name of the new parameter
+   * \param help some help text which describes the purpose of this
+   *        parameter
+   * \param param an instance of the associated ParamSpec subclass
+   * \returns this TypeId instance
+   *
+   * Record in this TypeId the fact that a new parameter exists.
+   */
+  TypeId AddParameter (std::string name,
+                       std::string help, Ptr<const ParamSpec> spec);
+
+  /**
+   * \param name the name of the new parameter
+   * \param help some help text which describes the purpose of this
+   *        parameter
+   * \param flags flags which describe how this parameter can be read and/or written.
+   * \param param an instance of the associated ParamSpec subclass
+   * \returns this TypeId instance
+   *
+   * Record in this TypeId the fact that a new parameter exists.
+   */
+  TypeId AddParameter (std::string name,
+                       std::string help, 
+                       uint32_t flags,
+                       Ptr<const ParamSpec> spec);
 
   ~TypeId ();
 private:
+  friend class Object;
+  friend class Parameters;
   friend bool operator == (TypeId a, TypeId b);
   friend bool operator != (TypeId a, TypeId b);
 
+  /**
+   * \param name the name of the requested parameter
+   * \returns the ParamSpec associated to the requested parameter
+   */
+  Ptr<const ParamSpec> LookupParamSpecByName (std::string name) const;
+  /**
+   * \param i the position of the requested parameter
+   * \returns the ParamSpec associated to the requested parameter
+   */
+  Ptr<const ParamSpec> LookupParamSpecByPosition (uint32_t i) const;
+  /**
+   * \param fullName the full name of the requested parameter
+   * \returns the ParamSpec associated to the requested parameter
+   */
+  static Ptr<const ParamSpec> LookupParamSpecByFullName (std::string fullName);
+
   explicit TypeId (uint16_t tid);
   void DoAddConstructor (CallbackBase callback, uint32_t nArguments);
-  CallbackBase LookupConstructor (uint32_t nArguments);
+  CallbackBase LookupConstructor (uint32_t nArguments) const;
+  Ptr<const ParamSpec> GetParameterParamSpec (uint32_t i) const;
   
   uint16_t m_tid;
 };
 
+
+/**
+ * \brief a container of parameters to be used during object's construction
+ *        and in ns3::Object::Set.
+ *
+ */
+class Parameters
+{
+public:
+  Parameters ();
+  Parameters (const Parameters &o);
+  Parameters &operator = (const Parameters &o);
+  ~Parameters ();
+  /**
+   * \param name the name of the parameter to set
+   * \param value the value to set
+   *
+   * This method checks that a parameter with the requested
+   * name exists and that the value specified is an acceptable
+   * value of that parameter. If any of these checks fails,
+   * the program terminates with a message.
+   */
+  bool Set (std::string name, std::string value);
+  bool Set (std::string name, Ptr<const Value> value);
+
+  void SetWithTid (TypeId tid, std::string name, std::string value);
+  void SetWithTid (TypeId tid, std::string name, Ptr<const Value> value);
+  void SetWithTid (TypeId tid, uint32_t position, std::string value);
+  void SetWithTid (TypeId tid, uint32_t position, Ptr<const Value> value);
+
+  /**
+   * Clear the content of this instance.
+   */
+  void Reset (void);
+
+  /**
+   * \returns the global parameter container
+   *
+   * The global parameter container can be used to specify
+   * a set of parameter 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 Parameters *GetGlobal (void);
+
+  std::string SerializeToString (void) const;
+  bool DeserializeFromString (std::string value);
+private:
+  friend class Object;
+  struct Param {
+    Ptr<const ParamSpec> spec;
+    Ptr<const Value> value;
+  };
+  typedef std::vector<struct Param> Params;
+  typedef Params::iterator Iterator;
+  typedef Params::const_iterator CIterator;
+
+
+
+  bool DoSet (Ptr<const ParamSpec> spec, Ptr<const Value> param);
+  bool DoSet (Ptr<const ParamSpec> spec, std::string value);
+  void DoSetOne (Ptr<const ParamSpec> spec, Ptr<const Value> param);
+  std::string LookupParameterFullNameByParamSpec (Ptr<const ParamSpec> spec) const;
+
+  Params m_parameters;
+};
+
+
 /**
  * \brief a base class which provides memory management and object aggregation
  *
- * Note: This base class is quite similar in spirit to IUnknown in COM or
- * BonoboObject in Bonobo: it provides three main methods: Ref, Unref and
- * QueryInterface.
  */
 class Object : public ObjectBase
 {
@@ -139,6 +345,30 @@
 
   Object ();
   virtual ~Object ();
+
+  /**
+   * \param name the name of the parameter to set
+   * \param value the name of the parameter to set
+   *
+   * Set a single parameter.
+   */
+  bool Set (std::string name, std::string value);
+  bool Set (std::string name, Ptr<const Value> value);
+  /**
+   * \param name the name of the parameter to read
+   * \param value a reference to the string where the value of the 
+   *        parameter should be stored.
+   * \returns true if the requested parameter was found, false otherwise.
+   */
+  bool Get (std::string name, std::string &value) const;
+  /**
+   * \param name the name of the parameter to read
+   * \param value a reference to the object where the value of the 
+   *        parameter should be stored.
+   * \returns true if the requested parameter was found, false otherwise.
+   */
+  Ptr<const Value> Get (std::string name) const;
+
   /**
    * Increment the reference count. This method should not be called
    * by user code. Object instances are expected to be used in conjunction
@@ -212,8 +442,13 @@
    * up to their parent's implementation once they are done.
    */
   virtual void DoDispose (void);
+  virtual void NotifyConstructionCompleted (void);
 private:
   friend class TypeIdTraceResolver;
+
+  template <typename T>
+  friend Ptr<T> CreateObject (const Parameters &parameters);
+
   template <typename T>
   friend Ptr<T> CreateObject (void);
   template <typename T, typename T1>
@@ -231,57 +466,76 @@
   template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
   friend Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7);
 
+
   Ptr<Object> DoQueryInterface (TypeId tid) const;
   void DoCollectSources (std::string path, const TraceContext &context, 
                          TraceResolver::SourceCollection *collection) const;
   void DoTraceAll (std::ostream &os, const TraceContext &context) const;
   bool Check (void) const;
   bool CheckLoose (void) const;
+  bool DoSet (std::string name, Ptr<const Value> value);
+  bool DoGet (std::string name, Ptr<Value> value) const;
+  /**
+   * Attempt to delete this object. This method iterates
+   * over all aggregated objects to check if they all 
+   * have a zero refcount. If yes, the object and all
+   * its aggregates are deleted. If not, nothing is done.
+   */
   void MaybeDelete (void) const;
   /**
    * \param tid an TypeId
    *
-   * Every subclass which defines a new TypeId for itself
-   * should register this TypeId by calling this method
-   * from its constructor.
+   * Invoked from ns3::CreateObject only.
+   * Initialize the m_tid member variable to
+   * keep track of the type of this object instance.
    */
   void SetTypeId (TypeId tid);
+  /**
+   * \param parameters the parameter values used to initialize 
+   *        the member variables of this object's instance.
+   *
+   * Invoked from ns3::CreateObject only.
+   * Initialize all the member variables which were
+   * registered with the associated TypeId.
+   */
+  void Construct (const Parameters &parameters);
 
+  /**
+   * The reference count for this object. Each aggregate
+   * has an individual reference count. When the global
+   * reference count (the sum of all reference counts) 
+   * reaches zero, the object and all its aggregates is 
+   * deleted.
+   */
   mutable uint32_t m_count;
+  /**
+   * Identifies the type of this object instance.
+   */
   TypeId m_tid;
+  /**
+   * Set to true when the DoDispose method of the object
+   * has run, false otherwise.
+   */
   bool m_disposed;
   mutable bool m_collecting;
+  /**
+   * A pointer to the next aggregate object. This is a circular
+   * linked list of aggregated objects: the last one points
+   * back to the first one. If an object is not aggregated to
+   * any other object, the value of this field is equal to the
+   * value of the 'this' pointer.
+   */
   Object *m_next;
 };
 
-template <typename T>
-Ptr<T> CreateObject (void);
-
-template <typename T, typename T1>
-Ptr<T> CreateObject (T1 a1);
-
-template <typename T, typename T1, typename T2>
-Ptr<T> CreateObject (T1 a1, T2 a2);
-
-template <typename T, typename T1, typename T2, typename T3>
-Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3);
-
-template <typename T, typename T1, typename T2, typename T3, typename T4>
-Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4);
-
-template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
-Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
-
-template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
-Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6);
-
-template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
-Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7);
-
 } // namespace ns3
 
 namespace ns3 {
 
+/*************************************************************************
+ *   The TypeId implementation which depends on templates
+ *************************************************************************/
+
 template <typename T>
 TypeId 
 TypeId::SetParent (void)
@@ -294,8 +548,8 @@
 TypeId::AddConstructor (void)
 {
   struct Maker {
-    static Ptr<Object> Create (void) {
-      return ns3::CreateObject<T> ();
+    static Ptr<Object> Create (const Parameters &parameters) {
+      return ns3::CreateObject<T> (parameters);
     }
   };
   CallbackBase cb = MakeCallback (&Maker::Create);
@@ -328,49 +582,9 @@
   DoAddConstructor (cb, 2);
   return *this;
 }
-template <typename T, typename T1, typename T2, typename T3>
-TypeId 
-TypeId::AddConstructor (void)
-{
-  struct Maker {
-    static Ptr<Object> Create (T1 a1, T2 a2, T3 a3) {
-      return ns3::CreateObject<T,T1,T2,T3> (a1, a2, a3);
-    }
-  };
-  CallbackBase cb = MakeCallback (&Maker::Create);
-  DoAddConstructor (cb, 3);
-  return *this;
-}
-template <typename T, typename T1, typename T2, typename T3, typename T4>
-TypeId 
-TypeId::AddConstructor (void)
-{
-  struct Maker {
-    static Ptr<Object> Create (T1 a1, T2 a2, T3 a3, T4 a4) {
-      return ns3::CreateObject<T,T1,T2,T3,T4> (a1, a2, a3, a4);
-    }
-  };
-  CallbackBase cb = MakeCallback (&Maker::Create);
-  DoAddConstructor (cb, 4);
-  return *this;
-}
-template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
-TypeId 
-TypeId::AddConstructor (void)
-{
-  struct Maker {
-    static Ptr<Object> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
-      return ns3::CreateObject<T,T1,T2,T3,T4,T5> (a1, a2, a3, a4, a5);
-    }
-  };
-  CallbackBase cb = MakeCallback (&Maker::Create);
-  DoAddConstructor (cb, 5);
-  return *this;
-}
-
 template <typename T1>
 Ptr<Object> 
-TypeId::CreateObject (T1 a1)
+TypeId::CreateObject (T1 a1) const
 {
   CallbackBase cb = LookupConstructor (1);
   Callback<Ptr<Object>,T1> realCb;
@@ -380,7 +594,7 @@
 }
 template <typename T1, typename T2>
 Ptr<Object> 
-TypeId::CreateObject (T1 a1, T2 a2)
+TypeId::CreateObject (T1 a1, T2 a2) const
 {
   CallbackBase cb = LookupConstructor (2);
   Callback<Ptr<Object>,T1,T2> realCb;
@@ -388,38 +602,10 @@
   Ptr<Object> object = realCb (a1,a2);
   return object;
 }
-template <typename T1, typename T2, typename T3>
-Ptr<Object> 
-TypeId::CreateObject (T1 a1, T2 a2, T3 a3)
-{
-  CallbackBase cb = LookupConstructor (3);
-  Callback<Ptr<Object>,T1,T2,T3> realCb;
-  realCb.Assign (cb);
-  Ptr<Object> object = realCb (a1,a2,a3);
-  return object;
-}
-template <typename T1, typename T2, typename T3, typename T4>
-Ptr<Object> 
-TypeId::CreateObject (T1 a1, T2 a2, T3 a3, T4 a4)
-{
-  CallbackBase cb = LookupConstructor (4);
-  Callback<Ptr<Object>,T1,T2,T3,T4> realCb;
-  realCb.Assign (cb);
-  Ptr<Object> object = realCb (a1,a2,a3,a4);
-  return object;
-}
-  template <typename T1, typename T2, typename T3, typename T4, typename T5>
-Ptr<Object> 
-TypeId::CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
-{
-  CallbackBase cb = LookupConstructor (5);
-  Callback<Ptr<Object>,T1,T2,T3,T4,T5> realCb;
-  realCb.Assign (cb);
-  Ptr<Object> object = realCb (a1,a2,a3,a4,a5);
-  return object;
-}
 
-
+/*************************************************************************
+ *   The Object implementation which depends on templates
+ *************************************************************************/
 
 void
 Object::Ref (void) const
@@ -461,11 +647,26 @@
   return 0;
 }
 
+/*************************************************************************
+ *   The helper functions which need templates.
+ *************************************************************************/
+
+
+template <typename T>
+Ptr<T> CreateObject (const Parameters &parameters)
+{
+  Ptr<T> p = Ptr<T> (new T (), false);
+  p->SetTypeId (T::GetTypeId ());
+  p->Object::Construct (parameters);
+  return p;  
+}
+
 template <typename T>
 Ptr<T> CreateObject (void)
 {
   Ptr<T> p = Ptr<T> (new T (), false);
   p->SetTypeId (T::GetTypeId ());
+  p->Object::Construct (Parameters ());
   return p;
 }
 
@@ -474,6 +675,7 @@
 {
   Ptr<T> p = Ptr<T> (new T (a1), false);
   p->SetTypeId (T::GetTypeId ());
+  p->Object::Construct (Parameters ());
   return p;
 }
 
@@ -482,9 +684,9 @@
 {
   Ptr<T> p = Ptr<T> (new T (a1, a2), false);
   p->SetTypeId (T::GetTypeId ());
+  p->Object::Construct (Parameters ());
   return p;
 }
-
 template <typename T, typename T1, typename T2, typename T3>
 Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3)
 {
@@ -526,6 +728,30 @@
 }
 
 
+template <typename T>
+Ptr<T> 
+CreateObjectWith (std::string n1, Ptr<const Value> v1,
+                  std::string n2 = "", Ptr<const Value> v2 = 0)
+              
+{
+  Parameters parameters;
+  parameters.SetWithTid (T::GetTypeId (), n1, v1);
+  parameters.SetWithTid (T::GetTypeId (), n2, v2);
+  return CreateObject<T> (parameters);
+}
+
+template <typename T>
+Ptr<T> 
+CreateObjectWith (std::string n1, std::string v1,
+                  std::string n2 = "", std::string v2 = "")
+              
+{
+  Parameters parameters;
+  parameters.SetWithTid (T::GetTypeId (), n1, v1);
+  parameters.SetWithTid (T::GetTypeId (), n2, v2);
+  return CreateObject<T> (parameters);
+}
+
 } // namespace ns3
 
 #endif /* OBJECT_H */
--- a/src/core/param-spec-helper.h	Wed Jan 30 17:28:18 2008 +0100
+++ b/src/core/param-spec-helper.h	Wed Jan 30 19:13:06 2008 +0100
@@ -99,7 +99,7 @@
     {
       return false;
     }
-  V v = *value;
+  V v = value->Get ();
   DoSet (obj, v);
   return true;
 }
@@ -118,7 +118,7 @@
       return false;
     }
   V v = DoGet (obj);
-  *value = v;
+  value->Set (v);
   return true;
 }
 template <typename T, typename U, typename V>
@@ -130,7 +130,7 @@
     {
       return false;
     }
-  V v = *value;
+  V v = value->Get ();
   DoCheck (v);
   return true;
 }
@@ -178,7 +178,7 @@
 void 
 MemberMethodParamSpecHelper<T,U,V>::DoSet (T *object, const V &v) const
 {
-  (object->m_setter) (v);
+  (object->*m_setter) (v);
 }
 template <typename T, typename U, typename V>
 V 
--- a/src/core/wscript	Wed Jan 30 17:28:18 2008 +0100
+++ b/src/core/wscript	Wed Jan 30 19:13:06 2008 +0100
@@ -56,6 +56,7 @@
         'value.cc',
         'param-spec.cc',
         'boolean-value.cc',
+        'value-test.cc',
         ]
 
     if sys.platform == 'win32':
@@ -100,5 +101,7 @@
         'trace-doc.h',
         'int-to-type.h',
         'type-id-default-value.h',
+        'value.h',
+        'param-spec.h',
         ]