Index: code/branches/presentation3/src/modules/pickup/CMakeLists.txt
===================================================================
--- code/branches/presentation3/src/modules/pickup/CMakeLists.txt	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/CMakeLists.txt	(revision 7162)
@@ -1,3 +1,4 @@
 SET_SOURCE_FILES(PICKUP_SRC_FILES
+  CollectiblePickup.cc
   DroppedPickup.cc
   Pickup.cc
Index: code/branches/presentation3/src/modules/pickup/CollectiblePickup.cc
===================================================================
--- code/branches/presentation3/src/modules/pickup/CollectiblePickup.cc	(revision 7162)
+++ code/branches/presentation3/src/modules/pickup/CollectiblePickup.cc	(revision 7162)
@@ -0,0 +1,164 @@
+/*
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file CollectiblePickup.cc
+    @brief Implementation of the CollectiblePickup class.
+*/
+
+#include "CollectiblePickup.h"
+
+#include "core/CoreIncludes.h"
+#include "PickupCollection.h"
+
+namespace orxonox {
+
+    /**
+    @brief
+        Constructor.
+        Registers the object and initializes variables.
+    */
+    CollectiblePickup::CollectiblePickup() : isInCollection_(false)
+    {
+        RegisterObject(CollectiblePickup);
+
+        this->collection_ = NULL;
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    CollectiblePickup::~CollectiblePickup()
+    {
+
+    }
+
+    /**
+    @brief
+        Is called by OrxonoxClass::destroy() before the object is actually destroyed.
+    */
+    void CollectiblePickup::preDestroy(void)
+    {
+        this->Pickupable::preDestroy();
+
+        // The PickupCollection has to be destroyed as well.
+        if(this->isInCollection())
+            this->collection_->Pickupable::destroy();
+    }
+
+    /**
+    @brief
+        Destroys a Pickupable.
+    */
+    void CollectiblePickup::destroyPickup(void)
+    {
+        if(!this->isInCollection()) // If the CollectiblePickup is not in a PickupCollection the destroyPickup method of Pickupable is called.
+            this->Pickupable::destroyPickup();
+        else // Else the ColectiblePickup is dropped and disabled,
+        {
+            this->drop(false);
+            if(this->isInCollection() && this->isEnabled()) // It is only disabled if it is enabled and still ina PickupCollection after having been dropped.
+            {
+                this->setDisabled();
+                this->collection_->pickupDisabled();
+            }
+        }
+    }
+
+    /**
+    @brief
+        Is called by the PickupCarrier when it is being destroyed.
+    */
+    void CollectiblePickup::carrierDestroyed(void)
+    {
+        if(!this->isInCollection())
+            this->Pickupable::destroy();
+        else // If the CollectiblePickup is part of a PickupCollection it is just dropped instead of destroyed.
+            this->drop(false);
+    }
+
+    /**
+    @brief
+        Is called when the pickup has transited from used to unused or the other way around.
+    */
+    void CollectiblePickup::changedUsed(void)
+    {
+        SUPER(CollectiblePickup, changedUsed);
+
+        if(this->isInCollection())
+            this->collection_->pickupChangedUsed(this->isUsed());
+    }
+
+    /**
+    @brief
+        Is called when the pickup has transited from picked up to dropped or the other way around.
+    */
+    void CollectiblePickup::changedPickedUp(void)
+    {
+        SUPER(CollectiblePickup, changedPickedUp);
+
+        if(this->isInCollection())
+            this->collection_->pickupChangedPickedUp(this->isPickedUp());
+    }
+
+    /**
+    @brief
+        Adds this CollectiblePickup to the input PickupCollection.
+    @param collection
+        A pointer to the PickupCollection to which the CollectiblePickup should be added.
+    @return
+        Returns true if the CollectiblePickup was successfully added to the PickupCollection.
+    */
+    bool CollectiblePickup::addToCollection(PickupCollection* collection)
+    {
+        if(this->isInCollection() || collection == NULL) //If the CollectiblePickup already is in a PickupCollection or if the input pointer is NULL.
+            return false;
+
+        this->isInCollection_ = true;
+        this->collection_ = collection;
+        return true;
+    }
+
+    /**
+    @brief
+        Removes this CollectiblePickup from its PickupCollection.
+    @return
+        Returns true if the CollectiblePickup was succcessfully removed.
+    */
+    bool CollectiblePickup::removeFromCollection(void)
+    {
+        if(!this->isInCollection()) //If the CollectiblePickup is not in a PickupCollection.
+            return false;
+
+        this->isInCollection_ = false;
+        this->collection_ = NULL;
+        return true;
+    }
+
+}
Index: code/branches/presentation3/src/modules/pickup/CollectiblePickup.h
===================================================================
--- code/branches/presentation3/src/modules/pickup/CollectiblePickup.h	(revision 7162)
+++ code/branches/presentation3/src/modules/pickup/CollectiblePickup.h	(revision 7162)
@@ -0,0 +1,82 @@
+/*
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file CollectiblePickup.h
+    @brief Definition of the CollectiblePickup class.
+*/
+
+#ifndef _CollectiblePickup_H__
+#define _CollectiblePickup_H__
+
+#include "pickup/PickupPrereqs.h"
+
+#include "interfaces/Pickupable.h"
+
+namespace orxonox {
+
+    /**
+    @brief
+        Collectible Pickup class. Any pickup inheriting from this class can be added to a PickupCollection and thus be part uf such.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _PickupExport CollectiblePickup : public Pickupable
+    {
+
+        public:
+            CollectiblePickup(); //!< Constructor.
+            virtual ~CollectiblePickup(); //! Destructor.
+
+            virtual void changedUsed(void); //!< Is called when the pickup has transited from used to unused or the other way around.
+            virtual void changedPickedUp(void); //!< Is called when the pickup has transited from picked up to dropped or the other way around.
+
+            /**
+            @brief Check whether the given CollectiblePickup is par of a PickupCollection.
+            @return Returns true if the ColelctiblePickup is part of a PickupCollection.
+            */
+            bool isInCollection(void)
+                { return this->isInCollection_; }
+            
+            bool addToCollection(PickupCollection* collection); //!< Adds this CollectiblePickup to the input PickupCollection.
+            bool removeFromCollection(void); //!< Removes this CollectiblePickup from its PickupCollection.
+
+            void carrierDestroyed(void); //!< Is called by the PickupCarrier when it is being destroyed.
+
+        protected:
+            virtual void preDestroy(void); //!< Is called by OrxonoxClass::destroy() before the object is actually destroyed.
+            virtual void destroyPickup(void); //!< //!< Destroys a Pickupable.
+
+        private:
+            bool isInCollection_; //!< True if the CollectiblePickup is in a PickupCollection.
+            PickupCollection* collection_; //!< A pointer to the PickupCollection this CollectiblePickup is in.
+
+    };
+}
+
+#endif // _CollectiblePickup_H__
Index: code/branches/presentation3/src/modules/pickup/Pickup.cc
===================================================================
--- code/branches/presentation3/src/modules/pickup/Pickup.cc	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/Pickup.cc	(revision 7162)
@@ -194,5 +194,5 @@
 
         //! Sets the Pickup to used if the Pickup has activation type 'immediate' and gets picked up.
-        if(this->getCarrier() != NULL && this->isPickedUp() && this->isImmediate())
+        if(this->isPickedUp() && this->isImmediate())
         {
             this->setUsed(true);
Index: code/branches/presentation3/src/modules/pickup/Pickup.h
===================================================================
--- code/branches/presentation3/src/modules/pickup/Pickup.h	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/Pickup.h	(revision 7162)
@@ -40,5 +40,5 @@
 #include "core/XMLPort.h"
 
-#include "interfaces/Pickupable.h"
+#include "CollectiblePickup.h"
 
 #include "tools/Timer.h"
@@ -74,5 +74,5 @@
         Damian 'Mozork' Frick
     */
-    class _PickupExport Pickup : public Pickupable, public BaseObject
+    class _PickupExport Pickup : public CollectiblePickup, public BaseObject
     {
 
Index: code/branches/presentation3/src/modules/pickup/PickupCollection.cc
===================================================================
--- code/branches/presentation3/src/modules/pickup/PickupCollection.cc	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/PickupCollection.cc	(revision 7162)
@@ -35,4 +35,5 @@
 #include "core/XMLPort.h"
 #include "interfaces/PickupCarrier.h"
+#include "CollectiblePickup.h"
 #include "DroppedPickup.h"
 #include "PickupCollectionIdentifier.h"
@@ -54,4 +55,9 @@
 
         this->pickupCollectionIdentifier_ = new PickupCollectionIdentifier(this);
+        this->usedCounter_ = 0;
+        this->pickedUpCounter_ = 0;
+        this->disabledCounter_ = 0;
+        this->processingUsed_ = false;
+        this->processingPickedUp_ = false;
     }
 
@@ -62,10 +68,11 @@
     PickupCollection::~PickupCollection()
     {
-        //! Destroy all Pickupables constructing this PickupCollection.
-        for(std::vector<WeakPtr<Pickupable> >::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
-        {
-            if((*it).get() != NULL)
-                (*it).get()->destroy();
-        }
+        // Destroy all Pickupables constructing this PickupCollection.
+        for(std::vector<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
+        {
+            (*it)->removeFromCollection();
+            (*it)->destroy();
+        }
+        this->pickups_.clear();
     }
 
@@ -78,5 +85,5 @@
         SUPER(PickupCollection, XMLPort, xmlelement, mode);
 
-        XMLPortObject(PickupCollection, Pickupable, "pickupables", addPickupable, getPickupable, xmlelement, mode);
+        XMLPortObject(PickupCollection, CollectiblePickup, "pickupables", addPickupable, getPickupable, xmlelement, mode);
 
         this->initializeIdentifier();
@@ -89,7 +96,7 @@
     void PickupCollection::initializeIdentifier(void)
     {
-        for(std::vector<WeakPtr<Pickupable> >::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
-        {
-            this->pickupCollectionIdentifier_->addPickup((*it).get()->getPickupIdentifier());
+        for(std::vector<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
+        {
+            this->pickupCollectionIdentifier_->addPickup((*it)->getPickupIdentifier());
         }
     }
@@ -104,9 +111,32 @@
         SUPER(PickupCollection, changedUsed);
 
-        //! Change used for all Pickupables this PickupCollection consists of.
-        for(std::vector<WeakPtr<Pickupable> >::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
-        {
-            (*it).get()->setUsed(this->isUsed());
-        }
+        this->processingUsed_ = true;
+        // Change used for all Pickupables this PickupCollection consists of.
+        for(std::vector<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
+        {
+            (*it)->setUsed(this->isUsed());
+        }
+        this->processingUsed_ = false;
+
+        this->changedUsedAction();
+    }
+
+    /**
+    @brief
+        Helper method.
+        Checks whether due to changes in the used status of the pickups of this PickupCollection the used status of this PickupCollection has to change as well.
+    */
+    void PickupCollection::changedUsedAction(void)
+    {
+        if(this->processingUsed_)
+            return;
+
+        // If all the pickups are not in use but the PickupCollection is.
+        if(this->usedCounter_ == 0 && this->isUsed())
+            this->setUsed(false);
+
+        // If all the enabled pickups are in use but the PickupCollection is not.
+        if(this->usedCounter_ != 0 && this->usedCounter_ == this->pickups_.size()-this->disabledCounter_ && !this->isUsed())
+            this->setUsed(true);
     }
 
@@ -120,8 +150,11 @@
         SUPER(PickupCollection, changedCarrier);
 
-        //! Change the PickupCarrier for all Pickupables this PickupCollection consists of.
-        for(std::vector<WeakPtr<Pickupable> >::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
-        {
-            (*it).get()->setCarrier(this->getCarrier()->getTarget(*it), true);
+        // Change the PickupCarrier for all Pickupables this PickupCollection consists of.
+        for(std::vector<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
+        {
+            if(this->getCarrier() == NULL)
+                (*it)->setCarrier(NULL);
+            else
+                (*it)->setCarrier(this->getCarrier()->getTarget(*it));
         }
     }
@@ -136,9 +169,32 @@
         SUPER(PickupCollection, changedPickedUp);
 
-        //! Change the pickedUp status for all Pickupables this PickupCollection consists of.
-        for(std::vector<WeakPtr<Pickupable> >::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
-        {
-            (*it).get()->setPickedUp(this->isPickedUp());
-        }
+        this->processingPickedUp_ = true;
+        // Change the pickedUp status for all Pickupables this PickupCollection consists of.
+        for(std::vector<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
+        {
+            (*it)->setPickedUp(this->isPickedUp());
+        }
+        this->processingPickedUp_ = false;
+
+        this->changedPickedUpAction();
+    }
+
+    /**
+    @brief
+        Helper method.
+        Checks whether due to changes in the picked up status of the pickups of this PickupCollection the picked up status of this PickupCollection has to change as well.
+    */
+    void PickupCollection::changedPickedUpAction(void)
+    {
+        if(this->processingPickedUp_)
+            return;
+
+        // If at least all the enabled pickups of this PickupCollection are no longer picked up. 
+        if(this->pickedUpCounter_ <= this->disabledCounter_ && this->isPickedUp())
+            this->Pickupable::destroy();
+
+        // If the PickupCollection is no longer picked up.
+        if(!this->isPickedUp())
+            this->pickedUpCounter_ = 0;
     }
 
@@ -158,9 +214,10 @@
 
         PickupCollection* pickup = dynamic_cast<PickupCollection*>(item);
-        //! Clone all Pickupables this PickupCollection consist of.
-        for(std::vector<WeakPtr<Pickupable> >::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
-        {
-            Pickupable* newPickup = (*it).get()->clone();
-            pickup->addPickupable(newPickup);
+        // Clone all Pickupables this PickupCollection consist of.
+        for(std::vector<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
+        {
+            Pickupable* newPickup = (*it)->clone();
+            CollectiblePickup* collectible = static_cast<CollectiblePickup*>(newPickup);
+            pickup->addPickupable(collectible);
         }
 
@@ -178,7 +235,7 @@
     bool PickupCollection::isTarget(PickupCarrier* carrier) const
     {
-        for(std::vector<WeakPtr<Pickupable> >::const_iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
-        {
-            if(!carrier->isTarget((*it).get()))
+        for(std::vector<CollectiblePickup*>::const_iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
+        {
+            if(!carrier->isTarget(*it))
                 return false;
         }
@@ -207,11 +264,11 @@
         Returns true if successful,
     */
-    bool PickupCollection::addPickupable(Pickupable* pickup)
+    bool PickupCollection::addPickupable(CollectiblePickup* pickup)
     {
         if(pickup == NULL)
             return false;
 
-        WeakPtr<Pickupable> ptr = pickup; //!< Create a weak pointer to be able to test in the constructor if the Pointer is still valid.
-        this->pickups_.push_back(ptr);
+        pickup->addToCollection(this);
+        this->pickups_.push_back(pickup);
         return true;
     }
@@ -227,5 +284,49 @@
     const Pickupable* PickupCollection::getPickupable(unsigned int index)
     {
-        return this->pickups_[index].get();
+        return this->pickups_[index];
+    }
+
+    /**
+    @brief
+        Informs the PickupCollection, that one of its pickups has changed its used status to the input value.
+        This is used internally by the CollectiblePickup class.
+    @param changed
+        The value the used status has changed to. 
+    */
+    void PickupCollection::pickupChangedUsed(bool changed)
+    {
+        if(changed)
+            this->usedCounter_++;
+        else
+            this->usedCounter_--;
+
+        this->changedUsedAction();
+    }
+
+    /**
+    @brief
+        Informs the PickupCollection, that one of its pickups has changed its picked up status to the input value.
+        This is used internally by the CollectiblePickup class.
+    @param changed
+        The value the picked up status has changed to.
+    */
+    void PickupCollection::pickupChangedPickedUp(bool changed)
+    {
+        if(changed)
+            this->pickedUpCounter_++;
+        else
+            this->pickedUpCounter_--;
+
+        this->changedPickedUpAction();
+    }
+
+    /**
+    @brief
+        Informs the PickupCollection, that one of its pickups has been disabled.
+        This is used internally by the CollectiblePickup class.
+    */
+    void PickupCollection::pickupDisabled(void)
+    {
+        this->disabledCounter_++;
     }
 
Index: code/branches/presentation3/src/modules/pickup/PickupCollection.h
===================================================================
--- code/branches/presentation3/src/modules/pickup/PickupCollection.h	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/PickupCollection.h	(revision 7162)
@@ -37,6 +37,6 @@
 #include "PickupPrereqs.h"
 
-#include "interfaces/Pickupable.h"
 #include "core/BaseObject.h"
+#include "CollectiblePickup.h"
 
 #include <list>
@@ -47,13 +47,12 @@
     /**
     @brief
-        The PickupCollection combines different Pickupables to a coherent, single pickup and makes the seem (from the outside looking in) just as if they were just one Pickupable.
+        The PickupCollection combines different Pickupables to a coherent, single pickup and makes them seem (from the outside looking in) just as if they were just one Pickupable.
     @author
         Damian 'Mozork' Frick
     */
-    class _PickupExport PickupCollection : public Pickupable, public BaseObject
+    class _PickupExport PickupCollection : public CollectiblePickup, public BaseObject
     {
 
         public:
-
             PickupCollection(BaseObject* creator); //!< Default Constructor.
             virtual ~PickupCollection(); //!< Destructor.
@@ -71,6 +70,10 @@
             virtual const PickupIdentifier* getPickupIdentifier(void); //!< Get the PickupIdentifier of this PickupCollection.
 
-            bool addPickupable(Pickupable* pickup); //!< Add the input Pickupable to list of Pickupables combined by this PickupCollection.
+            bool addPickupable(CollectiblePickup* pickup); //!< Add the input Pickupable to list of Pickupables combined by this PickupCollection.
             const Pickupable* getPickupable(unsigned int index); //!< Get the Pickupable at the given index.
+
+            void pickupChangedUsed(bool changed); //!< Informs the PickupCollection, that one of its pickups has changed its used status to the input value.
+            void pickupChangedPickedUp(bool changed); //!< Informs the PickupCollection, that one of its pickups has changed its picked up status to the input value.
+            void pickupDisabled(void); //!< Informs the PickupCollection, that one of its pickups has been disabled.
 
         protected:
@@ -82,6 +85,15 @@
 
         private:
+            void changedUsedAction(void); //!< Helper method.
+            void changedPickedUpAction(void); //!< Helper method.
+            
+            std::vector<CollectiblePickup*> pickups_; //!< The list of the pointers of all the Pickupables this PickupCollection consists of. They are weak pointers to facilitate testing, whether the pointers are still valid.
 
-            std::vector<WeakPtr<Pickupable> > pickups_; //!< The list of the pointers of all the Pickupables this PickupCollection consists of. They are weak pointers to facilitate testing, whether the pointers are still valid.
+            unsigned int usedCounter_; //!< Keeps track of the number of pickups of this PickupCollection, that are in use.
+            unsigned int pickedUpCounter_; //!< Keeps track of the number of pickups of this PickupCollection, that are picked up.
+            unsigned int disabledCounter_; //!< Keeps track of the number of pickups of this PickupCollection, that are disabled.
+
+            bool processingUsed_; //!< Boolean to ensure, that the PickupCollection doesn't update its used status while its internal state is inconsistent.
+            bool processingPickedUp_; //!< Boolean to ensure, that the PickupCollection doesn't update its picked upp status while its internal state is inconsistent.
 
     };
Index: code/branches/presentation3/src/modules/pickup/PickupCollectionIdentifier.cc
===================================================================
--- code/branches/presentation3/src/modules/pickup/PickupCollectionIdentifier.cc	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/PickupCollectionIdentifier.cc	(revision 7162)
@@ -67,9 +67,9 @@
     int PickupCollectionIdentifier::compare(const PickupIdentifier* identifier) const
     {
-        //! Slight un-niceity to cast the PickupIdentifier to a PickupCollectionIdentifier.
+        // Slight un-niceity to cast the PickupIdentifier to a PickupCollectionIdentifier.
         PickupIdentifier* temp = const_cast<PickupIdentifier*>(identifier);
         const PickupCollectionIdentifier* collectionIdentifier = dynamic_cast<PickupCollectionIdentifier*>(temp);
 
-        //! If the input PickupIdentifier 'identifier' is no PickupCollectionIdentifier then just the two PickupIdentifiers are compared.
+        // If the input PickupIdentifier 'identifier' is no PickupCollectionIdentifier then just the two PickupIdentifiers are compared.
         if(collectionIdentifier == NULL)
         {
@@ -77,9 +77,9 @@
         }
 
-        //! If the number of Pickupables each of the two PickupCollectionIdentifiers contain differ, the one with less is considered smaller.
+        // If the number of Pickupables each of the two PickupCollectionIdentifiers contain differ, the one with less is considered smaller.
         if(this->identifiers_.size() != collectionIdentifier->identifiers_.size())
             return this->identifiers_.size()-collectionIdentifier->identifiers_.size();
 
-        //! Compare the Pickupables of the two PickupCollectionIdentifiers one after the other. the one with the first 'smaller' one is considered smaller.
+        // Compare the Pickupables of the two PickupCollectionIdentifiers one after the other. the one with the first 'smaller' one is considered smaller.
         std::set<const PickupIdentifier*, PickupIdentifierCompare>::const_iterator it2 = collectionIdentifier->identifiers_.begin();
         for(std::set<const PickupIdentifier*, PickupIdentifierCompare>::const_iterator it = this->identifiers_.begin(); it != this->identifiers_.end(); it++)
Index: code/branches/presentation3/src/modules/pickup/PickupManager.cc
===================================================================
--- code/branches/presentation3/src/modules/pickup/PickupManager.cc	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/PickupManager.cc	(revision 7162)
@@ -43,4 +43,5 @@
 #include "infos/PlayerInfo.h"
 #include "worldentities/pawns/Pawn.h"
+#include "CollectiblePickup.h"
 #include "PickupRepresentation.h"
 
@@ -64,4 +65,5 @@
         RegisterRootObject(PickupManager);
 
+        //TODO: This doesn't work, yet.
         if( GameMode::showsGraphics() )
         {
@@ -172,5 +174,7 @@
             for(std::set<Pickupable*>::iterator pickup = pickups.begin(); pickup != pickups.end(); pickup++)
             {
-                this->pickupsList_.insert(std::pair<Pickupable*, WeakPtr<Pickupable> >(*pickup, WeakPtr<Pickupable>(*pickup)));
+                CollectiblePickup* collectible = orxonox_cast<CollectiblePickup*>(*pickup);
+                if(collectible == NULL || !collectible->isInCollection())
+                    this->pickupsList_.insert(std::pair<Pickupable*, WeakPtr<Pickupable> >(*pickup, WeakPtr<Pickupable>(*pickup)));
             }
         }
Index: code/branches/presentation3/src/modules/pickup/PickupPrereqs.h
===================================================================
--- code/branches/presentation3/src/modules/pickup/PickupPrereqs.h	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/PickupPrereqs.h	(revision 7162)
@@ -66,4 +66,5 @@
 {
 
+    class CollectiblePickup;
     class DroppedPickup;
     class Pickup;
Index: code/branches/presentation3/src/modules/pickup/PickupRepresentation.h
===================================================================
--- code/branches/presentation3/src/modules/pickup/PickupRepresentation.h	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/PickupRepresentation.h	(revision 7162)
@@ -149,5 +149,5 @@
             std::string spawnerTemplate_; //!<  The name of the template of this PickupRepresentation.
             StaticEntity* spawnerRepresentation_; //!< The spawnerRepresentation of this PickupRepresentation.
-            std::string inventoryRepresentation_; //!< The name of an image representing the pickup in the PickupInventory. TODO: Exact format and placement of image?
+            std::string inventoryRepresentation_; //!< The name of an image representing the pickup in the PickupInventory.
 
             Pickupable* pickup_; //!< The Pickupable that is represented by this PickupRepresentation.
Index: code/branches/presentation3/src/modules/pickup/PickupSpawner.cc
===================================================================
--- code/branches/presentation3/src/modules/pickup/PickupSpawner.cc	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/PickupSpawner.cc	(revision 7162)
@@ -107,4 +107,5 @@
         this->maxSpawnedItems_ = INF;
         this->spawnsRemaining_ = INF;
+        this->selfDestruct_ = false;
     }
 
@@ -115,5 +116,5 @@
     PickupSpawner::~PickupSpawner()
     {
-        if(this->pickup_ != NULL)
+        if(this->selfDestruct_ && this->pickup_ != NULL)
             this->pickup_->destroy();
     }
@@ -176,5 +177,5 @@
         if (this->isActive())
         {
-            SmartPtr<PickupSpawner> temp = this; // create a smart pointer to keep the PickupSpawner alive until we iterated through all Pawns (in case a Pawn takes the last pickup)
+            SmartPtr<PickupSpawner> temp = this; //Create a smart pointer to keep the PickupSpawner alive until we iterated through all Pawns (in case a Pawn takes the last pickup)
 
             //! Iterate trough all Pawns.
@@ -305,9 +306,8 @@
             {
                 if(pickup->pickup(target))
-                {
                     this->decrementSpawnsRemaining();
-                }
                 else
                 {
+                    this->selfDestruct_ = true;
                     pickup->destroy();
                 }
@@ -319,9 +319,8 @@
 
                 if(pickup == NULL)
-                {
                     COUT(1) << "PickupSpawner (&" << this << "): getPickup produced an error, no Pickupable created." << std::endl;
-                }
                 else
                 {
+                    this->selfDestruct_ = true;
                     pickup->destroy();
                 }
Index: code/branches/presentation3/src/modules/pickup/PickupSpawner.h
===================================================================
--- code/branches/presentation3/src/modules/pickup/PickupSpawner.h	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/PickupSpawner.h	(revision 7162)
@@ -125,4 +125,6 @@
             Timer respawnTimer_; //!< Timer used for re-activating.
 
+            bool selfDestruct_; //!< True if the PickupSpawner is selfdestructing.
+
             static const int INF = -1; //!< Constant for infinity.
     };
Index: code/branches/presentation3/src/modules/pickup/items/DronePickup.cc
===================================================================
--- code/branches/presentation3/src/modules/pickup/items/DronePickup.cc	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/items/DronePickup.cc	(revision 7162)
@@ -131,5 +131,5 @@
                 Pawn* pawn = this->carrierToPawnHelper();
                 if(pawn == NULL) //!< If the PickupCarrier is no Pawn, then this pickup is useless and therefore is destroyed.
-                    this->destroy();
+                    this->Pickupable::destroy();
 
                 //Attach to pawn
@@ -155,5 +155,5 @@
             if(this->isOnce() || (this->isContinuous() ))
             {
-                this->destroy();
+                this->Pickupable::destroy();
             }
         }
Index: code/branches/presentation3/src/modules/pickup/items/HealthPickup.cc
===================================================================
--- code/branches/presentation3/src/modules/pickup/items/HealthPickup.cc	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/items/HealthPickup.cc	(revision 7162)
@@ -143,5 +143,5 @@
             Pawn* pawn = this->carrierToPawnHelper();
             if(pawn == NULL) //!< If the PickupCarrier is no Pawn, then this pickup is useless and therefore is destroyed.
-                this->destroy();
+                this->Pickupable::destroy();
 
             //! Calculate the health that is added this tick.
@@ -191,5 +191,5 @@
 
         //! If the pickup is not picked up nothing must be done.
-        if(!this->isPickedUp())
+        if(!this->isPickedUp()) //TODO: Needed?
             return;
 
@@ -201,5 +201,5 @@
                 Pawn* pawn = this->carrierToPawnHelper();
                 if(pawn == NULL) //!< If the PickupCarrier is no Pawn, then this pickup is useless and therefore is destroyed.
-                    this->destroy();
+                    this->Pickupable::destroy();
 
                 float health = 0;
@@ -241,5 +241,5 @@
                 {
                     COUT(1) << "Something went horribly wrong in Health Pickup. PickupCarrier is no Pawn." << std::endl;
-                    this->destroy();
+                    this->Pickupable::destroy();
                     return;
                 }
@@ -256,5 +256,5 @@
             if(this->isOnce() || (this->isContinuous() && this->getHealth() == 0))
             {
-                this->destroy();
+                this->Pickupable::destroy();
             }
         }
Index: code/branches/presentation3/src/modules/pickup/items/InvisiblePickup.cc
===================================================================
--- code/branches/presentation3/src/modules/pickup/items/InvisiblePickup.cc	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/items/InvisiblePickup.cc	(revision 7162)
@@ -133,5 +133,5 @@
             if(!this->getTimer()->isActive() && this->getTimer()->getRemainingTime() == this->getDuration())
             {
-                this->destroy();
+                this->Pickupable::destroy();
             }
             else
Index: code/branches/presentation3/src/modules/pickup/items/MetaPickup.cc
===================================================================
--- code/branches/presentation3/src/modules/pickup/items/MetaPickup.cc	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/items/MetaPickup.cc	(revision 7162)
@@ -34,4 +34,5 @@
 #include "core/CoreIncludes.h"
 #include "core/XMLPort.h"
+#include "worldentities/pawns/Pawn.h"
 #include "interfaces/PickupCarrier.h"
 #include "pickup/PickupIdentifier.h"
@@ -47,4 +48,6 @@
     /*static*/ const std::string MetaPickup::metaTypeUse_s = "use";
     /*static*/ const std::string MetaPickup::metaTypeDrop_s = "drop";
+    /*static*/ const std::string MetaPickup::metaTypeDestroy_s = "destroy";
+    /*static*/ const std::string MetaPickup::metaTypeDestroyCarrier_s = "destroyCarrier";
 
     /**
@@ -120,6 +123,12 @@
             if(this->getMetaTypeDirect() != pickupMetaType::none && carrier != NULL)
             {
+                if(this->getMetaTypeDirect() == pickupMetaType::destroyCarrier)
+                {
+                    Pawn* pawn = orxonox_cast<Pawn*>(carrier);
+                    pawn->kill();
+                    return;
+                }
                 std::set<Pickupable*> pickups = carrier->getPickups();
-                //! Set all Pickupables carried by the PickupCarrier either to used or drop them, depending o the meta type.
+                //! Set all Pickupables carried by the PickupCarrier either to used or drop them, depending on the meta type.
                 for(std::set<Pickupable*>::iterator it = pickups.begin(); it != pickups.end(); it++)
                 {
@@ -136,10 +145,17 @@
                         if(pickup != NULL && pickup != this)
                         {
-                            pickup->drop(carrier);
+                            pickup->drop();
+                        }
+                    }
+                    if(this->getMetaTypeDirect() == pickupMetaType::destroy)
+                    {
+                        if(pickup != NULL && pickup != this)
+                        {
+                            pickup->Pickupable::destroy();
                         }
                     }
                 }
             }
-            this->destroy();
+            this->Pickupable::destroy();
         }
     }
@@ -180,4 +196,8 @@
             case pickupMetaType::drop:
                 return MetaPickup::metaTypeDrop_s;
+            case pickupMetaType::destroy:
+                return MetaPickup::metaTypeDestroy_s;
+            case pickupMetaType::destroyCarrier:
+                return MetaPickup::metaTypeDestroyCarrier_s;
             default:
                 return BLANKSTRING;
@@ -205,4 +225,14 @@
             this->setMetaTypeDirect(pickupMetaType::drop);
         }
+        else if(type == MetaPickup::metaTypeDestroy_s)
+        {
+            this->setMetaTypeDirect(pickupMetaType::destroy);
+        }
+        else if(type == MetaPickup::metaTypeDestroyCarrier_s)
+        {
+            this->setMetaTypeDirect(pickupMetaType::destroyCarrier);
+        }
+        else
+            COUT(2) << "Invalid metaType '" << type << "' in MetaPickup." << std::endl;
     }
 
Index: code/branches/presentation3/src/modules/pickup/items/MetaPickup.h
===================================================================
--- code/branches/presentation3/src/modules/pickup/items/MetaPickup.h	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/items/MetaPickup.h	(revision 7162)
@@ -48,5 +48,7 @@
             none,
             use,
-            drop
+            drop,
+            destroy,
+            destroyCarrier
         };
     }
@@ -54,5 +56,9 @@
     /**
     @brief
-        The MetaPickup is a pickup that can, depending on the parameters, either drop all pickups of the PickupCarrier that picks it up, or use all the unused pickups of the PickupCarrier, that picks it up. The parameter to set for this is the metaType and it can be used with the values 'none', 'drop' and 'use'.
+        The MetaPickup is a pickup that can, depending on the parameter 'metaType', do different things. If the 'metaType' is set to
+        1) 'use', all the pickups, the PickupCarrier has, are immediately set to used upon pickup of the MetaPickup.
+        2) 'drop', all the pickups, the PickupCarrier has, are immediately dropped upon pickup of the MetaPickup.
+        3) 'destroy', all the pickups, the PickupCarrier has, are immediately destroyed upon pickup of the MetaPickup.
+        4) 'destroyCarrier', the PickupCarrier is immediately destroyed upon pickup of the MetaPickup.
     @author
         Damian 'Mozork' Frick
@@ -98,4 +104,6 @@
             static const std::string metaTypeUse_s;
             static const std::string metaTypeDrop_s;
+            static const std::string metaTypeDestroy_s;
+            static const std::string metaTypeDestroyCarrier_s;
 
 
Index: code/branches/presentation3/src/modules/pickup/items/ShieldPickup.cc
===================================================================
--- code/branches/presentation3/src/modules/pickup/items/ShieldPickup.cc	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/items/ShieldPickup.cc	(revision 7162)
@@ -155,5 +155,5 @@
         Pawn* pawn = this->carrierToPawnHelper();
         if(pawn == NULL)
-            this->destroy();
+            this->Pickupable::destroy();
 
         //! If the pickup has transited to used.
@@ -181,5 +181,5 @@
                 if(!this->getTimer()->isActive() && this->getTimer()->getRemainingTime() == this->getDuration())
                 {
-                    this->destroy();
+                    this->Pickupable::destroy();
                 }
                 else
Index: code/branches/presentation3/src/modules/pickup/items/SpeedPickup.cc
===================================================================
--- code/branches/presentation3/src/modules/pickup/items/SpeedPickup.cc	(revision 7161)
+++ code/branches/presentation3/src/modules/pickup/items/SpeedPickup.cc	(revision 7162)
@@ -136,5 +136,5 @@
         Engine* engine = this->carrierToEngineHelper();
         if(engine == NULL) //!< If the PickupCarrier is no Engine, then this pickup is useless and therefore is destroyed.
-            this->destroy();
+            this->Pickupable::destroy();
 
         //! If the pickup has transited to used.
@@ -161,5 +161,5 @@
                 if(!this->getTimer()->isActive() && this->getTimer()->getRemainingTime() == this->getDuration())
                 {
-                    this->destroy();
+                    this->Pickupable::destroy();
                 }
                 else
Index: code/branches/presentation3/src/orxonox/CameraManager.cc
===================================================================
--- code/branches/presentation3/src/orxonox/CameraManager.cc	(revision 7161)
+++ code/branches/presentation3/src/orxonox/CameraManager.cc	(revision 7162)
@@ -68,5 +68,4 @@
     void CameraManager::requestFocus(Camera* camera)
     {
-      COUT(0) << "bliub" << endl;
         // notify old camera (if it exists)
         if (!this->cameraList_.empty())
Index: code/branches/presentation3/src/orxonox/gametypes/Dynamicmatch.cc
===================================================================
--- code/branches/presentation3/src/orxonox/gametypes/Dynamicmatch.cc	(revision 7161)
+++ code/branches/presentation3/src/orxonox/gametypes/Dynamicmatch.cc	(revision 7162)
@@ -102,5 +102,6 @@
 
     bool Dynamicmatch::allowPawnDamage(Pawn* victim, Pawn* originator)
-    { //TODO: static and fading message for the "human" player's
+    {
+        //TODO: static and fading message for the "human" player's
         if (!originator||!victim)
             return false;
Index: code/branches/presentation3/src/orxonox/interfaces/InterfaceCompilation.cc
===================================================================
--- code/branches/presentation3/src/orxonox/interfaces/InterfaceCompilation.cc	(revision 7161)
+++ code/branches/presentation3/src/orxonox/interfaces/InterfaceCompilation.cc	(revision 7162)
@@ -59,15 +59,25 @@
     {
         RegisterRootObject(PickupCarrier);
-
-        this->setCarrierName("PickupCarrier");
     }
 
     PickupCarrier::~PickupCarrier()
     {
+
+    }
+
+    void PickupCarrier::preDestroy(void)
+    {
         std::set<Pickupable*>::iterator it = this->pickups_.begin();
+        std::set<Pickupable*>::iterator temp;
         while(it != this->pickups_.end())
         {
-            (*it)->destroy();
+            (*it)->carrierDestroyed();
+            temp = it;
             it = this->pickups_.begin();
+            if(it == temp) // Infinite loop avoidance, in case the pickup wasn't removed from the carrier somewhere in the carrierDestroy() procedure.
+            {
+                COUT(2) << "Oops. In a PickupCarrier, while cleaning up, a Pickupable (&" << (*temp) << ") didn't unregister itself as it should have." << std::endl;;
+                it++;
+            }
         }
 
Index: code/branches/presentation3/src/orxonox/interfaces/PickupCarrier.h
===================================================================
--- code/branches/presentation3/src/orxonox/interfaces/PickupCarrier.h	(revision 7161)
+++ code/branches/presentation3/src/orxonox/interfaces/PickupCarrier.h	(revision 7162)
@@ -79,4 +79,5 @@
             PickupCarrier(); //!< Constructor.
             virtual ~PickupCarrier(); //!< Destructor.
+            void preDestroy(void);
 
             /**
@@ -138,10 +139,4 @@
             virtual const Vector3& getCarrierPosition(void) = 0;
 
-            /**
-            @brief Get the name of this PickupCarrier.
-            @return Returns the name as a string.
-            */
-            const std::string& getCarrierName(void) { return this->carrierName_; } // tolua_export
-
         protected:
             /**
@@ -160,4 +155,14 @@
 
             /**
+            @brief Get all Pickupables this PickupCarrier has.
+            @return  Returns the set of all Pickupables this PickupCarrier has.
+            */
+            std::set<Pickupable*>& getPickups(void)
+                { return this->pickups_; }
+
+        private:
+            std::set<Pickupable*> pickups_; //!< The list of Pickupables carried by this PickupCarrier.
+
+            /**
             @brief Adds a Pickupable to the list of pickups that are carried by this PickupCarrier.
             @param pickup A pointer to the pickup to be added.
@@ -165,5 +170,8 @@
             */
             bool addPickup(Pickupable* pickup)
-                { return this->pickups_.insert(pickup).second; }
+                {
+                    COUT(4) << "Adding Pickupable (&" << pickup << ") to PickupCarrier (&" << this << ")" << std::endl;
+                    return this->pickups_.insert(pickup).second;
+                }
 
             /**
@@ -173,72 +181,7 @@
             */
             bool removePickup(Pickupable* pickup)
-                { return this->pickups_.erase(pickup) == 1; }
-
-            /**
-            @brief Get all Pickupables this PickupCarrier has.
-            @return  Returns the set of all Pickupables this PickupCarrier has.
-            */
-            std::set<Pickupable*>& getPickups(void)
-                { return this->pickups_; }
-
-            /**
-            @brief Set the name of this PickupCarrier.
-                   The name needs to be set in the constructor of every class inheriting from PickupCarrier, by calling setCarrierName().
-            @param name The name to be set.
-            */
-            void setCarrierName(const std::string& name)
-                { this->carrierName_ = name; }
-
-        private:
-            std::set<Pickupable*> pickups_; //!< The list of Pickupables carried by this PickupCarrier.
-            std::string carrierName_; //!< The name of the PickupCarrier, as displayed in the PickupInventory.
-
-            /**
-            @brief Get the number of carrier children this PickupCarrier has.
-            @return Returns the number of carrier children.
-            */
-            unsigned int getNumCarrierChildren(void)
                 {
-                    std::vector<PickupCarrier*>* list = this->getCarrierChildren();
-                    unsigned int size = list->size();
-                    delete list;
-                    return size;
-                }
-
-            /**
-            @brief Get the index-th child of this PickupCarrier.
-            @param index The index of the child to return.
-            @return Returns the index-th child.
-            */
-            PickupCarrier* getCarrierChild(unsigned int index)
-                {
-                    std::vector<PickupCarrier*>* list = this->getCarrierChildren();
-                    if(list->size() < index)
-                        return NULL;
-                    PickupCarrier* carrier = (*list)[index];
-                    delete list;
-                    return carrier;
-                }
-
-            /**
-            @brief Get the number of Pickupables this PickupCarrier carries.
-            @return returns the number of pickups.
-            */
-            unsigned int getNumPickups(void)
-                { return this->pickups_.size(); }
-
-            /**
-            @brief Get the index-th Pickupable of this PickupCarrier.
-            @param index The index of the Pickupable to return.
-            @return Returns the index-th pickup.
-            */
-            Pickupable* getPickup(unsigned int index)
-                {
-                    std::set<Pickupable*>::iterator it;
-                    for(it = this->pickups_.begin(); index != 0 && it != this->pickups_.end(); it++)
-                        index--;
-                    if(it == this->pickups_.end())
-                        return NULL;
-                    return *it;
+                    COUT(4) << "Removing Pickupable (&" << pickup << ") from PickupCarrier (&" << this << ")" << std::endl;
+                    return this->pickups_.erase(pickup) == 1;
                 }
 
Index: code/branches/presentation3/src/orxonox/interfaces/Pickupable.cc
===================================================================
--- code/branches/presentation3/src/orxonox/interfaces/Pickupable.cc	(revision 7161)
+++ code/branches/presentation3/src/orxonox/interfaces/Pickupable.cc	(revision 7162)
@@ -58,4 +58,6 @@
 
         this->pickupIdentifier_ = new PickupIdentifier(this);
+        this->beingDestroyed_ = false;
+        this->enabled_ = true;
     }
 
@@ -66,14 +68,41 @@
     Pickupable::~Pickupable()
     {
-        if(this->isUsed())
-            this->setUsed(false);
-
-        if(this->isPickedUp())
-        {
-            this->drop(false);
-        }
-
+        COUT(4) << "Pickupable (" << this->getIdentifier()->getName() << ") (&" << this << ") destroyed." << std::endl;
         if(this->pickupIdentifier_ != NULL)
             this->pickupIdentifier_->destroy();
+    }
+
+    /**
+    @brief
+        A method that is called by OrxonoxClass::destroy() before the object is actually destroyed.
+    */
+    void Pickupable::preDestroy(void)
+    {
+        this->beingDestroyed_ = true;
+
+        if(this->isPickedUp())
+            this->drop(false); // Drops the pickup without creating a PickupSpawner.
+    }
+
+    /**
+    @brief
+        Is called internally within the pickup module to destroy pickups.
+    */
+    void Pickupable::destroy(void)
+    {
+        this->destroyPickup();
+    }
+
+    /**
+    @brief
+        Destroys a Pickupable.
+        If the Pickupable is already in the process of being destroyed a warning is displayed and this method is skipped.
+    */
+    void Pickupable::destroyPickup(void)
+    {
+        if(!this->beingDestroyed_)
+            this->OrxonoxClass::destroy();
+        else
+            COUT(2) << this->getIdentifier()->getName() << " may be unsafe. " << std::endl;
     }
 
@@ -88,5 +117,8 @@
     bool Pickupable::setUsed(bool used)
     {
-        if(this->used_ == used)
+        if(this->used_ == used || !this->isPickedUp()) // If either the used status of the Pickupable doesn't change or it isn't picked up.
+            return false;
+
+        if((!this->isUsable() && used) || (!this->isUnusable() && !used)) // If either the Pickupable is requested to be used but it is not usable or the Pickupable is requested to be unused, while it is not unusable.
             return false;
 
@@ -112,4 +144,5 @@
         if(carrier == NULL)
             return false;
+
         return this->isTarget(carrier->getIdentifier());
     }
@@ -131,4 +164,5 @@
                 return true;
         }
+
         return false;
     }
@@ -178,13 +212,12 @@
             return false;
 
-        if(!carrier->addPickup(this))
+        if(!this->setCarrier(carrier))
         {
             COUT(3) << "A Pickupable (&" << this << ") was trying to be added to a PickupCarrier, but was already present." << std::endl;
             return false;
         }
-
+        
+        this->setPickedUp(true);
         COUT(4) << "Pickupable (&" << this << ") got picked up by a PickupCarrier (&" << carrier << ")." << std::endl;
-        this->setCarrier(carrier);
-        this->setPickedUp(true);
         return true;
     }
@@ -194,5 +227,5 @@
         Can be called to drop a Pickupable.
     @param createSpawner
-        If true a spawner is be created for the dropped Pickupable. True is default.
+        If true a spawner is to be created for the dropped Pickupable. True is default.
     @return
         Returns true if the Pickupable has been dropped, false if not.
@@ -200,11 +233,11 @@
     bool Pickupable::drop(bool createSpawner)
     {
-        if(!this->isPickedUp()) //!< If the Pickupable is not picked up.
-            return false;
-
-        assert(this->getCarrier()); //!> The Carrier cannot be NULL at this point. //TODO: Too conservative?
+        if(!this->isPickedUp()) // If the Pickupable is not picked up.
+            return false;
+
+        assert(this->getCarrier()); // The Carrier cannot be NULL at this point.
         if(!this->getCarrier()->removePickup(this)) //TODO Shouldn't this be a little later?
-            COUT(2) << "Pickupable (&" << this << ") is being dropped, but it was not present in the PickupCarriers list of pickups." << std::endl;
-        
+            COUT(2) << "Pickupable (&" << this << ", " << this->getIdentifier()->getName() << ") is being dropped, but it was not present in the PickupCarriers list of pickups." << std::endl;
+
         COUT(4) << "Pickupable (&" << this << ") got dropped up by a PickupCarrier (&" << this->getCarrier() << ")." << std::endl;
         this->setUsed(false);
@@ -217,8 +250,6 @@
         this->setCarrier(NULL);
 
-        if(!created && createSpawner)
-        {
+        if(!created && createSpawner) // If a PickupSpawner should have been created but wasn't.
             this->destroy();
-        }
 
         return true;
@@ -235,5 +266,5 @@
     bool Pickupable::setPickedUp(bool pickedUp)
     {
-        if(this->pickedUp_ == pickedUp)
+        if(this->pickedUp_ == pickedUp) // If the picked up status has not changed.
             return false;
 
@@ -241,4 +272,6 @@
 
         this->pickedUp_ = pickedUp;
+        if(!pickedUp) // if the Pickupable has been dropped it unregisters itself with its PickupCarrier.
+            this->getCarrier()->removePickup(this);
         this->changedPickedUp();
         GUIManager::getInstance().getLuaState()->doString("PickupInventory.update()");
@@ -251,17 +284,34 @@
     @param carrier
         Sets the input PickupCarrier as the carrier of the pickup.
-    */
-    inline bool Pickupable::setCarrier(PickupCarrier* carrier, bool tell)
-    {
-        if(this->carrier_ == carrier)
+    @param tell
+        If true (default) the pickup is added to the list of pickups in the PickupCarrier.
+    @return
+        Returns true if successful, false if not.
+    */
+    bool Pickupable::setCarrier(orxonox::PickupCarrier* carrier, bool tell)
+    {
+        if(this->carrier_ == carrier) // If the PickupCarrier doesn't change.
             return false;
 
         COUT(4) << "Pickupable (&" << this << ") changed Carrier (& " << carrier << ")." << std::endl;
 
+        if(carrier != NULL && tell)
+        {
+            if(!carrier->addPickup(this))
+                return false;
+        }
+        
         this->carrier_ = carrier;
         this->changedCarrier();
-        if(tell && carrier != NULL)
-            this->carrier_->pickups_.insert(this);
-        return true;
+        return true;
+    }
+
+    /**
+    @brief
+        Is called by the PickupCarrier when it is being destroyed.
+    */
+    void Pickupable::carrierDestroyed(void)
+    {
+        this->destroy();
     }
 
Index: code/branches/presentation3/src/orxonox/interfaces/Pickupable.h
===================================================================
--- code/branches/presentation3/src/orxonox/interfaces/Pickupable.h	(revision 7161)
+++ code/branches/presentation3/src/orxonox/interfaces/Pickupable.h	(revision 7162)
@@ -95,6 +95,26 @@
             virtual void changedPickedUp(void) {}
 
-            bool pickup(PickupCarrier* carrier);
-            bool drop(bool createSpawner = true);
+            /**
+            @brief Returns whether the Pickupable can be used.
+            @return Returns true if it can be used.
+            */
+            inline bool isUsable(void) { return this->enabled_; } // tolua_export
+            
+            /**
+            @brief Returns whether the Pickupable can be unused.
+            @return Returns true if it can be unused.
+            */
+            inline bool isUnusable(void) { return this->enabled_; } // tolua_export
+
+            /**
+            @brief Returns whether the Pickupable is enabled.
+                   Once a Pickupable is disabled it cannot be enabled again. A Pickupable that is disabled can neither be used nor unused.
+            @return Returns true if the Pickupable is enabled.
+            */
+            inline bool isEnabled(void)
+                { return this->enabled_; }
+
+            bool pickup(PickupCarrier* carrier); //!< Can be called to pick up a Pickupable.
+            bool drop(bool createSpawner = true); //!< Can be called to drop a Pickupable.
 
             virtual bool isTarget(PickupCarrier* carrier) const; //!< Get whether the given PickupCarrier is a target of this pickup.
@@ -115,5 +135,11 @@
             bool setUsed(bool used); //!< Sets the Pickupable to used or unused, depending on the input.
             bool setPickedUp(bool pickedUp); //!< Helper method to set the Pickupable to either picked up or not picked up.
-            bool setCarrier(PickupCarrier* carrier, bool tell = false); //!< Sets the carrier of the pickup.
+            //TODO: private?
+            bool setCarrier(PickupCarrier* carrier, bool tell = true); //!< Sets the carrier of the pickup.
+
+            //TODO: private?
+            virtual void carrierDestroyed(void); //!< Is called by the PickupCarrier when it is being destroyed.
+
+            void destroy(void); //!< Is called internally within the pickup module to destroy pickups.
 
         protected:
@@ -122,4 +148,13 @@
             */
             void initializeIdentifier(void) {}
+
+            virtual void preDestroy(void); //!< A method that is called by OrxonoxClass::destroy() before the object is actually destroyed.
+            virtual void destroyPickup(void); //!< Destroys a Pickupable.
+
+            /**
+            @brief Sets the Pickuapble to disabled.
+            */
+            inline void setDisabled(void)
+                { this->enabled_ = false; }
 
             /**
@@ -136,9 +171,13 @@
         private:
 
-            bool used_; //!< Whether the pickup is currently in use or not.
-            bool pickedUp_; //!< Whether the pickup is currently picked up or not.
+            bool used_; //!< Whether the Pickupable is currently in use or not.
+            bool pickedUp_; //!< Whether the Pickupable is currently picked up or not.
 
-            PickupCarrier* carrier_; //!< The carrier of the pickup.
-            std::list<Identifier*> targets_; //!< The possible targets of this pickup.
+            bool enabled_; //!< Whether the Pickupable is enabled or not.
+
+            PickupCarrier* carrier_; //!< The PickupCarrier of the Pickupable.
+            std::list<Identifier*> targets_; //!< The possible targets of this Pickupable.
+
+            bool beingDestroyed_; //!< Is true if the Pickupable is in the process of being destroyed.
 
         // For implementing the Rewardable interface:
Index: code/branches/presentation3/src/orxonox/items/Engine.cc
===================================================================
--- code/branches/presentation3/src/orxonox/items/Engine.cc	(revision 7161)
+++ code/branches/presentation3/src/orxonox/items/Engine.cc	(revision 7162)
@@ -64,5 +64,4 @@
         this->boostBlur_ = 0;
 
-        this->setCarrierName("Engine");
         this->speedAdd_ = 0.0;
         this->speedMultiply_ = 1.0;
Index: code/branches/presentation3/src/orxonox/pickup/PickupIdentifier.cc
===================================================================
--- code/branches/presentation3/src/orxonox/pickup/PickupIdentifier.cc	(revision 7161)
+++ code/branches/presentation3/src/orxonox/pickup/PickupIdentifier.cc	(revision 7162)
@@ -105,5 +105,5 @@
         }
 
-        //! We iterate through all parameters and compar their values (which are strings). The first parameter is the most significant. The ordering is once again established by the alphabetical comparison of the two value strings.
+        //! We iterate through all parameters and compare their values (which are strings). The first parameter is the most significant. The ordering is once again established by the alphabetical comparison of the two value strings.
         for(std::map<std::string, std::string>::const_iterator it = this->parameters_.begin(); it != this->parameters_.end(); it++)
         {
Index: code/branches/presentation3/src/orxonox/worldentities/pawns/Pawn.cc
===================================================================
--- code/branches/presentation3/src/orxonox/worldentities/pawns/Pawn.cc	(revision 7161)
+++ code/branches/presentation3/src/orxonox/worldentities/pawns/Pawn.cc	(revision 7162)
@@ -83,6 +83,4 @@
             this->weaponSystem_ = 0;
 
-        this->setCarrierName("Pawn");
-
         this->setRadarObjectColour(ColourValue::Red);
         this->setRadarObjectShape(RadarViewable::Dot);
