Index: code/trunk/src/orxonox/gamestates/GSClient.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSClient.cc	(revision 1934)
+++ code/trunk/src/orxonox/gamestates/GSClient.cc	(revision 2087)
@@ -32,13 +32,13 @@
 #include "core/input/InputManager.h"
 #include "core/CommandLine.h"
+#include "core/Core.h"
 #include "network/Client.h"
-#include "Settings.h"
 
 namespace orxonox
 {
-    SetCommandLineArgument(ip, "127.0.0.1").setInformation("#.#.#.#");
+    SetCommandLineArgument(ip, "127.0.0.1").information("#.#.#.#");
 
     GSClient::GSClient()
-        : GSLevel("client")
+        : GameState<GSGraphics>("client")
         , client_(0)
     {
@@ -51,26 +51,19 @@
     void GSClient::enter()
     {
-        Settings::_getInstance().bIsClient_ = true;
+        Core::setIsClient(true);
 
-        GSLevel::enter();
-
-        int serverPort = CommandLine::getArgument<int>("port")->getValue();
-        std::string serverIP = CommandLine::getArgument<std::string>("ip")->getValue();
-        this->client_ = new network::Client(serverIP, serverPort);
+        this->client_ = new network::Client(CommandLine::getValue("ip").getString(), CommandLine::getValue("port"));
 
         if(!client_->establishConnection())
             ThrowException(InitialisationFailed, "Could not establish connection with server.");
 
+        GSLevel::enter(this->getParent()->getViewport());
+
         client_->tick(0);
-
-        // level is loaded: we can start capturing the input
-        InputManager::getInstance().requestEnterState("game");
     }
 
     void GSClient::leave()
     {
-        InputManager::getInstance().requestLeaveState("game");
-
-        // TODO: How do we unload the level in client mode?
+        GSLevel::leave();
 
         client_->closeConnection();
@@ -79,7 +72,5 @@
         delete this->client_;
 
-        GSLevel::leave();
-
-        Settings::_getInstance().bIsClient_ = false;
+        Core::setIsClient(false);
     }
 
Index: code/trunk/src/orxonox/gamestates/GSClient.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSClient.h	(revision 1934)
+++ code/trunk/src/orxonox/gamestates/GSClient.h	(revision 2087)
@@ -33,8 +33,9 @@
 #include "network/NetworkPrereqs.h"
 #include "GSLevel.h"
+#include "GSGraphics.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport GSClient : public GSLevel
+    class _OrxonoxExport GSClient : public GameState<GSGraphics>, public GSLevel
     {
     public:
Index: code/trunk/src/orxonox/gamestates/GSDedicated.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSDedicated.cc	(revision 1934)
+++ code/trunk/src/orxonox/gamestates/GSDedicated.cc	(revision 2087)
@@ -30,13 +30,7 @@
 #include "GSDedicated.h"
 
-#include <OgreRoot.h>
-#include <OgreSceneManager.h>
-#include "core/ConsoleCommand.h"
 #include "core/CommandLine.h"
-#include "core/Loader.h"
+#include "core/Core.h"
 #include "network/Server.h"
-#include "objects/Tickable.h"
-#include "GraphicsEngine.h"
-#include "Settings.h"
 
 namespace orxonox
@@ -44,8 +38,5 @@
     GSDedicated::GSDedicated()
         : GameState<GSRoot>("dedicated")
-        , timeFactor_(0)
         , server_(0)
-        , sceneManager_(0)
-        , startLevel_(0)
     {
     }
@@ -57,64 +48,29 @@
     void GSDedicated::enter()
     {
-        Settings::_getInstance().bHasServer_ = true;
+        Core::setHasServer(true);
 
-        // create Ogre SceneManager for the level
-        this->sceneManager_ = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC, "LevelSceneManager");
-        COUT(4) << "Created SceneManager: " << sceneManager_->getName() << std::endl;
+        this->server_ = new network::Server(CommandLine::getValue("port"));
+        COUT(0) << "Loading scene in server mode" << std::endl;
 
-        // temporary hack
-        GraphicsEngine::getInstance().setLevelSceneManager(this->sceneManager_);
-
-        // reset game speed to normal
-        timeFactor_ = 1.0f;
-
-        int serverPort = CommandLine::getArgument<int>("port")->getValue();
-        this->server_ = new network::Server(serverPort);
-
-        // call the loader
-        COUT(0) << "Loading level..." << std::endl;
-        startLevel_ = new Level(Settings::getDataPath() + "levels/sample.oxw");
-        Loader::open(startLevel_);
+        GSLevel::enter(0);
 
         server_->open();
-
-        // add console commands
-        FunctorMember01<GSDedicated, float>* functor = createFunctor(&GSDedicated::setTimeFactor);
-        functor->setObject(this);
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor, "setTimeFactor")).accessLevel(AccessLevel::Offline).defaultValue(0, 1.0);;
     }
 
     void GSDedicated::leave()
     {
-        // TODO: Remove and destroy console command
-
-        Loader::unload(startLevel_);
-        delete this->startLevel_;
+        GSLevel::leave();
 
         this->server_->close();
         delete this->server_;
 
-        Ogre::Root::getSingleton().destroySceneManager(this->sceneManager_);
-
-        Settings::_getInstance().bHasServer_ = false;
+        Core::setHasServer(false);
     }
 
     void GSDedicated::ticked(const Clock& time)
     {
-        // Call the scene objects
-        for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; ++it)
-            it->tick(time.getDeltaTime() * this->timeFactor_);
-
+        GSLevel::ticked(time);
         server_->tick(time.getDeltaTime());
         this->tickChild(time);
     }
