Index: /code/branches/gui/src/core/CommandLine.h
===================================================================
--- /code/branches/gui/src/core/CommandLine.h	(revision 1669)
+++ /code/branches/gui/src/core/CommandLine.h	(revision 1670)
@@ -38,8 +38,8 @@
 #define SetCommandLineArgument(name, defaultValue) \
     BaseCommandLineArgument& CmdArgumentDummyBoolVar##name \
-    = orxonox::CommandLine::addCommandLineArgument(#name, defaultValue)
+    = orxonox::CommandLine::addArgument(#name, defaultValue)
 #define SetCommandLineSwitch(name) \
     BaseCommandLineArgument& CmdArgumentDummyBoolVar##name \
-    = orxonox::CommandLine::addCommandLineArgument(#name, false)
+    = orxonox::CommandLine::addArgument(#name, false)
 
 
@@ -89,6 +89,6 @@
     protected:
         BaseCommandLineArgument(const std::string& name)
-            : name_(name)
-            , bHasDefaultValue_(true)
+            : bHasDefaultValue_(true)
+            , name_(name)
         { }
 
@@ -216,11 +216,11 @@
 
         template <class T>
-        static const CommandLineArgument<T>* getCommandLineArgument(const std::string& name);
+        static const CommandLineArgument<T>* getArgument(const std::string& name);
         //! Writes the argument value in the given parameter.
         template <class T>
-        static void getCommandLineValue(const std::string& name, T* value)
-        { *value = getCommandLineArgument<T>(name)->getValue(); }
-        template <class T>
-        static BaseCommandLineArgument& addCommandLineArgument(const std::string& name, T defaultValue);
+        static void getValue(const std::string& name, T* value)
+        { *value = getArgument<T>(name)->getValue(); }
+        template <class T>
+        static BaseCommandLineArgument& addArgument(const std::string& name, T defaultValue);
 
     private:
@@ -264,5 +264,5 @@
     */
     template <class T>
-    const CommandLineArgument<T>* CommandLine::getCommandLineArgument(const std::string& name)
+    const CommandLineArgument<T>* CommandLine::getArgument(const std::string& name)
     {
         std::map<std::string, BaseCommandLineArgument*>::const_iterator it = _getInstance().cmdLineArgs_.find(name);
@@ -302,5 +302,5 @@
     */
     template <class T>
-    BaseCommandLineArgument& CommandLine::addCommandLineArgument(const std::string& name, T defaultValue)
+    BaseCommandLineArgument& CommandLine::addArgument(const std::string& name, T defaultValue)
     {
         std::map<std::string, BaseCommandLineArgument*>::const_iterator it = _getInstance().cmdLineArgs_.find(name);
Index: /code/branches/gui/src/core/Core.cc
===================================================================
--- /code/branches/gui/src/core/Core.cc	(revision 1669)
+++ /code/branches/gui/src/core/Core.cc	(revision 1670)
@@ -36,6 +36,6 @@
 #include "CoreIncludes.h"
 #include "ConfigValueIncludes.h"
-#include "input/InputManager.h"
-#include "TclThreadManager.h"
+//#include "input/InputManager.h"
+//#include "TclThreadManager.h"
 
 namespace orxonox
@@ -188,14 +188,14 @@
     }
 
-    /**
-        @brief Ticks every core class in a specified sequence. Has to be called
-               every Orxonox tick!
-        @param dt Delta Time
-    */
-    void Core::tick(float dt)
-    {
-        TclThreadManager::getInstance().tick(dt);
-        InputManager::getInstance().tick(dt);
-    }
+    ///**
+    //    @brief Ticks every core class in a specified sequence. Has to be called
+    //           every Orxonox tick!
+    //    @param dt Delta Time
+    //*/
+    //void Core::tick(float dt)
+    //{
+    //    TclThreadManager::getInstance().tick(dt);
+    //    InputManager::getInstance().tick(dt);
+    //}
 }
 
Index: /code/branches/gui/src/core/Core.h
===================================================================
--- /code/branches/gui/src/core/Core.h	(revision 1669)
+++ /code/branches/gui/src/core/Core.h	(revision 1670)
@@ -58,5 +58,5 @@
             static void resetLanguage();
 
-            static void tick(float dt);
+            //static void tick(float dt);
 
         private:
Index: /code/branches/gui/src/core/Exception.h
===================================================================
--- /code/branches/gui/src/core/Exception.h	(revision 1669)
+++ /code/branches/gui/src/core/Exception.h	(revision 1670)
@@ -88,5 +88,5 @@
         std::string functionName_;
         std::string fileName_;
-        // mutable because of "what()" is a const method
+        // mutable because "what()" is a const method
         mutable std::string fullDescription_;
     };
@@ -101,6 +101,6 @@
                   : Exception(description, lineNumber, fileName, functionName)
         {
-            // let the catcher decide whether to display the message or not
-            //COUT(1) << this->getFullDescription() << std::endl;
+            // let the catcher decide whether to display the message below level 3
+            COUT(3) << this->getFullDescription() << std::endl;
         }
 
@@ -108,6 +108,6 @@
             : Exception(description)
         {
-            // let the catcher decide whether to display the message or not
-            //COUT(1) << this->getFullDescription() << std::endl;
+            // let the catcher decide whether to display the message below level 3
+            COUT(3) << this->getFullDescription() << std::endl;
         }
 
Index: /code/branches/gui/src/core/GameState.cc
===================================================================
--- /code/branches/gui/src/core/GameState.cc	(revision 1669)
+++ /code/branches/gui/src/core/GameState.cc	(revision 1670)
@@ -47,9 +47,13 @@
         : name_(name)
         , bPauseParent_(false)
-        , bActive_(false)
-        , bSuspended_(false)
+        //, bActive_(false)
+        //, bSuspended_(false)
+        //, bRunning_(false)
+        , scheduledTransition_(0)
         , parent_(0)
         , activeChild_(0)
     {
+        Operations temp = {false, false, false, false, false};
+        this->operation_ = temp;
     }
 
@@ -60,5 +64,5 @@
     GameState::~GameState()
     {
-        if (this->bActive_)
+        if (this->operation_.active)
         {
             if (this->parent_)
@@ -133,5 +137,5 @@
         if (it != this->grandchildrenToChildren_.end())
         {
-            if (state->isActive())
+            if (state->getOperation().active)
             {
                 ThrowException(GameState, "Cannot remove active game state child '"
@@ -247,5 +251,5 @@
     GameState* GameState::getCurrentState()
     {
-        if (this->bActive_)
+        if (this->operation_.active)
         {
             if (this->activeChild_)
@@ -284,21 +288,28 @@
     void GameState::requestState(const std::string& name)
     {
-        if (name == "")
-        {
-            // user would like to leave every state.
-            GameState* current = getCurrentState();
-            if (current)
-            {
-                // Deactivate all states but root
-                GameState* root = getRootNode();
-                current->makeTransition(root);
-                // Kick root too
-                root->deactivate();
-            }
-        }
+        GameState* current = getCurrentState();
+        if (current != 0 && (current->getOperation().entering || current->getOperation().leaving))
+        {
+            ThrowException(GameState, "Making state transitions during enter()/leave() is forbidden.");
+        }
+        //if (name == "")
+        //{
+        //    // user would like to leave every state.
+        //    if (current)
+        //    {
+        //        // Deactivate all states but root
+        //        GameState* root = getRootNode();
+        //        current->makeTransition(root);
+        //        //// Kick root too
+        //        //assert(!(root->getOperation().entering || root->getOperation().leaving));
+        //        //if (root->operation_.running)
+        //        //    root->scheduledTransition_ = 0;
+        //        //else
+        //        //    root->deactivate();
+        //    }
+        //}
         else
         {
             GameState* request = checkState(name);
-            GameState* current = getCurrentState();
             if (request)
             {
@@ -331,5 +342,5 @@
     {
         // we're always already active
-        assert(this->bActive_);
+        assert(this->operation_.active);
 
         if (state == this)
@@ -349,31 +360,68 @@
             assert(this->parent_ != 0);
 
-            // first, leave this state.
+            // only do the transition if we're not currently running
+            if (this->operation_.running)
+            {
+                //this->bDeactivationScheduled_ = true;
+                this->scheduledTransition_ = state;
+            }
+            else
+            {
+                this->deactivate();
+                this->parent_->makeTransition(state);
+            }
+
+        }
+    }
+
+    /**
+    @brief
+        Activates the state. Only sets bActive_ to true and notifies the parent.
+    */
+    void GameState::activate()
+    {
+        if (this->parent_)
+            this->parent_->activeChild_ = this;
+        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 GameState::deactivate()
+    {
+        this->operation_.leaving = true;
+        this->leave();
+        this->operation_.leaving = false;
+        this->operation_.active = false;
+        if (this->parent_)
+            this->parent_->activeChild_ = 0;
+    }
+
+    /**
+    @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 GameState::tick(float dt)
+    {
+        this->operation_.running = true;
+        this->ticked(dt);
+        this->operation_.running = false;
+
+        if (this->scheduledTransition_)
+        {
+            // state was requested to be deactivated when ticked.
+            this->makeTransition(this->scheduledTransition_);
+            this->scheduledTransition_ = 0;
             this->deactivate();
-            this->parent_->makeTransition(state);
-        }
-    }
-
-    /**
-    @brief
-        Activates the state. Only sets bActive_ to true and notifies the parent.
-    */
-    void GameState::activate()
-    {
-        this->bActive_ = true;
-        if (this->parent_)
-            this->parent_->activeChild_ = this;
-        this->enter();
-    }
-
-    /**
-        Activates the state. Only sets bActive_ to false and notifies the parent.
-    */
-    void GameState::deactivate()
-    {
-        this->leave();
-        this->bActive_ = false;
-        if (this->parent_)
-            this->parent_->activeChild_ = 0;
+        }
     }
 
Index: /code/branches/gui/src/core/GameState.h
===================================================================
--- /code/branches/gui/src/core/GameState.h	(revision 1669)
+++ /code/branches/gui/src/core/GameState.h	(revision 1670)
@@ -61,4 +61,13 @@
     {
     public:
+        struct Operations
+        {
+            unsigned active    : 1;
+            unsigned entering  : 1;
+            unsigned leaving   : 1;
+            unsigned running   : 1;
+            unsigned suspended : 1;
+        };
+
         GameState(const std::string& name);
         virtual ~GameState();
@@ -71,21 +80,25 @@
         void requestState(const std::string& name);
 
-        //! Determines whether the state is active.
-        bool isActive()       { return this->bActive_; }
-        //! Determines whether the state is suspended.
-        bool isSuspended()    { return this->bSuspended_; }
-        //! Determines whether the state is the current
-        bool isCurrentState() { return this->bActive_ && !this->activeChild_; }
+        ////! Determines whether the state is active.
+        //bool isActive()       { return this->bActive_; }
+        ////! Determines whether the state is suspended.
+        //bool isSuspended()    { return this->bSuspended_; }
+        ////! Determines whether the state is the current
+        //bool isCurrentState() { return this->bActive_ && !this->activeChild_; }
+        const Operations getOperation() { return this->operation_; }
 
-        virtual bool tick(float dt) { return true; }
+        void tick(float dt);
+        void tickChild(float dt) { if (this->activeChild_) this->activeChild_->tick(dt); }
 
     protected:
-        //virtual void enter() = 0;
-        //virtual void leave() = 0;
-        //virtual void tick(float dt) = 0;
-        virtual void enter() { }
-        virtual void leave() { }
+        virtual void enter() = 0;
+        virtual void leave() = 0;
+        virtual void ticked(float dt) = 0;
+        //virtual void enter() { }
+        //virtual void leave() { }
+        //virtual void ticked(float dt) { }
 
         GameState* getActiveChild() { return this->activeChild_; }
+        bool hasScheduledTransition() { return this->scheduledTransition_; }
 
     private:
@@ -102,9 +115,9 @@
         bool                                 bPauseParent_;
 
-        bool                                 bActive_;
-        bool                                 bSuspended_;
+        Operations                           operation_;
 
         GameState*                           parent_;
         GameState*                           activeChild_;
+        GameState*                           scheduledTransition_;
         std::map<std::string, GameState*>    allChildren_;
         std::map<GameState*, GameState*>     grandchildrenToChildren_;
Index: /code/branches/gui/src/core/Script.cc
===================================================================
--- /code/branches/gui/src/core/Script.cc	(revision 1669)
+++ /code/branches/gui/src/core/Script.cc	(revision 1670)
@@ -198,5 +198,5 @@
       for (std::map<unsigned int, bool>::iterator it = luaTags.begin(); it != luaTags.end(); ++it)
       {
-        if ((*it).second == expectedValue)
+        if (it->second == expectedValue)
           expectedValue = !expectedValue;
         else
Index: /code/branches/gui/src/core/input/InputManager.cc
===================================================================
--- /code/branches/gui/src/core/input/InputManager.cc	(revision 1669)
+++ /code/branches/gui/src/core/input/InputManager.cc	(revision 1670)
@@ -348,5 +348,5 @@
         for (std::map<int, InputState*>::const_iterator it = inputStatesByPriority_.begin();
             it != inputStatesByPriority_.end(); ++it)
-            (*it).second->setNumOfJoySticks(joySticksSize_);
+            it->second->setNumOfJoySticks(joySticksSize_);
     }
 
@@ -506,7 +506,13 @@
     }
 
+    /**
+    @brief
+        Removes and destroys an InputState.
+    @return
+        True if state was removed immediately, false if postponed.
+    */
     void InputManager::_destroyState(InputState* state)
     {
-        assert(state);
+        assert(state && !(this->internalState_ & Ticking));
         std::map<int, InputState*>::iterator it = this->activeStates_.find(state->getPriority());
         if (it != this->activeStates_.end())
@@ -633,27 +639,35 @@
         internalState_ |= Ticking;
 
-        // check for states to leave (don't use unsigned int!)
-        for (int i = stateLeaveRequests_.size() - 1; i >= 0; --i)
-        {
-            stateLeaveRequests_[i]->onLeave();
+        // check for states to leave
+        for (std::set<InputState*>::reverse_iterator it = stateLeaveRequests_.rbegin();
+            it != stateLeaveRequests_.rend(); ++it)
+        {
+            (*it)->onLeave();
             // just to be sure that the state actually is registered
-            assert(inputStatesByName_.find(stateLeaveRequests_[i]->getName()) != inputStatesByName_.end());
-            
-            activeStates_.erase(stateLeaveRequests_[i]->getPriority());
+            assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());
+
+            activeStates_.erase((*it)->getPriority());
             _updateActiveStates();
-            stateLeaveRequests_.pop_back();
-        }
-
-
-        // check for states to enter (don't use unsigned int!)
-        for (int i = stateEnterRequests_.size() - 1; i >= 0; --i)
+        }
+        stateLeaveRequests_.clear();
+
+        // check for states to enter
+        for (std::set<InputState*>::reverse_iterator it = stateEnterRequests_.rbegin();
+            it != stateEnterRequests_.rend(); ++it)
         {
             // just to be sure that the state actually is registered
-            assert(inputStatesByName_.find(stateEnterRequests_[i]->getName()) != inputStatesByName_.end());
-            
-            activeStates_[stateEnterRequests_[i]->getPriority()] = stateEnterRequests_[i];
+            assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());
+
+            activeStates_[(*it)->getPriority()] = (*it);
             _updateActiveStates();
-            stateEnterRequests_[i]->onEnter();
-            stateEnterRequests_.pop_back();
+            (*it)->onEnter();
+        }
+        stateEnterRequests_.clear();
+
+        // check for states to destroy
+        for (std::set<InputState*>::reverse_iterator it = stateDestroyRequests_.rbegin();
+            it != stateDestroyRequests_.rend(); ++it)
+        {
+            _destroyState((*it));
         }
 
@@ -703,6 +717,6 @@
         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;
+                if (it->second->isInputDeviceEnabled(i))
+                    activeStatesTop_[i] = it->second;
 
         // update tickables (every state will only appear once)
@@ -1135,5 +1149,5 @@
     /**
     @brief
-        Removes an input state internally.
+        Removes and destroys an input state internally.
     @param name
         Name of the handler.
@@ -1142,6 +1156,7 @@
     @remarks
         You can't remove the internal states "empty", "calibrator" and "detector".
-    */
-    bool InputManager::destroyState(const std::string& name)
+        The removal process is being postponed if InputManager::tick() is currently running.
+    */
+    bool InputManager::requestDestroyState(const std::string& name)
     {
         if (name == "empty" || name == "calibrator" || name == "detector")
@@ -1153,5 +1168,18 @@
         if (it != inputStatesByName_.end())
         {
-            _destroyState((*it).second);
+            if (activeStates_.find(it->second->getPriority()) != activeStates_.end())
+            {
+                // The state is still active. We have to postpone
+                stateLeaveRequests_.insert(it->second);
+                stateDestroyRequests_.insert(it->second);
+            }
+            else if (this->internalState_ & Ticking)
+            {
+                // cannot remove state while ticking
+                stateDestroyRequests_.insert(it->second);
+            }
+            else
+                _destroyState(it->second);
+
             return true;
         }
@@ -1171,5 +1199,5 @@
         std::map<std::string, InputState*>::iterator it = inputStatesByName_.find(name);
         if (it != inputStatesByName_.end())
-            return (*it).second;
+            return it->second;
         else
             return 0;
@@ -1202,6 +1230,16 @@
         if (it != inputStatesByName_.end())
         {
-            stateEnterRequests_.push_back((*it).second);
-            return true;
+            // exists
+            if (activeStates_.find(it->second->getPriority()) == activeStates_.end())
+            {
+                // not active
+                if (stateDestroyRequests_.find(it->second) == stateDestroyRequests_.end())
+                {
+                    // not scheduled for destruction
+                    // set prevents a state being added multiple times
+                    stateEnterRequests_.insert(it->second);
+                    return true;
+                }
+            }
         }
         return false;
@@ -1222,6 +1260,11 @@
         if (it != inputStatesByName_.end())
         {
-            stateLeaveRequests_.push_back((*it).second);
-            return true;
+            // exists
+            if (activeStates_.find(it->second->getPriority()) != activeStates_.end())
+            {
+                // active
+                stateLeaveRequests_.insert(it->second);
+                return true;
+            }
         }
         return false;
Index: /code/branches/gui/src/core/input/InputManager.h
===================================================================
--- /code/branches/gui/src/core/input/InputManager.h	(revision 1669)
+++ /code/branches/gui/src/core/input/InputManager.h	(revision 1670)
@@ -127,9 +127,11 @@
         }
 
-        bool destroyState          (const std::string& name);
         InputState* getState       (const std::string& name);
         InputState* getCurrentState();
+        bool requestDestroyState   (const std::string& name);
         bool requestEnterState     (const std::string& name);
         bool requestLeaveState     (const std::string& name);
+
+        void tick(float dt);
 
         static InputManager& getInstance()    { assert(singletonRef_s); return *singletonRef_s; }
@@ -167,6 +169,4 @@
         void _updateActiveStates();
         bool _configureInputState(InputState* state, const std::string& name, int priority);
-
-        void tick(float dt);
 
         // input events
@@ -204,6 +204,7 @@
         std::map<int, InputState*>          inputStatesByPriority_;
 
-        std::vector<InputState*>            stateEnterRequests_;   //!< Request to enter a new state
-        std::vector<InputState*>            stateLeaveRequests_;   //!< Request to leave the current state
+        std::set<InputState*>               stateEnterRequests_;   //!< Request to enter a new state
+        std::set<InputState*>               stateLeaveRequests_;   //!< Request to leave a running state
+        std::set<InputState*>               stateDestroyRequests_; //!< Request to destroy a state
 
         std::map<int, InputState*>          activeStates_;
Index: /code/branches/gui/src/orxonox/Main.cc
===================================================================
--- /code/branches/gui/src/orxonox/Main.cc	(revision 1669)
+++ /code/branches/gui/src/orxonox/Main.cc	(revision 1670)
@@ -44,6 +44,10 @@
 #include "gamestates/GSRoot.h"
 #include "gamestates/GSGraphics.h"
-#include "gamestates/GSLevel.h"
+#include "gamestates/GSStandalone.h"
+#include "gamestates/GSServer.h"
+#include "gamestates/GSClient.h"
 #include "gamestates/GSGUI.h"
+#include "gamestates/GSIO.h"
+#include "gamestates/GSIOConsole.h"
 
 using namespace orxonox;
@@ -77,7 +81,7 @@
 
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+//#ifdef __cplusplus
+//extern "C" {
+//#endif
 
 int main(int argc, char** argv)
@@ -122,20 +126,29 @@
     GSRoot root;
     GSGraphics graphics;
-    GSLevel level;
+    GSStandalone standalone;
+    GSServer server;
+    GSClient client;
     GSGUI gui;
+    GSIO io;
+    GSIOConsole ioConsole;
 
     root.addChild(&graphics);
-    graphics.addChild(&level);
+    graphics.addChild(&standalone);
+    graphics.addChild(&server);
+    graphics.addChild(&client);
     graphics.addChild(&gui);
 
+    root.addChild(&io);
+    io.addChild(&ioConsole);
+
     root.feedCommandLine(argc, argv);
-    root.requestState("root");
-    root.tick(0.0f);
-    root.requestState("");
+    root.requestState("ioConsole");
+    while (!root.isGameFinished())
+        root.tick(0.0f);
 
     return 0;
 }
 
-#ifdef __cplusplus
-}
-#endif
+//#ifdef __cplusplus
+//}
+//#endif
Index: /code/branches/gui/src/orxonox/Orxonox.cc
===================================================================
--- /code/branches/gui/src/orxonox/Orxonox.cc	(revision 1669)
+++ /code/branches/gui/src/orxonox/Orxonox.cc	(revision 1670)
@@ -424,5 +424,5 @@
 
         // tick the core (needs real time for input and tcl thread management)
-        Core::tick(dt);
+        //Core::tick(dt);
 
         // Call those objects that need the real time
Index: /code/branches/gui/src/orxonox/OrxonoxStableHeaders.h
===================================================================
--- /code/branches/gui/src/orxonox/OrxonoxStableHeaders.h	(revision 1669)
+++ /code/branches/gui/src/orxonox/OrxonoxStableHeaders.h	(revision 1670)
@@ -49,4 +49,7 @@
 #include <CEGUI.h>
 #include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/thread.hpp>
 
 //-----------------------------------------------------------------------
Index: /code/branches/gui/src/orxonox/gamestates/GSClient.cc
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSClient.cc	(revision 1670)
+++ /code/branches/gui/src/orxonox/gamestates/GSClient.cc	(revision 1670)
@@ -0,0 +1,87 @@
+/*
+ *   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:
+ *      Fabian 'x3n' Landau
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "GSClient.h"
+
+#include "core/input/InputManager.h"
+#include "core/CommandLine.h"
+#include "network/Client.h"
+
+namespace orxonox
+{
+    SetCommandLineArgument(ip, "127.0.0.0").setInformation("#.#.#.#");
+
+    GSClient::GSClient()
+        : GSLevel("client")
+        , client_(0)
+    {
+    }
+
+    GSClient::~GSClient()
+    {
+    }
+
+    void GSClient::enter()
+    {
+        GSLevel::enter();
+
+        int serverPort = CommandLine::getArgument<int>("port")->getValue();
+        std::string serverIP = CommandLine::getArgument<std::string>("ip")->getValue();
+        this->client_ = network::Client::createSingleton(serverIP, serverPort);
+
+        if(!client_->establishConnection())
+            ThrowException(InitialisationFailed, "Could not establish connection with server.");
+
+        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?
+
+        client_->closeConnection();
+
+        // TODO: destroy client
+
+        GSLevel::leave();
+    }
+
+    void GSClient::ticked(float dt)
+    {
+        GSLevel::ticked(dt);
+        client_->tick(dt);
+
+        this->tickChild(dt);
+    }
+}
Index: /code/branches/gui/src/orxonox/gamestates/GSClient.h
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSClient.h	(revision 1670)
+++ /code/branches/gui/src/orxonox/gamestates/GSClient.h	(revision 1670)
@@ -0,0 +1,54 @@
+/*
+ *   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 _GSClient_H__
+#define _GSClient_H__
+
+#include "OrxonoxPrereqs.h"
+#include "network/NetworkPrereqs.h"
+#include "GSLevel.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport GSClient : public GSLevel
+    {
+    public:
+        GSClient();
+        ~GSClient();
+
+
+    private:
+        void enter();
+        void leave();
+        void ticked(float dt);
+
+        network::Client* client_;
+    };
+}
+
+#endif /* _GSClient_H__ */
Index: /code/branches/gui/src/orxonox/gamestates/GSGUI.cc
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSGUI.cc	(revision 1669)
+++ /code/branches/gui/src/orxonox/gamestates/GSGUI.cc	(revision 1670)
@@ -58,10 +58,10 @@
     }
 
-    bool GSGUI::tick(float dt)
+    void GSGUI::ticked(float dt)
     {
         // tick CEGUI
         GUIManager::getInstance().tick(dt);
 
-        return true;
+        this->tickChild(dt);
     }
 }
Index: /code/branches/gui/src/orxonox/gamestates/GSGUI.h
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSGUI.h	(revision 1669)
+++ /code/branches/gui/src/orxonox/gamestates/GSGUI.h	(revision 1670)
@@ -44,5 +44,5 @@
         void enter();
         void leave();
-        bool tick(float dt);
+        void ticked(float dt);
 
     };
Index: /code/branches/gui/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSGraphics.cc	(revision 1669)
+++ /code/branches/gui/src/orxonox/gamestates/GSGraphics.cc	(revision 1670)
@@ -38,5 +38,6 @@
 #include "core/ConfigValueIncludes.h"
 #include "core/input/InputManager.h"
-#include "core/Core.h"
+#include "core/TclThreadManager.h"
+//#include "core/Core.h"
 #include "overlays/console/InGameConsole.h"
 #include "gui/GUIManager.h"
@@ -48,5 +49,4 @@
         : GameState("graphics")
         , timer_(0)
-        , bAbort_(false)
         , debugRefreshTime_(0.0f)
         , inputManager_(0)
@@ -90,9 +90,4 @@
         // use the ogre timer class to measure time.
         timer_ = new Ogre::Timer();
-
-        // add console commands
-        FunctorMember<GSGraphics>* functor = createFunctor(&GSGraphics::exitGame);
-        functor->setObject(this);
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor, "exit"));
     }
 
@@ -123,5 +118,5 @@
         need the time. So we shouldn't run into problems.
     */
-    bool GSGraphics::tick(float dt)
+    void GSGraphics::ticked(float dt)
     {
         // note: paramter 'dt' is of no meaning
@@ -147,5 +142,5 @@
         {
             timer_->reset();
-            while (!bAbort_)
+            while (!this->hasScheduledTransition())
             {
                 // get current time
@@ -154,12 +149,8 @@
                 float dt = (timeBeforeTick - timeBeforeTickOld) / 1000000.0;
 
-
-                // tick the core (needs real time for input and tcl thread management)
-                // TODO: ticks of InputManager and tcl thread manager have to be separated.
-                Core::tick(dt);
-
-                // tick child state
-                if (this->getActiveChild())
-                    this->getActiveChild()->tick(dt);
+                this->inputManager_->tick(dt);
+                TclThreadManager::getInstance().tick(dt);
+
+                this->tickChild(dt);
 
                 // tick console
@@ -210,5 +201,5 @@
             COUT(1) << ex.what() << std::endl;
             COUT(1) << "Main loop was stopped by an unhandled exception. Shutting down." << std::endl;
-        }        return true;
+        }
     }
 }
Index: /code/branches/gui/src/orxonox/gamestates/GSGraphics.h
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSGraphics.h	(revision 1669)
+++ /code/branches/gui/src/orxonox/gamestates/GSGraphics.h	(revision 1670)
@@ -43,15 +43,12 @@
         ~GSGraphics();
 
-        bool tick(float dt);
         void setConfigValues();
-
-        void exitGame() { this->bAbort_ = true; }
 
     private:
         void enter();
         void leave();
+        void ticked(float dt);
 
         Ogre::Timer*          timer_;            //!< Main loop timer
-        bool                  bAbort_;           //!< aborts the render loop if true
 
         // config values
Index: /code/branches/gui/src/orxonox/gamestates/GSIO.cc
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSIO.cc	(revision 1670)
+++ /code/branches/gui/src/orxonox/gamestates/GSIO.cc	(revision 1670)
@@ -0,0 +1,130 @@
+/*
+ *   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 "OrxonoxStableHeaders.h"
+#include "GSIO.h"
+
+#include <OgreFrameListener.h>
+#include <OgreRoot.h>
+#include <OgreTimer.h>
+
+#include "core/ConsoleCommand.h"
+#include "core/TclThreadManager.h"
+#include "GraphicsEngine.h"
+
+namespace orxonox
+{
+    GSIO::GSIO()
+        : GameState("io")
+        //, timer_(0)
+    {
+    }
+
+    GSIO::~GSIO()
+    {
+    }
+
+    void GSIO::enter()
+    {
+    }
+
+    void GSIO::leave()
+    {
+    }
+
+    void GSIO::ticked(float dt)
+    {
+        this->tickChild(dt);
+        //Ogre::Root& ogreRoot = Ogre::Root::getSingleton();
+
+        //unsigned long frameCount = 0;
+
+        //const unsigned long refreshTime = (unsigned long)(debugRefreshTime_ * 1000000.0f);
+        //unsigned long refreshStartTime = 0;
+        //unsigned long tickTime = 0;
+        //unsigned long oldFrameCount = 0;
+
+        //unsigned long timeBeforeTick = 0;
+        //unsigned long timeBeforeTickOld = 0;
+        //unsigned long timeAfterTick = 0;
+
+        //// TODO: Update time in seconds every 7 seconds to avoid any overflow (7 secs is very tight)
+
+        //COUT(3) << "Orxonox: Starting the main loop." << std::endl;
+
+        //try
+        //{
+        //    timer_->reset();
+        //    while (!this->hasScheduledTransition())
+        //    {
+        //        // get current time
+        //        timeBeforeTickOld = timeBeforeTick;
+        //        timeBeforeTick    = timer_->getMicroseconds();
+        //        float dt = (timeBeforeTick - timeBeforeTickOld) / 1000000.0;
+
+        //        TclThreadManager::getInstance().tick(dt);
+
+        //        this->tickChild(dt);
+
+        //        // get current time once again
+        //        timeAfterTick = timer_->getMicroseconds();
+
+        //        tickTime += timeAfterTick - timeBeforeTick;
+        //        if (timeAfterTick > refreshStartTime + refreshTime)
+        //        {
+        //            GraphicsEngine::getInstance().setAverageTickTime(
+        //                (float)tickTime * 0.001 / (frameCount - oldFrameCount));
+        //            float avgFPS = (float)(frameCount - oldFrameCount) / (timeAfterTick - refreshStartTime) * 1000000.0;
+        //            GraphicsEngine::getInstance().setAverageFramesPerSecond(avgFPS);
+
+        //            oldFrameCount = frameCount;
+        //            tickTime = 0;
+        //            refreshStartTime = timeAfterTick;
+        //        }
+
+        //        // don't forget to call _fireFrameStarted in ogre to make sure
+        //        // everything goes smoothly
+        //        Ogre::FrameEvent evt;
+        //        evt.timeSinceLastFrame = dt;
+        //        evt.timeSinceLastEvent = dt; // note: same time, but shouldn't matter anyway
+        //        ogreRoot._fireFrameStarted(evt);
+
+        //        // again, just to be sure ogre works fine
+        //        ogreRoot._fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
+
+        //        ++frameCount;
+        //    }
+        //}
+        //catch (std::exception& ex)
+        //{
+        //    // something went wrong.
+        //    COUT(1) << ex.what() << std::endl;
+        //    COUT(1) << "Main loop was stopped by an unhandled exception. Shutting down." << std::endl;
+        //}
+    }
+}
Index: /code/branches/gui/src/orxonox/gamestates/GSIO.h
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSIO.h	(revision 1670)
+++ /code/branches/gui/src/orxonox/gamestates/GSIO.h	(revision 1670)
@@ -0,0 +1,53 @@
+/*
+ *   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 _GSIO_H__
+#define _GSIO_H__
+
+#include "OrxonoxPrereqs.h"
+#include <OgrePrerequisites.h>
+#include "core/GameState.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport GSIO : public GameState
+    {
+    public:
+        GSIO();
+        ~GSIO();
+
+    private:
+        void enter();
+        void leave();
+        void ticked(float dt);
+
+        //Ogre::Timer*          timer_;            //!< Main loop timer
+    };
+}
+
+#endif /* _GSIO_H__ */
Index: /code/branches/gui/src/orxonox/gamestates/GSIOConsole.cc
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSIOConsole.cc	(revision 1670)
+++ /code/branches/gui/src/orxonox/gamestates/GSIOConsole.cc	(revision 1670)
@@ -0,0 +1,69 @@
+/*
+ *   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 "OrxonoxStableHeaders.h"
+#include "GSIOConsole.h"
+
+#include <iostream>
+#include <OgreFrameListener.h>
+#include <OgreRoot.h>
+#include <OgreTimer.h>
+
+#include "core/ConsoleCommand.h"
+#include "core/TclThreadManager.h"
+#include "GraphicsEngine.h"
+
+namespace orxonox
+{
+    GSIOConsole::GSIOConsole()
+        : GameState("ioConsole")
+    {
+    }
+
+    GSIOConsole::~GSIOConsole()
+    {
+    }
+
+    void GSIOConsole::enter()
+    {
+    }
+
+    void GSIOConsole::leave()
+    {
+    }
+
+    void GSIOConsole::ticked(float dt)
+    {
+        while (!this->hasScheduledTransition())
+        {
+            std::string command;
+            std::cin >> command;
+            CommandExecutor::execute(command, true);
+        }
+    }
+}
Index: /code/branches/gui/src/orxonox/gamestates/GSIOConsole.h
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSIOConsole.h	(revision 1670)
+++ /code/branches/gui/src/orxonox/gamestates/GSIOConsole.h	(revision 1670)
@@ -0,0 +1,51 @@
+/*
+ *   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 _GSIOConsole_H__
+#define _GSIOConsole_H__
+
+#include "OrxonoxPrereqs.h"
+#include <OgrePrerequisites.h>
+#include "core/GameState.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport GSIOConsole : public GameState
+    {
+    public:
+        GSIOConsole();
+        ~GSIOConsole();
+
+    private:
+        void enter();
+        void leave();
+        void ticked(float dt);
+    };
+}
+
+#endif /* _GSIOConsole_H__ */
Index: /code/branches/gui/src/orxonox/gamestates/GSLevel.cc
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSLevel.cc	(revision 1669)
+++ /code/branches/gui/src/orxonox/gamestates/GSLevel.cc	(revision 1670)
@@ -30,27 +30,21 @@
 #include "GSLevel.h"
 
-#include "core/ConsoleCommand.h"
 #include "core/input/InputManager.h"
 #include "core/input/SimpleInputState.h"
 #include "core/input/KeyBinder.h"
 #include "core/Loader.h"
-#include "core/CommandLine.h"
-#include "overlays/console/InGameConsole.h"
-#include "gui/GUIManager.h"
 #include "objects/Backlight.h"
 #include "tools/ParticleInterface.h"
+#include "Settings.h"
 #include "Radar.h"
-#include "Settings.h"
 #include "GraphicsEngine.h"
 
 namespace orxonox
 {
-    SetCommandLineArgument(port, 55556).setShortcut("p").setInformation("PORT");
-    SetCommandLineArgument(ip, "127.0.0.0").setInformation("#.#.#.#");
-
-    GSLevel::GSLevel()
-        : GameState("level")
+    GSLevel::GSLevel(const std::string& name)
+        : GameState(name)
         , timefactor_(1.0f)
         , keyBinder_(0)
+        , inputState_(0)
         , radar_(0)
         , startLevel_(0)
@@ -65,7 +59,8 @@
     void GSLevel::enter()
     {
+        inputState_ = InputManager::getInstance().createInputState<SimpleInputState>("game", 20);
         keyBinder_ = new KeyBinder();
         keyBinder_->loadBindings();
-        InputManager::getInstance().createInputState<SimpleInputState>("game", 20)->setHandler(keyBinder_);
+        inputState_->setHandler(keyBinder_);
 
         // create Ogre SceneManager for the level
@@ -79,28 +74,8 @@
         hud_ = new Level(Settings::getDataPath() + "overlay/hud.oxo");
         Loader::load(hud_);
-
-        // call the loader
-        COUT(0) << "Loading level..." << std::endl;
-        startLevel_ = new Level(Settings::getDataPath() + "levels/sample.oxw");
-        Loader::open(startLevel_);
-
-        // add console commands
-        FunctorMember<GSLevel>* functor = createFunctor(&GSLevel::setTimeFactor);
-        functor->setObject(this);
-        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor, "setTimeFactor"));
-
-        // level is loaded: we can start capturing the input
-        InputManager::getInstance().requestEnterState("game");
     }
 
     void GSLevel::leave()
     {
-        InputManager::getInstance().requestLeaveState("game");
-
-        // TODO: Remove and destroy console command
-
-        Loader::unload(startLevel_);
-        delete this->startLevel_;
-
         Loader::unload(hud_);
         delete this->hud_;
@@ -116,9 +91,10 @@
         // TODO: delete SceneManager
 
-        InputManager::getInstance().destroyState("game");
+        inputState_->setHandler(0);
+        InputManager::getInstance().requestDestroyState("game");
         delete this->keyBinder_;
     }
 
-    bool GSLevel::tick(float dt)
+    void GSLevel::ticked(float dt)
     {
         // Call those objects that need the real time
@@ -128,13 +104,4 @@
         for (Iterator<Tickable> it = ObjectList<Tickable>::start(); it; ++it)
             it->tick(dt * this->timefactor_);
-
-        // TODO: split file into server/client/standalone
-        // call server/client with normal dt
-        //if (client_g)
-        //    client_g->tick(dt * this->timefactor_);
-        //if (server_g)
-        //    server_g->tick(dt * this->timefactor_);
-
-        return true;
     }
 
@@ -153,3 +120,17 @@
             it->setTimeFactor(timefactor_);
     }
