Index: code/branches/gui/src/core/CMakeLists.txt
===================================================================
--- code/branches/gui/src/core/CMakeLists.txt	(revision 1659)
+++ code/branches/gui/src/core/CMakeLists.txt	(revision 1660)
@@ -5,4 +5,5 @@
   Error.cc
   Exception.cc
+  GameState.cc
   Language.cc
   OrxonoxClass.cc
Index: code/branches/gui/src/core/Exception.h
===================================================================
--- code/branches/gui/src/core/Exception.h	(revision 1659)
+++ code/branches/gui/src/core/Exception.h	(revision 1660)
@@ -43,4 +43,11 @@
 #include "core/Debug.h"
 
+// Define some ugly macros to make things more clear
+#define CREATE_ORXONOX_EXCEPTION(name) typedef SpecificException<Exception::name> name##Exception;
+#define RETURN_EXCEPTION_CODE(name) \
+    case Exception::name:           \
+        return #name;
+
+
 namespace orxonox
 {
@@ -54,5 +61,6 @@
             PluginsNotFound,
             InitialisationFailed,
-            NotImplemented
+            NotImplemented,
+            GameState
         };
 
@@ -106,17 +114,13 @@
         std::string getTypeName() const
         {
-            // note: break is not necessary due to the return. Keep in mind!
+            // note: break is not necessary due to the return in the macros.
             switch (Type)
             {
-            case Exception::General:
-                return "General";
-            case Exception::FileNotFound:
-                return "FileNotFound";
-            case Exception::PluginsNotFound:
-                return "PluginsNotFound";
-            case Exception::InitialisationFailed:
-                return "InitialisationFailed";
-            case Exception::NotImplemented:
-                return "NotImplemented";
+            RETURN_EXCEPTION_CODE(General)
+            RETURN_EXCEPTION_CODE(FileNotFound);
+            RETURN_EXCEPTION_CODE(PluginsNotFound);
+            RETURN_EXCEPTION_CODE(InitialisationFailed);
+            RETURN_EXCEPTION_CODE(NotImplemented);
+            RETURN_EXCEPTION_CODE(GameState);
             default:
                 return "";
@@ -125,9 +129,11 @@
     };
 
-    typedef SpecificException<Exception::General> GeneralException;
-    typedef SpecificException<Exception::FileNotFound> FileNotFoundException;
-    typedef SpecificException<Exception::PluginsNotFound> PluginsNotFoundException;
-    typedef SpecificException<Exception::InitialisationFailed> InitialisationFailedException;
-    typedef SpecificException<Exception::NotImplemented> NotImplementedException;
+    // define the template spcialisations
+    CREATE_ORXONOX_EXCEPTION(General);
+    CREATE_ORXONOX_EXCEPTION(FileNotFound);
+    CREATE_ORXONOX_EXCEPTION(PluginsNotFound);
+    CREATE_ORXONOX_EXCEPTION(InitialisationFailed);
+    CREATE_ORXONOX_EXCEPTION(NotImplemented);
+    CREATE_ORXONOX_EXCEPTION(GameState);
 
 #define ThrowException(type, description) \
Index: code/branches/gui/src/core/GameState.cc
===================================================================
--- code/branches/gui/src/core/GameState.cc	(revision 1660)
+++ code/branches/gui/src/core/GameState.cc	(revision 1660)
@@ -0,0 +1,271 @@
+/*
+ *   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:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of GameState class.
+*/
+
+#include "GameState.h"
+#include <cassert>
+#include "Debug.h"
+#include "Exception.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Constructor only initialises variables and sets the name permanently.
+    */
+    GameState::GameState(const std::string& name)
+        : name_(name)
+        , bPauseParent_(false)
+        , bActive_(false)
+        , bSuspended_(false)
+        , parent_(0)
+        , activeChild_(0)
+    {
+    }
+
+    /**
+    @brief
+        Adds a child to the current tree. The Child can contain children of its own.
+        But you cannot a state tree that already has an active state.
+    @param state
+        The state to be added.
+    */
+    void GameState::addChild(GameState* state)
+    {
+        if (!state)
+            return;
+        // check if the state/tree to be added has states in it that already exist in this tree.
+        for (std::map<std::string, GameState*>::const_iterator it = state->allChildren_.begin();
+            it != state->allChildren_.end(); ++it)
+        {
+            if (this->checkState(it->second->getName()))
+            {
+                ThrowException(GameState, "Cannot add a GameState to the hierarchy twice.");
+                return;
+            }
+        }
+        if (this->checkState(state->name_))
+        {
+            ThrowException(GameState, "Cannot add a GameState to the hierarchy twice.");
+            return;
+        }
+        // Make sure we don't add a tree that already has an active state.
+        if (state->getCurrentState())
+        {
+            ThrowException(GameState, "Cannot merge a tree that is already active.");
+            return;
+        }
+
+        // merge the child's children into this tree
+        for (std::map<std::string, GameState*>::const_iterator it = state->allChildren_.begin();
+            it != state->allChildren_.end(); ++it)
+        {
+            this->allChildren_[it->second->getName()] = it->second;
+            this->grandchildrenToChildren_[it->second] = state;
+            if (this->parent_)
+                this->parent_->grandchildAdded(this, it->second);
+        }
+        // merge 'state' into this tree
+        this->allChildren_[state->name_] = state;
+        this->grandchildrenToChildren_[state] = state;
+        if (this->parent_)
+            this->parent_->grandchildAdded(this, state);
+
+        // mark us as parent
+        state->parent_ = this;
+    }
+
+    /**
+    @brief
+        Tells a state that one of its children has added a child. This is necessary
+        to fill the internal maps correctly.
+    @param child
+        The child who notices this state.
+    @param grandchild
+        The child that has been added.
+    */
+    void GameState::grandchildAdded(GameState* child, GameState* grandchild)
+    {
+        // fill the two maps correctly.
+        this->allChildren_[grandchild->getName()] = grandchild;
+        this->grandchildrenToChildren_[grandchild] = child;
+        if (this->parent_)
+            this->parent_->grandchildAdded(this, grandchild);
+    }
+
+    /**
+    @brief
+        Checks whether a specific game states exists in the hierarchy.
+    @remarks
+        Remember that the every node has a map with all its child nodes.
+    */
+    GameState* GameState::checkState(const std::string& name)
+    {
+        if (this->parent_)
+            return this->parent_->checkState(name);
+        else
+        {
+            // The map only contains children, so check ourself first
+            if (name == this->name_)
+                return this;
+            // Search in the map. If there is no entry, we can be sure the state doesn't exist.
+            std::map<std::string, GameState*>::const_iterator it = this->allChildren_.find(name);
+            return (it!= this->allChildren_.end() ? it->second : 0);
+        }
+    }
+
+    /**
+    @brief
+        Returns the current active state.
+    @remarks
+        Remember that the current active state is the one that does not
+        have active children itself. Many states can be active at once.
+    */
+    GameState* GameState::getCurrentState()
+    {
+        if (this->bActive_)
+        {
+            if (this->activeChild_)
+                return this->activeChild_->getCurrentState();
+            else
+                return this;
+        }
+        else
+        {
+            if (this->parent_)
+                return this->parent_->getCurrentState();
+            else
+                return 0;
+        }
+    }
+
+    /**
+    @brief
+        Returns the root node of the tree.
+    */
+    GameState* GameState::getRootNode()
+    {
+        if (this->parent_)
+            return this->parent_->getRootNode();
+        else
+            return this;
+    }
+
+    /**
+    @brief
+        Makes a state transition according to the state tree. You can choose any state
+        in the tree to do the call. The function finds the current state on its own.
+    @param state
+        The state to be entered, has to exist in the tree.
+    */
+    void GameState::requestState(const std::string& name)
+    {
+        GameState* request = checkState(name);
+        GameState* current = getCurrentState();
+        if (request)
+        {
+            if (current)
+            {
+                // There is already an active state
+                current->makeTransition(request);
+            }
+            else
+            {
+                // no active state --> we have to activate the root node first.
+                GameState* root = getRootNode();
+                root->activate();
+                root->makeTransition(request);
+            }
+        }
+        else
+        {
+            COUT(2) << "Warning: GameState '" << name << "' doesn't exist." << std::endl;
+        }
+    }
+
+    /**
+    @brief
+        Internal method that actually makes the state transition. Since it is internal,
+        the method can assume certain things to be granted (like 'this' is always active).
+    */
+    void GameState::makeTransition(GameState* state)
+    {
+        // we're always already active
+        assert(this->bActive_);
+
+        if (state == this)
+            return;
+
+        // Check for 'state' in the children map first
+        std::map<GameState*, GameState*>::const_iterator it = this->grandchildrenToChildren_.find(state);
+        if (it != this->grandchildrenToChildren_.end())
+        {
+            // child state. Don't use 'state', might be a grandchild!
+            it->second->activate();
+            it->second->makeTransition(state);
+        }
+        else
+        {
+            // parent. We can be sure of this.
+            assert(this->parent_ != 0);
+
+            // first, leave this state.
+            this->deactivate();
+            this->parent_->makeTransition(state);
+        }
+    }
+
+    /**
+    @brief
+        Activates the state. Only sets bActive_ to true and notifies the parent.
+    */
+    void GameState::activate()
+    {
+        this->bActive_ = true;
+        if (this->parent_)
+            this->parent_->activeChild_ = this;
+        this->enter();
+    }
+
+    /**
+        Activates the state. Only sets bActive_ to false and notifies the parent.
+    */
+    void GameState::deactivate()
+    {
+        this->leave();
+        this->bActive_ = false;
+        if (this->parent_)
+            this->parent_->activeChild_ = 0;
+    }
+
+}
Index: code/branches/gui/src/core/GameState.h
===================================================================
--- code/branches/gui/src/core/GameState.h	(revision 1660)
+++ code/branches/gui/src/core/GameState.h	(revision 1660)
@@ -0,0 +1,105 @@
+/*
+ *   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:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Definition of GameState class.
+*/
+
+#ifndef _GameState_H__
+#define _GameState_H__
+
+#include "CorePrereqs.h"
+
+#include <string>
+#include <vector>
+#include <map>
+
+namespace orxonox
+{
+    /**
+    @brief
+        An implementation of a tree to manage game states.
+        This leads to a certain hierarchy that is created at runtime.
+        To actually use the structure, you will have to derive from it and
+        implement 'enter', 'leave' and 'tick'. The latter corresponds to an
+        update function.
+
+        Internally the tree is managed by two maps per node: One stores all its
+        children, grandchildren, etc. by name of the state. The other maps these
+        children states to the actual child of the node.
+        An example: Foo is a grandchildren of Bar and Foofoo is the Foo's parent.
+        Then Bar stores Foo in map by its name. The other one then maps Foo to Foofoo.
+    */
+    class _CoreExport GameState
+    {
+    public:
+        GameState(const std::string& name);
+        virtual ~GameState() { }
+
+        const std::string& getName() const { return name_; }
+
+        void addChild(GameState* state);
+        void requestState(const std::string& name);
+
+        //! Determines whether the state is active.
+        bool isActive()       { return this->bActive_; }
+        //! Determines whether the state is suspended.
+        bool isSuspended()    { return this->bSuspended_; }
+        //! Determines whether the state is the current
+        bool isCurrentState() { return this->bActive_ && !this->activeChild_; }
+
+    protected:
+        virtual void enter() { }
+        virtual void leave() { }
+        virtual void tick(float dt) { }
+
+    private:
+        GameState* checkState(const std::string& name);
+        GameState* getCurrentState();
+        GameState* getRootNode();
+        void grandchildAdded(GameState* child, GameState* grandchild);
+        void makeTransition(GameState* state);
+        void activate();
+        void deactivate();
+
+        const std::string                    name_;
+        bool                                 bPauseParent_;
+
+        bool                                 bActive_;
+        bool                                 bSuspended_;
+
+        GameState*                           parent_;
+        GameState*                           activeChild_;
+        std::map<std::string, GameState*>    allChildren_;
+        std::map<GameState*, GameState*>     grandchildrenToChildren_;
+    };
+}
+
+#endif /* _GameState_H__ */
Index: code/branches/gui/src/core/input/InputManager.cc
===================================================================
--- code/branches/gui/src/core/input/InputManager.cc	(revision 1659)
+++ code/branches/gui/src/core/input/InputManager.cc	(revision 1660)
@@ -498,5 +498,8 @@
 
             joySticks_.clear();
-            _redimensionLists();
+            // don't use _redimensionLists(), might mess with registered handler if
+            // downgrading from 2 to 1 joystick
+            //_redimensionLists();
+            joySticksSize_ = 0;
         }
         CCOUT(4) << "Joy sticks destroyed." << std::endl;
Index: code/branches/gui/src/orxonox/Main.cc
===================================================================
--- code/branches/gui/src/orxonox/Main.cc	(revision 1659)
+++ code/branches/gui/src/orxonox/Main.cc	(revision 1660)
@@ -110,4 +110,6 @@
 }
 
+#include "core/GameState.h"
+
 #ifdef __cplusplus
 extern "C" {
@@ -125,4 +127,38 @@
         return 0;
     }
+
+
+    /*GameState* state1 = new GameState("state1");
+    GameState* state2 = new GameState("state2");
+    GameState* state3 = new GameState("state3");
+    GameState* state4 = new GameState("state4");
+    GameState* state5 = new GameState("state5");
+    GameState* state6 = new GameState("state6");
+
+    state1->addChild(state4);
+    state1->addChild(state6);
+    state2->addChild(state3);
+    state2->addChild(state5);
+    state3->addChild(state1);
+    state6->addChild(state2);
+
+    state5->requestState("state3");
+    COUT(2) << std::endl;
+    state2->requestState("state2");
+    COUT(2) << std::endl;
+    state2->requestState("state1");
+    COUT(2) << std::endl;
+    state4->requestState("state3");
+    COUT(2) << std::endl;
+    state1->requestState("state4");
+    COUT(2) << std::endl;
+    state1->requestState("state2");
+    COUT(2) << std::endl;
+    state1->requestState("stat");
+    COUT(2) << std::endl;
+    state1->requestState("state5");
+    COUT(2) << std::endl;*/
+
+
 
     Orxonox orxonoxInstance;