-
-    /**
-    @brief
-        Changes the speed of Orxonox
-    */
-    void GSDedicated::setTimeFactor(float factor)
-    {
-        this->timeFactor_ = factor;
-    }
 }
Index: code/trunk/src/orxonox/gamestates/GSDedicated.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSDedicated.h	(revision 1934)
+++ code/trunk/src/orxonox/gamestates/GSDedicated.h	(revision 2087)
@@ -32,16 +32,14 @@
 #include "OrxonoxPrereqs.h"
 #include "network/NetworkPrereqs.h"
+#include "GSLevel.h"
 #include "GSRoot.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport GSDedicated : public GameState<GSRoot>
+    class _OrxonoxExport GSDedicated : public GameState<GSRoot>, public GSLevel
     {
     public:
         GSDedicated();
         ~GSDedicated();
-
-        void setTimeFactor(float factor);
-        float getTimeFactor() { return this->timeFactor_; }
 
     private:
@@ -50,11 +48,5 @@
         void ticked(const Clock& time);
 
-        void loadLevel();
-        void unloadLevel();
-
-        float                 timeFactor_;       //!< A factor to change the gamespeed
         network::Server*      server_;
-        Ogre::SceneManager*   sceneManager_;
-        Level*                startLevel_;       //!< current hard coded default level
     };
 }
Index: code/trunk/src/orxonox/gamestates/GSGUI.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSGUI.cc	(revision 1934)
+++ code/trunk/src/orxonox/gamestates/GSGUI.cc	(revision 2087)
@@ -31,5 +31,4 @@
 
 #include <OgreViewport.h>
-#include "GraphicsEngine.h"
 #include "core/input/InputManager.h"
 #include "core/input/SimpleInputState.h"
Index: code/trunk/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSGraphics.cc	(revision 1934)
+++ code/trunk/src/orxonox/gamestates/GSGraphics.cc	(revision 2087)
@@ -47,10 +47,14 @@
 #include "core/ConfigValueIncludes.h"
 #include "core/CoreIncludes.h"
+#include "core/Core.h"
 #include "core/input/InputManager.h"
 #include "core/input/KeyBinder.h"
 #include "core/input/ExtendedInputState.h"
+#include "core/Loader.h"
+#include "core/XMLFile.h"
 #include "overlays/console/InGameConsole.h"
 #include "gui/GUIManager.h"
 #include "tools/WindowEventListener.h"
+#include "objects/Tickable.h"
 #include "Settings.h"
 
@@ -64,4 +68,5 @@
         , renderWindow_(0)
         , viewport_(0)
+        , bWindowEventListenerUpdateRequired_(false)
         , inputManager_(0)
         , console_(0)
