Index: code/branches/pickup3/src/modules/pickup/Pickup.cc
===================================================================
--- code/branches/pickup3/src/modules/pickup/Pickup.cc	(revision 6476)
+++ code/branches/pickup3/src/modules/pickup/Pickup.cc	(revision 6477)
@@ -192,5 +192,5 @@
         
         //! Sets the Pickup to used if the Pickup has activation type 'immediate' and gets picked up.
-        if(this->isPickedUp() && this->isImmediate())
+        if(this->getCarrier() != NULL && this->isPickedUp() && this->isImmediate())
         {
             this->setUsed(true);
Index: code/branches/pickup3/src/modules/pickup/items/HealthPickup.cc
===================================================================
--- code/branches/pickup3/src/modules/pickup/items/HealthPickup.cc	(revision 6476)
+++ code/branches/pickup3/src/modules/pickup/items/HealthPickup.cc	(revision 6477)
@@ -31,4 +31,5 @@
 #include "core/CoreIncludes.h"
 #include "core/XMLPort.h"
+#include "util/StringUtils.h"
 
 #include "worldentities/pawns/Pawn.h"
@@ -43,8 +44,11 @@
     /*static*/ const std::string HealthPickup::healthTypeTemporary_s = "temporary";
     /*static*/ const std::string HealthPickup::healthTypePermanent_s = "permanent";
-    /*static*/ const std::string HealthPickup::blankString_s = "";
     
     CreateFactory(HealthPickup);
     
+    /**
+    @brief
+        Constructor. Registers the object and initializes the member variables.
+    */
     HealthPickup::HealthPickup(BaseObject* creator) : Pickup(creator)
     {
@@ -54,4 +58,8 @@
     }
     
+    /**
+    @brief
+        Destructor.
+    */
     HealthPickup::~HealthPickup()
     {
@@ -59,4 +67,8 @@
     }
     
+    /**
+    @brief 
+        Initializes the member variables.
+    */
     void HealthPickup::initialize(void)
     {
@@ -64,9 +76,15 @@
         
         this->health_ = 0;
-        this->healthSpeed_ = 0;
+        this->healthRate_ = 0;
         this->healthType_ = pickupHealthType::limited;
-        
-    }
-    
+        this->maxHealthSave_ = 0;
+        this->maxHealthOverwrite_ = 0;
+        
+    }
+    
+    /**
+    @brief
+        Initializes the PickupIdentifier of this pickup.
+    */
     void HealthPickup::initializeIdentifier(void)
     {
@@ -83,6 +101,16 @@
         std::string type2 = "healthType";
         this->pickupIdentifier_->addParameter(type2, val2);
-    }
-    
+        
+        stream.clear();
+        stream << this->getHealthRate();
+        std::string val3 = stream.str();
+        std::string type3 = "healthRate";
+        this->pickupIdentifier_->addParameter(type3, val3);
+    }
+    
+    /**
+    @brief
+        Method for creating a HealthPickup object through XML.
+    */
     void HealthPickup::HealthPickup::XMLPort(Element& xmlelement, orxonox::XMLPort::Mode mode)
     {
@@ -90,73 +118,33 @@
         
         XMLPortParam(HealthPickup, "health", setHealth, getHealth, xmlelement, mode);
-        XMLPortParam(HealthPickup, "healthSpeed", setHealthSpeed, getHealthSpeed, xmlelement, mode);
+        XMLPortParam(HealthPickup, "healthRate", setHealthRate, getHealthRate, xmlelement, mode);
         XMLPortParam(HealthPickup, "healthType", setHealthType, getHealthType, xmlelement, mode);
         
         if(!this->isContinuous())
-            this->healthSpeed_ = 0.0;
+            this->healthRate_ = 0.0;
         
         this->initializeIdentifier();
     }
     
