introduce Config::Reset
authorMathieu Lacage <mathieu.lacage@gmail.com>
Wed, 03 Aug 2011 13:58:10 -0400
changeset 7399 520706f801e8
parent 7398 0d18f207c57b
child 7400 dd257897c454
introduce Config::Reset
src/config-store/model/config-store.cc
src/core/model/attribute-construction-list.cc
src/core/model/attribute-construction-list.h
src/core/model/attribute-list.cc
src/core/model/attribute-list.h
src/core/model/attribute.cc
src/core/model/attribute.h
src/core/model/config.cc
src/core/model/config.h
src/core/model/global-value.cc
src/core/model/global-value.h
src/core/model/object-base.cc
src/core/model/object-base.h
src/core/model/object-factory.cc
src/core/model/object-factory.h
src/core/model/object.cc
src/core/model/object.h
src/core/model/type-id.cc
src/core/model/type-id.h
src/core/test/attribute-test-suite.cc
src/core/wscript
--- a/src/config-store/model/config-store.cc	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/config-store/model/config-store.cc	Wed Aug 03 13:58:10 2011 -0400
@@ -3,8 +3,8 @@
 #include "ns3/string.h"
 #include "ns3/log.h"
 #include "ns3/simulator.h"
+#include "ns3/attribute-construction-list.h"
 #include "ns3/enum.h"
-#include "ns3/attribute-list.h"
 #include "ns3/config-store-config.h"
 #ifdef HAVE_LIBXML2
 #include "xml-config.h"
@@ -59,7 +59,7 @@
 
 ConfigStore::ConfigStore ()
 {
-  ObjectBase::ConstructSelf (AttributeList ());
+  ObjectBase::ConstructSelf (AttributeConstructionList ());
 
 #ifdef HAVE_LIBXML2
   if (m_fileFormat == ConfigStore::XML)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/model/attribute-construction-list.cc	Wed Aug 03 13:58:10 2011 -0400
@@ -0,0 +1,77 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Mathieu Lacage
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Authors: Mathieu Lacage <mathieu.lacage@gmail.com>
+ */
+#include "attribute-construction-list.h"
+#include "log.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE("AttributeConstructionList");
+
+AttributeConstructionList::AttributeConstructionList ()
+{}
+
+void 
+AttributeConstructionList::Add (std::string name, Ptr<const AttributeChecker> checker, Ptr<AttributeValue> value)
+{
+  // get rid of any previous value stored in this
+  // vector of values.
+  for (std::list<struct Item>::iterator k = m_list.begin (); k != m_list.end (); k++)
+    {
+      if (k->checker == checker)
+        {
+          m_list.erase (k);
+          break;
+        }
+    }
+  // store the new value.
+  struct Item attr;
+  attr.checker = checker;
+  attr.value = value;
+  attr.name = name;
+  m_list.push_back (attr);
+
+}
+Ptr<AttributeValue> 
+AttributeConstructionList::Find (Ptr<const AttributeChecker> checker) const
+{
+  NS_LOG_FUNCTION (checker);
+  for (CIterator k = m_list.begin (); k != m_list.end (); k++)
+    {
+      NS_LOG_DEBUG ("Found " << k->name << " " << k->checker << " " << k->value);
+      if (k->checker == checker)
+        {
+	  return k->value;
+	}
+    }  
+  return 0;
+}
+
+AttributeConstructionList::CIterator 
+AttributeConstructionList::Begin (void) const
+{
+  return m_list.begin();
+}
+AttributeConstructionList::CIterator
+AttributeConstructionList::End (void) const
+{
+  return m_list.end();
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/model/attribute-construction-list.h	Wed Aug 03 13:58:10 2011 -0400
@@ -0,0 +1,50 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Mathieu Lacage
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Authors: Mathieu Lacage <mathieu.lacage@gmail.com>
+ */
+#ifndef ATTRIBUTE_CONSTRUCTION_LIST_H
+#define ATTRIBUTE_CONSTRUCTION_LIST_H
+
+#include "attribute.h"
+#include <list>
+
+namespace ns3 {
+
+class AttributeConstructionList
+{
+public:
+  struct Item 
+  {
+    Ptr<const AttributeChecker> checker;
+    Ptr<AttributeValue> value;
+    std::string name;
+  };
+  typedef std::list<struct Item>::const_iterator CIterator;
+
+  AttributeConstructionList ();
+  void Add (std::string name, Ptr<const AttributeChecker> checker, Ptr<AttributeValue> value);
+  Ptr<AttributeValue> Find (Ptr<const AttributeChecker> checker) const;
+  CIterator Begin (void) const;
+  CIterator End (void) const;
+private:
+  std::list<struct Item> m_list;
+};
+
+} // namespace ns3
+
+#endif /* ATTRIBUTE_CONSTRUCTION_LIST_H */
--- a/src/core/model/attribute-list.cc	Wed Aug 03 13:52:16 2011 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,262 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#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, const AttributeValue &value)
-{
-  struct TypeId::AttributeInformation 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, const AttributeValue &value)
-{
-  struct TypeId::AttributeInformation 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, const AttributeValue & value)
-{
-  struct TypeId::AttributeInformation 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, const AttributeValue &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::AttributeInformation *info, const AttributeValue &value)
-{
-  if (info->checker == 0)
-    {
-      return false;
-    }
-  bool ok = info->checker->Check (value);
-  if (ok)
-    {
-      DoSetOne (info->checker, value);
-      return true;
-    }
-
-  // attempt to convert to string.
-  const StringValue *str = dynamic_cast<const StringValue *> (&value);
-  if (str == 0)
-    {
-      return false;
-    }
-  // attempt to convert back to value.
-  Ptr<AttributeValue> v = info->checker->Create ();
-  ok = v->DeserializeFromString (str->Get (), info->checker);
-  if (!ok)
-    {
-      return false;
-    }
-  ok = info->checker->Check (*v);
-  if (!ok)
-    {
-      return false;
-    }
-  DoSetOne (info->checker, *v);
-  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.GetAttributeN (); j++)
-        {
-          struct TypeId::AttributeInformation info = tid.GetAttribute(j);
-          if (checker == info.checker)
-            {
-              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 ();)
-    {
-      std::string name = LookupAttributeFullNameByChecker (i->checker);
-      oss << name << "=" << i->value->SerializeToString (i->checker);
-      i++;
-      if (i != m_attributes.end ())
-        {
-          oss << "|";
-        }
-    }
-  return oss.str ();
-}
-bool 
-AttributeList::DeserializeFromString (std::string str)
-{
-  Reset ();
-
-  std::string::size_type cur;
-  cur = 0;
-  while (cur != str.size ())
-    {
-      std::string::size_type equal = str.find ("=", cur);
-      if (equal == std::string::npos)
-        {
-          NS_FATAL_ERROR ("Error while parsing serialized attribute: \"" << str << "\"");
-          break;
-        }
-      else
-        {
-          std::string name = str.substr (cur, equal-cur);
-          struct TypeId::AttributeInformation info;
-          if (!TypeId::LookupAttributeByFullName (name, &info))
-            {
-              NS_FATAL_ERROR ("Error while parsing serialized attribute: name does not exist: \"" << 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 = next + 1;
-                }
-              Ptr<AttributeValue> val = info.checker->Create ();
-              bool ok = val->DeserializeFromString (value, info.checker);
-              if (!ok)
-                {
-                  NS_FATAL_ERROR ("Error while parsing serialized attribute: value invalid: \"" << value << "\"");
-                  break;
-                }
-              else
-                {
-                  DoSetOne (info.checker, *val);
-                }
-            }
-        }
-    }
-
-  return true;
-}
-
-} // namespace ns3
--- a/src/core/model/attribute-list.h	Wed Aug 03 13:52:16 2011 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef ATTRIBUTE_LIST_H
-#define ATTRIBUTE_LIST_H
-
-#include <string>
-#include <vector>
-#include "attribute.h"
-#include "type-id.h"
-
-namespace ns3 {
-
-/**
- * \ingroup attribute
- *
- * \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, const AttributeValue &value);
-  /**
-   * \param name the full name of the attribute to set
-   * \param value the value to set
-   * \returns true if the requested attribute exists and could be
-   *          stored, false otherwise.
-   */
-  bool SetFailSafe (std::string name, const AttributeValue &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, const AttributeValue &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);
-
-  std::string SerializeToString (void) const;
-  bool DeserializeFromString (std::string value);
-private:
-  friend class ObjectBase;
-  struct Attr {
-    Ptr<const AttributeChecker> checker;
-    Ptr<const AttributeValue> value;
-  };
-  typedef std::vector<struct Attr> Attrs;
-  typedef Attrs::iterator Iterator;
-  typedef Attrs::const_iterator CIterator;
-
-
-
-  bool DoSet (struct TypeId::AttributeInformation *info, const AttributeValue &param);
-  void DoSetOne (Ptr<const AttributeChecker> checker, const AttributeValue &param);
-  std::string LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const;
-
-  Attrs m_attributes;
-};
-
-} // namespace ns3
-
-#endif /* ATTRIBUTE_LIST_H */
--- a/src/core/model/attribute.cc	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/model/attribute.cc	Wed Aug 03 13:58:10 2011 -0400
@@ -20,6 +20,7 @@
 #include "attribute.h"
 #include "log.h"
 #include "fatal-error.h"