+
+    void GSLevel::loadLevel()
+    {
+        // call the loader
+        COUT(0) << "Loading level..." << std::endl;
+        startLevel_ = new Level(Settings::getDataPath() + "levels/sample.oxw");
+        Loader::open(startLevel_);
+    }
+
+    void GSLevel::unloadLevel()
+    {
+        Loader::unload(startLevel_);
+        delete this->startLevel_;
+    }
 }
Index: /code/branches/gui/src/orxonox/gamestates/GSLevel.h
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSLevel.h	(revision 1669)
+++ /code/branches/gui/src/orxonox/gamestates/GSLevel.h	(revision 1670)
@@ -38,18 +38,26 @@
     {
     public:
-        GSLevel();
-        ~GSLevel();
+        GSLevel(const std::string& name);
+        virtual ~GSLevel();
 
-        bool tick(float dt);
+        // this has to be public because proteced triggers a bug in msvc
+        // when taking the function address.
+        void setTimeFactor(float factor);
+        float getTimeFactor() { return this->timefactor_; }
+
+    protected:
+        virtual void enter();
+        virtual void leave();
+        virtual void ticked(float dt);
+
+        void loadLevel();
+        void unloadLevel();
 
     private:
-        void enter();
-        void leave();
-
-        void setTimeFactor(float factor);
 
         float timefactor_;       //!< A factor to change the gamespeed
 
         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
Index: /code/branches/gui/src/orxonox/gamestates/GSRoot.cc
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSRoot.cc	(revision 1669)
+++ /code/branches/gui/src/orxonox/gamestates/GSRoot.cc	(revision 1670)
@@ -52,4 +52,5 @@
         , settings_(0)
         , graphicsEngine_(0)
+        , bExit_(false)
     {
     }
@@ -101,5 +102,5 @@
 
         std::string dataPath;
-        CommandLine::getCommandLineValue("dataPath", &dataPath);
+        CommandLine::getValue("dataPath", &dataPath);
         if (dataPath != "")
         {
@@ -122,5 +123,8 @@
         CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor, "loadGame"));
 
