Index: code/branches/gui/src/core/input/InputManager.cc
===================================================================
--- code/branches/gui/src/core/input/InputManager.cc	(revision 1654)
+++ code/branches/gui/src/core/input/InputManager.cc	(revision 1656)
@@ -45,4 +45,5 @@
 #include "core/ConfigValueIncludes.h"
 #include "core/Debug.h"
+#include "core/Exception.h"
 #include "core/CommandExecutor.h"
 #include "core/ConsoleCommand.h"
@@ -67,4 +68,23 @@
     using namespace InputDevice;
 
+    /**
+    @brief
+        Defines the |= operator for easier use.
+    */
+    inline InputManager::InputManagerState operator|=(InputManager::InputManagerState& lval,
+                                                      InputManager::InputManagerState rval)
+    {
+        return (lval = (InputManager::InputManagerState)(lval | rval));
+    }
+
+    /**
+    @brief
+        Defines the &= operator for easier use.
+    */
+    inline InputManager::InputManagerState operator&=(InputManager::InputManagerState& lval, int rval)
+    {
+        return (lval = (InputManager::InputManagerState)(lval & rval));
+    }
+
     // ############################################################
     // #####                  Initialisation                  #####
@@ -83,4 +103,6 @@
         , joySticksSize_(0)
         , devicesNum_(0)
+        , windowHnd_(0)
+        , internalState_(Uninitialised)
         , stateDetector_(0)
         , stateCalibrator_(0)
@@ -105,18 +127,22 @@
     @param windowHeight
         The height of the render window
-    */
-    bool InputManager::initialise(const size_t windowHnd, int windowWidth, int windowHeight,
-                                   bool createKeyboard, bool createMouse, bool createJoySticks)
-    {
-        if (inputSystem_ == 0)
+    @param joyStickSupport
+        Whether or not to load the joy sticks as well
+    */
+    void InputManager::initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport)
+    {
+        if (internalState_ == Uninitialised)
         {
             CCOUT(3) << "Initialising Input System..." << std::endl;
             CCOUT(4) << "Initialising OIS components..." << std::endl;
 
+            // store handle internally so we can reload OIS
+            windowHnd_ = windowHnd;
+
             OIS::ParamList paramList;
             std::ostringstream windowHndStr;
 
             // Fill parameter list
-            windowHndStr << (unsigned int)windowHnd;
+            windowHndStr << (unsigned int)windowHnd_;
             paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
             //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
@@ -126,34 +152,20 @@
 //#endif
 
-            try
-            {
-                inputSystem_ = OIS::InputManager::createInputSystem(paramList);
-                CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl;
-            }
-            catch (OIS::Exception ex)
-            {
-                CCOUT(ORX_ERROR) << "Error: Failed creating an OIS input system."
-                    << "OIS message: \"" << ex.eText << "\"" << std::endl;
-                inputSystem_ = 0;
-                return false;
-            }
-
-            if (createKeyboard)
-                _initialiseKeyboard();
-
-            if (createMouse)
-                _initialiseMouse();
-
-            if (createJoySticks)
+            inputSystem_ = OIS::InputManager::createInputSystem(paramList);
+            CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl;
+
+            _initialiseKeyboard();
+
+            _initialiseMouse();
+
+            if (joyStickSupport)
                 _initialiseJoySticks();
-
-            // set all the std::vector list sizes now that the devices have been created
-            _redimensionLists();
 
             // Set mouse/joystick region
             if (mouse_)
-            {
                 setWindowExtents(windowWidth, windowHeight);
-            }
+
+            // clear all buffers
+            _clearBuffers();
 
             CCOUT(ORX_DEBUG) << "Initialising OIS components done." << std::endl;
@@ -178,4 +190,6 @@
             _updateActiveStates();
 
+            internalState_ = Ready;
+
             CCOUT(3) << "Initialising complete." << std::endl;
         }
@@ -184,5 +198,4 @@
             CCOUT(2) << "Warning: OIS compoments already initialised, skipping" << std::endl;
         }
-        return true;
     }
 
@@ -193,34 +206,22 @@
         False if keyboard stays uninitialised, true otherwise.
     */