@@ -76,4 +81,5 @@
         , statisticsStartCount_(0)
         , tickTime_(0)
+        , debugOverlay_(0)
     {
         RegisterRootObject(GSGraphics);
@@ -101,5 +107,5 @@
     void GSGraphics::enter()
     {
-        Settings::_getInstance().bShowsGraphics_ = true;
+        Core::setShowsGraphics(true);
 
         // initialise graphics engine. Doesn't load the render window yet!
@@ -113,10 +119,13 @@
         this->initialiseResources();
 
-
-        // HACK: temporary:
-        graphicsEngine_->renderWindow_  = this->renderWindow_;
-        graphicsEngine_->root_          = this->ogreRoot_;
-        graphicsEngine_->viewport_      = this->viewport_;
-
+        // We want to get informed whenever an object of type WindowEventListener is created
+        // in order to later update the window size.
+        bWindowEventListenerUpdateRequired_ = false;
+        RegisterConstructionCallback(GSGraphics, orxonox::WindowEventListener, requestWindowEventListenerUpdate);
+
+        // load debug overlay
+        COUT(3) << "Loading Debug Overlay..." << std::endl;
+        this->debugOverlay_ = new XMLFile(Settings::getDataPath() + "overlay/debug.oxo");
+        Loader::open(debugOverlay_);
 
         // Calls the InputManager which sets up the input devices.
@@ -133,5 +142,5 @@
         // Load the InGameConsole
         console_ = new InGameConsole();
-        console_->initialise();
+        console_->initialise(this->renderWindow_->getWidth(), this->renderWindow_->getHeight());
 
         // load the CEGUI interface
@@ -165,4 +174,7 @@
         //delete this->masterKeyBinder_;
         delete this->inputManager_;
+
+        Loader::unload(this->debugOverlay_);
+        delete this->debugOverlay_;
 
         // destroy render window
@@ -196,5 +208,5 @@
         delete graphicsEngine_;
 
-        Settings::_getInstance().bShowsGraphics_ = false;
+        Core::setShowsGraphics(false);
     }
 
@@ -221,5 +233,18 @@
         this->console_->tick(dt);
         this->tickChild(time);
-        
+
+        /*** HACK *** HACK ***/
+        // Call the Tickable objects
+        for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; ++it)
+            it->tick(time.getDeltaTime());
+        /*** HACK *** HACK ***/
+
+        if (this->bWindowEventListenerUpdateRequired_)
+        {
+            // Update all WindowEventListeners for the case a new one was created.
+            this->windowResized(this->renderWindow_);
+            this->bWindowEventListenerUpdateRequired_ = false;
+        }
+
         unsigned long long timeAfterTick = time.getRealMicroseconds();
 
@@ -487,4 +512,8 @@
         for (ObjectList<orxonox::WindowEventListener>::iterator it = ObjectList<orxonox::WindowEventListener>::begin(); it; ++it)
             it->windowResized(this->renderWindow_->getWidth(), this->renderWindow_->getHeight());
+
+        // OIS needs this under linux even if we only use relative input measurement.
+        if (this->inputManager_)
+            this->inputManager_->setWindowExtents(renderWindow_->getWidth(), renderWindow_->getHeight());
     }
 
@@ -501,5 +530,6 @@
 
         // instruct InputManager to clear the buffers (core library so we cannot use the interface)
-        InputManager::getInstance().clearBuffers();
+        if (this->inputManager_)
+            this->inputManager_->clearBuffers();
     }
 
@@ -512,6 +542,4 @@
     void GSGraphics::windowClosed(Ogre::RenderWindow *rw)
     {
-        // using CommandExecutor in order to avoid depending on Orxonox.h.
-        //CommandExecutor::execute("exit", false);
         this->requestState("root");
     }
Index: code/trunk/src/orxonox/gamestates/GSGraphics.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSGraphics.h	(revision 1934)
+++ code/trunk/src/orxonox/gamestates/GSGraphics.h	(revision 2087)
@@ -77,7 +77,10 @@
         void windowClosed      (Ogre::RenderWindow* rw);
 
