Index: /code/branches/core5/src/libraries/core/OrxonoxClass.cc
===================================================================
--- /code/branches/core5/src/libraries/core/OrxonoxClass.cc	(revision 5822)
+++ /code/branches/core5/src/libraries/core/OrxonoxClass.cc	(revision 5823)
@@ -36,4 +36,5 @@
 #include "MetaObjectList.h"
 #include "Identifier.h"
+#include "WeakPtr.h"
 
 namespace orxonox
@@ -62,4 +63,8 @@
         if (this->parents_)
             delete this->parents_;
+            
+        // reset all weak pointers pointing to this object
+        for (std::set<WeakPtr<OrxonoxClass>*>::iterator it = this->weakPointers_.begin(); it != this->weakPointers_.end(); )
+            (*(it++))->reset();
     }
 
Index: /code/branches/core5/src/libraries/core/OrxonoxClass.h
===================================================================
--- /code/branches/core5/src/libraries/core/OrxonoxClass.h	(revision 5822)
+++ /code/branches/core5/src/libraries/core/OrxonoxClass.h	(revision 5823)
@@ -57,4 +57,7 @@
         template <class T>
         friend class SmartPtr;
+
+        template <class T>
+        friend class WeakPtr;
 
         public:
@@ -131,4 +134,13 @@
             inline void decrementReferenceCount()
                 { --this->referenceCount_; if (this->referenceCount_ == 0 && this->requestedDestruction_) { delete this; } }
+                
+            /** @brief Register a weak pointer which points to this object. */
+            template <class T>
+            inline void registerWeakPtr(WeakPtr<T>* pointer)
+                { this->weakPointers_.insert(reinterpret_cast<WeakPtr<OrxonoxClass>*>(pointer)); }
+            /** @brief Unegister a weak pointer which pointed to this object before. */
+            template <class T>
+            inline void unregisterWeakPtr(WeakPtr<T>* pointer)
+                { this->weakPointers_.erase(reinterpret_cast<WeakPtr<OrxonoxClass>*>(pointer)); }
 
             Identifier* identifier_;                   //!< The Identifier of the object
@@ -137,4 +149,5 @@
             int referenceCount_;                       //!< Counts the references from smart pointers to this object
             bool requestedDestruction_;                //!< Becomes true after someone called delete on this object
+            std::set<WeakPtr<OrxonoxClass>*> weakPointers_; //!< All weak pointers which point to this object (and like to get notified if it dies)
 
             //! 'Fast map' that holds this-pointers of all derived types
Index: /code/branches/core5/src/libraries/core/SmartPtr.h
===================================================================
--- /code/branches/core5/src/libraries/core/SmartPtr.h	(revision 5822)
+++ /code/branches/core5/src/libraries/core/SmartPtr.h	(revision 5823)
@@ -35,6 +35,7 @@
 
 #include <cassert>
-#include <ostream>
+
 #include "OrxonoxClass.h"
+#include "WeakPtr.h"
 
 namespace orxonox
@@ -71,4 +72,11 @@
             }
 
+            template <class O>
+            inline SmartPtr(const WeakPtr<O>& other) : pointer_(other.get()), base_(other.getBase())
+            {
+                if (this->base_)
+                    this->base_->incrementReferenceCount();
+            }
+
             inline ~SmartPtr()
             {
@@ -102,7 +110,19 @@
             }
 
+            template <class O>
+            inline const SmartPtr& operator=(const WeakPtr<O>& other)
+            {
+                SmartPtr(other).swap(*this);
+                return *this;
+            }
+
             inline T* get() const
             {
                 return this->pointer_;
+            }
+
+            inline OrxonoxClass* getBase() const
+            {
+                return this->base_;
             }
 
@@ -153,22 +173,4 @@
     };
 
-    template <class A, class B>
-    inline bool operator==(const SmartPtr<A>& a, const SmartPtr<B>& b)
-    {
-        return (a.get() == b.get());
-    }
-
-    template <class A, class B>
-    inline bool operator!=(const SmartPtr<A>& a, const SmartPtr<B>& b)
-    {
-        return (a.get() != b.get());
-    }
-
-    template <class T>
-    inline bool operator<(const SmartPtr<T>& a, const SmartPtr<T>& b)
-    {
-        return std::less<T*>()(a.get(), b.get());
-    }
-
     template <class T>
     void swap(SmartPtr<T>& a, SmartPtr<T>& b)