-    bool InputManager::_initialiseKeyboard()
+    void InputManager::_initialiseKeyboard()
     {
         if (keyboard_ != 0)
         {
             CCOUT(2) << "Warning: Keyboard already initialised, skipping." << std::endl;
-            return true;
-        }
-        try
-        {
-            if (inputSystem_->getNumberOfDevices(OIS::OISKeyboard) > 0)
-            {
-                keyboard_ = (OIS::Keyboard*)inputSystem_->createInputObject(OIS::OISKeyboard, true);
-                // register our listener in OIS.
-                keyboard_->setEventCallback(this);
-                // note: OIS will not detect keys that have already been down when the keyboard was created.
-                CCOUT(ORX_DEBUG) << "Created OIS keyboard" << std::endl;
-                return true;
-            }
-            else
-            {
-                CCOUT(ORX_WARNING) << "Warning: No keyboard found!" << std::endl;
-                return false;
-            }
-        }
-        catch (OIS::Exception ex)
-        {
-            CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS keyboard\n"
-                << "OIS error message: \"" << ex.eText << "\"" << std::endl;
-            keyboard_ = 0;
-            return false;
+            return;
+        }
+        if (inputSystem_->getNumberOfDevices(OIS::OISKeyboard) > 0)
+        {
+            keyboard_ = (OIS::Keyboard*)inputSystem_->createInputObject(OIS::OISKeyboard, true);
+            // register our listener in OIS.
+            keyboard_->setEventCallback(this);
+            // note: OIS will not detect keys that have already been down when the keyboard was created.
+            CCOUT(ORX_DEBUG) << "Created OIS keyboard" << std::endl;
+        }
+        else
+        {
+            ThrowException(InitialisationFailed, "No keyboard found!");
         }
     }
@@ -232,10 +233,10 @@
         False if mouse stays uninitialised, true otherwise.
     */
-    bool InputManager::_initialiseMouse()
+    void InputManager::_initialiseMouse()
     {
         if (mouse_ != 0)
         {
             CCOUT(2) << "Warning: Mouse already initialised, skipping." << std::endl;
-            return true;
+            return;
         }
         try
@@ -247,10 +248,8 @@
                 mouse_->setEventCallback(this);
                 CCOUT(ORX_DEBUG) << "Created OIS mouse" << std::endl;
-                return true;
             }
             else
             {
                 CCOUT(ORX_WARNING) << "Warning: No mouse found!" << std::endl;
-                return false;
             }
         }
@@ -260,5 +259,4 @@
                 << "OIS error message: \"" << ex.eText << "\"" << std::endl;
             mouse_ = 0;
-            return false;
         }
     }
@@ -270,12 +268,11 @@
         False joy stick stay uninitialised, true otherwise.
     */
-    bool InputManager::_initialiseJoySticks()
+    void InputManager::_initialiseJoySticks()
     {
         if (joySticksSize_ > 0)
         {
             CCOUT(2) << "Warning: Joy sticks already initialised, skipping." << std::endl;
-            return true;
-        }
-        bool success = false;
+            return;
+        }
         if (inputSystem_->getNumberOfDevices(OIS::OISJoyStick) > 0)
         {
@@ -290,5 +287,4 @@
                     // register our listener in OIS.
                     stig->setEventCallback(this);
-                    success = true;
                 }
                 catch (OIS::Exception ex)
@@ -301,8 +297,7 @@
         else
         {
-            CCOUT(ORX_WARNING) << "Warning: Joy stick support requested, but no joy stick was found" << std::endl;
-            return false;
-        }
-        return success;
+            //CCOUT(ORX_WARNING) << "Warning: Joy stick support requested, but no joy stick was found" << std::endl;
+        }
+        _redimensionLists();
     }
 