-        requestState("gui");
+        // add console commands
+        functor = createFunctor(&GSRoot::exitGame);
+        functor->setObject(this);
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor, "exit"));
     }
 
@@ -128,13 +132,12 @@
     {
         delete graphicsEngine_;
+        delete settings_;
 
-        delete settings_;
+        // TODO: remove and destroy console commands
     }
 
-    bool GSRoot::tick(float dt)
+    void GSRoot::ticked(float dt)
     {
-        if (this->getActiveChild())
-            this->getActiveChild()->tick(dt);
-        return true;
+        this->tickChild(dt);
     }
 
Index: /code/branches/gui/src/orxonox/gamestates/GSRoot.h
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSRoot.h	(revision 1669)
+++ /code/branches/gui/src/orxonox/gamestates/GSRoot.h	(revision 1670)
@@ -42,13 +42,18 @@
 
         void feedCommandLine(int argc, char** argv);
-        bool tick(float dt);
         void loadGame(const std::string& name);
+
+        void exitGame()
+        { requestState("root"); }
+        bool isGameFinished() { return (this->getActiveChild() == 0); }
 
     private:
         void enter();
         void leave();
+        void ticked(float dt);
 
         Settings*             settings_;
         GraphicsEngine*       graphicsEngine_;   //!< our dearest graphics engine <3