+        void requestWindowEventListenerUpdate() { this->bWindowEventListenerUpdateRequired_ = true; }
+
     private: // variables
         Ogre::RenderWindow*   renderWindow_;          //!< the current render window
         Ogre::Viewport*       viewport_;              //!< default full size viewport
+        bool bWindowEventListenerUpdateRequired_;     //!< True if a new WindowEventListener was created but not yet updated.
 
         // managed singletons
@@ -97,4 +100,5 @@
         unsigned long         statisticsStartCount_;
         unsigned int          tickTime_;
+        XMLFile*              debugOverlay_;
 
         // config values
Index: code/trunk/src/orxonox/gamestates/GSIOConsole.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSIOConsole.cc	(revision 1934)
+++ code/trunk/src/orxonox/gamestates/GSIOConsole.cc	(revision 2087)
@@ -36,6 +36,4 @@
 
 #include "core/ConsoleCommand.h"
-#include "core/TclThreadManager.h"
-#include "GraphicsEngine.h"
 
 namespace orxonox
Index: code/trunk/src/orxonox/gamestates/GSLevel.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSLevel.cc	(revision 1934)
+++ code/trunk/src/orxonox/gamestates/GSLevel.cc	(revision 2087)
@@ -30,10 +30,9 @@
 #include "GSLevel.h"
 
-#include <OgreSceneManager.h>
-#include <OgreRoot.h>
 #include "core/input/InputManager.h"
 #include "core/input/SimpleInputState.h"
 #include "core/input/KeyBinder.h"
 #include "core/Loader.h"
+#include "core/XMLFile.h"
 #include "core/CommandExecutor.h"
 #include "core/ConsoleCommand.h"
@@ -41,24 +40,26 @@
 #include "core/ConfigValueIncludes.h"
 #include "core/CoreIncludes.h"
-#include "objects/Backlight.h"
+#include "core/Core.h"
+//#include "objects/Backlight.h"
 #include "objects/Tickable.h"
 #include "objects/Radar.h"
-#include "tools/ParticleInterface.h"
+//#include "tools/ParticleInterface.h"
+#include "CameraManager.h"
+#include "LevelManager.h"
 #include "Settings.h"