+#include "string.h"
 #include <sstream>
 
 NS_LOG_COMPONENT_DEFINE ("AttributeValue");
@@ -48,6 +49,34 @@
 {
 }
 
+Ptr<AttributeValue> 
+AttributeChecker::CreateValidValue (const AttributeValue &value) const
+{
+  if (Check (value))
+    {
+      return value.Copy ();
+    }
+  // attempt to convert to string.
+  const StringValue *str = dynamic_cast<const StringValue *> (&value);
+  if (str == 0)
+    {
+      return 0;
+    }
+  // attempt to convert back to value.
+  Ptr<AttributeValue> v = Create ();
+  bool ok = v->DeserializeFromString (str->Get (), this);
+  if (!ok)
+    {
+      return 0;
+    }
+  ok = Check (*v);
+  if (!ok)
+    {
+      return 0;
+    }
+  return v;
+}
+
 EmptyAttributeValue::EmptyAttributeValue ()
 {
 }
--- a/src/core/model/attribute.h	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/model/attribute.h	Wed Aug 03 13:58:10 2011 -0400
@@ -151,6 +151,8 @@
 public:
   AttributeChecker ();
   virtual ~AttributeChecker ();
+
+  Ptr<AttributeValue> CreateValidValue (const AttributeValue &value) const;
   /**
    * \param value a pointer to the value to check
    * \returns true if the input value is both of the right type
@@ -191,6 +193,7 @@
 
   virtual bool Copy (const AttributeValue &source, AttributeValue &destination) const = 0;
 
+  
 };
 
 /**
--- a/src/core/model/config.cc	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/model/config.cc	Wed Aug 03 13:58:10 2011 -0400
@@ -583,17 +583,66 @@
 
 namespace Config {
 
+void Reset (void)
+{
+  // First, let's reset the initial value of every attribute
+  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++)
+    {
+      TypeId tid = TypeId::GetRegistered (i);
+      for (uint32_t j = 0; j < tid.GetAttributeN (); j++)
+        {
+          struct TypeId::AttributeInformation info = tid.GetAttribute (j);
+          tid.SetAttributeInitialValue (j, info.originalInitialValue);
+        }
+    }
+  // now, let's reset the initial value of every global value.
+  for (GlobalValue::Iterator i = GlobalValue::Begin (); i != GlobalValue::End (); ++i)
+    {
+      (*i)->ResetInitialValue ();
+    }
+}
+
 void Set (std::string path, const AttributeValue &value)
 {
   Singleton<ConfigImpl>::Get ()->Set (path, value);
 }
 void SetDefault (std::string name, const AttributeValue &value)
 {
-  AttributeList::GetGlobal ()->Set (name, value);
+  if (!SetDefaultFailSafe(name, value))
+    {
+      NS_FATAL_ERROR ("Could not set default value for " << name);
+    }
 }
-bool SetDefaultFailSafe (std::string name, const AttributeValue &value)
+bool SetDefaultFailSafe (std::string fullName, const AttributeValue &value)
 {
-  return AttributeList::GetGlobal ()->SetFailSafe (name, value);
+  std::string::size_type pos = fullName.rfind ("::");
+  if (pos == std::string::npos)
+    {
+      return false;
+    }
+  std::string tidName = fullName.substr (0, pos);
+  std::string paramName = fullName.substr (pos+2, fullName.size () - (pos+2));
+  TypeId tid;
+  bool ok = TypeId::LookupByNameFailSafe (tidName, &tid);
+  if (!ok)
+    {
+      return false;
+    }
+  for (uint32_t j = 0; j < tid.GetAttributeN (); j++)
+    {
+      struct TypeId::AttributeInformation tmp = tid.GetAttribute(j);
+      if (tmp.name == paramName)
+        {
+          Ptr<AttributeValue> v = tmp.checker->CreateValidValue (value);
+          if (v == 0)
+            {
+              return false;
+            }
+          tid.SetAttributeInitialValue (j, v);
+          return true;
+        }
+    }
+  return false;
 }
 void SetGlobal (std::string name, const AttributeValue &value)
 {
--- a/src/core/model/config.h	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/model/config.h	Wed Aug 03 13:58:10 2011 -0400
@@ -37,6 +37,12 @@
 namespace Config {
 
 /**
+ * Reset the initial value of every attribute as well as the value of every
+ * global to what they were before any call to SetDefault and SetGlobal.
+ */
+void Reset (void);
+
+/**
  * \param path a path to match attributes.
  * \param value the value to set in all matching attributes.
  *
--- a/src/core/model/global-value.cc	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/model/global-value.cc	Wed Aug 03 13:58:10 2011 -0400
@@ -35,13 +35,20 @@
                           Ptr<const AttributeChecker> checker)
   : m_name (name),
     m_help (help),
-    m_initialValue (initialValue.Copy ()),
+    m_initialValue (0),
+    m_currentValue (0),
     m_checker (checker)
 {
   if (m_checker == 0)
     {
       NS_FATAL_ERROR ("Checker should not be zero.");
     }
+  m_initialValue = m_checker->CreateValidValue (initialValue);
+  m_currentValue = m_initialValue;
+  if (m_initialValue == 0)
+    {
+      NS_FATAL_ERROR ("Value set by user is invalid.");
+    }
   GetVector ()->push_back (this);
   InitializeFromEnv ();
 }
@@ -69,7 +76,13 @@
           std::string value = tmp.substr (equal+1, tmp.size () - equal - 1);
           if (name == m_name)
             {
-              SetValue (StringValue (value));
+              Ptr<AttributeValue> v = m_checker->CreateValidValue (StringValue (value));
+              if (v != 0)
+                {
+                  m_initialValue = v;
+                  m_currentValue = v;
+                }
+              return;
             }
         }
       cur = next + 1;
@@ -90,7 +103,7 @@
 void
 GlobalValue::GetValue (AttributeValue &value) const
 {
-  bool ok = m_checker->Copy (*m_initialValue, value);
+  bool ok = m_checker->Copy (*m_currentValue, value);
   if (ok)
     {
       return;
@@ -100,7 +113,7 @@
     {
       NS_FATAL_ERROR ("GlobalValue name="<<m_name<<": input value is not a string");
     }
-  str->Set (m_initialValue->SerializeToString (m_checker));
+  str->Set (m_currentValue->SerializeToString (m_checker));
 }
 Ptr<const AttributeChecker> 
 GlobalValue::GetChecker (void) const
@@ -111,30 +124,12 @@
 bool
 GlobalValue::SetValue (const AttributeValue &value)
 {
-  if (m_checker->Check (value))
+  Ptr<AttributeValue> v = m_checker->CreateValidValue (value);
+  if (v == 0)
     {
-      m_initialValue = value.Copy ();
-      return true;
-    }
-  // attempt to convert to string.
-  const StringValue *str = dynamic_cast<const StringValue *> (&value);
-  if (str == 0)
-    {
-      return false;
+      return 0;
     }
-  // attempt to convert back to value.
-  Ptr<AttributeValue> v = m_checker->Create ();
-  bool ok = v->DeserializeFromString (str->Get (), m_checker);
-  if (!ok)
-    {
-      return false;
-    }
-  ok = m_checker->Check (*v);
-  if (!ok)
-    {
-      return false;
-    }
-  m_checker->Copy (*v, *PeekPointer (m_initialValue));
+  m_currentValue = v;
   return true;
 }
 
@@ -177,6 +172,12 @@
   return GetVector ()->end ();
 }
 
+void 
+GlobalValue::ResetInitialValue (void)
+{
+  m_currentValue = m_initialValue;
+}
+
 bool
 GlobalValue::GetValueByNameFailSafe (std::string name, AttributeValue &value)
 {
--- a/src/core/model/global-value.h	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/model/global-value.h	Wed Aug 03 13:58:10 2011 -0400
@@ -85,6 +85,8 @@
    */
   bool SetValue (const AttributeValue &value);
 