@@ -194,11 +196,4 @@
         return dynamic_cast<T*>(p.get());
     }
-
-    template <class T>
-    std::ostream& operator<<(std::ostream& os, const SmartPtr<T>& p)
-    {
-        os << p.get();
-        return os;
-    }
 }
 
Index: /code/branches/core5/src/libraries/core/WeakPtr.h
===================================================================
--- /code/branches/core5/src/libraries/core/WeakPtr.h	(revision 5823)
+++ /code/branches/core5/src/libraries/core/WeakPtr.h	(revision 5823)
@@ -0,0 +1,184 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+// Inspired by boost::intrusive_ptr by Peter Dimov
+
+#ifndef _WeakPtr_H__
+#define _WeakPtr_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    template <class T>
+    class WeakPtr
+    {
+        public:
+            inline WeakPtr() : pointer_(0), base_(0)
+            {
+            }
+
+            inline WeakPtr(int) : pointer_(0), base_(0)
+            {
+            }
+
+            inline WeakPtr(T* pointer) : pointer_(pointer), base_(pointer)
+            {
+                if (this->base_)
+                    this->base_->registerWeakPtr(this);
+            }
+
+            inline WeakPtr(const WeakPtr& other) : pointer_(other.pointer_), base_(other.base_)
+            {
+                if (this->base_)
+                    this->base_->registerWeakPtr(this);
+            }
+
+            template <class O>
+            inline WeakPtr(const WeakPtr<O>& other) : pointer_(other.get()), base_(other.base_)
+            {
+                if (this->base_)
+                    this->base_->registerWeakPtr(this);
+            }
+
+            inline ~WeakPtr()
+            {
+                if (this->base_)
+                    this->base_->unregisterWeakPtr(this);
+            }
+            
+            inline const WeakPtr& operator=(int)
+            {
+                WeakPtr(0).swap(*this);
+                return *this;
+            }
+
+            inline const WeakPtr& operator=(T* pointer)
+            {
+                WeakPtr(pointer).swap(*this);
+                return *this;
+            }
+
+            inline const WeakPtr& operator=(const WeakPtr& other)
+            {
+                WeakPtr(other).swap(*this);
+                return *this;
+            }
+
+            template <class O>
+            inline const WeakPtr& operator=(const WeakPtr<O>& other)
+            {
+                WeakPtr(other).swap(*this);
+                return *this;
+            }
+
+            inline T* get() const
+            {
+                return this->pointer_;
+            }
+
+            inline OrxonoxClass* getBase() const
+            {
+                return this->base_;
+            }
+
+            inline operator T*() const
+            {
+                return this->pointer_;
+            }
+
+            inline T* operator->() const
+            {
+                assert(this->pointer_ != 0);
+                return this->pointer_;
+            }
+
+            inline T& operator*() const
+            {
+                assert(this->pointer_ != 0);
+                return *this->pointer_;
+            }
+
+            inline bool operator!() const
+            {
+                return (this->pointer_ == 0);
+            }
+
+            inline void swap(WeakPtr& other)
+            {
+                {
+                    T* temp = this->pointer_;
+                    this->pointer_ = other.pointer_;
+                    other.pointer_ = temp;
+                }
+                {
+                    OrxonoxClass* temp = this->base_;
+                    this->base_ = other.base_;
+                    other.base_ = temp;
+                }
+            }
+
+            inline void reset()
+            {
+                WeakPtr().swap(*this);
+            }
+
+        private:
+            T* pointer_;
+            OrxonoxClass* base_;
+    };
+
+    template <class T>
+    void swap(WeakPtr<T>& a, WeakPtr<T>& b)
+    {
+        a.swap(b);
+    }
+
+    template <class T, class U>
+    WeakPtr<T> static_pointer_cast(const WeakPtr<U>& p)
+    {
+        return static_cast<T*>(p.get());
+    }
+
+    template <class T, class U>
+    WeakPtr<T> const_pointer_cast(const WeakPtr<U>& p)
+    {
+        return const_cast<T*>(p.get());
+    }
+
+    template <class T, class U>
+    WeakPtr<T> dynamic_pointer_cast(const WeakPtr<U>& p)
+    {
+        return dynamic_cast<T*>(p.get());
+    }
+}
+
+#endif /* _WeakPtr_H__ */