-    void HealthPickup::setHealth(float health)
-    {
-        if(health > 0.0f)
-        {
-            this->health_ = health;
-        }
-        else
-        {
-            COUT(1) << "Invalid health in HealthPickup." << std::endl;
-        }
-    }
-    
-    void HealthPickup::setHealthSpeed(float speed)
-    {
-        if(speed >= 0)
-        {
-            this->healthSpeed_ = speed;
-        }
-        else
-        {
-            COUT(1) << "Invalid healthSpeed in HealthPickup." << std::endl; 
-        }
-    }
-    
-    void HealthPickup::setHealthType(std::string type)
-    {
-        if(type == HealthPickup::healthTypeLimited_s)
-        {
-            this->setHealthTypeDirect(pickupHealthType::limited);
-        }
-        else if(type == HealthPickup::healthTypeTemporary_s)
-        {
-            this->setHealthTypeDirect(pickupHealthType::temporary);
-        }
-        else if(type == HealthPickup::healthTypePermanent_s)
-        {
-            this->setHealthTypeDirect(pickupHealthType::permanent);
-        }
-        else
-        {
-            COUT(1) << "Invalid healthType in HealthPickup." << std::endl;
-        }
-    }
-    
+    /**
+    @brief
+        Is called every tick.
+        Does all the continuous stuff of this HealthPickup.
+    @param dt
+        The duration of the last tick.
+    */
     void HealthPickup::tick(float dt)
     {
         if(this->isContinuous() && this->isUsed())
         {
-            PickupCarrier* carrier = this->getCarrier();
-            Pawn* pawn = dynamic_cast<Pawn*>(carrier);
+            Pawn* pawn = this->carrierToPawnHelper();
+            if(pawn == NULL) //!< If the PickupCarrier is no Pawn, then this pickup is useless and therefore is destroyed.
+                this->destroy();
             
-            if(pawn == NULL)
-            {
-                COUT(1) << "Invalid PickupCarrier in HealthPickup." << std::endl;
-                return;
-            }
-            
-            float health = dt*this->getHealthSpeed();
+            //! Calculate the health that is added this tick.
+            float health = dt*this->getHealthRate();
             if(health > this->getHealth())
                 health = this->getHealth();
+            //! Calculate the health the Pawn will have once the health is added.
             float fullHealth = pawn->getHealth() + health;
             this->setHealth(this->getHealth()-health);
@@ -171,5 +159,11 @@
                     break;
                 case pickupHealthType::temporary:
-                    //TODO: How?
+                    if(pawn->getMaxHealth() > fullHealth)
+                    {
+                        this->maxHealthSave_ = pawn->getMaxHealth();
+                        this->maxHealthOverwrite_ = fullHealth;
+                        pawn->setMaxHealth(fullHealth);
+                    }
+                    pawn->addHealth(health);
                     break;
                 default:
@@ -177,61 +171,33 @@
             }
             
+            //! If all health has been transfered.
             if(this->getHealth() == 0)
             {
-                //TODO: Destroy
-            }
-        }
-    }
-    
-    const std::string& HealthPickup::getHealthType(void)
-    {
-        switch(this->getHealthTypeDirect())
-        {
-            case pickupHealthType::limited:
-                return HealthPickup::healthTypeLimited_s;
-            case pickupHealthType::temporary:
-                return HealthPickup::healthTypeTemporary_s;
-            case pickupHealthType::permanent:
-                return HealthPickup::healthTypePermanent_s;
-            default:
-                COUT(1) << "Invalid healthType in HealthPickup." << std::endl;
-                return HealthPickup::blankString_s;
-        }
-    }
-    
-    void HealthPickup::clone(OrxonoxClass* item)
-    {
-        if(item == NULL)
-            item = new HealthPickup(this);
-        
-        SUPER(HealthPickup, clone, item);
-        
-        //TODO: No temp needed?
-        HealthPickup* pickup = dynamic_cast<HealthPickup*>(item);
-        pickup->setHealth(this->getHealth());
-        pickup->setHealthSpeed(this->getHealthSpeed());
-        pickup->setHealthTypeDirect(this->getHealthTypeDirect());
-        
-        pickup->initializeIdentifier();
-    }
-    
-    //TODO: Does this work even if Pickup doesn't implement it?
+                this->setUsed(false);
+            }
+        }
+    }
+    
+    /**
+    @brief
+        Is called when the pickup has transited from used to unused or the other way around.
+    */
     void HealthPickup::changedUsed(void)
     {
         SUPER(HealthPickup, changedUsed);
         
+        //! If the pickup is not picked up nothing must be done.
+        if(!this->isPickedUp())
+            return;
+        
+        //! If the pickup has transited to used.
         if(this->isUsed())
         {
-            PickupCarrier* carrier = this->getCarrier();
-            Pawn* pawn = dynamic_cast<Pawn*>(carrier);
-            
-            if(pawn == NULL)
-            {
-                COUT(1) << "Invalid PickupCarrier in HealthPickup." << std::endl;
-                return;
-            }
-            
             if(this->isOnce())
             {
+                Pawn* pawn = this->carrierToPawnHelper();
+                if(pawn == NULL) //!< If the PickupCarrier is no Pawn, then this pickup is useless and therefore is destroyed.
+                    this->destroy();
+                
                 float health = 0;
                 switch(this->getHealthTypeDirect())
@@ -245,5 +211,12 @@
                         break;
                     case pickupHealthType::temporary:
-                        //TODO: How?
+                        health = pawn->getHealth()+this->getHealth();
+                        if(pawn->getMaxHealth() < health)
+                        {
+                            this->maxHealthSave_ = pawn->getMaxHealth();
+                            this->maxHealthOverwrite_ = health;
+                            pawn->setMaxHealth(health);
+                        }
+                        pawn->addHealth(this->getHealth());
                         break;
                     default:
@@ -251,10 +224,160 @@
                 }
                 
-                //TODO: Destroy.
+                //! The pickup has been used up.
+                this->setUsed(false);
             }
         }
         else
         {
-            //TODO: Destroy, but be careful to not destroy before being used.
+            if(this->getHealthTypeDirect() == pickupHealthType::temporary)
+            {
+                PickupCarrier* carrier = this->getCarrier();
+                Pawn* pawn = dynamic_cast<Pawn*>(carrier);
+                
+                if(pawn == NULL)
+                {
+                    COUT(1) << "Something went horribly wrong in Health Pickup. PickupCarrier is no Pawn." << std::endl;
+                    this->destroy();
+                    return;
+                }
+                
+                if(pawn->getMaxHealth() == this->maxHealthOverwrite_)
+                {
+                    pawn->setMaxHealth(this->maxHealthSave_);
+                    this->maxHealthOverwrite_ = 0;
+                    this->maxHealthSave_ = 0;
+                }
+            }
+            
+            //! If either the pickup can only be used once or it is continuous and used up, it is destroyed upon setting it to unused.
+            if(this->isOnce() || (this->isContinuous() && this->getHealth() == 0))
+            {
+                this->destroy();
+            }
+        }
+    }
+    
+    /**
+    @brief
+        Helper to transform the PickupCarrier to a Pawn, and throw an error message if the conversion fails.
+    @return
+        A pointer to the Pawn, or NULL if the conversion failed.
+    */
+    Pawn* HealthPickup::carrierToPawnHelper(void)
+    {
+        PickupCarrier* carrier = this->getCarrier();
+        Pawn* pawn = dynamic_cast<Pawn*>(carrier);
+        
+        if(pawn == NULL)
+        {
+            COUT(1) << "Invalid PickupCarrier in HealthPickup." << std::endl;
+        }
+        
+        return pawn;
+    }
+    
+    /**
+    @brief
+        Creates a duplicate of the input OrxonoxClass.
+    @param item
+        A pointer to the Orxonox class.
+    */
+    void HealthPickup::clone(OrxonoxClass* item)
+    {
+        if(item == NULL)
+            item = new HealthPickup(this);
+        
+        SUPER(HealthPickup, clone, item);
+        
+        HealthPickup* pickup = dynamic_cast<HealthPickup*>(item);
+        pickup->setHealth(this->getHealth());
+        pickup->setHealthRate(this->getHealthRate());
+        pickup->setHealthTypeDirect(this->getHealthTypeDirect());
+        
+        pickup->initializeIdentifier();
+    }
+    
+    /**
+    @brief
+        Get the health type of this pickup.
+    @return
+        Returns the health type as a string.
+    */
+    const std::string& HealthPickup::getHealthType(void)
+    {
+        switch(this->getHealthTypeDirect())
+        {
+            case pickupHealthType::limited:
+                return HealthPickup::healthTypeLimited_s;
+            case pickupHealthType::temporary:
+                return HealthPickup::healthTypeTemporary_s;
+            case pickupHealthType::permanent:
+                return HealthPickup::healthTypePermanent_s;
+            default:
+                COUT(1) << "Invalid healthType in HealthPickup." << std::endl;
+                return BLANKSTRING;
+        }
+    }
+    
+    /**
+    @brief
+        Sets the health.
+    @param health
+        The health.
+    */
+    void HealthPickup::setHealth(float health)
+    {
+        if(health > 0.0f)
+        {
+            this->health_ = health;
+        }
+        else
+        {
+            COUT(1) << "Invalid health in HealthPickup." << std::endl;
+            this->health_ = 0.0;
+        }
+    }
+    
+    /**
+    @brief
+        Set the rate at which health is transferred if the pickup is continuous.
+    @param rate
+        The rate.
+    */
+    void HealthPickup::setHealthRate(float rate)
+    {
+        if(rate >= 0)
+        {
+            this->healthRate_ = rate;
+        }
+        else
+        {
+            COUT(1) << "Invalid healthSpeed in HealthPickup." << std::endl; 
+        }
+    }
+    
+    /**
+    @brief
+        Set the type of the HealthPickup.
+    @param type
+        The type as a string.
+    */
+    void HealthPickup::setHealthType(std::string type)
+    {
+        if(type == HealthPickup::healthTypeLimited_s)
+        {
+            this->setHealthTypeDirect(pickupHealthType::limited);
+        }
+        else if(type == HealthPickup::healthTypeTemporary_s)
+        {
+            this->setHealthTypeDirect(pickupHealthType::temporary);
+        }
+        else if(type == HealthPickup::healthTypePermanent_s)
+        {
+            this->setHealthTypeDirect(pickupHealthType::permanent);
+        }
+        else
+        {
+            COUT(1) << "Invalid healthType in HealthPickup." << std::endl;
         }
     }