@@ -412,5 +407,5 @@
     InputManager::~InputManager()
     {
-        if (inputSystem_)
+        if (internalState_ != Uninitialised)
         {
             try
@@ -429,16 +424,8 @@
                     (*rit).second->onLeave();
                 }
-                //activeStates_.clear();
-                //_updateActiveStates();
 
                 // destroy all input states
                 while (inputStatesByPriority_.size() > 0)
-                {
                     _destroyState((*inputStatesByPriority_.rbegin()).second);
-                }
-
-                //stateEmpty_ = 0;
-                //stateCalibrator_ = 0;
-                //stateDetector_ = 0;
 
                 // destroy the devices
@@ -447,9 +434,5 @@
                 _destroyJoySticks();
 
-                // 0 joy sticks now
-                //_redimensionLists();
-
                 OIS::InputManager::destroyInputSystem(inputSystem_);
-                //inputSystem_ = 0;
 
                 CCOUT(3) << "Destroying done." << std::endl;
@@ -457,5 +440,6 @@
             catch (OIS::Exception& ex)
             {
-                CCOUT(1) << "An exception has occured while destroying:\n" << ex.what() << std::endl;
+                CCOUT(1) << "An exception has occured while destroying:\n" << ex.what()
+                         << "This could lead to a possible memory/resource leak!" << std::endl;
             }
         }
@@ -468,8 +452,8 @@
     void InputManager::_destroyKeyboard()
     {
+        assert(inputSystem_);
         if (keyboard_)
             inputSystem_->destroyInputObject(keyboard_);
         keyboard_ = 0;
-        keysDown_.clear();
         CCOUT(4) << "Keyboard destroyed." << std::endl;
     }
@@ -481,8 +465,8 @@
     void InputManager::_destroyMouse()
     {
+        assert(inputSystem_);
         if (mouse_)
             inputSystem_->destroyInputObject(mouse_);
         mouse_ = 0;
-        mouseButtonsDown_.clear();
         CCOUT(4) << "Mouse destroyed." << std::endl;
     }
@@ -496,5 +480,5 @@
         if (joySticksSize_ > 0)
         {
-            // note: inputSystem_ can never be 0, or else the code is mistaken
+            assert(inputSystem_);
             for (unsigned int i = 0; i < joySticksSize_; i++)
                 if (joySticks_[i] != 0)
@@ -520,4 +504,92 @@
     }
 
+    void InputManager::_clearBuffers()
+    {
+        keysDown_.clear();
+        keyboardModifiers_ = 0;
+        mouseButtonsDown_.clear();
+        for (unsigned int i = 0; i < joySticksSize_; ++i)
+        {
+            joyStickButtonsDown_[i].clear();
+            for (int j = 0; j < 4; ++j)
+            {
+                sliderStates_[i].sliderStates[j].x = 0;
+                sliderStates_[i].sliderStates[j].y = 0;
+                povStates_[i][j] = 0;
+            }
+        }
+    }
+
+
+    // ############################################################
+    // #####                     Reloading                    #####
+    // ##########                                        ##########
+    // ############################################################
+
+    /**
+    @brief
+        Public interface. Only reloads immediately if the call stack doesn't
+        include the tick() method.
+    @param joyStickSupport
+        Whether or not to initialise joy sticks as well.
+    */
+    void InputManager::reloadInputSystem(bool joyStickSupport)
+    {
+        if (internalState_ & Ticking)
+        {
+            // We cannot destroy OIS right now, because reload was probably
+            // caused by a user clicking on a GUI item. The backtrace would then
+            // include an OIS method. So it would be a very bad thing to destroy it..
+            internalState_ |= ReloadRequest;
+            // Misuse of internalState_: We can easily store the joyStickSupport bool.
+            // use Uninitialised as 0 value in order to use the overloaded |= operator
+            internalState_ |= joyStickSupport ? JoyStickSupport : Uninitialised;
+        }
+        else if (internalState_ == Ready)
+        {
+            _reload(joyStickSupport);
+        }
+        else
+        {
+            CCOUT(2) << "Warning: Cannot reload OIS. May not yet be initialised or"
+                     << "joy sticks are currently calibrating." << std::endl;
+        }
+    }
+
+    /**
+    @brief
+        Internal reload method. Destroys the OIS devices and loads them again.
+    */
+    void InputManager::_reload(bool joyStickSupport)
+    {
+        try
+        {
+            CCOUT(3) << "Reloading ..." << std::endl;
+
+            // Save mouse clipping size
+            int mouseWidth  = mouse_->getMouseState().width;
+            int mouseHeight = mouse_->getMouseState().height;
+
+            internalState_ = Uninitialised;
+            // destroy the devices
+            _destroyKeyboard();
+            _destroyMouse();
+            _destroyJoySticks();
+
+            OIS::InputManager::destroyInputSystem(inputSystem_);
+            inputSystem_ = 0;
+
+            // clear all buffers containing input information
+            _clearBuffers();
+
+            initialise(windowHnd_, mouseWidth, mouseHeight, joyStickSupport);
+
+            CCOUT(3) << "Reloading done." << std::endl;
+        }
+        catch (OIS::Exception& ex)
+        {
+            CCOUT(1) << "An exception has occured while reloading:\n" << ex.what() << std::endl;
+        }
+    }
 
     // ############################################################