+        bool                  bExit_;
     };
 }
Index: /code/branches/gui/src/orxonox/gamestates/GSServer.cc
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSServer.cc	(revision 1670)
+++ /code/branches/gui/src/orxonox/gamestates/GSServer.cc	(revision 1670)
@@ -0,0 +1,91 @@
+/*
+ *   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:
+ *      Fabian 'x3n' Landau
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "GSServer.h"
+
+#include "core/ConsoleCommand.h"
+#include "core/input/InputManager.h"
+#include "core/CommandLine.h"
+#include "network/Server.h"
+
+namespace orxonox
+{
+    SetCommandLineArgument(port, 55556).setShortcut("p").setInformation("0-65535");
+
+    GSServer::GSServer()
+        : GSLevel("server")
+        , server_(0)
+    {
+    }
+
+    GSServer::~GSServer()
+    {
+    }
+
+    void GSServer::enter()
+    {
+        GSLevel::enter();
+
+        int serverPort = CommandLine::getArgument<int>("port")->getValue();
+        this->server_ = network::Server::createSingleton(serverPort);
+
+        this->loadLevel();
+
+        server_->open();
+
+        // add console commands
+        FunctorMember<GSLevel>* functor = createFunctor(&GSLevel::setTimeFactor);
+        functor->setObject(this);
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor, "setTimeFactor"));
+
+        // 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();
+
+        this->server_->close();
+        // TODO: destroy server
+
+        GSLevel::leave();
+    }
+
+    void GSServer::ticked(float dt)
+    {
+        GSLevel::ticked(dt);
+        server_->tick(dt);
+        this->tickChild(dt);
+    }
+}
Index: /code/branches/gui/src/orxonox/gamestates/GSServer.h
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSServer.h	(revision 1670)
+++ /code/branches/gui/src/orxonox/gamestates/GSServer.h	(revision 1670)
@@ -0,0 +1,54 @@
+/*
+ *   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 _GSServer_H__
+#define _GSServer_H__
+
+#include "OrxonoxPrereqs.h"
+#include "network/NetworkPrereqs.h"
+#include "GSLevel.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport GSServer : public GSLevel
+    {
+    public:
+        GSServer();
+        ~GSServer();
+
+
+    private:
+        void enter();
+        void leave();
+        void ticked(float dt);
+
+        network::Server*      server_;
+    };
+}
+
+#endif /* _GSServer_H__ */
Index: /code/branches/gui/src/orxonox/gamestates/GSStandalone.cc
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSStandalone.cc	(revision 1670)
+++ /code/branches/gui/src/orxonox/gamestates/GSStandalone.cc	(revision 1670)
@@ -0,0 +1,78 @@
+/*
+ *   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:
+ *      Fabian 'x3n' Landau
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "GSStandalone.h"
+
+#include "core/input/InputManager.h"
+#include "core/ConsoleCommand.h"
+
+namespace orxonox
+{
+    GSStandalone::GSStandalone()
+        : GSLevel("standalone")
+    {
+    }
+
+    GSStandalone::~GSStandalone()
+    {
+    }
+
+    void GSStandalone::enter()
+    {
+        GSLevel::enter();
+
+        this->loadLevel();
+
+        // add console commands
+        FunctorMember<GSLevel>* functor = createFunctor(&GSLevel::setTimeFactor);
+        functor->setObject(this);
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor, "setTimeFactor"));
+
+        // level is loaded: we can start capturing the input
+        InputManager::getInstance().requestEnterState("game");
+    }
+
+    void GSStandalone::leave()
+    {
+        InputManager::getInstance().requestLeaveState("game");
+
+        // TODO: Remove and destroy console command
+
+        this->unloadLevel();
+
+        GSLevel::leave();
+    }
+
+    void GSStandalone::ticked(float dt)
+    {
+        GSLevel::ticked(dt);
+
+        this->tickChild(dt);
+    }
+}
Index: /code/branches/gui/src/orxonox/gamestates/GSStandalone.h
===================================================================
--- /code/branches/gui/src/orxonox/gamestates/GSStandalone.h	(revision 1670)
+++ /code/branches/gui/src/orxonox/gamestates/GSStandalone.h	(revision 1670)
@@ -0,0 +1,51 @@
+/*
+ *   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 _GSStandalone_H__
+#define _GSStandalone_H__
+
+#include "OrxonoxPrereqs.h"
+#include "GSLevel.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport GSStandalone : public GSLevel
+    {
+    public:
+        GSStandalone();
+        ~GSStandalone();
+
+
+    private:
+        void enter();
+        void leave();
+        void ticked(float dt);
+    };
+}
+
+#endif /* _GSStandalone_H__ */
Index: /code/branches/gui/src/orxonox/gui/GUIManager.cc
===================================================================
--- /code/branches/gui/src/orxonox/gui/GUIManager.cc	(revision 1669)
+++ /code/branches/gui/src/orxonox/gui/GUIManager.cc	(revision 1670)
@@ -92,5 +92,5 @@
         }
 
