Index: code/trunk/src/libraries/core/Core.cc
===================================================================
--- code/trunk/src/libraries/core/Core.cc	(revision 6536)
+++ code/trunk/src/libraries/core/Core.cc	(revision 6746)
@@ -78,4 +78,5 @@
 
     SetCommandLineArgument(settingsFile, "orxonox.ini").information("THE configuration file");
+    SetCommandLineSwitch(noIOConsole).information("Use this if you don't want to use the IOConsole (for instance for Lua debugging)");
 #ifdef ORXONOX_PLATFORM_WINDOWS
     SetCommandLineArgument(limitToCPU, 1).information("Limits the program to one CPU/core (1, 2, 3, etc.). Default is the first core (faster than off)");
@@ -88,4 +89,5 @@
         , consoleCommandDestroyer_(CommandExecutor::destroyExternalCommands)
         , bGraphicsLoaded_(false)
+        , bStartIOConsole_(true)
     {
         // Set the hard coded fixed paths
@@ -149,5 +151,10 @@
 
         // create persistent io console
-        this->ioConsole_.reset(new IOConsole());
+        if (CommandLineParser::getValue("noIOConsole").getBool())
+        {
+            ModifyConfigValue(bStartIOConsole_, tset, false);
+        }
+        if (this->bStartIOConsole_)
+            this->ioConsole_.reset(new IOConsole());
 
         // creates the class hierarchy for all classes with factories
@@ -193,4 +200,6 @@
             .description("If true, all random actions are different each time you start the game")
             .callback(this, &Core::initRandomNumberGenerator);
+        SetConfigValue(bStartIOConsole_, true)
+            .description("Set to false if you don't want to use the IOConsole (for Lua debugging for instance)");
     }
 
@@ -225,6 +234,5 @@
 
         // Load the CEGUI interface
-        guiManager_.reset(new GUIManager(graphicsManager_->getRenderWindow(),
-            inputManager_->getMousePosition(), graphicsManager_->isFullScreen()));
+        guiManager_.reset(new GUIManager(inputManager_->getMousePosition()));
 
         bGraphicsLoaded_ = true;
@@ -328,5 +336,6 @@
         }
         // Process console events and status line
-        this->ioConsole_->preUpdate(time);
+        if (this->ioConsole_ != NULL)
+            this->ioConsole_->preUpdate(time);
         // Process thread commands
         this->tclThreadManager_->preUpdate(time);
Index: code/trunk/src/libraries/core/Core.h
===================================================================
--- code/trunk/src/libraries/core/Core.h	(revision 6536)
+++ code/trunk/src/libraries/core/Core.h	(revision 6746)
@@ -38,5 +38,5 @@
 #include "util/ScopeGuard.h"
 #include "util/Singleton.h"
-#include "core/OrxonoxClass.h"
+#include "OrxonoxClass.h"
 
 namespace orxonox
@@ -97,5 +97,5 @@
             scoped_ptr<TclBind>           tclBind_;
             scoped_ptr<TclThreadManager>  tclThreadManager_;
-            scoped_ptr<Scope<ScopeID::Root> >     rootScope_;
+            scoped_ptr<Scope<ScopeID::Root> > rootScope_;
             // graphical
             scoped_ptr<GraphicsManager>   graphicsManager_;     //!< Interface to OGRE
@@ -108,4 +108,5 @@
             std::string                   language_;                   //!< The language
             bool                          bInitRandomNumberGenerator_; //!< If true, srand(time(0)) is called
+            bool                          bStartIOConsole_;            //!< Set to false if you don't want to use the IOConsole
 
             static Core*                  singletonPtr_s;
Index: code/trunk/src/libraries/core/GUIManager.cc
===================================================================
--- code/trunk/src/libraries/core/GUIManager.cc	(revision 6536)
+++ code/trunk/src/libraries/core/GUIManager.cc	(revision 6746)
@@ -30,4 +30,5 @@
 #include "GUIManager.h"
 
+#include <boost/bind.hpp>
 #include <memory>
 extern "C" {
@@ -41,4 +42,5 @@
 #include <CEGUISystem.h>
 #include <CEGUIWindow.h>
+#include <CEGUIWindowManager.h>
 #include <ogreceguirenderer/OgreCEGUIRenderer.h>
 
@@ -57,7 +59,11 @@
 #include "ConsoleCommand.h"
 #include "Core.h"
+#include "GraphicsManager.h"
 #include "LuaState.h"
 #include "PathConfig.h"
 #include "Resource.h"
+#include "input/InputManager.h"
+#include "input/InputState.h"
+#include "input/KeyBinderManager.h"
 
 namespace orxonox
@@ -108,9 +114,7 @@
     @return true if success, otherwise false
     */
-    GUIManager::GUIManager(Ogre::RenderWindow* renderWindow, const std::pair<int, int>& mousePosition, bool bFullScreen)
-        : renderWindow_(renderWindow)
-        , resourceProvider_(0)
+    GUIManager::GUIManager(const std::pair<int, int>& mousePosition)
+        : resourceProvider_(NULL)
         , camera_(NULL)
-        , bShowIngameGUI_(false)
     {
         using namespace CEGUI;
@@ -119,5 +123,5 @@
 
         // Note: No SceneManager specified yet
-        guiRenderer_.reset(new OgreCEGUIRenderer(renderWindow_, Ogre::RENDER_QUEUE_OVERLAY, false, 3000));
+        guiRenderer_.reset(new OgreCEGUIRenderer(GraphicsManager::getInstance().getRenderWindow(), Ogre::RENDER_QUEUE_OVERLAY, false, 3000));
         resourceProvider_ = guiRenderer_->createResourceProvider();
         resourceProvider_->setDefaultResourceGroup("GUI");
@@ -141,13 +145,22 @@
         guiSystem_.reset(new System(guiRenderer_.get(), resourceProvider_, 0, scriptModule_.get()));
 
-        // Initialise the basic Lua code
-        this->luaState_->doFile("InitialiseGUI.lua");
-
         // Align CEGUI mouse with OIS mouse
         guiSystem_->injectMousePosition((float)mousePosition.first, (float)mousePosition.second);
 
-        // Hide the mouse cursor unless playing in full screen mode
-        if (!bFullScreen)
-            CEGUI::MouseCursor::getSingleton().hide();
+        // Initialise the Lua framework and load the schemes
+        this->luaState_->doFile("InitialiseGUI.lua");
+
+        // Create the root nodes
+        this->rootWindow_ = CEGUI::WindowManager::getSingleton().createWindow("MenuWidgets/StaticImage", "AbsoluteRootWindow");
+        this->rootWindow_->setProperty("FrameEnabled", "False");
+        this->hudRootWindow_ = CEGUI::WindowManager::getSingleton().createWindow("DefaultWindow", "HUDRootWindow");
+        this->menuRootWindow_ = CEGUI::WindowManager::getSingleton().createWindow("DefaultWindow", "MenuRootWindow");
+        // And connect them
+        CEGUI::System::getSingleton().setGUISheet(this->rootWindow_);
+        this->rootWindow_->addChildWindow(this->hudRootWindow_);
+        this->rootWindow_->addChildWindow(this->menuRootWindow_);
+
+        // Set up the sheet manager in the Lua framework
+        this->luaState_->doFile("SheetManager.lua");
     }
 
@@ -173,5 +186,5 @@
     {
         assert(guiSystem_);
-        guiSystem_->injectTimePulse(time.getDeltaTime());
+        this->protectedCall(boost::bind(&CEGUI::System::injectTimePulse, _1, time.getDeltaTime()));
     }
 
@@ -200,10 +213,17 @@
     @param str
         reference to string object holding the Lua code which is to be executed
-
-        This function gives total access to the GUI. You can execute ANY Lua code here.
     */
     void GUIManager::executeCode(const std::string& str)
     {
         this->luaState_->doString(str, rootFileInfo_);
+    }
+
+    /** Loads a GUI sheet by Lua script
+    @param name
+        The name of the GUI (like the script name, but without the extension)
+    */
+    void GUIManager::loadGUI(const std::string& name)
+    {
+        this->executeCode("loadSheet(\"" + name + "\")");
     }
 
@@ -215,9 +235,8 @@
 
         The function executes the Lua function with the same name in case the GUIManager is ready.
-        For more details check out loadGUI_2.lua where the function presides.
-    */
-    /*static*/ void GUIManager::showGUI(const std::string& name, bool hidePrevious, bool showCursor)
-    {
-        GUIManager::getInstance().executeCode("showGUI(\"" + name + "\", " + multi_cast<std::string>(hidePrevious) + ", " + multi_cast<std::string>(showCursor) + ")");
+    */
+    /*static*/ void GUIManager::showGUI(const std::string& name, bool bHidePrevious)
+    {
+        GUIManager::getInstance().executeCode("showMenuSheet(\"" + name + "\", " + multi_cast<std::string>(bHidePrevious) + ")");
     }
 
@@ -226,7 +245,7 @@
         Hack-ish. Needed for GUIOverlay.
     */
-    void GUIManager::showGUIExtra(const std::string& name, const std::string& ptr, bool hidePrevious, bool showCursor)
-    {
-        this->executeCode("showGUI(\"" + name + "\", " + multi_cast<std::string>(hidePrevious) + ", " + multi_cast<std::string>(showCursor) + ", " + ptr + ")");
+    void GUIManager::showGUIExtra(const std::string& name, const std::string& ptr, bool bHidePrevious)
+    {
+        this->executeCode("showMenuSheet(\"" + name + "\", " + multi_cast<std::string>(bHidePrevious) + ", " + ptr + ")");
     }
 
@@ -239,5 +258,39 @@
     /*static*/ void GUIManager::hideGUI(const std::string& name)
     {
-        GUIManager::getInstance().executeCode("hideGUI(\"" + name + "\")");
+        GUIManager::getInstance().executeCode("hideMenuSheet(\"" + name + "\")");
+    }
+
+    const std::string& GUIManager::createInputState(const std::string& name, TriBool::Value showCursor, TriBool::Value useKeyboard, bool bBlockJoyStick)
+    {
+        InputState* state = InputManager::getInstance().createInputState(name);
+
+        /* Table that maps isFullScreen() and showCursor to mouseExclusive
+        isFullscreen / showCursor | True  | False | Dontcare
+        ----------------------------------------------------
+        true                      | True  | True  | Dontcare
+        ----------------------------------------------------
+        false                     | False | True  | Dontcare
+        */
+        if (showCursor == TriBool::Dontcare)
+            state->setMouseExclusive(TriBool::Dontcare);
+        else if (GraphicsManager::getInstance().isFullScreen() || showCursor == TriBool::False)
+            state->setMouseExclusive(TriBool::True);
+        else
+            state->setMouseExclusive(TriBool::False);
+
+        if (showCursor == TriBool::True)
+            state->setMouseHandler(this);
+        else if (showCursor == TriBool::False)
+            state->setMouseHandler(&InputHandler::EMPTY);
+
+        if (useKeyboard == TriBool::True)
+            state->setKeyHandler(this);
+        else if (useKeyboard == TriBool::False)
+            state->setKeyHandler(&InputHandler::EMPTY);
+
+        if (bBlockJoyStick)
+            state->setJoyStickHandler(&InputHandler::EMPTY);
+
+        return state->getName();
     }
 
@@ -247,17 +300,30 @@
     }
 
-    void GUIManager::setBackground(const std::string& name)
-    {
-        this->executeCode("setBackground(\"" + name + "\")");
+    void GUIManager::setBackgroundImage(const std::string& imageSet, const std::string imageName)
+    {
+        if (imageSet.empty() || imageName.empty())
+            this->setBackgroundImage("");
+        else
+            this->setBackgroundImage("set: " + imageSet + " image: " + imageName);
+    }
+
+    void GUIManager::setBackgroundImage(const std::string& image)
+    {
+        if (image.empty())
+            this->rootWindow_->setProperty("Alpha", "0.0");
+        else
+            this->rootWindow_->setProperty("Alpha", "1.0");
+        this->rootWindow_->setProperty("Image", image);
     }
 
     void GUIManager::keyPressed(const KeyEvent& evt)
     {
-        guiSystem_->injectKeyDown(evt.getKeyCode());
-        guiSystem_->injectChar(evt.getText());
-    }
+        this->protectedCall(boost::bind(&CEGUI::System::injectKeyDown, _1, evt.getKeyCode()));
+        this->protectedCall(boost::bind(&CEGUI::System::injectChar, _1, evt.getText()));
+    }
+
     void GUIManager::keyReleased(const KeyEvent& evt)
     {
-        guiSystem_->injectKeyUp(evt.getKeyCode());
+        this->protectedCall(boost::bind(&CEGUI::System::injectKeyUp, _1, evt.getKeyCode()));
     }
 
@@ -273,13 +339,5 @@
     void GUIManager::buttonPressed(MouseButtonCode::ByEnum id)
     {
-        try
-        {
-            guiSystem_->injectMouseButtonDown(convertButton(id));
-        }
-        catch (CEGUI::ScriptException& ex)
-        {
-            // We simply ignore the exception and proceed
-            COUT(1) << ex.getMessage() << std::endl;
-        }
+        this->protectedCall(boost::bind(&CEGUI::System::injectMouseButtonDown, _1, convertButton(id)));
     }
 
@@ -295,22 +353,15 @@
     void GUIManager::buttonReleased(MouseButtonCode::ByEnum id)
     {
-        try
-        {
-            guiSystem_->injectMouseButtonUp(convertButton(id));
-        }
-        catch (CEGUI::ScriptException& ex)
-        {
-            // We simply ignore the exception and proceed
-            COUT(1) << ex.getMessage() << std::endl;
-        }
+        this->protectedCall(boost::bind(&CEGUI::System::injectMouseButtonUp, _1, convertButton(id)));
     }
 
     void GUIManager::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
     {
-        guiSystem_->injectMousePosition(static_cast<float>(abs.x), static_cast<float>(abs.y));
-    }
+        this->protectedCall(boost::bind(&CEGUI::System::injectMousePosition, _1, (float)abs.x, (float)abs.y));
+    }
+
     void GUIManager::mouseScrolled(int abs, int rel)
     {
-        guiSystem_->injectMouseWheelChange(static_cast<float>(rel));
+        this->protectedCall(boost::bind(&CEGUI::System::injectMouseWheelChange, _1, (float)rel));
     }
 
@@ -349,4 +400,34 @@
     }
 
+    /** Executes a CEGUI function normally, but catches CEGUI::ScriptException.
+        When a ScriptException occurs, the error message will be displayed and
+        the program carries on.
+    @remarks
+        The exception behaviour may pose problems if the code is not written
+        exception-safe (and you can forget about that in Lua). The program might
+        be left in an undefined state. But otherwise one script error would
+        terminate the whole program...
+    @note
+        Your life gets easier if you use boost::bind to create the object/function.
+    @param function
+        Any callable object/function that takes this->guiSystem_ as its only parameter.
+    @return
+        True if input was handled, false otherwise. A caught exception yields true.
+    */
+    template <typename FunctionType>
+    bool GUIManager::protectedCall(FunctionType function)
+    {
+        try
+        {
+            return function(this->guiSystem_);
+        }
+        catch (CEGUI::ScriptException& ex)
+        {
+            // Display the error and proceed. See @remarks why this can be dangerous.
+            COUT(1) << ex.getMessage() << std::endl;
+            return true;
+        }
+    }
+
     void GUIManager::subscribeEventHelper(CEGUI::Window* window, const std::string& event, const std::string& function)
     {
Index: code/trunk/src/libraries/core/GUIManager.h
===================================================================
--- code/trunk/src/libraries/core/GUIManager.h	(revision 6536)
+++ code/trunk/src/libraries/core/GUIManager.h	(revision 6746)
@@ -41,6 +41,12 @@
 
 #include "util/OgreForwardRefs.h"
+#include "util/TriBool.h"
 #include "util/Singleton.h"
 #include "input/InputHandler.h"
+
+// Tolua includes (have to be relative to the current directory)
+/*
+$cfile "../util/TriBool.h" // tolua_export
+*/
 
 namespace orxonox // tolua_export
@@ -54,5 +60,4 @@
 
         The GUIManager is a singleton and can be called anywhere when access on the GUI is needed.
-        Creation of the GUIManager is therefore not possible and the cunstructor is private.
 
         Since the GUI needs user input, the GUIManager implements the functions needed to act as a key and/or mouse handler.
@@ -64,19 +69,27 @@
         friend class Singleton<GUIManager>;
     public:
-        GUIManager(Ogre::RenderWindow* renderWindow, const std::pair<int, int>& mousePosition, bool bFullScreen);
+        GUIManager(const std::pair<int, int>& mousePosition);
         ~GUIManager();
 
         void preUpdate(const Clock& time);
 
-        static void showGUI(const std::string& name, bool hidePrevious=false, bool showCursor=true);
-        void showGUIExtra(const std::string& name, const std::string& ptr, bool hidePrevious=false, bool showCursor=true);
+        void loadGUI(const std::string& name);
+        static void showGUI(const std::string& name, bool bHidePrevious = false);
+        void showGUIExtra(const std::string& name, const std::string& ptr, bool bHidePrevious = false);
         static void hideGUI(const std::string& name);
         void keyESC();
-        void setBackground(const std::string& name);
+        void setBackgroundImage(const std::string& imageSet, const std::string imageName); // tolua_export
+        void setBackgroundImage(const std::string& image);
+
+        //! Creates a new InputState to be used with a GUI Sheet
+        const std::string& createInputState(const std::string& name, TriBool::Value showCursor = TriBool::True, TriBool::Value useKeyboard = TriBool::True, bool bBlockJoyStick = false); // tolua_export
+
+        //! Returns the root window for all menu sheets
+        CEGUI::Window* getMenuRootWindow() { return this->menuRootWindow_; } // tolua_export
+        //! Returns the root window for all HUD sheets
+        CEGUI::Window* getHUDRootWindow() { return this->hudRootWindow_; } // tolua_export
 
         void setCamera(Ogre::Camera* camera);
         Ogre::Camera* getCamera() { return this->camera_; }
-
-        static GUIManager* getInstancePtr() { return singletonPtr_s; }
 
         inline void setPlayer(const std::string& guiname, PlayerInfo* player)
@@ -88,8 +101,13 @@
         static void subscribeEventHelper(CEGUI::Window* window, const std::string& event, const std::string& function); //tolua_export
 
+        static GUIManager& getInstance() { return Singleton<GUIManager>::getInstance(); } // tolua_export
+
     private:
         GUIManager(const GUIManager& instance); //!< private and undefined copy c'tor (this is a singleton class)
 
         void executeCode(const std::string& str);
+
+        template <typename FunctionType>
+        bool protectedCall(FunctionType function);
 
         // keyHandler functions
@@ -102,5 +120,4 @@
         void mouseMoved    (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
         void mouseScrolled (int abs, int rel);
-
         scoped_ptr<CEGUI::OgreCEGUIRenderer> guiRenderer_;      //!< CEGUI's interface to the Ogre Engine
         scoped_ptr<LuaState>                 luaState_;         //!< LuaState, access point to the Lua engine
@@ -108,12 +125,13 @@
         scoped_ptr<CEGUI::System>            guiSystem_;        //!< CEGUI's main system
         shared_ptr<ResourceInfo>             rootFileInfo_;     //!< Resource information about the root script
-        Ogre::RenderWindow*                  renderWindow_;     //!< Ogre's render window to give CEGUI access to it
         CEGUI::ResourceProvider*             resourceProvider_; //!< CEGUI's resource provider
         CEGUI::Logger*                       ceguiLogger_;      //!< CEGUI's logger to be able to log CEGUI errors in our log
-        std::map<std::string, PlayerInfo*>   players_;          //!< Stores the player (owner) for each gui
+        CEGUI::Window*                       rootWindow_;       //!< Root node for all windows
+        CEGUI::Window*                       hudRootWindow_;    //!< Root node for the HUD sheets
+        CEGUI::Window*                       menuRootWindow_;   //!< Root node for the menu sheets (used by Lua)
+        std::map<std::string, PlayerInfo*>   players_;          //!< Stores the player (owner) for each GUI
         Ogre::Camera*                        camera_;           //!< Camera used to render the scene with the GUI
 
         static GUIManager*                   singletonPtr_s;    //!< Singleton reference to GUIManager
-        bool                                 bShowIngameGUI_;
 
     }; // tolua_export
Index: code/trunk/src/libraries/core/Game.h
===================================================================
--- code/trunk/src/libraries/core/Game.h	(revision 6536)
+++ code/trunk/src/libraries/core/Game.h	(revision 6746)
@@ -50,5 +50,5 @@
 #include "util/ScopeGuard.h"
 #include "util/Singleton.h"
-#include "core/OrxonoxClass.h"
+#include "OrxonoxClass.h"
 
 /**
Index: code/trunk/src/libraries/core/IOConsole.cc
===================================================================
--- code/trunk/src/libraries/core/IOConsole.cc	(revision 6536)
+++ code/trunk/src/libraries/core/IOConsole.cc	(revision 6746)
@@ -35,6 +35,6 @@
 #include "util/Clock.h"
 #include "util/Math.h"
-#include "core/Game.h"
-#include "core/input/InputBuffer.h"
+#include "Game.h"
+#include "input/InputBuffer.h"
 
 // ##########################
Index: code/trunk/src/libraries/core/IOConsole.h
===================================================================
--- code/trunk/src/libraries/core/IOConsole.h	(revision 6536)
+++ code/trunk/src/libraries/core/IOConsole.h	(revision 6746)
@@ -37,5 +37,5 @@
 #include <vector>
 #include "util/Singleton.h"
-#include "core/Shell.h"
+#include "Shell.h"
 
 #ifdef ORXONOX_PLATFORM_UNIX
Index: code/trunk/src/libraries/core/LuaState.cc
===================================================================
--- code/trunk/src/libraries/core/LuaState.cc	(revision 6536)
+++ code/trunk/src/libraries/core/LuaState.cc	(revision 6746)
@@ -37,4 +37,7 @@
 
 #include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/ScopeGuard.h"
+#include "IOConsole.h"
 #include "Resource.h"
 #include "ToluaBindCore.h"
@@ -54,4 +57,5 @@
         // Create new lua state and configure it
         luaState_ = lua_open();
+        Loki::ScopeGuard luaStateGuard = Loki::MakeGuard(&lua_close, luaState_);
 #if LUA_VERSION_NUM == 501
         luaL_openlibs(luaState_);
@@ -78,5 +82,8 @@
 
         // Parse init script
-        this->doFile("LuaStateInit.lua");
+        if (!this->doFile("LuaStateInit.lua"))
+            ThrowException(InitialisationFailed, "Running LuaStateInit.lua failed");
+
+        luaStateGuard.Dismiss();
     }
 
@@ -96,14 +103,17 @@
     }
 
-    void LuaState::includeFile(const std::string& filename)
+    bool LuaState::includeFile(const std::string& filename)
     {
         shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename);
         if (sourceInfo != NULL)
-            this->includeString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
-        else
-            COUT(2) << "LuaState: Cannot include file '" << filename << "'." << std::endl;
-    }
-
-    void LuaState::includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
+            return this->includeString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
+        else
+        {
+            COUT(2) << "LuaState: Cannot include file '" << filename << "' (not found)." << std::endl;
+            return false;
+        }
+    }
+
+    bool LuaState::includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
     {
         // Parse string with provided include parser (otherwise don't preparse at all)
@@ -114,17 +124,36 @@
             luaInput = code;
 
-        this->doString(luaInput, sourceFileInfo);
-    }
-
-    void LuaState::doFile(const std::string& filename)
+        if (sourceFileInfo != NULL)
+        {
+            // Also fill a map with the actual source code. This is just for the include* commands
+            // where the content of sourceFileInfo->filename doesn't match 'code'
+            this->sourceCodeMap_[sourceFileInfo->filename] = code;
+        }
+
+        bool returnValue = this->doString(luaInput, sourceFileInfo);
+
+        if (sourceFileInfo != NULL)
+        {
+            // Delete source code entry
+            if (sourceFileInfo != NULL)
+                this->sourceCodeMap_.erase(sourceFileInfo->filename);
+        }
+
+        return returnValue;
+    }
+
+    bool LuaState::doFile(const std::string& filename)
     {
         shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename);
         if (sourceInfo != NULL)
-            this->doString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
-        else
-            COUT(2) << "LuaState: Cannot do file '" << filename << "'." << std::endl;
-    }
-
-    void LuaState::doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
+            return this->doString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
+        else
+        {
+            COUT(2) << "LuaState: Cannot do file '" << filename << "' (not found)." << std::endl;
+            return false;
+        }
+    }
+
+    bool LuaState::doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
     {
         // Save the old source file info
@@ -134,31 +163,91 @@
             sourceFileInfo_ = sourceFileInfo;
 
-        int error = 0;
+        std::string chunkname;
+        if (sourceFileInfo != NULL)
+        {
+            // Provide lua_load with the filename for debug purposes
+            // The '@' is a Lua convention to identify the chunk name as filename
+            chunkname = '@' + sourceFileInfo->filename;
+        }
+        else
+        {
+            // Use the code string to identify the chunk
+            chunkname = code;
+        }
+
+        // Push custom error handler that uses the debugger
+        lua_getglobal(this->luaState_, "errorHandler");
+        int errorHandler = lua_gettop(luaState_);
+        if (lua_isnil(this->luaState_, -1))
+        {
+            lua_pop(this->luaState_, 1);
+            errorHandler = 0;
+        }
+
 #if LUA_VERSION_NUM != 501
         LoadS ls;
         ls.s = code.c_str();
         ls.size = code.size();
-        error = lua_load(luaState_, &orxonox::LuaState::lua_Chunkreader, &ls, code.c_str());
+        int error = lua_load(luaState_, &orxonox::LuaState::lua_Chunkreader, &ls, chunkname.c_str());
 #else
-        error = luaL_loadstring(luaState_, code.c_str());
+        int error = luaL_loadbuffer(luaState_, code.c_str(), code.size(), chunkname.c_str());
 #endif
 
-        // execute the chunk
+        switch (error)
+        {
+        case LUA_ERRSYNTAX: // Syntax error
+            COUT(1) << "Lua syntax error: " << lua_tostring(luaState_, -1) << std::endl;
+            break;
+        case LUA_ERRMEM:    // Memory allocation error
+            COUT(1) << "Lua memory allocation error: Consult your dentist immediately!" << std::endl;
+            break;
+        }
+
         if (error == 0)
-            error = lua_pcall(luaState_, 0, 1, 0);
+        {
+            // Execute the chunk in protected mode with an error handler function (stack index)
+            error = lua_pcall(luaState_, 0, 1, errorHandler);
+
+            switch (error)
+            {
+            case LUA_ERRRUN: // Runtime error
+                if (errorHandler)
+                {
+                    // Do nothing (we already display the error in the
+                    // 'errorHandler' Lua function in LuaStateInit.lua)
+                }
+                else
+                {
+                    std::string errorString = lua_tostring(this->luaState_, -1);
+                    if (errorString.find("Error propagation") == std::string::npos)
+                        COUT(1) << "Lua runtime error: " << errorString << std::endl;
+                }
+                break;
+            case LUA_ERRERR: // Error in the error handler
+                COUT(1) << "Lua error in error handler. No message available." << std::endl;
+                break;
+            case LUA_ERRMEM: // Memory allocation error
+                COUT(1) << "Lua memory allocation error: Consult your dentist immediately!" << std::endl;
+                break;
+            }
+        }
+
         if (error != 0)
         {
-            std::string origin;
-            if (sourceFileInfo != NULL)
-                origin = " originating from " + sourceFileInfo_->filename;
-            COUT(1) << "Error in Lua-script" << origin << ": " << lua_tostring(luaState_, -1) << std::endl;
-            // return value is nil
-            lua_pushnil(luaState_);
-        }
-        // push return value because it will get lost since the return value of this function is void
+            lua_pop(luaState_, 1);  // Remove error message
+            lua_pushnil(luaState_); // Push a nil return value
+        }
+
+        if (errorHandler != 0)
+            lua_remove(luaState_, errorHandler); // Remove error handler from stack
+
+        // Set return value to a global variable because we cannot return a table in this function
+        // here. It would work for numbers, pointers and strings, but certainly not for Lua tables.
         lua_setglobal(luaState_, "LuaStateReturnValue");
 
         // Load the old info again
         sourceFileInfo_ = oldSourceFileInfo;
+
+        return (error == 0);
     }
 
@@ -180,4 +269,24 @@
         else
             return true;
+    }
+
+    //! Returns the content of a file
+    std::string LuaState::getSourceCode(const std::string& filename)
+    {
+        // Try the internal map first to get the actual Lua code
+        // and not just some pseudo Lua-XML code when using include* commands
+        std::map<std::string, std::string>::const_iterator it = this->sourceCodeMap_.find(filename);
+        if (it != this->sourceCodeMap_.end())
+            return it->second;
+        shared_ptr<ResourceInfo> info = Resource::getInfo(filename);
+        if (info == NULL)
+            return "";
+        else
+            return Resource::open(info)->getAsString();
+    }
+
+    bool LuaState::usingIOConsole() const
+    {
+        return IOConsole::exists();
     }
 
Index: code/trunk/src/libraries/core/LuaState.h
===================================================================
--- code/trunk/src/libraries/core/LuaState.h	(revision 6536)
+++ code/trunk/src/libraries/core/LuaState.h	(revision 6746)
@@ -40,5 +40,5 @@
 
 #include "util/ScopeGuard.h"
-#include "core/Functor.h"
+#include "Functor.h"
 #include "ToluaInterface.h"
 
@@ -71,13 +71,14 @@
         ~LuaState();
 
-        void doFile(const std::string& filename); // tolua_export
-        void doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>());
+        bool doFile(const std::string& filename); // tolua_export
+        bool doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>());
 
-        void includeFile(const std::string& filename); // tolua_export
-        void includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>());
+        bool includeFile(const std::string& filename); // tolua_export
+        bool includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>());
 
         void luaPrint(const std::string& str); // tolua_export
         void luaLog(unsigned int level, const std::string& message); // tolua_export
         bool fileExists(const std::string& filename); // tolua_export
+        std::string getSourceCode(const std::string& filename); // tolua_export
 
         const std::stringstream& getOutput() const { return output_; }
@@ -91,4 +92,6 @@
 
         Functor* createLuaFunctor(const std::string& code) { return new LuaFunctor(code, this); } // tolua_export
+        //! Tells about whether IOConsole was activated. The Lua debugger only works with a normal console.
+        bool usingIOConsole() const; // tolua_export
 
         static bool addToluaInterface(int (*function)(lua_State*), const std::string& name);
@@ -114,4 +117,5 @@
         bool bIsRunning_;
         shared_ptr<ResourceInfo> sourceFileInfo_;
+        std::map<std::string, std::string> sourceCodeMap_;
         std::string (*includeParseFunction_)(const std::string&);
 
Index: code/trunk/src/libraries/core/Resource.cc
===================================================================
--- code/trunk/src/libraries/core/Resource.cc	(revision 6536)
+++ code/trunk/src/libraries/core/Resource.cc	(revision 6746)
@@ -29,5 +29,7 @@
 #include "Resource.h"
 
+#include <boost/filesystem/path.hpp>
 #include <OgreException.h>
+#include <OgreFileSystem.h>
 #include <OgreResourceGroupManager.h>
 
@@ -89,4 +91,10 @@
                 ptr->group = group;
                 ptr->size = it->uncompressedSize;
+                if (dynamic_cast<Ogre::FileSystemArchive*>(it->archive) != NULL)
+                {
+                    boost::filesystem::path base(it->archive->getName());
+                    base /= it->filename;
+                    ptr->fileSystemPath = base.string();
+                }
                 return ptr;
             }
Index: code/trunk/src/libraries/core/Resource.h
===================================================================
--- code/trunk/src/libraries/core/Resource.h	(revision 6536)
+++ code/trunk/src/libraries/core/Resource.h	(revision 6746)
@@ -57,4 +57,6 @@
         //! Uncompressed size
         size_t size;
+        //! Absolute file path ("" for files not on filesystem)
+        std::string fileSystemPath;
     };
 
Index: code/trunk/src/libraries/core/Template.cc
===================================================================
--- code/trunk/src/libraries/core/Template.cc	(revision 6536)
+++ code/trunk/src/libraries/core/Template.cc	(revision 6746)
@@ -33,6 +33,6 @@
 
 #include "util/Debug.h"
-#include "core/CoreIncludes.h"
-#include "core/XMLPort.h"
+#include "CoreIncludes.h"
+#include "XMLPort.h"
 
 namespace orxonox
Index: code/trunk/src/libraries/core/input/InputDevice.h
===================================================================
--- code/trunk/src/libraries/core/input/InputDevice.h	(revision 6536)
+++ code/trunk/src/libraries/core/input/InputDevice.h	(revision 6746)
@@ -159,5 +159,5 @@
             for (unsigned int iB = 0; iB < pressedButtons_.size(); ++iB)
                 for (unsigned int iS = 0; iS < inputStates_.size(); ++iS)
-                    inputStates_[iS]->buttonEvent<ButtonEvent::THold, Traits>(
+                    inputStates_[iS]->buttonEvent<ButtonEvent::THold, typename Traits::ButtonTypeParam>(
                         this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(pressedButtons_[iB]));
 
@@ -196,5 +196,5 @@
             // Call states
             for (unsigned int i = 0; i < inputStates_.size(); ++i)
-                inputStates_[i]->buttonEvent<ButtonEvent::TPress, Traits>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
+                inputStates_[i]->buttonEvent<ButtonEvent::TPress, typename Traits::ButtonTypeParam>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
         }
 
@@ -218,5 +218,5 @@
             // Call states
             for (unsigned int i = 0; i < inputStates_.size(); ++i)
-                inputStates_[i]->buttonEvent<ButtonEvent::TRelease, Traits>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
+                inputStates_[i]->buttonEvent<ButtonEvent::TRelease, typename Traits::ButtonTypeParam>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
         }
 
Index: code/trunk/src/libraries/core/input/InputHandler.h
===================================================================
--- code/trunk/src/libraries/core/input/InputHandler.h	(revision 6536)
+++ code/trunk/src/libraries/core/input/InputHandler.h	(revision 6746)
@@ -112,16 +112,10 @@
         virtual ~InputHandler() { }
 
-        template<class T> void buttonEvent(unsigned int device, const T& button, ButtonEvent::TPress)
+        template<class T> void buttonEvent(unsigned int device, T button, ButtonEvent::TPress)
             { this->buttonPressed(button); }
-        template<class T> void buttonEvent(unsigned int device, const T& button, ButtonEvent::TRelease)
+        template<class T> void buttonEvent(unsigned int device, T button, ButtonEvent::TRelease)
             { this->buttonReleased(button); }
-        template<class T> void buttonEvent(unsigned int device, const T& button, ButtonEvent::THold)
+        template<class T> void buttonEvent(unsigned int device, T button, ButtonEvent::THold)
             { this->buttonHeld(button); }
-        void buttonEvent(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TPress)
-            { this->buttonPressed(device - InputDeviceEnumerator::FirstJoyStick, button); }
-        void buttonEvent(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TRelease)
-            { this->buttonReleased(device - InputDeviceEnumerator::FirstJoyStick, button); }
-        void buttonEvent(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::THold)
-            { this->buttonHeld(device - InputDeviceEnumerator::FirstJoyStick, button); }
 
         virtual void buttonPressed (const KeyEvent& evt) { }
@@ -149,4 +143,11 @@
         static InputHandler EMPTY;
     };
+
+    template<> inline void InputHandler::buttonEvent<JoyStickButtonCode::ByEnum>(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TPress)
+        { this->buttonPressed(device - InputDeviceEnumerator::FirstJoyStick, button); }
+    template<> inline void InputHandler::buttonEvent<JoyStickButtonCode::ByEnum>(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TRelease)
+        { this->buttonReleased(device - InputDeviceEnumerator::FirstJoyStick, button); }
+    template<> inline void InputHandler::buttonEvent<JoyStickButtonCode::ByEnum>(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::THold)
+        { this->buttonHeld(device - InputDeviceEnumerator::FirstJoyStick, button); }
 }
 
Index: code/trunk/src/libraries/core/input/InputManager.cc
===================================================================
--- code/trunk/src/libraries/core/input/InputManager.cc	(revision 6536)
+++ code/trunk/src/libraries/core/input/InputManager.cc	(revision 6746)
@@ -87,5 +87,5 @@
         , oisInputManager_(0)
         , devices_(2)
-        , mouseMode_(MouseMode::Nonexclusive)
+        , exclusiveMouse_(TriBool::False)
         , emptyState_(0)
         , calibratorCallbackHandler_(0)
@@ -95,8 +95,11 @@
         CCOUT(4) << "Constructing..." << std::endl;
 
+        // Allocate space for the function call buffer
+        this->callBuffer_.reserve(16);
+
         this->setConfigValues();
 
         if (GraphicsManager::getInstance().isFullScreen())
-            mouseMode_ = MouseMode::Exclusive;
+            exclusiveMouse_ = TriBool::True;
         this->loadDevices();
 
@@ -155,5 +158,5 @@
         paramList.insert(std::make_pair("w32_keyboard", "DISCL_FOREGROUND"));
         paramList.insert(std::make_pair("w32_mouse", "DISCL_FOREGROUND"));
-        if (mouseMode_ == MouseMode::Exclusive || GraphicsManager::getInstance().isFullScreen())
+        if (exclusiveMouse_ == TriBool::True || GraphicsManager::getInstance().isFullScreen())
         {
             // Disable Windows key plus special keys (like play, stop, next, etc.)
@@ -168,5 +171,5 @@
         paramList.insert(std::make_pair("XAutoRepeatOn", "true"));
 
-        if (mouseMode_ == MouseMode::Exclusive || GraphicsManager::getInstance().isFullScreen())
+        if (exclusiveMouse_ == TriBool::True || GraphicsManager::getInstance().isFullScreen())
         {
             if (CommandLineParser::getValue("keyboard_no_grab").getBool())
@@ -266,12 +269,17 @@
         CCOUT(3) << "Destroying..." << std::endl;
 
+        // Leave all active InputStates (except "empty")
+        while (this->activeStates_.size() > 1)
+            this->leaveState(this->activeStates_.rbegin()->second->getName());
+        this->activeStates_.clear();
+
         // Destroy calibrator helper handler and state
         this->destroyState("calibrator");
         // Destroy KeyDetector and state
         calibratorCallbackHandler_->destroy();
-        // destroy the empty InputState
+        // Destroy the empty InputState
         this->destroyStateInternal(this->emptyState_);
 
-        // destroy all user InputStates
+        // Destroy all user InputStates
         while (statesByName_.size() > 0)
             this->destroyStateInternal(statesByName_.rbegin()->second);
@@ -335,12 +343,5 @@
     void InputManager::reload()
     {
-        if (internalState_ & Ticking)
-        {
-            // We cannot destroy OIS right now, because reload was probably
-            // caused by a user clicking on a GUI item. The stack trace would then
-            // include an OIS method. So it would be a very bad thing to destroy it..
-            internalState_ |= ReloadRequest;
-        }
-        else if (internalState_ & Calibrating)
+        if (internalState_ & Calibrating)
             CCOUT(2) << "Warning: Cannot reload input system. Joy sticks are currently being calibrated." << std::endl;
         else
@@ -351,5 +352,5 @@
     void InputManager::reloadInternal()
     {
-        CCOUT(3) << "Reloading ..." << std::endl;
+        CCOUT(4) << "Reloading ..." << std::endl;
 
         this->destroyDevices();
@@ -357,5 +358,4 @@
 
         internalState_ &= ~Bad;
-        internalState_ &= ~ReloadRequest;
         CCOUT(4) << "Reloading complete." << std::endl;
     }
@@ -370,68 +370,4 @@
         if (internalState_ & Bad)
             ThrowException(General, "InputManager was not correctly reloaded.");
-
-        else if (internalState_ & ReloadRequest)
-            reloadInternal();
-
-        // check for states to leave
-        if (!stateLeaveRequests_.empty())
-        {
-            for (std::set<InputState*>::iterator it = stateLeaveRequests_.begin();
-                it != stateLeaveRequests_.end(); ++it)
-            {
-                (*it)->left();
-                // just to be sure that the state actually is registered
-                assert(statesByName_.find((*it)->getName()) != statesByName_.end());
-
-                activeStates_.erase((*it)->getPriority());
-                if ((*it)->getPriority() < InputStatePriority::HighPriority)
-                    (*it)->setPriority(0);
-                updateActiveStates();
-            }
-            stateLeaveRequests_.clear();
-        }
-
-        // check for states to enter
-        if (!stateEnterRequests_.empty())
-        {
-            for (std::set<InputState*>::const_iterator it = stateEnterRequests_.begin();
-                it != stateEnterRequests_.end(); ++it)
-            {
-                // just to be sure that the state actually is registered
-                assert(statesByName_.find((*it)->getName()) != statesByName_.end());
-
-                if ((*it)->getPriority() == 0)
-                {
-                    // Get smallest possible priority between 1 and maxStateStackSize_s
-                    for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
-                        rit != activeStates_.rend(); ++rit)
-                    {
-                        if (rit->first < InputStatePriority::HighPriority)
-                        {
-                            (*it)->setPriority(rit->first + 1);
-                            break;
-                        }
-                    }
-                    // In case no normal handler was on the stack
-                    if ((*it)->getPriority() == 0)
-                        (*it)->setPriority(1);
-                }
-                activeStates_[(*it)->getPriority()] = (*it);
-                updateActiveStates();
-                (*it)->entered();
-            }
-            stateEnterRequests_.clear();
-        }
-
-        // check for states to destroy
-        if (!stateDestroyRequests_.empty())
-        {
-            for (std::set<InputState*>::iterator it = stateDestroyRequests_.begin();
-                it != stateDestroyRequests_.end(); ++it)
-            {
-                destroyStateInternal((*it));
-            }
-            stateDestroyRequests_.clear();
-        }
 
         // check whether a state has changed its EMPTY situation
@@ -448,17 +384,25 @@
             updateActiveStates();
 
-        // mark that we now start capturing and distributing input
-        internalState_ |= Ticking;
-
-        // Capture all the input and handle it
+        // Capture all the input and collect the function calls
+        // No event gets triggered here yet!
         BOOST_FOREACH(InputDevice* device, devices_)
             if (device != NULL)
                 device->update(time);
 
-        // Update the states
+        // Collect function calls for the update
         for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
             activeStatesTicked_[i]->update(time.getDeltaTime());
 
-        internalState_ &= ~Ticking;
+        // Execute all cached function calls in order
+        // Why so complicated? The problem is that an InputHandler could trigger
+        // a reload that would destroy the OIS devices or it could even leave and
+        // then destroy its own InputState. That would of course lead to access
+        // violations.
+        // If we delay the calls, then OIS and and the InputStates are not anymore
+        // in the call stack and can therefore be edited.
+        for (size_t i = 0; i < this->callBuffer_.size(); ++i)
+            this->callBuffer_[i]();
+
+        this->callBuffer_.clear();
     }
 
@@ -470,6 +414,6 @@
     void InputManager::updateActiveStates()
     {
-        assert((internalState_ & InputManager::Ticking) == 0);
-        // temporary resize
+        // Calculate the stack of input states
+        // and assign it to the corresponding device
         for (unsigned int i = 0; i < devices_.size(); ++i)
         {
@@ -490,6 +434,6 @@
         }
 
-        // update tickables (every state will only appear once)
-        // Using a std::set to avoid duplicates
+        // See that we only update each InputState once for each device
+        // Using an std::set to avoid duplicates
         std::set<InputState*> tempSet;
         for (unsigned int i = 0; i < devices_.size(); ++i)
@@ -498,5 +442,5 @@
                     tempSet.insert(devices_[i]->getStateListRef()[iState]);
 
-        // copy the content of the std::set back to the actual vector
+        // Copy the content of the std::set back to the actual vector
         activeStatesTicked_.clear();
         for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
@@ -504,13 +448,13 @@
 
         // Check whether we have to change the mouse mode
-        MouseMode::Value requestedMode = MouseMode::Dontcare;
+        TriBool::Value requestedMode = TriBool::Dontcare;
         std::vector<InputState*>& mouseStates = devices_[InputDeviceEnumerator::Mouse]->getStateListRef();
         if (mouseStates.empty())
-            requestedMode = MouseMode::Nonexclusive;
-        else
-            requestedMode = mouseStates.front()->getMouseMode();
-        if (requestedMode != MouseMode::Dontcare && mouseMode_ != requestedMode)
-        {
-            mouseMode_ = requestedMode;
+            requestedMode = TriBool::False;
+        else
+            requestedMode = mouseStates.front()->getMouseExclusive();
+        if (requestedMode != TriBool::Dontcare && exclusiveMouse_ != requestedMode)
+        {
+            exclusiveMouse_ = requestedMode;
             if (!GraphicsManager::getInstance().isFullScreen())
                 this->reloadInternal();
@@ -622,23 +566,28 @@
         // get pointer from the map with all stored handlers
         std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name);
-        if (it != statesByName_.end())
-        {
-            // exists
-            if (activeStates_.find(it->second->getPriority()) == activeStates_.end())
-            {
-                // not active
-                if (stateDestroyRequests_.find(it->second) == stateDestroyRequests_.end())
+        if (it != statesByName_.end() && activeStates_.find(it->second->getPriority()) == activeStates_.end())
+        {
+            // exists and not active
+            if (it->second->getPriority() == 0)
+            {
+                // Get smallest possible priority between 1 and maxStateStackSize_s
+                for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
+                    rit != activeStates_.rend(); ++rit)
                 {
-                    // not scheduled for destruction
-                    // prevents a state from being added multiple times
-                    stateEnterRequests_.insert(it->second);
-                    return true;
+                    if (rit->first < InputStatePriority::HighPriority)
+                    {
+                        it->second->setPriority(rit->first + 1);
+                        break;
+                    }
                 }
-            }
-            else if (this->stateLeaveRequests_.find(it->second) != this->stateLeaveRequests_.end())
-            {
-                // State already scheduled for leaving --> cancel
-                this->stateLeaveRequests_.erase(this->stateLeaveRequests_.find(it->second));
-            }
+                // In case no normal handler was on the stack
+                if (it->second->getPriority() == 0)
+                    it->second->setPriority(1);
+            }
+            activeStates_[it->second->getPriority()] = it->second;
+            updateActiveStates();
+            it->second->entered();
+
+            return true;
         }
         return false;
@@ -654,18 +603,16 @@
         // get pointer from the map with all stored handlers
         std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name);
-        if (it != statesByName_.end())
-        {
-            // exists
-            if (activeStates_.find(it->second->getPriority()) != activeStates_.end())
-            {
-                // active
-                stateLeaveRequests_.insert(it->second);
-                return true;
-            }
-            else if (this->stateEnterRequests_.find(it->second) != this->stateEnterRequests_.end())
-            {
-                // State already scheduled for entering --> cancel
-                this->stateEnterRequests_.erase(this->stateEnterRequests_.find(it->second));
-            }
+        if (it != statesByName_.end() && activeStates_.find(it->second->getPriority()) != activeStates_.end())
+        {
+            // exists and active
+
+            it->second->left();
+
+            activeStates_.erase(it->second->getPriority());
+            if (it->second->getPriority() < InputStatePriority::HighPriority)
+                it->second->setPriority(0);
+            updateActiveStates();
+
+            return true;
         }
         return false;
@@ -682,17 +629,6 @@
         if (it != statesByName_.end())
         {
-            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
-                destroyStateInternal(it->second);
+            this->leaveState(name);
+            destroyStateInternal(it->second);
 
             return true;
@@ -704,11 +640,5 @@
     void InputManager::destroyStateInternal(InputState* state)
     {
-        assert(state && !(this->internalState_ & Ticking));
-        std::map<int, InputState*>::iterator it = this->activeStates_.find(state->getPriority());
-        if (it != this->activeStates_.end())
-        {
-            this->activeStates_.erase(it);
-            updateActiveStates();
-        }
+        assert(state && this->activeStates_.find(state->getPriority()) == this->activeStates_.end());
         statesByName_.erase(state->getName());
         state->destroy();
Index: code/trunk/src/libraries/core/input/InputManager.h
===================================================================
--- code/trunk/src/libraries/core/input/InputManager.h	(revision 6536)
+++ code/trunk/src/libraries/core/input/InputManager.h	(revision 6746)
@@ -36,8 +36,9 @@
 #include <string>
 #include <vector>
+#include <boost/function.hpp>
 
 #include "util/Singleton.h"
+#include "util/TriBool.h"
 #include "core/WindowEventListener.h"
-#include "InputState.h"
 
 // tolua_begin
@@ -75,7 +76,5 @@
             Nothing       = 0x00,
             Bad           = 0x02,
-            Ticking       = 0x04,
-            Calibrating   = 0x08,
-            ReloadRequest = 0x10,
+            Calibrating   = 0x04,
         };
 
@@ -159,5 +158,5 @@
             - The removal process is being postponed if InputManager::preUpdate() is currently running.
         */
-        bool destroyState(const std::string& name);
+        bool destroyState(const std::string& name); // tolua_export
 
         //-------------------------------
@@ -169,5 +168,14 @@
         //! Returns a pointer to the OIS InputManager. Only you if you know what you're doing!
         OIS::InputManager* getOISInputManager() { return this->oisInputManager_; }
+        //! Returns the position of the cursor as std::pair of ints
         std::pair<int, int> getMousePosition() const;
+        //! Tells whether the mouse is used exclusively to the game
+        bool isMouseExclusive() const { return this->exclusiveMouse_; } // tolua_export
+
+        //-------------------------------
+        // Function call caching
+        //-------------------------------
+        void pushCall(const boost::function<void ()>& function)
+            { this->callBuffer_.push_back(function); }
 
         static InputManager& getInstance() { return Singleton<InputManager>::getInstance(); } // tolua_export
@@ -196,5 +204,5 @@
         OIS::InputManager*                  oisInputManager_;      //!< OIS input manager
         std::vector<InputDevice*>           devices_;              //!< List of all input devices (keyboard, mouse, joy sticks)
-        MouseMode::Value                    mouseMode_;            //!< Currently applied mouse mode
+        TriBool::Value                      exclusiveMouse_;       //!< Currently applied mouse mode
 
         // some internally handled states and handlers
@@ -207,7 +215,5 @@
         std::vector<InputState*>            activeStatesTicked_;   //!< Like activeStates_, but only contains the ones that currently receive events
 
-        std::set<InputState*>               stateEnterRequests_;   //!< Requests to enter a new state
-        std::set<InputState*>               stateLeaveRequests_;   //!< Requests to leave a running state
-        std::set<InputState*>               stateDestroyRequests_; //!< Requests to destroy a state
+        std::vector<boost::function<void ()> > callBuffer_;        //!< Caches all calls from InputStates to be executed afterwards (see preUpdate)
 
         static InputManager*                singletonPtr_s;        //!< Pointer reference to the singleton
Index: code/trunk/src/libraries/core/input/InputPrereqs.h
===================================================================
--- code/trunk/src/libraries/core/input/InputPrereqs.h	(revision 6536)
+++ code/trunk/src/libraries/core/input/InputPrereqs.h	(revision 6746)
@@ -42,4 +42,5 @@
 #include <ois/OISMouse.h>
 #include <ois/OISJoyStick.h>
+#include "util/OrxEnum.h"
 
 namespace orxonox
@@ -448,4 +449,18 @@
         };
     }
+
+    //! Enumeration wrapper for input state priorities
+    struct InputStatePriority : OrxEnum<InputStatePriority>
+    {
+        OrxEnumConstructors(InputStatePriority);
+
+        static const int Empty        = -1;
+        static const int Dynamic      = 0;
+
+        static const int HighPriority = 1000;
+        static const int Console      = HighPriority + 0;
+        static const int Calibrator   = HighPriority + 1;
+        static const int Detector     = HighPriority + 2;
+    };
 }
 
Index: code/trunk/src/libraries/core/input/InputState.cc
===================================================================
--- code/trunk/src/libraries/core/input/InputState.cc	(revision 6536)
+++ code/trunk/src/libraries/core/input/InputState.cc	(revision 6746)
@@ -37,5 +37,5 @@
         , bAlwaysGetsInput_(bAlwaysGetsInput)
         , bTransparent_(bTransparent)
-        , mouseMode_(MouseMode::Dontcare)
+        , exclusiveMouse_(TriBool::Dontcare)
         , bExpired_(true)
         , handlers_(2)
Index: code/trunk/src/libraries/core/input/InputState.h
===================================================================
--- code/trunk/src/libraries/core/input/InputState.h	(revision 6536)
+++ code/trunk/src/libraries/core/input/InputState.h	(revision 6746)
@@ -35,35 +35,17 @@
 #include <string>
 #include <vector>
-
-#include "util/OrxEnum.h"
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+
+#include "util/TriBool.h"
 #include "InputHandler.h"
+#include "InputManager.h"
 #include "JoyStickQuantityListener.h"
+
+#define INPUT_STATE_PUSH_CALL(deviceIndex, functionName, ...) \
+    InputManager::getInstance().pushCall(boost::function<void ()>(boost::bind(&InputHandler::functionName, handlers_[deviceIndex], __VA_ARGS__)))
 
 namespace orxonox
 {
-    //! Enumeration wrapper for input state priorities
-    struct InputStatePriority : OrxEnum<InputStatePriority>
-    {
-        OrxEnumConstructors(InputStatePriority);
-
-        static const int Empty        = -1;
-        static const int Dynamic      = 0;
-
-        static const int HighPriority = 1000;
-        static const int Console      = HighPriority + 0;
-        static const int Calibrator   = HighPriority + 1;
-        static const int Detector     = HighPriority + 2;
-    };
-
-    namespace MouseMode
-    {
-        enum Value
-        {
-            Exclusive,
-            Nonexclusive,
-            Dontcare
-        };
-    }
-
     /**
     @brief
@@ -73,5 +55,5 @@
         that stack and only the top one gets the input events. This is done for
         every device (keyboard, mouse, all joy sticks) separately to allow
-        for intance keyboard input capturing for the console while you can still
+        for instance keyboard input capturing for the console while you can still
         steer a ship with the mouse.
         There are two exceptions to this behaviour though:
@@ -83,5 +65,5 @@
           the state will always receive input as long as it is activated.
         - Note: If you mark an InputState with both parameters on, then it will
-          not influence ony other InputState at all.
+          not influence only other InputState at all.
 
     @par Priorities
@@ -95,5 +77,5 @@
     @par Exclusive/Non-Exclusive mouse Mode
         You can select a specific mouse mode that tells whether the application
-        should have exclusive accessto it or not.
+        should have exclusive access to it or not.
         When in non-exclusive mode, you can move the mouse out of the window
         like with any other normal window (only for windowed mode!).
@@ -130,6 +112,6 @@
         void setHandler        (InputHandler* handler);
 
-        void setMouseMode(MouseMode::Value value) { mouseMode_ = value; this->bExpired_ = true; }
-        MouseMode::Value getMouseMode() const { return mouseMode_; }
+        void setMouseExclusive(TriBool::Value value) { exclusiveMouse_ = value; this->bExpired_ = true; }
+        TriBool::Value getMouseExclusive() const { return exclusiveMouse_; }
 
         //! Returns the name of the state (which is unique!)
@@ -152,6 +134,6 @@
 
         //! Generic function that distributes all 9 button events
-        template <typename EventType, class Traits>
-        void buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button);
+        template <typename EventType, class ButtonTypeParam>
+        void buttonEvent(unsigned int device, ButtonTypeParam button);
 
         //! Event handler
@@ -184,5 +166,5 @@
         const bool                  bAlwaysGetsInput_;      //!< See class declaration for explanation
         const bool                  bTransparent_;          //!< See class declaration for explanation
-        MouseMode::Value            mouseMode_;             //!< See class declaration for explanation
+        TriBool::Value              exclusiveMouse_;        //!< See class declaration for explanation
         int                         priority_;              //!< Current priority (might change)
         bool                        bExpired_;              //!< See hasExpired()
@@ -198,5 +180,5 @@
         for (unsigned int i = 0; i < handlers_.size(); ++i)
             if (handlers_[i] != NULL)
-                handlers_[i]->allDevicesUpdated(dt);
+                INPUT_STATE_PUSH_CALL(i, allDevicesUpdated, dt);
     }
 
@@ -207,25 +189,29 @@
         case InputDeviceEnumerator::Keyboard:
             if (handlers_[keyboardIndex_s] != NULL)
-                handlers_[keyboardIndex_s]->keyboardUpdated(dt);
+                INPUT_STATE_PUSH_CALL(keyboardIndex_s, keyboardUpdated, dt);
             break;
 
         case InputDeviceEnumerator::Mouse:
             if (handlers_[mouseIndex_s] != NULL)
-                handlers_[mouseIndex_s]->mouseUpdated(dt);
+                INPUT_STATE_PUSH_CALL(mouseIndex_s, mouseUpdated, dt);
             break;
 
         default: // joy sticks
             if (handlers_[device] != NULL)
-                handlers_[device]->joyStickUpdated(device - firstJoyStickIndex_s, dt);
+                INPUT_STATE_PUSH_CALL(device, joyStickUpdated, device - firstJoyStickIndex_s, dt);
             break;
         }
     }
 
-    template <typename EventType, class Traits>
-    FORCEINLINE void InputState::buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button)
+    template <typename EventType, class ButtonTypeParam>
+    FORCEINLINE void InputState::buttonEvent(unsigned int device, ButtonTypeParam button)
     {
         assert(device < handlers_.size());
         if (handlers_[device] != NULL)
-            handlers_[device]->buttonEvent(device, button, EventType());
+        {
+            // We have to store the function pointer to tell the compiler about its actual type because of overloading
+            void (InputHandler::*function)(unsigned int, ButtonTypeParam, EventType) = &InputHandler::buttonEvent<ButtonTypeParam>;
+            InputManager::getInstance().pushCall(boost::function<void ()>(boost::bind(function, handlers_[device], device, button, EventType())));
+        }
     }
 
@@ -233,5 +219,5 @@
     {
         if (handlers_[mouseIndex_s] != NULL)
-            handlers_[mouseIndex_s]->mouseMoved(abs, rel, clippingSize);
+            INPUT_STATE_PUSH_CALL(mouseIndex_s, mouseMoved, abs, rel, clippingSize);
     }
 
@@ -239,5 +225,5 @@
     {
         if (handlers_[mouseIndex_s] != NULL)
-            handlers_[mouseIndex_s]->mouseScrolled(abs, rel);
+            INPUT_STATE_PUSH_CALL(mouseIndex_s, mouseScrolled, abs, rel);
     }
 
@@ -246,5 +232,5 @@
         assert(device < handlers_.size());
         if (handlers_[device] != NULL)
-            handlers_[device]->axisMoved(device - firstJoyStickIndex_s, axis, value);
+            INPUT_STATE_PUSH_CALL(device, axisMoved, device - firstJoyStickIndex_s, axis, value);
     }
 }
