Index: /code/branches/core7/src/libraries/core/CoreStaticInitializationHandler.cc
===================================================================
--- /code/branches/core7/src/libraries/core/CoreStaticInitializationHandler.cc	(revision 10538)
+++ /code/branches/core7/src/libraries/core/CoreStaticInitializationHandler.cc	(revision 10539)
@@ -29,6 +29,8 @@
 #include "CoreStaticInitializationHandler.h"
 
+#include "CoreIncludes.h"
 #include "module/ModuleInstance.h"
 #include "class/IdentifierManager.h"
+#include "object/Iterator.h"
 
 namespace orxonox
@@ -53,5 +55,5 @@
     void CoreStaticInitializationHandler::loadInstances(ModuleInstance* module)
     {
-        // the order of initialization is important
+        // the order of initialization is important: handlers > identifiers > singletons > everything else
         module->loadAllStaticallyInitializedInstances(StaticInitialization::STATIC_INITIALIZATION_HANDLER);
         module->loadAllStaticallyInitializedInstances(StaticInitialization::IDENTIFIER);
@@ -72,6 +74,53 @@
         module->unloadAllStaticallyInitializedInstances(StaticInitialization::COMMAND_LINE_ARGUMENT);
         module->unloadAllStaticallyInitializedInstances(StaticInitialization::SCOPED_SINGLETON_WRAPPER);
+
+        // until now every object (including singletons) of the unloaded identifiers should have been destroyed in a controlled manner.
+        // every remaining object is now destroyed in random order.
+        this->destroyObjects(module);
+
+        // all objects are gone now and we can unload identifiers
         module->unloadAllStaticallyInitializedInstances(StaticInitialization::IDENTIFIER);
         module->unloadAllStaticallyInitializedInstances(StaticInitialization::STATIC_INITIALIZATION_HANDLER);
     }
+
+    void CoreStaticInitializationHandler::destroyObjects(ModuleInstance* module)
+    {
+        // collect all identifiers that are about to be unloaded
+        std::set<Identifier*> identifiers;
+        const std::set<StaticallyInitializedInstance*>& instances = module->getInstances(StaticInitialization::IDENTIFIER);
+        for (std::set<StaticallyInitializedInstance*>::const_iterator it = instances.begin(); it != instances.end(); ++it)
+            identifiers.insert(&static_cast<StaticallyInitializedIdentifier*>(*it)->getIdentifier());
+
+        // destroy objects. some objects may survive this at first because they still have smart pointers pointing at them. this is
+        // ok as long as those smart pointers are held by objects that are also about to be destroyed in the same loop. this means
+        // that objects within one module may reference each other by smart pointers. but it is not allowed that objects from another
+        // module (which is not unloaded) uses smart pointers to point at objects inside the unloaded module. this will lead to a crash.
+        for (std::set<Identifier*>::iterator it = identifiers.begin(); it != identifiers.end(); ++it)
+            (*it)->destroyObjects();
+
+        // check if all objects were really destroyed. this is not the case if an object is referenced by a smart pointer from another
+        // module (or if two objects inside this module reference each other). this will lead to a crash and must be fixed (e.g. by
+        // changing object dependencies; or by changing the logic that allows modules to be unloaded).
+        for (std::set<Identifier*>::iterator it = identifiers.begin(); it != identifiers.end(); ++it)
+        {
+            ObjectListBase* objectList = Context::getRootContext()->getObjectList(*it);
+            if (objectList->size() > 0)
+            {
+                orxout(internal_error) << "There are still " << objectList->size() << " objects of type " << (*it)->getName()
+                    << " after unloading the Identifier. This may lead to a crash" << endl;
+            }
+        }
+
+        // destroy object-lists in all contexts
+        for (std::set<Identifier*>::iterator it_identifier = identifiers.begin(); it_identifier != identifiers.end(); ++it_identifier)
+        {
+            // only do this if the Identifier is not a Context itself; otherwise we delete the list we're iterating over
+            if (!(*it_identifier)->isExactlyA(Class(Context)))
+            {
+                // iterate over all contexts
+                for (ObjectList<Context>::iterator it_context = ObjectList<Context>::begin(); it_context != ObjectList<Context>::end(); ++it_context)
+                    it_context->destroyObjectList((*it_identifier));
+            }
+        }
+    }
 }
Index: /code/branches/core7/src/libraries/core/CoreStaticInitializationHandler.h
===================================================================
--- /code/branches/core7/src/libraries/core/CoreStaticInitializationHandler.h	(revision 10538)
+++ /code/branches/core7/src/libraries/core/CoreStaticInitializationHandler.h	(revision 10539)
@@ -56,4 +56,6 @@
             void initInstances(ModuleInstance* module);
 
+            void destroyObjects(ModuleInstance* module);
+
             bool bInitInstances_;
     };
Index: /code/branches/core7/src/libraries/core/class/Identifier.h
===================================================================
--- /code/branches/core7/src/libraries/core/class/Identifier.h	(revision 10538)
+++ /code/branches/core7/src/libraries/core/class/Identifier.h	(revision 10539)
@@ -152,4 +152,10 @@
             inline bool isInitialized() const { return this->bInitialized_; }
 
+            virtual void destroyObjects() = 0;
+
+            virtual bool canDynamicCastObjectToIdentifierClass(Identifiable* object) const = 0;
+
+            static bool initConfigValues_s; // TODO: this is a hack - remove it as soon as possible
+
 
             /////////////////////////////
@@ -215,8 +221,4 @@
             XMLPortObjectContainer* getXMLPortObjectContainer(const std::string& sectionname);
 
-            virtual bool canDynamicCastObjectToIdentifierClass(Identifiable* object) const = 0;
-
-            static bool initConfigValues_s; // TODO: this is a hack - remove it as soon as possible
-
         protected:
             virtual void createSuperFunctionCaller() const = 0;
@@ -297,4 +299,6 @@
                 { return dynamic_cast<T*>(object) != 0; }
 
+            virtual void destroyObjects();
+
             static ClassIdentifier<T>* getIdentifier();
 
@@ -307,4 +311,10 @@
             void addObjectToList(T* object, Listable*);
             void addObjectToList(T* object, Identifiable*);
+
+            void destroyObjects(Listable*);
+            void destroyObjects(void*);
+
+            void destroyObject(Destroyable* object);
+            void destroyObject(void* object);
 
             void updateConfigValues(bool updateChildren, Listable*) const;
@@ -389,4 +399,48 @@
     {
         // no action
+    }
+
+    /**
+     * @brief Destroy all objects of this class (must be Listable).
+     * Destroyables are destroyed with destroy(), all other classes with delete.
+     */
+    template <class T>
+    void ClassIdentifier<T>::destroyObjects()
+    {
+        this->destroyObjects((T*)0);
+    }
+
+    /**
+     * @brief Only searches and destroys objects if is a @ref Listable
+     */
+    template <class T>
+    void ClassIdentifier<T>::destroyObjects(Listable*)
+    {
+        ObjectListBase* objectList = Context::getRootContext()->getObjectList(this);
+        ObjectListElement<T>* begin = static_cast<ObjectListElement<T>*>(objectList->begin());
+        ObjectListElement<T>* end = static_cast<ObjectListElement<T>*>(objectList->end());
+        for (typename ObjectList<T>::iterator it = begin; it != end; )
+            this->destroyObject(*(it++));
+    }
+
+    template <class T>
+    void ClassIdentifier<T>::destroyObjects(void*)
+    {
+        // no action
+    }
+
+    /**
+     * @brief Call 'object->destroy()' for Destroyables and 'delete object' for all other types.
+     */
+    template <class T>
+    void ClassIdentifier<T>::destroyObject(Destroyable* object)
+    {
+        object->destroy();
+    }
+
+    template <class T>
+    void ClassIdentifier<T>::destroyObject(void* object)
+    {
+        delete static_cast<Identifiable*>(object);
     }
 
Index: /code/branches/core7/src/libraries/core/module/ModuleInstance.h
===================================================================
--- /code/branches/core7/src/libraries/core/module/ModuleInstance.h	(revision 10538)
+++ /code/branches/core7/src/libraries/core/module/ModuleInstance.h	(revision 10539)
@@ -52,4 +52,7 @@
             void unloadAllStaticallyInitializedInstances(StaticInitialization::Type type);
 
+            inline const std::set<StaticallyInitializedInstance*>& getInstances(StaticInitialization::Type type)
+                { return this->staticallyInitializedInstancesByType_[type]; }
+
             void deleteAllStaticallyInitializedInstances();
 
Index: /code/branches/core7/src/libraries/core/object/Context.cc
===================================================================
--- /code/branches/core7/src/libraries/core/object/Context.cc	(revision 10538)
+++ /code/branches/core7/src/libraries/core/object/Context.cc	(revision 10539)
@@ -97,3 +97,10 @@
         return this->objectLists_[classID];
     }
+
+    void Context::destroyObjectList(const Identifier* identifier)
+    {
+        ObjectListBase* objectList = this->getObjectList(identifier);
+        delete objectList;
+        this->objectLists_[identifier->getClassID()] = NULL;
+    }
 }
Index: /code/branches/core7/src/libraries/core/object/Context.h
===================================================================
--- /code/branches/core7/src/libraries/core/object/Context.h	(revision 10538)
+++ /code/branches/core7/src/libraries/core/object/Context.h	(revision 10539)
@@ -71,4 +71,6 @@
             }
 
+            void destroyObjectList(const Identifier* identifier);
+
         private:
             Context* parentContext_;