+  void ResetInitialValue (void);
+
   /**
    * \param name the name of the global value
    * \param value the value to set in the requested global value.
@@ -146,6 +148,7 @@
   std::string m_name;
   std::string m_help;
   Ptr<AttributeValue> m_initialValue;
+  Ptr<AttributeValue> m_currentValue;
   Ptr<const AttributeChecker> m_checker;
 };
 
--- a/src/core/model/object-base.cc	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/model/object-base.cc	Wed Aug 03 13:58:10 2011 -0400
@@ -20,7 +20,7 @@
 #include "object-base.h"
 #include "log.h"
 #include "trace-source-accessor.h"
-#include "attribute-list.h"
+#include "attribute-construction-list.h"
 #include "string.h"
 #include "ns3/core-config.h"
 #ifdef HAVE_STDLIB_H
@@ -57,7 +57,7 @@
 {}
 
 void
-ObjectBase::ConstructSelf (const AttributeList &attributes)
+ObjectBase::ConstructSelf (const AttributeConstructionList &attributes)
 {
   // loop over the inheritance tree back to the Object base class.
   TypeId tid = GetInstanceTypeId ();
@@ -74,41 +74,19 @@
               continue;
             }
           bool found = false;
-          // is this attribute stored in this AttributeList instance ?
-          for (AttributeList::Attrs::const_iterator j = attributes.m_attributes.begin ();
-               j != attributes.m_attributes.end (); j++)
-            {
-              if (j->checker == info.checker)
-                {
-                  // We have a matching attribute value.
-                  if (DoSet (info.accessor, info.checker, *j->value))
-                    {
-                      NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
-                                    info.name<<"\"");
-                      found = true;
-                      break;
-                    }
-                }
-            }
-          if (!found)
+          // is this attribute stored in this AttributeConstructionList instance ?
+          Ptr<AttributeValue> value = attributes.Find(info.checker);
+          if (value != 0)
             {
-              // is this attribute stored in the global instance ?
-              for (AttributeList::Attrs::const_iterator j = AttributeList::GetGlobal ()->m_attributes.begin ();
-                   j != AttributeList::GetGlobal ()->m_attributes.end (); j++)
+              // We have a matching attribute value.
+              if (DoSet (info.accessor, info.checker, *value))
                 {
-                  if (j->checker == info.checker)
-                    {
-                      // We have a matching attribute value.
-                      if (DoSet (info.accessor, info.checker, *j->value))
-                        {
-                          NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
-                                        info.name <<"\" from global");
-                          found = true;
-                          break;
-                        }
-                    }
+                  NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
+                                info.name<<"\"");
+                  found = true;
+                  continue;
                 }
-            }
+            }              
           if (!found)
             {
               // No matching attribute value so we try to look at the env var.
@@ -162,31 +140,12 @@
                    Ptr<const AttributeChecker> checker,
                    const AttributeValue &value)
 {
-  bool ok = checker->Check (value);
-  if (ok)
-    {
-      ok = accessor->Set (this, value);
-      return ok;
-    }
-  // attempt to convert to string
-  const StringValue *str = dynamic_cast<const StringValue *> (&value);
-  if (str == 0)
+  Ptr<AttributeValue> v = checker->CreateValidValue (value);
+  if (v == 0)
     {
       return false;
     }
-  // attempt to convert back from string.
-  Ptr<AttributeValue> v = checker->Create ();
-  ok = v->DeserializeFromString (str->Get (), checker);
-  if (!ok)
-    {
-      return false;
-    }
-  ok = checker->Check (*v);
-  if (!ok)
-    {
-      return false;
-    }
-  ok = accessor->Set (this, *v);
+  bool ok = accessor->Set (this, *v);
   return ok;
 }
 void
--- a/src/core/model/object-base.h	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/model/object-base.h	Wed Aug 03 13:58:10 2011 -0400
@@ -23,6 +23,7 @@
 #include "type-id.h"
 #include "callback.h"
 #include <string>
+#include <list>
 
 /**
  * This macro should be invoked once for every class which
@@ -39,7 +40,7 @@
 
 namespace ns3 {
 
-class AttributeList;
+class AttributeConstructionList;
 
 /**
  * \ingroup object
@@ -150,7 +151,7 @@
    * you should make sure that you invoke this method from
    * your most-derived constructor.
    */
-  void ConstructSelf (const AttributeList &attributes);
+  void ConstructSelf (const AttributeConstructionList &attributes);
 
 private:
   bool DoSet (Ptr<const AttributeAccessor> spec,
--- a/src/core/model/object-factory.cc	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/model/object-factory.cc	Wed Aug 03 13:58:10 2011 -0400
@@ -18,14 +18,22 @@
  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 #include "object-factory.h"
+#include "log.h"
 #include <sstream>
 
 namespace ns3 {
 
+NS_LOG_COMPONENT_DEFINE("ObjectFactory");
+
 ObjectFactory::ObjectFactory ()
 {
 }
 
+ObjectFactory::ObjectFactory (std::string typeId)
+{
+  SetTypeId (typeId);
+}
+
 void
 ObjectFactory::SetTypeId (TypeId tid)
 {
@@ -48,13 +56,20 @@
     {
       return;
     }
-  m_parameters.SetWithTid (m_tid, name, value);
-}
-
-void 
-ObjectFactory::Set (const AttributeList &list)
-{
-  m_parameters = list;
+  
+  struct TypeId::AttributeInformation info;
+  if (!m_tid.LookupAttributeByName (name, &info))
+    {
+      NS_FATAL_ERROR ("Invalid attribute set (" << name << ") on " << m_tid.GetName ());
+      return;
+    }
+  Ptr<AttributeValue> v = info.checker->CreateValidValue (value);
+  if (v == 0)
+    {
+      NS_FATAL_ERROR ("Invalid value for attribute set (" << name << ") on " << m_tid.GetName ());
+      return;
+    }
+  m_parameters.Add (name, info.checker, v);
 }
 
 TypeId 
@@ -77,7 +92,17 @@
 
 std::ostream & operator << (std::ostream &os, const ObjectFactory &factory)
 {
-  os << factory.m_tid.GetName () << "[" << factory.m_parameters.SerializeToString () << "]";
+  os << factory.m_tid.GetName () << "[";
+  bool first = true;
+  for (AttributeConstructionList::CIterator i = factory.m_parameters.Begin (); i != factory.m_parameters.End (); ++i)
+    {
+      os << i->name << "=" << i->value->SerializeToString (i->checker);
+      if (first)
+        {
+          os << "|";
+        }
+    }
+  os << "]";
   return os;
 }
 std::istream & operator >> (std::istream &is, ObjectFactory &factory)
@@ -92,7 +117,56 @@
   std::string tid = v.substr (0, lbracket);
   std::string parameters = v.substr (lbracket+1,rbracket-(lbracket+1));
   factory.SetTypeId (tid);
-  factory.m_parameters.DeserializeFromString (parameters);
+  std::string::size_type cur;
+  cur = 0;
+  while (cur != parameters.size ())
+    {
+      std::string::size_type equal = parameters.find ("=", cur);
+      if (equal == std::string::npos)
+        {
+          is.setstate (std::ios_base::failbit);
+          NS_LOG_DEBUG ("Error while parsing serialized attribute: \"" << parameters << "\"");
+          break;
+        }
+      else
+        {
+          std::string name = parameters.substr (cur, equal-cur);
+          struct TypeId::AttributeInformation info;
+          if (!factory.m_tid.LookupAttributeByName (name, &info))
+            {
+              is.setstate (std::ios_base::failbit);
+              NS_LOG_DEBUG ("Error while parsing serialized attribute: name does not exist: \"" << name << "\"");
+              break;
+            }
+          else
+            {
+              std::string::size_type next = parameters.find ("|", cur);
+              std::string value;
+              if (next == std::string::npos)
+                {
+                  value = parameters.substr (equal+1, parameters.size () - (equal+1));
+                  cur = parameters.size ();
+                }
+              else
+                {
+                  value = parameters.substr (equal+1, next - (equal+1));
+                  cur = next + 1;
+                }
+              Ptr<AttributeValue> val = info.checker->Create ();
+              bool ok = val->DeserializeFromString (value, info.checker);
+              if (!ok)
+                {
+                  is.setstate (std::ios_base::failbit);
+                  NS_LOG_DEBUG ("Error while parsing serialized attribute: value invalid: \"" << value << "\"");
+                  break;
+                }
+              else
+                {
+                  factory.m_parameters.Add (name, info.checker, val);
+                }
+            }
+        }
+    }
   return is;
 }
 
--- a/src/core/model/object-factory.h	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/model/object-factory.h	Wed Aug 03 13:58:10 2011 -0400
@@ -20,7 +20,7 @@
 #ifndef OBJECT_FACTORY_H
 #define OBJECT_FACTORY_H
 
-#include "attribute-list.h"
+#include "attribute-construction-list.h"
 #include "object.h"
 #include "type-id.h"
 
@@ -40,6 +40,7 @@
 {
 public:
   ObjectFactory ();
+  ObjectFactory (std::string typeId);
 
   /**
    * \param tid the TypeId of the object to instantiate.
@@ -59,8 +60,6 @@
    */
   void Set (std::string name, const AttributeValue &value);
 
-  void Set (const AttributeList &list);
-
   /**
    * \returns the currently-selected TypeId to use to create an object
    *          instance.
@@ -86,12 +85,52 @@
   friend std::istream & operator >> (std::istream &is, ObjectFactory &factory);
 
   TypeId m_tid;
-  AttributeList m_parameters;
+  AttributeConstructionList m_parameters;
 };
 
 std::ostream & operator << (std::ostream &os, const ObjectFactory &factory);
 std::istream & operator >> (std::istream &is, ObjectFactory &factory);
 
+
+/**
+ * \param n1 name of attribute
+ * \param v1 value of attribute
+ * \param n2 name of attribute
+ * \param v2 value of attribute
+ * \param n3 name of attribute
+ * \param v3 value of attribute
+ * \param n4 name of attribute
+ * \param v4 value of attribute
+ * \param n5 name of attribute
+ * \param v5 value of attribute
+ * \param n6 name of attribute
+ * \param v6 value of attribute
+ * \param n7 name of attribute
+ * \param v7 value of attribute
+ * \param n8 name of attribute
+ * \param v8 value of attribute
+ * \param n9 name of attribute
+ * \param v9 value of attribute
+ * \returns a pointer to a newly allocated object.
+ *
+ * This allocates an object on the heap and initializes
+ * it with a set of attributes.
+ */
+template <typename T>
+Ptr<T> 
+CreateObjectWithAttributes (std::string n1 = "", const AttributeValue & v1 = EmptyAttributeValue (),
+                            std::string n2 = "", const AttributeValue & v2 = EmptyAttributeValue (),
+                            std::string n3 = "", const AttributeValue & v3 = EmptyAttributeValue (),
+                            std::string n4 = "", const AttributeValue & v4 = EmptyAttributeValue (),
+                            std::string n5 = "", const AttributeValue & v5 = EmptyAttributeValue (),
+                            std::string n6 = "", const AttributeValue & v6 = EmptyAttributeValue (),
+                            std::string n7 = "", const AttributeValue & v7 = EmptyAttributeValue (),
+                            std::string n8 = "", const AttributeValue & v8 = EmptyAttributeValue (),
+                            std::string n9 = "", const AttributeValue & v9 = EmptyAttributeValue ());
+
+
+
+
 /**
  * \class ns3::ObjectFactoryValue
  * \brief hold objects of type ns3::ObjectFactory
@@ -111,6 +150,33 @@
   return object->GetObject<T> ();
 }
 
+template <typename T>
+Ptr<T> 
+CreateObjectWithAttributes (std::string n1, const AttributeValue & v1,
+                            std::string n2, const AttributeValue & v2,
+                            std::string n3, const AttributeValue & v3,
+                            std::string n4, const AttributeValue & v4,
+                            std::string n5, const AttributeValue & v5,
+                            std::string n6, const AttributeValue & v6,
+                            std::string n7, const AttributeValue & v7,
+                            std::string n8, const AttributeValue & v8,
+                            std::string n9, const AttributeValue & v9)
+{
+  ObjectFactory factory;
+  factory.SetTypeId (T::GetTypeId ());
+  factory.Set(n1, v1);
+  factory.Set(n2, v2);
+  factory.Set(n3, v3);
+  factory.Set(n4, v4);
+  factory.Set(n5, v5);
+  factory.Set(n6, v6);
+  factory.Set(n7, v7);
+  factory.Set(n8, v8);
+  factory.Set(n9, v9);
+  return factory.Create<T> ();
+}
+
+
 } // namespace ns3
 
 #endif /* OBJECT_FACTORY_H */
--- a/src/core/model/object.cc	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/model/object.cc	Wed Aug 03 13:58:10 2011 -0400
@@ -125,7 +125,7 @@
   m_aggregates->buffer[0] = this;
 }
 void
-Object::Construct (const AttributeList &attributes)
+Object::Construct (const AttributeConstructionList &attributes)
 {
   ConstructSelf (attributes);
 }
--- a/src/core/model/object.h	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/model/object.h	Wed Aug 03 13:58:10 2011 -0400
@@ -27,7 +27,7 @@
 #include "ptr.h"
 #include "attribute.h"
 #include "object-base.h"
-#include "attribute-list.h"
+#include "attribute-construction-list.h"
 #include "simple-ref-count.h"
 
 
@@ -36,7 +36,6 @@
 class Object;
 class AttributeAccessor;
 class AttributeValue;
-class AttributeList;
 class TraceSourceAccessor;
 
 struct ObjectDeleter
@@ -217,15 +216,13 @@
 private:
 
   template <typename T>
-  friend Ptr<T> CreateObjectWithAttributes (const AttributeList &attributes);
-  template <typename T>
   friend Ptr<T> CopyObject (Ptr<T> object);
   template <typename T>
   friend Ptr<T> CopyObject (Ptr<const T> object);
   // The following friend method declaration is used only
   // by our python bindings to call the protected ObjectBase::Construct
   // method.
-  friend void PythonCompleteConstruct (Ptr<Object> object, TypeId typeId, const AttributeList &attributes);
+  friend void PythonCompleteConstruct (Ptr<Object> object, TypeId typeId, const AttributeConstructionList &attributes);
   template <typename T>
   friend Ptr<T> CompleteConstruct (T *object);
 
@@ -267,7 +264,7 @@
   * Initialize all the member variables which were
   * registered with the associated TypeId.
   */
-  void Construct (const AttributeList &attributes);
+  void Construct (const AttributeConstructionList &attributes);
 
   void UpdateSortedArray (struct Aggregates *aggregates, uint32_t i) const;
   /**
@@ -320,56 +317,6 @@
 template <typename T>
 Ptr<T> CopyObject (Ptr<T> object);
 
-
-/**
- * \param attributes a list of attributes to set on the 
- *        object during construction.
- * \returns a pointer to a newly allocated object.
- *
- * This allocates an object on the heap and initializes
- * it with a set of attributes.
- */
-template <typename T>
-Ptr<T> CreateObjectWithAttributes (const AttributeList &attributes);
-
-/**
- * \param n1 name of attribute
- * \param v1 value of attribute
- * \param n2 name of attribute
- * \param v2 value of attribute
- * \param n3 name of attribute
- * \param v3 value of attribute
- * \param n4 name of attribute
- * \param v4 value of attribute
- * \param n5 name of attribute
- * \param v5 value of attribute
- * \param n6 name of attribute
- * \param v6 value of attribute
- * \param n7 name of attribute
- * \param v7 value of attribute
- * \param n8 name of attribute
- * \param v8 value of attribute
- * \param n9 name of attribute
- * \param v9 value of attribute
- * \returns a pointer to a newly allocated object.
- *
- * This allocates an object on the heap and initializes
- * it with a set of attributes.
- */
-template <typename T>
-Ptr<T> 
-CreateObjectWithAttributes (std::string n1 = "", const AttributeValue & v1 = EmptyAttributeValue (),
-                            std::string n2 = "", const AttributeValue & v2 = EmptyAttributeValue (),
-                            std::string n3 = "", const AttributeValue & v3 = EmptyAttributeValue (),
-                            std::string n4 = "", const AttributeValue & v4 = EmptyAttributeValue (),
-                            std::string n5 = "", const AttributeValue & v5 = EmptyAttributeValue (),
-                            std::string n6 = "", const AttributeValue & v6 = EmptyAttributeValue (),
-                            std::string n7 = "", const AttributeValue & v7 = EmptyAttributeValue (),
-                            std::string n8 = "", const AttributeValue & v8 = EmptyAttributeValue (),
-                            std::string n9 = "", const AttributeValue & v9 = EmptyAttributeValue ());
-
-
-
 } // namespace ns3
 
 namespace ns3 {
@@ -440,79 +387,9 @@
 Ptr<T> CompleteConstruct (T *p)
 {
   p->SetTypeId (T::GetTypeId ());
-  p->Object::Construct (AttributeList ());
+  p->Object::Construct (AttributeConstructionList ());
   return Ptr<T> (p, false);
 }
-template <typename T>
-Ptr<T> CreateObjectWithAttributes (const AttributeList &attributes)
-{
-  Ptr<T> p = Ptr<T> (new T (), false);
-  p->SetTypeId (T::GetTypeId ());
-  p->Object::Construct (attributes);
-  return p;
-}
-
-template <typename T>
-Ptr<T> 
-CreateObjectWithAttributes (std::string n1, const AttributeValue & v1,
-                            std::string n2, const AttributeValue & v2,
-                            std::string n3, const AttributeValue & v3,
-                            std::string n4, const AttributeValue & v4,
-                            std::string n5, const AttributeValue & v5,
-                            std::string n6, const AttributeValue & v6,
-                            std::string n7, const AttributeValue & v7,
-                            std::string n8, const AttributeValue & v8,
-                            std::string n9, const AttributeValue & v9)
-{
-  AttributeList attributes;
-  if (n1 == "")
-    {
-      goto end;
-    }
-  attributes.SetWithTid (T::GetTypeId (), n1, v1);
-  if (n2 == "")
-    {
-      goto end;
-    }
-  attributes.SetWithTid (T::GetTypeId (), n2, v2);
-  if (n3 == "")
-    {
-      goto end;
-    }
-  attributes.SetWithTid (T::GetTypeId (), n3, v3);
-  if (n4 == "")
-    {
-      goto end;
-    }
-  attributes.SetWithTid (T::GetTypeId (), n4, v4);
-  if (n5 == "")
-    {
-      goto end;
-    }
-  attributes.SetWithTid (T::GetTypeId (), n5, v5);
-  if (n6 == "")
-    {
-      goto end;
-    }
-  attributes.SetWithTid (T::GetTypeId (), n6, v6);
-  if (n7 == "")
-    {
-      goto end;
-    }
-  attributes.SetWithTid (T::GetTypeId (), n7, v7);
-  if (n8 == "")
-    {
-      goto end;
-    }
-  attributes.SetWithTid (T::GetTypeId (), n8, v8);
-  if (n9 == "")
-    {
-      goto end;
-    }
-  attributes.SetWithTid (T::GetTypeId (), n9, v9);
-end:
-  return CreateObjectWithAttributes<T> (attributes);
-}
 
 template <typename T>
 Ptr<T> CreateObject (void)
--- a/src/core/model/type-id.cc	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/model/type-id.cc	Wed Aug 03 13:58:10 2011 -0400
@@ -53,6 +53,9 @@
                      ns3::Ptr<const ns3::AttributeValue> initialValue,
                      ns3::Ptr<const ns3::AttributeAccessor> spec,
                      ns3::Ptr<const ns3::AttributeChecker> checker);
+  void SetAttributeInitialValue(uint16_t uid,
+                                uint32_t i,
+                                ns3::Ptr<const ns3::AttributeValue> initialValue);
   uint32_t GetAttributeN (uint16_t uid) const;
   struct ns3::TypeId::AttributeInformation GetAttribute(uint16_t uid, uint32_t i) const;
   void AddTraceSource (uint16_t uid,
@@ -262,10 +265,21 @@
   info.help = help;
   info.flags = flags;
   info.initialValue = initialValue;
+  info.originalInitialValue = initialValue;
   info.accessor = accessor;
   info.checker = checker;
   information->attributes.push_back (info);
 }
+void 
+IidManager::SetAttributeInitialValue(uint16_t uid,
+                                     uint32_t i,
+                                     ns3::Ptr<const ns3::AttributeValue> initialValue)
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->attributes.size ());
+  information->attributes[i].initialValue = initialValue;
+}
+
 
 
 uint32_t 
@@ -386,24 +400,6 @@
   return true;
 }
 
-bool
-TypeId::LookupAttributeByFullName (std::string fullName, struct TypeId::AttributeInformation *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)
 {
@@ -520,6 +516,15 @@
   return *this;
 }
 
+bool 
+TypeId::SetAttributeInitialValue(uint32_t i, 
+                                 Ptr<const AttributeValue> initialValue)
+{
+  Singleton<IidManager>::Get ()->SetAttributeInitialValue (m_tid, i, initialValue);
+  return true;
+}
+
+
 Callback<ObjectBase *> 
 TypeId::GetConstructor (void) const
 {
--- a/src/core/model/type-id.h	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/model/type-id.h	Wed Aug 03 13:58:10 2011 -0400
@@ -57,6 +57,7 @@
     std::string name;
     std::string help;
     uint32_t flags;
+    ns3::Ptr<const ns3::AttributeValue> originalInitialValue;
     ns3::Ptr<const ns3::AttributeValue> initialValue;
     ns3::Ptr<const ns3::AttributeAccessor> accessor;
     ns3::Ptr<const ns3::AttributeChecker> checker;
@@ -68,6 +69,12 @@
   };
 
   /**
+   * Reset the initial value of every attribute to the one
+   * that was specified by the associated object implementation.
+   */
+  static void ResetInitialValues(void);
+
+  /**
    * \param name the name of the requested TypeId
    * \returns the unique id associated with the requested
    *          name. 
@@ -235,6 +242,14 @@
                        Ptr<const AttributeChecker> checker);
 
   /**
+   * \param i the attribute to manipulate
+   * \param initialValue the new initial value to use for this attribute.
+   * \returns true if the call was successfuly, false otherwise.
+   */
+  bool SetAttributeInitialValue(uint32_t i, 
+                                Ptr<const AttributeValue> initialValue);
+
+  /**
    * \param name the name of the new attribute
    * \param help some help text which describes the purpose of this
    *        attribute
@@ -283,15 +298,6 @@
    */
   Ptr<const TraceSourceAccessor> LookupTraceSourceByName (std::string name) const;
 
-
-  /**
-   * \param fullName the full name of the requested attribute
-   * \param info a pointer to the TypeId::AttributeInformation 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 AttributeInformation *info);
-
   /**
    * \returns the internal integer which uniquely identifies this
    *          TypeId.
--- a/src/core/test/attribute-test-suite.cc	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/test/attribute-test-suite.cc	Wed Aug 03 13:58:10 2011 -0400
@@ -21,6 +21,7 @@
 #include "ns3/boolean.h"
 #include "ns3/integer.h"
 #include "ns3/uinteger.h"
+#include "ns3/config.h"
 #include "ns3/enum.h"
 #include "ns3/string.h"
 #include "ns3/random-variable.h"
@@ -280,31 +281,17 @@
 template <> void
 AttributeTestCase<BooleanValue>::DoRun (void)
 {
-  AttributeList attrs;
   Ptr<AttributeObjectTest> p;
   bool ok;
 
-  //
-  // Test setting a boolean via string representation using AttributeList.
-  //
-  ok = attrs.SetFailSafe ("ns3::AttributeObjectTest::TestBoolName", StringValue ("false"));
-  NS_TEST_ASSERT_MSG_EQ (ok, true, "Could not SetFailSafe() \"ns3::AttributeObjectTest::TestBoolName\" into AttributeList");
-
-  //
-  // Create an object using that attribute list (which should therefore have the
-  // boolean from above set to false.
-  //
-  p = CreateObjectWithAttributes<AttributeObjectTest> (attrs);
-  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObjectWithAttributes");
-
-  ok = CheckGetCodePaths (p, "TestBoolName", "false", BooleanValue (false));
-  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly from CreateObjectWithAttributes");
+  p = CreateObject<AttributeObjectTest> ();
+  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
 
   //
   // Set the default value of the BooleanValue and create an object.  The new
   // default value should stick.
   //
-  AttributeList::GetGlobal ()->SetFailSafe ("ns3::AttributeObjectTest::TestBoolName", StringValue ("true"));
+  Config::SetDefault ("ns3::AttributeObjectTest::TestBoolName", StringValue ("true"));
   p = CreateObject<AttributeObjectTest> ();
   NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
 
@@ -315,7 +302,7 @@
   // Set the default value of the BooleanValue the other way and create an object.
   // The new default value should stick.
   //
-  AttributeList::GetGlobal ()->SetFailSafe ("ns3::AttributeObjectTest::TestBoolName", StringValue ("false"));
+  Config::SetDefaultFailSafe ("ns3::AttributeObjectTest::TestBoolName", StringValue ("false"));
 
   p = CreateObject<AttributeObjectTest> ();
   NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
@@ -342,22 +329,10 @@
   NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by SetAttributeFailSafe() via StringValue");
 
   //
-  // Create an object using individually provided StringValue Attribute.
+  // Create an object using
   //
-  p = CreateObjectWithAttributes<AttributeObjectTest> ("TestBoolName", StringValue ("true"));
-  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObjectWithAttributes");
-
-  ok = CheckGetCodePaths (p, "TestBoolName", "true", BooleanValue (true));
-  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by CreateObjectWithAttributes() with StringValue");
-
-  //
-  // Create an object using individually provided BooleanValue Attribute.
-  //
-  p = CreateObjectWithAttributes<AttributeObjectTest> ("TestBoolName", BooleanValue (false));
-  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObjectWithAttributes");
-
-  ok = CheckGetCodePaths (p, "TestBoolName", "false", BooleanValue (false));
-  NS_TEST_ASSERT_MSG_EQ (ok, true, "Attribute not set properly by CreateObjectWithAttributes() with BooleanValue");
+  p = CreateObject<AttributeObjectTest> ();
+  NS_TEST_ASSERT_MSG_NE (p, 0, "Unable to CreateObject");
 
   //
   // The previous object-based tests checked access directly.  Now check through
@@ -1044,17 +1019,6 @@
   p->GetAttribute ("Pointer", ptr);
   Ptr<AttributeObjectTest> x = ptr.Get<AttributeObjectTest> ();
   NS_TEST_ASSERT_MSG_EQ (x, 0, "Unexpectedly retreived unrelated Ptr<type> from stored Ptr<Derived>");
-
-  //
-  // We should be able to create the object From a list of attributes.
-  //
-  p = CreateObjectWithAttributes<AttributeObjectTest> ("Pointer", PointerValue (Create<Derived> ()));
-  NS_TEST_ASSERT_MSG_NE (p, 0, "Could not create Object with PointerValue Attribute in Attribute List");
-
-  derived = 0;
-  p->GetAttribute ("Pointer", ptr);
-  derived = ptr.Get<Derived> ();
-  NS_TEST_ASSERT_MSG_NE (p, 0, "Retrieved zero PointerValue Attribute after initializing to non-zero Ptr");
 }
 
 // ===========================================================================
--- a/src/core/wscript	Wed Aug 03 13:52:16 2011 -0400
+++ b/src/core/wscript	Wed Aug 03 13:58:10 2011 -0400
@@ -119,7 +119,7 @@
         'model/log.cc',
         'model/breakpoint.cc',
         'model/type-id.cc',
-        'model/attribute-list.cc',
+        'model/attribute-construction-list.cc',
         'model/object-base.cc',
         'model/ref-count-base.cc',
         'model/object.cc',
@@ -199,7 +199,7 @@
         'model/ref-count-base.h',
         'model/simple-ref-count.h',
         'model/type-id.h',
-        'model/attribute-list.h',
+        'model/attribute-construction-list.h',
         'model/ptr.h',
         'model/object.h',
         'model/log.h',