-        InputManager::getInstance().destroyState("gui");
+        InputManager::getInstance().requestDestroyState("gui");
 
         if (guiSystem_)
Index: /code/branches/gui/src/orxonox/overlays/console/InGameConsole.cc
===================================================================
--- /code/branches/gui/src/orxonox/overlays/console/InGameConsole.cc	(revision 1669)
+++ /code/branches/gui/src/orxonox/overlays/console/InGameConsole.cc	(revision 1670)
@@ -95,5 +95,5 @@
 
         // destroy the input state previously created (InputBuffer gets destroyed by the Shell)
-        InputManager::getInstance().destroyState("console");
+        InputManager::getInstance().requestDestroyState("console");
 
         Ogre::OverlayManager* ovMan = Ogre::OverlayManager::getSingletonPtr();
Index: /code/branches/gui/visual_studio/vc8/core.vcproj
===================================================================
--- /code/branches/gui/visual_studio/vc8/core.vcproj	(revision 1669)
+++ /code/branches/gui/visual_studio/vc8/core.vcproj	(revision 1670)
@@ -149,4 +149,8 @@
 			>
 			<File
+				RelativePath="..\..\src\core\BaseGameState.cc"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\core\ConfigFileManager.cc"
 				>
@@ -376,4 +380,8 @@
 			>
 			<File