-#include "GraphicsEngine.h"
 
 namespace orxonox
 {
-    SetCommandLineArgument(level, "sample.oxw").setShortcut("l");
-
-    GSLevel::GSLevel(const std::string& name)
-        : GameState<GSGraphics>(name)
-        , timeFactor_(1.0f)
-        , sceneManager_(0)
+    SetCommandLineArgument(level, "sample2.oxw").shortcut("l");
+
+    GSLevel::GSLevel()
+//        : GameState<GSGraphics>(name)
+        : timeFactor_(1.0f)
         , keyBinder_(0)
         , inputState_(0)
         , radar_(0)
-        , startLevel_(0)
-        , hud_(0)
+        , startFile_(0)
+        , cameraManager_(0)
+        , levelManager_(0)
     {
         RegisterObject(GSLevel);
@@ -75,48 +76,62 @@
     }
 
-    void GSLevel::enter()
-    {
-        inputState_ = InputManager::getInstance().createInputState<SimpleInputState>("game", 20);
-        keyBinder_ = new KeyBinder();
-        keyBinder_->loadBindings("keybindings.ini");
-        inputState_->setHandler(keyBinder_);
-
-        // create Ogre SceneManager for the level
-        this->sceneManager_ = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC, "LevelSceneManager");
-        COUT(4) << "Created SceneManager: " << sceneManager_->getName() << std::endl;
-
-        // temporary hack
-        GraphicsEngine::getInstance().setLevelSceneManager(this->sceneManager_);
-
-        // Start the Radar
-        this->radar_ = new Radar();
-
-        // Load the HUD
-        COUT(3) << "Orxonox: Loading HUD" << std::endl;
-        hud_ = new Level(Settings::getDataPath() + "overlay/hud.oxo");
-        Loader::load(hud_);
-
-        // reset game speed to normal
-        timeFactor_ = 1.0f;
-
-        // TODO: insert slomo console command with
-        // .accessLevel(AccessLevel::Offline).defaultValue(0, 1.0).axisParamIndex(0).isAxisRelative(false);
-
-        // keybind console command
-        FunctorMember<GSLevel>* functor1 = createFunctor(&GSLevel::keybind);
-        functor1->setObject(this);
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor1, "keybind"));
-        FunctorMember<GSLevel>* functor2 = createFunctor(&GSLevel::tkeybind);
-        functor2->setObject(this);
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor2, "tkeybind"));
-        // set our console command as callback for the key detector
-        InputManager::getInstance().setKeyDetectorCallback(std::string("keybind ") + keyDetectorCallbackCode_);
+    void GSLevel::enter(Ogre::Viewport* viewport)
+    {
+        if (Core::showsGraphics())
+        {
+            inputState_ = InputManager::getInstance().createInputState<SimpleInputState>("game", 20);
+            keyBinder_ = new KeyBinder();
+            keyBinder_->loadBindings("keybindings.ini");
+            inputState_->setHandler(keyBinder_);
+
+            // create the global CameraManager
+            assert(viewport);
+            this->cameraManager_ = new CameraManager(viewport);
+
+            // Start the Radar
+            this->radar_ = new Radar();
+        }
+
+        if (Core::isMaster())
+        {
+            // create the global LevelManager
+            this->levelManager_ = new LevelManager();
+
+            // reset game speed to normal
+            timeFactor_ = 1.0f;
+
+            this->loadLevel();
+        }
+
+        if (Core::showsGraphics())
+        {
+            // TODO: insert slomo console command with
+            // .accessLevel(AccessLevel::Offline).defaultValue(0, 1.0).axisParamIndex(0).isAxisRelative(false);
+
+            // keybind console command
+            FunctorMember<GSLevel>* functor1 = createFunctor(&GSLevel::keybind);
+            functor1->setObject(this);
+            CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor1, "keybind"));
+            FunctorMember<GSLevel>* functor2 = createFunctor(&GSLevel::tkeybind);
+            functor2->setObject(this);
+            CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor2, "tkeybind"));
+            // set our console command as callback for the key detector
+            InputManager::getInstance().setKeyDetectorCallback(std::string("keybind ") + keyDetectorCallbackCode_);
+
+            // level is loaded: we can start capturing the input
+            InputManager::getInstance().requestEnterState("game");
+        }
+
+        if (Core::isMaster())
+        {
+            // time factor console command
+            FunctorMember<GSLevel>* functor = createFunctor(&GSLevel::setTimeFactor);
+            functor->setObject(this);
+            CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor, "setTimeFactor")).accessLevel(AccessLevel::Offline).defaultValue(0, 1.0);;
+        }
     }
 
     void GSLevel::leave()
     {
-        Loader::unload(hud_);
-        delete this->hud_;
-
         // this call will delete every BaseObject!
         // But currently this will call methods of objects that exist no more
@@ -125,18 +140,34 @@
         //Loader::close();
 
-        delete this->radar_;
-
-        Ogre::Root::getSingleton().destroySceneManager(this->sceneManager_);
-
-        inputState_->setHandler(0);
-        InputManager::getInstance().requestDestroyState("game");
-        delete this->keyBinder_;
+        if (Core::showsGraphics())
+            InputManager::getInstance().requestLeaveState("game");
+
+        if (Core::isMaster())
+            this->unloadLevel();
+
+        if (this->radar_)
+            delete this->radar_;
+
+        if (this->cameraManager_)
+            delete this->cameraManager_;
+
+        if (this->levelManager_)
+            delete this->levelManager_;
+
+        if (Core::showsGraphics())
+        {
+            inputState_->setHandler(0);
+            InputManager::getInstance().requestDestroyState("game");
+            if (this->keyBinder_)
+                delete this->keyBinder_;
+        }
     }
 
     void GSLevel::ticked(const Clock& time)
     {
-        // Call the scene objects
-        for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; ++it)
-            it->tick(time.getDeltaTime() * this->timeFactor_);
+        // Commented by 1337: Temporarily moved to GSGraphics.
+        //// Call the scene objects
+        //for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; ++it)
+        //    it->tick(time.getDeltaTime() * this->timeFactor_);
     }
 