Index: code/branches/pickup3/src/modules/pickup/items/HealthPickup.h
===================================================================
--- code/branches/pickup3/src/modules/pickup/items/HealthPickup.h	(revision 6476)
+++ code/branches/pickup3/src/modules/pickup/items/HealthPickup.h	(revision 6477)
@@ -32,9 +32,10 @@
 #include "pickup/PickupPrereqs.h"
 
+#include <string>
+#include <worldentities/pawns/Pawn.h>
+#include "worldentities/StaticEntity.h"
+
 #include "pickup/Pickup.h"
 #include "tools/interfaces/Tickable.h"
-#include "worldentities/StaticEntity.h"
-
-#include <string>
 
 namespace orxonox {
@@ -51,46 +52,77 @@
     }
     
+    /**
+    @brief
+        A pickup that can do (dependent upon the parameters) lots of different things to the health of a Pawn.
+        There are 4 parameters that can be choosen:
+        1) The health. The amount of health that (in a way dependent on the other parameters) is transfered to the Pawn.
+        2) The activation type: It can be chosen to be either 'immediate' or 'onUse'. The activation type essentially (as indicated by the name) defines when the health is transfered, either immediately after being picked up or only after the player uses it.
+        3) The duration type: It can be chosen to be either 'once' or 'continuous'. For 'once' the specified health is transfered once to the Pawn, for 'continuous' the set health is transfered over a span of time at a rate defined by the health rate parameter.
+        4) The health type: The health type can be choosen to be 'limited', 'temporary' or 'permanent'. 'limited' means that the health is increased only to the maximum health of the Pawn. 'temporary' means that the maximum health is temporarily elevated but will be set back as soon as the pickup is no longer in use. 'permanent' means that the maximum health of the Pawn is increased such that the health provided by the pickup will fit in and the maximum health stays that way.
+    @author
+        Damian 'Mozork' Frick
+    */
     class _PickupExport HealthPickup : public Pickup, public Tickable
     {
         public:
         
-            HealthPickup(BaseObject* creator);
-            virtual ~HealthPickup();
+            HealthPickup(BaseObject* creator); //!< Constructor.
+            virtual ~HealthPickup(); //!< Destructor.
             
-            virtual void XMLPort(Element& xmlelement, orxonox::XMLPort::Mode mode);
-            virtual void tick(float dt);
+            virtual void XMLPort(Element& xmlelement, orxonox::XMLPort::Mode mode); //!< Method for creating a HealthPickup object through XML.
+            virtual void tick(float dt); //!< Is called every tick.
             
-            virtual void clone(OrxonoxClass* item);
-                        
-            virtual void changedUsed(void);
+            virtual void changedUsed(void); //!< Is called when the pickup has transited from used to unused or the other way around.
+            virtual void clone(OrxonoxClass* item); //!< Creates a duplicate of the input OrxonoxClass.
+            
+            /**
+            @brief Get the health that is transfered to the Pawn upon usage of this pickup.
+            @return Returns the health.
+            */
+            inline float getHealth(void)
+                { return this->health_; }
+            /**
+            @brief Get the rate at which the health is transferred to the Pawn, if this pickup has duration type 'continuous'.
+            @return Returns the rate.
+            */
+            inline float getHealthRate(void)
+                { return this->healthRate_; }
+                
+            /**
+            @brief Get the type of HealthPickup, this pickup is.
+            @return Returns the health type as an enum. 
+            */
+            inline pickupHealthType::Value getHealthTypeDirect(void)
+                { return this->healthType_; }
+            const std::string& getHealthType(void); //!< Get the health type of this pickup.
             
         protected:
-            void initializeIdentifier(void);
+            void initializeIdentifier(void); //!< Initializes the PickupIdentifier of this pickup.
 
-            void setHealth(float health);
-            void setHealthSpeed(float speed);
-            void setHealthType(std::string type);
+            void setHealth(float health); //!< Sets the health.
+            void setHealthRate(float speed); //!< Set the rate at which health is transferred if the pickup is continuous.
+            
+            /**
+            @brief Set the health type of this pickup.
+            @param type The type of this pickup as an enum.
+            */
             inline void setHealthTypeDirect(pickupHealthType::Value type)
                 { this->healthType_ = type; }
-            
-            inline float getHealth(void)
-                { return this->health_; }
-            inline float getHealthSpeed(void)
-                { return this->healthSpeed_; }
-            const std::string& getHealthType(void);
-            inline pickupHealthType::Value getHealthTypeDirect(void)
-                { return this->healthType_; }
+            void setHealthType(std::string type); //!< Set the type of the HealthPickup.
         
         private:
-            void initialize(void);
+            void initialize(void); //!< Initializes the member variables.
+            Pawn* carrierToPawnHelper(void); //!< Helper to transform the PickupCarrier to a Pawn, and throw an error message if the conversion fails.
             
-            float health_;
-            float healthSpeed_;
-            pickupHealthType::Value healthType_;
+            float health_; //!< The health that is transferred to the Pawn.
+            float healthRate_; //!< The rate at which the health is transferred.
+            float maxHealthSave_; //!< Helper to remember what the actual maxHealth of the Pawn was before we changed it.
+            float maxHealthOverwrite_; //!< Helper to remember with which value we overwrote the maxHealh, to detect if someone else changed it as well.
+            pickupHealthType::Value healthType_; //!< The type of the HealthPickup.
             
+            //! Strings for the health types.
             static const std::string healthTypeLimited_s;
             static const std::string healthTypeTemporary_s;
             static const std::string healthTypePermanent_s;
-            static const std::string blankString_s; //TODO: Maybe already implemented somewhere?
         
     };