+				RelativePath="..\..\src\core\BaseGameState.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\core\ConfigFileManager.h"
 				>
Index: /code/branches/gui/visual_studio/vc8/orxonox.vcproj
===================================================================
--- /code/branches/gui/visual_studio/vc8/orxonox.vcproj	(revision 1669)
+++ /code/branches/gui/visual_studio/vc8/orxonox.vcproj	(revision 1670)
@@ -496,4 +496,8 @@
 				>
 				<File
+					RelativePath="..\..\src\orxonox\gamestates\GSClient.cc"
+					>
+				</File>
+				<File
 					RelativePath="..\..\src\orxonox\gamestates\GSGraphics.cc"
 					>
@@ -504,4 +508,12 @@
 				</File>
 				<File
+					RelativePath="..\..\src\orxonox\gamestates\GSIO.cc"
+					>
+				</File>
+				<File
+					RelativePath="..\..\src\orxonox\gamestates\GSIOConsole.cc"
+					>
+				</File>
+				<File
 					RelativePath="..\..\src\orxonox\gamestates\GSLevel.cc"
 					>
@@ -509,4 +521,12 @@
 				<File
 					RelativePath="..\..\src\orxonox\gamestates\GSRoot.cc"
+					>
+				</File>
+				<File
+					RelativePath="..\..\src\orxonox\gamestates\GSServer.cc"
+					>
+				</File>
+				<File
+					RelativePath="..\..\src\orxonox\gamestates\GSStandalone.cc"
 					>
 				</File>
@@ -738,4 +758,8 @@
 				>
 				<File
+					RelativePath="..\..\src\orxonox\gamestates\GSClient.h"
+					>
+				</File>
+				<File
 					RelativePath="..\..\src\orxonox\gamestates\GSGraphics.h"
 					>
@@ -746,4 +770,12 @@
 				</File>
 				<File
+					RelativePath="..\..\src\orxonox\gamestates\GSIO.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\src\orxonox\gamestates\GSIOConsole.h"
+					>
+				</File>
+				<File
 					RelativePath="..\..\src\orxonox\gamestates\GSLevel.h"
 					>
@@ -751,4 +783,12 @@
 				<File
 					RelativePath="..\..\src\orxonox\gamestates\GSRoot.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\src\orxonox\gamestates\GSServer.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\src\orxonox\gamestates\GSStandalone.h"
 					>
 				</File>
