Index: code/branches/questsystem5/src/core/CMakeLists.txt
===================================================================
--- code/branches/questsystem5/src/core/CMakeLists.txt	(revision 2777)
+++ code/branches/questsystem5/src/core/CMakeLists.txt	(revision 2907)
@@ -24,4 +24,6 @@
   Core.cc
   Event.cc
+  Game.cc
+  GameMode.cc
   GameState.cc
   Language.cc
@@ -29,5 +31,4 @@
   ObjectListBase.cc
   OrxonoxClass.cc
-  RootGameState.cc
 
   # command
Index: code/branches/questsystem5/src/core/Clock.h
===================================================================
--- code/branches/questsystem5/src/core/Clock.h	(revision 2777)
+++ code/branches/questsystem5/src/core/Clock.h	(revision 2907)
@@ -45,9 +45,9 @@
     class _CoreExport Clock
     {
-        friend class RootGameState;
-
     public:
         Clock();
         ~Clock();
+
+        void capture();
 
         unsigned long long getMicroseconds()   const { return tickTime_; }
@@ -63,5 +63,4 @@
     private:
         Clock(const Clock& instance);
-        void capture();
 
         Ogre::Timer*       timer_;
Index: code/branches/questsystem5/src/core/ConfigFileManager.cc
===================================================================
--- code/branches/questsystem5/src/core/ConfigFileManager.cc	(revision 2777)
+++ code/branches/questsystem5/src/core/ConfigFileManager.cc	(revision 2907)
@@ -190,5 +190,5 @@
         this->bUpdated_ = true;
 
-        return this->entries_.insert(this->entries_.end(), (ConfigFileEntry*)(new ConfigFileEntryValue(name, fallback, bString)));
+        return this->entries_.insert(this->entries_.end(), static_cast<ConfigFileEntry*>(new ConfigFileEntryValue(name, fallback, bString)));
     }
 
@@ -207,7 +207,7 @@
 
         if (index == 0)
-            return this->entries_.insert(this->entries_.end(), (ConfigFileEntry*)(new ConfigFileEntryVectorValue(name, index, fallback, bString)));
-        else
-            return this->entries_.insert(++this->getEntryIterator(name, index - 1, "", bString), (ConfigFileEntry*)(new ConfigFileEntryVectorValue(name, index, fallback, bString)));
+            return this->entries_.insert(this->entries_.end(), static_cast<ConfigFileEntry*>(new ConfigFileEntryVectorValue(name, index, fallback, bString)));
+        else
+            return this->entries_.insert(++this->getEntryIterator(name, index - 1, "", bString), static_cast<ConfigFileEntry*>(new ConfigFileEntryVectorValue(name, index, fallback, bString)));
     }
 
Index: code/branches/questsystem5/src/core/Core.cc
===================================================================
--- code/branches/questsystem5/src/core/Core.cc	(revision 2777)
+++ code/branches/questsystem5/src/core/Core.cc	(revision 2907)
@@ -22,6 +22,7 @@
  *   Author:
  *      Fabian 'x3n' Landau
+ *      Reto Grieder
  *   Co-authors:
- *      Reto Grieder
+ *      ...
  *
  */
@@ -41,4 +42,7 @@
 
 #ifdef ORXONOX_PLATFORM_WINDOWS
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#  endif
 #  include <windows.h>
 #elif defined(ORXONOX_PLATFORM_APPLE)
@@ -51,10 +55,20 @@
 
 #include "SpecialConfig.h"
+#include "util/Debug.h"
 #include "util/Exception.h"
+#include "util/SignalHandler.h"
+#include "Clock.h"
+#include "CommandExecutor.h"
+#include "CommandLine.h"
+#include "ConfigFileManager.h"
+#include "ConfigValueIncludes.h"
+#include "CoreIncludes.h"
+#include "Factory.h"
+#include "Identifier.h"
 #include "Language.h"
-#include "CoreIncludes.h"
-#include "ConfigValueIncludes.h"
 #include "LuaBind.h"
-#include "CommandLine.h"
+#include "Shell.h"
+#include "TclBind.h"
+#include "TclThreadManager.h"
 
 namespace orxonox
@@ -67,20 +81,11 @@
     static boost::filesystem::path logPath_g;                   //!< Path to the log file folder
 
-    bool Core::bShowsGraphics_s = false;
-    bool Core::bHasServer_s     = false;
-    bool Core::bIsClient_s      = false;
-    bool Core::bIsStandalone_s  = false;
-    bool Core::bIsMaster_s      = false;
-
-    bool Core::isDevBuild_s     = false;
     Core* Core::singletonRef_s  = 0;
 
     SetCommandLineArgument(mediaPath, "").information("PATH");
-    SetCommandLineArgument(directory, "").information("DIR");
-
-    /**
-        @brief Constructor: Registers the object and sets the config-values.
-        @param A reference to a global variable, used to avoid an infinite recursion in getSoftDebugLevel()
-    */
+    SetCommandLineArgument(writingPathSuffix, "").information("DIR");
+    SetCommandLineArgument(settingsFile, "orxonox.ini");
+    SetCommandLineArgument(limitToCPU, 0).information("0: off | #cpu");
+
     Core::Core()
     {
@@ -89,11 +94,55 @@
         assert(Core::singletonRef_s == 0);
         Core::singletonRef_s = this;
-
-        this->bInitializeRandomNumberGenerator_ = false;
-        this->setConfigValues();
+    }
+
+    void Core::initialise(int argc, char** argv)
+    {
+        // Parse command line arguments fist
+        try
+        {
+            CommandLine::parseAll(argc, argv);
+        }
+        catch (ArgumentException& ex)
+        {
+            COUT(1) << ex.what() << std::endl;
+            COUT(0) << "Usage:" << std::endl << "orxonox " << CommandLine::getUsageInformation() << std::endl;
+        }
+
+        // limit the main thread to the first core so that QueryPerformanceCounter doesn't jump
+        // do this after ogre has initialised. Somehow Ogre changes the settings again (not through
+        // the timer though).
+        int limitToCPU = CommandLine::getValue("limitToCPU");
+        if (limitToCPU > 0)
+            setThreadAffinity((unsigned int)limitToCPU);
+
+        // Determine and set the location of the executable
+        setExecutablePath();
+
+        // Determine whether we have an installed or a binary dir run
+        // The latter occurs when simply running from the build directory
+        checkDevBuild();
+
+        // Make sure the directories we write in exist or else make them
+        createDirectories();
+
+        // create a signal handler (only active for linux)
+        // This call is placed as soon as possible, but after the directories are set
+        this->signalHandler_ = new SignalHandler();
+        this->signalHandler_->doCatch(executablePath_g.string(), Core::getLogPathString() + "orxonox_crash.log");
 
         // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used
         OutputHandler::getOutStream().setLogPath(Core::getLogPathString());
 
+        // Manage ini files and set the default settings file (usually orxonox.ini)
+        this->configFileManager_ = new ConfigFileManager();
+        this->configFileManager_->setFilename(ConfigFileType::Settings,
+            CommandLine::getValue("settingsFile").getString());
+
+        this->languageInstance_ = new Language();
+
+        // Do this soon after the ConfigFileManager has been created to open up the
+        // possibility to configure everything below here
+        this->setConfigValues();
+
         // Possible media path override by the command line
         if (!CommandLine::getArgument("mediaPath")->hasDefaultValue())
@@ -102,4 +151,19 @@
             Core::tsetMediaPath(CommandLine::getValue("mediaPath"));
         }
+
+        // Create the lua interface
+        this->luaBind_ = new LuaBind();
+
+        // initialise Tcl
+        this->tclBind_ = new TclBind(Core::getMediaPathString());
+        this->tclThreadManager_ = new TclThreadManager(tclBind_->getTclInterpreter());
+
+        // create a shell
+        this->shell_ = new Shell();
+
+        // creates the class hierarchy for all classes with factories
+        Factory::createClassHierarchy();
+        
+        this->loaded_ = true;
     }
 
@@ -109,4 +173,19 @@
     Core::~Core()
     {
+        this->loaded_ = false;
+
+        delete this->shell_;
+        delete this->tclThreadManager_;
+        delete this->tclBind_;
+        delete this->luaBind_;
+        delete this->languageInstance_;
+        delete this->configFileManager_;
+        delete this->signalHandler_;
+
+        // Destroy command line arguments
+        CommandLine::destroyAllArguments();
+        // Also delete external console command that don't belong to an Identifier
+        CommandExecutor::destroyExternalCommands();
+
         assert(Core::singletonRef_s);
         Core::singletonRef_s = 0;
@@ -292,23 +371,48 @@
     }
 
-    /**
-    @brief
-        Performs the rather lower level operations just after
-        int main() has been called.
-    @remarks
-        This gets called AFTER pre-main stuff like AddFactory,
-        SetConsoleCommand, etc.
-    */
-    /*static*/ void Core::postMainInitialisation()
-    {
-        // set location of the executable
-        Core::setExecutablePath();
-
-        // Determine whether we have an installed or a binary dir run
-        // The latter occurs when simply running from the build directory
-        Core::checkDevBuild();
-
-        // Make sure the directories we write in exist or else make them
-        Core::createDirectories();
+
+    /**
+    @note
+        The code of this function has been copied and adjusted from OGRE, an open source graphics engine.
+            (Object-oriented Graphics Rendering Engine)
+        For the latest info, see http://www.ogre3d.org/
+
+        Copyright (c) 2000-2008 Torus Knot Software Ltd
+
+        OGRE is licensed under the LGPL. For more info, see OGRE license.
+    */
+    void Core::setThreadAffinity(int limitToCPU)
+    {
+        if (limitToCPU <= 0)
+            return;
+
+#ifdef ORXONOX_PLATFORM_WINDOWS
+        unsigned int coreNr = limitToCPU - 1;
+        // Get the current process core mask
+        DWORD procMask;
+        DWORD sysMask;
+#  if _MSC_VER >= 1400 && defined (_M_X64)
+        GetProcessAffinityMask(GetCurrentProcess(), (PDWORD_PTR)&procMask, (PDWORD_PTR)&sysMask);
+#  else
+        GetProcessAffinityMask(GetCurrentProcess(), &procMask, &sysMask);
+#  endif
+
+        // If procMask is 0, consider there is only one core available
+        // (using 0 as procMask will cause an infinite loop below)
+        if (procMask == 0)
+            procMask = 1;
+
+        // if the core specified with coreNr is not available, take the lowest one
+        if (!(procMask & (1 << coreNr)))
+            coreNr = 0;
+
+        // Find the lowest core that this process uses and coreNr suggests
+        DWORD threadMask = 1;
+        while ((threadMask & procMask) == 0 || (threadMask < (1u << coreNr)))
+            threadMask <<= 1;
+
+        // Set affinity to the first core
+        SetThreadAffinityMask(GetCurrentThread(), threadMask);
+#endif
     }
 
@@ -317,5 +421,5 @@
         Compares the executable path with the working directory
     */
-    /*static*/ void Core::setExecutablePath()
+    void Core::setExecutablePath()
     {
 #ifdef ORXONOX_PLATFORM_WINDOWS
@@ -369,10 +473,10 @@
         don't write the logs and config files to ~/.orxonox
     */
-    /*static*/ void Core::checkDevBuild()
+    void Core::checkDevBuild()
     {
         if (boost::filesystem::exists(executablePath_g / "orxonox_dev_build.keep_me"))
         {
             COUT(1) << "Running from the build tree." << std::endl;
-            Core::isDevBuild_s = true;
+            Core::isDevBuild_ = true;
             mediaPath_g  = ORXONOX_MEDIA_DEV_PATH;
             configPath_g = ORXONOX_CONFIG_DEV_PATH;
@@ -385,5 +489,5 @@
             boost::filesystem::path relativeExecutablePath(ORXONOX_RUNTIME_INSTALL_PATH);
             rootPath_g = executablePath_g;
-            while (!boost::filesystem::equivalent(rootPath_g / relativeExecutablePath, executablePath_g) || rootPath_g.empty())
+            while (!boost::filesystem::equivalent(rootPath_g / relativeExecutablePath, executablePath_g) && !rootPath_g.empty())
                 rootPath_g = rootPath_g.branch_path();
             if (rootPath_g.empty())
@@ -416,7 +520,7 @@
 
         // Option to put all the config and log files in a separate folder
-        if (!CommandLine::getArgument("directory")->hasDefaultValue())
-        {
-            std::string directory(CommandLine::getValue("directory").getString());
+        if (!CommandLine::getArgument("writingPathSuffix")->hasDefaultValue())
+        {
+            std::string directory(CommandLine::getValue("writingPathSuffix").getString());
             configPath_g = configPath_g / directory;
             logPath_g    = logPath_g    / directory;
@@ -429,5 +533,5 @@
         if necessary. Otherwise me might have problems opening those files.
     */
-    /*static*/ void Core::createDirectories()
+    void Core::createDirectories()
     {
         std::vector<std::pair<boost::filesystem::path, std::string> > directories;
@@ -451,3 +555,8 @@
         }
     }
+
+    void Core::update(const Clock& time)
+    {
+        this->tclThreadManager_->update(time);
+    }
 }
Index: code/branches/questsystem5/src/core/Core.h
===================================================================
--- code/branches/questsystem5/src/core/Core.h	(revision 2777)
+++ code/branches/questsystem5/src/core/Core.h	(revision 2907)
@@ -22,6 +22,7 @@
  *   Author:
  *      Fabian 'x3n' Landau
+ *      Reto Grieder
  *   Co-authors:
- *      Reto Grieder
+ *      ...
  *
  */
@@ -44,6 +45,4 @@
 #include "util/OutputHandler.h"
 
-// Only allow main to access postMainInitialisation, so we need a forward declaration
-int main(int, char**);
 // boost::filesystem header has quite a large tail, use forward declaration
 namespace boost { namespace filesystem
@@ -59,10 +58,12 @@
     class _CoreExport Core : public OrxonoxClass
     {
-        friend int ::main(int, char**); // sets isDevBuild_s
-
         public:
             Core();
             ~Core();
+
+            void initialise(int argc, char** argv);
             void setConfigValues();
+
+            void update(const Clock& time);
 
             static Core& getInstance() { assert(Core::singletonRef_s); return *Core::singletonRef_s; }
@@ -72,6 +73,4 @@
             static const std::string& getLanguage();
             static void  resetLanguage();
-
-            static bool isDevBuild() { return Core::isDevBuild_s; }
 
             static void tsetMediaPath(const std::string& path)
@@ -84,18 +83,12 @@
             static std::string getLogPathString();
 
-            // fast access global variables.
-            static bool showsGraphics() { return bShowsGraphics_s; }
-            static bool hasServer()     { return bHasServer_s; }
-            static bool isClient()      { return bIsClient_s; }
-            static bool isStandalone()  { return bIsStandalone_s; }
-            static bool isMaster()      { return bIsMaster_s; }
-            static void setShowsGraphics(bool val) { bShowsGraphics_s = val; updateIsMaster(); }
-            static void setHasServer    (bool val) { bHasServer_s     = val; updateIsMaster(); }
-            static void setIsClient     (bool val) { bIsClient_s      = val; updateIsMaster(); }
-            static void setIsStandalone (bool val) { bIsStandalone_s  = val; updateIsMaster(); }
-            static void updateIsMaster  ()         { bIsMaster_s      = (bHasServer_s || bIsStandalone_s); }
-
         private:
             Core(const Core&);
+
+            void checkDevBuild();
+            void setExecutablePath();
+            void createDirectories();
+            void setThreadAffinity(int limitToCPU);
+
             void resetLanguageIntern();
             void initializeRandomNumberGenerator();
@@ -105,8 +98,12 @@
             void _tsetMediaPath(const std::string& path);
 
-            static void postMainInitialisation();
-            static void checkDevBuild();
-            static void setExecutablePath();
-            static void createDirectories();
+            // Singletons
+            ConfigFileManager*    configFileManager_;
+            Language*             languageInstance_;
+            LuaBind*              luaBind_;
+            Shell*                shell_;
+            SignalHandler*        signalHandler_;
+            TclBind*              tclBind_;
+            TclThreadManager*     tclThreadManager_;
 
             int softDebugLevel_;                            //!< The debug level
@@ -117,12 +114,6 @@
             bool bInitializeRandomNumberGenerator_;         //!< If true, srand(time(0)) is called
             std::string mediaPathString_;                   //!< Path to the data/media file folder as string
-
-            static bool bShowsGraphics_s;                   //!< global variable that tells whether to show graphics
-            static bool bHasServer_s;                       //!< global variable that tells whether this is a server
-            static bool bIsClient_s;
-            static bool bIsStandalone_s;
-            static bool bIsMaster_s;
-
-            static bool isDevBuild_s;                       //!< True for builds in the build directory (not installed)
+            bool isDevBuild_;                               //!< True for builds in the build directory (not installed)
+            bool loaded_;                                   //!< Only true if constructor was interrupted
 
             static Core* singletonRef_s;
Index: code/branches/questsystem5/src/core/CorePrereqs.h
===================================================================
--- code/branches/questsystem5/src/core/CorePrereqs.h	(revision 2777)
+++ code/branches/questsystem5/src/core/CorePrereqs.h	(revision 2907)
@@ -166,8 +166,7 @@
 
   // game states
-  class GameStateBase;
-  template <class ParentType>
+  class Game;
   class GameState;
-  class RootGameState;
+  struct GameStateTreeNode;
 
   // input
Index: code/branches/questsystem5/src/core/Game.cc
===================================================================
--- code/branches/questsystem5/src/core/Game.cc	(revision 2907)
+++ code/branches/questsystem5/src/core/Game.cc	(revision 2907)
@@ -0,0 +1,393 @@
+/*
+ *   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 the Game class.
+*/
+
+#include "Game.h"
+
+#include <exception>
+#include <cassert>
+
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/SubString.h"
+#include "Clock.h"
+#include "CommandLine.h"
+#include "ConsoleCommand.h"
+#include "Core.h"
+#include "CoreIncludes.h"
+#include "ConfigValueIncludes.h"
+#include "GameState.h"
+
+namespace orxonox
+{
+    static void stop_game()
+        { Game::getInstance().stop(); }
+    SetConsoleCommandShortcutExternAlias(stop_game, "exit");
+
+    struct _CoreExport GameStateTreeNode
+    {
+        GameState*                      state_;
+        GameStateTreeNode*              parent_;
+        std::vector<GameStateTreeNode*> children_;
+    };
+
+    std::map<std::string, GameState*> Game::allStates_s;
+    Game* Game::singletonRef_s = 0;
+
+    /**
+    @brief
+        Non-initialising constructor.
+    */
+    Game::Game(int argc, char** argv)
+    {
+        assert(singletonRef_s == 0);
+        singletonRef_s = this;
+
+        this->rootStateNode_ = 0;
+        this->activeStateNode_ = 0;
+
+        this->abort_ = false;
+
+        // reset statistics
+        this->statisticsStartTime_ = 0;
+        this->statisticsTickTimes_.clear();
+        this->periodTickTime_ = 0;
+        this->periodTime_ = 0;
+        this->avgFPS_ = 0.0f;
+        this->avgTickTime_ = 0.0f;
+
+
+        // Set up a basic clock to keep time
+        this->gameClock_ = new Clock();
+
+        this->core_ = new orxonox::Core();
+        this->core_->initialise(argc, argv);
+
+        RegisterRootObject(Game);
+        this->setConfigValues();
+    }
+
+    /**
+    @brief
+    */
+    Game::~Game()
+    {
+        // Destroy pretty much everyhting left
+        delete this->core_;
+
+        // Delete all GameStates created by the macros
+        for (std::map<std::string, GameState*>::const_iterator it = allStates_s.begin(); it != allStates_s.end(); ++it)
+            delete it->second;
+
+        delete this->gameClock_;
+
+        assert(singletonRef_s);
+        singletonRef_s = 0;
+    }
+
+    void Game::setConfigValues()
+    {
+        SetConfigValue(statisticsRefreshCycle_, 250000)
+            .description("Sets the time in microseconds interval at which average fps, etc. get updated.");
+        SetConfigValue(statisticsAvgLength_, 1000000)
+            .description("Sets the time in microseconds interval at which average fps, etc. gets calculated.");
+    }
+
+    /**
+    @brief
+        Main loop of the orxonox game.
+    @note
+        We use the Ogre::Timer to measure time since it uses the most precise
+        method an any platform (however the windows timer lacks time when under
+        heavy kernel load!).
+    */
+    void Game::run()
+    {
+        // Always start with the ROOT state
+        this->requestedStateNodes_.push_back(this->rootStateNode_);
+        this->activeStateNode_ = this->rootStateNode_;
+        this->loadState(this->rootStateNode_->state_);
+
+        // START GAME
+        this->gameClock_->capture(); // first delta time should be about 0 seconds
+        while (!this->abort_ && !this->activeStates_.empty())
+        {
+            this->gameClock_->capture();
+            uint64_t currentTime = this->gameClock_->getMicroseconds();
+
+            // STATISTICS
+            statisticsTickInfo tickInfo = {currentTime, 0};
+            statisticsTickTimes_.push_back(tickInfo);
+            this->periodTime_ += this->gameClock_->getDeltaTimeMicroseconds();
+
+            // UPDATE STATE STACK
+            while (this->requestedStateNodes_.size() > 1)
+            {
+                // Note: this->requestedStateNodes_.front() is the currently active state node
+                std::vector<GameStateTreeNode*>::iterator it = this->requestedStateNodes_.begin() + 1;
+                if (*it == this->activeStateNode_->parent_)
+                    this->unloadState(this->activeStateNode_->state_);
+                else // has to be child
+                    this->loadState((*it)->state_);
+                this->activeStateNode_ = *it;
+                this->requestedStateNodes_.erase(this->requestedStateNodes_.begin());
+            }
+
+            // UPDATE, bottom to top in the stack
+            this->core_->update(*this->gameClock_);
+            for (std::vector<GameState*>::const_iterator it = this->activeStates_.begin();
+                it != this->activeStates_.end(); ++it)
+                (*it)->update(*this->gameClock_);
+
+            // STATISTICS
+            if (this->periodTime_ > statisticsRefreshCycle_)
+            {
+                std::list<statisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();
+                assert(it != this->statisticsTickTimes_.end());
+                int64_t lastTime = currentTime - this->statisticsAvgLength_;
+                if ((int64_t)it->tickTime < lastTime)
+                {
+                    do
+                    {
+                        assert(this->periodTickTime_ > it->tickLength);
+                        this->periodTickTime_ -= it->tickLength;
+                        ++it;
+                        assert(it != this->statisticsTickTimes_.end());
+                    } while ((int64_t)it->tickTime < lastTime);
+                    this->statisticsTickTimes_.erase(this->statisticsTickTimes_.begin(), it);
+                }
+
+                uint32_t framesPerPeriod = this->statisticsTickTimes_.size();
+                this->avgFPS_ = (float)framesPerPeriod / (currentTime - this->statisticsTickTimes_.front().tickTime) * 1000000.0;
+                this->avgTickTime_ = (float)this->periodTickTime_ / framesPerPeriod / 1000.0;
+
+                this->periodTime_ -= this->statisticsRefreshCycle_;
+            }
+        }
+
+        // UNLOAD all remaining states
+        while (!this->activeStates_.empty())
+            this->unloadState(this->activeStates_.back());
+        this->activeStateNode_ = 0;
+        this->requestedStateNodes_.clear();
+    }
+
+    void Game::stop()
+    {
+        this->abort_ = true;
+    }
+
+    void Game::addTickTime(uint32_t length)
+    {
+        assert(!this->statisticsTickTimes_.empty());
+        this->statisticsTickTimes_.back().tickLength += length;
+        this->periodTickTime_+=length;
+    }
+
+
+    /***** GameState related *****/
+
+    void Game::requestState(const std::string& name)
+    {
+        GameState* state = this->getState(name);
+        if (state == NULL || this->activeStateNode_ == NULL)
+            return;
+
+        GameStateTreeNode* requestedNode = 0;
+
+        // this->requestedStateNodes_.back() is the currently active state
+        GameStateTreeNode* lastRequestedNode = this->requestedStateNodes_.back();
+
+        // Already the active node?
+        if (state == lastRequestedNode->state_)
+        {
+            COUT(2) << "Warning: Requesting the currently active state! Ignoring." << std::endl;
+            return;
+        }
+
+        // Check children first
+        for (unsigned int i = 0; i < lastRequestedNode->children_.size(); ++i)
+        {
+            if (lastRequestedNode->children_[i]->state_ == state)
+            {
+                requestedNode = lastRequestedNode->children_[i];
+                break;
+            }
+        }
+
+        // Check parent and all its grand parents
+        GameStateTreeNode* currentNode = lastRequestedNode;
+        while (requestedNode == NULL && currentNode != NULL)
+        {
+            if (currentNode->state_ == state)
+                requestedNode = currentNode;
+            currentNode = currentNode->parent_;
+        }
+
+        if (requestedNode == NULL)
+            COUT(1) << "Error: Requested GameState transition is not allowed. Ignoring." << std::endl;
+        else
+            this->requestedStateNodes_.push_back(requestedNode);
+    }
+
+    void Game::requestStates(const std::string& names)
+    {
+        SubString tokens(names, ",;", " ");
+        for (unsigned int i = 0; i < tokens.size(); ++i)
+            this->requestState(tokens[i]);
+    }
+
+    void Game::popState()
+    {
+        if (this->activeStateNode_ != NULL && this->requestedStateNodes_.back()->parent_)
+            this->requestState(this->requestedStateNodes_.back()->parent_->state_->getName());
+        else
+            COUT(2) << "Warning: Could not pop GameState. Ignoring." << std::endl;
+    }
+
+    GameState* Game::getState(const std::string& name)
+    {
+        std::map<std::string, GameState*>::const_iterator it = allStates_s.find(getLowercase(name));
+        if (it != allStates_s.end())
+            return it->second;
+        else
+        {
+            COUT(1) << "Error: Could not find GameState '" << name << "'. Ignoring." << std::endl;
+            return 0;
+        }
+    }
+
+    void Game::setStateHierarchy(const std::string& str)
+    {
+        // Split string into pieces of the form whitespacesText
+        std::vector<std::pair<std::string, unsigned> > stateStrings;
+        size_t pos = 0;
+        size_t startPos = 0;
+        while (pos < str.size())
+        {
+            unsigned indentation = 0;
+            while(pos < str.size() && str[pos] == ' ')
+                ++indentation, ++pos;
+            startPos = pos;
+            while(pos < str.size() && str[pos] != ' ')
+                ++pos;
+            stateStrings.push_back(std::pair<std::string, unsigned>(
+                str.substr(startPos, pos - startPos), indentation));
+        }
+        unsigned int currentLevel = 0;
+        GameStateTreeNode* currentNode = 0;
+        for (std::vector<std::pair<std::string, unsigned> >::const_iterator it = stateStrings.begin(); it != stateStrings.end(); ++it)
+        {
+            std::string newStateName = it->first;
+            unsigned newLevel = it->second;
+            GameState* newState = this->getState(newStateName);
+            if (!newState)
+                ThrowException(GameState, std::string("GameState with name '") + newStateName + "' not found!");
+            if (newLevel == 0)
+            {
+                // root
+                if (this->rootStateNode_ != NULL)
+                    ThrowException(GameState, "No two root GameStates are allowed!");
+                GameStateTreeNode* newNode = new GameStateTreeNode;
+                newNode->state_ = newState;
+                newNode->parent_ = 0;
+                this->rootStateNode_ = newNode;
+                currentNode = this->rootStateNode_;
+            }
+            else if (currentNode)
+            {
+                GameStateTreeNode* newNode = new GameStateTreeNode;
+                newNode->state_ = newState;
+                if (newLevel < currentLevel)
+                {
+                    // Get down the hierarchy
+                    do
+                        currentNode = currentNode->parent_;
+                    while (newLevel < --currentLevel);
+                }
+                if (newLevel == currentLevel)
+                {
+                    // same level
+                    newNode->parent_ = currentNode->parent_;
+                    newNode->parent_->children_.push_back(newNode);
+                }
+                else if (newLevel == currentLevel + 1)
+                {
+                    // child
+                    newNode->parent_ = currentNode;
+                    currentNode->children_.push_back(newNode);
+                }
+                else
+                    ThrowException(GameState, "Indentation error while parsing the hierarchy.");
+                currentNode = newNode;
+                currentLevel = newLevel;
+            }
+            else
+            {
+                ThrowException(GameState, "No root GameState specified!");
+            }
+        }
+    }
+
+    /*** Internal ***/
+
+    void Game::loadState(GameState* state)
+    {
+        if (!this->activeStates_.empty())
+            this->activeStates_.back()->activity_.topState = false;
+        state->activate();
+        state->activity_.topState = true;
+        this->activeStates_.push_back(state);
+    }
+
+    void Game::unloadState(orxonox::GameState* state)
+    {
+        state->activity_.topState = false;
+        state->deactivate();
+        this->activeStates_.pop_back();
+        if (!this->activeStates_.empty())
+            this->activeStates_.back()->activity_.topState = true;
+    }
+
+    /*static*/ bool Game::addGameState(GameState* state)
+    {
+        std::map<std::string, GameState*>::const_iterator it = allStates_s.find(getLowercase(state->getName()));
+        if (it == allStates_s.end())
+            allStates_s[getLowercase(state->getName())] = state;
+        else
+            ThrowException(GameState, "Cannot add two GameStates with the same name to 'Game'.");
+
+        // just a required dummy return value
+        return true;
+    }
+}
Index: code/branches/questsystem5/src/core/Game.h
===================================================================
--- code/branches/questsystem5/src/core/Game.h	(revision 2907)
+++ code/branches/questsystem5/src/core/Game.h	(revision 2907)
@@ -0,0 +1,120 @@
+/*
+ *   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
+    Declaration of Game Singleton.
+ */
+
+#ifndef _Game_H__
+#define _Game_H__
+
+#include "CorePrereqs.h"
+#include <cassert>
+#include <list>
+#include <map>
+#include <vector>
+#include "OrxonoxClass.h"
+
+#define AddGameState(classname, name) \
+    static bool bGameStateDummy_##classname##__LINE__ = orxonox::Game::addGameState(new classname(name))
+
+namespace orxonox
+{
+    /**
+    @brief
+        Main class responsible for running the game.
+    */
+    class _CoreExport Game : public OrxonoxClass
+    {
+    public:
+        Game(int argc, char** argv);
+        ~Game();
+        void setConfigValues();
+
+        void setStateHierarchy(const std::string& str);
+        GameState* getState(const std::string& name);
+
+        void run();
+        void stop();
+
+        void requestState(const std::string& name);
+        void requestStates(const std::string& names);
+        void popState();
+
+        const Clock& getGameClock() { return *this->gameClock_; }
+
+        float getAvgTickTime() { return this->avgTickTime_; }
+        float getAvgFPS()      { return this->avgFPS_; }
+
+        void addTickTime(uint32_t length);
+
+        static bool addGameState(GameState* state);
+        static Game& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
+
+    private:
+        struct statisticsTickInfo
+        {
+            uint64_t    tickTime;
+            uint32_t    tickLength;
+        };
+
+        Game(Game&); // don't mess with singletons
+
+        void loadState(GameState* state);
+        void unloadState(GameState* state);
+
+        std::vector<GameState*>         activeStates_;
+        GameStateTreeNode*              rootStateNode_;
+        GameStateTreeNode*              activeStateNode_;
+        std::vector<GameStateTreeNode*> requestedStateNodes_;
+
+        Core*                           core_;
+        Clock*                          gameClock_;
+
+        bool                            abort_;
+
+        // variables for time statistics
+        uint64_t                        statisticsStartTime_;
+        std::list<statisticsTickInfo>   statisticsTickTimes_;
+        uint32_t                        periodTime_;
+        uint32_t                        periodTickTime_;
+        float                           avgFPS_;
+        float                           avgTickTime_;
+
+        // config values
+        unsigned int                    statisticsRefreshCycle_;
+        unsigned int                    statisticsAvgLength_;
+
+        static std::map<std::string, GameState*> allStates_s;
+        static Game* singletonRef_s;        //!< Pointer to the Singleton
+    };
+}
+
+#endif /* _Game_H__ */
Index: code/branches/questsystem5/src/core/GameMode.cc
===================================================================
--- code/branches/questsystem5/src/core/GameMode.cc	(revision 2907)
+++ code/branches/questsystem5/src/core/GameMode.cc	(revision 2907)
@@ -0,0 +1,43 @@
+/*
+ *   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 the GameMode class.
+*/
+
+#include "GameMode.h"
+
+namespace orxonox
+{
+    bool GameMode::bShowsGraphics_s = false;
+    bool GameMode::bHasServer_s     = false;
+    bool GameMode::bIsClient_s      = false;
+    bool GameMode::bIsStandalone_s  = false;
+    bool GameMode::bIsMaster_s      = false;
+}
Index: code/branches/questsystem5/src/core/GameMode.h
===================================================================
--- code/branches/questsystem5/src/core/GameMode.h	(revision 2907)
+++ code/branches/questsystem5/src/core/GameMode.h	(revision 2907)
@@ -0,0 +1,68 @@
+/*
+ *   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 Declaration of the GameMode class.
+*/
+
+#ifndef _GameMode_H__
+#define _GameMode_H__
+
+#include "CorePrereqs.h"
+
+namespace orxonox
+{
+    class _CoreExport GameMode
+    {
+        public:
+            static bool showsGraphics() { return bShowsGraphics_s; }
+            static bool hasServer()     { return bHasServer_s; }
+            static bool isClient()      { return bIsClient_s; }
+            static bool isStandalone()  { return bIsStandalone_s; }
+            static bool isMaster()      { return bIsMaster_s; }
+            static void setShowsGraphics(bool val) { bShowsGraphics_s = val; updateIsMaster(); }
+            static void setHasServer    (bool val) { bHasServer_s     = val; updateIsMaster(); }
+            static void setIsClient     (bool val) { bIsClient_s      = val; updateIsMaster(); }
+            static void setIsStandalone (bool val) { bIsStandalone_s  = val; updateIsMaster(); }
+            static void updateIsMaster  ()         { bIsMaster_s      = (bHasServer_s || bIsStandalone_s); }
+
+        private:
+            GameMode();
+            GameMode(const GameMode& inst);
+            ~GameMode();
+
+            static bool bShowsGraphics_s;                   //!< global variable that tells whether to show graphics
+            static bool bHasServer_s;                       //!< global variable that tells whether this is a server
+            static bool bIsClient_s;
+            static bool bIsStandalone_s;
+            static bool bIsMaster_s;
+    };
+}
+
+#endif /* _GameMode_H__ */
Index: code/branches/questsystem5/src/core/GameState.cc
===================================================================
--- code/branches/questsystem5/src/core/GameState.cc	(revision 2777)
+++ code/branches/questsystem5/src/core/GameState.cc	(revision 2907)
@@ -30,10 +30,12 @@
 @file
 @brief
-    Implementation of GameStateBase class.
+    Implementation of GameState class.
 */
 
 #include "GameState.h"
+#include <cassert>
 #include "util/Debug.h"
 #include "util/Exception.h"
+#include "Clock.h"
 
 namespace orxonox
@@ -43,12 +45,14 @@
         Constructor only initialises variables and sets the name permanently.
     */
-    GameStateBase::GameStateBase(const std::string& name)
+    GameState::GameState(const std::string& name)
         : name_(name)
-        //, parent_(0)
-        , activeChild_(0)
-        //, bPausegetParent()(false)
+        , parent_(0)
     {
-        Operations temp = {false, false, false, false, false};
-        this->operation_ = temp;
+        this->activity_.activating   = false;
+        this->activity_.active       = false;
+        this->activity_.deactivating = false;
+        this->activity_.suspended    = false;
+        this->activity_.topState     = false;
+        this->activity_.updating     = false;
     }
 
@@ -57,7 +61,7 @@
         Destructor only checks that we don't delete an active state.
     */
-    GameStateBase::~GameStateBase()
+    GameState::~GameState()
     {
-        OrxAssert(this->operation_.active == false, "Deleting an active GameState is a very bad idea..");
+        OrxAssert(this->activity_.active == false, "Deleting an active GameState is a very bad idea..");
     }
 
@@ -69,39 +73,19 @@
         The state to be added.
     */
-    void GameStateBase::addChild(GameStateBase* state)
+    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, GameStateBase*>::const_iterator it = state->allChildren_.begin();
-            it != state->allChildren_.end(); ++it)
+        assert(state != NULL);
+
+        std::map<std::string, GameState*>::const_iterator it = this->children_.find(state->getName());
+        if (it == this->children_.end())
         {
-            if (this->getState(it->second->getName()))
-            {
-                ThrowException(GameState, "Cannot add a GameState to the hierarchy twice.");
-                return;
-            }
+            this->children_[state->getName()] = state;
+            // mark us as parent
+            state->setParent(this);
         }
-        if (this->getState(state->name_))
+        else
         {
-            ThrowException(GameState, "Cannot add a GameState to the hierarchy twice.");
-            return;
+            ThrowException(GameState, "Cannot add two children with the same name");
         }
-        // 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, GameStateBase*>::const_iterator it = state->allChildren_.begin();
-            it != state->allChildren_.end(); ++it)
-            this->grandchildAdded(state, it->second);
-        // merge 'state' into this tree
-        this->grandchildAdded(state, state);
-
-        // mark us as parent
-        state->setParent(this);
     }
 
@@ -113,254 +97,41 @@
         GameState by instance pointer
     */
-    void GameStateBase::removeChild(GameStateBase* state)
+    void GameState::removeChild(GameState* state)
     {
-        std::map<GameStateBase*, GameStateBase*>::iterator it = this->grandchildrenToChildren_.find(state);
-        if (it != this->grandchildrenToChildren_.end())
-        {
-            if (state->isInSubtree(getCurrentState()))
-            {
-                ThrowException(GameState, "Cannot remove an active game state child '"
-                    + state->getName() + "' from '" + name_ + "'.");
-                //COUT(2) << "Warning: Cannot remove an active game state child '" << state->getName()
-                //    << "' from '" << name_ << "'." << std::endl;
-            }
-            else
-            {
-                for (std::map<GameStateBase*, GameStateBase*>::const_iterator it = state->grandchildrenToChildren_.begin();
-                    it != state->grandchildrenToChildren_.end(); ++it)
-                    this->grandchildRemoved(it->first);
-                this->grandchildRemoved(state);
-            }
-        }
+        assert(state != NULL);
+
+        std::map<std::string, GameState*>::iterator it = this->children_.find(state->getName());
+        if (it != this->children_.end())
+            this->children_.erase(it);
         else
         {
             ThrowException(GameState, "Game state '" + name_ + "' doesn't have a child named '"
                 + state->getName() + "'.");
-            //COUT(2) << "Warning: Game state '" << name_ << "' doesn't have a child named '"
-            //    << state->getName() << "'. Removal skipped." << std::endl;
         }
     }
 
-    /**
-    @brief
-        Removes a child by name. This splits the tree in two parts,
-        each of them functional on its own.
-    @param state
-        GameState by name
-    */
-
-    void GameStateBase::removeChild(const std::string& name)
+    void GameState::activateInternal()
     {
-        GameStateBase* state = getState(name);
-        if (state)
-        {
-            removeChild(state);
-        }
-        else
-        {
-            ThrowException(GameState, "GameState '" + name + "' doesn't exist.");
-            //COUT(2) << "Warning: GameState '" << name << "' doesn't exist." << std::endl;
-        }
+        this->activity_.activating = true;
+        this->activate();
+        this->activity_.activating = false;
+        this->activity_.active = true;
     }
 
-    /**
-    @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.
-    */
-    inline void GameStateBase::grandchildAdded(GameStateBase* child, GameStateBase* grandchild)
+    void GameState::deactivateInternal()
     {
-        // fill the two maps correctly.
-        this->allChildren_[grandchild->getName()] = grandchild;
-        this->grandchildrenToChildren_[grandchild] = child;
-        if (this->getParent())
-            this->getParent()->grandchildAdded(this, grandchild);
+        this->activity_.active = false;
+        this->activity_.deactivating = true;
+        this->activate();
+        this->activity_.deactivating = false;
+        this->activity_.suspended = false;
+        this->activity_.updating = false;
     }
 
-    /**
-    @brief
-        Tells a state that one of its children has removed 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 removed.
-    */
-    inline void GameStateBase::grandchildRemoved(GameStateBase* grandchild)
+    void GameState::updateInternal(const Clock& time)
     {
-        // adjust the two maps correctly.
-        this->allChildren_.erase(grandchild->getName());
-        this->grandchildrenToChildren_.erase(grandchild);
-        if (this->getParent())
-            this->getParent()->grandchildRemoved(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.
-    */
-    GameStateBase* GameStateBase::getState(const std::string& name)
-    {
-        if (this->getParent())
-            return this->getParent()->getState(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, GameStateBase*>::const_iterator it = this->allChildren_.find(name);
-            return (it!= this->allChildren_.end() ? it->second : 0);
-        }
-    }
-
-    /**
-    @brief
-        Returns the root node of the tree.
-    */
-    GameStateBase* GameStateBase::getRoot()
-    {
-        if (this->getParent())
-            return this->getParent()->getRoot();
-        else
-            return this;
-    }
-
-    /**
-    @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.
-    */
-    GameStateBase* GameStateBase::getCurrentState()
-    {
-        if (this->operation_.active)
-        {
-            if (this->activeChild_)
-                return this->activeChild_->getCurrentState();
-            else
-                return this;
-        }
-        else
-        {
-            if (this->getParent())
-                return this->getParent()->getCurrentState();
-            else
-                return 0;
-        }
-    }
-
-    /**
-    @brief
-        Determines whether 'state' is in this subtree, including this node.
-    */
-    bool GameStateBase::isInSubtree(GameStateBase* state) const
-    {
-        return (grandchildrenToChildren_.find(state) != grandchildrenToChildren_.end()
-                || state == 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 GameStateBase::requestState(const std::string& name)
-    {
-        assert(getRoot());
-        getRoot()->requestState(name);
-    }
-
-    /**
-    @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 GameStateBase::makeTransition(GameStateBase* source, GameStateBase* destination)
-    {
-        if (source == this->getParent())
-        {
-            // call is from the parent
-            this->activate();
-        }
-        else if (source == 0)
-        {
-            // call was just started by root
-            // don't do anyting yet
-        }
-        else
-        {
-            // call is from a child
-            this->activeChild_ = 0;
-        }
-
-        if (destination == this)
-            return;
-
-        // Check for 'destination' in the children map first
-        std::map<GameStateBase*, GameStateBase*>::const_iterator it
-            = this->grandchildrenToChildren_.find(destination);
-        if (it != this->grandchildrenToChildren_.end())
-        {
-            // child state. Don't use 'state', might be a grandchild!
-            this->activeChild_ = it->second;
-            it->second->makeTransition(this, destination);
-        }
-        else
-        {
-            // parent. We can be sure of this.
-            assert(this->getParent() != 0);
-
-            this->deactivate();
-            this->getParent()->makeTransition(this, destination);
-        }
-    }
-
-    /**
-    @brief
-        Activates the state. Only sets bActive_ to true and notifies the parent.
-    */
-    void GameStateBase::activate()
-    {
-        this->operation_.active = true;
-        this->operation_.entering = true;
-        this->enter();
-        this->operation_.entering = false;
-    }
-
-    /**
-        Activates the state. Only sets bActive_ to false and notifies the parent.
-    */
-    void GameStateBase::deactivate()
-    {
-        this->operation_.leaving = true;
-        this->leave();
-        this->operation_.leaving = false;
-        this->operation_.active = false;
-    }
-
-    /**
-    @brief
-        Update method that calls ticked() with enclosed bRunning_ = true
-        If there was a state transition request within ticked() then this
-        method will transition in the end.
-    @param dt Delta time
-    @note
-        This method is not virtual! You cannot override it therefore.
-    */
-    void GameStateBase::tick(const Clock& time)
-    {
-        this->operation_.running = true;
-        this->ticked(time);
-        this->operation_.running = false;
+        this->activity_.updating = true;
+        this->update(time);
+        this->activity_.updating = false;
     }
 }
Index: code/branches/questsystem5/src/core/GameState.h
===================================================================
--- code/branches/questsystem5/src/core/GameState.h	(revision 2777)
+++ code/branches/questsystem5/src/core/GameState.h	(revision 2907)
@@ -39,8 +39,6 @@
 
 #include <string>
-#include <vector>
 #include <map>
-#include <cassert>
-#include "Clock.h"
+#include "CorePrereqs.h"
 
 namespace orxonox
@@ -60,9 +58,7 @@
         Then Bar stores Foo in map by its name. The other one then maps Foo to Foofoo.
     */
-    class _CoreExport GameStateBase
+    class _CoreExport GameState
     {
-        friend class RootGameState;
-        template <class ParentType>
-        friend class GameState;
+        friend class Game;
 
     public:
@@ -71,89 +67,41 @@
             Gives information about what the GameState is currently doing
         */
-        struct Operations
+        struct State
         {
-            unsigned active    : 1;
-            unsigned entering  : 1;
-            unsigned leaving   : 1;
-            unsigned running   : 1;
-            unsigned suspended : 1;
+            unsigned active       : 1;
+            unsigned activating   : 1;
+            unsigned deactivating : 1;
+            unsigned updating     : 1;
+            unsigned suspended    : 1;
+            unsigned topState     : 1;
         };
 
     public:
-        virtual ~GameStateBase();
+        GameState(const std::string& name);
+        virtual ~GameState();
 
         const std::string& getName() const { return name_; }
-        const Operations getOperation() const { return this->operation_; }
-        bool isInSubtree(GameStateBase* state) const;
+        State getActivity() const    { return this->activity_; }
+        GameState* getParent() const       { return this->parent_; }
 
-        GameStateBase* getState(const std::string& name);
-        GameStateBase* getRoot();
-        //! Returns the currently active game state
-        virtual GameStateBase* getCurrentState();
-
-        virtual void requestState(const std::string& name);
-
-        void addChild(GameStateBase* state);
-        void removeChild(GameStateBase* state);
-        void removeChild(const std::string& name);
+        void addChild(GameState* state);
+        void removeChild(GameState* state);
 
     protected:
-        virtual void enter() = 0;
-        virtual void leave() = 0;
-        virtual void ticked(const Clock& time) = 0;
-
-        GameStateBase* getActiveChild() { return this->activeChild_; }
-
-        void tickChild(const Clock& time) { if (this->getActiveChild()) this->getActiveChild()->tick(time); }
-
-        virtual GameStateBase* getParent() const = 0;
-        virtual void setParent(GameStateBase* state) = 0;
+        virtual void activate() = 0;
+        virtual void deactivate() = 0;
+        virtual void update(const Clock& time) = 0;
 
     private:
-        // Making the constructor private ensures that game states
-        // are always derivates of GameState<T>. Note the friend declaration above.
-        GameStateBase(const std::string& name);
-
-        //! Performs a transition to 'destination'
-        virtual void makeTransition(GameStateBase* source, GameStateBase* destination);
-
-        void grandchildAdded(GameStateBase* child, GameStateBase* grandchild);
-        void grandchildRemoved(GameStateBase* grandchild);
-
-        void tick(const Clock& time);
-        void activate();
-        void deactivate();
+        void setParent(GameState* state) { this->parent_ = state; }
+        void setActivity(State activity);
+        void activateInternal();
+        void deactivateInternal();
+        void updateInternal(const Clock& time);
 
         const std::string                        name_;
-        Operations                               operation_;
-        GameStateBase*                           activeChild_;
-        //bool                                     bPauseParent_;
-        std::map<std::string, GameStateBase*>    allChildren_;
-        std::map<GameStateBase*, GameStateBase*> grandchildrenToChildren_;
-    };
-
-
-    template <class ParentType>
-    class GameState : public GameStateBase
-    {
-    public:
-        GameState(const std::string& name)
-            : GameStateBase(name)
-            , parent_(0)
-        { }
-        virtual ~GameState() { }
-
-        ParentType* getParent() const
-            { return parent_; }
-
-    protected:
-        void setParent(GameStateBase* state)
-        {
-            assert(dynamic_cast<ParentType*>(state) != 0);
-            this->parent_ = dynamic_cast<ParentType*>(state);
-        }
-
-    private:
-        ParentType* parent_;
+        State                                    activity_;
+        GameState*                               parent_;
+        std::map<std::string, GameState*>        children_;
     };
 }
Index: code/branches/questsystem5/src/core/Identifier.h
===================================================================
--- code/branches/questsystem5/src/core/Identifier.h	(revision 2777)
+++ code/branches/questsystem5/src/core/Identifier.h	(revision 2907)
@@ -357,9 +357,9 @@
             static ClassIdentifier<T> *getIdentifier(const std::string& name);
             void addObject(T* object);
-            static bool isFirstCall();
 
             void updateConfigValues(bool updateChildren = true) const;
 
         private:
+            static void initialiseIdentifier();
             ClassIdentifier(const ClassIdentifier<T>& identifier) {}    // don't copy
             ClassIdentifier()
@@ -376,70 +376,56 @@
 
     template <class T>
-    ClassIdentifier<T>* ClassIdentifier<T>::classIdentifier_s;
-
-    /**
-        @brief Returns true if the function gets called the first time, false otherwise.
-        @return True if this function got called the first time.
-    */
-    template <class T>
-    bool ClassIdentifier<T>::isFirstCall()
-    {
-        static bool bFirstCall = true;
-
-        if (bFirstCall)
+    ClassIdentifier<T>* ClassIdentifier<T>::classIdentifier_s = 0;
+
+    /**
+        @brief Returns the only instance of this class.
+        @return The unique Identifier
+    */
+    template <class T>
+    ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
+    {
+        // check if the static field has already been filled
+        if (ClassIdentifier<T>::classIdentifier_s == 0)
+            ClassIdentifier<T>::initialiseIdentifier();
+
+        return ClassIdentifier<T>::classIdentifier_s;
+    }
+
+    /**
+        @brief Does the same as getIdentifier() but sets the name if this wasn't done yet.
+        @param name The name of this Identifier
+        @return The Identifier
+    */
+    template <class T>
+    ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier(const std::string& name)
+    {
+        ClassIdentifier<T>* identifier = ClassIdentifier<T>::getIdentifier();
+        identifier->setName(name);
+        return identifier;
+    }
+
+    /**
+        @brief Assigns the static field for the identifier singleton.
+    */
+    template <class T>
+    void ClassIdentifier<T>::initialiseIdentifier()
+    {
+        // Get the name of the class
+        std::string name = typeid(T).name();
+
+        // create a new identifier anyway. Will be deleted in Identifier::getIdentifier if not used.
+        ClassIdentifier<T>* proposal = new ClassIdentifier<T>();
+
+        // Get the entry from the map
+        ClassIdentifier<T>::classIdentifier_s = (ClassIdentifier<T>*)Identifier::getIdentifierSingleton(name, proposal);
+
+        if (ClassIdentifier<T>::classIdentifier_s == proposal)
         {
-            bFirstCall = false;
-            return true;
+            COUT(4) << "*** Identifier: Requested Identifier for " << name << " was not yet existing and got created." << std::endl;
         }
         else
         {
-            return false;
+            COUT(4) << "*** Identifier: Requested Identifier for " << name << " was already existing and got assigned." << std::endl;
         }
-    }
-
-    /**
-        @brief Returns the only instance of this class.
-        @return The unique Identifier
-    */
-    template <class T>
-    ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
-    {
-        // check if the static field has already been filled
-        if (ClassIdentifier<T>::isFirstCall())
-        {
-            // Get the name of the class
-            std::string name = typeid(T).name();
-
-            // create a new identifier anyway. Will be deleted in Identifier::getIdentifier if not used.
-            ClassIdentifier<T>* proposal = new ClassIdentifier<T>();
-
-            // Get the entry from the map
-            ClassIdentifier<T>::classIdentifier_s = (ClassIdentifier<T>*)Identifier::getIdentifierSingleton(name, proposal);
-
-            if (ClassIdentifier<T>::classIdentifier_s == proposal)
-            {
-                COUT(4) << "*** Identifier: Requested Identifier for " << name << " was not yet existing and got created." << std::endl;
-            }
-            else
-            {
-                COUT(4) << "*** Identifier: Requested Identifier for " << name << " was already existing and got assigned." << std::endl;
-            }
-        }
-
-        // Finally return the unique ClassIdentifier
-        return ClassIdentifier<T>::classIdentifier_s;
-    }
-
-    /**
-        @brief Does the same as getIdentifier() but sets the name if this wasn't done yet.
-        @param name The name of this Identifier
-        @return The Identifier
-    */
-    template <class T>
-    ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier(const std::string& name)
-    {
-        ClassIdentifier<T>* identifier = ClassIdentifier<T>::getIdentifier();
-        identifier->setName(name);
-        return identifier;
     }
 
Index: code/branches/questsystem5/src/core/Iterator.h
===================================================================
--- code/branches/questsystem5/src/core/Iterator.h	(revision 2777)
+++ code/branches/questsystem5/src/core/Iterator.h	(revision 2907)
@@ -75,5 +75,5 @@
                 this->element_ = exp.element_;
                 this->list_ = exp.list_;
-                this->iterator_ = this->list_->registerIterator(this);
+                this->list_->registerIterator(this);
             }
 
@@ -86,5 +86,5 @@
                 this->element_ = other.element_;
                 this->list_ = other.list_;
-                this->iterator_ = this->list_->registerIterator(this);
+                this->list_->registerIterator(this);
             }
 
@@ -98,5 +98,5 @@
                 this->element_ = (element) ? static_cast<ObjectListBaseElement*>(element) : 0;
                 this->list_ = ClassIdentifier<O>::getIdentifier()->getObjects();
-                this->iterator_ = this->list_->registerIterator(this);
+                this->list_->registerIterator(this);
             }
 
@@ -110,5 +110,5 @@
                 this->element_ = (other.element_) ? static_cast<ObjectListBaseElement*>(other.element_) : 0;
                 this->list_ = ClassIdentifier<O>::getIdentifier()->getObjects();
-                this->iterator_ = this->list_->registerIterator(this);
+                this->list_->registerIterator(this);
             }
 
@@ -118,5 +118,5 @@
             inline ~Iterator()
             {
-                this->list_->unregisterIterator(this->iterator_);
+                this->list_->unregisterIterator(this);
             }
 
@@ -128,9 +128,9 @@
             {
                 if (this->list_)
-                    this->list_->unregisterIterator(this->iterator_);
+                    this->list_->unregisterIterator(this);
 
                 this->element_ = exp.element_;
                 this->list_ = exp.list_;
-                this->iterator_ = this->list_->registerIterator(this);
+                this->list_->registerIterator(this);
 
                 return (*this);
@@ -144,9 +144,9 @@
             {
                 if (this->list_)
-                    this->list_->unregisterIterator(this->iterator_);
+                    this->list_->unregisterIterator(this);
 
                 this->element_ = other.element_;
                 this->list_ = other.list_;
-                this->iterator_ = this->list_->registerIterator(this);
+                this->list_->registerIterator(this);
 
                 return (*this);
@@ -161,9 +161,9 @@
             {
                 if (this->list_)
-                    this->list_->unregisterIterator(this->iterator_);
+                    this->list_->unregisterIterator(this);
 
                 this->element_ = (element) ? static_cast<ObjectListBaseElement*>(element) : 0;
                 this->list_ = ClassIdentifier<O>::getIdentifier()->getObjects();
-                this->iterator_ = this->list_->registerIterator(this);
+                this->list_->registerIterator(this);
 
                 return (*this);
@@ -179,9 +179,9 @@
             {
                 if (this->list_)
-                    this->list_->unregisterIterator(this->iterator_);
-
-                this->element_ = (other.element_) ? (ObjectListBaseElement*)other.element_ : 0;
+                    this->list_->unregisterIterator(this);
+
+                this->element_ = (other.element_) ? static_cast<ObjectListBaseElement*>(other.element_) : 0;
                 this->list_ = ClassIdentifier<O>::getIdentifier()->getObjects();
-                this->iterator_ = this->list_->registerIterator(this);
+                this->list_->registerIterator(this);
 
                 return (*this);
@@ -300,5 +300,4 @@
             ObjectListBaseElement* element_;       //!< The element the Iterator points at
             ObjectListBase* list_;                 //!< The list wherein the element is
-            std::list<void*>::iterator iterator_;  //!< The iterator in the notifying list of the ObjectList
     };
 
Index: code/branches/questsystem5/src/core/ObjectListBase.cc
===================================================================
--- code/branches/questsystem5/src/core/ObjectListBase.cc	(revision 2777)
+++ code/branches/questsystem5/src/core/ObjectListBase.cc	(revision 2907)
@@ -75,7 +75,7 @@
     void ObjectListBase::notifyIterators(OrxonoxClass* object) const
     {
-        for (std::list<void*>::const_iterator it = this->iterators_.begin(); it != this->iterators_.end(); ++it)
+        for (std::vector<void*>::const_iterator it = this->iterators_.begin(); it != this->iterators_.end(); ++it)
             ((Iterator<OrxonoxClass>*)(*it))->incrementIfEqual(object);
-        for (std::list<void*>::const_iterator it = this->objectListIterators_.begin(); it != this->objectListIterators_.end(); ++it)
+        for (std::vector<void*>::const_iterator it = this->objectListIterators_.begin(); it != this->objectListIterators_.end(); ++it)
             ((ObjectListIterator<OrxonoxClass>*)(*it))->incrementIfEqual(object);
     }
Index: code/branches/questsystem5/src/core/ObjectListBase.h
===================================================================
--- code/branches/questsystem5/src/core/ObjectListBase.h	(revision 2777)
+++ code/branches/questsystem5/src/core/ObjectListBase.h	(revision 2907)
@@ -38,5 +38,5 @@
 #define _ObjectListBase_H__
 
-#include <list>
+#include <vector>
 
 #include "CorePrereqs.h"
@@ -71,5 +71,5 @@
     {
         public:
-            ObjectListElement(T* object) : ObjectListBaseElement((OrxonoxClass*)object), object_(object) {}
+            ObjectListElement(T* object) : ObjectListBaseElement(static_cast<OrxonoxClass*>(object)), object_(object) {}
             T* object_;              //!< The object
     };
@@ -110,8 +110,28 @@
             inline Export rend() { return ObjectListBase::Export(this, 0); }
 
-            inline std::list<void*>::iterator registerIterator(void* iterator) { return this->iterators_.insert(this->iterators_.begin(), iterator); }
-            inline void unregisterIterator(const std::list<void*>::iterator& iterator) { this->iterators_.erase(iterator); }
-            inline std::list<void*>::iterator registerObjectListIterator(void* iterator) { return this->objectListIterators_.insert(this->objectListIterators_.begin(), iterator); }
-            inline void unregisterObjectListIterator(const std::list<void*>::iterator& iterator) { this->objectListIterators_.erase(iterator); }
+            inline void registerIterator(void* iterator) { this->iterators_.push_back(iterator); }
+            inline void unregisterIterator(void* iterator)
+            {
+                for (unsigned int i = 0; i < this->iterators_.size(); ++i)
+                {
+                    if (iterators_[i] == iterator)
+                    {
+                        iterators_.erase(iterators_.begin() + i);
+                        break;
+                    }
+                }
+            }
+            inline void registerObjectListIterator(void* iterator) { this->objectListIterators_.push_back(iterator); }
+            inline void unregisterObjectListIterator(void* iterator)
+            {
+                for (unsigned int i = 0; i < this->objectListIterators_.size(); ++i)
+                {
+                    if (objectListIterators_[i] == iterator)
+                    {
+                        objectListIterators_.erase(objectListIterators_.begin() + i);
+                        break;
+                    }
+                }
+            }
             void notifyIterators(OrxonoxClass* object) const;
 
@@ -122,6 +142,6 @@
             ObjectListBaseElement* first_;         //!< The first element in the list
             ObjectListBaseElement* last_;          //!< The last element in the list
-            std::list<void*> iterators_;           //!< A list of Iterators pointing on an element in this list
-            std::list<void*> objectListIterators_; //!< A list of ObjectListIterators pointing on an element in this list
+            std::vector<void*> iterators_;           //!< A list of Iterators pointing on an element in this list
+            std::vector<void*> objectListIterators_; //!< A list of ObjectListIterators pointing on an element in this list
     };
 }
Index: code/branches/questsystem5/src/core/ObjectListIterator.h
===================================================================
--- code/branches/questsystem5/src/core/ObjectListIterator.h	(revision 2777)
+++ code/branches/questsystem5/src/core/ObjectListIterator.h	(revision 2907)
@@ -65,5 +65,5 @@
             {
                 this->element_ = 0;
-                this->iterator_ = ClassIdentifier<T>::getIdentifier()->getObjects()->registerObjectListIterator(this);
+                ClassIdentifier<T>::getIdentifier()->getObjects()->registerObjectListIterator(this);
             }
 
@@ -75,5 +75,5 @@
             {
                 this->element_ = element;
-                this->iterator_ = ClassIdentifier<T>::getIdentifier()->getObjects()->registerObjectListIterator(this);
+                ClassIdentifier<T>::getIdentifier()->getObjects()->registerObjectListIterator(this);
             }
 
@@ -85,5 +85,5 @@
             {
                 this->element_ = other.element_;
-                this->iterator_ = ClassIdentifier<T>::getIdentifier()->getObjects()->registerObjectListIterator(this);
+                ClassIdentifier<T>::getIdentifier()->getObjects()->registerObjectListIterator(this);
             }
 
@@ -93,5 +93,5 @@
             inline ~ObjectListIterator()
             {
-                ClassIdentifier<T>::getIdentifier()->getObjects()->unregisterObjectListIterator(this->iterator_);
+                ClassIdentifier<T>::getIdentifier()->getObjects()->unregisterObjectListIterator(this);
             }
 
@@ -227,5 +227,4 @@
         private:
             ObjectListElement<T>* element_;        //!< The element the Iterator points at
-            std::list<void*>::iterator iterator_;  //!< The iterator in the notifying list of the ObjectList
     };
 }
Index: code/branches/questsystem5/src/core/RootGameState.cc
===================================================================
--- code/branches/questsystem5/src/core/RootGameState.cc	(revision 2777)
+++ 	(revision )
@@ -1,178 +1,0 @@
-/*
- *   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:
- *      ...
- *
- */
-
-#include "RootGameState.h"
-
-#include "util/Debug.h"
-#include "util/Exception.h"
-#include "Clock.h"
-#include "CommandLine.h"
-
-namespace orxonox
-{
-    SetCommandLineArgument(state, "gui").shortcut("s");
-
-    RootGameState::RootGameState(const std::string& name)
-        : GameState<GameStateBase>(name)
-        , stateRequest_("")
-    {
-    }
-
-    RootGameState::~RootGameState()
-    {
-    }
-
-    /**
-    @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 RootGameState::makeTransition(GameStateBase* source, GameStateBase* destination)
-    {
-        if (source != 0)
-        {
-            // transition was not initiated by root itself
-            this->activeChild_ = 0;
-        }
-
-        if (destination == this)
-        {
-            // this marks the end of the game.
-            return;
-        }
-
-        // Check for 'destination' in the children map first
-        std::map<GameStateBase*, GameStateBase*>::const_iterator it
-            = this->grandchildrenToChildren_.find(destination);
-        if (it != this->grandchildrenToChildren_.end())
-        {
-            OrxAssert(dynamic_cast<GameStateBase*>(it->second) != 0,
-                "There was a mix with RootGameState and GameState, could not cast.");
-            GameStateBase* child = static_cast<GameStateBase*>(it->second);
-            // child state. Don't use 'state', might be a grandchild!
-            this->activeChild_ = child;
-            child->makeTransition(this, destination);
-        }
-        else
-        {
-            // root doesn't have a parent..
-            OrxAssert(false, "GameState '" + destination->getName() + "' not found in children list of Root.");
-        }
-    }
-
-    void RootGameState::gotoState(const std::string& name)
-    {
-        GameStateBase* request = getState(name);
-        if (request)
-        {
-            GameStateBase* current = getCurrentState();
-            if (current)
-            {
-                current->makeTransition(0, request);
-            }
-            else
-            {
-                // Root is not yet active. This is a violation.
-                ThrowException(GameState, "Activate Root before requesting a state.");
-            }
-        }
-        else
-        {
-            COUT(2) << "Warning: GameState '" << name << "' doesn't exist." << std::endl;
-        }
-    }
-
-    /**
-    @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 RootGameState::requestState(const std::string& name)
-    {
-        this->stateRequest_ = name;
-    }
-
-    /**
-    @brief
-        Main loop of the orxonox game.
-        Starts the game. The little 'while' denotes the main loop.
-        Whenever the root state is selected, the game ends.
-    @param name
-        State to start with (usually main menu or specified by command line)
-    @note
-        We use the Ogre::Timer to measure time since it uses the most precise
-        method an a platform (however the windows timer lacks time when under
-        heavy kernel load!).
-    */
-    void RootGameState::start()
-    {
-        // Don't catch errors when having a debugger in msvc
-#if !defined(ORXONOX_COMPILER_MSVC) || defined(NDEBUG)
-        try
-        {
-#endif
-            // start global orxonox time
-            Clock clock;
-
-            this->activate();
-
-            // get initial state from command line
-            gotoState(CommandLine::getValue("state"));
-
-            while (this->activeChild_)
-            {
-                clock.capture();
-
-                this->tick(clock);
-
-                if (this->stateRequest_ != "")
-                    gotoState(stateRequest_);
-            }
-
-            this->deactivate();
-#if !defined(ORXONOX_COMPILER_MSVC) || defined(NDEBUG)
-        }
-        // Note: These are all unhandled exceptions that should not have made its way here!
-        // almost complete game catch block to display the messages appropriately.
-        catch (std::exception& ex)
-        {
-            COUT(0) << ex.what() << std::endl;
-            COUT(0) << "Program aborted." << std::endl;
-            abort();
-        }
-        // anything that doesn't inherit from std::exception
-        catch (...)
-        {
-            COUT(0) << "An unidentifiable exception has occured. Program aborted." << std::endl;
-            abort();
-        }
-#endif
-    }
-}
Index: code/branches/questsystem5/src/core/RootGameState.h
===================================================================
--- code/branches/questsystem5/src/core/RootGameState.h	(revision 2777)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- *   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:
- *      ...
- *
- */
-
-#ifndef _RootGameState_H__
-#define _RootGameState_H__
-
-#include "CorePrereqs.h"
-#include "GameState.h"
-
-namespace orxonox
-{
-    class _CoreExport RootGameState : public GameState<GameStateBase>
-    {
-    public:
-        RootGameState(const std::string& name);
-        ~RootGameState();
-
-        void requestState(const std::string& name);
-        void start();
-
-    private:
-        void makeTransition(GameStateBase* source, GameStateBase* destination);
-        void gotoState(const std::string& name);
-
-        std::string stateRequest_;
-    };
-}
-
-#endif /* _RootGameState_H__ */
Index: code/branches/questsystem5/src/core/TclThreadManager.cc
===================================================================
--- code/branches/questsystem5/src/core/TclThreadManager.cc	(revision 2777)
+++ code/branches/questsystem5/src/core/TclThreadManager.cc	(revision 2907)
@@ -35,4 +35,5 @@
 #include <OgreTimer.h>
 
+#include "Clock.h"
 #include "CoreIncludes.h"
 #include "ConsoleCommand.h"
@@ -598,5 +599,5 @@
     }
 