@@ -147,6 +178,9 @@
     void GSLevel::setTimeFactor(float factor)
     {
+/*
         float change = factor / this->timeFactor_;
+*/
         this->timeFactor_ = factor;
+/*
         for (ObjectList<ParticleInterface>::iterator it = ObjectList<ParticleInterface>::begin(); it; ++it)
             it->setSpeedFactor(it->getSpeedFactor() * change);
@@ -154,4 +188,5 @@
         for (ObjectList<Backlight>::iterator it = ObjectList<Backlight>::begin(); it; ++it)
             it->setTimeFactor(timeFactor_);
+*/
     }
 
@@ -162,12 +197,17 @@
         std::string levelName;
         CommandLine::getValue("level", &levelName);
-        startLevel_ = new Level(Settings::getDataPath() + std::string("levels/") + levelName);
-        Loader::open(startLevel_);
+        startFile_ = new XMLFile(Settings::getDataPath() + std::string("levels/") + levelName);
+        Loader::open(startFile_);
     }
 
     void GSLevel::unloadLevel()
     {
-        Loader::unload(startLevel_);
-        delete this->startLevel_;
+        //////////////////////////////////////////////////////////////////////////////////////////
+        // TODO // TODO // TODO // TODO // TODO // TODO // TODO // TODO // TODO // TODO // TODO //
+        //////////////////////////////////////////////////////////////////////////////////////////
+        // Loader::unload(startFile_); // TODO: REACTIVATE THIS IF LOADER::UNLOAD WORKS PROPERLY /
+        //////////////////////////////////////////////////////////////////////////////////////////
+
+        delete this->startFile_;
     }
 