Index: code/branches/pickup3/src/orxonox/interfaces/PickupCarrier.h
===================================================================
--- code/branches/pickup3/src/orxonox/interfaces/PickupCarrier.h	(revision 6476)
+++ code/branches/pickup3/src/orxonox/interfaces/PickupCarrier.h	(revision 6477)
@@ -76,10 +76,11 @@
             @brief Can be called to drop a Pickupable.
             @param pickup A pointer to the Pickupable.
+            @param drop If the Pickupable should just be removed from the PickupCarrier without further action, this can be set to false. true is default.
             @return Returns true if the Pickupable has been dropped, false if not.
             */
-            bool drop(Pickupable* pickup)
+            bool drop(Pickupable* pickup, bool drop = true)
                 { 
                    bool dropped = this->pickups_.erase(pickup) == 1;
-                   if(dropped)
+                   if(dropped && drop)
                    {
                        pickup->dropped();
Index: code/branches/pickup3/src/orxonox/interfaces/Pickupable.cc
===================================================================
--- code/branches/pickup3/src/orxonox/interfaces/Pickupable.cc	(revision 6476)
+++ code/branches/pickup3/src/orxonox/interfaces/Pickupable.cc	(revision 6477)
@@ -63,5 +63,12 @@
     Pickupable::~Pickupable()
     {
-        
+        if(this->isUsed())
+            this->setUsed(false);
+        
+        if(this->isPickedUp())
+        {
+            this->getCarrier()->drop(this, false);
+            this->setCarrier(NULL);
+        }
     }
     