@@ -534,6 +606,13 @@
     void InputManager::tick(float dt)
     {
-        if (inputSystem_ == 0)
+        if (internalState_ == Uninitialised)
             return;
+        else if (internalState_ & ReloadRequest)
+        {
+            _reload(internalState_ & JoyStickSupport);
+            internalState_ &= ~ReloadRequest;
+            internalState_ &= ~JoyStickSupport;
+        }
+        internalState_ |= Ticking;
 
         // check for states to leave (don't use unsigned int!)
@@ -594,4 +673,6 @@
                 activeStatesTicked_[i]->tickInput(dt);
         }
+
+        internalState_ &= ~Ready;
     }
 
Index: code/branches/gui/src/core/input/InputManager.h
===================================================================
--- code/branches/gui/src/core/input/InputManager.h	(revision 1654)
+++ code/branches/gui/src/core/input/InputManager.h	(revision 1656)
@@ -55,5 +55,5 @@
     {
     public:
-        int operator[](unsigned int index) { return povStates[index]; }
+        int& operator[](unsigned int index) { return povStates[index]; }
         int povStates[4];
     };
@@ -90,9 +90,20 @@
 
     public:
+        enum InputManagerState
+        {
+            Uninitialised    = 0,
+            Ready            = 1,
+            Ticking          = 2,
+            Calibrating      = 4,
+            ReloadRequest    = 8,
+            JoyStickSupport  = 16 // used with ReloadRequest to store a bool
+        };
+
         InputManager ();
         ~InputManager();
 
-        bool initialise(const size_t windowHnd, int windowWidth, int windowHeight,
-                               bool createKeyboard = true, bool createMouse = true, bool createJoySticks = false);
+        void initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport = true);
+
+        void reloadInputSystem(bool joyStickSupport = true);
 
         int  numberOfKeyboards() { return keyboard_ ? 1 : 0; }
@@ -134,7 +145,7 @@
 
         // Intenal methods
-        bool _initialiseKeyboard();
-        bool _initialiseMouse();
-        bool _initialiseJoySticks();
+        void _initialiseKeyboard();
+        void _initialiseMouse();
+        void _initialiseJoySticks();
         void _redimensionLists();
 
@@ -143,4 +154,7 @@
         void _destroyJoySticks();
         void _destroyState(InputState* state);
+        void _clearBuffers();
+
+        void _reload(bool joyStickSupport);
 
         void _completeCalibration();
@@ -177,4 +191,6 @@
         unsigned int                        joySticksSize_;
         unsigned int                        devicesNum_;
+        size_t                              windowHnd_;            //!< Render window handle
+        InputManagerState                   internalState_;        //!< Current internal state
 
         // some internally handled states
Index: code/branches/gui/src/orxonox/Orxonox.cc
===================================================================
--- code/branches/gui/src/orxonox/Orxonox.cc	(revision 1654)
+++ code/branches/gui/src/orxonox/Orxonox.cc	(revision 1656)
@@ -269,5 +269,5 @@
                 inputManager_ = new InputManager();
                 inputManager_->initialise(graphicsEngine_->getWindowHandle(),
-                    graphicsEngine_->getWindowWidth(), graphicsEngine_->getWindowHeight(), true, true, true);
+                    graphicsEngine_->getWindowWidth(), graphicsEngine_->getWindowHeight(), true);
                 KeyBinder* keyBinder = new KeyBinder();
                 keyBinder->loadBindings();