-    void TclThreadManager::tick(float dt)
+    void TclThreadManager::update(const Clock& time)
     {
         {
@@ -633,5 +634,5 @@
             boost::try_mutex::scoped_lock interpreter_lock(this->orxonoxInterpreterBundle_.interpreterMutex_);
 #endif
-            unsigned long maxtime = (unsigned long)(dt * 1000000 * TCLTHREADMANAGER_MAX_CPU_USAGE);
+            unsigned long maxtime = (unsigned long)(time.getDeltaTime() * 1000000 * TCLTHREADMANAGER_MAX_CPU_USAGE);
             Ogre::Timer timer;
             while (!this->queueIsEmpty())
Index: code/branches/questsystem5/src/core/TclThreadManager.h
===================================================================
--- code/branches/questsystem5/src/core/TclThreadManager.h	(revision 2777)
+++ code/branches/questsystem5/src/core/TclThreadManager.h	(revision 2907)
@@ -90,5 +90,5 @@
             void debug(const std::string& error);
 
-            virtual void tick(float dt);
+            void update(const Clock& time);
 
             std::list<unsigned int> getThreadList() const;
Index: code/branches/questsystem5/src/core/Template.cc
===================================================================
--- code/branches/questsystem5/src/core/Template.cc	(revision 2777)
+++ code/branches/questsystem5/src/core/Template.cc	(revision 2907)
@@ -65,5 +65,5 @@
         if (element)
         {
-            TiXmlElement* tixmlelement = dynamic_cast<TiXmlElement*>(element->GetTiXmlPointer());
+            TiXmlElement* tixmlelement = static_cast<TiXmlElement*>(element->GetTiXmlPointer());
             if (tixmlelement)
                 this->setXMLElement(*tixmlelement);
@@ -138,5 +138,5 @@
         COUT(4) << object->getLoaderIndentation() << " aplying Template \"" << this->getName() << "\"..." << std::endl;
 
-        Element temp = ((TiXmlElement*)&this->getXMLElement());
+        Element temp = &const_cast<TiXmlElement&>(this->getXMLElement());
 
         if (this->bLoadDefaults_)
Index: code/branches/questsystem5/src/core/XMLPort.h
===================================================================
--- code/branches/questsystem5/src/core/XMLPort.h	(revision 2777)
+++ code/branches/questsystem5/src/core/XMLPort.h	(revision 2907)
@@ -556,9 +556,9 @@
                                                 try
                                                 {
-                                                    COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "fabricating " << child->Value() << "..." << std::endl;
+                                                    COUT(4) << object->getLoaderIndentation() << "fabricating " << child->Value() << "..." << std::endl;
 
                                                     BaseObject* newObject = identifier->fabricate((BaseObject*)object);
                                                     assert(newObject);
-                                                    newObject->setLoaderIndentation(((BaseObject*)object)->getLoaderIndentation() + "  ");
+                                                    newObject->setLoaderIndentation(object->getLoaderIndentation() + "  ");
 
                                                     O* castedObject = dynamic_cast<O*>(newObject);
@@ -568,12 +568,12 @@
                                                     {
                                                         newObject->XMLPort(*child, XMLPort::LoadObject);
-                                                        COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl;
+                                                        COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl;
                                                     }
                                                     else
                                                     {
-                                                        COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl;
+                                                        COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << this->identifier_->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl;
                                                     }
 
-                                                    COUT(5) << ((BaseObject*)object)->getLoaderIndentation();
+                                                    COUT(5) << object->getLoaderIndentation();
                                                     (*this->loadexecutor_)(object, castedObject);
 
@@ -581,5 +581,5 @@
                                                         newObject->XMLPort(*child, XMLPort::LoadObject);
 
-                                                    COUT(5) << ((BaseObject*)object)->getLoaderIndentation() << "...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl;
+                                                    COUT(5) << object->getLoaderIndentation() << "...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl;
                                                 }
                                                 catch (AbortLoadingException& ex)
@@ -601,10 +601,10 @@
                                         else
                                         {
-                                            COUT(2) << ((BaseObject*)object)->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not loadable." << std::endl;
+                                            COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not loadable." << std::endl;
                                         }
                                     }
                                     else
                                     {
-                                        COUT(2) << ((BaseObject*)object)->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a '" << Class(O)->getName() << "'." << std::endl;
+                                        COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a '" << Class(O)->getName() << "'." << std::endl;
                                     }
                                 }
@@ -626,5 +626,5 @@
                     {
                         COUT(1) << std::endl;
-                        COUT(1) << "An error occurred in XMLPort.h while loading a '" << Class(O)->getName() << "' in '" << this->sectionname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << ((BaseObject*)object)->getName() << ") in " << object->getFilename() << ":" << std::endl;
+                        COUT(1) << "An error occurred in XMLPort.h while loading a '" << Class(O)->getName() << "' in '" << this->sectionname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << object->getName() << ") in " << object->getFilename() << ":" << std::endl;
                         COUT(1) << ex.what() << std::endl;
                     }
Index: code/branches/questsystem5/src/core/input/CalibratorCallback.h
===================================================================
--- code/branches/questsystem5/src/core/input/CalibratorCallback.h	(revision 2777)
+++ code/branches/questsystem5/src/core/input/CalibratorCallback.h	(revision 2907)
@@ -52,5 +52,5 @@
         void keyHeld    (const KeyEvent& evt) { }
 
-        void tickInput(float dt) { }
+        void updateInput(float dt) { }
     };
 }
Index: code/branches/questsystem5/src/core/input/ExtendedInputState.cc
===================================================================
--- code/branches/questsystem5/src/core/input/ExtendedInputState.cc	(revision 2777)
+++ code/branches/questsystem5/src/core/input/ExtendedInputState.cc	(revision 2907)
@@ -402,13 +402,13 @@
     }
 
-    void ExtendedInputState::tickInput(float dt)
+    void ExtendedInputState::updateInput(float dt)
     {
         for (unsigned int i = 0; i < allHandlers_.size(); ++i)
         {
-            allHandlers_[i]->tickInput(dt);
-        }
-    }
-
-    void ExtendedInputState::tickInput(float dt, unsigned int device)
+            allHandlers_[i]->updateInput(dt);
+        }
+    }
+
+    void ExtendedInputState::updateInput(float dt, unsigned int device)
     {
         switch (device)
@@ -416,15 +416,15 @@
         case Keyboard:
             for (unsigned int i = 0; i < keyHandlers_.size(); ++i)
-                keyHandlers_[i]->tickKey(dt);
+                keyHandlers_[i]->updateKey(dt);
             break;
 
         case Mouse:
             for (unsigned int i = 0; i < mouseHandlers_.size(); ++i)
-                mouseHandlers_[i]->tickMouse(dt);
+                mouseHandlers_[i]->updateMouse(dt);
             break;
 
         default: // joy sticks
             for (unsigned int i = 0; i < joyStickHandlers_[device - 2].size(); ++i)
-                joyStickHandlers_[device - 2][i]->tickJoyStick(dt, device - 2);
+                joyStickHandlers_[device - 2][i]->updateJoyStick(dt, device - 2);
             break;
         }
Index: code/branches/questsystem5/src/core/input/ExtendedInputState.h
===================================================================
--- code/branches/questsystem5/src/core/input/ExtendedInputState.h	(revision 2777)
+++ code/branches/questsystem5/src/core/input/ExtendedInputState.h	(revision 2907)
@@ -68,6 +68,6 @@
         ~ExtendedInputState() { }
 
-        void tickInput(float dt);
-        void tickInput(float dt, unsigned int device);
+        void updateInput(float dt);
+        void updateInput(float dt, unsigned int device);
 
         void keyPressed (const KeyEvent& evt);
Index: code/branches/questsystem5/src/core/input/InputBuffer.cc
===================================================================
--- code/branches/questsystem5/src/core/input/InputBuffer.cc	(revision 2777)
+++ code/branches/questsystem5/src/core/input/InputBuffer.cc	(revision 2907)
@@ -224,8 +224,8 @@
 
     /**
-        @brief This tick() function is called by the InputManager if the InputBuffer is active.
+        @brief This update() function is called by the InputManager if the InputBuffer is active.
         @param dt Delta time
     */
-    void InputBuffer::tickInput(float dt)
+    void InputBuffer::updateInput(float dt)
     {
         timeSinceKeyPressed_ += dt;
Index: code/branches/questsystem5/src/core/input/InputBuffer.h
===================================================================
--- code/branches/questsystem5/src/core/input/InputBuffer.h	(revision 2777)
+++ code/branches/questsystem5/src/core/input/InputBuffer.h	(revision 2907)
@@ -127,5 +127,5 @@
                 for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); )
                 {
-                    InputBufferListenerTuple<T>* refListener = dynamic_cast<InputBufferListenerTuple<T>*>(*it);
+                    InputBufferListenerTuple<T>* refListener = static_cast<InputBufferListenerTuple<T>*>(*it);
                     if (refListener && refListener->listener_ == listener)
                         this->listeners_.erase(it++);
@@ -171,6 +171,6 @@
             void processKey (const KeyEvent &e);
 
-            void tickInput(float dt);
-            void tickKey(float dt) { }
+            void updateInput(float dt);
+            void updateKey(float dt) { }
 
             std::string buffer_;
Index: code/branches/questsystem5/src/core/input/InputInterfaces.h
===================================================================
--- code/branches/questsystem5/src/core/input/InputInterfaces.h	(revision 2777)
+++ code/branches/questsystem5/src/core/input/InputInterfaces.h	(revision 2907)
@@ -474,5 +474,5 @@
     public:
         virtual ~InputHandler() { }
-        virtual void tickInput(float dt) = 0;
+        virtual void updateInput(float dt) = 0;
     };
 
@@ -488,5 +488,5 @@
         virtual void keyReleased(const KeyEvent& evt) = 0;
         virtual void keyHeld    (const KeyEvent& evt) = 0;
-        virtual void tickKey    (float dt) = 0;
+        virtual void updateKey    (float dt) = 0;
     };
 
@@ -504,5 +504,5 @@
         virtual void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0;
         virtual void mouseScrolled      (int abs, int rel)     = 0;
-        virtual void tickMouse          (float dt) = 0;
+        virtual void updateMouse          (float dt) = 0;
     };
 
@@ -520,5 +520,5 @@
         virtual void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
         virtual void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) = 0;
-        virtual void tickJoyStick          (float dt, unsigned int joyStick) = 0;
+        virtual void updateJoyStick          (float dt, unsigned int joyStick) = 0;
     };
 
@@ -531,8 +531,8 @@
         virtual ~EmptyHandler() { }
 
-        void tickInput(float dt) { }
-        void tickJoyStick(float dt, unsigned int joyStick) { }
-        void tickMouse(float dt) { }
-        void tickKey(float dt) { }
+        void updateInput(float dt) { }
+        void updateJoyStick(float dt, unsigned int joyStick) { }
+        void updateMouse(float dt) { }
+        void updateKey(float dt) { }
 
         void keyPressed (const KeyEvent& evt) { }
Index: code/branches/questsystem5/src/core/input/InputManager.cc
===================================================================
--- code/branches/questsystem5/src/core/input/InputManager.cc	(revision 2777)
+++ code/branches/questsystem5/src/core/input/InputManager.cc	(revision 2907)
@@ -43,4 +43,5 @@
 
 #include "util/Exception.h"
+#include "core/Clock.h"
 #include "core/CoreIncludes.h"
 #include "core/ConfigValueIncludes.h"
@@ -108,5 +109,4 @@
         , internalState_(Uninitialised)
         , stateEmpty_(0)
-        , stateMaster_(0)
         , keyDetector_(0)
         , calibratorCallbackBuffer_(0)
@@ -173,5 +173,5 @@
             //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
             //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
-#if defined OIS_LINUX_PLATFORM
+#if defined ORXONOX_PLATFORM_LINUX
             paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
             paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true"));
@@ -218,20 +218,15 @@
 
             // Lowest priority empty InputState
-            stateEmpty_ = createInputState<SimpleInputState>("empty", -1);
+            stateEmpty_ = createInputState<SimpleInputState>("empty", false, false, InputStatePriority::Empty);
             stateEmpty_->setHandler(&EMPTY_HANDLER);
             activeStates_[stateEmpty_->getPriority()] = stateEmpty_;
 
-            // Always active master InputState
-            stateMaster_ = new ExtendedInputState();
-            stateMaster_->setName("master");
-            stateMaster_->setNumOfJoySticks(joySticksSize_);
-
             // KeyDetector to evaluate a pressed key's name
-            SimpleInputState* detector = createInputState<SimpleInputState>("detector", 101);
+            SimpleInputState* detector = createInputState<SimpleInputState>("detector", false, false, InputStatePriority::Detector);
             keyDetector_ = new KeyDetector();
             detector->setHandler(keyDetector_);
 
             // Joy stick calibration helper callback
-            SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", 100);
+            SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", false, false, InputStatePriority::Calibrator);
             calibrator->setHandler(&EMPTY_HANDLER);
             calibratorCallbackBuffer_ = new InputBuffer();
@@ -424,15 +419,12 @@
 
         // state management
-        activeStatesTop_.resize(devicesNum_);
+        activeStatesTriggered_.resize(devicesNum_);
 
         // inform all states
-        for (std::map<int, InputState*>::const_iterator it = inputStatesByPriority_.begin();
-            it != inputStatesByPriority_.end(); ++it)
+        for (std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.begin();
+            it != inputStatesByName_.end(); ++it)
         {
             it->second->setNumOfJoySticks(joySticksSize_);
         }
-        // inform master state
-        if (stateMaster_)
-            this->stateMaster_->setNumOfJoySticks(joySticksSize_);
 
         // inform all JoyStick Device Number Listeners
@@ -454,5 +446,5 @@
         }
     }
-    
+
     void InputManager::_startCalibration()
     {
@@ -549,11 +541,8 @@
                 // destroy the empty InputState
                 _destroyState(this->stateEmpty_);
-                // destroy the master input state. This might trigger a memory leak
-                // because the user has forgotten to destroy the KeyBinder or any Handler!
-                delete stateMaster_;
 
                 // destroy all user InputStates
-                while (inputStatesByPriority_.size() > 0)
-                    _destroyState((*inputStatesByPriority_.rbegin()).second);
+                while (inputStatesByName_.size() > 0)
+                    _destroyState((*inputStatesByName_.rbegin()).second);
 
                 // destroy the devices
@@ -639,5 +628,4 @@
             _updateActiveStates();
         }
-        inputStatesByPriority_.erase(state->getPriority());
         inputStatesByName_.erase(state->getName());
         delete state;
@@ -670,5 +658,5 @@
     @brief
         Public interface. Only reloads immediately if the call stack doesn't
-        include the tick() method.
+        include the update() method.
     @param joyStickSupport
         Whether or not to initialise joy sticks as well.
@@ -742,8 +730,8 @@
     @brief
         Updates the states and the InputState situation.
-    @param dt
-        Delta time
-    */
-    void InputManager::tick(float dt)
+    @param time
+        Clock holding the current time.
+    */
+    void InputManager::update(const Clock& time)
     {
         if (internalState_ == Uninitialised)
@@ -759,12 +747,14 @@
         if (!stateLeaveRequests_.empty())
         {
-            for (std::set<InputState*>::reverse_iterator rit = stateLeaveRequests_.rbegin();
-                rit != stateLeaveRequests_.rend(); ++rit)
-            {
-                (*rit)->onLeave();
+            for (std::set<InputState*>::iterator it = stateLeaveRequests_.begin();
+                it != stateLeaveRequests_.end(); ++it)
+            {
+                (*it)->onLeave();
                 // just to be sure that the state actually is registered
-                assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end());
-
-                activeStates_.erase((*rit)->getPriority());
+                assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());
+
+                activeStates_.erase((*it)->getPriority());
+                if ((*it)->getPriority() < InputStatePriority::HighPriority)
+                    (*it)->setPriority(0);
                 _updateActiveStates();
             }
@@ -775,13 +765,34 @@
         if (!stateEnterRequests_.empty())
         {
-            for (std::set<InputState*>::reverse_iterator rit = stateEnterRequests_.rbegin();
-                rit != stateEnterRequests_.rend(); ++rit)
+            for (std::set<InputState*>::const_iterator it = stateEnterRequests_.begin();
+                it != stateEnterRequests_.end(); ++it)
             {
                 // just to be sure that the state actually is registered
-                assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end());
-
-                activeStates_[(*rit)->getPriority()] = (*rit);
+                assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());
+
+                if ((*it)->getPriority() == 0)
+                {
+                    // Get smallest possible priority between 1 and maxStateStackSize_s
+#if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator
+                    for(std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
+                        rit != activeStates_.rend(); ++rit)
+#else
+                    for(std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin();
+                        rit != activeStates_.rend(); ++rit)
+#endif
+                    {
+                        if (rit->first < InputStatePriority::HighPriority)
+                        {
+                            (*it)->setPriority(rit->first + 1);
+                            break;
+                        }
+                    }
+                    // In case no normal handler was on the stack
+                    if ((*it)->getPriority() == 0)
+                        (*it)->setPriority(1);
+                }
+                activeStates_[(*it)->getPriority()] = (*it);
                 _updateActiveStates();
-                (*rit)->onEnter();
+                (*it)->onEnter();
             }
             stateEnterRequests_.clear();
@@ -791,8 +802,8 @@
         if (!stateDestroyRequests_.empty())
         {
-            for (std::set<InputState*>::reverse_iterator rit = stateDestroyRequests_.rbegin();
-                rit != stateDestroyRequests_.rend(); ++rit)
-            {
-                _destroyState((*rit));
+            for (std::set<InputState*>::iterator it = stateDestroyRequests_.begin();
+                it != stateDestroyRequests_.end(); ++it)
+            {
+                _destroyState((*it));
             }
             stateDestroyRequests_.clear();
@@ -812,5 +823,5 @@
             _updateActiveStates();
 
-        // mark that we capture and distribute input
+        // mark that we now start capturing and distributing input
         internalState_ |= Ticking;
 
@@ -829,6 +840,7 @@
             {
                 KeyEvent kEvt(keysDown_[iKey], keyboardModifiers_);
-                activeStatesTop_[Keyboard]->keyHeld(kEvt);
-                stateMaster_->keyHeld(kEvt);
+
+                for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
+                    activeStatesTriggered_[Keyboard][iState]->keyHeld(kEvt);
             }
 
@@ -836,6 +848,6 @@
             for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
             {
-                activeStatesTop_[Mouse]->mouseButtonHeld(mouseButtonsDown_[iButton]);
-                stateMaster_->mouseButtonHeld(mouseButtonsDown_[iButton]);
+                for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
+                    activeStatesTriggered_[Mouse][iState]->mouseButtonHeld(mouseButtonsDown_[iButton]);
             }
 
@@ -844,21 +856,18 @@
                 for (unsigned int iButton   = 0; iButton   < joyStickButtonsDown_[iJoyStick].size(); iButton++)
                 {
-                    activeStatesTop_[JoyStick0 + iJoyStick]
-                        ->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
-                    stateMaster_->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
+                    for (unsigned int iState = 0; iState < activeStatesTriggered_[JoyStick0 + iJoyStick].size(); ++iState)
+                        activeStatesTriggered_[JoyStick0 + iJoyStick][iState]->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
                 }
 
-            // tick the handlers for each active handler
+            // update the handlers for each active handler
             for (unsigned int i = 0; i < devicesNum_; ++i)
             {
-                activeStatesTop_[i]->tickInput(dt, i);
-                if (stateMaster_->isInputDeviceEnabled(i))
-                    stateMaster_->tickInput(dt, i);
-            }
-
-            // tick the handler with a general tick afterwards
+                for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState)
+                    activeStatesTriggered_[i][iState]->updateInput(time.getDeltaTime(), i);
+            }
+
+            // update the handler with a general tick afterwards
             for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
-                activeStatesTicked_[i]->tickInput(dt);
-            stateMaster_->tickInput(dt);
+                activeStatesTicked_[i]->updateInput(time.getDeltaTime());
         }
 
@@ -869,12 +878,27 @@
     @brief
         Updates the currently active states (according to activeStates_) for each device.
-        Also, a list of all active states (no duplicates!) is compiled for the general tick.
+        Also, a list of all active states (no duplicates!) is compiled for the general update().
     */
     void InputManager::_updateActiveStates()
     {
-        for (std::map<int, InputState*>::const_iterator it = activeStates_.begin(); it != activeStates_.end(); ++it)
-            for (unsigned int i = 0; i < devicesNum_; ++i)
-                if (it->second->isInputDeviceEnabled(i))
-                    activeStatesTop_[i] = it->second;
+        for (unsigned int i = 0; i < devicesNum_; ++i)
+        {
+            bool occupied = false;
+            activeStatesTriggered_[i].clear();
+#if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator
+            for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
+            {
+#else
+            for (std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
+            {
+#endif
+                if (rit->second->isInputDeviceEnabled(i) && (!occupied || rit->second->bAlwaysGetsInput_))
+                {
+                    activeStatesTriggered_[i].push_back(rit->second);
+                    if (!rit->second->bTransparent_)
+                        occupied = true;
+                }
+            }
+        }
 
         // update tickables (every state will only appear once)
@@ -882,7 +906,8 @@
         std::set<InputState*> tempSet;
         for (unsigned int i = 0; i < devicesNum_; ++i)
-            tempSet.insert(activeStatesTop_[i]);
-
-        // copy the content of the set back to the actual vector
+            for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState)
+                tempSet.insert(activeStatesTriggered_[i][iState]);
+
+        // copy the content of the std::set back to the actual vector
         activeStatesTicked_.clear();
         for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
@@ -942,6 +967,6 @@
 
         KeyEvent kEvt(e, keyboardModifiers_);
-        activeStatesTop_[Keyboard]->keyPressed(kEvt);
-        stateMaster_->keyPressed(kEvt);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
+            activeStatesTriggered_[Keyboard][iState]->keyPressed(kEvt);
 
         return true;
@@ -975,6 +1000,6 @@
 
         KeyEvent kEvt(e, keyboardModifiers_);
-        activeStatesTop_[Keyboard]->keyReleased(kEvt);
-        stateMaster_->keyReleased(kEvt);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
+            activeStatesTriggered_[Keyboard][iState]->keyReleased(kEvt);
 
         return true;
@@ -998,6 +1023,6 @@
             IntVector2 rel(e.state.X.rel, e.state.Y.rel);
             IntVector2 clippingSize(e.state.width, e.state.height);
-            activeStatesTop_[Mouse]->mouseMoved(abs, rel, clippingSize);
-            stateMaster_->mouseMoved(abs, rel, clippingSize);
+            for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
+                activeStatesTriggered_[Mouse][iState]->mouseMoved(abs, rel, clippingSize);
         }
 
@@ -1005,6 +1030,6 @@
         if (e.state.Z.rel != 0)
         {
-            activeStatesTop_[Mouse]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
-            stateMaster_->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
+            for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
+                activeStatesTriggered_[Mouse][iState]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
         }
 
@@ -1029,6 +1054,6 @@
             mouseButtonsDown_.push_back((MouseButtonCode::ByEnum)id);
 
-        activeStatesTop_[Mouse]->mouseButtonPressed((MouseButtonCode::ByEnum)id);
-        stateMaster_->mouseButtonPressed((MouseButtonCode::ByEnum)id);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
+            activeStatesTriggered_[Mouse][iState]->mouseButtonPressed((MouseButtonCode::ByEnum)id);
 
         return true;
@@ -1055,6 +1080,6 @@
         }
 
-        activeStatesTop_[Mouse]->mouseButtonReleased((MouseButtonCode::ByEnum)id);
-        stateMaster_->mouseButtonReleased((MouseButtonCode::ByEnum)id);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
+            activeStatesTriggered_[Mouse][iState]->mouseButtonReleased((MouseButtonCode::ByEnum)id);
 
         return true;
@@ -1092,6 +1117,6 @@
             buttonsDown.push_back((JoyStickButtonCode::ByEnum)button);
 
-        activeStatesTop_[2 + iJoyStick]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
-        stateMaster_->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
+            activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
 
         return true;
@@ -1113,6 +1138,6 @@
         }
 
-        activeStatesTop_[2 + iJoyStick]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
-        stateMaster_->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
+            activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
 
         return true;
@@ -1141,6 +1166,6 @@
                 fValue *= joyStickCalibrations_[iJoyStick].negativeCoeff[axis];
 
-            activeStatesTop_[2 + iJoyStick]->joyStickAxisMoved(iJoyStick, axis, fValue);
-            stateMaster_->joyStickAxisMoved(iJoyStick, axis, fValue);
+            for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
+                activeStatesTriggered_[2 + iJoyStick][iState]->joyStickAxisMoved(iJoyStick, axis, fValue);
         }
     }
@@ -1245,9 +1270,11 @@
         Unique name of the handler.
     @param priority
-        Unique integer number. Higher means more prioritised.
+        Determines which InputState gets the input. Higher is better.
+        Use 0 to handle it implicitely by the order of activation.
+        Otherwise numbers larger than maxStateStackSize_s have to be used!
     @return
         True if added, false if name or priority already existed.
     */
-    bool InputManager::_configureInputState(InputState* state, const std::string& name, int priority)
+    bool InputManager::_configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority)
     {
         if (name == "")
@@ -1257,20 +1284,26 @@
         if (inputStatesByName_.find(name) == inputStatesByName_.end())
         {
-            if (inputStatesByPriority_.find(priority)
-                == inputStatesByPriority_.end())
-            {
-                inputStatesByName_[name] = state;
-                inputStatesByPriority_[priority] = state;
-                state->setNumOfJoySticks(numberOfJoySticks());
-                state->setName(name);
+            if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
+            {
+                // Make sure we don't add two high priority states with the same priority
+                for (std::map<std::string, InputState*>::const_iterator it = this->inputStatesByName_.begin();
+                    it != this->inputStatesByName_.end(); ++it)
+                {
+                    if (it->second->getPriority() == priority)
+                    {
+                        COUT(2) << "Warning: Could not add an InputState with the same priority '"
+                            << priority << "' != 0." << std::endl;
+                        return false;
+                    }
+                }
+            }
+            inputStatesByName_[name] = state;
+            state->setNumOfJoySticks(numberOfJoySticks());
+            state->setName(name);
+            state->bAlwaysGetsInput_ = bAlwaysGetsInput;
+            state->bTransparent_ = bTransparent;
+            if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
                 state->setPriority(priority);
-                return true;
-            }
-            else
-            {
-                COUT(2) << "Warning: Could not add an InputState with the same priority '"
-                    << priority << "'." << std::endl;
-                return false;
-            }
+            return true;
         }
         else
@@ -1290,5 +1323,5 @@
     @remarks
         You can't remove the internal states "empty", "calibrator" and "detector".
-        The removal process is being postponed if InputManager::tick() is currently running.
+        The removal process is being postponed if InputManager::update() is currently running.
     */
     bool InputManager::requestDestroyState(const std::string& name)
@@ -1371,5 +1404,5 @@
                 {
                     // not scheduled for destruction
-                    // set prevents a state being added multiple times
+                    // prevents a state being added multiple times
                     stateEnterRequests_.insert(it->second);
                     return true;
@@ -1390,4 +1423,9 @@
     bool InputManager::requestLeaveState(const std::string& name)
     {
+        if (name == "empty")
+        {
+            COUT(2) << "InputManager: Leaving the empty state is not allowed!" << std::endl;
+            return false;
+        }
         // get pointer from the map with all stored handlers
         std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name);
Index: code/branches/questsystem5/src/core/input/InputManager.h
===================================================================
--- code/branches/questsystem5/src/core/input/InputManager.h	(revision 2777)
+++ code/branches/questsystem5/src/core/input/InputManager.h	(revision 2907)
@@ -43,4 +43,5 @@
 #include <stack>
 #include "util/Math.h"
+#include "util/OrxEnum.h"
 #include "core/OrxonoxClass.h"
 #include "InputInterfaces.h"
@@ -74,4 +75,17 @@
         float positiveCoeff[24];
         float negativeCoeff[24];
+    };
+
+    struct InputStatePriority : OrxEnum<InputStatePriority>
+    {
+        OrxEnumConstructors(InputStatePriority);
+
+        static const int Empty        = -1;
+        static const int Dynamic      = 0;
+
+        static const int HighPriority = 1000;
+        static const int Console      = HighPriority + 0;
+        static const int Calibrator   = HighPriority + 1;
+        static const int Detector     = HighPriority + 2;
     };
 
@@ -116,14 +130,13 @@
 
         template <class T>
-        T* createInputState(const std::string& name, int priority);
+        T* createInputState(const std::string& name, bool bAlwaysGetsInput = false, bool bTransparent = false, InputStatePriority priority = InputStatePriority::Dynamic);
 
         InputState* getState       (const std::string& name);
         InputState* getCurrentState();
-        ExtendedInputState* getMasterInputState() { return this->stateMaster_; }
         bool requestDestroyState   (const std::string& name);
         bool requestEnterState     (const std::string& name);
         bool requestLeaveState     (const std::string& name);
 
-        void tick(float dt);
+        void update(const Clock& time);
 
         static InputManager& getInstance()    { assert(singletonRef_s); return *singletonRef_s; }
@@ -165,5 +178,5 @@
 
         void _updateActiveStates();
-        bool _configureInputState(InputState* state, const std::string& name, int priority);
+        bool _configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority);
 
         // input events
@@ -197,10 +210,8 @@
         // some internally handled states and handlers
         SimpleInputState*                   stateEmpty_;
-        ExtendedInputState*                 stateMaster_;          //!< Always active master input state
         KeyDetector*                        keyDetector_;          //!< KeyDetector instance
         InputBuffer*                        calibratorCallbackBuffer_;
 
         std::map<std::string, InputState*>  inputStatesByName_;
-        std::map<int, InputState*>          inputStatesByPriority_;
 
         std::set<InputState*>               stateEnterRequests_;   //!< Request to enter a new state
@@ -209,6 +220,6 @@
 
         std::map<int, InputState*>          activeStates_;
-        std::vector<InputState*>            activeStatesTop_;      //!< Current input states for joy stick events.
-        std::vector<InputState*>            activeStatesTicked_;   //!< Current input states for joy stick events.
+        std::vector<std::vector<InputState*> > activeStatesTriggered_;
+        std::vector<InputState*>            activeStatesTicked_;
 
         // joystick calibration
@@ -249,8 +260,8 @@
     */
     template <class T>
-    T* InputManager::createInputState(const std::string& name, int priority)
+    T* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
     {
         T* state = new T;
-        if (_configureInputState(state, name, priority))
+        if (_configureInputState(state, name, bAlwaysGetsInput, bTransparent, priority))
             return state;
         else
Index: code/branches/questsystem5/src/core/input/InputState.h
===================================================================
--- code/branches/questsystem5/src/core/input/InputState.h	(revision 2777)
+++ code/branches/questsystem5/src/core/input/InputState.h	(revision 2907)
@@ -71,6 +71,6 @@
         virtual void unRegisterOnLeave()                      { executorOnLeave_ = 0; }
 
-        virtual void tickInput(float dt, unsigned int device) = 0;
-        virtual void tickInput(float dt) = 0;
+        virtual void updateInput(float dt, unsigned int device) = 0;
+        virtual void updateInput(float dt) = 0;
 
         virtual void keyPressed (const KeyEvent& evt) = 0;
@@ -90,5 +90,12 @@
 
     protected:
-        InputState() : bHandlersChanged_(false), priority_(0), executorOnEnter_(0), executorOnLeave_(0) { }
+        InputState()
+            : bHandlersChanged_(false)
+            , priority_(0)
+            , bAlwaysGetsInput_(false)
+            , bTransparent_(false)
+            , executorOnEnter_(0)
+            , executorOnLeave_(0)
+        { }
         virtual ~InputState() { }
 
@@ -114,4 +121,6 @@
         int                                         priority_;
         std::vector<bool>                           bInputDeviceEnabled_;
+        bool                                        bAlwaysGetsInput_;
+        bool                                        bTransparent_;
 
         Executor*                                   executorOnEnter_;
Index: code/branches/questsystem5/src/core/input/KeyBinder.cc
===================================================================
--- code/branches/questsystem5/src/core/input/KeyBinder.cc	(revision 2777)
+++ code/branches/questsystem5/src/core/input/KeyBinder.cc	(revision 2907)
@@ -42,5 +42,4 @@
 #include "core/CoreIncludes.h"
 #include "core/ConfigFileManager.h"
-#include "core/Core.h"
 #include "InputCommands.h"
 #include "InputManager.h"
@@ -309,5 +308,5 @@
     }
 
-    void KeyBinder::tickMouse(float dt)
+    void KeyBinder::updateMouse(float dt)
     {
         if (bDeriveMouseInput_)
@@ -349,5 +348,5 @@
             // Why dividing relative value by dt? The reason lies in the simple fact, that when you
             // press a button that has relative movement, that value has to be multiplied by dt to be
-            // frame rate independent. This can easily (and only) be done in tickInput(float).
+            // frame rate independent. This can easily (and only) be done in updateInput(float).
             // Hence we need to divide by dt here for the mouse to compensate, because the relative
             // move movements have nothing to do with dt.
@@ -362,5 +361,5 @@
     }
 
-    void KeyBinder::tickJoyStick(float dt, unsigned int joyStick)
+    void KeyBinder::updateJoyStick(float dt, unsigned int joyStick)
     {
         for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
Index: code/branches/questsystem5/src/core/input/KeyBinder.h
===================================================================
--- code/branches/questsystem5/src/core/input/KeyBinder.h	(revision 2777)
+++ code/branches/questsystem5/src/core/input/KeyBinder.h	(revision 2907)
@@ -68,8 +68,8 @@
 
     protected: // functions
-        void tickInput(float dt);
-        void tickKey(float dt) { }
-        void tickMouse(float dt);
-        void tickJoyStick(float dt, unsigned int joyStick);
+        void updateInput(float dt);
+        void updateKey(float dt) { }
+        void updateMouse(float dt);
+        void updateJoyStick(float dt, unsigned int joyStick);
         // internal
         void tickHalfAxis(HalfAxis& halfAxis);
@@ -134,5 +134,5 @@
         @brief
             Commands that have additional parameters (axes) are executed at the end of
-            the tick() so that all values can be buffered for single execution.
+            update() so that all values can be buffered for single execution.
         */
         std::vector<BufferedParamCommand*> paramCommandBuffer_;
@@ -200,5 +200,5 @@
     { joyStickButtons_[joyStickID][id].execute(KeybindMode::OnHold); }
 
-    inline void KeyBinder::tickInput(float dt)
+    inline void KeyBinder::updateInput(float dt)
     {
         // execute all buffered bindings (additional parameter)
Index: code/branches/questsystem5/src/core/input/SimpleInputState.h
===================================================================
--- code/branches/questsystem5/src/core/input/SimpleInputState.h	(revision 2777)
+++ code/branches/questsystem5/src/core/input/SimpleInputState.h	(revision 2907)
@@ -59,6 +59,6 @@
         ~SimpleInputState() { }
 
-        void tickInput(float dt);
-        void tickInput(float dt, unsigned int device);
+        void updateInput(float dt);
+        void updateInput(float dt, unsigned int device);
 
         void keyPressed (const KeyEvent& evt);
@@ -87,13 +87,13 @@
     };
 
-    inline void SimpleInputState::tickInput(float dt)
+    inline void SimpleInputState::updateInput(float dt)
     {
         for (unsigned int i = 0; i < allHandlers_.size(); ++i)
         {
-            allHandlers_[i]->tickInput(dt);
+            allHandlers_[i]->updateInput(dt);
         }
     }
 
-    inline void SimpleInputState::tickInput(float dt, unsigned int device)
+    inline void SimpleInputState::updateInput(float dt, unsigned int device)
     {
         switch (device)
@@ -101,15 +101,15 @@
         case InputDevice::Keyboard:
             if (keyHandler_)
-                keyHandler_->tickKey(dt);
+                keyHandler_->updateKey(dt);
             break;
 
         case InputDevice::Mouse:
             if (mouseHandler_)
-                mouseHandler_->tickMouse(dt);
+                mouseHandler_->updateMouse(dt);
             break;
 
         default: // joy sticks
             if (joyStickHandler_[device - 2])
-                joyStickHandler_[device - 2]->tickJoyStick(dt, device - 2);
+                joyStickHandler_[device - 2]->updateJoyStick(dt, device - 2);
             break;
         }