@@ -192,33 +232,36 @@
     void GSLevel::keybindInternal(const std::string& command, bool bTemporary)
     {
-        static std::string bindingString = "";
-        static bool bTemporarySaved = false;
-        static bool bound = true;
-        // note: We use a long name to make 'sure' that the user doesn't use it accidentally.
-        // Howerver there will be no real issue if it happens anyway.
-        if (command.find(keyDetectorCallbackCode_) != 0)
-        {
-            if (bound)
+        if (Core::showsGraphics())
+        {
+            static std::string bindingString = "";
+            static bool bTemporarySaved = false;
+            static bool bound = true;
+            // note: We use a long name to make 'sure' that the user doesn't use it accidentally.
+            // Howerver there will be no real issue if it happens anyway.
+            if (command.find(keyDetectorCallbackCode_) != 0)
             {
-                COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl;
-                InputManager::getInstance().requestEnterState("detector");
-                bindingString = command;
-                bTemporarySaved = bTemporary;
-                bound = false;
+                if (bound)
+                {
+                    COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl;
+                    InputManager::getInstance().requestEnterState("detector");
+                    bindingString = command;
+                    bTemporarySaved = bTemporary;
+                    bound = false;
+                }
+                //else:  We're still in a keybind command. ignore this call.
             }
-            //else:  We're still in a keybind command. ignore this call.
-        }
-        else
-        {
-            if (!bound)
+            else
             {
-                // user has pressed the key
-                std::string name = command.substr(this->keyDetectorCallbackCode_.size());
-                COUT(0) << "Binding string \"" << bindingString << "\" on key '" << name << "'" << std::endl;
-                this->keyBinder_->setBinding(bindingString, name, bTemporarySaved);
-                InputManager::getInstance().requestLeaveState("detector");
-                bound = true;
+                if (!bound)
+                {
+                    // user has pressed the key
+                    std::string name = command.substr(this->keyDetectorCallbackCode_.size());
+                    COUT(0) << "Binding string \"" << bindingString << "\" on key '" << name << "'" << std::endl;
+                    this->keyBinder_->setBinding(bindingString, name, bTemporarySaved);
+                    InputManager::getInstance().requestLeaveState("detector");
+                    bound = true;
+                }
+                // else: A key was pressed within the same tick, ignore it.
             }
-            // else: A key was pressed within the same tick, ignore it.
         }
     }
Index: code/trunk/src/orxonox/gamestates/GSLevel.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSLevel.h	(revision 1934)
+++ code/trunk/src/orxonox/gamestates/GSLevel.h	(revision 2087)
@@ -37,10 +37,10 @@
 namespace orxonox
 {
-    class _OrxonoxExport GSLevel : public GameState<GSGraphics>, public OrxonoxClass
+    class _OrxonoxExport GSLevel : public OrxonoxClass //,public GameState<GSGraphics>
     {
         friend class ClassIdentifier<GSLevel>;
     public:
-        GSLevel(const std::string& name);
-        virtual ~GSLevel();
+        GSLevel();
+        ~GSLevel();
 
         // this has to be public because proteced triggers a bug in msvc
@@ -50,12 +50,12 @@
 
     protected:
-        virtual void enter();
-        virtual void leave();
-        virtual void ticked(const Clock& time);
+        void enter(Ogre::Viewport* viewport);
+        void leave();
+        void ticked(const Clock& time);
 
         void loadLevel();
         void unloadLevel();
 
-        float timeFactor_;       //!< A factor to change the gamespeed
+        float timeFactor_;       //!< A factor that sets the gamespeed. 1 is normal.
 
         // console commands
@@ -64,14 +64,14 @@
         void keybindInternal(const std::string& command, bool bTemporary);
 
-        Ogre::SceneManager*   sceneManager_;
         KeyBinder*            keyBinder_;        //!< tool that loads and manages the input bindings
         SimpleInputState*     inputState_;
         Radar*                radar_;            //!< represents the Radar (not the HUD part)
-        Level*                startLevel_;       //!< current hard coded default level
-        Level*                hud_;              //!< 'level' object fo the HUD
+        XMLFile*              startFile_;        //!< current hard coded default level
+        CameraManager*        cameraManager_;
+        LevelManager*         levelManager_;
 
         // config values
         std::string           keyDetectorCallbackCode_;
-        
+
     private:
         void setConfigValues();
Index: code/trunk/src/orxonox/gamestates/GSRoot.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSRoot.cc	(revision 1934)
+++ code/trunk/src/orxonox/gamestates/GSRoot.cc	(revision 2087)
@@ -41,5 +41,4 @@
 #include "core/TclThreadManager.h"
 #include "tools/Timer.h"
-#include "GraphicsEngine.h"
 #include "Settings.h"
 
@@ -61,6 +60,6 @@
 namespace orxonox
 {
-    SetCommandLineArgument(dataPath, "").setInformation("PATH");
-    SetCommandLineArgument(limitToCPU, 1).setInformation("0: off | #cpu");
+    SetCommandLineArgument(dataPath, "").information("PATH");
+    SetCommandLineArgument(limitToCPU, 1).information("0: off | #cpu");
 
     GSRoot::GSRoot()
@@ -91,6 +90,5 @@
         this->settings_ = new Settings();
 
-        std::string dataPath;
-        CommandLine::getValue("dataPath", &dataPath);
+        std::string dataPath = CommandLine::getValue("dataPath");
         if (dataPath != "")
         {
@@ -111,6 +109,5 @@
         // do this after ogre has initialised. Somehow Ogre changes the settings again (not through
         // the timer though).
-        int limitToCPU;
-        CommandLine::getValue("limitToCPU", &limitToCPU);
+        int limitToCPU = CommandLine::getValue("limitToCPU");
         if (limitToCPU > 0)
             setThreadAffinity((unsigned int)(limitToCPU - 1));
@@ -157,5 +154,5 @@
         Copyright (c) 2000-2008 Torus Knot Software Ltd
         
-        OGRE is licensed under the LGPL. For more info, see ogre license info.
+        OGRE is licensed under the LGPL. For more info, see OGRE license.
     */
     void GSRoot::setThreadAffinity(unsigned int limitToCPU)
Index: code/trunk/src/orxonox/gamestates/GSServer.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSServer.cc	(revision 1934)
+++ code/trunk/src/orxonox/gamestates/GSServer.cc	(revision 2087)
@@ -30,16 +30,14 @@
 #include "GSServer.h"
 
-#include "core/ConsoleCommand.h"
-#include "core/input/InputManager.h"
 #include "core/CommandLine.h"
+#include "core/Core.h"
 #include "network/Server.h"
-#include "Settings.h"
 
 namespace orxonox
 {
-    SetCommandLineArgument(port, 55556).setShortcut("p").setInformation("0-65535");
+    SetCommandLineArgument(port, 55556).shortcut("p").information("0-65535");
 
     GSServer::GSServer()
-        : GSLevel("server")
+        : GameState<GSGraphics>("server")
         , server_(0)
     {
@@ -52,39 +50,22 @@
     void GSServer::enter()
     {
-        Settings::_getInstance().bHasServer_ = true;
+        Core::setHasServer(true);
 
-        GSLevel::enter();
-
-        int serverPort = CommandLine::getArgument<int>("port")->getValue();
-        this->server_ = new network::Server(serverPort);
+        this->server_ = new network::Server(CommandLine::getValue("port"));
         COUT(0) << "Loading scene in server mode" << std::endl;
 
-        this->loadLevel();
+        GSLevel::enter(this->getParent()->getViewport());
 
         server_->open();
-
-        // add console commands
-        FunctorMember<GSLevel>* functor = createFunctor(&GSLevel::setTimeFactor);
-        functor->setObject(this);
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor, "setTimeFactor")).accessLevel(AccessLevel::Offline).defaultValue(0, 1.0);;
-
-        // level is loaded: we can start capturing the input
-        InputManager::getInstance().requestEnterState("game");
     }
 
     void GSServer::leave()
     {
-        InputManager::getInstance().requestLeaveState("game");
-
-        // TODO: Remove and destroy console command
-
-        this->unloadLevel();
+        GSLevel::leave();
 
         this->server_->close();
         delete this->server_;
 
-        GSLevel::leave();
-	
-        Settings::_getInstance().bHasServer_ = false;
+        Core::setHasServer(false);
     }
 
Index: code/trunk/src/orxonox/gamestates/GSServer.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSServer.h	(revision 1934)
+++ code/trunk/src/orxonox/gamestates/GSServer.h	(revision 2087)
@@ -33,13 +33,13 @@
 #include "network/NetworkPrereqs.h"
 #include "GSLevel.h"
+#include "GSGraphics.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport GSServer : public GSLevel
+    class _OrxonoxExport GSServer : public GameState<GSGraphics>, public GSLevel
     {
     public:
         GSServer();
         ~GSServer();
-
 
     private:
Index: code/trunk/src/orxonox/gamestates/GSStandalone.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSStandalone.cc	(revision 1934)
+++ code/trunk/src/orxonox/gamestates/GSStandalone.cc	(revision 2087)
@@ -30,11 +30,10 @@
 #include "GSStandalone.h"
 
-#include "core/input/InputManager.h"
-#include "core/ConsoleCommand.h"
+#include "core/Core.h"
 
 namespace orxonox
 {
     GSStandalone::GSStandalone()
-        : GSLevel("standalone")
+        : GameState<GSGraphics>("standalone")
     {
     }
@@ -46,26 +45,14 @@
     void GSStandalone::enter()
     {
-        GSLevel::enter();
+        Core::setIsStandalone(true);
 
-        this->loadLevel();
-
-        // add console commands
-        FunctorMember<GSLevel>* functor = createFunctor(&GSLevel::setTimeFactor);
-        functor->setObject(this);
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor, "setTimeFactor")).accessLevel(AccessLevel::Offline).defaultValue(0, 1.0);;
-
-        // level is loaded: we can start capturing the input
-        InputManager::getInstance().requestEnterState("game");
+        GSLevel::enter(this->getParent()->getViewport());
     }
 
     void GSStandalone::leave()
     {
-        InputManager::getInstance().requestLeaveState("game");
+        GSLevel::leave();
 
-        // TODO: Remove and destroy console command
-
-        this->unloadLevel();
-
-        GSLevel::leave();
+        Core::setIsStandalone(false);
     }
 
Index: code/trunk/src/orxonox/gamestates/GSStandalone.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSStandalone.h	(revision 1934)
+++ code/trunk/src/orxonox/gamestates/GSStandalone.h	(revision 2087)
@@ -32,8 +32,9 @@
 #include "OrxonoxPrereqs.h"
 #include "GSLevel.h"
+#include "GSGraphics.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport GSStandalone : public GSLevel
+    class _OrxonoxExport GSStandalone : public GameState<GSGraphics>, public GSLevel
     {
     public:
