merge with HEAD
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Mon, 27 Oct 2008 12:17:38 +0100
changeset 3815 ffea4fa619db
parent 3814 f4ffcfc3a8ad (current diff)
parent 3795 707acdf0f8b3 (diff)
child 3816 edd4928b2046
merge with HEAD
samples/wscript
--- a/bindings/python/ns3_module_common.py	Wed Oct 15 15:53:06 2008 +0200
+++ b/bindings/python/ns3_module_common.py	Mon Oct 27 12:17:38 2008 +0100
@@ -13,6 +13,14 @@
     module.add_class('DataRate')
     ## packet.h: ns3::Packet [class]
     module.add_class('Packet', memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
+    ## packet-metadata.h: ns3::PacketMetadata [class]
+    module.add_class('PacketMetadata')
+    ## packet-metadata.h: ns3::PacketMetadata::Item [struct]
+    module.add_class('Item', outer_class=root_module['ns3::PacketMetadata'])
+    ## packet-metadata.h: ns3::PacketMetadata::Item [enumeration]
+    module.add_enum('', ['PAYLOAD', 'HEADER', 'TRAILER'], outer_class=root_module['ns3::PacketMetadata::Item'])
+    ## packet-metadata.h: ns3::PacketMetadata::ItemIterator [class]
+    module.add_class('ItemIterator', outer_class=root_module['ns3::PacketMetadata'])
     ## tag.h: ns3::Tag [class]
     module.add_class('Tag', parent=root_module['ns3::ObjectBase'])
     ## tag-buffer.h: ns3::TagBuffer [class]
@@ -91,6 +99,9 @@
     register_Ns3BufferIterator_methods(root_module, root_module['ns3::Buffer::Iterator'])
     register_Ns3DataRate_methods(root_module, root_module['ns3::DataRate'])
     register_Ns3Packet_methods(root_module, root_module['ns3::Packet'])
+    register_Ns3PacketMetadata_methods(root_module, root_module['ns3::PacketMetadata'])
+    register_Ns3PacketMetadataItem_methods(root_module, root_module['ns3::PacketMetadata::Item'])
+    register_Ns3PacketMetadataItemIterator_methods(root_module, root_module['ns3::PacketMetadata::ItemIterator'])
     register_Ns3Tag_methods(root_module, root_module['ns3::Tag'])
     register_Ns3TagBuffer_methods(root_module, root_module['ns3::TagBuffer'])
     register_Ns3TagIterator_methods(root_module, root_module['ns3::TagIterator'])
@@ -394,6 +405,11 @@
                    'ns3::Ptr< ns3::Packet >', 
                    [], 
                    is_const=True)
+    ## packet.h: uint32_t ns3::Packet::CopyData(uint8_t * buffer, uint32_t size) const [member function]
+    cls.add_method('CopyData', 
+                   'uint32_t', 
+                   [param('uint8_t *', 'buffer'), param('uint32_t', 'size')], 
+                   is_const=True)
     ## packet.h: ns3::Ptr<ns3::Packet> ns3::Packet::CreateFragment(uint32_t start, uint32_t length) const [member function]
     cls.add_method('CreateFragment', 
                    'ns3::Ptr< ns3::Packet >', 
@@ -489,6 +505,119 @@
                    is_const=True)
     return
 
+def register_Ns3PacketMetadata_methods(root_module, cls):
+    ## packet-metadata.h: static void ns3::PacketMetadata::Enable() [member function]
+    cls.add_method('Enable', 
+                   'void', 
+                   [], 
+                   is_static=True)
+    ## packet-metadata.h: static void ns3::PacketMetadata::EnableChecking() [member function]
+    cls.add_method('EnableChecking', 
+                   'void', 
+                   [], 
+                   is_static=True)
+    ## packet-metadata.h: ns3::PacketMetadata::PacketMetadata(uint32_t uid, uint32_t size) [constructor]
+    cls.add_constructor([param('uint32_t', 'uid'), param('uint32_t', 'size')])
+    ## packet-metadata.h: ns3::PacketMetadata::PacketMetadata(ns3::PacketMetadata const & o) [copy constructor]
+    cls.add_constructor([param('ns3::PacketMetadata const &', 'o')])
+    ## packet-metadata.h: void ns3::PacketMetadata::AddHeader(ns3::Header const & header, uint32_t size) [member function]
+    cls.add_method('AddHeader', 
+                   'void', 
+                   [param('ns3::Header const &', 'header'), param('uint32_t', 'size')])
+    ## packet-metadata.h: void ns3::PacketMetadata::RemoveHeader(ns3::Header const & header, uint32_t size) [member function]
+    cls.add_method('RemoveHeader', 
+                   'void', 
+                   [param('ns3::Header const &', 'header'), param('uint32_t', 'size')])
+    ## packet-metadata.h: void ns3::PacketMetadata::AddTrailer(ns3::Trailer const & trailer, uint32_t size) [member function]
+    cls.add_method('AddTrailer', 
+                   'void', 
+                   [param('ns3::Trailer const &', 'trailer'), param('uint32_t', 'size')])
+    ## packet-metadata.h: void ns3::PacketMetadata::RemoveTrailer(ns3::Trailer const & trailer, uint32_t size) [member function]
+    cls.add_method('RemoveTrailer', 
+                   'void', 
+                   [param('ns3::Trailer const &', 'trailer'), param('uint32_t', 'size')])
+    ## packet-metadata.h: ns3::PacketMetadata ns3::PacketMetadata::CreateFragment(uint32_t start, uint32_t end) const [member function]
+    cls.add_method('CreateFragment', 
+                   'ns3::PacketMetadata', 
+                   [param('uint32_t', 'start'), param('uint32_t', 'end')], 
+                   is_const=True)
+    ## packet-metadata.h: void ns3::PacketMetadata::AddAtEnd(ns3::PacketMetadata const & o) [member function]
+    cls.add_method('AddAtEnd', 
+                   'void', 
+                   [param('ns3::PacketMetadata const &', 'o')])
+    ## packet-metadata.h: void ns3::PacketMetadata::AddPaddingAtEnd(uint32_t end) [member function]
+    cls.add_method('AddPaddingAtEnd', 
+                   'void', 
+                   [param('uint32_t', 'end')])
+    ## packet-metadata.h: void ns3::PacketMetadata::RemoveAtStart(uint32_t start) [member function]
+    cls.add_method('RemoveAtStart', 
+                   'void', 
+                   [param('uint32_t', 'start')])
+    ## packet-metadata.h: void ns3::PacketMetadata::RemoveAtEnd(uint32_t end) [member function]
+    cls.add_method('RemoveAtEnd', 
+                   'void', 
+                   [param('uint32_t', 'end')])
+    ## packet-metadata.h: uint32_t ns3::PacketMetadata::GetUid() const [member function]
+    cls.add_method('GetUid', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True)
+    ## packet-metadata.h: uint32_t ns3::PacketMetadata::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True)
+    ## packet-metadata.h: void ns3::PacketMetadata::Serialize(ns3::Buffer::Iterator i, uint32_t size) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'i'), param('uint32_t', 'size')], 
+                   is_const=True)
+    ## packet-metadata.h: uint32_t ns3::PacketMetadata::Deserialize(ns3::Buffer::Iterator i) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'i')])
+    ## packet-metadata.h: ns3::PacketMetadata::ItemIterator ns3::PacketMetadata::BeginItem(ns3::Buffer buffer) const [member function]
+    cls.add_method('BeginItem', 
+                   'ns3::PacketMetadata::ItemIterator', 
+                   [param('ns3::Buffer', 'buffer')], 
+                   is_const=True)
+    return
+
+def register_Ns3PacketMetadataItem_methods(root_module, cls):
+    ## packet-metadata.h: ns3::PacketMetadata::Item::isFragment [variable]
+    cls.add_instance_attribute('isFragment', 'bool', is_const=False)
+    ## packet-metadata.h: ns3::PacketMetadata::Item::tid [variable]
+    cls.add_instance_attribute('tid', 'ns3::TypeId', is_const=False)
+    ## packet-metadata.h: ns3::PacketMetadata::Item::currentSize [variable]
+    cls.add_instance_attribute('currentSize', 'uint32_t', is_const=False)
+    ## packet-metadata.h: ns3::PacketMetadata::Item::currentTrimedFromStart [variable]
+    cls.add_instance_attribute('currentTrimedFromStart', 'uint32_t', is_const=False)
+    ## packet-metadata.h: ns3::PacketMetadata::Item::currentTrimedFromEnd [variable]
+    cls.add_instance_attribute('currentTrimedFromEnd', 'uint32_t', is_const=False)
+    ## packet-metadata.h: ns3::PacketMetadata::Item::current [variable]
+    cls.add_instance_attribute('current', 'ns3::Buffer::Iterator', is_const=False)
+    ## packet-metadata.h: ns3::PacketMetadata::Item::Item(ns3::PacketMetadata::Item const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::PacketMetadata::Item const &', 'arg0')])
+    ## packet-metadata.h: ns3::PacketMetadata::Item::Item() [constructor]
+    cls.add_constructor([])
+    return
+
+def register_Ns3PacketMetadataItemIterator_methods(root_module, cls):
+    ## packet-metadata.h: ns3::PacketMetadata::ItemIterator::ItemIterator(ns3::PacketMetadata::ItemIterator const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::PacketMetadata::ItemIterator const &', 'arg0')])
+    ## packet-metadata.h: ns3::PacketMetadata::ItemIterator::ItemIterator(ns3::PacketMetadata const * metadata, ns3::Buffer buffer) [constructor]
+    cls.add_constructor([param('ns3::PacketMetadata const *', 'metadata'), param('ns3::Buffer', 'buffer')])
+    ## packet-metadata.h: bool ns3::PacketMetadata::ItemIterator::HasNext() const [member function]
+    cls.add_method('HasNext', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## packet-metadata.h: ns3::PacketMetadata::Item ns3::PacketMetadata::ItemIterator::Next() [member function]
+    cls.add_method('Next', 
+                   'ns3::PacketMetadata::Item', 
+                   [])
+    return
+
 def register_Ns3Tag_methods(root_module, cls):
     ## tag.h: ns3::Tag::Tag(ns3::Tag const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Tag const &', 'arg0')])
--- a/bindings/python/ns3_module_core.py	Wed Oct 15 15:53:06 2008 +0200
+++ b/bindings/python/ns3_module_core.py	Mon Oct 27 12:17:38 2008 +0100
@@ -91,6 +91,10 @@
     module.add_class('BooleanChecker', parent=root_module['ns3::AttributeChecker'])
     ## boolean.h: ns3::BooleanValue [class]
     module.add_class('BooleanValue', parent=root_module['ns3::AttributeValue'])
+    ## callback.h: ns3::CallbackChecker [class]
+    module.add_class('CallbackChecker', parent=root_module['ns3::AttributeChecker'])
+    ## callback.h: ns3::CallbackValue [class]
+    module.add_class('CallbackValue', parent=root_module['ns3::AttributeValue'])
     ## random-variable.h: ns3::ConstantVariable [class]
     module.add_class('ConstantVariable', parent=root_module['ns3::RandomVariable'])
     ## random-variable.h: ns3::DeterministicVariable [class]
@@ -236,6 +240,8 @@
     register_Ns3AttributeValue_methods(root_module, root_module['ns3::AttributeValue'])
     register_Ns3BooleanChecker_methods(root_module, root_module['ns3::BooleanChecker'])
     register_Ns3BooleanValue_methods(root_module, root_module['ns3::BooleanValue'])
+    register_Ns3CallbackChecker_methods(root_module, root_module['ns3::CallbackChecker'])
+    register_Ns3CallbackValue_methods(root_module, root_module['ns3::CallbackValue'])
     register_Ns3ConstantVariable_methods(root_module, root_module['ns3::ConstantVariable'])
     register_Ns3DeterministicVariable_methods(root_module, root_module['ns3::DeterministicVariable'])
     register_Ns3DoubleValue_methods(root_module, root_module['ns3::DoubleValue'])
@@ -945,11 +951,6 @@
                    'ns3::TypeId', 
                    [param('std::string', 'name')], 
                    is_static=True)
-    ## type-id.h: static bool ns3::TypeId::LookupByNameFailSafe(std::string name, ns3::TypeId * tid) [member function]
-    cls.add_method('LookupByNameFailSafe', 
-                   'bool', 
-                   [param('std::string', 'name'), param('ns3::TypeId *', 'tid', transfer_ownership=False)], 
-                   is_static=True)
     ## type-id.h: ns3::Ptr<ns3::TraceSourceAccessor const> ns3::TypeId::LookupTraceSourceByName(std::string name) const [member function]
     cls.add_method('LookupTraceSourceByName', 
                    'ns3::Ptr< ns3::TraceSourceAccessor const >', 
@@ -1155,6 +1156,41 @@
                    [param('bool', 'value')])
     return
 
+def register_Ns3CallbackChecker_methods(root_module, cls):
+    ## callback.h: ns3::CallbackChecker::CallbackChecker(ns3::CallbackChecker const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::CallbackChecker const &', 'arg0')])
+    ## callback.h: ns3::CallbackChecker::CallbackChecker() [constructor]
+    cls.add_constructor([])
+    return
+
+def register_Ns3CallbackValue_methods(root_module, cls):
+    ## callback.h: ns3::CallbackValue::CallbackValue(ns3::CallbackValue const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::CallbackValue const &', 'arg0')])
+    ## callback.h: ns3::CallbackValue::CallbackValue() [constructor]
+    cls.add_constructor([])
+    ## callback.h: ns3::CallbackValue::CallbackValue(ns3::CallbackBase const & base) [constructor]
+    cls.add_constructor([param('ns3::CallbackBase const &', 'base')])
+    ## callback.h: void ns3::CallbackValue::Set(ns3::CallbackBase base) [member function]
+    cls.add_method('Set', 
+                   'void', 
+                   [param('ns3::CallbackBase', 'base')])
+    ## callback.h: ns3::Ptr<ns3::AttributeValue> ns3::CallbackValue::Copy() const [member function]
+    cls.add_method('Copy', 
+                   'ns3::Ptr< ns3::AttributeValue >', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## callback.h: std::string ns3::CallbackValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
+    cls.add_method('SerializeToString', 
+                   'std::string', 
+                   [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_const=True, is_virtual=True)
+    ## callback.h: bool ns3::CallbackValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
+    cls.add_method('DeserializeFromString', 
+                   'bool', 
+                   [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], 
+                   is_virtual=True)
+    return
+
 def register_Ns3ConstantVariable_methods(root_module, cls):
     ## random-variable.h: ns3::ConstantVariable::ConstantVariable(ns3::ConstantVariable const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::ConstantVariable const &', 'arg0')])
@@ -1831,7 +1867,7 @@
     cls.add_method('ConnectWithoutContext', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb')])
-    ## traced-value.h: void ns3::TracedValue<unsigned int>::Connect(ns3::CallbackBase const & cb, std::string path) [member function]
+    ## traced-value.h: void ns3::TracedValue<unsigned int>::Connect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
     cls.add_method('Connect', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
@@ -1839,7 +1875,7 @@
     cls.add_method('DisconnectWithoutContext', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb')])
-    ## traced-value.h: void ns3::TracedValue<unsigned int>::Disconnect(ns3::CallbackBase const & cb, std::string path) [member function]
+    ## traced-value.h: void ns3::TracedValue<unsigned int>::Disconnect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
     cls.add_method('Disconnect', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
@@ -1874,7 +1910,7 @@
     module.add_function('TypeNameGet', 
                         'std::string', 
                         [], 
-                        template_parameters=['long long'])
+                        template_parameters=['long'])
     ## type-name.h: extern std::string ns3::TypeNameGet() [free function]
     module.add_function('TypeNameGet', 
                         'std::string', 
@@ -1894,7 +1930,7 @@
     module.add_function('TypeNameGet', 
                         'std::string', 
                         [], 
-                        template_parameters=['unsigned long long'])
+                        template_parameters=['unsigned long'])
     ## type-name.h: extern std::string ns3::TypeNameGet() [free function]
     module.add_function('TypeNameGet', 
                         'std::string', 
@@ -1910,14 +1946,22 @@
                         'std::string', 
                         [], 
                         template_parameters=['unsigned char'])
-    ## log.h: extern void ns3::LogComponentDisable(char const * name, ns3::LogLevel level) [free function]
-    module.add_function('LogComponentDisable', 
-                        'void', 
-                        [param('char const *', 'name'), param('ns3::LogLevel', 'level')])
     ## string.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeStringChecker() [free function]
     module.add_function('MakeStringChecker', 
                         'ns3::Ptr< ns3::AttributeChecker const >', 
                         [])
+    ## enum.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeEnumChecker(int v1, std::string n1, int v2=0, std::string n2="", int v3=0, std::string n3="", int v4=0, std::string n4="", int v5=0, std::string n5="", int v6=0, std::string n6="", int v7=0, std::string n7="", int v8=0, std::string n8="", int v9=0, std::string n9="", int v10=0, std::string n10="", int v11=0, std::string n11="", int v12=0, std::string n12="") [free function]
+    module.add_function('MakeEnumChecker', 
+                        'ns3::Ptr< ns3::AttributeChecker const >', 
+                        [param('int', 'v1'), param('std::string', 'n1'), param('int', 'v2', default_value='0'), param('std::string', 'n2', default_value='""'), param('int', 'v3', default_value='0'), param('std::string', 'n3', default_value='""'), param('int', 'v4', default_value='0'), param('std::string', 'n4', default_value='""'), param('int', 'v5', default_value='0'), param('std::string', 'n5', default_value='""'), param('int', 'v6', default_value='0'), param('std::string', 'n6', default_value='""'), param('int', 'v7', default_value='0'), param('std::string', 'n7', default_value='""'), param('int', 'v8', default_value='0'), param('std::string', 'n8', default_value='""'), param('int', 'v9', default_value='0'), param('std::string', 'n9', default_value='""'), param('int', 'v10', default_value='0'), param('std::string', 'n10', default_value='""'), param('int', 'v11', default_value='0'), param('std::string', 'n11', default_value='""'), param('int', 'v12', default_value='0'), param('std::string', 'n12', default_value='""')])
+    ## log.h: extern void ns3::LogComponentEnableAll(ns3::LogLevel level) [free function]
+    module.add_function('LogComponentEnableAll', 
+                        'void', 
+                        [param('ns3::LogLevel', 'level')])
+    ## type-id.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeTypeIdChecker() [free function]
+    module.add_function('MakeTypeIdChecker', 
+                        'ns3::Ptr< ns3::AttributeChecker const >', 
+                        [])
     ## ptr.h: extern ns3::Ptr<ns3::PointerValue> ns3::Create() [free function]
     module.add_function('Create', 
                         'ns3::Ptr< ns3::PointerValue >', 
@@ -1928,14 +1972,6 @@
                         'ns3::Ptr< ns3::ObjectVectorValue >', 
                         [], 
                         template_parameters=['ns3::ObjectVectorValue'])
-    ## log.h: extern void ns3::LogComponentEnableAll(ns3::LogLevel level) [free function]
-    module.add_function('LogComponentEnableAll', 
-                        'void', 
-                        [param('ns3::LogLevel', 'level')])
-    ## type-id.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeTypeIdChecker() [free function]
-    module.add_function('MakeTypeIdChecker', 
-                        'ns3::Ptr< ns3::AttributeChecker const >', 
-                        [])
     ## object-factory.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeObjectFactoryChecker() [free function]
     module.add_function('MakeObjectFactoryChecker', 
                         'ns3::Ptr< ns3::AttributeChecker const >', 
@@ -1944,6 +1980,10 @@
     module.add_function('LogComponentDisableAll', 
                         'void', 
                         [param('ns3::LogLevel', 'level')])
+    ## callback.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeCallbackChecker() [free function]
+    module.add_function('MakeCallbackChecker', 
+                        'ns3::Ptr< ns3::AttributeChecker const >', 
+                        [])
     ## breakpoint.h: extern void ns3::BreakpointFallback() [free function]
     module.add_function('BreakpointFallback', 
                         'void', 
@@ -1952,14 +1992,14 @@
     module.add_function('MakeRandomVariableChecker', 
                         'ns3::Ptr< ns3::AttributeChecker const >', 
                         [])
+    ## log.h: extern void ns3::LogComponentDisable(char const * name, ns3::LogLevel level) [free function]
+    module.add_function('LogComponentDisable', 
+                        'void', 
+                        [param('char const *', 'name'), param('ns3::LogLevel', 'level')])
     ## log.h: extern void ns3::LogComponentEnable(char const * name, ns3::LogLevel level) [free function]
     module.add_function('LogComponentEnable', 
                         'void', 
                         [param('char const *', 'name'), param('ns3::LogLevel', 'level')])
-    ## enum.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeEnumChecker(int v1, std::string n1, int v2=0, std::string n2="", int v3=0, std::string n3="", int v4=0, std::string n4="", int v5=0, std::string n5="", int v6=0, std::string n6="", int v7=0, std::string n7="", int v8=0, std::string n8="", int v9=0, std::string n9="", int v10=0, std::string n10="", int v11=0, std::string n11="", int v12=0, std::string n12="") [free function]
-    module.add_function('MakeEnumChecker', 
-                        'ns3::Ptr< ns3::AttributeChecker const >', 
-                        [param('int', 'v1'), param('std::string', 'n1'), param('int', 'v2', default_value='0'), param('std::string', 'n2', default_value='""'), param('int', 'v3', default_value='0'), param('std::string', 'n3', default_value='""'), param('int', 'v4', default_value='0'), param('std::string', 'n4', default_value='""'), param('int', 'v5', default_value='0'), param('std::string', 'n5', default_value='""'), param('int', 'v6', default_value='0'), param('std::string', 'n6', default_value='""'), param('int', 'v7', default_value='0'), param('std::string', 'n7', default_value='""'), param('int', 'v8', default_value='0'), param('std::string', 'n8', default_value='""'), param('int', 'v9', default_value='0'), param('std::string', 'n9', default_value='""'), param('int', 'v10', default_value='0'), param('std::string', 'n10', default_value='""'), param('int', 'v11', default_value='0'), param('std::string', 'n11', default_value='""'), param('int', 'v12', default_value='0'), param('std::string', 'n12', default_value='""')])
     register_functions_ns3_internal(module.get_submodule('internal'), root_module)
     register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
     register_functions_ns3_Config(module.get_submodule('Config'), root_module)
@@ -2017,10 +2057,6 @@
     module.add_function('SetGlobalFailSafe', 
                         'bool', 
                         [param('std::string', 'name'), param('ns3::AttributeValue const &', 'value')])
-    ## config.h: extern void ns3::Config::Disconnect(std::string path, ns3::CallbackBase const & cb) [free function]
-    module.add_function('Disconnect', 
-                        'void', 
-                        [param('std::string', 'path'), param('ns3::CallbackBase const &', 'cb')])
     ## config.h: extern uint32_t ns3::Config::GetRootNamespaceObjectN() [free function]
     module.add_function('GetRootNamespaceObjectN', 
                         'uint32_t', 
@@ -2037,6 +2073,10 @@
     module.add_function('RegisterRootNamespaceObject', 
                         'void', 
                         [param('ns3::Ptr< ns3::Object >', 'obj')])
+    ## config.h: extern void ns3::Config::Disconnect(std::string path, ns3::CallbackBase const & cb) [free function]
+    module.add_function('Disconnect', 
+                        'void', 
+                        [param('std::string', 'path'), param('ns3::CallbackBase const &', 'cb')])
     return
 
 def register_functions_ns3_olsr(module, root_module):
--- a/bindings/python/ns3_module_mobility.py	Wed Oct 15 15:53:06 2008 +0200
+++ b/bindings/python/ns3_module_mobility.py	Mon Oct 27 12:17:38 2008 +0100
@@ -150,21 +150,12 @@
     cls.add_constructor([])
     ## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper(ns3::Vector const & position) [constructor]
     cls.add_constructor([param('ns3::Vector const &', 'position')])
-    ## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper(ns3::Vector const & position, ns3::Vector const & speed) [constructor]
-    cls.add_constructor([param('ns3::Vector const &', 'position'), param('ns3::Vector const &', 'speed')])
-    ## static-speed-helper.h: void ns3::StaticSpeedHelper::InitializePosition(ns3::Vector const & position) [member function]
-    cls.add_method('InitializePosition', 
+    ## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper(ns3::Vector const & position, ns3::Vector const & vel) [constructor]
+    cls.add_constructor([param('ns3::Vector const &', 'position'), param('ns3::Vector const &', 'vel')])
+    ## static-speed-helper.h: void ns3::StaticSpeedHelper::SetPosition(ns3::Vector const & position) [member function]
+    cls.add_method('SetPosition', 
                    'void', 
                    [param('ns3::Vector const &', 'position')])
-    ## static-speed-helper.h: void ns3::StaticSpeedHelper::Reset(ns3::Vector const & speed) [member function]
-    cls.add_method('Reset', 
-                   'void', 
-                   [param('ns3::Vector const &', 'speed')])
-    ## static-speed-helper.h: ns3::Vector ns3::StaticSpeedHelper::GetCurrentPosition(ns3::Rectangle const & bounds) const [member function]
-    cls.add_method('GetCurrentPosition', 
-                   'ns3::Vector', 
-                   [param('ns3::Rectangle const &', 'bounds')], 
-                   is_const=True)
     ## static-speed-helper.h: ns3::Vector ns3::StaticSpeedHelper::GetCurrentPosition() const [member function]
     cls.add_method('GetCurrentPosition', 
                    'ns3::Vector', 
@@ -175,10 +166,10 @@
                    'ns3::Vector', 
                    [], 
                    is_const=True)
-    ## static-speed-helper.h: void ns3::StaticSpeedHelper::SetSpeed(ns3::Vector const & speed) [member function]
-    cls.add_method('SetSpeed', 
+    ## static-speed-helper.h: void ns3::StaticSpeedHelper::SetVelocity(ns3::Vector const & vel) [member function]
+    cls.add_method('SetVelocity', 
                    'void', 
-                   [param('ns3::Vector const &', 'speed')])
+                   [param('ns3::Vector const &', 'vel')])
     ## static-speed-helper.h: void ns3::StaticSpeedHelper::Pause() [member function]
     cls.add_method('Pause', 
                    'void', 
@@ -187,6 +178,16 @@
     cls.add_method('Unpause', 
                    'void', 
                    [])
+    ## static-speed-helper.h: void ns3::StaticSpeedHelper::UpdateWithBounds(ns3::Rectangle const & rectangle) const [member function]
+    cls.add_method('UpdateWithBounds', 
+                   'void', 
+                   [param('ns3::Rectangle const &', 'rectangle')], 
+                   is_const=True)
+    ## static-speed-helper.h: void ns3::StaticSpeedHelper::Update() const [member function]
+    cls.add_method('Update', 
+                   'void', 
+                   [], 
+                   is_const=True)
     return
 
 def register_Ns3Vector_methods(root_module, cls):
@@ -631,8 +632,8 @@
                    is_static=True)
     ## static-speed-mobility-model.h: ns3::StaticSpeedMobilityModel::StaticSpeedMobilityModel() [constructor]
     cls.add_constructor([])
-    ## static-speed-mobility-model.h: void ns3::StaticSpeedMobilityModel::SetSpeed(ns3::Vector const & speed) [member function]
-    cls.add_method('SetSpeed', 
+    ## static-speed-mobility-model.h: void ns3::StaticSpeedMobilityModel::SetVelocity(ns3::Vector const & speed) [member function]
+    cls.add_method('SetVelocity', 
                    'void', 
                    [param('ns3::Vector const &', 'speed')])
     ## static-speed-mobility-model.h: ns3::Vector ns3::StaticSpeedMobilityModel::DoGetPosition() const [member function]
--- a/bindings/python/ns3_module_node.py	Wed Oct 15 15:53:06 2008 +0200
+++ b/bindings/python/ns3_module_node.py	Mon Oct 27 12:17:38 2008 +0100
@@ -1251,9 +1251,9 @@
     cls.add_method('SetAcceptCallback', 
                    'void', 
                    [param('ns3::Callback< bool, ns3::Ptr< ns3::Socket >, ns3::Address const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'connectionRequest'), param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, ns3::Address const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'newConnectionCreated')])
-    ## socket.h: bool ns3::Socket::SetDataSentCallback(ns3::Callback<void, ns3::Ptr<ns3::Socket>, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty> dataSent) [member function]
+    ## socket.h: void ns3::Socket::SetDataSentCallback(ns3::Callback<void, ns3::Ptr<ns3::Socket>, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty> dataSent) [member function]
     cls.add_method('SetDataSentCallback', 
-                   'bool', 
+                   'void', 
                    [param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'dataSent')])
     ## socket.h: void ns3::Socket::SetSendCallback(ns3::Callback<void, ns3::Ptr<ns3::Socket>, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty> sendCb) [member function]
     cls.add_method('SetSendCallback', 
@@ -1293,10 +1293,10 @@
                    'int', 
                    [param('ns3::Address const &', 'address')], 
                    is_pure_virtual=True, is_virtual=True)
-    ## socket.h: int ns3::Socket::Listen(uint32_t queueLimit) [member function]
+    ## socket.h: int ns3::Socket::Listen() [member function]
     cls.add_method('Listen', 
                    'int', 
-                   [param('uint32_t', 'queueLimit')], 
+                   [], 
                    is_pure_virtual=True, is_virtual=True)
     ## socket.h: uint32_t ns3::Socket::GetTxAvailable() const [member function]
     cls.add_method('GetTxAvailable', 
@@ -1356,6 +1356,11 @@
     cls.add_method('RecvFrom', 
                    'int', 
                    [param('uint8_t *', 'buf'), param('uint32_t', 'size'), param('uint32_t', 'flags'), param('ns3::Address &', 'fromAddress')])
+    ## socket.h: int ns3::Socket::GetSockName(ns3::Address & address) const [member function]
+    cls.add_method('GetSockName', 
+                   'int', 
+                   [param('ns3::Address &', 'address')], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
     ## socket.h: void ns3::Socket::NotifyConnectionSucceeded() [member function]
     cls.add_method('NotifyConnectionSucceeded', 
                    'void', 
@@ -2581,18 +2586,10 @@
 
 def register_functions(root_module):
     module = root_module
-    ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Mac48Address & ad) [free function]
-    module.add_function('ReadFrom', 
-                        'void', 
-                        [param('ns3::Buffer::Iterator &', 'i'), param('ns3::Mac48Address &', 'ad')])
-    ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Address & ad, uint32_t len) [free function]
-    module.add_function('ReadFrom', 
-                        'void', 
-                        [param('ns3::Buffer::Iterator &', 'i'), param('ns3::Address &', 'ad'), param('uint32_t', 'len')])
-    ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Ipv4Address & ad) [free function]
-    module.add_function('ReadFrom', 
-                        'void', 
-                        [param('ns3::Buffer::Iterator &', 'i'), param('ns3::Ipv4Address &', 'ad')])
+    ## mac48-address.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeMac48AddressChecker() [free function]
+    module.add_function('MakeMac48AddressChecker', 
+                        'ns3::Ptr< ns3::AttributeChecker const >', 
+                        [])
     ## ipv4-address.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeIpv4AddressChecker() [free function]
     module.add_function('MakeIpv4AddressChecker', 
                         'ns3::Ptr< ns3::AttributeChecker const >', 
@@ -2617,10 +2614,18 @@
     module.add_function('MakeIpv4MaskChecker', 
                         'ns3::Ptr< ns3::AttributeChecker const >', 
                         [])
-    ## mac48-address.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeMac48AddressChecker() [free function]
-    module.add_function('MakeMac48AddressChecker', 
-                        'ns3::Ptr< ns3::AttributeChecker const >', 
-                        [])
+    ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Mac48Address & ad) [free function]
+    module.add_function('ReadFrom', 
+                        'void', 
+                        [param('ns3::Buffer::Iterator &', 'i'), param('ns3::Mac48Address &', 'ad')])
+    ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Address & ad, uint32_t len) [free function]
+    module.add_function('ReadFrom', 
+                        'void', 
+                        [param('ns3::Buffer::Iterator &', 'i'), param('ns3::Address &', 'ad'), param('uint32_t', 'len')])
+    ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Ipv4Address & ad) [free function]
+    module.add_function('ReadFrom', 
+                        'void', 
+                        [param('ns3::Buffer::Iterator &', 'i'), param('ns3::Ipv4Address &', 'ad')])
     register_functions_ns3_internal(module.get_submodule('internal'), root_module)
     register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
     register_functions_ns3_Config(module.get_submodule('Config'), root_module)
--- a/bindings/python/ns3_module_wifi.py	Wed Oct 15 15:53:06 2008 +0200
+++ b/bindings/python/ns3_module_wifi.py	Mon Oct 27 12:17:38 2008 +0100
@@ -507,16 +507,16 @@
                    'bool', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet')], 
                    is_virtual=True)
-    ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetNFragments(ns3::Ptr<const ns3::Packet> packet) [member function]
-    cls.add_method('GetNFragments', 
-                   'uint32_t', 
-                   [param('ns3::Ptr< ns3::Packet const >', 'packet')], 
-                   is_virtual=True)
     ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetFragmentSize(ns3::Ptr<const ns3::Packet> packet, uint32_t fragmentNumber) [member function]
     cls.add_method('GetFragmentSize', 
                    'uint32_t', 
                    [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint32_t', 'fragmentNumber')], 
                    is_virtual=True)
+    ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetFragmentOffset(ns3::Ptr<const ns3::Packet> packet, uint32_t fragmentNumber) [member function]
+    cls.add_method('GetFragmentOffset', 
+                   'uint32_t', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint32_t', 'fragmentNumber')], 
+                   is_virtual=True)
     ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::IsLastFragment(ns3::Ptr<const ns3::Packet> packet, uint32_t fragmentNumber) [member function]
     cls.add_method('IsLastFragment', 
                    'bool', 
--- a/bindings/python/ns3module_helpers.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/bindings/python/ns3module_helpers.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -188,3 +188,35 @@
     return NULL;
 }
 
+
+PyObject *
+_wrap_TypeId_LookupByNameFailSafe(PyNs3TypeId *PYBINDGEN_UNUSED(dummy), PyObject *args, PyObject *kwargs,
+                                  PyObject **return_exception)
+{
+    bool ok;
+    const char *name;
+    Py_ssize_t name_len;
+    ns3::TypeId tid;
+    PyNs3TypeId *py_tid;
+    const char *keywords[] = {"name", NULL};
+    
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, (char *) "s#", (char **) keywords, &name, &name_len)) {
+        PyObject *exc_type, *traceback;
+        PyErr_Fetch(&exc_type, return_exception, &traceback);
+        Py_XDECREF(exc_type);
+        Py_XDECREF(traceback);
+        return NULL;
+    }
+    ok = ns3::TypeId::LookupByNameFailSafe(std::string(name, name_len), &tid);
+    if (!ok)
+    {
+        PyErr_Format(PyExc_KeyError, "The ns3 type with name `%s' is not registered", name);
+        return NULL;
+    }
+
+    py_tid = PyObject_New(PyNs3TypeId, &PyNs3TypeId_Type);
+    py_tid->obj = new ns3::TypeId (tid);
+    PyNs3TypeId_wrapper_registry[(void *) py_tid->obj] = (PyObject *) py_tid;    
+    
+    return (PyObject *) py_tid;
+}
--- a/bindings/python/ns3modulegen.py	Wed Oct 15 15:53:06 2008 +0200
+++ b/bindings/python/ns3modulegen.py	Mon Oct 27 12:17:38 2008 +0100
@@ -85,6 +85,7 @@
 
     ns3modulegen_core_customizations.Simulator_customizations(root_module)
     ns3modulegen_core_customizations.CommandLine_customizations(root_module)
+    ns3modulegen_core_customizations.TypeId_customizations(root_module)
 
 
     for local_module in LOCAL_MODULES:
--- a/bindings/python/ns3modulegen_core_customizations.py	Wed Oct 15 15:53:06 2008 +0200
+++ b/bindings/python/ns3modulegen_core_customizations.py	Mon Oct 27 12:17:38 2008 +0100
@@ -424,6 +424,7 @@
         return -1;
     }
     %(CONSTRUCT_CODE)s
+    PyNs3ObjectBase_wrapper_registry[(void *) self->obj] = (PyObject *) self;
     return 0;
 }
 ''' % dict(WRAPPER_NAME=wrapper_name, PYSTRUCT=cls.pystruct, CLASS_NAME=cls.full_name,
@@ -517,3 +518,10 @@
                             and param.default_value_type is None:
                         param.default_value_type = 'ns3::EmptyAttributeValue'
 
+
+def TypeId_customizations(module):
+    TypeId = module['ns3::TypeId']
+    TypeId.add_custom_method_wrapper("LookupByNameFailSafe", "_wrap_TypeId_LookupByNameFailSafe",
+                                     flags=["METH_VARARGS", "METH_KEYWORDS", "METH_STATIC"])
+    
+
--- a/bindings/python/ns3modulescan.py	Wed Oct 15 15:53:06 2008 +0200
+++ b/bindings/python/ns3modulescan.py	Mon Oct 27 12:17:38 2008 +0100
@@ -48,9 +48,6 @@
         'decref_method': 'Unref',
         'peekref_method': 'GetReferenceCount',
         },
-    '::ns3::PacketMetadata': {
-        'ignore': None,
-        },
     '::ns3::AttributeChecker': {
         'automatic_type_narrowing': 'true',
         'allow_subclassing': 'false',
@@ -73,7 +70,7 @@
         'params': {'info':{'transfer_ownership': 'false'}}
         },
     'static bool ns3::TypeId::LookupByNameFailSafe(std::string name, ns3::TypeId * tid) [member function]': {
-        'params': {'tid': {'transfer_ownership': 'false'}}
+        'ignore': None, # manually wrapped in 
         },
     'bool ns3::TraceSourceAccessor::ConnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function]': {
         'params': {'obj': {'transfer_ownership':'false'}}
--- a/bindings/python/wscript	Wed Oct 15 15:53:06 2008 +0200
+++ b/bindings/python/wscript	Mon Oct 27 12:17:38 2008 +0100
@@ -22,7 +22,7 @@
     os.environ['PYTHONPATH'] = LOCAL_PYBINDGEN_PATH
 
 ## https://launchpad.net/pybindgen/
-REQUIRED_PYBINDGEN_VERSION = (0, 9, 0, 598)
+REQUIRED_PYBINDGEN_VERSION = (0, 9, 0, 600)
 REQUIRED_PYGCCXML_VERSION = (0, 9, 5)
 
 
--- a/doc/tutorial/building-topologies.texi	Wed Oct 15 15:53:06 2008 +0200
+++ b/doc/tutorial/building-topologies.texi	Mon Oct 27 12:17:38 2008 +0100
@@ -63,7 +63,7 @@
 since you can actually vary the number of nodes created on the LAN.  If you
 set nCsma to one, there will be a total of two nodes on the LAN (CSMA 
 channel) --- one required node and one ``extra'' node.  By default there are
-thee ``extra'' nodes as seen below:
+three ``extra'' nodes as seen below:
 
 @verbatim
 // Default Network Topology
@@ -589,7 +589,7 @@
 number of ``extra'' CSMA nodes.  Similarly, you can set @code{nWifi} to 
 control how many @code{STA} (station) nodes are created in the simulation.
 There will always be one @code{AP} (access point) node on the wireless 
-network.  By default there are thee ``extra'' CSMA nodes and three wireless 
+network.  By default there are three ``extra'' CSMA nodes and three wireless 
 @code{STA} nodes.
 
 The code begins by loading module include files just as was done in the
--- a/doc/tutorial/conceptual-overview.texi	Wed Oct 15 15:53:06 2008 +0200
+++ b/doc/tutorial/conceptual-overview.texi	Mon Oct 27 12:17:38 2008 +0100
@@ -681,7 +681,7 @@
 @end verbatim
 
 we actually scheduled events in the simulator at 1.0 seconds, 2.0 seconds and
-10.0 seconds.  When @code{Simulator::Run} is called, the ssytem will begin 
+10.0 seconds.  When @code{Simulator::Run} is called, the system will begin 
 looking through the list of scheduled events and executing them.  First it 
 will run the event at 1.0 seconds, which will enable the echo server 
 application.  Then it will run the event scheduled for t=2.0 seconds which 
--- a/doc/tutorial/tweaking.texi	Wed Oct 15 15:53:06 2008 +0200
+++ b/doc/tutorial/tweaking.texi	Mon Oct 27 12:17:38 2008 +0100
@@ -180,7 +180,7 @@
 colon to remind you in a relatively subtle way to conceptually separate the 
 logging component name from the class name.
 
-It turns out that in come cases, it can be hard to determine which method
+It turns out that in some cases, it can be hard to determine which method
 actually generates a log message.  If you look in the text above, you may
 wonder where the string ``@code{Received 1024 bytes from 10.1.1.2}'' comes
 from.  You can resolve this by ORing the @code{prefix_func} level into the
@@ -625,7 +625,7 @@
 start with the following code,
 
 @verbatim
-    int
+  int
   main (int argc, char *argv[])
   {
     uint32_t nPackets = 1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/csma-star.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -0,0 +1,201 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ *
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/global-route-manager.h"
+
+// Network topology (default)
+//
+//            n2     +          +     n3          .
+//             | ... |\        /| ... |           .
+//             ======= \      / =======           .
+//              CSMA    \    /   CSMA             .
+//                       \  /                     .
+//            n1     +--- n0 ---+     n4          .
+//             | ... |   /  \   | ... |           .
+//             =======  /    \  =======           .
+//              CSMA   /      \  CSMA             .
+//                    /        \                  .
+//            n6     +          +     n5          .
+//             | ... |          | ... |           .
+//             =======          =======           .
+//              CSMA             CSMA             .
+//
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("CsmaStar");
+
+int 
+main (int argc, char *argv[])
+{
+  //
+  // Make the random number generators generate reproducible results.
+  //
+  RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
+
+  //
+  // Set up some default values for the simulation.
+  //
+  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (137));
+
+  // ??? try and stick 15kb/s into the data rate
+  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("14kb/s"));
+
+  //
+  // Default number of nodes in the star.  Overridable by command line argument.
+  //
+  uint32_t nNodes = 7;
+
+  CommandLine cmd;
+  cmd.AddValue("nNodes", "Number of nodes to place in the star", nNodes);
+  cmd.Parse (argc, argv);
+
+  NS_LOG_INFO ("Create nodes.");
+  NodeContainer hubNode;
+  NodeContainer spokeNodes;
+  hubNode.Create (1);
+  Ptr<Node> hub = hubNode.Get (0);
+  spokeNodes.Create (nNodes - 1);
+
+  CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
+  csma.SetChannelAttribute ("Delay", StringValue ("1ms"));
+
+  NS_LOG_INFO ("Build star topology.");
+  NetDeviceContainer hubDevices, spokeDevices;
+  csma.InstallStar (hubNode.Get (0), spokeNodes, hubDevices, spokeDevices);
+
+  NodeContainer fillNodes;
+
+  //
+  // Just to be nasy, hang some more nodes off of the CSMA channel for each
+  // spoke, so that there are a total of 16 nodes on each channel.  Stash
+  // all of these new devices into a container.
+  //
+  NetDeviceContainer fillDevices;
+
+  uint32_t nFill = 14;
+  for (uint32_t i = 0; i < spokeDevices.GetN (); ++i)
+    {
+      Ptr<Channel> channel = spokeDevices.Get (i)->GetChannel ();
+      Ptr<CsmaChannel> csmaChannel = channel->GetObject<CsmaChannel> ();
+      NodeContainer newNodes;
+      NetDeviceContainer newDevices;
+      newNodes.Create (nFill);
+      fillNodes.Add (newNodes);
+      fillDevices.Add (csma.Install (newNodes, csmaChannel));
+    }
+
+  NS_LOG_INFO ("Install internet stack on all nodes.");
+  InternetStackHelper internet;
+  internet.Install (NodeContainer (hubNode, spokeNodes, fillNodes));
+
+  NS_LOG_INFO ("Assign IP Addresses.");
+  Ipv4AddressHelper address;
+
+  //
+  // Assign IPv4 interfaces and IP addresses to the devices we previously
+  // created.  Keep track of the resulting addresses, one for the addresses
+  // of the hub node, and one for addresses on the spoke nodes.  Despite the
+  // name of the class, what is visible to clients is really the address.
+  //
+  Ipv4InterfaceContainer hubAddresses;
+  Ipv4InterfaceContainer spokeAddresses;
+
+  for(uint32_t i = 0; i < spokeNodes.GetN (); ++i)
+  {
+    std::ostringstream subnet;
+    subnet << "10.1." << i << ".0";
+    NS_LOG_INFO ("Assign IP Addresses for CSMA subnet " << subnet.str ());
+    address.SetBase (subnet.str ().c_str (), "255.255.255.0");
+    hubAddresses.Add (address.Assign (hubDevices.Get (i)));
+    spokeAddresses.Add (address.Assign (spokeDevices.Get (i)));
+  }
+
+  NS_LOG_INFO ("Create applications.");
+  //
+  // Create a packet sink on the star "hub" to receive packets.  
+  // 
+  uint16_t port = 50000;
+  Address hubLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
+  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", hubLocalAddress);
+  ApplicationContainer hubApp = packetSinkHelper.Install (hubNode);
+  hubApp.Start (Seconds (1.0));
+  hubApp.Stop (Seconds (10.0));
+
+  //
+  // Create OnOff applications to send TCP to the hub, one on each spoke node.
+  //
+  OnOffHelper onOffHelper ("ns3::TcpSocketFactory", Address ());
+  onOffHelper.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onOffHelper.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+
+  ApplicationContainer spokeApps;
+
+  for (uint32_t i = 0; i < spokeNodes.GetN (); ++i)
+    {
+      AddressValue remoteAddress (InetSocketAddress (hubAddresses.GetAddress (i), port));
+      onOffHelper.SetAttribute ("Remote", remoteAddress);
+      spokeApps.Add (onOffHelper.Install (spokeNodes.Get (i)));
+    }
+
+  spokeApps.Start (Seconds (1.0));
+  spokeApps.Stop (Seconds (10.0));
+
+  //
+  // Because we are evil, we also add OnOff applications to send TCP to the hub 
+  // from the fill devices on each CSMA link.  The first nFill nodes in the 
+  // fillNodes container are on the CSMA network talking to the zeroth device
+  // on the hub node.  The next nFill nodes are on the CSMA network talking to
+  // the first device on the hub node, etc.  So the ith fillNode is associated
+  // with the hub address found on the (i / nFill)th device on the hub node.
+  //
+  ApplicationContainer fillApps;
+
+  for (uint32_t i = 0; i < fillNodes.GetN (); ++i)
+    {
+      AddressValue remoteAddress (InetSocketAddress (hubAddresses.GetAddress (i / nFill), port));
+      onOffHelper.SetAttribute ("Remote", remoteAddress);
+      fillApps.Add (onOffHelper.Install (fillNodes.Get (i)));
+    }
+
+  fillApps.Start (Seconds (1.0));
+  fillApps.Stop (Seconds (10.0));
+
+  NS_LOG_INFO ("Enable static global routing.");
+  //
+  // Turn on global static routing so we can actually be routed across the star.
+  //
+  GlobalRouteManager::PopulateRoutingTables ();
+
+  NS_LOG_INFO ("Enable pcap tracing.");
+  //
+  // Do pcap tracing on all devices on all nodes.
+  //
+  PointToPointHelper::EnablePcapAll ("csma-star");
+
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/star.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -0,0 +1,153 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ *
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/global-route-manager.h"
+
+// Network topology (default)
+//
+//        n2 n3 n4              .
+//         \ | /                .
+//          \|/                 .
+//     n1--- n0---n5            .
+//          /|\                 .
+//         / | \                .
+//        n8 n7 n6              .
+//
+
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("Star");
+
+int 
+main (int argc, char *argv[])
+{
+  //
+  // Make the random number generators generate reproducible results.
+  //
+  RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
+
+  //
+  // Set up some default values for the simulation.
+  //
+  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (137));
+
+  // ??? try and stick 15kb/s into the data rate
+  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("14kb/s"));
+
+  //
+  // Default number of nodes in the star.  Overridable by command line argument.
+  //
+  uint32_t nNodes = 9;
+
+  CommandLine cmd;
+  cmd.AddValue("nNodes", "Number of nodes to place in the star", nNodes);
+  cmd.Parse (argc, argv);
+
+  NS_LOG_INFO ("Create nodes.");
+  NodeContainer hubNode;
+  NodeContainer spokeNodes;
+  hubNode.Create (1);
+  Ptr<Node> hub = hubNode.Get (0);
+  spokeNodes.Create (nNodes - 1);
+
+  NS_LOG_INFO ("Install internet stack on all nodes.");
+  InternetStackHelper internet;
+  internet.Install (NodeContainer (hubNode, spokeNodes));
+
+  PointToPointHelper pointToPoint;
+  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
+
+  NS_LOG_INFO ("Build star topology.");
+  NetDeviceContainer hubDevices, spokeDevices;
+  pointToPoint.InstallStar (hubNode.Get (0), spokeNodes, hubDevices, spokeDevices);
+
+  NS_LOG_INFO ("Assign IP Addresses.");
+  Ipv4AddressHelper address;
+
+  //
+  // Assign IPv4 interfaces and IP addresses to the devices we previously
+  // created.  Keep track of the resulting addresses, one for the addresses
+  // of the hub node, and one for addresses on the spoke nodes.  Despite the
+  // name of the class, what is visible to clients is really the address.
+  //
+  Ipv4InterfaceContainer hubAddresses;
+  Ipv4InterfaceContainer spokeAddresses;
+
+  for(uint32_t i = 0; i < spokeNodes.GetN (); ++i)
+  {
+    std::ostringstream subnet;
+    subnet << "10.1.1." << (i << 2);
+    NS_LOG_INFO ("Assign IP Addresses for point-to-point subnet " << subnet.str ());
+    address.SetBase (subnet.str ().c_str (), "255.255.255.252");
+    hubAddresses.Add (address.Assign (hubDevices.Get (i)));
+    spokeAddresses.Add (address.Assign (spokeDevices.Get (i)));
+  }
+
+  NS_LOG_INFO ("Create applications.");
+  //
+  // Create a packet sink on the star "hub" to receive packets.  
+  // 
+  uint16_t port = 50000;
+  Address hubLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
+  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", hubLocalAddress);
+  ApplicationContainer hubApp = packetSinkHelper.Install (hubNode);
+  hubApp.Start (Seconds (1.0));
+  hubApp.Stop (Seconds (10.0));
+
+  //
+  // Create OnOff applications to send TCP to the hub, one on each spoke node.
+  //
+  OnOffHelper onOffHelper ("ns3::TcpSocketFactory", Address ());
+  onOffHelper.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onOffHelper.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+
+  ApplicationContainer spokeApps;
+
+  for (uint32_t i = 0; i < spokeNodes.GetN (); ++i)
+    {
+      AddressValue remoteAddress (InetSocketAddress (hubAddresses.GetAddress (i), port));
+      onOffHelper.SetAttribute ("Remote", remoteAddress);
+      spokeApps.Add (onOffHelper.Install (spokeNodes.Get (i)));
+  }
+  spokeApps.Start (Seconds (1.0));
+  spokeApps.Stop (Seconds (10.0));
+
+  NS_LOG_INFO ("Enable static global routing.");
+  //
+  // Turn on global static routing so we can actually be routed across the star.
+  //
+  GlobalRouteManager::PopulateRoutingTables ();
+
+  NS_LOG_INFO ("Enable pcap tracing.");
+  //
+  // Do pcap tracing on all devices on all nodes.
+  //
+  PointToPointHelper::EnablePcapAll ("star");
+
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+
+  return 0;
+}
--- a/examples/wscript	Wed Oct 15 15:53:06 2008 +0200
+++ b/examples/wscript	Mon Oct 27 12:17:38 2008 +0100
@@ -5,73 +5,81 @@
     obj.source = 'hello-simulator.cc'
         
     obj = bld.create_ns3_program('mixed-wireless',
-        ['core', 'simulator', 'mobility', 'wifi', 'point-to-point', 'internet-stack'])
+                                 ['core', 'simulator', 'mobility', 'wifi', 'point-to-point', 'internet-stack'])
     obj.source = 'mixed-wireless.cc'
 
     obj = bld.create_ns3_program('simple-global-routing',
-        ['point-to-point', 'internet-stack', 'global-routing'])
+                                 ['point-to-point', 'internet-stack', 'global-routing'])
     obj.source = 'simple-global-routing.cc'
 
     obj = bld.create_ns3_program('simple-alternate-routing',
-        ['point-to-point', 'internet-stack', 'global-routing'])
+                                 ['point-to-point', 'internet-stack', 'global-routing'])
     obj.source = 'simple-alternate-routing.cc'
 
     obj = bld.create_ns3_program('simple-error-model',
-        ['point-to-point', 'internet-stack'])
+                                 ['point-to-point', 'internet-stack'])
     obj.source = 'simple-error-model.cc'
 
     obj = bld.create_ns3_program('csma-one-subnet',
-        ['csma', 'internet-stack'])
+                                 ['csma', 'internet-stack'])
     obj.source = 'csma-one-subnet.cc'
 
     obj = bld.create_ns3_program('csma-bridge',
-        ['bridge', 'csma', 'internet-stack'])
+                                 ['bridge', 'csma', 'internet-stack'])
     obj.source = 'csma-bridge.cc'
 
     obj = bld.create_ns3_program('udp-echo',
-        ['csma', 'internet-stack'])
+                                 ['csma', 'internet-stack'])
     obj.source = 'udp-echo.cc'
 
     obj = bld.create_ns3_program('realtime-udp-echo',
-        ['csma', 'internet-stack'])
+                                 ['csma', 'internet-stack'])
     obj.source = 'realtime-udp-echo.cc'
 
     obj = bld.create_ns3_program('csma-broadcast',
-        ['csma', 'internet-stack'])
+                                 ['csma', 'internet-stack'])
     obj.source = 'csma-broadcast.cc'
 
     obj = bld.create_ns3_program('csma-packet-socket',
-        ['csma', 'internet-stack'])
+                                 ['csma', 'internet-stack'])
     obj.source = 'csma-packet-socket.cc'
 
     obj = bld.create_ns3_program('csma-multicast',
-        ['csma', 'internet-stack'])
+                                 ['csma', 'internet-stack'])
     obj.source = 'csma-multicast.cc'
 
     obj = bld.create_ns3_program( 'mixed-global-routing',
-        ['point-to-point', 'internet-stack', 'global-routing' , 'csma-cd'])
+                                  ['point-to-point', 'internet-stack', 'global-routing' , 'csma-cd'])
     obj.source = 'mixed-global-routing.cc'
 
     obj = bld.create_ns3_program('simple-point-to-point-olsr',
-        ['point-to-point', 'internet-stack', 'olsr'])
+                                 ['point-to-point', 'internet-stack', 'olsr'])
     obj.source = 'simple-point-to-point-olsr.cc'
 
     obj = bld.create_ns3_program('tcp-large-transfer',
-        ['point-to-point', 'internet-stack'])
+                                 ['point-to-point', 'internet-stack'])
     obj.source = 'tcp-large-transfer.cc'
 
     obj = bld.create_ns3_program('tcp-nsc-lfn',
-      ['point-to-point', 'internet-stack'])
+                                 ['point-to-point', 'internet-stack'])
     obj.source = 'tcp-nsc-lfn.cc'
 
     obj = bld.create_ns3_program('tcp-nsc-zoo',
-      ['csma', 'internet-stack'])
+                                 ['csma', 'internet-stack'])
     obj.source = 'tcp-nsc-zoo.cc'
 
     obj = bld.create_ns3_program('tcp-star-server',
-        ['point-to-point', 'internet-stack'])
+                                 ['point-to-point', 'internet-stack'])
     obj.source = 'tcp-star-server.cc'
 
+    obj = bld.create_ns3_program('star',
+                                 ['point-to-point', 'internet-stack'])
+    obj.source = 'star.cc'
+
+    obj = bld.create_ns3_program('csma-star',
+                                 ['csma', 'internet-stack'])
+    obj.source = 'csma-star.cc'
+
     obj = bld.create_ns3_program('wifi-adhoc',
                                  ['core', 'simulator', 'mobility', 'wifi'])
     obj.source = 'wifi-adhoc.cc'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/main-ns2-mob.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -0,0 +1,37 @@
+#include "ns3/core-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/mobility-module.h"
+#include <iostream>
+
+using namespace ns3;
+
+static void 
+CourseChange (std::ostream *os, std::string foo, Ptr<const MobilityModel> mobility)
+{
+  Vector pos = mobility->GetPosition ();
+  Vector vel = mobility->GetVelocity ();
+  *os << Simulator::Now () << " POS: x=" << pos.x << ", y=" << pos.y
+      << ", z=" << pos.z << "; VEL:" << vel.x << ", y=" << vel.y
+      << ", z=" << vel.z << std::endl;
+}
+
+int main (int argc, char *argv[])
+{
+  Ns2MobilityHelper mobility(argv[1]);
+  std::ofstream os;
+  os.open (argv[2]);
+  NodeContainer stas;
+  stas.Create (1);
+
+  mobility.Install ();
+
+  Config::Connect ("/NodeList/*/$ns3::MobilityModel/CourseChange",
+                   MakeBoundCallback (&CourseChange, &os));
+
+  Simulator::Stop (Seconds (10.0));
+  Simulator::Run ();
+  Simulator::Destroy ();
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/ns2-mob.tr	Mon Oct 27 12:17:38 2008 +0100
@@ -0,0 +1,7 @@
+
+$node_(0) set X_ 0.0
+$node_(0) set Y_ 25.0
+$node_(0) set Z_ 0.0
+$ns_ at 3.0 "$node_(0) setdest 25 0 0"
+$ns_ at 4.8 "$node_(0) setdest 0 0 0"
+$ns_ at 5.0 "$node_(0) setdest 25 0 0"
--- a/samples/wscript	Wed Oct 15 15:53:06 2008 +0200
+++ b/samples/wscript	Mon Oct 27 12:17:38 2008 +0100
@@ -42,4 +42,8 @@
                                  ['core', 'simulator', 'mobility', 'wifi'])
     obj.source = 'main-propagation-loss.cc'
 
+    obj = bld.create_ns3_program('main-ns2-mob',
+                                 ['core', 'simulator', 'mobility', 'wifi'])
+    obj.source = 'main-ns2-mob.cc'
 
+
--- a/src/applications/packet-sink/packet-sink.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/applications/packet-sink/packet-sink.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -87,7 +87,7 @@
     {
       m_socket = Socket::CreateSocket (GetNode(), m_tid);
       m_socket->Bind (m_local);
-      m_socket->Listen (0);
+      m_socket->Listen ();
     }
 
   m_socket->SetRecvCallback (MakeCallback(&PacketSink::HandleRead, this));
--- a/src/common/packet-metadata.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/common/packet-metadata.h	Mon Oct 27 12:17:38 2008 +0100
@@ -157,8 +157,6 @@
   void Serialize (Buffer::Iterator i, uint32_t size) const;
   uint32_t Deserialize (Buffer::Iterator i);
 
-  static void PrintStats (void);
-
   ItemIterator BeginItem (Buffer buffer) const;
 
 private:
--- a/src/common/packet.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/common/packet.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -297,6 +297,19 @@
 }
 
 uint32_t 
+Packet::CopyData (uint8_t *buffer, uint32_t size) const
+{
+  Buffer::Iterator i = m_buffer.Begin ();
+  uint32_t cur = 0;
+  while (!i.IsEnd () && cur < size)
+    {
+      buffer[cur] = i.ReadU8 ();
+      cur++;
+    }
+  return cur;
+}
+
+uint32_t 
 Packet::GetUid (void) const
 {
   return m_metadata.GetUid ();
--- a/src/common/packet.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/common/packet.h	Mon Oct 27 12:17:38 2008 +0100
@@ -281,6 +281,16 @@
   uint8_t const *PeekData (void) const;
 
   /**
+   * \param buffer a pointer to a byte buffer where the packet data 
+   *        should be copied.
+   * \param size the size of the byte buffer. 
+   * \returns the number of bytes read from the packet
+   *
+   * No more than \b size bytes will be copied by this function.
+   */
+  uint32_t CopyData (uint8_t *buffer, uint32_t size) const;
+
+  /**
    * A packet is allocated a new uid when it is created
    * empty or with zero-filled payload.
    *
@@ -437,6 +447,7 @@
  *   - ns3::Packet::CreateFragment
  *   - ns3::Packet::RemoveAtStart
  *   - ns3::Packet::RemoveAtEnd
+ *   - ns3::Packet::CopyData
  *
  * Dirty operations will always be slower than non-dirty operations,
  * sometimes by several orders of magnitude. However, even the
--- a/src/common/tag-list.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/common/tag-list.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -72,10 +72,8 @@
   struct Item item = Item (TagBuffer (m_current+16, m_end));
   item.tid.SetUid (m_nextTid);
   item.size = m_nextSize;
-  item.start = m_nextStart;
-  item.end = m_nextEnd;
-  item.start = std::max (item.start, m_offsetStart);
-  item.end = std::min (item.end, m_offsetEnd);
+  item.start = std::max (m_nextStart, m_offsetStart);
+  item.end = std::min (m_nextEnd, m_offsetEnd);
   m_current += 4 + 4 + 4 + 4 + item.size;
   item.buf.TrimAtEnd (m_end - m_current);
   PrepareForNext ();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/abort.h	Mon Oct 27 12:17:38 2008 +0100
@@ -0,0 +1,54 @@
+/* -*- 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
+ *
+ */
+#ifndef NS3_ABORT_H
+#define NS3_ABORT_H
+
+#include "fatal-error.h"
+
+#define NS_ABORT_IF(cond)					\
+  do {								\
+    if (cond)							\
+      {								\
+	std::cerr << "file=" << __FILE__ <<			\
+	  ", line=" << __LINE__ << ", abort on=\""#cond <<	\
+            "\"" << std::endl;                                  \
+	int *a = 0;						\
+	*a = 0;							\
+      }								\
+  } while (false)
+
+#define NS_ABORT_MSG_IF(cond, msg)				\
+  do {								\
+    if (cond)							\
+      {								\
+	std::cerr << "file=" << __FILE__ <<			\
+	  ", line=" << __LINE__ << ", abort on=\""#cond <<	\
+	  "\", msg=\"" << msg << "\"" << std::endl;		\
+	int *a = 0;						\
+	*a = 0;							\
+      }								\
+  } while (false)
+
+#define NS_ABORT_UNLESS(cond)				\
+  NS_ABORT_IF(!(cond))
+
+#define NS_ABORT_MSG_UNLESS(cond, msg)			\
+  NS_ABORT_MSG_IF(!(cond),msg)
+
+#endif /* NS3_ABORT_H */
--- a/src/core/attribute-accessor-helper.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/attribute-accessor-helper.h	Mon Oct 27 12:17:38 2008 +0100
@@ -48,6 +48,12 @@
 
 namespace ns3 {
 
+template <typename T>
+struct AccessorTrait
+{
+  typedef typename TypeTraits<typename TypeTraits<T>::ReferencedType>::NonConstType Result;
+};
+
 template <typename T, typename U>
 class AccessorHelper : public AttributeAccessor
 {
@@ -100,7 +106,13 @@
 	{}
     private:
       virtual bool DoSet (T *object, const V *v) const {
-	(object->*m_memberVariable) = U (v->Get ());
+        typename AccessorTrait<U>::Result tmp;
+        bool ok = v->GetAccessor (tmp);
+        if (!ok)
+          {
+            return false;
+          }
+	(object->*m_memberVariable) = tmp;
 	return true;
       }
       virtual bool DoGet (const T *object, V *v) const {
@@ -163,7 +175,13 @@
 	{}
     private:
       virtual bool DoSet (T *object, const V *v) const {
-	(object->*m_setter) (U (v->Get ()));
+        typename AccessorTrait<U>::Result tmp;
+        bool ok = v->GetAccessor (tmp);
+        if (!ok)
+          {
+            return false;
+          }
+	(object->*m_setter) (tmp);
 	return true;
       }
       virtual bool DoGet (const T *object, V *v) const {
@@ -196,7 +214,13 @@
 	{}
     private:
       virtual bool DoSet (T *object, const W *v) const {
-	(object->*m_setter) (v->Get ());
+        typename AccessorTrait<U>::Result tmp;
+        bool ok = v->GetAccessor (tmp);
+        if (!ok)
+          {
+            return false;
+          }
+	(object->*m_setter) (tmp);
 	return true;
       }
       virtual bool DoGet (const T *object, W *v) const {
@@ -239,7 +263,13 @@
 	{}
     private:
       virtual bool DoSet (T *object, const W *v) const {
-	bool ok = (object->*m_setter) (v->Get ());
+        typename AccessorTrait<U>::Result tmp;
+        bool ok = v->GetAccessor (tmp);
+        if (!ok)
+          {
+            return false;
+          }
+	ok = (object->*m_setter) (tmp);
         return ok;
       }
       virtual bool DoGet (const T *object, W *v) const {
--- a/src/core/attribute-helper.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/attribute-helper.h	Mon Oct 27 12:17:38 2008 +0100
@@ -117,6 +117,11 @@
     name##Value (const type &value);					\
     void Set (const type &value);					\
     type Get (void) const;						\
+    template <typename T>                                               \
+    bool GetAccessor (T &value) const {                                 \
+      value = T (m_value);                                              \
+      return true;                                                      \
+    }                                                                   \
     virtual Ptr<AttributeValue> Copy (void) const;                      \
     virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const; \
     virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker); \
@@ -220,17 +225,6 @@
     return MakeSimpleAttributeChecker<type##Value,type##Checker> (#type "Value", name); \
   }									\
 
-
-/**
- * \ingroup AttributeHelper
- * \param type the name of the class
- *
- * This macro implements the conversion operators to and from
- * instances of type Attribute. Typically invoked from xxx.cc.
- */
-#define ATTRIBUTE_CONVERTER_IMPLEMENT(type)
-
-
 /**
  * \ingroup AttributeHelper
  * \param type the name of the class
@@ -251,7 +245,6 @@
  */
 #define ATTRIBUTE_HELPER_CPP(type)                                      \
   ATTRIBUTE_CHECKER_IMPLEMENT (type);					\
-  ATTRIBUTE_CONVERTER_IMPLEMENT (type);					\
   ATTRIBUTE_VALUE_IMPLEMENT (type);
 
 
--- a/src/core/attribute-test.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/attribute-test.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -29,6 +29,7 @@
 #include "double.h"
 #include "object-vector.h"
 #include "traced-value.h"
+#include "callback.h"
 #include "trace-source-accessor.h"
 #include "pointer.h"
 
@@ -71,9 +72,13 @@
   void NotifySourceValue (ValueClassTest old, ValueClassTest n) {
     m_gotValue = n;
   }
+  void NotifyCallbackValue (int8_t a) {
+    m_gotCbValue = a;
+  }
   int64_t m_got1;
   double m_got2;
   ValueClassTest m_gotValue;
+  int16_t m_gotCbValue;
 };
 
 class Derived : public Object
@@ -171,6 +176,10 @@
                      PointerValue (),
                      MakePointerAccessor (&AttributeObjectTest::m_ptr),
                      MakePointerChecker<Derived> ())
+      .AddAttribute ("Callback", "help text",
+                     CallbackValue (),
+                     MakeCallbackAccessor (&AttributeObjectTest::m_cbValue),
+                     MakeCallbackChecker ())
       ;
         
     return tid;
@@ -187,6 +196,13 @@
     m_cb (a,b,c);
   }
 
+  void InvokeCbValue (int8_t a) {
+    if (!m_cbValue.IsNull ())
+      {
+        m_cbValue (a);
+      }
+  }
+
 private:
   void DoSetTestB (bool v) {
     m_boolTestA = v;
@@ -224,6 +240,7 @@
   RandomVariable m_random;
   std::vector<Ptr<Derived> > m_vector1;
   std::vector<Ptr<Derived> > m_vector2;
+  Callback<void,int8_t> m_cbValue;
   TracedValue<int8_t> m_intSrc1;
   TracedValue<int8_t> m_intSrc2;
   TracedCallback<double, int, float> m_cb;
@@ -492,6 +509,21 @@
   derived = ptr.Get<Derived> ();
   NS_TEST_ASSERT (derived != 0);
 
+  p = CreateObject<AttributeObjectTest> ();
+  NS_TEST_ASSERT (p != 0);
+  m_gotCbValue = 1;
+  p->InvokeCbValue (2);
+  CallbackValue cbValue = MakeCallback (&AttributeTest::NotifyCallbackValue, this);
+  NS_TEST_ASSERT_EQUAL (m_gotCbValue, 1);
+  NS_TEST_ASSERT (p->SetAttributeFailSafe ("Callback", 
+                                           cbValue));
+  p->InvokeCbValue (2);
+  NS_TEST_ASSERT_EQUAL (m_gotCbValue, 2);
+  NS_TEST_ASSERT (p->SetAttributeFailSafe ("Callback", 
+                                           CallbackValue (MakeNullCallback<void,int8_t> ())));
+  p->InvokeCbValue (3);
+  NS_TEST_ASSERT_EQUAL (m_gotCbValue, 2);
+  
   return result;
 }
 
--- a/src/core/boolean.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/boolean.h	Mon Oct 27 12:17:38 2008 +0100
@@ -42,6 +42,8 @@
   BooleanValue (bool value);
   void Set (bool value);
   bool Get (void) const;
+  template <typename T>
+  bool GetAccessor (T &v) const;
   
   operator bool () const;
 
@@ -52,6 +54,13 @@
   bool m_value;
 };
 
+template <typename T>
+bool BooleanValue::GetAccessor (T &v) const
+{
+  v = T (m_value);
+  return true;
+}
+
 std::ostream & operator << (std::ostream &os, const BooleanValue &value);
 
 ATTRIBUTE_CHECKER_DEFINE (Boolean);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/callback.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -0,0 +1,38 @@
+#include "callback.h"
+
+namespace ns3 {
+
+CallbackValue::CallbackValue ()
+  : m_value ()
+{}
+CallbackValue::CallbackValue (const CallbackBase &base)
+  : m_value (base)
+{}
+CallbackValue::~CallbackValue ()
+{}
+void 
+CallbackValue::Set (CallbackBase base)
+{
+  m_value = base;
+}
+Ptr<AttributeValue> 
+CallbackValue::Copy (void) const
+{
+  return Create<CallbackValue> (m_value);
+}
+std::string 
+CallbackValue::SerializeToString (Ptr<const AttributeChecker> checker) const
+{
+  std::ostringstream oss;
+  oss << PeekPointer (m_value.GetImpl ());
+  return oss.str ();
+}
+bool 
+CallbackValue::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker)
+{
+  return false;
+}
+
+ATTRIBUTE_CHECKER_IMPLEMENT (Callback);
+
+} // namespace ns3
--- a/src/core/callback.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/callback.h	Mon Oct 27 12:17:38 2008 +0100
@@ -25,6 +25,8 @@
 #include "fatal-error.h"
 #include "empty.h"
 #include "type-traits.h"
+#include "attribute.h"
+#include "attribute-helper.h"
 #include <typeinfo>
 
 namespace ns3 {
@@ -399,7 +401,11 @@
     return static_cast<CallbackImpl<R,T1,T2,T3,T4,T5,T6> *> (PeekPointer (m_impl));
   }
   bool DoCheckType (Ptr<const CallbackImplBase> other) const {
-    if (dynamic_cast<const CallbackImpl<R,T1,T2,T3,T4,T5,T6> *> (PeekPointer (other)) != 0)
+    if (other != 0 && dynamic_cast<const CallbackImpl<R,T1,T2,T3,T4,T5,T6> *> (PeekPointer (other)) != 0)
+      {
+        return true;
+      }
+    else if (other == 0)
       {
         return true;
       }
@@ -753,9 +759,45 @@
     Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5),R,TX,T1,T2,T3,T4,T5> > (fnPtr, a);
   return Callback<R,T1,T2,T3,T4,T5> (impl);
 }
+} // namespace ns3
 
+namespace ns3 {
+
+class CallbackValue : public AttributeValue
+{
+public:
+  CallbackValue ();
+  CallbackValue (const CallbackBase &base);
+  virtual ~CallbackValue ();
+  void Set (CallbackBase base);
+  template <typename T>
+  bool GetAccessor (T &value) const;
+  virtual Ptr<AttributeValue> Copy (void) const;
+  virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const;
+  virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker);
+private:
+  CallbackBase m_value;
+};
 
-}; // namespace ns3
+ATTRIBUTE_ACCESSOR_DEFINE(Callback);
+ATTRIBUTE_CHECKER_DEFINE (Callback);
+
+} // namespace ns3
+
+namespace ns3 {
+
+template <typename T>
+bool CallbackValue::GetAccessor (T &value) const
+{
+  if (value.CheckType (m_value))
+    {
+      value.Assign (m_value);
+      return true;
+    }
+  return false;
+}
+
+} // namespace ns3
 
 
 #endif /* CALLBACK_H */
--- a/src/core/config.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/config.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -30,6 +30,100 @@
 
 namespace ns3 {
 
+namespace Config {
+
+MatchContainer::MatchContainer ()
+{}
+MatchContainer::MatchContainer (const std::vector<Ptr<Object> > &objects, 
+                                const std::vector<std::string> &contexts,
+                                std::string path)
+  : m_objects (objects),
+    m_contexts (contexts),
+    m_path (path)
+{}
+MatchContainer::Iterator 
+MatchContainer::Begin (void) const
+{
+  return m_objects.begin ();
+}
+MatchContainer::Iterator 
+MatchContainer::End (void) const
+{
+  return m_objects.end ();
+}
+uint32_t 
+MatchContainer::GetN (void) const
+{
+  return m_objects.size ();
+}
+Ptr<Object> 
+MatchContainer::Get (uint32_t i) const
+{
+  return m_objects[i];
+}
+std::string 
+MatchContainer::GetMatchedPath (uint32_t i) const
+{
+  return m_contexts[i];
+}
+std::string 
+MatchContainer::GetPath (void) const
+{
+  return m_path;
+}
+
+void 
+MatchContainer::Set (std::string name, const AttributeValue &value)
+{
+  for (Iterator tmp = Begin (); tmp != End (); ++tmp)
+    {
+      Ptr<Object> object = *tmp;
+      object->SetAttribute (name, value);
+    }
+}
+void 
+MatchContainer::Connect (std::string name, const CallbackBase &cb)
+{
+  NS_ASSERT (m_objects.size () == m_contexts.size ());
+  for (uint32_t i = 0; i < m_objects.size (); ++i)
+    {
+      Ptr<Object> object = m_objects[i];
+      std::string ctx = m_contexts[i] + name;
+      object->TraceConnect (name, ctx, cb);
+    }
+}
+void 
+MatchContainer::ConnectWithoutContext (std::string name, const CallbackBase &cb)
+{
+  for (Iterator tmp = Begin (); tmp != End (); ++tmp)
+    {
+      Ptr<Object> object = *tmp;
+      object->TraceConnectWithoutContext (name, cb);
+    }
+}
+void 
+MatchContainer::Disconnect (std::string name, const CallbackBase &cb)
+{
+  NS_ASSERT (m_objects.size () == m_contexts.size ());
+  for (uint32_t i = 0; i < m_objects.size (); ++i)
+    {
+      Ptr<Object> object = m_objects[i];
+      std::string ctx = m_contexts[i] + name;
+      object->TraceDisconnect (name, ctx, cb);
+    }
+}
+void 
+MatchContainer::DisconnectWithoutContext (std::string name, const CallbackBase &cb)
+{
+  for (Iterator tmp = Begin (); tmp != End (); ++tmp)
+    {
+      Ptr<Object> object = *tmp;
+      object->TraceDisconnectWithoutContext (name, cb);
+    }
+}
+
+} // namespace Config
+
 class ArrayMatcher
 {
 public:
@@ -125,20 +219,40 @@
 
   void Resolve (Ptr<Object> root);
 private:
+  void Canonicalize (void);
   void DoResolve (std::string path, Ptr<Object> root);
   void DoArrayResolve (std::string path, const ObjectVectorValue &vector);
-  void DoResolveOne (Ptr<Object> object, std::string name);
-  std::string GetResolvedPath (std::string name) const;
-  virtual void DoOne (Ptr<Object> object, std::string path, std::string name) = 0;
+  void DoResolveOne (Ptr<Object> object);
+  std::string GetResolvedPath (void) const;
+  virtual void DoOne (Ptr<Object> object, std::string path) = 0;
   std::vector<std::string> m_workStack;
   std::string m_path;
 };
 
 Resolver::Resolver (std::string path)
   : m_path (path)
-{}
+{
+  Canonicalize ();
+}
 Resolver::~Resolver ()
 {}
+void
+Resolver::Canonicalize (void)
+{
+  // ensure that we start and end with a '/'
+  std::string::size_type tmp = m_path.find ("/");
+  if (tmp != 0)
+    {
+      // no slash at start
+      m_path = "/" + m_path;
+    }
+  tmp = m_path.find_last_of ("/");
+  if (tmp != (m_path.size () - 1))
+    {
+      // no slash at end
+      m_path = m_path + "/";
+    }
+}
 
 void 
 Resolver::Resolve (Ptr<Object> root)
@@ -147,40 +261,34 @@
 }
 
 std::string
-Resolver::GetResolvedPath (std::string name) const
+Resolver::GetResolvedPath (void) const
 {
-  std::string fullPath = "";
+  std::string fullPath = "/";
   for (std::vector<std::string>::const_iterator i = m_workStack.begin (); i != m_workStack.end (); i++)
     {
-      fullPath += "/" + *i;
+      fullPath += *i + "/";
     }
-  fullPath += "/" + name;
   return fullPath;
 }
 
 void 
-Resolver::DoResolveOne (Ptr<Object> object, std::string name)
+Resolver::DoResolveOne (Ptr<Object> object)
 {
-  NS_LOG_DEBUG ("resolved="<<GetResolvedPath (name));
-  DoOne (object, GetResolvedPath (name), name);
+  NS_LOG_DEBUG ("resolved="<<GetResolvedPath ());
+  DoOne (object, GetResolvedPath ());
 }
 
 void
 Resolver::DoResolve (std::string path, Ptr<Object> root)
 {
-  NS_ASSERT (path != "");
-  std::string::size_type pos = path.find ("/");
-  if (pos != 0)
-    {
-      NS_FATAL_ERROR ("path does not start with a \"/\": \""<<path<<"\"");
-      return;
-    }
+  NS_LOG_FUNCTION (path << root);
+  std::string::size_type tmp;
+  tmp = path.find ("/");
+  NS_ASSERT (tmp == 0);
   std::string::size_type next = path.find ("/", 1);
   if (next == std::string::npos)
     {
-      std::string attributeName = path.substr (1, path.size ()-1);
-      NS_LOG_DEBUG ("handle attr="<<attributeName);
-      DoOne (root, GetResolvedPath (attributeName), attributeName);
+      DoResolveOne (root);
       return;
     }
   std::string item = path.substr (1, next-1);
@@ -191,12 +299,12 @@
     {
       // This is a call to GetObject
       std::string tidString = item.substr (1, item.size () - 1);
-      NS_LOG_DEBUG ("GetObject="<<tidString<<" on path="<<GetResolvedPath (""));
+      NS_LOG_DEBUG ("GetObject="<<tidString<<" on path="<<GetResolvedPath ());
       TypeId tid = TypeId::LookupByName (tidString);
       Ptr<Object> object = root->GetObject<Object> (tid);
       if (object == 0)
 	{
-	  NS_LOG_DEBUG ("GetObject ("<<tidString<<") failed on path="<<GetResolvedPath (""));
+	  NS_LOG_DEBUG ("GetObject ("<<tidString<<") failed on path="<<GetResolvedPath ());
 	  return;
 	}
       m_workStack.push_back (item);
@@ -210,21 +318,21 @@
       struct TypeId::AttributeInfo info;
       if (!tid.LookupAttributeByName (item, &info))
 	{
-	  NS_LOG_DEBUG ("Requested item="<<item<<" does not exist on path="<<GetResolvedPath (""));
+	  NS_LOG_DEBUG ("Requested item="<<item<<" does not exist on path="<<GetResolvedPath ());
 	  return;
 	}
       // attempt to cast to a pointer checker.
       const PointerChecker *ptr = dynamic_cast<const PointerChecker *> (PeekPointer (info.checker));
       if (ptr != 0)
 	{
-	  NS_LOG_DEBUG ("GetAttribute(ptr)="<<item<<" on path="<<GetResolvedPath (""));
+	  NS_LOG_DEBUG ("GetAttribute(ptr)="<<item<<" on path="<<GetResolvedPath ());
           PointerValue ptr;
           root->GetAttribute (item, ptr);
 	  Ptr<Object> object = ptr.Get<Object> ();
 	  if (object == 0)
 	    {
 	      NS_LOG_ERROR ("Requested object name=\""<<item<<
-			    "\" exists on path=\""<<GetResolvedPath ("")<<"\""
+			    "\" exists on path=\""<<GetResolvedPath ()<<"\""
 			    " but is null.");
 	      return;
 	    }
@@ -236,7 +344,7 @@
       const ObjectVectorChecker *vectorChecker = dynamic_cast<const ObjectVectorChecker *> (PeekPointer (info.checker));
       if (vectorChecker != 0)
 	{
-	  NS_LOG_DEBUG ("GetAttribute(vector)="<<item<<" on path="<<GetResolvedPath (""));
+	  NS_LOG_DEBUG ("GetAttribute(vector)="<<item<<" on path="<<GetResolvedPath ());
 	  ObjectVectorValue vector;
           root->GetAttribute (item, vector);
 	  m_workStack.push_back (item);
@@ -252,17 +360,13 @@
 Resolver::DoArrayResolve (std::string path, const ObjectVectorValue &vector)
 {
   NS_ASSERT (path != "");
-  std::string::size_type pos = path.find ("/");
-  if (pos != 0)
-    {
-      NS_FATAL_ERROR ("path does not start with a \"/\": \""<<path<<"\"");
-      return;
-    }
+  std::string::size_type tmp;
+  tmp = path.find ("/");
+  NS_ASSERT (tmp == 0);
   std::string::size_type next = path.find ("/", 1);
   if (next == std::string::npos)
     {
-      NS_LOG_DEBUG ("vector path includes no index data on path=\""<<path<<"\"");
-      return;
+      NS_FATAL_ERROR ("vector path includes no index data on path=\""<<path<<"\"");
     }
   std::string item = path.substr (1, next-1);
   std::string pathLeft = path.substr (next, path.size ()-next);
@@ -290,6 +394,7 @@
   void Connect (std::string path, const CallbackBase &cb);
   void DisconnectWithoutContext (std::string path, const CallbackBase &cb);
   void Disconnect (std::string path, const CallbackBase &cb);
+  Config::MatchContainer LookupMatches (std::string path);
 
   void RegisterRootNamespaceObject (Ptr<Object> obj);
   void UnregisterRootNamespaceObject (Ptr<Object> obj);
@@ -298,110 +403,86 @@
   Ptr<Object> GetRootNamespaceObject (uint32_t i) const;
   
 private:
+  void ParsePath (std::string path, std::string *root, std::string *leaf) const;
   typedef std::vector<Ptr<Object> > Roots;
   Roots m_roots;
 };
 
 void 
+ConfigImpl::ParsePath (std::string path, std::string *root, std::string *leaf) const
+{
+  std::string::size_type slash = path.find_last_of ("/");
+  NS_ASSERT (slash != std::string::npos);
+  *root = path.substr (0, slash);
+  *leaf = path.substr (slash+1, path.size ()-(slash+1));
+  NS_LOG_FUNCTION (path << *root << *leaf);
+}
+
+void 
 ConfigImpl::Set (std::string path, const AttributeValue &value)
 {
-  class SetResolver : public Resolver 
-  {
-  public:
-    SetResolver (std::string path, const AttributeValue &value)
-      : Resolver (path),
-	m_value (value.Copy ()) {}
-  private:
-    virtual void DoOne (Ptr<Object> object, std::string path, std::string name) {
-      object->SetAttribute (name, *m_value);
-    }
-    Ptr<const AttributeValue> m_value;
-  } resolver = SetResolver (path, value);
-  for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++)
-    {
-      resolver.Resolve (*i);
-    }
+  std::string root, leaf;
+  ParsePath (path, &root, &leaf);
+  Config::MatchContainer container = LookupMatches (root);
+  container.Set (leaf, value);
 }
 void 
 ConfigImpl::ConnectWithoutContext (std::string path, const CallbackBase &cb)
 {
-  class ConnectResolver : public Resolver 
-  {
-  public:
-    ConnectResolver (std::string path, const CallbackBase &cb)
-      : Resolver (path),
-	m_cb (cb) {}
-  private:
-    virtual void DoOne (Ptr<Object> object, std::string path, std::string name) {
-      object->TraceConnectWithoutContext (name, m_cb);
-    }
-    CallbackBase m_cb;
-  } resolver = ConnectResolver (path, cb);
-  for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++)
-    {
-      resolver.Resolve (*i);
-    }
+  std::string root, leaf;
+  ParsePath (path, &root, &leaf);
+  Config::MatchContainer container = LookupMatches (root);
+  container.ConnectWithoutContext (leaf, cb);
 }
 void 
 ConfigImpl::DisconnectWithoutContext (std::string path, const CallbackBase &cb)
 {
-  class DisconnectResolver : public Resolver 
-  {
-  public:
-    DisconnectResolver (std::string path, const CallbackBase &cb)
-      : Resolver (path),
-	m_cb (cb) {}
-  private:
-    virtual void DoOne (Ptr<Object> object, std::string path, std::string name) {
-      object->TraceDisconnectWithoutContext (name, m_cb);
-    }
-    CallbackBase m_cb;
-  } resolver = DisconnectResolver (path, cb);
-  for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++)
-    {
-      resolver.Resolve (*i);
-    }
+  std::string root, leaf;
+  ParsePath (path, &root, &leaf);
+  Config::MatchContainer container = LookupMatches (root);
+  container.DisconnectWithoutContext (leaf, cb);
 }
 void 
 ConfigImpl::Connect (std::string path, const CallbackBase &cb)
 {
-  class ConnectWithContextResolver : public Resolver 
+  std::string root, leaf;
+  ParsePath (path, &root, &leaf);
+  Config::MatchContainer container = LookupMatches (root);
+  container.Connect (leaf, cb);
+}
+void 
+ConfigImpl::Disconnect (std::string path, const CallbackBase &cb)
+{
+  std::string root, leaf;
+  ParsePath (path, &root, &leaf);
+  Config::MatchContainer container = LookupMatches (root);
+  container.Disconnect (leaf, cb);
+}
+
+Config::MatchContainer 
+ConfigImpl::LookupMatches (std::string path)
+{
+  NS_LOG_FUNCTION (path);
+  class LookupMatchesResolver : public Resolver 
   {
   public:
-    ConnectWithContextResolver (std::string path, const CallbackBase &cb)
-      : Resolver (path),
-	m_cb (cb) {}
-  private:
-    virtual void DoOne (Ptr<Object> object, std::string path, std::string name) {
-      object->TraceConnect (name, path, m_cb);
+    LookupMatchesResolver (std::string path)
+      : Resolver (path)
+    {}
+    virtual void DoOne (Ptr<Object> object, std::string path) {
+      m_objects.push_back (object);
+      m_contexts.push_back (path);
     }
-    CallbackBase m_cb;
-  } resolver = ConnectWithContextResolver (path, cb);
+    std::vector<Ptr<Object> > m_objects;
+    std::vector<std::string> m_contexts;
+  } resolver = LookupMatchesResolver (path);
   for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++)
     {
       resolver.Resolve (*i);
     }
+  return Config::MatchContainer (resolver.m_objects, resolver.m_contexts, path);
 }
-void 
-ConfigImpl::Disconnect (std::string path, const CallbackBase &cb)
-{
-  class DisconnectWithContextResolver : public Resolver 
-  {
-  public:
-    DisconnectWithContextResolver (std::string path, const CallbackBase &cb)
-      : Resolver (path),
-	m_cb (cb) {}
-  private:
-    virtual void DoOne (Ptr<Object> object, std::string path, std::string name) {
-      object->TraceDisconnect (name, path, m_cb);
-    }
-    CallbackBase m_cb;
-  } resolver = DisconnectWithContextResolver (path, cb);
-  for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++)
-    {
-      resolver.Resolve (*i);
-    }
-}
+
 void 
 ConfigImpl::RegisterRootNamespaceObject (Ptr<Object> obj)
 {
@@ -472,6 +553,10 @@
 {
   Singleton<ConfigImpl>::Get ()->Disconnect (path, cb);
 }
+Config::MatchContainer LookupMatches (std::string path)
+{
+  return Singleton<ConfigImpl>::Get ()->LookupMatches (path);
+}
 
 void RegisterRootNamespaceObject (Ptr<Object> obj)
 {
--- a/src/core/config.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/config.h	Mon Oct 27 12:17:38 2008 +0100
@@ -22,6 +22,7 @@
 
 #include "ptr.h"
 #include <string>
+#include <vector>
 
 namespace ns3 {
 
@@ -110,6 +111,35 @@
  */
 void Disconnect (std::string path, const CallbackBase &cb);
 
+class MatchContainer
+{
+public:
+  typedef std::vector<Ptr<Object> >::const_iterator Iterator;
+  MatchContainer ();
+  MatchContainer (const std::vector<Ptr<Object> > &objects, 
+                  const std::vector<std::string> &contexts, 
+                  std::string path);
+
+  MatchContainer::Iterator Begin (void) const;
+  MatchContainer::Iterator End (void) const;
+  uint32_t GetN (void) const;
+  Ptr<Object> Get (uint32_t i) const;
+  std::string GetMatchedPath (uint32_t i) const;
+  std::string GetPath (void) const;
+
+  void Set (std::string name, const AttributeValue &value);
+  void Connect (std::string name, const CallbackBase &cb);
+  void ConnectWithoutContext (std::string name, const CallbackBase &cb);
+  void Disconnect (std::string name, const CallbackBase &cb);
+  void DisconnectWithoutContext (std::string name, const CallbackBase &cb);
+private:
+  std::vector<Ptr<Object> > m_objects;
+  std::vector<std::string> m_contexts;
+  std::string m_path;
+};
+
+MatchContainer LookupMatches (std::string path);
+
 /**
  * \param obj a new root object
  *
--- a/src/core/enum.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/enum.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -39,7 +39,6 @@
 {
   return m_v;
 }
-
 Ptr<AttributeValue>
 EnumValue::Copy (void) const
 {
--- a/src/core/enum.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/enum.h	Mon Oct 27 12:17:38 2008 +0100
@@ -41,6 +41,8 @@
   EnumValue (int v);
   void Set (int v);
   int Get (void) const;
+  template <typename T>
+  bool GetAccessor (T &v) const;
 
   virtual Ptr<AttributeValue> Copy (void) const;
   virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const;
@@ -50,6 +52,13 @@
   int m_v;
 };
 
+template <typename T>
+bool EnumValue::GetAccessor (T &v) const
+{
+  v = T (m_v);
+  return true;
+}
+
 class EnumChecker : public AttributeChecker
 {
 public:
--- a/src/core/pointer.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/pointer.h	Mon Oct 27 12:17:38 2008 +0100
@@ -51,6 +51,9 @@
   Ptr<T> Get (void) const;
 
   template <typename T>
+  bool GetAccessor (Ptr<T> &v) const;
+
+  template <typename T>
   operator Ptr<T> () const;
 
   virtual Ptr<AttributeValue> Copy (void) const;
@@ -61,23 +64,6 @@
   Ptr<Object> m_value;
 };
 
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePointerAccessor (Ptr<U> T::*memberVariable);
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePointerAccessor (void (T::*setter) (Ptr<U>));
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePointerAccessor (Ptr<U> (T::*getter) (void) const);
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePointerAccessor (void (T::*setter) (Ptr<U>),
-		     Ptr<U> (T::*getter) (void) const);
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePointerAccessor (Ptr<U> (T::*getter) (void) const,
-		     void (T::*setter) (Ptr<U>));
 
 class PointerChecker : public AttributeChecker 
 {
@@ -142,57 +128,8 @@
   }
 };
 
-/********************************************************
- *              The Accessor associated to 
- *               PointerValue
- ********************************************************/
-
-template <typename T, typename U>
-class PointerAccessor : public AttributeAccessor
-{
-public:
-  virtual ~PointerAccessor () {}
-  virtual bool Set (ObjectBase * object, const AttributeValue &val) const {
-      T *obj = dynamic_cast<T *> (object);
-      if (obj == 0)
-        {
-          return false;
-        }
-      const PointerValue *value = dynamic_cast<const PointerValue *> (&val);
-      if (value == 0)
-        {
-          return false;
-        }
-      Ptr<U> ptr = dynamic_cast<U*> (PeekPointer (value->GetObject ()));
-      if (ptr == 0)
-        {
-          return false;
-        }
-      DoSet (obj, ptr);
-      return true;
-    }
-  virtual bool Get (const ObjectBase * object, AttributeValue &val) const {
-      const T *obj = dynamic_cast<const T *> (object);
-      if (obj == 0)
-        {
-          return false;
-        }
-      PointerValue *value = dynamic_cast<PointerValue *> (&val);
-      if (value == 0)
-        {
-          return false;
-        }
-      value->Set (DoGet (obj));
-      return true;
-    }
-private:
-  virtual void DoSet (T *object, Ptr<U> value) const = 0;
-  virtual Ptr<U> DoGet (const T *object) const = 0;
-};
-
 } // namespace internal
 
-
 template <typename T>
 PointerValue::PointerValue (const Ptr<T> &object)
 {
@@ -220,112 +157,21 @@
   return Get<T> ();
 }
 
-
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePointerAccessor (Ptr<U> T::*memberVariable)
+template <typename T>
+bool 
+PointerValue::GetAccessor (Ptr<T> &v) const
 {
-  struct MemberVariable : public internal::PointerAccessor<T,U>
-  {
-    Ptr<U> T::*m_memberVariable;
-    virtual void DoSet (T *object, Ptr<U> value) const {
-      (object->*m_memberVariable) = value;
-    }
-    virtual Ptr<U> DoGet (const T *object) const {
-      return object->*m_memberVariable;
-    }
-    virtual bool HasGetter (void) const {
-      return true;
-    }
-    virtual bool HasSetter (void) const {
-      return true;
-    }
-  } *spec = new MemberVariable ();
-  spec->m_memberVariable = memberVariable;
-  return Ptr<const AttributeAccessor> (spec, false);
-}
-
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePointerAccessor (void (T::*setter) (Ptr<U>))
-{
-  struct MemberMethod : public internal::PointerAccessor<T,U>
-  {
-    void (T::*m_setter) (Ptr<U>);
-    virtual void DoSet (T *object, Ptr<U> value) const {
-      (object->*m_setter) (value);
-    }
-    virtual Ptr<U> DoGet (const T *object) const {
-      return 0;
-      //return (object->*m_getter) ();
-    }
-    virtual bool HasGetter (void) const {
+  Ptr<T> ptr = dynamic_cast<T*> (PeekPointer (m_value));
+  if (ptr == 0)
+    {
       return false;
     }
-    virtual bool HasSetter (void) const {
-      return true;
-    }
-  } *spec = new MemberMethod ();
-  spec->m_setter = setter;
-  return Ptr<const AttributeAccessor> (spec, false);
+  v = ptr;
+  return true;
 }
 
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePointerAccessor (Ptr<U> (T::*getter) (void) const)
-{
-  struct MemberMethod : public internal::PointerAccessor<T,U>
-  {
-    Ptr<U> (T::*m_getter) (void) const;
-    virtual void DoSet (T *object, Ptr<U> value) const {
-      //(object->*m_setter) (value);
-    }
-    virtual Ptr<U> DoGet (const T *object) const {
-      return (object->*m_getter) ();
-    }
-    virtual bool HasGetter (void) const {
-      return true;
-    }
-    virtual bool HasSetter (void) const {
-      return false;
-    }
-  } *spec = new MemberMethod ();
-  spec->m_getter = getter;
-  return Ptr<const AttributeAccessor> (spec, false);
-}
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePointerAccessor (void (T::*setter) (Ptr<U>),
-		     Ptr<U> (T::*getter) (void) const)
-{
-  return MakePointerAccessor (getter, setter);
-}
-template <typename T, typename U>
-Ptr<const AttributeAccessor>
-MakePointerAccessor (Ptr<U> (T::*getter) (void) const,
-		     void (T::*setter) (Ptr<U>))
-{
-  struct MemberMethod : public internal::PointerAccessor<T,U>
-  {
-    void (T::*m_setter) (Ptr<U>);
-    Ptr<U> (T::*m_getter) (void) const;
-    virtual void DoSet (T *object, Ptr<U> value) const {
-      (object->*m_setter) (value);
-    }
-    virtual Ptr<U> DoGet (const T *object) const {
-      return (object->*m_getter) ();
-    }
-    virtual bool HasGetter (void) const {
-      return true;
-    }
-    virtual bool HasSetter (void) const {
-      return true;
-    }
-  } *spec = new MemberMethod ();
-  spec->m_setter = setter;
-  spec->m_getter = getter;
-  return Ptr<const AttributeAccessor> (spec, false);
-}
+
+ATTRIBUTE_ACCESSOR_DEFINE (Pointer);
 
 template <typename T>
 Ptr<AttributeChecker>
--- a/src/core/ptr.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/ptr.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -249,8 +249,8 @@
     Ptr<NoCount> p4 = CallTestConst (p1);
     Ptr<NoCount const> p5 = p4;
     //p4 = p5; You cannot make a const pointer be a non-const pointer.
-    // but if you use const_pointer_cast, you can.
-    p4 = const_pointer_cast<NoCount> (p5);
+    // but if you use ConstCast, you can.
+    p4 = ConstCast<NoCount> (p5);
     p5 = p1;
     Ptr<NoCount> p;
     if (p == 0)
--- a/src/core/ptr.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/ptr.h	Mon Oct 27 12:17:38 2008 +0100
@@ -341,13 +341,38 @@
   return PeekPointer<T> (lhs) < PeekPointer<T> (rhs);
 }
 
+template <typename T>
+bool operator <= (const Ptr<T> &lhs, const Ptr<T> &rhs)
+{
+  return PeekPointer<T> (lhs) <= PeekPointer<T> (rhs);
+}
+
+template <typename T>
+bool operator > (const Ptr<T> &lhs, const Ptr<T> &rhs)
+{
+  return PeekPointer<T> (lhs) > PeekPointer<T> (rhs);
+}
+
+template <typename T>
+bool operator >= (const Ptr<T> &lhs, const Ptr<T> &rhs)
+{
+  return PeekPointer<T> (lhs) >= PeekPointer<T> (rhs);
+}
+
 template <typename T1, typename T2>
 Ptr<T1>
-const_pointer_cast (Ptr<T2> const&p)
+ConstCast (Ptr<T2> const&p)
 {
   return Ptr<T1> (const_cast<T1 *> (PeekPointer (p)));
 }
 
+template <typename T1, typename T2>
+Ptr<T1>
+DynamicCast (Ptr<T2> const&p)
+{
+  return Ptr<T1> (dynamic_cast<T1 *> (PeekPointer (p)));
+}
+
 
 /****************************************************
  *      Member method implementations.
--- a/src/core/string.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/string.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -3,7 +3,6 @@
 namespace ns3 {
 
 ATTRIBUTE_CHECKER_IMPLEMENT_WITH_NAME (String, "std::string");
-ATTRIBUTE_CONVERTER_IMPLEMENT (String);
 ATTRIBUTE_VALUE_IMPLEMENT_WITH_NAME (std::string, String);
 
 } // namespace ns3
--- a/src/core/system-thread.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/system-thread.h	Mon Oct 27 12:17:38 2008 +0100
@@ -84,6 +84,10 @@
    * method provided to do this is Join (). If you call Join() you will block
    * until the SystemThread run method returns.
    *
+   * @warning The SystemThread uses SIGALRM to wake threads that are possibly
+   * blocked on IO.
+   * @see Shutdown
+   *
    * @warning I've made the system thread class look like a normal ns3 object
    * with smart pointers, and living in the heap.  This makes it very easy to
    * manage threads from a single master thread context.  You should be very
@@ -128,9 +132,47 @@
    */
   void Join (void);
 
+  /**
+   * @brief Indicates to a managed thread doing cooperative multithreading that
+   * its managing thread wants it to exit.
+   *
+   * It is often the case that we want a thread to be off doing work until such
+   * time as its job is done (typically when the simulation is done).  We then 
+   * want the thread to exit itself.  This method provides a consistent way for
+   * the managing thread to communicate with the managed thread.  After the
+   * manager thread calls this method, the Break() method will begin returning
+   * true, telling the managed thread to exit.
+   *
+   * This alone isn't really enough to merit these events, but in Unix, if a
+   * worker thread is doing blocking IO, it will need to be woken up from that
+   * read somehow.  This method also provides that functionality, by sending a
+   * SIGALRM signal to the possibly blocked thread.
+   *
+   * @warning Uses SIGALRM to notifiy threads possibly blocked on IO.  Beware
+   * if you are using signals.
+   * @see Break
+   */
+  void Shutdown (void);
+
+  /**
+   * @brief Indicates to a thread doing cooperative multithreading that
+   * its managing thread wants it to exit.
+   *
+   * It is often the case that we want a thread to be off doing work until such
+   * time as its job is done.  We then want the thread to exit itself.  This
+   * method allows a thread to query whether or not it should be running.  
+   * Typically, the worker thread is running in a forever-loop, and will need to
+   * "break" out of that loop to exit -- thus the name.
+   *
+   * @see Shutdown
+   * @returns true if thread is expected to exit (break out of the forever-loop)
+   */
+  bool Break (void);
+
 private:
   SystemThreadImpl * m_impl;
   mutable uint32_t m_count;
+  bool m_break;
 };
 
  void
--- a/src/core/unix-system-thread.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/unix-system-thread.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -20,6 +20,7 @@
 
 #include <pthread.h>
 #include <string.h>
+#include <signal.h>
 #include "fatal-error.h"
 #include "system-thread.h"
 #include "log.h"
@@ -49,11 +50,14 @@
 
   void Start (void);
   void Join (void);
+  void Shutdown (void);
+  bool Break (void);
 
 private:
   static void *DoRun (void *arg);
   Callback<void> m_callback;
   pthread_t m_thread;
+  bool m_break;
   void *    m_ret;
 };
 
@@ -61,6 +65,13 @@
   : m_callback (callback)
 {
   NS_LOG_FUNCTION_NOARGS ();
+  // Make sure we have a SIGALRM handler which does not terminate
+  // our process.
+  struct sigaction act;
+  act.sa_flags = 0;
+  sigemptyset (&act.sa_mask);
+  act.sa_handler = SIG_IGN;
+  sigaction (SIGALRM, &act, 0);
 }
 
   void
@@ -92,6 +103,26 @@
     }
 }
 
+  void 
+SystemThreadImpl::Shutdown (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  m_break = true;
+
+  // send a SIGALRM signal on the target thread to make sure that it
+  // will unblock.
+  pthread_kill (m_thread, SIGALRM);
+}
+
+  bool
+SystemThreadImpl::Break (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  return m_break;
+}
+
   void *
 SystemThreadImpl::DoRun (void *arg)
 {
@@ -136,4 +167,18 @@
   m_impl->Join ();
 }  
 
+  void 
+SystemThread::Shutdown (void) 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_impl->Shutdown ();
+}  
+
+  bool 
+SystemThread::Break (void) 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_impl->Break ();
+}  
+
 } // namespace ns3
--- a/src/core/wscript	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/core/wscript	Mon Oct 27 12:17:38 2008 +0100
@@ -72,6 +72,7 @@
         'traced-callback.cc',
         'trace-source-accessor.cc',
         'config.cc',
+        'callback.cc',
         ]
     core.uselib = 'RT'
 
@@ -115,7 +116,8 @@
         'trace-source-accessor.h',
         'config.h',
         'object-vector.h',
-        'deprecated.h'
+        'deprecated.h',
+        'abort.h',
         ]
 
     if sys.platform == 'win32':
--- a/src/devices/wifi/dca-txop.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/devices/wifi/dca-txop.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -305,12 +305,6 @@
   return station->NeedFragmentation (m_currentPacket);
 }
 
-uint32_t
-DcaTxop::GetNFragments (void)
-{
-  WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
-  return station->GetNFragments (m_currentPacket);
-}
 void
 DcaTxop::NextFragment (void)
 {
@@ -337,12 +331,19 @@
   return station->GetFragmentSize (m_currentPacket, m_fragmentNumber + 1);
 }
 
+uint32_t
+DcaTxop::GetFragmentOffset (void) 
+{
+  WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
+  return station->GetFragmentOffset (m_currentPacket, m_fragmentNumber);
+}
+
 Ptr<Packet>
 DcaTxop::GetFragmentPacket (WifiMacHeader *hdr)
 {
   *hdr = m_currentHdr;
   hdr->SetFragmentNumber (m_fragmentNumber);
-  uint32_t startOffset = m_fragmentNumber * GetFragmentSize ();
+  uint32_t startOffset = GetFragmentOffset ();
   Ptr<Packet> fragment;
   if (IsLastFragment ()) 
     {
--- a/src/devices/wifi/dca-txop.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/devices/wifi/dca-txop.h	Mon Oct 27 12:17:38 2008 +0100
@@ -137,9 +137,9 @@
   bool NeedRtsRetransmission (void);
   bool NeedDataRetransmission (void);
   bool NeedFragmentation (void);
-  uint32_t GetNFragments (void);
   uint32_t GetNextFragmentSize (void);
   uint32_t GetFragmentSize (void);
+  uint32_t GetFragmentOffset (void);
   WifiRemoteStation *GetStation (Mac48Address to) const;
   bool IsLastFragment (void);
   void NextFragment (void);
--- a/src/devices/wifi/mac-low.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/devices/wifi/mac-low.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -1055,7 +1055,7 @@
 void
 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode, double rtsSnr)
 {
-  NS_LOG_FUNCTION (this);
+  NS_LOG_FUNCTION (this << source << duration << rtsTxMode << rtsSnr);
   /* send a CTS when you receive a RTS 
    * right after SIFS.
    */
--- a/src/devices/wifi/nqap-wifi-mac.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/devices/wifi/nqap-wifi-mac.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -76,6 +76,9 @@
   m_dca->SetTxFailedCallback (MakeCallback (&NqapWifiMac::TxFailed, this));
 
   m_beaconDca = CreateObject<DcaTxop> ();
+  m_beaconDca->SetAifsn(1);
+  m_beaconDca->SetMinCw(0);
+  m_beaconDca->SetMaxCw(0);
   m_beaconDca->SetLow (m_low);
   m_beaconDca->SetManager (m_dcfManager);
 }
--- a/src/devices/wifi/nqsta-wifi-mac.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/devices/wifi/nqsta-wifi-mac.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -479,7 +479,10 @@
     } 
   else if (hdr->IsData ()) 
     {
-      ForwardUp (packet, hdr->GetAddr2 (), hdr->GetAddr1 ());
+      if (hdr->GetAddr3 () != GetAddress ())
+        {
+          ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ());
+        }
     } 
   else if (hdr->IsProbeReq () ||
            hdr->IsAssocReq ()) 
--- a/src/devices/wifi/wifi-mac.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/devices/wifi/wifi-mac.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -75,7 +75,8 @@
     .SetParent<Object> ()
     .AddAttribute ("CtsTimeout", "When this timeout expires, the RTS/CTS handshake has failed.",
                    TimeValue (GetDefaultCtsAckTimeout ()),
-                   MakeTimeAccessor (&WifiMac::m_ctsTimeout),
+                   MakeTimeAccessor (&WifiMac::SetCtsTimeout,
+                                     &WifiMac::GetCtsTimeout),
                    MakeTimeChecker ())
     .AddAttribute ("AckTimeout", "When this timeout expires, the DATA/ACK handshake has failed.",
                    TimeValue (GetDefaultCtsAckTimeout ()),
@@ -120,31 +121,11 @@
   return tid;
 }
 
-void
-WifiMac::SetPifs (Time pifs)
-{
-  m_pifs = pifs;
-}
-void 
-WifiMac::SetCtsTimeout (Time ctsTimeout)
-{
-  m_ctsTimeout = ctsTimeout;
-}
 void 
 WifiMac::SetMaxPropagationDelay (Time delay)
 {
   m_maxPropagationDelay = delay;
 }
-Time
-WifiMac::GetPifs (void) const
-{
-  return m_pifs;
-}
-Time
-WifiMac::GetCtsTimeout (void) const
-{
-  return m_ctsTimeout;
-}
 
 Time
 WifiMac::GetMsduLifetime (void) const
--- a/src/devices/wifi/wifi-mac.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/devices/wifi/wifi-mac.h	Mon Oct 27 12:17:38 2008 +0100
@@ -187,8 +187,6 @@
   static Time GetDefaultCtsAckDelay (void);
   static Time GetDefaultCtsAckTimeout (void);
 
-  Time m_pifs;
-  Time m_ctsTimeout;
   Time m_maxPropagationDelay;
   uint32_t m_maxMsduSize;
 };
--- a/src/devices/wifi/wifi-remote-station-manager.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/devices/wifi/wifi-remote-station-manager.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -656,6 +656,13 @@
       return GetManager ()->GetFragmentationThreshold ();
     }
 }
+uint32_t
+WifiRemoteStation::GetFragmentOffset (Ptr<const Packet> packet, uint32_t fragmentNumber)
+{
+  NS_ASSERT (fragmentNumber < GetNFragments (packet));
+  uint32_t fragmentOffset = fragmentNumber * GetManager ()->GetFragmentationThreshold ();
+  return fragmentOffset;
+}
 
 bool
 WifiRemoteStation::IsLastFragment (Ptr<const Packet> packet, uint32_t fragmentNumber) 
--- a/src/devices/wifi/wifi-remote-station-manager.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/devices/wifi/wifi-remote-station-manager.h	Mon Oct 27 12:17:38 2008 +0100
@@ -228,11 +228,6 @@
   virtual bool NeedFragmentation (Ptr<const Packet> packet);
   /**
    * \param packet the packet to send
-   * \returns the number of fragments which should be used for this packet.
-   */
-  virtual uint32_t GetNFragments (Ptr<const Packet> packet);
-  /**
-   * \param packet the packet to send
    * \param fragmentNumber the fragment index of the next fragment to send (starts at zero).
    * \returns the size of the corresponding fragment.
    */
@@ -240,6 +235,12 @@
   /**
    * \param packet the packet to send
    * \param fragmentNumber the fragment index of the next fragment to send (starts at zero).
+   * \returns the offset within the original packet where this fragment starts.
+   */
+  virtual uint32_t GetFragmentOffset (Ptr<const Packet> packet, uint32_t fragmentNumber);
+  /**
+   * \param packet the packet to send
+   * \param fragmentNumber the fragment index of the next fragment to send (starts at zero).
    * \returns true if this is the last fragment, false otherwise.
    */
   virtual bool IsLastFragment (Ptr<const Packet> packet, uint32_t fragmentNumber);
@@ -262,6 +263,7 @@
   virtual Ptr<WifiRemoteStationManager> GetManager (void) const = 0;
   virtual WifiMode DoGetDataMode (uint32_t size) = 0;
   virtual WifiMode DoGetRtsMode (void) = 0;
+  uint32_t GetNFragments (Ptr<const Packet> packet);
 protected:
   virtual void DoReportRtsFailed (void) = 0;
   virtual void DoReportDataFailed (void) = 0;
--- a/src/helper/csma-helper.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/helper/csma-helper.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -39,10 +39,10 @@
 
 void 
 CsmaHelper::SetQueue (std::string type,
-		      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 n1, const AttributeValue &v1,
+                      std::string n2, const AttributeValue &v2,
+                      std::string n3, const AttributeValue &v3,
+                      std::string n4, const AttributeValue &v4)
 {
   m_queueFactory.SetTypeId (type);
   m_queueFactory.Set (n1, v1);
@@ -78,6 +78,13 @@
 CsmaHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
 {
   std::ostringstream oss;
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/";
+  Config::MatchContainer matches = Config::LookupMatches (oss.str ());
+  if (matches.GetN () == 0)
+    {
+      return;
+    }
+  oss.str ("");
   oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
   Ptr<PcapWriter> pcap = Create<PcapWriter> ();
   pcap->Open (oss.str ());
@@ -106,9 +113,9 @@
     {
       Ptr<Node> node = *i;
       for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-	{
-	  devs.Add (node->GetDevice (j));
-	}
+        {
+          devs.Add (node->GetDevice (j));
+        }
     }
   EnablePcap (filename, devs);
 }
@@ -153,9 +160,9 @@
     {
       Ptr<Node> node = *i;
       for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-	{
-	  devs.Add (node->GetDevice (j));
-	}
+        {
+          devs.Add (node->GetDevice (j));
+        }
     }
   EnableAscii (os, devs);
 }
@@ -193,6 +200,19 @@
 }
 
 void 
+CsmaHelper::InstallStar (Ptr<Node> hub, NodeContainer spokes, 
+                         NetDeviceContainer& hubDevices, NetDeviceContainer& spokeDevices)
+{
+  for (uint32_t i = 0; i < spokes.GetN (); ++i)
+    {
+      NodeContainer nodes (hub, spokes.Get (i));
+      NetDeviceContainer nd = Install (nodes);
+      hubDevices.Add (nd.Get (0));
+      spokeDevices.Add (nd.Get (1));
+    }
+}
+
+void 
 CsmaHelper::EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
 {
   writer->WritePacket (packet);
--- a/src/helper/csma-helper.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/helper/csma-helper.h	Mon Oct 27 12:17:38 2008 +0100
@@ -57,10 +57,10 @@
    * CsmaNetDevice created through CsmaHelper::Install.
    */
   void SetQueue (std::string type,
-		 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 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 ());
 
   /**
    * \param n1 the name of the attribute to set
@@ -179,6 +179,39 @@
    */
   NetDeviceContainer Install (const NodeContainer &c, Ptr<CsmaChannel> channel);
 
+  /**
+   * \brief Make a star network topology.
+   *
+   * Given a pointer to a node that  will become the hub of the star, and a 
+   * NodeContainer containing pointers to the nodes that will become the 
+   * spokes; we construct CSMA net devices on the hub (corresponding to the 
+   * spokes) and store them in the hubDevices NetDeviceContainer.  We add a 
+   * net device to each spoke node and store them in the spokeDevices 
+   * NetDeviceContainer.  A CSMA is created for each spoke.
+   *
+   * Usually when one thinks of a star network, one thinks of point-to-point
+   * links.  We're just using a single pair of devices on a multi-point-to-point
+   * network "drops" as the link.  You are free to add any number of other 
+   * devices on the link if you want.
+   *
+   * The ordering of the devices in the hubDevices container is according to
+   * the order of the spokes container -- that is, hubDevices[0] will be the
+   * net device used on the hub that talks to spokes[0].  the container entry
+   * spokeDevices[0] will have the device that hubDevices[0] talks to -- those
+   * two devices are the ones that connect hub to spokes[0].
+   *
+   * \param hub The central node of the star network
+   * \param spokes A NodeContainer of the nodes that will be the spoke (leaf)
+   *               nodes
+   * \param hubDevices A NetDeviceContainer that will be filled with pointers
+   *                   to the point-to-point net devices created on the hub.
+   * \param spokeDevices A NetDeviceContainer that will be filled with pointers
+   *                    to the point-to-point net devices created on each of 
+   *                    the spokes.
+   */
+  void InstallStar (Ptr<Node> hub, NodeContainer spokes, 
+                    NetDeviceContainer& hubDevices, NetDeviceContainer& spokeDevices);
+
 private:
   static void RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
   static void EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
--- a/src/helper/ipv4-interface-container.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/helper/ipv4-interface-container.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -6,11 +6,21 @@
 Ipv4InterfaceContainer::Ipv4InterfaceContainer ()
 {}
 
+void 
+Ipv4InterfaceContainer::Add (Ipv4InterfaceContainer other)
+{
+    for (InterfaceVector::const_iterator i = other.m_interfaces.begin (); i != other.m_interfaces.end (); i++)
+    {
+      m_interfaces.push_back (*i);
+    }
+}
+
 uint32_t 
 Ipv4InterfaceContainer::GetN (void) const
 {
   return m_interfaces.size ();
 }
+
 Ipv4Address 
 Ipv4InterfaceContainer::GetAddress (uint32_t i) const
 {
--- a/src/helper/ipv4-interface-container.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/helper/ipv4-interface-container.h	Mon Oct 27 12:17:38 2008 +0100
@@ -21,6 +21,11 @@
   Ipv4InterfaceContainer ();
 
   /**
+   * Concatenate the entries in the other container with ours.
+   */
+  void Add (Ipv4InterfaceContainer other);
+
+  /**
    * \returns the number of interfaces stored in this Ipv4InterfaceContainer.
    */
   uint32_t GetN (void) const;
@@ -31,7 +36,9 @@
   void Add (Ptr<Ipv4> ipv4, uint32_t interface);
 
  private:
-  std::vector<std::pair<Ptr<Ipv4>,uint32_t> > m_interfaces;
+  
+  typedef std::vector<std::pair<Ptr<Ipv4>,uint32_t> > InterfaceVector;
+  InterfaceVector m_interfaces;
 };
 
 } // namespace ns3
--- a/src/helper/mobility-helper.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/helper/mobility-helper.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -47,15 +47,15 @@
 }
 void 
 MobilityHelper::SetPositionAllocator (std::string type,
-				      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)
+                                      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 pos;
   pos.SetTypeId (type);
@@ -73,15 +73,15 @@
 
 void 
 MobilityHelper::SetMobilityModel (std::string type,
-				  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)
+                                  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)
 {
   m_mobility.SetTypeId (type);
   m_mobility.Set (n1, v1);
@@ -122,29 +122,29 @@
       Ptr<Object> object = *i;
       Ptr<MobilityModel> model = object->GetObject<MobilityModel> ();
       if (model == 0)
-	{
-	  model = m_mobility.Create ()->GetObject<MobilityModel> ();
-	  if (model == 0)
-	    {
-	      NS_FATAL_ERROR ("The requested mobility model is not a mobility model: \""<< 
-			      m_mobility.GetTypeId ().GetName ()<<"\"");
-	    }
-	  if (m_mobilityStack.empty ())
-	    {
-	      NS_LOG_DEBUG ("node="<<object<<", mob="<<model);
-	      object->AggregateObject (model);
-	    }
-	  else
-	    {
-	      // we need to setup a hierarchical mobility model
-	      Ptr<MobilityModel> parent = m_mobilityStack.back ();
-	      Ptr<MobilityModel> hierarchical = 
-		CreateObject<HierarchicalMobilityModel> ("Child", PointerValue (model),
-							 "Parent", PointerValue (parent));
-	      object->AggregateObject (hierarchical);
-	      NS_LOG_DEBUG ("node="<<object<<", mob="<<hierarchical);
-	    }
-	}
+        {
+          model = m_mobility.Create ()->GetObject<MobilityModel> ();
+          if (model == 0)
+            {
+              NS_FATAL_ERROR ("The requested mobility model is not a mobility model: \""<< 
+                              m_mobility.GetTypeId ().GetName ()<<"\"");
+            }
+          if (m_mobilityStack.empty ())
+            {
+              NS_LOG_DEBUG ("node="<<object<<", mob="<<model);
+              object->AggregateObject (model);
+            }
+          else
+            {
+              // we need to setup a hierarchical mobility model
+              Ptr<MobilityModel> parent = m_mobilityStack.back ();
+              Ptr<MobilityModel> hierarchical = 
+                CreateObject<HierarchicalMobilityModel> ("Child", PointerValue (model),
+                                                         "Parent", PointerValue (parent));
+              object->AggregateObject (hierarchical);
+              NS_LOG_DEBUG ("node="<<object<<", mob="<<hierarchical);
+            }
+        }
       Vector position = m_position->GetNext ();
       model->SetPosition (position);
     }
--- a/src/helper/mobility-helper.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/helper/mobility-helper.h	Mon Oct 27 12:17:38 2008 +0100
@@ -72,15 +72,15 @@
    * \param v9 the value of the attribute to set in the mobility model.
    */
   void SetPositionAllocator (std::string type,
-			     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 ());
+                             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 ());
 
   /**
    * \param type the type of mobility model to use.
@@ -107,15 +107,15 @@
    * mobility model for each node.
    */
   void SetMobilityModel (std::string type,
-			 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 ());
+                         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 ());
 
   /**
    * \param reference item to push.
--- a/src/helper/node-container.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/helper/node-container.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -35,14 +35,14 @@
   Add (b);
 }
 NodeContainer::NodeContainer (const NodeContainer &a, const NodeContainer &b, 
-			      const NodeContainer &c)
+                              const NodeContainer &c)
 {
   Add (a);
   Add (b);
   Add (c);
 }
 NodeContainer::NodeContainer (const NodeContainer &a, const NodeContainer &b, 
-			      const NodeContainer &c, const NodeContainer &d)
+                              const NodeContainer &c, const NodeContainer &d)
 {
   Add (a);
   Add (b);
--- a/src/helper/ns2-mobility-helper.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/helper/ns2-mobility-helper.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -75,62 +75,65 @@
   if (file.is_open())
     {
       while (!file.eof() )
-	{
-	  std::string line;
-	  getline (file, line);
-	  std::string::size_type startNodeId = line.find_first_of ("(");
-	  std::string::size_type endNodeId = line.find_first_of (")");
-	  if (startNodeId == std::string::npos ||
-	      endNodeId == std::string::npos)
-	    {
-	      continue;
-	    }
-	  Ptr<StaticSpeedMobilityModel> model = GetMobilityModel (line.substr (startNodeId + 1, 
-									       endNodeId - startNodeId), 
-								  store);
-	  if (model == 0)
-	    {
-	      continue;
-	    }
-	  if (startNodeId == 6)
-	    {
-	      double value = ReadDouble (line.substr (endNodeId + 9, std::string::npos));
-	      std::string coordinate = line.substr (endNodeId + 6, 1);
+        {
+          std::string line;
+          getline (file, line);
+          std::string::size_type startNodeId = line.find_first_of ("(");
+          std::string::size_type endNodeId = line.find_first_of (")");
+          if (startNodeId == std::string::npos ||
+              endNodeId == std::string::npos)
+            {
+              continue;
+            }
+          Ptr<StaticSpeedMobilityModel> model = GetMobilityModel (line.substr (startNodeId + 1, 
+                                                                               endNodeId - startNodeId), 
+                                                                  store);
+          if (model == 0)
+            {
+              continue;
+            }
+          if (startNodeId == 6)
+            {
+              double value = ReadDouble (line.substr (endNodeId + 9, std::string::npos));
+              std::string coordinate = line.substr (endNodeId + 6, 1);
               Vector position = model->GetPosition ();
-	      if (coordinate == "X")
-		{
+              if (coordinate == "X")
+                {
                   position.x = value;
-		  NS_LOG_DEBUG ("X=" << value);
-		}
-	      else if (coordinate == "Y")
-		{
+                  NS_LOG_DEBUG ("X=" << value);
+                }
+              else if (coordinate == "Y")
+                {
                   position.y = value;
-		  NS_LOG_DEBUG ("Y=" << value);
-		}
-	      else if (coordinate == "Z")
-		{
+                  NS_LOG_DEBUG ("Y=" << value);
+                }
+              else if (coordinate == "Z")
+                {
                   position.z = value;
-		  NS_LOG_DEBUG ("Z=" << value);
-		}
+                  NS_LOG_DEBUG ("Z=" << value);
+                }
               else
                 {
                   continue;
                 }
               model->SetPosition (position);
-	    }
-	  else 
-	    {
-	      double at = ReadDouble (line.substr (8, startNodeId - 17));
-	      std::string::size_type xSpeedEnd = line.find_first_of (" ", endNodeId + 10);
-	      std::string::size_type ySpeedEnd = line.find_first_of (" ", xSpeedEnd + 1);
-	      double xSpeed = ReadDouble (line.substr (endNodeId + 10, xSpeedEnd - endNodeId - 10));
-	      double ySpeed = ReadDouble (line.substr (xSpeedEnd + 1, ySpeedEnd - xSpeedEnd - 1));
-	      double zSpeed = ReadDouble (line.substr (ySpeedEnd + 1, std::string::npos));
-	      NS_LOG_DEBUG ("at=" << at << "xSpeed=" << xSpeed << ", ySpeed=" << ySpeed << ", zSpeed=" << zSpeed);
-	      Simulator::Schedule (Seconds (at), &StaticSpeedMobilityModel::SetSpeed, model,
-				   Vector (xSpeed, ySpeed, zSpeed));
-	    }
-	}
+            }
+          else 
+            {
+              std::string::size_type atEnd = line.find_first_of (" ", 8);
+              std::string atStr = line.substr (8, atEnd-8);
+              NS_LOG_DEBUG (atStr);
+              double at = ReadDouble (atStr);
+              std::string::size_type xSpeedEnd = line.find_first_of (" ", endNodeId + 10);
+              std::string::size_type ySpeedEnd = line.find_first_of (" ", xSpeedEnd + 1);
+              double xSpeed = ReadDouble (line.substr (endNodeId + 10, xSpeedEnd - endNodeId - 10));
+              double ySpeed = ReadDouble (line.substr (xSpeedEnd + 1, ySpeedEnd - xSpeedEnd - 1));
+              double zSpeed = ReadDouble (line.substr (ySpeedEnd + 1, std::string::npos));
+              NS_LOG_DEBUG ("at=" << at << "xSpeed=" << xSpeed << ", ySpeed=" << ySpeed << ", zSpeed=" << zSpeed);
+              Simulator::Schedule (Seconds (at), &StaticSpeedMobilityModel::SetVelocity, model,
+                                   Vector (xSpeed, ySpeed, zSpeed));
+            }
+        }
       file.close();
     }
 }
--- a/src/helper/ns2-mobility-helper.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/helper/ns2-mobility-helper.h	Mon Oct 27 12:17:38 2008 +0100
@@ -90,14 +90,14 @@
     MyObjectStore (T begin, T end)
       : m_begin (begin),
       m_end (end)
-	{}
+        {}
     virtual Ptr<Object> Get (uint32_t i) const {
       T iterator = m_begin;
       iterator += i;
       if (iterator >= m_end)
-	{
-	  return 0;
-	}
+        {
+          return 0;
+        }
       return *iterator;
     }
   private:
--- a/src/helper/olsr-helper.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/helper/olsr-helper.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -30,14 +30,14 @@
 
 void 
 OlsrHelper::SetAgent (std::string tid,
-		      std::string n0, const AttributeValue &v0,
-		      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 n0, const AttributeValue &v0,
+                      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)
 {
   m_agentFactory.SetTypeId (tid);
   m_agentFactory.Set (n0, v0);
--- a/src/helper/olsr-helper.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/helper/olsr-helper.h	Mon Oct 27 12:17:38 2008 +0100
@@ -38,14 +38,14 @@
    * \brief Set default OLSR routing agent attributes
    */
   void SetAgent (std::string tid,
-		 std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
-		 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 n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+                 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 ());
 
   /**
    * \brief Enable OLSR routing for a set of nodes
--- a/src/helper/point-to-point-helper.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/helper/point-to-point-helper.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -39,10 +39,10 @@
 
 void 
 PointToPointHelper::SetQueue (std::string type,
-			      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 n1, const AttributeValue &v1,
+                              std::string n2, const AttributeValue &v2,
+                              std::string n3, const AttributeValue &v3,
+                              std::string n4, const AttributeValue &v4)
 {
   m_queueFactory.SetTypeId (type);
   m_queueFactory.Set (n1, v1);
@@ -78,6 +78,13 @@
 PointToPointHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
 {
   std::ostringstream oss;
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/";
+  Config::MatchContainer matches = Config::LookupMatches (oss.str ());
+  if (matches.GetN () == 0)
+    {
+      return;
+    }
+  oss.str ("");
   oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
   Ptr<PcapWriter> pcap = Create<PcapWriter> ();
   pcap->Open (oss.str ());
@@ -106,9 +113,9 @@
     {
       Ptr<Node> node = *i;
       for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-	{
-	  devs.Add (node->GetDevice (j));
-	}
+        {
+          devs.Add (node->GetDevice (j));
+        }
     }
   EnablePcap (filename, devs);
 }
@@ -153,9 +160,9 @@
     {
       Ptr<Node> node = *i;
       for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-	{
-	  devs.Add (node->GetDevice (j));
-	}
+        {
+          devs.Add (node->GetDevice (j));
+        }
     }
   EnableAscii (os, devs);
 }
@@ -172,6 +179,7 @@
   NS_ASSERT (c.GetN () == 2);
   return Install (c.Get (0), c.Get (1));
 }
+
 NetDeviceContainer 
 PointToPointHelper::Install (Ptr<Node> a, Ptr<Node> b)
 {
@@ -197,6 +205,18 @@
 }
 
 void 
+PointToPointHelper::InstallStar (Ptr<Node> hub, NodeContainer spokes, 
+                                 NetDeviceContainer& hubDevices, NetDeviceContainer& spokeDevices)
+{
+  for (uint32_t i = 0; i < spokes.GetN (); ++i)
+    {
+      NetDeviceContainer nd = Install (hub, spokes.Get (i));
+      hubDevices.Add (nd.Get (0));
+      spokeDevices.Add (nd.Get (1));
+    }
+}
+
+void 
 PointToPointHelper::EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
 {
   writer->WritePacket (packet);
--- a/src/helper/point-to-point-helper.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/helper/point-to-point-helper.h	Mon Oct 27 12:17:38 2008 +0100
@@ -57,10 +57,10 @@
    * PointToPointNetDevice created through PointToPointHelper::Install.
    */
   void SetQueue (std::string type,
-		 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 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 ());
 
   /**
    * \param name the name of the attribute to set
@@ -170,6 +170,7 @@
    * ns3::NetDevice with the ns3::Node and ns3::PointToPointChannel.
    */
   NetDeviceContainer Install (NodeContainer c);
+
   /**
    * \param a first node
    * \param b second node
@@ -178,6 +179,34 @@
    */
   NetDeviceContainer Install (Ptr<Node> a, Ptr<Node> b);
 
+  /**
+   * \brief Make a star network topology.
+   *
+   * Given a pointer to a node that  will become the hub of the star, and a 
+   * NodeContainer containing pointers to the nodes that will become the 
+   * spokes; we construct point to point net devices on the hub (corresponding 
+   * to the spokes) and store them in the hubDevices NetDeviceContainer.  We 
+   * add a net device to each spoke node and store them in the spokeDevices 
+   * NetDeviceContainer.  A point-to-point channel is created for each spoke.
+   *
+   * The ordering of the devices in the hubDevices container is according to
+   * the order of the spokes container -- that is, hubDevices[0] will be the
+   * net device used on the hub that talks to spokes[0].  the container entry
+   * spokeDevices[0] will have the device that hubDevices[0] talks to -- those
+   * two devices are the ones that connect hub to spokes[0].
+   *
+   * \param hub The central node of the star network
+   * \param spokes A NodeContainer of the nodes that will be the spoke (leaf)
+   *               nodes
+   * \param hubDevices A NetDeviceContainer that will be filled with pointers
+   *                   to the point-to-point net devices created on the hub.
+   * \param spokeDevices A NetDeviceContainer that will be filled with pointers
+   *                    to the point-to-point net devices created on each of 
+   *                    the spokes.
+   */
+  void InstallStar (Ptr<Node> hub, NodeContainer spokes, 
+                    NetDeviceContainer& hubDevices, NetDeviceContainer& spokeDevices);
+
 private:
   void EnablePcap (Ptr<Node> node, Ptr<NetDevice> device, Ptr<Queue> queue);
   void EnableAscii (Ptr<Node> node, Ptr<NetDevice> device);
--- a/src/helper/wifi-helper.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/helper/wifi-helper.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -40,30 +40,30 @@
 namespace ns3 {
 
 static void PcapPhyTxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet,
-			    WifiMode mode, WifiPreamble preamble, 
-			    uint8_t txLevel)
+                            WifiMode mode, WifiPreamble preamble, 
+                            uint8_t txLevel)
 {
   writer->WritePacket (packet);
 }
 
 static void PcapPhyRxEvent (Ptr<PcapWriter> writer, 
-			    Ptr<const Packet> packet, double snr, WifiMode mode, 
-			    enum WifiPreamble preamble)
+                            Ptr<const Packet> packet, double snr, WifiMode mode, 
+                            enum WifiPreamble preamble)
 {
   writer->WritePacket (packet);
 }
 
 static void AsciiPhyTxEvent (std::ostream *os, std::string context, 
-			     Ptr<const Packet> packet,
-			     WifiMode mode, WifiPreamble preamble, 
-			     uint8_t txLevel)
+                             Ptr<const Packet> packet,
+                             WifiMode mode, WifiPreamble preamble, 
+                             uint8_t txLevel)
 {
   *os << "+ " << Simulator::Now () << " " << context << " " << *packet << std::endl;
 }
 
 static void AsciiPhyRxOkEvent (std::ostream *os, std::string context, 
-			       Ptr<const Packet> packet, double snr, WifiMode mode, 
-			       enum WifiPreamble preamble)
+                               Ptr<const Packet> packet, double snr, WifiMode mode, 
+                               enum WifiPreamble preamble)
 {
   *os << "r " << Simulator::Now () << " " << context << " " << *packet << std::endl;
 }
@@ -78,14 +78,14 @@
 
 void 
 WifiHelper::SetRemoteStationManager (std::string type,
-				     std::string n0, const AttributeValue &v0,
-				     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 n0, const AttributeValue &v0,
+                                     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)
 {
   m_stationManager = ObjectFactory ();
   m_stationManager.SetTypeId (type);
@@ -101,14 +101,14 @@
 
 void 
 WifiHelper::SetMac (std::string type,
-		    std::string n0, const AttributeValue &v0,
-		    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 n0, const AttributeValue &v0,
+                    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)
 {
   m_mac = ObjectFactory ();
   m_mac.SetTypeId (type);
@@ -124,14 +124,14 @@
 
 void 
 WifiHelper::SetPhy (std::string type,
-		    std::string n0, const AttributeValue &v0,
-		    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 n0, const AttributeValue &v0,
+                    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)
 {
   m_phy = ObjectFactory ();
   m_phy.SetTypeId (type);
@@ -149,6 +149,13 @@
 WifiHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
 {
   std::ostringstream oss;
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/";
+  Config::MatchContainer matches = Config::LookupMatches (oss.str ());
+  if (matches.GetN () == 0)
+    {
+      return;
+    }
+  oss.str ("");
   oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
   Ptr<PcapWriter> pcap = Create<PcapWriter> ();
   pcap->Open (oss.str ());
@@ -177,9 +184,9 @@
     {
       Ptr<Node> node = *i;
       for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-	{
-	  devs.Add (node->GetDevice (j));
-	}
+        {
+          devs.Add (node->GetDevice (j));
+        }
     }
   EnablePcap (filename, devs);
 }
@@ -218,9 +225,9 @@
     {
       Ptr<Node> node = *i;
       for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-	{
-	  devs.Add (node->GetDevice (j));
-	}
+        {
+          devs.Add (node->GetDevice (j));
+        }
     }
   EnableAscii (os, devs);
 }
--- a/src/helper/wifi-helper.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/helper/wifi-helper.h	Mon Oct 27 12:17:38 2008 +0100
@@ -65,14 +65,14 @@
    * in the requested station manager.
    */
   void SetRemoteStationManager (std::string type,
-				std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
-				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 n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+                                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 ());
 
   /**
    * \param type the type of ns3::WifiMac to create.
@@ -97,14 +97,14 @@
    * in the requested mac.
    */
   void SetMac (std::string type,
-	       std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
-	       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 n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+               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 ());
 
   /**
    * \param phyType the type of ns3::WifiPhy to create.
@@ -129,14 +129,14 @@
    * in the requested phy.
    */
   void SetPhy (std::string phyType,
-	       std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
-	       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 n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+               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 ());
 
 
 
--- a/src/internet-stack/arp-l3-protocol.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/internet-stack/arp-l3-protocol.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -89,7 +89,7 @@
 Ptr<ArpCache> 
 ArpL3Protocol::CreateCache (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface)
 {
-  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_FUNCTION (this << device << interface);
   Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
   Ptr<ArpCache> cache = CreateObject<ArpCache> ();
   cache->SetDevice (device, interface);
@@ -103,7 +103,7 @@
 Ptr<ArpCache>
 ArpL3Protocol::FindCache (Ptr<NetDevice> device)
 {
-  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_FUNCTION (this << device);
   for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++)
     {
       if ((*i)->GetDevice () == device)
@@ -120,7 +120,7 @@
 ArpL3Protocol::Receive(Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
                        const Address &to, NetDevice::PacketType packetType)
 {
-  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_FUNCTION (this << device << p->GetSize () << protocol << from << to << packetType);
 
   Ptr<Packet> packet = p->Copy ();
 
@@ -199,7 +199,7 @@
                        Ptr<ArpCache> cache,
                        Address *hardwareDestination)
 {
-  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_FUNCTION (this << packet << destination << device << cache);
   ArpCache::Entry *entry = cache->Lookup (destination);
   if (entry != 0)
     {
@@ -265,7 +265,7 @@
 void
 ArpL3Protocol::SendArpRequest (Ptr<const ArpCache> cache, Ipv4Address to)
 {
-  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_FUNCTION (this << cache << to);
   ArpHeader arp;
   NS_LOG_LOGIC ("ARP: sending request from node "<<m_node->GetId ()<<
             " || src: " << cache->GetDevice ()->GetAddress () <<
@@ -284,7 +284,7 @@
 void
 ArpL3Protocol::SendArpReply (Ptr<const ArpCache> cache, Ipv4Address toIp, Address toMac)
 {
-  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_FUNCTION (this << cache << toIp << toMac);
   ArpHeader arp;
   NS_LOG_LOGIC ("ARP: sending reply from node "<<m_node->GetId ()<<
             "|| src: " << cache->GetDevice ()->GetAddress () << 
--- a/src/internet-stack/nsc-tcp-socket-impl.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/internet-stack/nsc-tcp-socket-impl.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -64,6 +64,8 @@
   : m_endPoint (0),
     m_node (0),
     m_tcp (0),
+    m_localAddress (Ipv4Address::GetZero ()),
+    m_localPort (0),
     m_peerAddress ("0.0.0.0", 0),
     m_errno (ERROR_NOTERROR),
     m_shutdownSend (false),
@@ -328,34 +330,19 @@
       return -1;
     }
 
-    bool txEmpty = m_txBuffer.empty();
+    uint32_t sent = p->GetSize ();
     if (m_state == ESTABLISHED)
       {
-        if (txEmpty)
-          {
-            m_txBuffer.push(p);
-            m_txBufferSize += p->GetSize ();
-          }
-        if (!SendPendingData())
-          {
-             if (m_errno == ERROR_AGAIN)
-               {
-                 return txEmpty ? p->GetSize () : -1;
-               }
-             if (txEmpty)
-               {
-                  m_txBuffer.pop ();
-                  m_txBufferSize = 0;
-               }
-             return -1;
-          }
+        m_txBuffer.push(p);
+        m_txBufferSize += sent;
+        SendPendingData();
       }
       else
       {  // SYN_SET -- Queue Data
          m_txBuffer.push(p);
-         m_txBufferSize += p->GetSize ();
+         m_txBufferSize += sent;
       }
-    return p->GetSize ();
+    return sent;
   }
   else
   {
@@ -395,9 +382,9 @@
 }
 
 int
-NscTcpSocketImpl::Listen (uint32_t q)
+NscTcpSocketImpl::Listen (void)
 {
-  NS_LOG_FUNCTION (this << q);
+  NS_LOG_FUNCTION (this);
   m_nscTcpSocket->listen(m_localPort);
   m_state = LISTEN;
   return 0;
@@ -434,6 +421,7 @@
   NS_LOG_FUNCTION_NOARGS ();
   if (m_deliveryQueue.empty() )
     {
+      m_errno = ERROR_AGAIN;
       return 0;
     }
   Ptr<Packet> p = m_deliveryQueue.front ();
@@ -444,6 +432,7 @@
     }
   else
     {
+      m_errno = ERROR_AGAIN;
       p = 0;
     }
   return p;
@@ -466,6 +455,14 @@
   return packet;
 }
 
+int
+NscTcpSocketImpl::GetSockName (Address &address) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  address = InetSocketAddress(m_localAddress, m_localPort);
+  return 0;
+}
+
 uint32_t
 NscTcpSocketImpl::GetRxAvailable (void) const
 {
@@ -627,6 +624,7 @@
   size_t size, written = 0;
 
   do {
+    NS_ASSERT (!m_txBuffer.empty ());
     Ptr<Packet> &p = m_txBuffer.front ();
     size = p->GetSize ();
     NS_ASSERT (size > 0);
@@ -635,12 +633,6 @@
     ret = m_nscTcpSocket->send_data((const char *)p->PeekData (), size);
     if (ret <= 0)
       {
-        m_errno = GetNativeNs3Errno(ret);
-        if (m_errno != ERROR_AGAIN)
-          {
-            NS_LOG_WARN ("Error (" << ret << ") " <<
-                         "during send_data, ns-3 errno set to" << m_errno);
-          }
         break;
       }
     written += ret;
--- a/src/internet-stack/nsc-tcp-socket-impl.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/internet-stack/nsc-tcp-socket-impl.h	Mon Oct 27 12:17:38 2008 +0100
@@ -73,7 +73,7 @@
   virtual int ShutdownSend (void);
   virtual int ShutdownRecv (void);
   virtual int Connect(const Address &address);
-  virtual int Listen(uint32_t queueLimit);
+  virtual int Listen(void);
   virtual uint32_t GetTxAvailable (void) const;
   virtual int Send (Ptr<Packet> p, uint32_t flags);
   virtual int SendTo(Ptr<Packet> p, uint32_t flags, const Address &toAddress);
@@ -81,6 +81,7 @@
   virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
   virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
     Address &fromAddress);
+  virtual int GetSockName (Address &address) const; 
 
 private:
   void NSCWakeup(void);
--- a/src/internet-stack/tcp-socket-impl.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/internet-stack/tcp-socket-impl.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -62,6 +62,8 @@
     m_endPoint (0),
     m_node (0),
     m_tcp (0),
+    m_localAddress (Ipv4Address::GetZero ()),
+    m_localPort (0),
     m_errno (ERROR_NOTERROR),
     m_shutdownSend (false),
     m_shutdownRecv (false),
@@ -454,9 +456,9 @@
 }
 
 int
-TcpSocketImpl::Listen (uint32_t q)
+TcpSocketImpl::Listen (void)
 {
-  NS_LOG_FUNCTION (this << q);
+  NS_LOG_FUNCTION (this);
   Actions_t action = ProcessEvent (APP_LISTEN);
   ProcessAction (action);
   return 0;
@@ -553,6 +555,14 @@
   return packet;
 }
 
+int
+TcpSocketImpl::GetSockName (Address &address) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  address = InetSocketAddress(m_localAddress, m_localPort);
+  return 0;
+}
+
 void
 TcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
 {
@@ -1915,7 +1925,7 @@
   InetSocketAddress serverremoteaddr (Ipv4Address(ipaddr0), port);
 
   listeningSock->Bind(serverlocaladdr);
-  listeningSock->Listen (0);
+  listeningSock->Listen ();
 
   sock1->Connect(serverremoteaddr);
 }
--- a/src/internet-stack/tcp-socket-impl.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/internet-stack/tcp-socket-impl.h	Mon Oct 27 12:17:38 2008 +0100
@@ -86,7 +86,7 @@
   virtual int ShutdownSend (void);
   virtual int ShutdownRecv (void);
   virtual int Connect(const Address &address);
-  virtual int Listen(uint32_t queueLimit);
+  virtual int Listen(void);
   virtual uint32_t GetTxAvailable (void) const;
   virtual int Send (Ptr<Packet> p, uint32_t flags);
   virtual int SendTo(Ptr<Packet> p, uint32_t flags, const Address &toAddress);
@@ -94,6 +94,7 @@
   virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
   virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
     Address &fromAddress);
+  virtual int GetSockName (Address &address) const; 
 
 private:
   friend class Tcp;
--- a/src/internet-stack/udp-socket-impl.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/internet-stack/udp-socket-impl.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -216,7 +216,7 @@
 }
 
 int 
-UdpSocketImpl::Listen (uint32_t queueLimit)
+UdpSocketImpl::Listen (void)
 {
   m_errno = Socket::ERROR_OPNOTSUPP;
   return -1;
@@ -345,6 +345,7 @@
           m_udp->Send (p->Copy (), addri, bcast,
                        m_endPoint->GetLocalPort (), port);
           NotifyDataSent (p->GetSize ());
+          NotifySend (GetTxAvailable ());
         }
       NS_LOG_LOGIC ("Limited broadcast end.");
       return p->GetSize();
@@ -355,6 +356,7 @@
       m_udp->Send (p->Copy (), ipv4->GetAddress (localIfIndex), dest,
 		   m_endPoint->GetLocalPort (), port);
       NotifyDataSent (p->GetSize ());
+      NotifySend (GetTxAvailable ());
       return p->GetSize();;
     }
   else
@@ -435,6 +437,21 @@
   return packet;
 }
 
+int
+UdpSocketImpl::GetSockName (Address &address) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_endPoint != 0)
+    {
+      address = InetSocketAddress (m_endPoint->GetLocalAddress (), m_endPoint->GetLocalPort());
+    }
+  else
+    {
+      address = InetSocketAddress(Ipv4Address::GetZero(), 0);
+    }
+  return 0;
+}
+
 void 
 UdpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
 {
--- a/src/internet-stack/udp-socket-impl.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/internet-stack/udp-socket-impl.h	Mon Oct 27 12:17:38 2008 +0100
@@ -65,7 +65,7 @@
   virtual int ShutdownSend (void);
   virtual int ShutdownRecv (void);
   virtual int Connect(const Address &address);
-  virtual int Listen (uint32_t queueLimit);
+  virtual int Listen (void);
   virtual uint32_t GetTxAvailable (void) const;
   virtual int Send (Ptr<Packet> p, uint32_t flags);
   virtual int SendTo (Ptr<Packet> p, uint32_t flags, const Address &address);
@@ -73,6 +73,7 @@
   virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
   virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
     Address &fromAddress);
+  virtual int GetSockName (Address &address) const; 
 
 private:
   // Attributes set through UdpSocket base class 
--- a/src/mobility/random-direction-2d-mobility-model.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/mobility/random-direction-2d-mobility-model.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -76,8 +76,9 @@
 void
 RandomDirection2dMobilityModel::BeginPause (void)
 {
+  m_helper.Update ();
+  m_helper.Pause ();
   Time pause = Seconds (m_pause.GetValue ());
-  m_helper.Pause ();
   m_event = Simulator::Schedule (pause, &RandomDirection2dMobilityModel::ResetDirectionAndSpeed, this);
   NotifyCourseChange ();
 }
@@ -86,12 +87,14 @@
 RandomDirection2dMobilityModel::SetDirectionAndSpeed (double direction)
 {
   NS_LOG_FUNCTION_NOARGS ();
+  m_helper.UpdateWithBounds (m_bounds);
+  Vector position = m_helper.GetCurrentPosition ();
   double speed = m_speed.GetValue ();
   const Vector vector (std::cos (direction) * speed,
                        std::sin (direction) * speed,
                        0.0);
-  Vector position = m_helper.GetCurrentPosition (m_bounds);
-  m_helper.Reset (vector);
+  m_helper.SetVelocity (vector);
+  m_helper.Unpause ();
   Vector next = m_bounds.CalculateIntersection (position, vector);
   Time delay = Seconds (CalculateDistance (position, next) / speed);
   m_event = Simulator::Schedule (delay,
@@ -103,7 +106,8 @@
 {
   double direction = UniformVariable::GetSingleValue (0, PI);
   
-  Vector position = m_helper.GetCurrentPosition (m_bounds);
+  m_helper.UpdateWithBounds (m_bounds);
+  Vector position = m_helper.GetCurrentPosition ();
   switch (m_bounds.GetClosestSide (position))
     {
     case Rectangle::RIGHT:
@@ -124,12 +128,13 @@
 Vector
 RandomDirection2dMobilityModel::DoGetPosition (void) const
 {
-  return m_helper.GetCurrentPosition (m_bounds);
+  m_helper.UpdateWithBounds (m_bounds);
+  return m_helper.GetCurrentPosition ();
 }
 void
 RandomDirection2dMobilityModel::DoSetPosition (const Vector &position)
 {
-  m_helper.InitializePosition (position);
+  m_helper.SetPosition (position);
   Simulator::Remove (m_event);
   m_event = Simulator::ScheduleNow (&RandomDirection2dMobilityModel::Start, this);
 }
--- a/src/mobility/random-walk-2d-mobility-model.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/mobility/random-walk-2d-mobility-model.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -80,12 +80,14 @@
 void
 RandomWalk2dMobilityModel::Start (void)
 {
+  m_helper.Update ();
   double speed = m_speed.GetValue ();
   double direction = m_direction.GetValue ();
   Vector vector (std::cos (direction) * speed,
                  std::sin (direction) * speed,
                  0.0);
-  m_helper.Reset (vector);
+  m_helper.SetVelocity (vector);
+  m_helper.Unpause ();
 
   Time delayLeft;
   if (m_mode == RandomWalk2dMobilityModel::MODE_TIME)
@@ -124,7 +126,8 @@
 void
 RandomWalk2dMobilityModel::Rebound (Time delayLeft)
 {
-  Vector position = m_helper.GetCurrentPosition (m_bounds);
+  m_helper.UpdateWithBounds (m_bounds);
+  Vector position = m_helper.GetCurrentPosition ();
   Vector speed = m_helper.GetVelocity ();
   switch (m_bounds.GetClosestSide (position))
     {
@@ -137,7 +140,8 @@
       speed.y = - speed.y;
       break;
     }
-  m_helper.Reset (speed);
+  m_helper.SetVelocity (speed);
+  m_helper.Unpause ();
   DoWalk (delayLeft);
 }
 
@@ -150,13 +154,14 @@
 Vector
 RandomWalk2dMobilityModel::DoGetPosition (void) const
 {
-  return m_helper.GetCurrentPosition (m_bounds);
+  m_helper.UpdateWithBounds (m_bounds);
+  return m_helper.GetCurrentPosition ();
 }
 void
 RandomWalk2dMobilityModel::DoSetPosition (const Vector &position)
 {
   NS_ASSERT (m_bounds.IsInside (position));
-  m_helper.InitializePosition (position);
+  m_helper.SetPosition (position);
   Simulator::Remove (m_event);
   m_event = Simulator::ScheduleNow (&RandomWalk2dMobilityModel::Start, this);
 }
--- a/src/mobility/random-waypoint-mobility-model.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/mobility/random-waypoint-mobility-model.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -62,6 +62,7 @@
 void
 RandomWaypointMobilityModel::BeginWalk (void)
 {
+  m_helper.Update ();
   Vector m_current = m_helper.GetCurrentPosition ();
   Vector destination = m_position->GetNext ();
   double speed = m_speed.GetValue ();
@@ -70,7 +71,7 @@
   double dz = (destination.z - m_current.z);
   double k = speed / std::sqrt (dx*dx + dy*dy + dz*dz);
 
-  m_helper.Reset (Vector (k*dx, k*dy, k*dz));
+  m_helper.SetVelocity (Vector (k*dx, k*dy, k*dz));
   Time travelDelay = Seconds (CalculateDistance (destination, m_current) / speed);
   m_event = Simulator::Schedule (travelDelay,
 				 &RandomWaypointMobilityModel::Start, this);
@@ -80,21 +81,23 @@
 void
 RandomWaypointMobilityModel::Start (void)
 {
-  Time pause = Seconds (m_pause.GetValue ());
+  m_helper.Update ();
   m_helper.Pause ();
+  Time pause = Seconds (m_pause.GetValue ());
+  m_event = Simulator::Schedule (pause, &RandomWaypointMobilityModel::BeginWalk, this);
   NotifyCourseChange ();
-  m_event = Simulator::Schedule (pause, &RandomWaypointMobilityModel::BeginWalk, this);
 }
 
 Vector
 RandomWaypointMobilityModel::DoGetPosition (void) const
 {
+  m_helper.Update ();
   return m_helper.GetCurrentPosition ();
 }
 void 
 RandomWaypointMobilityModel::DoSetPosition (const Vector &position)
 {
-  m_helper.InitializePosition (position);
+  m_helper.SetPosition (position);
   Simulator::Remove (m_event);
   Simulator::ScheduleNow (&RandomWaypointMobilityModel::Start, this);
 }
--- a/src/mobility/static-speed-helper.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/mobility/static-speed-helper.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -29,67 +29,56 @@
   : m_position (position)
 {}
 StaticSpeedHelper::StaticSpeedHelper (const Vector &position,
-				      const Vector &speed)
+				      const Vector &vel)
   : m_position (position),
-    m_speed (speed),
+    m_velocity (vel),
     m_paused (true)
 {}
 void 
-StaticSpeedHelper::InitializePosition (const Vector &position)
+StaticSpeedHelper::SetPosition (const Vector &position)
 {
   m_position = position;
-  m_speed.x = 0.0;
-  m_speed.y = 0.0;
-  m_speed.z = 0.0;
+  m_velocity = Vector (0.0, 0.0, 0.0);
   m_lastUpdate = Simulator::Now ();
-  m_paused = true;
 }
 
 Vector
 StaticSpeedHelper::GetCurrentPosition (void) const
 {
-  Update ();
   return m_position;
 }
 
 Vector 
 StaticSpeedHelper::GetVelocity (void) const
 {
-  return m_paused? Vector (0.0, 0.0, 0.0) : m_speed;
+  return m_paused? Vector (0.0, 0.0, 0.0) : m_velocity;
 }
 void 
-StaticSpeedHelper::SetSpeed (const Vector &speed)
+StaticSpeedHelper::SetVelocity (const Vector &vel)
 {
-  Update ();
-  m_speed = speed;
+  m_velocity = vel;
+  m_lastUpdate = Simulator::Now ();
 }
 
 void
 StaticSpeedHelper::Update (void) const
 {
-  if (m_paused)
-    {
-      return;
-    }
   Time now = Simulator::Now ();
   NS_ASSERT (m_lastUpdate <= now);
   Time deltaTime = now - m_lastUpdate;
   m_lastUpdate = now;
+  if (m_paused)
+    {
+      return;
+    }
   double deltaS = deltaTime.GetSeconds ();
-  m_position.x += m_speed.x * deltaS;
-  m_position.y += m_speed.y * deltaS;
-  m_position.z += m_speed.z * deltaS;
+  m_position.x += m_velocity.x * deltaS;
+  m_position.y += m_velocity.y * deltaS;
+  m_position.z += m_velocity.z * deltaS;
 }
 
-void 
-StaticSpeedHelper::Reset (const Vector &speed)
-{
-  Update ();
-  m_speed = speed;
-  Unpause ();
-}
 void
-StaticSpeedHelper::UpdateFull (const Rectangle &bounds) const
+StaticSpeedHelper::UpdateWithBounds (const Rectangle &bounds) const
 {
   Update ();
   m_position.x = std::min (bounds.xMax, m_position.x);
@@ -98,28 +87,16 @@
   m_position.y = std::max (bounds.yMin, m_position.y);
 }
 
-Vector 
-StaticSpeedHelper::GetCurrentPosition (const Rectangle &bounds) const
-{
-  UpdateFull (bounds);
-  return m_position;
-}
-
 void 
 StaticSpeedHelper::Pause (void)
 {
-  Update ();
   m_paused = true;
 }
 
 void 
 StaticSpeedHelper::Unpause (void)
 {
-  if (m_paused)
-    {
-      m_lastUpdate = Simulator::Now ();
-      m_paused = false;
-    }
+  m_paused = false;
 }
 
 } // namespace ns3
--- a/src/mobility/static-speed-helper.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/mobility/static-speed-helper.h	Mon Oct 27 12:17:38 2008 +0100
@@ -33,23 +33,21 @@
   StaticSpeedHelper ();
   StaticSpeedHelper (const Vector &position);
   StaticSpeedHelper (const Vector &position,
-		     const Vector &speed);
-  void InitializePosition (const Vector &position);
+		     const Vector &vel);
 
-  void Reset (const Vector &speed);
-  Vector GetCurrentPosition (const Rectangle &bounds) const;
+  void SetPosition (const Vector &position);
   Vector GetCurrentPosition (void) const;
   Vector GetVelocity (void) const;
-  void SetSpeed (const Vector &speed);
+  void SetVelocity (const Vector &vel);
   void Pause (void);
   void Unpause (void);
 
- private:
+  void UpdateWithBounds (const Rectangle &rectangle) const;
   void Update (void) const;
-  void UpdateFull (const Rectangle &rectangle) const;
+ private:
   mutable Time m_lastUpdate;
   mutable Vector m_position;
-  Vector m_speed;
+  Vector m_velocity;
   bool m_paused;
 };
 
--- a/src/mobility/static-speed-mobility-model.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/mobility/static-speed-mobility-model.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -39,9 +39,11 @@
 {}
 
 void 
-StaticSpeedMobilityModel::SetSpeed (const Vector &speed)
+StaticSpeedMobilityModel::SetVelocity (const Vector &speed)
 {
-  m_helper.SetSpeed (speed);
+  m_helper.Update ();
+  m_helper.SetVelocity (speed);
+  m_helper.Unpause ();
   NotifyCourseChange ();
 }
 
@@ -49,12 +51,13 @@
 Vector
 StaticSpeedMobilityModel::DoGetPosition (void) const
 {
+  m_helper.Update ();
   return m_helper.GetCurrentPosition ();
 }
 void 
 StaticSpeedMobilityModel::DoSetPosition (const Vector &position)
 {
-  m_helper.InitializePosition (position);
+  m_helper.SetPosition (position);
   NotifyCourseChange ();
 }
 Vector
--- a/src/mobility/static-speed-mobility-model.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/mobility/static-speed-mobility-model.h	Mon Oct 27 12:17:38 2008 +0100
@@ -49,7 +49,7 @@
    * Set the current speed now to (dx,dy,dz)
    * Unit is meters/s
    */
-  void SetSpeed (const Vector &speed);
+  void SetVelocity (const Vector &speed);
 private:
   virtual Vector DoGetPosition (void) const;
   virtual void DoSetPosition (const Vector &position);
--- a/src/node/channel.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/node/channel.h	Mon Oct 27 12:17:38 2008 +0100
@@ -14,8 +14,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef CHANNEL_H
-#define CHANNEL_H
+#ifndef NS3_CHANNEL_H
+#define NS3_CHANNEL_H
 
 #include <string>
 #include <stdint.h>
@@ -69,4 +69,4 @@
 
 }; // namespace ns3
 
-#endif /* CHANNEL_H */
+#endif /* NS3_CHANNEL_H */
--- a/src/node/ipv4-header.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/node/ipv4-header.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -221,6 +221,7 @@
   os << "tos 0x" << std::hex << m_tos << std::dec << " "
      << "ttl " << m_ttl << " "
      << "id " << m_identification << " "
+     << "protocol " << m_protocol << " "
      << "offset " << m_fragmentOffset << " "
      << "flags [" << flags << "] "
      << "length: " << (m_payloadSize + 5 * 4)
--- a/src/node/packet-socket.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/node/packet-socket.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -57,6 +57,8 @@
   m_shutdownSend = false;
   m_shutdownRecv = false;
   m_errno = ERROR_NOTERROR;
+  m_isSingleDevice = false;
+  m_device = 0;
 }
 
 void 
@@ -222,7 +224,7 @@
   return -1;
 }
 int 
-PacketSocket::Listen(uint32_t queueLimit)
+PacketSocket::Listen(void)
 {
   m_errno = Socket::ERROR_OPNOTSUPP;
   return -1;
@@ -329,6 +331,7 @@
   if (!error)
     {
       NotifyDataSent (p->GetSize ());
+      NotifySend (GetTxAvailable ());
     }
 
   if (error)
@@ -428,4 +431,27 @@
   return packet;
 }
 
+int
+PacketSocket::GetSockName (Address &address) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  PacketSocketAddress ad = PacketSocketAddress::ConvertFrom(address);
+  
+  ad.SetProtocol (m_protocol);
+  if (m_isSingleDevice)
+    {
+      Ptr<NetDevice> device = m_node->GetDevice (ad.GetSingleDevice ());
+      ad.SetPhysicalAddress(device->GetAddress());      
+      ad.SetSingleDevice (m_device);
+    }
+  else
+    {
+      ad.SetPhysicalAddress(Address());   
+      ad.SetAllDevices ();
+    }  
+  address = ad;
+  
+  return 0;
+}
+
 }//namespace ns3
--- a/src/node/packet-socket.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/node/packet-socket.h	Mon Oct 27 12:17:38 2008 +0100
@@ -93,7 +93,7 @@
   virtual int ShutdownSend (void);
   virtual int ShutdownRecv (void);
   virtual int Connect(const Address &address);
-  virtual int Listen(uint32_t queueLimit);
+  virtual int Listen(void);
   virtual uint32_t GetTxAvailable (void) const;
   virtual int Send (Ptr<Packet> p, uint32_t flags);
   virtual int SendTo(Ptr<Packet> p, uint32_t flags, const Address &toAddress);
@@ -101,6 +101,7 @@
   virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
   virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
     Address &fromAddress);
+  virtual int GetSockName (Address &address) const; 
 
 private:
   void ForwardUp (Ptr<NetDevice> device, Ptr<const Packet> packet, 
--- a/src/node/socket.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/node/socket.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -71,12 +71,11 @@
   m_newConnectionCreated = newConnectionCreated;
 }
 
-bool 
+void
 Socket::SetDataSentCallback (Callback<void, Ptr<Socket>, uint32_t> dataSent)
 {
   NS_LOG_FUNCTION_NOARGS ();
   m_dataSent = dataSent;
-  return true;
 }
 
 void
@@ -100,12 +99,6 @@
   return Send (p, 0);
 }
 
-
-int Socket::Listen (uint32_t queueLimit)
-{
-  return 0; //XXX the base class version does nothing
-}
-
 int 
 Socket::Send (const uint8_t* buf, uint32_t size, uint32_t flags)
 {
--- a/src/node/socket.h	Wed Oct 15 15:53:06 2008 +0200
+++ b/src/node/socket.h	Mon Oct 27 12:17:38 2008 +0100
@@ -141,13 +141,8 @@
    * \param dataSent Callback for the event that data is sent from the
    *        underlying transport protocol.  This callback is passed a
    *        pointer to the socket, and the number of bytes sent.
-   * \returns whether or not this socket supports this callback.  Note 
-   *        that this is a non-standard socket call.  Some socket 
-   *        implementations in ns-3 may not support this call, so the
-   *        user should check this return value to confirm that the
-   *        callback is supported.
    */
-  bool SetDataSentCallback (Callback<void, Ptr<Socket>, 
+  void SetDataSentCallback (Callback<void, Ptr<Socket>, 
                             uint32_t> dataSent);
   /**
    * \brief Notify application when space in transmit buffer is added
@@ -222,7 +217,7 @@
    * \param queueLimit maximum number of incoming request to queue
    * \returns 0 on success, -1 on error (in which case errno is set).
    */
-  virtual int Listen (uint32_t queueLimit) = 0;
+  virtual int Listen (void) = 0;
 
   /**
    * \brief Returns the number of bytes which can be sent in a single call
@@ -492,6 +487,10 @@
    */
   int RecvFrom (uint8_t* buf, uint32_t size, uint32_t flags,
                 Address &fromAddress);
+    /**
+   * \returns the address name  this socket is associated with.
+   */
+  virtual int GetSockName (Address &address) const = 0; 
  
 protected:
   void NotifyConnectionSucceeded (void);
--- a/utils/bench-packets.cc	Wed Oct 15 15:53:06 2008 +0200
+++ b/utils/bench-packets.cc	Mon Oct 27 12:17:38 2008 +0100
@@ -266,6 +266,10 @@
           iss.str (nAscii);
           iss >> n;
         }
+      if (strncmp ("--enable-printing", argv[0], strlen ("--enable-printing")) == 0)
+        {
+          Packet::EnablePrinting ();
+        }
       argc--;
       argv++;
   }
@@ -282,13 +286,5 @@
   runBench (&benchC, n, "c");
   runBench (&benchD, n, "d");
 
-  Packet::EnablePrinting ();
-  runBench (&benchA, n, "meta-a");
-  runBench (&benchB, n, "meta-b");
-  runBench (&benchC, n, "meta-c");
-  runBench (&benchD, n, "meta-d");
-
-
-
   return 0;
 }
--- a/utils/python-unit-tests.py	Wed Oct 15 15:53:06 2008 +0200
+++ b/utils/python-unit-tests.py	Mon Oct 27 12:17:38 2008 +0100
@@ -57,7 +57,6 @@
         self.assertEqual(v1, ns3.Seconds(50))
 
     def testConfig(self):
-        ns3.Config.Set("ns3::OnOffApplication::PacketSize", ns3.UintegerValue(123))
         ns3.Config.SetDefault("ns3::OnOffApplication::PacketSize", ns3.UintegerValue(123))
         # hm.. no Config.Get?
 
@@ -118,5 +117,11 @@
 
         self.assert_(c1 is c2)
 
+    def testTypeId(self):
+        typeId1 = ns3.TypeId.LookupByNameFailSafe("ns3::UdpSocketFactory")
+        self.assertEqual(typeId1.GetName (), "ns3::UdpSocketFactory")
+        
+        self.assertRaises(KeyError, ns3.TypeId.LookupByNameFailSafe, "__InvalidTypeName__")
+
 if __name__ == '__main__':
     unittest.main()