Index: code/trunk/src/core/CMakeLists.txt
===================================================================
--- code/trunk/src/core/CMakeLists.txt	(revision 3326)
+++ code/trunk/src/core/CMakeLists.txt	(revision 3327)
@@ -31,4 +31,5 @@
   ObjectListBase.cc
   OrxonoxClass.cc
+  WindowEventListener.cc
 
   # command
Index: code/trunk/src/core/CorePrereqs.h
===================================================================
--- code/trunk/src/core/CorePrereqs.h	(revision 3326)
+++ code/trunk/src/core/CorePrereqs.h	(revision 3327)
@@ -155,5 +155,5 @@
     class TclThreadManager;
     class Template;
-    class Tickable;
+    class WindowEventListener;
     class XMLFile;
     class XMLNameListener;
@@ -176,17 +176,20 @@
     class Button;
     class CalibratorCallback;
-    class ExtendedInputState;
     class HalfAxis;
     class InputBuffer;
+    class InputDevice;
+    template <class Traits>
+    class InputDeviceTemplated;
+    class InputHandler;
     class InputManager;
     class InputState;
-    class JoyStickHandler;
-    class MouseHandler;
+    class JoyStick;
+    class Mouse;
+    class Keyboard;
     class KeyBinder;
     class KeyDetector;
-    class KeyHandler;
     class ParamCommand;
     class SimpleCommand;
-    class SimpleInputState;
+
 
     // multithreading
Index: code/trunk/src/core/OrxonoxClass.h
===================================================================
--- code/trunk/src/core/OrxonoxClass.h	(revision 3326)
+++ code/trunk/src/core/OrxonoxClass.h	(revision 3327)
@@ -39,5 +39,7 @@
 
 #include "CorePrereqs.h"
+
 #include <set>
+#include <vector>
 
 namespace orxonox
Index: code/trunk/src/core/WindowEventListener.cc
===================================================================
--- code/trunk/src/core/WindowEventListener.cc	(revision 3327)
+++ code/trunk/src/core/WindowEventListener.cc	(revision 3327)
@@ -0,0 +1,64 @@
+/*
+ *   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 "WindowEventListener.h"
+#include "CoreIncludes.h"
+
+namespace orxonox
+{
+    unsigned int WindowEventListener::windowWidth_s  = 0;
+    unsigned int WindowEventListener::windowHeight_s = 0;
+
+    WindowEventListener::WindowEventListener()
+    {
+        RegisterRootObject(WindowEventListener);
+    }
+
+    //! Calls all registered objects
+    /*static*/ void WindowEventListener::moveWindow()
+    {
+        for (ObjectList<WindowEventListener>::iterator it = ObjectList<WindowEventListener>::begin(); it; ++it)
+            it->windowMoved();
+    }
+
+    //! Calls all registered objects and sets the static variables
+    /*static*/ void WindowEventListener::resizeWindow(unsigned int newWidth, unsigned int newHeight)
+    {
+        windowWidth_s = newWidth;
+        windowHeight_s = newHeight;
+        for (ObjectList<WindowEventListener>::iterator it = ObjectList<WindowEventListener>::begin(); it; ++it)
+            it->windowResized(newWidth, newHeight);
+    }
+
+    //! Calls all registered objects
+    /*static*/ void WindowEventListener::changeWindowFocus()
+    {
+        for (ObjectList<WindowEventListener>::iterator it = ObjectList<WindowEventListener>::begin(); it; ++it)
+            it->windowFocusChanged();
+    }
+}
Index: code/trunk/src/core/WindowEventListener.h
===================================================================
--- code/trunk/src/core/WindowEventListener.h	(revision 3327)
+++ code/trunk/src/core/WindowEventListener.h	(revision 3327)
@@ -0,0 +1,71 @@
+/*
+ *   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 _WindowEventListener_H__
+#define _WindowEventListener_H__
+
+#include "CorePrereqs.h"
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    //! Interface for receiving window events like resize, moved and focusChanged
+    class _CoreExport WindowEventListener : virtual public OrxonoxClass
+    {
+        friend class OgreWindowEventListener;
+
+        protected:
+            WindowEventListener();
+            virtual ~WindowEventListener() { }
+
+            //! Returns the current render window width
+            unsigned int getWindowWidth() const { return windowWidth_s; }
+            //! Returns the current render window height
+            unsigned int getWindowHeight() const { return windowHeight_s; }
+
+        private:
+            //! Window has been moved
+            virtual void windowMoved() { }
+
+            //! Window has resized
+            virtual void windowResized(unsigned int newWidth, unsigned int newHeight) { }
+
+            //! Window has lost/gained focus
+            virtual void windowFocusChanged() { }
+
+            static void moveWindow();
+            static void resizeWindow(unsigned int newWidth, unsigned int newHeight);
+            static void changeWindowFocus();
+
+            //! Static variable that holds the latest distributed information
+            static unsigned int windowWidth_s;
+            static unsigned int windowHeight_s;
+    };
+}
+
+#endif /* _WindowEventListener_H__ */
Index: code/trunk/src/core/input/Button.cc
===================================================================
--- code/trunk/src/core/input/Button.cc	(revision 3326)
+++ code/trunk/src/core/input/Button.cc	(revision 3327)
@@ -60,5 +60,4 @@
         nCommands_[2]=0;
         this->configContainer_ = 0;
-        clear();
     }
 
@@ -83,8 +82,4 @@
                 commands_[j] = 0;
                 nCommands_[j] = 0;
-            }
-            else
-            {
-                commands_[j] = 0;
             }
         }
Index: code/trunk/src/core/input/Button.h
===================================================================
--- code/trunk/src/core/input/Button.h	(revision 3326)
+++ code/trunk/src/core/input/Button.h	(revision 3327)
@@ -36,5 +36,5 @@
 #define _Button_H__
 
-#include "core/CorePrereqs.h"
+#include "InputPrereqs.h"
 
 #include <string>
Index: code/trunk/src/core/input/CMakeLists.txt
===================================================================
--- code/trunk/src/core/input/CMakeLists.txt	(revision 3326)
+++ code/trunk/src/core/input/CMakeLists.txt	(revision 3327)
@@ -1,12 +1,14 @@
 ADD_SOURCE_FILES(CORE_SRC_FILES
   Button.cc
-  ExtendedInputState.cc
   HalfAxis.cc
   InputBuffer.cc
   InputCommands.cc
   InputManager.cc
-  JoyStickDeviceNumberListener.cc
+  InputState.cc
+  JoyStick.cc
+  JoyStickQuantityListener.cc
   KeyBinder.cc
+  Keyboard.cc
   KeyDetector.cc
-  SimpleInputState.cc
+  Mouse.cc
 )
Index: code/trunk/src/core/input/ExtendedInputState.cc
===================================================================
--- code/trunk/src/core/input/ExtendedInputState.cc	(revision 3326)
+++ 	(revision )
@@ -1,471 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation; either version 2
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Reto Grieder
- *   Co-authors:
- *      ...
- *
- */
-
-/**
-@file
-@brief
-    Implementation of the ExtendedInputState class.
-*/
-
-#include "ExtendedInputState.h"
-
-#include <cassert>
-#include "core/Executor.h"
-
-namespace orxonox
-{
-    using namespace InputDevice;
-
-    void ExtendedInputState::numberOfJoySticksChanged(unsigned int n)
-    {
-        unsigned int oldSize = joyStickHandlers_.size();
-        joyStickHandlers_.resize(n);
-
-        if (oldSize > n)
-        {
-            // we have to add all the handlers in joyStickHandlersAll_ to the joyStickHandlers_[>n]
-            for (unsigned int j = 0; j < joyStickHandlersAll_.size(); ++j)
-            {
-                for (unsigned int i = oldSize; i < n; ++i)
-                {
-                    joyStickHandlers_[i].push_back(joyStickHandlersAll_[j]);
-                }
-            }
-        }
-        update();
-    }
-
-    void ExtendedInputState::keyPressed(const KeyEvent& evt)
-    {
-        for (unsigned int i = 0; i < keyHandlers_.size(); i++)
-            keyHandlers_[i]->keyPressed(evt);
-    }
-
-    void ExtendedInputState::keyReleased(const KeyEvent& evt)
-    {
-        for (unsigned int i = 0; i < keyHandlers_.size(); i++)
-            keyHandlers_[i]->keyReleased(evt);
-    }
-
-    void ExtendedInputState::keyHeld(const KeyEvent& evt)
-    {
-        for (unsigned int i = 0; i < keyHandlers_.size(); i++)
-            keyHandlers_[i]->keyHeld(evt);
-    }
-
-
-    void ExtendedInputState::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
-    {
-        for (unsigned int i = 0; i < mouseHandlers_.size(); i++)
-            mouseHandlers_[i]->mouseMoved(abs, rel, clippingSize);
-    }
-
-    void ExtendedInputState::mouseScrolled(int abs, int rel)
-    {
-        for (unsigned int i = 0; i < mouseHandlers_.size(); i++)
-            mouseHandlers_[i]->mouseScrolled(abs, rel);
-    }
-
-    void ExtendedInputState::mouseButtonPressed(MouseButtonCode::ByEnum id)
-    {
-        for (unsigned int i = 0; i < mouseHandlers_.size(); i++)
-            mouseHandlers_[i]->mouseButtonPressed(id);
-    }
-
-    void ExtendedInputState::mouseButtonReleased(MouseButtonCode::ByEnum id)
-    {
-        for (unsigned int i = 0; i < mouseHandlers_.size(); i++)
-            mouseHandlers_[i]->mouseButtonReleased(id);
-    }
-
-    void ExtendedInputState::mouseButtonHeld(MouseButtonCode::ByEnum id)
-    {
-        for (unsigned int i = 0; i < mouseHandlers_.size(); i++)
-            mouseHandlers_[i]->mouseButtonHeld(id);
-    }
-
-
-    void ExtendedInputState::joyStickAxisMoved(unsigned int joyStickID, unsigned int axis, float value)
-    {
-        assert(joyStickID < joyStickHandlers_.size());
-        for (unsigned int i = 0; i < joyStickHandlers_[joyStickID].size(); i++)
-            joyStickHandlers_[joyStickID][i]->joyStickAxisMoved(joyStickID, axis, value);
-    }
-
-    void ExtendedInputState::joyStickButtonPressed(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
-    {
-        assert(joyStickID < joyStickHandlers_.size());
-        for (unsigned int i = 0; i < joyStickHandlers_[joyStickID].size(); i++)
-            joyStickHandlers_[joyStickID][i]->joyStickButtonPressed(joyStickID, id);
-    }
-
-    void ExtendedInputState::joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
-    {
-        assert(joyStickID < joyStickHandlers_.size());
-        for (unsigned int i = 0; i < joyStickHandlers_[joyStickID].size(); i++)
-            joyStickHandlers_[joyStickID][i]->joyStickButtonReleased(joyStickID, id);
-    }
-
-    void ExtendedInputState::joyStickButtonHeld(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
-    {
-        assert(joyStickID < joyStickHandlers_.size());
-        for (unsigned int i = 0; i < joyStickHandlers_[joyStickID].size(); i++)
-            joyStickHandlers_[joyStickID][i]->joyStickButtonHeld(joyStickID, id);
-    }
-
-
-    /**
-    @brief
-        Adds a key handler.
-    @param handler
-        Pointer to the handler object.
-    @return
-        True if added, false if handler already existed.
-    */
-    bool ExtendedInputState::addKeyHandler(KeyHandler* handler)
-    {
-        if (!handler)
-            return false;
-
-        // see whether the handler already is in the list
-        for (std::vector<KeyHandler*>::iterator it = keyHandlers_.begin(); it != keyHandlers_.end(); it++)
-        {
-            if ((*it) == handler)
-            {
-                return false;
-            }
-        }
-        keyHandlers_.push_back(handler);
-        update();
-        return true;
-    }
-
-    /**
-    @brief
-        Removes a Key handler from the state.
-    @param handler
-        Pointer to the handler.
-    @return
-        True if removal was successful, false if handler was not found.
-    */
-    bool ExtendedInputState::removeKeyHandler(KeyHandler* handler)
-    {
-        if (!handler)
-            return false;
-
-        for (std::vector<KeyHandler*>::iterator it = keyHandlers_.begin(); it != keyHandlers_.end(); it++)
-        {
-            if ((*it) == handler)
-            {
-                keyHandlers_.erase(it);
-                update();
-                return true;
-            }
-        }
-        return false;
-    }
-
-
-    /**
-    @brief
-        Adds a mouse handler.
-    @param handler
-        Pointer to the handler object.
-    @return
-        True if added, false if handler already existed.
-    */
-    bool ExtendedInputState::addMouseHandler(MouseHandler* handler)
-    {
-        if (!handler)
-            return false;
-
-        // see whether the handler already is in the list
-        for (std::vector<MouseHandler*>::iterator it = mouseHandlers_.begin(); it != mouseHandlers_.end(); it++)
-        {
-            if ((*it) == handler)
-            {
-                return false;
-            }
-        }
-        mouseHandlers_.push_back(handler);
-        update();
-        return true;
-    }
-
-    /**
-    @brief
-        Removes a mouse handler from the state.
-    @param handler
-        Pointer to the handler.
-    @return
-        True if removal was successful, false if handler was not found.
-    */
-    bool ExtendedInputState::removeMouseHandler(MouseHandler* handler)
-    {
-        if (!handler)
-            return false;
-
-        for (std::vector<MouseHandler*>::iterator it = mouseHandlers_.begin(); it != mouseHandlers_.end(); it++)
-        {
-            if ((*it) == handler)
-            {
-                mouseHandlers_.erase(it);
-                update();
-                return true;
-            }
-        }
-        return false;
-    }
-
-
-    /**
-    @brief
-        Adds a joy stick handler.
-    @param handler
-        Pointer to the handler object.
-    @param joyStickID
-        ID of the joy stick
-    @return
-        True if added, false if handler already existed.
-    */
-    bool ExtendedInputState::addJoyStickHandler(JoyStickHandler* handler, unsigned int joyStickID)
-    {
-        if (!handler || joyStickID >= joyStickHandlers_.size())
-            return false;
-
-        // see whether the handler already is in the list
-        for (std::vector<JoyStickHandler*>::iterator it = joyStickHandlers_[joyStickID].begin();
-            it != joyStickHandlers_[joyStickID].end(); it++)
-        {
-            if ((*it) == handler)
-            {
-                return false;
-            }
-        }
-        joyStickHandlers_[joyStickID].push_back(handler);
-        update();
-        return true;
-    }
-
-    /**
-    @brief
-        Removes a joy stick handler from the state.
-    @param handler
-        Pointer to the handler.
-    @param joyStickID
-        ID of the joy stick
-    @return
-        True if removal was successful, false if handler was not found.
-    */
-    bool ExtendedInputState::removeJoyStickHandler(JoyStickHandler* handler, unsigned int joyStickID)
-    {
-        if (!handler || joyStickID >= joyStickHandlers_.size())
-            return false;
-
-        // remove it from the list of all-joystick handlers if present
-        for (std::vector<JoyStickHandler*>::iterator it = joyStickHandlersAll_.begin();
-            it != joyStickHandlersAll_.end(); it++)
-        {
-            if ((*it) == handler)
-            {
-                joyStickHandlersAll_.erase(it);
-            }
-        }
-
-        // remove handler from the list of seperate lists of handlers
-        for (std::vector<JoyStickHandler*>::iterator it = joyStickHandlers_[joyStickID].begin();
-            it != joyStickHandlers_[joyStickID].end(); it++)
-        {
-            if ((*it) == handler)
-            {
-                joyStickHandlers_[joyStickID].erase(it);
-                update();
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-    @brief
-        Adds a joy stick handler.
-    @param handler
-        Pointer to the handler object.
-    @return
-        True if added, false if handler already existed.
-    */
-    bool ExtendedInputState::addJoyStickHandler(JoyStickHandler* handler)
-    {
-        if (!handler)
-            return false;
-
-        // see whether the handler already is in the big list
-        for (std::vector<JoyStickHandler*>::iterator it = joyStickHandlersAll_.begin();
-            it != joyStickHandlersAll_.end(); it++)
-        {
-            if ((*it) == handler)
-            {
-                return false;
-            }
-        }
-        joyStickHandlersAll_.push_back(handler);
-        update();
-
-        // now, we have to add it to all the separate lists
-        for (unsigned int iJoyStick = 0; iJoyStick < joyStickHandlers_.size(); ++iJoyStick)
-            addJoyStickHandler(handler, iJoyStick);
-        return true;
-    }
-
-    /**
-    @brief
-        Removes a joy stick handler from the state.
-    @param handler
-        Pointer to the handler.
-    @return
-        True if removal was successful, false if handler was not found.
-    */
-    bool ExtendedInputState::removeJoyStickHandler(JoyStickHandler* handler)
-    {
-        if (!handler)
-            return false;
-
-        bool success = false;
-        // remove from all lists in a loop (also removes it from the big list)
-        for (unsigned int iJoyStick = 0; iJoyStick < joyStickHandlers_.size(); ++iJoyStick)
-            success |= removeJoyStickHandler(handler, iJoyStick);
-
-        return success;
-    }
-
-    /**
-    @brief
-        Adds a handler of any kind. dynamic_cast determines to which list it is added.
-    @param handler
-        Pointer to the handler object.
-    @return
-        True if added, false if handler already existed.
-    */
-    bool ExtendedInputState::addHandler(InputHandler* handler)
-    {
-        bool success = false;
-
-        success |= addKeyHandler(dynamic_cast<KeyHandler*>(handler));
-        success |= addMouseHandler(dynamic_cast<MouseHandler*>(handler));
-        success |= addJoyStickHandler(dynamic_cast<JoyStickHandler*>(handler));
-
-        return success;
-    }
-
-    /**
-    @brief
-        Removes a handler from all lists.
-    @param handler
-        Pointer to the handler.
-    @return
-        True if removal was successful, false if handler was not found.
-    */
-    bool ExtendedInputState::removeHandler(InputHandler* handler)
-    {
-        bool success = false;
-
-        success |= removeKeyHandler(dynamic_cast<KeyHandler*>(handler));
-        success |= removeMouseHandler(dynamic_cast<MouseHandler*>(handler));
-        success |= removeJoyStickHandler(dynamic_cast<JoyStickHandler*>(handler));
-
-        return success;
-    }
-
-    void ExtendedInputState::updateInput(float dt)
-    {
-        for (unsigned int i = 0; i < allHandlers_.size(); ++i)
-        {
-            allHandlers_[i]->updateInput(dt);
-        }
-    }
-
-    void ExtendedInputState::updateInput(float dt, unsigned int device)
-    {
-        switch (device)
-        {
-        case Keyboard:
-            for (unsigned int i = 0; i < keyHandlers_.size(); ++i)
-                keyHandlers_[i]->updateKey(dt);
-            break;
-
-        case Mouse:
-            for (unsigned int i = 0; i < mouseHandlers_.size(); ++i)
-                mouseHandlers_[i]->updateMouse(dt);
-            break;
-
-        default: // joy sticks
-            for (unsigned int i = 0; i < joyStickHandlers_[device - 2].size(); ++i)
-                joyStickHandlers_[device - 2][i]->updateJoyStick(dt, device - 2);
-            break;
-        }
-    }
-
-    void ExtendedInputState::update()
-    {
-        // we can use a set to have a list of unique pointers (an object can implement all 3 handlers)
-        std::set<InputHandler*> tempSet;
-        for (unsigned int iHandler = 0; iHandler < keyHandlers_.size(); iHandler++)
-            tempSet.insert(keyHandlers_[iHandler]);
-        for (unsigned int iHandler = 0; iHandler < mouseHandlers_.size(); iHandler++)
-            tempSet.insert(mouseHandlers_[iHandler]);
-        for (unsigned int iJoyStick = 0; iJoyStick < joyStickHandlers_.size(); iJoyStick++)
-            for (unsigned int iHandler = 0; iHandler < joyStickHandlers_[iJoyStick].size(); iHandler++)
-                tempSet.insert(joyStickHandlers_[iJoyStick][iHandler]);
-
-        // copy the content of the map back to the actual vector
-        allHandlers_.clear();
-        for (std::set<InputHandler*>::const_iterator itHandler = tempSet.begin();
-            itHandler != tempSet.end(); itHandler++)
-            allHandlers_.push_back(*itHandler);
-
-        // update the deviceEnabled options
-        setInputDeviceEnabled(Keyboard, (keyHandlers_.size() != 0));
-        setInputDeviceEnabled(Mouse, (mouseHandlers_.size() != 0));
-        for (unsigned int i = 0; i < joyStickHandlers_.size(); ++i)
-            setInputDeviceEnabled(2 + i, (joyStickHandlers_[i].size() != 0));
-
-        this->bHandlersChanged_ = true;
-    }
-
-    void ExtendedInputState::onEnter()
-    {
-        if (executorOnEnter_)
-            (*executorOnEnter_)();
-    }
-
-    void ExtendedInputState::onLeave()
-    {
-        if (executorOnLeave_)
-            (*executorOnLeave_)();
-    }
-}
Index: code/trunk/src/core/input/ExtendedInputState.h
===================================================================
--- code/trunk/src/core/input/ExtendedInputState.h	(revision 3326)
+++ 	(revision )
@@ -1,102 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation; either version 2
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Reto Grieder
- *   Co-authors:
- *      ...
- *
- */
-
-/**
-@file
-@brief 
-*/
-
-#ifndef _ExtendedInputState_H__
-#define _ExtendedInputState_H__
-
-#include "core/CorePrereqs.h"
-
-#include <vector>
-#include "InputInterfaces.h"
-#include "InputState.h"
-
-namespace orxonox
-{
-
-    class _CoreExport ExtendedInputState : public InputState
-    {
-        friend class InputManager;
-
-    public:
-        bool addKeyHandler        (KeyHandler* handler);
-        bool removeKeyHandler     (KeyHandler* handler);
-
-        bool addMouseHandler      (MouseHandler* handler);
-        bool removeMouseHandler   (MouseHandler* handler);
-
-        bool addJoyStickHandler   (JoyStickHandler* handler, unsigned int joyStickID);
-        bool removeJoyStickHandler(JoyStickHandler* handler, unsigned int joyStickID);
-        bool addJoyStickHandler   (JoyStickHandler* handler);
-        bool removeJoyStickHandler(JoyStickHandler* handler);
-
-        bool addHandler(InputHandler* handler);
-        bool removeHandler(InputHandler* handler);
-
-    private:
-        ExtendedInputState() { }
-        ~ExtendedInputState() { }
-
-        void updateInput(float dt);
-        void updateInput(float dt, unsigned int device);
-
-        void keyPressed (const KeyEvent& evt);
-        void keyReleased(const KeyEvent& evt);
-        void keyHeld    (const KeyEvent& evt);
-
-        void mouseButtonPressed (MouseButtonCode::ByEnum id);
-        void mouseButtonReleased(MouseButtonCode::ByEnum id);
-        void mouseButtonHeld    (MouseButtonCode::ByEnum id);
-        void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
-        void mouseScrolled      (int abs, int rel);
-
-        void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
-        void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
-        void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
-        void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value);        void updateTickables();
-
-        void numberOfJoySticksChanged(unsigned int n);
-        void update();
-
-        void onEnter();
-        void onLeave();
-
-        std::vector<KeyHandler*>                    keyHandlers_;
-        std::vector<MouseHandler*>                  mouseHandlers_;
-        std::vector<std::vector<JoyStickHandler*> > joyStickHandlers_;
-        std::vector<JoyStickHandler*>               joyStickHandlersAll_;
-
-        std::vector<InputHandler*> allHandlers_;
-    };
-}
-
-#endif /* _ExtendedInputState_H__ */
Index: code/trunk/src/core/input/HalfAxis.cc
===================================================================
--- code/trunk/src/core/input/HalfAxis.cc	(revision 3326)
+++ code/trunk/src/core/input/HalfAxis.cc	(revision 3327)
@@ -49,8 +49,4 @@
             nParamCommands_ = 0;
         }
-        else
-        {
-            nParamCommands_ = 0; nParamCommands_ = 0;
-        }
     }
 
Index: code/trunk/src/core/input/HalfAxis.h
===================================================================
--- code/trunk/src/core/input/HalfAxis.h	(revision 3326)
+++ code/trunk/src/core/input/HalfAxis.h	(revision 3327)
@@ -36,5 +36,5 @@
 #define _HalfAxis_H__
 
-#include "core/CorePrereqs.h"
+#include "InputPrereqs.h"
 
 #include "Button.h"
Index: code/trunk/src/core/input/InputBuffer.cc
===================================================================
--- code/trunk/src/core/input/InputBuffer.cc	(revision 3326)
+++ code/trunk/src/core/input/InputBuffer.cc	(revision 3327)
@@ -184,12 +184,12 @@
 
 
-    void InputBuffer::processKey(const KeyEvent &evt)
-    {
-        if (evt.isModifierDown(KeyboardModifier::Alt) && evt.key == KeyCode::Tab)
+    void InputBuffer::processKey(const KeyEvent& evt)
+    {
+        if (evt.isModifierDown(KeyboardModifier::Alt) && evt.getKeyCode() == KeyCode::Tab)
             return;
 
         for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
         {
-            if ((*it)->trueKeyFalseChar_ && ((*it)->key_ == evt.key))
+            if ((*it)->trueKeyFalseChar_ && ((*it)->key_ == evt.getKeyCode()))
                 (*it)->callFunction();
         }
@@ -197,9 +197,9 @@
         if (evt.isModifierDown(KeyboardModifier::Ctrl))
         {
-            if (evt.key == KeyCode::V)
+            if (evt.getKeyCode() == KeyCode::V)
                 this->insert(fromClipboard());
-            else if (evt.key == KeyCode::C)
+            else if (evt.getKeyCode() == KeyCode::C)
                 toClipboard(this->buffer_);
-            else if (evt.key == KeyCode::X)
+            else if (evt.getKeyCode() == KeyCode::X)
             {
                 toClipboard(this->buffer_);
@@ -209,7 +209,7 @@
         else if (evt.isModifierDown(KeyboardModifier::Shift))
         {
-            if (evt.key == KeyCode::Insert)
+            if (evt.getKeyCode() == KeyCode::Insert)
                 this->insert(fromClipboard());
-            else if (evt.key == KeyCode::Delete)
+            else if (evt.getKeyCode() == KeyCode::Delete)
             {
                 toClipboard(this->buffer_);
@@ -218,5 +218,5 @@
         }
 
-        this->insert(static_cast<char>(evt.text));
+        this->insert(static_cast<char>(evt.getText()));
     }
 
@@ -225,5 +225,5 @@
         @param dt Delta time
     */
-    void InputBuffer::updateInput(float dt)
+    void InputBuffer::keyboardUpdated(float dt)
     {
         timeSinceKeyPressed_ += dt;
@@ -239,7 +239,7 @@
     }
 
-    void InputBuffer::keyPressed(const KeyEvent &evt)
-    {
-        lastKey_ = evt.key;
+    void InputBuffer::buttonPressed(const KeyEvent& evt)
+    {
+        lastKey_ = evt.getKeyCode();
         timeSinceKeyPressed_ = 0.0;
         timeSinceKeyRepeated_ = keyRepeatDeleay_;
@@ -249,7 +249,7 @@
     }
 
-    void InputBuffer::keyHeld(const KeyEvent& evt)
-    {
-        if (evt.key == lastKey_)
+    void InputBuffer::buttonHeld(const KeyEvent& evt)
+    {
+        if (evt.getKeyCode() == lastKey_)
         {
             while (keysToRepeat_)
Index: code/trunk/src/core/input/InputBuffer.h
===================================================================
--- code/trunk/src/core/input/InputBuffer.h	(revision 3326)
+++ code/trunk/src/core/input/InputBuffer.h	(revision 3327)
@@ -30,10 +30,10 @@
 #define _InputBuffer_H__
 
-#include "core/CorePrereqs.h"
+#include "InputPrereqs.h"
 
 #include <list>
 #include <string>
 #include "core/OrxonoxClass.h"
-#include "InputInterfaces.h"
+#include "InputHandler.h"
 
 namespace orxonox
@@ -74,5 +74,5 @@
     };
 
-    class _CoreExport InputBuffer : public KeyHandler, public OrxonoxClass
+    class _CoreExport InputBuffer : public InputHandler, public OrxonoxClass
     {
         public:
@@ -165,11 +165,9 @@
             bool charIsAllowed(const char& input);
 
-            void keyPressed (const KeyEvent& evt);
-            void keyReleased(const KeyEvent& evt) { }
-            void keyHeld    (const KeyEvent& evt);
-            void processKey (const KeyEvent &e);
+            void buttonPressed(const KeyEvent& evt);
+            void buttonHeld   (const KeyEvent& evt);
+            void processKey   (const KeyEvent& evt);
 
-            void updateInput(float dt);
-            void updateKey(float dt) { }
+            void keyboardUpdated(float dt);
 
             std::string buffer_;
Index: code/trunk/src/core/input/InputCommands.h
===================================================================
--- code/trunk/src/core/input/InputCommands.h	(revision 3326)
+++ code/trunk/src/core/input/InputCommands.h	(revision 3327)
@@ -36,5 +36,5 @@
 #define _InputCommands_H__
 
-#include "core/CorePrereqs.h"
+#include "InputPrereqs.h"
 #include "core/CommandEvaluation.h"
 
Index: code/trunk/src/core/input/InputDevice.h
===================================================================
--- code/trunk/src/core/input/InputDevice.h	(revision 3327)
+++ code/trunk/src/core/input/InputDevice.h	(revision 3327)
@@ -0,0 +1,233 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of InputDevice and InputDeviceTemplated
+*/
+
+#ifndef _InputDevice_H__
+#define _InputDevice_H__
+
+#include "InputPrereqs.h"
+
+#include <vector>
+#include <ois/OISInputManager.h>
+
+#include "util/Debug.h"
+#include "core/Clock.h"
+#include "InputState.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Abstract base class for all input devices (mouse, keyboard and joy sticks).
+
+        It provides common virtual functions to be used by the InputManager.
+    */
+    class InputDevice
+    {
+    public:
+        //! Only resets the members
+        InputDevice(unsigned int id) : bCalibrating_(false), deviceID_(id) { }
+        virtual ~InputDevice() { }
+        //! Returns the device class (derived) name as string
+        virtual std::string getClassName() const = 0;
+        //! Updates the device which should in turn distribute events
+        virtual void update(const Clock& time) = 0;
+        //! Clear all button related buffers
+        virtual void clearBuffers() = 0;
+
+        //! Start calibrating (only useful for joy sticks)
+        void startCalibration()
+        {
+            bCalibrating_ = true;
+            this->calibrationStarted();
+        }
+
+        //! Stop calibrating and evaluate the data (only useful for joy sticks)
+        void stopCalibration()
+        {
+            this->calibrationStopped();
+            bCalibrating_ = false;
+        }
+
+        //! Returns a reference to the internal input state vector. Use with care!
+        std::vector<InputState*>& getStateListRef() { return this->inputStates_; }
+        //! Returns the ID of the device (the same as in InputDeviceEnumerator for mouse and keyboard)
+        unsigned int getDeviceID() const { return this->deviceID_; }
+        //! Tells whether the device is in calibration mode
+        bool isCalibrating() const { return bCalibrating_; }
+
+    protected:
+        //! To be ovrridden by the subclass
+        virtual void calibrationStarted() { }
+        //! To be ovrridden by the subclass
+        virtual void calibrationStopped() { }
+
+        //! List of all input states that receive events from this device
+        std::vector<InputState*> inputStates_;
+
+    private:
+        InputDevice(const InputDevice& rhs); //!< Don't use!
+
+        bool bCalibrating_;                  //!< Whether the device is in calibration mode
+        const unsigned int deviceID_;        //!< ID of the device (the same as in InputDeviceEnumerator for mouse and keyboard)
+    };
+
+    /**
+    @brief
+        Heavily templated base class for all three input devices.
+
+        The purpose of this class is not to provide an interface but rather
+        to reduce code redundancy. This concerns device creation and destruction
+        as well as common code for button events (press, release, hold).
+
+        In order to derive from this class you have to supply it with a struct
+        as template parameter that contains the necessary type traits.
+    */
+    template <class Traits>
+    class InputDeviceTemplated : public InputDevice
+    {
+        typedef typename Traits::DeviceClass DeviceClass;
+        typedef typename Traits::OISDeviceClass OISDeviceClass;
+        typedef typename Traits::ButtonType ButtonType;
+        typedef typename Traits::ButtonTypeParam ButtonTypeParam;
+        static const OIS::Type OISDeviceValue = Traits::OISDeviceValue;
+
+    public:
+        //! Creates the OIS device
+        InputDeviceTemplated(unsigned int id, OIS::InputManager* oisInputManager)
+            : InputDevice(id)
+            , oisInputManager_(oisInputManager)
+        {
+            oisDevice_ = static_cast<OISDeviceClass*>(oisInputManager_->createInputObject(OISDeviceValue, true));
+            // Note: after the static_cast here, the casted this pointer becomes
+            //       invalid right until the subclass has been constructed!
+            oisDevice_->setEventCallback(static_cast<DeviceClass*>(this));
+            COUT(4) << "Instantiated a " << this->getClassName() << std::endl;
+        }
+
+        //! Destroys the OIS device
+        virtual ~InputDeviceTemplated()
+        {
+            try
+            {
+                oisInputManager_->destroyInputObject(oisDevice_);
+            }
+            catch (...)
+            {
+                COUT(1) << this->getClassName() << " destruction failed! Potential resource leak!" << std::endl;
+            }
+        }
+
+        //! Captures OIS events (which then get distributed to the derived class) and creates the button held events
+        void update(const Clock& time)
+        {
+            oisDevice_->capture();
+
+            // Call all the states with the held button event
+            for (unsigned int iB = 0; iB < pressedButtons_.size(); ++iB)
+                for (unsigned int iS = 0; iS < inputStates_.size(); ++iS)
+                    inputStates_[iS]->buttonEvent<ButtonEvent::THold, Traits>(
+                        this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(pressedButtons_[iB]));
+
+            // Call states with device update events
+            for (unsigned int i = 0; i < inputStates_.size(); ++i)
+                inputStates_[i]->update(time.getDeltaTime(), this->getDeviceID());
+
+            static_cast<DeviceClass*>(this)->updateImpl(time);
+        }
+
+        //! Clears the list of pressed buttons and calls the derived class's method
+        void clearBuffers()
+        {
+            pressedButtons_.clear();
+            static_cast<DeviceClass*>(this)->clearBuffersImpl();
+        }
+
+        // Returns a pointer to the OIS device
+        OISDeviceClass* getOISDevice()   { return this->oisDevice_; }
+        // Returns the name of the derived class as string
+        std::string getClassName() const { return DeviceClass::getClassNameImpl(); }
+
+    protected:
+        //! Common code for all button pressed events (updates pressed buttons list and calls the input states)
+        FORCEINLINE void buttonPressed(ButtonTypeParam button)
+        {
+            // check whether the button already is in the list (can happen when focus was lost)
+            unsigned int iButton = 0;
+            while (iButton < pressedButtons_.size() && pressedButtons_[iButton] != button)
+                iButton++;
+            if (iButton == pressedButtons_.size())
+                pressedButtons_.push_back(button);
+            else
+                return; // Button already pressed
+
+            // 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));
+        }
+
+        //! Common code for all button released events (updates pressed buttons list and calls the input states)
+        FORCEINLINE void buttonReleased(ButtonTypeParam button)
+        {
+            // remove the button from the pressedButtons_ list
+            for (unsigned int iButton = 0; iButton < pressedButtons_.size(); iButton++)
+            {
+                if (pressedButtons_[iButton] == button)
+                {
+                    pressedButtons_.erase(pressedButtons_.begin() + iButton);
+                    break;
+                }
+            }
+
+            // 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));
+        }
+
+        //! Managed pointer to the OIS device
+        OISDeviceClass* oisDevice_;
+
+    private:
+        //!< Fallback dummy function for static polymorphism
+        void clearBuffersImpl() { }
+        //!< Fallback dummy function for static polymorphism
+        void updateImpl(const Clock& time) { }
+        //!< Fallback dummy function for static polymorphism
+        ButtonType& getButtonEventArg(ButtonType& button) { return button; }
+
+        std::vector<ButtonType> pressedButtons_; //!< List of all buttons that are currently pressed down
+        OIS::InputManager* oisInputManager_;     //!< Pointer to the OIS InputManager that can create and destroy devices
+    };
+}
+
+#endif /* _InputDevice_H__ */
Index: code/trunk/src/core/input/InputHandler.h
===================================================================
--- code/trunk/src/core/input/InputHandler.h	(revision 3327)
+++ code/trunk/src/core/input/InputHandler.h	(revision 3327)
@@ -0,0 +1,148 @@
+/*
+ *   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 _InputHandler_H__
+#define _InputHandler_H__
+
+#include "InputPrereqs.h"
+#include "util/Math.h"
+
+namespace orxonox
+{
+    namespace ButtonEvent
+    {
+        //! Helper enum to deploy events with the help of templates
+        enum Value
+        {
+            Press,
+            Release,
+            Hold
+        };
+
+        //! Enables function overloading with integer values
+        template <ButtonEvent::Value Event>
+        struct EnumToType { };
+        typedef EnumToType<Press>   TPress;
+        typedef EnumToType<Release> TRelease;
+        typedef EnumToType<Hold>    THold;
+    }
+
+    namespace KeyboardModifier
+    {
+        //! Keyboard modifiers (shift, ctrl and alt)
+        enum Enum
+        {
+            Shift = 0x0000001,
+            Ctrl  = 0x0000010,
+            Alt   = 0x0000100
+        };
+    }
+
+    //! Event argument for key events
+    class _CoreExport KeyEvent
+    {
+    public:
+        KeyEvent(const OIS::KeyEvent& evt)
+            : key_(static_cast<KeyCode::ByEnum>(evt.key))
+            , text_(evt.text)
+            , modifiers_(0)
+        { }
+        bool operator==(const KeyEvent& rhs) const
+            { return rhs.key_ == key_; }
+        bool operator!=(const KeyEvent& rhs) const
+            { return rhs.key_ != key_; }
+        void setModifiers(int modifiers)
+            { modifiers_ = modifiers; }
+
+        bool isModifierDown(KeyboardModifier::Enum modifier) const
+            { return static_cast<KeyboardModifier::Enum>(modifier & modifiers_); }
+        KeyCode::ByEnum getKeyCode() const
+            { return key_; }
+        unsigned int getText() const { return text_; }
+
+    private:
+        KeyCode::ByEnum key_;
+        unsigned int text_;
+        int modifiers_;
+    };
+
+    /**
+    @brief
+        Base class for all input handlers like KeyBinder, InputBuffer, etc.
+
+        Derive from this class if you wish to receive input events.
+        But keep in mind that this is pointless wihtout first having an InputState.
+    @note
+        The definitions for the button events with the weird arguments are simply
+        to avoid redunant code in the input devices.
+    */
+    class _CoreExport InputHandler
+    {
+    public:
+        virtual ~InputHandler() { }
+
+        template<class T> void buttonEvent(unsigned int device, const T& button, ButtonEvent::TPress)
+            { this->buttonPressed(button); }
+        template<class T> void buttonEvent(unsigned int device, const T& button, ButtonEvent::TRelease)
+            { this->buttonReleased(button); }
+        template<class T> void buttonEvent(unsigned int device, const 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) { }
+        virtual void buttonReleased(const KeyEvent& evt) { }
+        virtual void buttonHeld    (const KeyEvent& evt) { }
+
+        virtual void buttonPressed (MouseButtonCode::ByEnum button) { }
+        virtual void buttonReleased(MouseButtonCode::ByEnum button) { }
+        virtual void buttonHeld    (MouseButtonCode::ByEnum button) { }
+        virtual void mouseMoved    (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) { }
+        virtual void mouseScrolled (int abs, int rel) { }
+
+        virtual void buttonPressed (unsigned int joyStick, JoyStickButtonCode::ByEnum button) { }
+        virtual void buttonReleased(unsigned int joyStick, JoyStickButtonCode::ByEnum button) { }
+        virtual void buttonHeld    (unsigned int joyStick, JoyStickButtonCode::ByEnum button) { }
+        virtual void axisMoved     (unsigned int joyStick, unsigned int axis, float value){ }
+
+        virtual void keyboardUpdated(float dt) { }
+        virtual void mouseUpdated   (float dt) { }
+        virtual void joyStickUpdated(unsigned int joyStick, float dt) { }
+
+        virtual void allDevicesUpdated(float dt) { }
+
+        //! Use this input handler if you want to occupy a device in an input state.
+        static InputHandler EMPTY;
+    };
+}
+
+#endif /* _InputHandler_H__ */
Index: code/trunk/src/core/input/InputInterfaces.h
===================================================================
--- code/trunk/src/core/input/InputInterfaces.h	(revision 3326)
+++ 	(revision )
@@ -1,556 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation; either version 2
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Reto Grieder
- *   Co-authors:
- *      ...
- *
- */
-
-/**
-@file
-@brief
-    Declarations of various interface classes for the input management.
-*/
-
-#ifndef _InputInterfaces_H__
-#define _InputInterfaces_H__
-
-#include "core/CorePrereqs.h"
-
-#include <ois/OISKeyboard.h>
-#include <ois/OISMouse.h>
-#include <ois/OISJoyStick.h>
-#include "util/Math.h"
-
-namespace orxonox
-{
-    namespace KeyCode
-    {
-        const unsigned int numberOfKeys = 0xEE; // 238
-
-        // note: KeyCode comments were directly copied from OISKeyboard.h
-        enum ByEnum
-        {
-            Unassigned    = OIS::KC_UNASSIGNED,
-            Escape        = OIS::KC_ESCAPE,
-            NumRow1       = OIS::KC_1,
-            NumRow2       = OIS::KC_2,
-            NumRow3       = OIS::KC_3,
-            NumRow4       = OIS::KC_4,
-            NumRow5       = OIS::KC_5,
-            NumRow6       = OIS::KC_6,
-            NumRow7       = OIS::KC_7,
-            NumRow8       = OIS::KC_8,
-            NumRow9       = OIS::KC_9,
-            NumRow0       = OIS::KC_0,
-            Minus         = OIS::KC_MINUS,           // - on main keyboard
-            Equals        = OIS::KC_EQUALS,
-            Back          = OIS::KC_BACK,            // backspace
-            Tab           = OIS::KC_TAB,
-            Q             = OIS::KC_Q,
-            W             = OIS::KC_W,
-            E             = OIS::KC_E,
-            R             = OIS::KC_R,
-            T             = OIS::KC_T,
-            Y             = OIS::KC_Y,
-            U             = OIS::KC_U,
-            I             = OIS::KC_I,
-            O             = OIS::KC_O,
-            P             = OIS::KC_P,
-            LeftBracket   = OIS::KC_LBRACKET,
-            RightBracket  = OIS::KC_RBRACKET,
-            Return        = OIS::KC_RETURN,          // Enter on main keyboard
-            LeftControl   = OIS::KC_LCONTROL,
-            A             = OIS::KC_A,
-            S             = OIS::KC_S,
-            D             = OIS::KC_D,
-            F             = OIS::KC_F,
-            G             = OIS::KC_G,
-            H             = OIS::KC_H,
-            J             = OIS::KC_J,
-            K             = OIS::KC_K,
-            L             = OIS::KC_L,
-            Semicolon     = OIS::KC_SEMICOLON,
-            Apostrophe    = OIS::KC_APOSTROPHE,
-            Grave         = OIS::KC_GRAVE,           // accent
-            LeftShift     = OIS::KC_LSHIFT,
-            Backslash     = OIS::KC_BACKSLASH,
-            Z             = OIS::KC_Z,
-            X             = OIS::KC_X,
-            C             = OIS::KC_C,
-            V             = OIS::KC_V,
-            B             = OIS::KC_B,
-            N             = OIS::KC_N,
-            M             = OIS::KC_M,
-            Comma         = OIS::KC_COMMA,
-            Period        = OIS::KC_PERIOD,          // . on main keyboard
-            Slash         = OIS::KC_SLASH,           // / on main keyboard
-            RightShift    = OIS::KC_RSHIFT,
-            Multiply      = OIS::KC_MULTIPLY,        // * on numeric keypad
-            LeftAlt       = OIS::KC_LMENU,           // left Alt
-            Space         = OIS::KC_SPACE,
-            CapsLock      = OIS::KC_CAPITAL,
-            F1            = OIS::KC_F1,
-            F2            = OIS::KC_F2,
-            F3            = OIS::KC_F3,
-            F4            = OIS::KC_F4,
-            F5            = OIS::KC_F5,
-            F6            = OIS::KC_F6,
-            F7            = OIS::KC_F7,
-            F8            = OIS::KC_F8,
-            F9            = OIS::KC_F9,
-            F10           = OIS::KC_F10,
-            NumLock       = OIS::KC_NUMLOCK,
-            ScrollLock    = OIS::KC_SCROLL,          // Scroll Lock
-            Numpad7       = OIS::KC_NUMPAD7,
-            Numpad8       = OIS::KC_NUMPAD8,
-            Numpad9       = OIS::KC_NUMPAD9,
-            NumpadSubtract= OIS::KC_SUBTRACT,        // - on numeric keypad
-            Numpad4       = OIS::KC_NUMPAD4,
-            Numpad5       = OIS::KC_NUMPAD5,
-            Numpad6       = OIS::KC_NUMPAD6,
-            NumpadAdd     = OIS::KC_ADD,             // + on numeric keypad
-            Numpad1       = OIS::KC_NUMPAD1,
-            Numpad2       = OIS::KC_NUMPAD2,
-            Numpad3       = OIS::KC_NUMPAD3,
-            Numpad0       = OIS::KC_NUMPAD0,
-            NumpadPeriod  = OIS::KC_DECIMAL,         // . on numeric keypad
-            LessThan      = OIS::KC_OEM_102,         // < > | on UK/Germany keyboards
-            F11           = OIS::KC_F11,
-            F12           = OIS::KC_F12,
-            F13           = OIS::KC_F13,             //                     (NEC PC98)
-            F14           = OIS::KC_F14,             //                     (NEC PC98)
-            F15           = OIS::KC_F15,             //                     (NEC PC98)
-            Kana          = OIS::KC_KANA,            // (Japanese keyboard)
-            ABNT_C1       = OIS::KC_ABNT_C1,         // / ? on Portugese (Brazilian) keyboards
-            Convert       = OIS::KC_CONVERT,         // (Japanese keyboard)
-            NoConvert     = OIS::KC_NOCONVERT,       // (Japanese keyboard)
-            Yen           = OIS::KC_YEN,             // (Japanese keyboard)
-            ABNT_C2       = OIS::KC_ABNT_C2,         // Numpad . on Portugese (Brazilian) keyboards
-            NumpadEquals  = OIS::KC_NUMPADEQUALS,    // = on numeric keypad (NEC PC98)
-            PreviousTrack = OIS::KC_PREVTRACK,       // Previous Track (KC_CIRCUMFLEX on Japanese keyboard)
-            AT            = OIS::KC_AT,              //                     (NEC PC98)
-            Colon         = OIS::KC_COLON,           //                     (NEC PC98)
-            Underline     = OIS::KC_UNDERLINE,       //                     (NEC PC98)
-            Kanji         = OIS::KC_KANJI,           // (Japanese keyboard)
-            Stop          = OIS::KC_STOP,            //                     (NEC PC98)
-            AX            = OIS::KC_AX,              //                     (Japan AX)
-            Unlabeled     = OIS::KC_UNLABELED,       //                        (J3100)
-            NextTrack     = OIS::KC_NEXTTRACK,       // Next Track
-            NumpadEnter   = OIS::KC_NUMPADENTER,     // Enter on numeric keypad
-            RightControl  = OIS::KC_RCONTROL,
-            Mute          = OIS::KC_MUTE,            // Mute
-            Calculator    = OIS::KC_CALCULATOR,      // Calculator
-            PlayPause     = OIS::KC_PLAYPAUSE,       // Play / Pause
-            MediaStop     = OIS::KC_MEDIASTOP,       // Media Stop
-            VolumeDown    = OIS::KC_VOLUMEDOWN,      // Volume -
-            VolumeUp      = OIS::KC_VOLUMEUP,        // Volume +
-            WebHome       = OIS::KC_WEBHOME,         // Web home
-            NumpadComma   = OIS::KC_NUMPADCOMMA,     // , on numeric keypad (NEC PC98)
-            Divide        = OIS::KC_DIVIDE,          // / on numeric keypad
-            SystemRequest = OIS::KC_SYSRQ,
-            RightAlt      = OIS::KC_RMENU,           // right Alt
-            Pause         = OIS::KC_PAUSE,           // Pause
-            Home          = OIS::KC_HOME,            // Home on arrow keypad
-            Up            = OIS::KC_UP,              // UpArrow on arrow keypad
-            PageUp        = OIS::KC_PGUP,            // PgUp on arrow keypad
-            Left          = OIS::KC_LEFT,            // LeftArrow on arrow keypad
-            Right         = OIS::KC_RIGHT,           // RightArrow on arrow keypad
-            End           = OIS::KC_END,             // End on arrow keypad
-            Down          = OIS::KC_DOWN,            // DownArrow on arrow keypad
-            PageDown      = OIS::KC_PGDOWN,          // PgDn on arrow keypad
-            Insert        = OIS::KC_INSERT,          // Insert on arrow keypad
-            Delete        = OIS::KC_DELETE,          // Delete on arrow keypad
-            LeftWindows   = OIS::KC_LWIN,            // Left Windows key
-            RightWindows  = OIS::KC_RWIN,            // Right Windows key
-            Apps          = OIS::KC_APPS,            // AppMenu key
-            Power         = OIS::KC_POWER,           // System Power
-            Sleep         = OIS::KC_SLEEP,           // System Sleep
-            Wake          = OIS::KC_WAKE,            // System Wake
-            WebSearch     = OIS::KC_WEBSEARCH,       // Web Search
-            WebFavorites  = OIS::KC_WEBFAVORITES,    // Web Favorites
-            WebRefresh    = OIS::KC_WEBREFRESH,      // Web Refresh
-            WebStop       = OIS::KC_WEBSTOP,         // Web Stop
-            WebForward    = OIS::KC_WEBFORWARD,      // Web Forward
-            WebBack       = OIS::KC_WEBBACK,         // Web Back
-            MyComputer    = OIS::KC_MYCOMPUTER,      // My Computer
-            Mail          = OIS::KC_MAIL,            // Mail
-            MediaSelect   = OIS::KC_MEDIASELECT      // Media Select
-        };
-        
-        // Names as string. Has no real linkage!
-        const char* const ByString[] =
-        {
-            "Unassigned",
-            "Escape",
-            "NumRow1", "NumRow2", "NumRow3", "NumRow4", "NumRow5",
-            "NumRow6", "NumRow7", "NumRow8", "NumRow9", "NumRow0",
-            "Minus", "Equals", "Back", "Tab",
-            "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
-            "LeftBracket", "RightBracket",
-            "Return", "LeftControl",
-            "A", "S", "D", "F", "G", "H", "J", "K", "L",
-            "Semicolon", "Apostrophe", "Grave",
-            "LeftShift", "Backslash",
-            "Z", "X", "C", "V", "B", "N", "M",
-            "Comma", "Period", "Slash",
-            "RightShift",
-            "Multiply",
-            "LeftAlt",
-            "Space",
-            "CapsLock",
-            "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
-            "NumLock", "ScrollLock",
-            "Numpad7", "Numpad8", "Numpad9",
-            "NumpadSubtract",
-            "Numpad4", "Numpad5", "Numpad6",
-            "NumpadAdd",
-            "Numpad1", "Numpad2", "Numpad3", "Numpad0",
-            "NumpadPeriod",
-            "","",
-            "LessThan",
-            "F11", "F12",
-            "","","","","","","","","","","",
-            "F13", "F14", "F15",
-            "","","","","","","","","","",
-            "Kana",
-            "","",
-            "ABNT_C1",
-            "","","","","",
-            "Convert",
-            "",
-            "NoConvert",
-            "",
-            "Yen",
-            "ABNT_C2",
-            "","","","","","","","","","","","","","",
-            "NumpadEquals",
-            "","",
-            "PreviousTrack",
-            "AT",
-            "Colon", "Underline",
-            "Kanji",
-            "Stop",
-            "AX",
-            "Unlabeled",
-            "NextTrack",
-            "","",
-            "NumpadEnter",
-            "RightControl",
-            "","",
-            "Mute",
-            "Calculator",
-            "PlayPause",
-            "",
-            "MediaStop",
-            "","","","","","","","","",
-            "VolumeDown",
-            "",
-            "VolumeUp",
-            "",
-            "WebHome",
-            "NumpadComma",
-            "",
-            "Divide",
-            "",
-            "SystemRequest",
-            "RightAlt",
-            "","","","","","","","","","","","",
-            "Pause",
-            "",
-            "Home",
-            "UP",
-            "PageUp",
-            "",
-            "Left",
-            "",
-            "Right",
-            "",
-            "End", "Down", "PageDown", "Insert", "Delete",
-            "","","","","","","",
-            "LeftWindows", "RightWindows", "Apps",
-            "Power", "Sleep",
-            "","","",
-            "Wake",
-            "",
-            "WebSearch", "WebFavorites", "WebRefresh", "WebStop", "WebForward", "WebBack",
-            "MyComputer", "Mail", "MediaSelect"
-        };
-    }
-
-    namespace MouseButtonCode
-    {
-        const unsigned int numberOfButtons = 8;
-
-        enum ByEnum
-        {
-            Left    = OIS::MB_Left,
-            Right   = OIS::MB_Right,
-            Middle  = OIS::MB_Middle,
-            Button3 = OIS::MB_Button3,
-            Button4 = OIS::MB_Button4,
-            Button5 = OIS::MB_Button5,
-            Button6 = OIS::MB_Button6,
-            Button7 = OIS::MB_Button7,
-        };
-
-        // Names as string. Has no real linkage!
-        const char* const ByString[] =
-        {
-            "Left",
-            "Right",
-            "Middle",
-            "Button3",
-            "Button4",
-            "Button5",
-            "Button6",
-            "Button7",
-        };
-    }
-
-    namespace MouseAxisCode
-    {
-        const unsigned int numberOfAxes = 2;
-
-        enum ByEnum
-        {
-            X,
-            Y
-        };
-
-        // Names as string. Has no real linkage!
-        const char* const ByString[] =
-        {
-            "X",
-            "Y"
-        };
-    }
-
-    namespace JoyStickButtonCode
-    {
-        const unsigned int numberOfButtons = 64;
-
-        enum ByEnum
-        {
-            Button0       =  0, Button1       =  1, Button2       =  2, Button3       =  3,
-            Button4       =  4, Button5       =  5, Button6       =  6, Button7       =  7,
-            Button8       =  8, Button9       =  9, Button10      = 10, Button11      = 11,
-            Button12      = 12, Button13      = 13, Button14      = 14, Button15      = 15,
-            Button16      = 16, Button17      = 17, Button18      = 18, Button19      = 19,
-            Button20      = 20, Button21      = 21, Button22      = 22, Button23      = 23,
-            Button24      = 24, Button25      = 25, Button26      = 26, Button27      = 27,
-            Button28      = 28, Button29      = 29, Button30      = 30, Button31      = 31,
-
-            POV0North     = 32, POV0South     = 33, POV0East      = 34, POV0West      = 35,
-            POV0NorthEast = 36, POV0SouthEast = 37, POV0NorthWest = 38, POV0SouthWest = 39,
-
-            POV1North     = 40, POV1South     = 41, POV1East      = 42, POV1West      = 43,
-            POV1NorthEast = 44, POV1SouthEast = 45, POV1NorthWest = 46, POV1SouthWest = 47,
-
-            POV2North     = 48, POV2South     = 49, POV2East      = 50, POV2West      = 51,
-            POV2NorthEast = 52, POV2SouthEast = 53, POV2NorthWest = 54, POV2SouthWest = 55,
-
-            POV3North     = 56, POV3South     = 57, POV3East      = 58, POV3West      = 59,
-            POV3NorthEast = 60, POV3SouthEast = 61, POV3NorthWest = 62, POV3SouthWest = 63,
-        };
-
-        // Names as string. Has no real linkage!
-        const char* const ByString[] =
-        {
-            "Button00",      "Button01",      "Button02",      "Button03",
-            "Button04",      "Button05",      "Button06",      "Button07",
-            "Button08",      "Button09",      "Button10",      "Button11",
-            "Button12",      "Button13",      "Button14",      "Button15",
-            "Button16",      "Button17",      "Button18",      "Button19",
-            "Button20",      "Button21",      "Button22",      "Button23",
-            "Button24",      "Button25",      "Button26",      "Button27",
-            "Button28",      "Button29",      "Button30",      "Button31",
-            "POV0North",     "POV0South",     "POV0East",      "POV0West",
-            "POV0NorthEast", "POV0SouthEast", "POV0NorthWest", "POV0SouthWest",
-            "POV1North",     "POV1South",     "POV1East",      "POV1West",
-            "POV1NorthEast", "POV1SouthEast", "POV1NorthWest", "POV1SouthWest",
-            "POV2North",     "POV2South",     "POV2East",      "POV2West",
-            "POV2NorthEast", "POV2SouthEast", "POV2NorthWest", "POV2SouthWest",
-            "POV3North",     "POV3South",     "POV3East",      "POV3West",
-            "POV3NorthEast", "POV3SouthEast", "POV3NorthWest", "POV3SouthWest"
-        };
-    }
-
-    namespace JoyStickAxisCode
-    {
-        const unsigned int numberOfAxes = 24;
-
-        enum ByEnum
-        {
-            Slider0 =  0, Slider1 =  1, Slider2 =  2, Slider3 =  3,
-            Slider4 =  4, Slider5 =  5, Slider6 =  6, Slider7 =  7,
-            Axis0   =  8, Axis1   =  9, Axis2   = 10, Axis3   = 11,
-            Axis4   = 12, Axis5   = 13, Axis6   = 14, Axis7   = 15,
-            Axis8   = 16, Axis9   = 17, Axis10  = 18, Axis11  = 19,
-            Axis12  = 20, Axis13  = 21, Axis14  = 22, Axis15  = 23
-        };
-
-        // Names as string. Has no real linkage!
-        const char* const ByString[] =
-        {
-            "Slider0", "Slider1", "Slider2", "Slider3",
-            "Slider4", "Slider5", "Slider6", "Slider7",
-            "Axis00",  "Axis01",  "Axis02",  "Axis03",
-            "Axis04",  "Axis05",  "Axis06",  "Axis07",
-            "Axis08",  "Axis09",  "Axis10",  "Axis11",
-            "Axis12",  "Axis13",  "Axis14",  "Axis15"
-        };
-    }
-
-    namespace KeyboardModifier
-    {
-        enum Enum
-        {
-            Shift = 0x0000001,
-            Ctrl  = 0x0000010,
-            Alt   = 0x0000100
-        };
-    }
-    
-    namespace InputDevice
-    {
-        enum Enum
-        {
-            Keyboard,
-            Mouse,
-            JoyStick0,
-            JoyStick1,
-            JoyStick2,
-            JoyStick3
-            // note: No problem if there are more joy sticks. This enum is just for convenience.
-        };
-    }
-
-    struct _CoreExport Key
-    {
-        Key(const OIS::KeyEvent& evt) : key((KeyCode::ByEnum)evt.key), text(evt.text) { }
-        KeyCode::ByEnum key;
-        unsigned int text;
-    };
-
-    class _CoreExport KeyEvent
-    {
-    public:
-        KeyEvent(KeyCode::ByEnum key, unsigned int text) : key(key), text(text) { }
-        KeyEvent(const OIS::KeyEvent& evt, unsigned int mod)
-            : key((KeyCode::ByEnum)evt.key), text(evt.text), modifiers(mod) { }
-        KeyEvent(const Key& key, unsigned int mod) : key(key.key), text(key.text), modifiers(mod) { }
-        bool isModifierDown(KeyboardModifier::Enum modifier) const
-            { return (KeyboardModifier::Enum)modifier&modifiers; }
-
-        const KeyCode::ByEnum key;
-        unsigned int text;
-        unsigned int modifiers;
-    };
-
-
-    class _CoreExport InputHandler
-    {
-    public:
-        virtual ~InputHandler() { }
-        virtual void updateInput(float dt) = 0;
-    };
-
-    /**
-    @brief
-        Interface class used for key input listeners.
-    */
-    class _CoreExport KeyHandler : virtual public InputHandler
-    {
-    public:
-        virtual ~KeyHandler() { }
-        virtual void keyPressed (const KeyEvent& evt) = 0;
-        virtual void keyReleased(const KeyEvent& evt) = 0;
-        virtual void keyHeld    (const KeyEvent& evt) = 0;
-        virtual void updateKey    (float dt) = 0;
-    };
-
-    /**
-    @brief
-        Interface class used for mouse input listeners.
-    */
-    class _CoreExport MouseHandler : virtual public InputHandler
-    {
-    public:
-        virtual ~MouseHandler() { }
-        virtual void mouseButtonPressed (MouseButtonCode::ByEnum id) = 0;
-        virtual void mouseButtonReleased(MouseButtonCode::ByEnum id) = 0;
-        virtual void mouseButtonHeld    (MouseButtonCode::ByEnum id) = 0;
-        virtual void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0;
-        virtual void mouseScrolled      (int abs, int rel)     = 0;
-        virtual void updateMouse          (float dt) = 0;
-    };
-
-
-    /**
-    @brief
-        Interface class used for joy stick input listeners.
-    */
-    class _CoreExport JoyStickHandler : virtual public InputHandler
-    {
-    public:
-        virtual ~JoyStickHandler() { }
-        virtual void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
-        virtual void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
-        virtual void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
-        virtual void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) = 0;
-        virtual void updateJoyStick          (float dt, unsigned int joyStick) = 0;
-    };
-
-    class _CoreExport EmptyHandler : public KeyHandler, public MouseHandler, public JoyStickHandler
-    {
-        friend class InputManager;
-    private:
-        EmptyHandler() { }
-        EmptyHandler(EmptyHandler&);
-        virtual ~EmptyHandler() { }
-
-        void updateInput(float dt) { }
-        void updateJoyStick(float dt, unsigned int joyStick) { }
-        void updateMouse(float dt) { }
-        void updateKey(float dt) { }
-
-        void keyPressed (const KeyEvent& evt) { }
-        void keyReleased(const KeyEvent& evt) { }
-        void keyHeld    (const KeyEvent& evt) { }
-
-        void mouseButtonPressed (MouseButtonCode::ByEnum id) { }
-        void mouseButtonReleased(MouseButtonCode::ByEnum id) { }
-        void mouseButtonHeld    (MouseButtonCode::ByEnum id) { }
-        void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) { }
-        void mouseScrolled      (int abs, int rel) { }
-
-        void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) { }
-        void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id) { }
-        void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) { }
-        void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) { }
-    };
-
-}
-
-#endif /* _InputInterfaces_H__ */
Index: code/trunk/src/core/input/InputManager.cc
===================================================================
--- code/trunk/src/core/input/InputManager.cc	(revision 3326)
+++ code/trunk/src/core/input/InputManager.cc	(revision 3327)
@@ -30,16 +30,15 @@
 @file
 @brief
-    Implementation of the InputManager that captures all the input from OIS
-    and redirects it to handlers.
- */
+    Implementation of the InputManager and a static variable from the InputHandler.
+*/
 
 #include "InputManager.h"
 
+#include <cassert>
 #include <climits>
-#include <cassert>
 #include <ois/OISException.h>
 #include <ois/OISInputManager.h>
-
-#include "util/Convert.h"
+#include <boost/foreach.hpp>
+
 #include "util/Exception.h"
 #include "util/ScopeGuard.h"
@@ -49,49 +48,32 @@
 #include "core/ConsoleCommand.h"
 #include "core/CommandLine.h"
+#include "core/Functor.h"
 
 #include "InputBuffer.h"
 #include "KeyDetector.h"
-#include "InputState.h"
-#include "SimpleInputState.h"
-#include "ExtendedInputState.h"
-#include "JoyStickDeviceNumberListener.h"
-
-// HACK (include this as last, X11 seems to define some macros...)
-#ifdef ORXONOX_PLATFORM_LINUX
-#  include <ois/linux/LinuxMouse.h>
-#endif
+#include "JoyStick.h"
+#include "JoyStickQuantityListener.h"
+#include "Mouse.h"
+#include "Keyboard.h"
 
 namespace orxonox
 {
-    SetConsoleCommand(InputManager, calibrate, true);
-    SetConsoleCommand(InputManager, reload, false);
-#ifdef ORXONOX_PLATFORM_LINUX
-    SetConsoleCommand(InputManager, grabMouse, true);
-    SetConsoleCommand(InputManager, ungrabMouse, true);
-#endif
     SetCommandLineSwitch(keyboard_no_grab).information("Whether not to exclusively grab the keyboard");
 
-    EmptyHandler InputManager::EMPTY_HANDLER;
+    // Abuse of this source file for the InputHandler
+    InputHandler InputHandler::EMPTY;
+
     InputManager* InputManager::singletonRef_s = 0;
 
-    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));
+    //! Defines the |= operator for easier use.
+    inline InputManager::State operator|=(InputManager::State& lval, InputManager::State rval)
+    {
+        return (lval = (InputManager::State)(lval | rval));
+    }
+
+    //! Defines the &= operator for easier use.
+    inline InputManager::State operator&=(InputManager::State& lval, int rval)
+    {
+        return (lval = (InputManager::State)(lval & rval));
     }
 
@@ -100,22 +82,12 @@
     // ##########                                        ##########
     // ############################################################
-
-    /**
-    @brief
-        Constructor only sets member fields to initial zero values
-        and registers the class in the class hierarchy.
-    */
-    InputManager::InputManager()
-        : inputSystem_(0)
-        , keyboard_(0)
-        , mouse_(0)
-        , joySticksSize_(0)
-        , devicesNum_(0)
+    InputManager::InputManager(size_t windowHnd)
+        : internalState_(Bad)
+        , oisInputManager_(0)
+        , devices_(2)
         , windowHnd_(0)
-        , internalState_(Uninitialised)
-        , stateEmpty_(0)
+        , emptyState_(0)
         , keyDetector_(0)
-        , calibratorCallbackBuffer_(0)
-        , keyboardModifiers_(0)
+        , calibratorCallbackHandler_(0)
     {
         RegisterRootObject(InputManager);
@@ -124,25 +96,52 @@
         singletonRef_s = this;
 
-        setConfigValues();
-    }
-
-    /**
-    @brief
-        Sets the configurable values.
-    */
+        CCOUT(4) << "Constructing..." << std::endl;
+
+        this->setConfigValues();
+
+        this->loadDevices(windowHnd);
+
+        // Lowest priority empty InputState
+        emptyState_ = createInputState("empty", false, false, InputStatePriority::Empty);
+        emptyState_->setHandler(&InputHandler::EMPTY);
+        activeStates_[emptyState_->getPriority()] = emptyState_;
+
+        // KeyDetector to evaluate a pressed key's name
+        InputState* detector = createInputState("detector", false, false, InputStatePriority::Detector);
+        // Create a callback to avoid buttonHeld events after the key has been detected
+        FunctorMember<InputManager>* bufferFunctor = createFunctor(&InputManager::clearBuffers);
+        bufferFunctor->setObject(this);
+        detector->setLeaveFunctor(bufferFunctor);
+        keyDetector_ = new KeyDetector();
+        detector->setHandler(keyDetector_);
+
+        // Joy stick calibration helper callback
+        InputState* calibrator = createInputState("calibrator", false, false, InputStatePriority::Calibrator);
+        calibrator->setHandler(&InputHandler::EMPTY);
+        calibratorCallbackHandler_ = new InputBuffer();
+        calibratorCallbackHandler_->registerListener(this, &InputManager::stopCalibration, '\r', true);
+        calibrator->setKeyHandler(calibratorCallbackHandler_);
+
+        this->updateActiveStates();
+
+        {
+            // calibrate console command
+            FunctorMember<InputManager>* functor = createFunctor(&InputManager::calibrate);
+            functor->setObject(this);
+            this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "calibrate"), true);
+        }
+        {
+            // reload console command
+            FunctorMember<InputManager>* functor = createFunctor(&InputManager::reload);
+            functor->setObject(this);
+            this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "reload"), false);
+        }
+
+        internalState_ = Nothing;
+        CCOUT(4) << "Construction complete." << std::endl;
+    }
+
     void InputManager::setConfigValues()
     {
-        SetConfigValue(calibrationFilename_, "joystick_calibration.ini")
-            .description("Ini filename for the the joy stick calibration data.")
-            .callback(this, &InputManager::_calibrationFileCallback);
-    }
-
-    /**
-    @brief
-        Callback for the joy stick calibration config file. @see setConfigValues.
-    */
-    void InputManager::_calibrationFileCallback()
-    {
-        ConfigFileManager::getInstance().setFilename(ConfigFileType::JoyStickCalibration, calibrationFilename_);
     }
 
@@ -150,5 +149,5 @@
     @brief
         Creates the OIS::InputMananger, the keyboard, the mouse and
-        the joysticks and assigns the key bindings.
+        the joys ticks. If either of the first two fail, this method throws an exception.
     @param windowHnd
         The window handle of the render window
@@ -157,533 +156,190 @@
     @param windowHeight
         The height of the render window
-    @param joyStickSupport
-        Whether or not to load the joy sticks as well
     */
-    void InputManager::initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport)
-    {
-        CCOUT(3) << "Initialising Input System..." << std::endl;
-
-        if (!(internalState_ & OISReady))
-        {
-            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 << static_cast<unsigned int>(windowHnd);
-            paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
+    void InputManager::loadDevices(size_t windowHnd)
+    {
+        CCOUT(3) << "Loading input devices..." << std::endl;
+
+        // When loading the devices they should not already be loaded
+        assert(internalState_ & Bad);
+        assert(devices_[InputDeviceEnumerator::Mouse] == 0);
+        assert(devices_[InputDeviceEnumerator::Keyboard] == 0);
+        assert(devices_.size() == InputDeviceEnumerator::FirstJoyStick);
+
+        // store handle internally so we can reload OIS
+        windowHnd_ = windowHnd;
+
+        OIS::ParamList paramList;
+        std::ostringstream windowHndStr;
+
+        // Fill parameter list
+        windowHndStr << static_cast<unsigned int>(windowHnd);
+        paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
 #if defined(ORXONOX_PLATFORM_WINDOWS)
-            //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
-            //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
-            //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
-            //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
+        //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
+        //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
+        //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
+        //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
 #elif defined(ORXONOX_PLATFORM_LINUX)
-            paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
-            paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true"));
-            paramList.insert(std::make_pair(std::string("x11_mouse_hide"), "true"));
-            bool kbNoGrab;
-            CommandLine::getValue("keyboard_no_grab", &kbNoGrab);
-            if (kbNoGrab)
-                paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
+        paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
+        paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true"));
+        paramList.insert(std::make_pair(std::string("x11_mouse_hide"), "true"));
+        bool kbNoGrab;
+        CommandLine::getValue("keyboard_no_grab", &kbNoGrab);
+        if (kbNoGrab)
+            paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
+        else
+            paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("true")));
+#endif
+
+        try
+        {
+            oisInputManager_ = OIS::InputManager::createInputSystem(paramList);
+            // Exception-safety
+            Loki::ScopeGuard guard = Loki::MakeGuard(OIS::InputManager::destroyInputSystem, oisInputManager_);
+            CCOUT(ORX_DEBUG) << "Created OIS input manager." << std::endl;
+
+            if (oisInputManager_->getNumberOfDevices(OIS::OISKeyboard) > 0)
+                devices_[InputDeviceEnumerator::Keyboard] = new Keyboard(InputDeviceEnumerator::Keyboard, oisInputManager_);
             else
-                paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("true")));
-#endif
-
+                ThrowException(InitialisationFailed, "InputManager: No keyboard found, cannot proceed!");
+
+            // Successful initialisation
+            guard.Dismiss();
+        }
+        catch (std::exception& ex)
+        {
+            oisInputManager_ = NULL;
+            internalState_ |= Bad;
+            ThrowException(InitialisationFailed, "Could not initialise the input system: " << ex.what());
+        }
+
+        // TODO: Remove the two parameters
+        this->loadMouse();
+        this->loadJoySticks();
+
+        // Reorder states in case some joy sticks were added/removed
+        this->updateActiveStates();
+
+        CCOUT(3) << "Input devices loaded." << std::endl;
+    }
+
+    //! Creates a new orxonox::Mouse
+    void InputManager::loadMouse()
+    {
+        if (oisInputManager_->getNumberOfDevices(OIS::OISMouse) > 0)
+        {
             try
             {
-                inputSystem_ = OIS::InputManager::createInputSystem(paramList);
-                // Exception-safety
-                Loki::ScopeGuard guard = Loki::MakeGuard(OIS::InputManager::destroyInputSystem, inputSystem_);
-                CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl;
-
-                _initialiseKeyboard();
-
-                // Nothing below should throw anymore, dismiss the guard
-                guard.Dismiss();
-            }
-            catch (OIS::Exception& ex)
-            {
-                ThrowException(InitialisationFailed, "Could not initialise the input system: " << ex.what());
-            }
-
-            _initialiseMouse();
-
-            if (joyStickSupport)
-                _initialiseJoySticks();
-            // Do this anyway to also inform when a joystick was detached.
-            _configureJoySticks();
-
-            // Set mouse/joystick region
-            if (mouse_)
-                setWindowExtents(windowWidth, windowHeight);
-
-            // clear all buffers
-            _clearBuffers();
-
-            internalState_ |= OISReady;
-
-            CCOUT(ORX_DEBUG) << "Initialising OIS components done." << std::endl;
+                devices_[InputDeviceEnumerator::Mouse] = new Mouse(InputDeviceEnumerator::Mouse, oisInputManager_);
+            }
+            catch (const OIS::Exception& ex)
+            {
+                CCOUT(2) << "Warning: Failed to create Mouse:" << ex.eText << std::endl
+                         << "Proceeding without mouse support." << std::endl;
+            }
         }
         else
-        {
-            CCOUT(2) << "Warning: OIS compoments already initialised, skipping" << std::endl;
-        }
-
-        if (!(internalState_ & InternalsReady))
-        {
-            CCOUT(4) << "Initialising InputStates components..." << std::endl;
-
-            // Lowest priority empty InputState
-            stateEmpty_ = createInputState<SimpleInputState>("empty", false, false, InputStatePriority::Empty);
-            stateEmpty_->setHandler(&EMPTY_HANDLER);
-            activeStates_[stateEmpty_->getPriority()] = stateEmpty_;
-
-            // KeyDetector to evaluate a pressed key's name
-            SimpleInputState* detector = createInputState<SimpleInputState>("detector", false, false, InputStatePriority::Detector);
-            keyDetector_ = new KeyDetector();
-            detector->setHandler(keyDetector_);
-
-            // Joy stick calibration helper callback
-            SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", false, false, InputStatePriority::Calibrator);
-            calibrator->setHandler(&EMPTY_HANDLER);
-            calibratorCallbackBuffer_ = new InputBuffer();
-            calibratorCallbackBuffer_->registerListener(this, &InputManager::_completeCalibration, '\r', true);
-            calibrator->setKeyHandler(calibratorCallbackBuffer_);
-
-            internalState_ |= InternalsReady;
-
-            CCOUT(4) << "Initialising InputStates complete." << std::endl;
-        }
-
-        _updateActiveStates();
-
-        CCOUT(3) << "Initialising complete." << std::endl;
+            CCOUT(ORX_WARNING) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
+    }
+
+    //! Creates as many joy sticks as are available.
+    void InputManager::loadJoySticks()
+    {
+        for (int i = 0; i < oisInputManager_->getNumberOfDevices(OIS::OISJoyStick); i++)
+        {
+            try
+            {
+                devices_.push_back(new JoyStick(InputDeviceEnumerator::FirstJoyStick + i, oisInputManager_));
+            }
+            catch (std::exception ex)
+            {
+                CCOUT(2) << "Warning: Failed to create joy stick: " << ex.what() << std::endl;
+            }
+        }
+
+        // inform all JoyStick Device Number Listeners
+        std::vector<JoyStick*> joyStickList;
+        for (unsigned int i = InputDeviceEnumerator::FirstJoyStick; i < devices_.size(); ++i)
+            joyStickList.push_back(static_cast<JoyStick*>(devices_[i]));
+        JoyStickQuantityListener::changeJoyStickQuantity(joyStickList);
+    }
+
+    void InputManager::setKeyDetectorCallback(const std::string& command)
+    {
+        this->keyDetector_->setCallbackCommand(command);
+    }
+
+    // ############################################################
+    // #####                    Destruction                   #####
+    // ##########                                        ##########
+    // ############################################################
+
+    InputManager::~InputManager()
+    {
+        CCOUT(4) << "Destroying..." << std::endl;
+
+        // Destroy calibrator helper handler and state
+        delete keyDetector_;
+        this->destroyState("calibrator");
+        // Destroy KeyDetector and state
+        delete calibratorCallbackHandler_;
+        this->destroyState("detector");
+        // destroy the empty InputState
+        this->destroyStateInternal(this->emptyState_);
+
+        // destroy all user InputStates
+        while (statesByName_.size() > 0)
+            this->destroyStateInternal((*statesByName_.rbegin()).second);
+
+        if (!(internalState_ & Bad))
+            this->destroyDevices();
+
+        CCOUT(4) << "Destruction complete." << std::endl;
+        singletonRef_s = 0;
     }
 
     /**
     @brief
-        Creates a keyboard and sets the event handler.
-    @return
-        False if keyboard stays uninitialised, true otherwise.
+        Destoys all input devices (joy sticks, mouse, keyboard and OIS::InputManager)
+    @throw
+        Method does not throw
     */
-    void InputManager::_initialiseKeyboard()
-    {
-        if (keyboard_ != 0)
-        {
-            CCOUT(2) << "Warning: Keyboard already initialised, skipping." << std::endl;
-            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, "InputManager: No keyboard found, cannot proceed!");
-        }
-    }
-
-    /**
-    @brief
-        Creates a mouse and sets the event handler.
-    @return
-        False if mouse stays uninitialised, true otherwise.
-    */
-    void InputManager::_initialiseMouse()
-    {
-        if (mouse_ != 0)
-        {
-            CCOUT(2) << "Warning: Mouse already initialised, skipping." << std::endl;
-            return;
-        }
+    void InputManager::destroyDevices()
+    {
+        CCOUT(3) << "Destroying devices..." << std::endl;
+
+        BOOST_FOREACH(InputDevice*& device, devices_)
+        {
+            if (device == NULL)
+                continue;
+            std::string className = device->getClassName();
+            try
+            {
+                delete device;
+                device = 0;
+                CCOUT(4) << className << " destroyed." << std::endl;
+            }
+            catch (...)
+            {
+                CCOUT(1) << className << " destruction failed! Potential resource leak!" << std::endl;
+            }
+        }
+        devices_.resize(InputDeviceEnumerator::FirstJoyStick);
+
+        assert(oisInputManager_ != NULL);
         try
         {
-            if (inputSystem_->getNumberOfDevices(OIS::OISMouse) > 0)
-            {
-                mouse_ = static_cast<OIS::Mouse*>(inputSystem_->createInputObject(OIS::OISMouse, true));
-                // register our listener in OIS.
-                mouse_->setEventCallback(this);
-                CCOUT(ORX_DEBUG) << "Created OIS mouse" << std::endl;
-            }
-            else
-            {
-                CCOUT(ORX_WARNING) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
-            }
-        }
-        catch (OIS::Exception ex)
-        {
-            CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS mouse\n"
-                << "OIS error message: \"" << ex.eText << "\"\n Proceeding without mouse support." << std::endl;
-            mouse_ = 0;
-        }
-    }
-
-    /**
-    @brief
-        Creates all joy sticks and sets the event handler.
-    @return
-        False joy stick stay uninitialised, true otherwise.
-    */
-    void InputManager::_initialiseJoySticks()
-    {
-        if (joySticksSize_ > 0)
-        {
-            CCOUT(2) << "Warning: Joy sticks already initialised, skipping." << std::endl;
-            return;
-        }
-        if (inputSystem_->getNumberOfDevices(OIS::OISJoyStick) > 0)
-        {
-            for (int i = 0; i < inputSystem_->getNumberOfDevices(OIS::OISJoyStick); i++)
-            {
-                try
-                {
-                    OIS::JoyStick* stig = static_cast<OIS::JoyStick*>
-                        (inputSystem_->createInputObject(OIS::OISJoyStick, true));
-                    CCOUT(ORX_DEBUG) << "Created OIS joy stick with ID " << stig->getID() << std::endl;
-                    joySticks_.push_back(stig);
-                    // register our listener in OIS.
-                    stig->setEventCallback(this);
-                }
-                catch (OIS::Exception ex)
-                {
-                    CCOUT(ORX_WARNING) << "Warning: Failed to create OIS joy number" << i << "\n"
-                        << "OIS error message: \"" << ex.eText << "\"" << std::endl;
-                }
-            }
-        }
-    }
-
-    /**
-    @brief
-        Helper function that loads the config value vector of one coefficient
-    */
-    void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue)
-    {
-        list.resize(size);
-        unsigned int configValueVectorSize = ConfigFileManager::getInstance().getVectorSize(ConfigFileType::JoyStickCalibration, sectionName, valueName);
-        if (configValueVectorSize > size)
-            configValueVectorSize = size;
-
-        for (unsigned int i = 0; i < configValueVectorSize; ++i)
-        {
-            list[i] = multi_cast<int>(ConfigFileManager::getInstance().getValue(
-                ConfigFileType::JoyStickCalibration, sectionName, valueName, i, multi_cast<std::string>(defaultValue), false));
-        }
-
-        // fill the rest with default values
-        for (unsigned int i = configValueVectorSize; i < size; ++i)
-        {
-            list[i] = defaultValue;
-        }
-    }
-
-    /**
-    @brief
-        Sets the size of all the different lists that are dependent on the number
-        of joy stick devices created and loads the joy stick calibration.
-    @remarks
-        No matter whether there are a mouse and/or keyboard, they will always
-        occupy 2 places in the device number dependent lists.
-    */
-    void InputManager::_configureJoySticks()
-    {
-        joySticksSize_ = joySticks_.size();
-        devicesNum_    = 2 + joySticksSize_;
-        joyStickIDs_         .resize(joySticksSize_);
-        joyStickButtonsDown_ .resize(joySticksSize_);
-        povStates_           .resize(joySticksSize_);
-        sliderStates_        .resize(joySticksSize_);
-        joyStickMinValues_   .resize(joySticksSize_);
-        joyStickMaxValues_   .resize(joySticksSize_);
-        joyStickMiddleValues_.resize(joySticksSize_);
-        joyStickCalibrations_.resize(joySticksSize_);
-
-        for (unsigned int iJoyStick = 0; iJoyStick < joySticksSize_; iJoyStick++)
-        {
-            // Generate some sort of execution unique id per joy stick
-            std::string id = "JoyStick_";
-            id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Button))  + "_";
-            id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Axis))    + "_";
-            id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Slider))  + "_";
-            id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_POV))     + "_";
-            id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Vector3)) + "_";
-            id += joySticks_[iJoyStick]->vendor();
-            for (unsigned int i = 0; i < iJoyStick; ++i)
-            {
-                if (id == joyStickIDs_[i])
-                {
-                    // Two joysticks are probably equal --> add the index as well
-                    id += "_" + multi_cast<std::string>(iJoyStick);
-                }
-            }
-            joyStickIDs_[iJoyStick] = id;
-
-            size_t axes = sliderAxes + (size_t)this->joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Axis);
-            loadCalibration(joyStickMinValues_[iJoyStick], id, "MinValue", axes, -32768);
-            loadCalibration(joyStickMaxValues_[iJoyStick], id, "MaxValue", axes,  32768);
-            loadCalibration(joyStickMiddleValues_[iJoyStick], id, "MiddleValue", axes,      0);
-        }
-
-        _evaluateCalibration();
-
-        // state management
-        activeStatesTriggered_.resize(devicesNum_);
-
-        // inform all states
-        for (std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.begin();
-            it != inputStatesByName_.end(); ++it)
-        {
-            it->second->setNumOfJoySticks(joySticksSize_);
-        }
-
-        // inform all JoyStick Device Number Listeners
-        for (ObjectList<JoyStickDeviceNumberListener>::iterator it = ObjectList<JoyStickDeviceNumberListener>::begin(); it; ++it)
-            it->JoyStickDeviceNumberChanged(joySticksSize_);
-
-    }
-
-    void InputManager::_evaluateCalibration()
-    {
-        for (unsigned int iJoyStick = 0; iJoyStick < this->joySticksSize_; ++iJoyStick)
-        {
-            for (unsigned int i = 0; i < this->joyStickMinValues_[iJoyStick].size(); i++)
-            {
-                this->joyStickCalibrations_[iJoyStick].middleValue[i] = this->joyStickMiddleValues_[iJoyStick][i];
-                this->joyStickCalibrations_[iJoyStick].negativeCoeff[i] = - 1.0f / (this->joyStickMinValues_[iJoyStick][i] - this->joyStickMiddleValues_[iJoyStick][i]);
-                this->joyStickCalibrations_[iJoyStick].positiveCoeff[i] =   1.0f / (this->joyStickMaxValues_[iJoyStick][i] - this->joyStickMiddleValues_[iJoyStick][i]);
-            }
-        }
-    }
-
-    void InputManager::_startCalibration()
-    {
-        for (unsigned int iJoyStick = 0; iJoyStick < this->joySticksSize_; ++iJoyStick)
-        {
-            // Set initial values
-            for (unsigned int i = 0; i < this->joyStickMinValues_[iJoyStick].size(); ++i)
-                this->joyStickMinValues_[iJoyStick][i] = INT_MAX;
-            for (unsigned int i = 0; i < this->joyStickMaxValues_[iJoyStick].size(); ++i)
-                this->joyStickMaxValues_[iJoyStick][i] = INT_MIN;
-            for (unsigned int i = 0; i < this->joyStickMiddleValues_[iJoyStick].size(); ++i)
-                this->joyStickMiddleValues_[iJoyStick][i] = 0;
-        }
-
-        getInstance().internalState_ |= Calibrating;
-        getInstance().requestEnterState("calibrator");
-    }
-
-    void InputManager::_completeCalibration()
-    {
-        for (unsigned int iJoyStick = 0; iJoyStick < this->joySticksSize_; ++iJoyStick)
-        {
-            // Get the middle positions now
-            unsigned int iAxis = 0;
-            for (unsigned int i = 0; i < sliderAxes/2; ++i)
-            {
-                this->joyStickMiddleValues_[iJoyStick][iAxis++] = this->joySticks_[iJoyStick]->getJoyStickState().mSliders[i].abX;
-                this->joyStickMiddleValues_[iJoyStick][iAxis++] = this->joySticks_[iJoyStick]->getJoyStickState().mSliders[i].abY;
-            }
-            // Note: joyStickMiddleValues_[iJoyStick] was already correctly resized in _configureJoySticks()
-            assert(joySticks_[iJoyStick]->getJoyStickState().mAxes.size() == joyStickMiddleValues_[iJoyStick].size() - sliderAxes);
-            for (unsigned int i = 0; i < joyStickMiddleValues_[iJoyStick].size() - sliderAxes; ++i)
-            {
-                this->joyStickMiddleValues_[iJoyStick][iAxis++] = this->joySticks_[iJoyStick]->getJoyStickState().mAxes[i].abs;
-            }
-
-            for (unsigned int i = 0; i < joyStickMinValues_[iJoyStick].size(); ++i)
-            {
-                // Minimum values
-                if (joyStickMinValues_[iJoyStick][i] == INT_MAX)
-                    joyStickMinValues_[iJoyStick][i] = -32768;
-                ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
-                    this->joyStickIDs_[iJoyStick], "MinValue", i, multi_cast<std::string>(joyStickMinValues_[iJoyStick][i]), false);
-
-                // Maximum values
-                if (joyStickMaxValues_[iJoyStick][i] == INT_MIN)
-                    joyStickMaxValues_[iJoyStick][i] = 32767;
-                ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
-                    this->joyStickIDs_[iJoyStick], "MaxValue", i, multi_cast<std::string>(joyStickMaxValues_[iJoyStick][i]), false);
-
-                // Middle values
-                ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
-                    this->joyStickIDs_[iJoyStick], "MiddleValue", i, multi_cast<std::string>(joyStickMiddleValues_[iJoyStick][i]), false);
-            }
-        }
-
-        _evaluateCalibration();
-
-        // restore old input state
-        requestLeaveState("calibrator");
-        internalState_ &= ~Calibrating;
-    }
-
-    // ############################################################
-    // #####                    Destruction                   #####
-    // ##########                                        ##########
-    // ############################################################
-
-    /**
-    @brief
-        Destroys all the created input devices and states.
-    */
-    InputManager::~InputManager()
-    {
-        if (internalState_ != Uninitialised)
-        {
-            CCOUT(3) << "Destroying ..." << std::endl;
-
-            // kick all active states 'nicely'
-            for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
-                rit != activeStates_.rend(); ++rit)
-            {
-                (*rit).second->onLeave();
-            }
-
-            // Destroy calibrator helper handler and state
-            delete keyDetector_;
-            requestDestroyState("calibrator");
-            // Destroy KeyDetector and state
-            delete calibratorCallbackBuffer_;
-            requestDestroyState("detector");
-            // destroy the empty InputState
-            _destroyState(this->stateEmpty_);
-
-            // destroy all user InputStates
-            while (inputStatesByName_.size() > 0)
-                _destroyState((*inputStatesByName_.rbegin()).second);
-
-            // destroy the devices
-            _destroyKeyboard();
-            _destroyMouse();
-            _destroyJoySticks();
-
-            try
-            {
-                OIS::InputManager::destroyInputSystem(inputSystem_);
-            }
-            catch (...)
-            {
-                CCOUT(1) << "OIS::InputManager destruction failed! Potential resource leak!" << std::endl;
-            }
-        }
-
-        singletonRef_s = 0;
-    }
-
-    /**
-    @brief
-        Destroys the keyboard and sets it to 0.
-    */
-    void InputManager::_destroyKeyboard()
-    {
-        assert(inputSystem_);
-        try
-        {
-            if (keyboard_)
-                inputSystem_->destroyInputObject(keyboard_);
-            keyboard_ = 0;
-            CCOUT(4) << "Keyboard destroyed." << std::endl;
+            OIS::InputManager::destroyInputSystem(oisInputManager_);
         }
         catch (...)
         {
-            CCOUT(1) << "Keyboard destruction failed! Potential resource leak!" << std::endl;
-        }
-    }
-
-    /**
-    @brief
-        Destroys the mouse and sets it to 0.
-    */
-    void InputManager::_destroyMouse()
-    {
-        assert(inputSystem_);
-        try
-        {
-            if (mouse_)
-                inputSystem_->destroyInputObject(mouse_);
-            mouse_ = 0;
-            CCOUT(4) << "Mouse destroyed." << std::endl;
-        }
-        catch (...)
-        {
-            CCOUT(1) << "Mouse destruction failed! Potential resource leak!" << std::endl;
-        }
-    }
-
-    /**
-    @brief
-        Destroys all the joy sticks and resizes the lists to 0.
-    */
-    void InputManager::_destroyJoySticks()
-    {
-        if (joySticksSize_ > 0)
-        {
-            assert(inputSystem_);
-            for (unsigned int i = 0; i < joySticksSize_; i++)
-            {
-                try
-                {
-                    if (joySticks_[i] != 0)
-                        inputSystem_->destroyInputObject(joySticks_[i]);
-                }
-                catch (...)
-                {
-                    CCOUT(1) << "Joy stick destruction failed! Potential resource leak!" << std::endl;
-                }
-            }
-
-            joySticks_.clear();
-            // don't use _configureNumberOfJoySticks(), might mess with registered handler if
-            // downgrading from 2 to 1 joystick
-            //_configureNumberOfJoySticks();
-            joySticksSize_ = 0;
-        }
-        CCOUT(4) << "Joy sticks destroyed." << std::endl;
-    }
-
-    /**
-    @brief
-        Removes and destroys an InputState.
-    @return
-        True if state was removed immediately, false if postponed.
-    */
-    void InputManager::_destroyState(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();
-        }
-        inputStatesByName_.erase(state->getName());
-        delete state;
-    }
-
-    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;
-            }
-        }
-    }
-
+            CCOUT(1) << "OIS::InputManager destruction failed! Potential resource leak!" << std::endl;
+        }
+        oisInputManager_ = NULL;
+
+        internalState_ |= Bad;
+        CCOUT(3) << "Destroyed devices." << std::endl;
+    }
 
     // ############################################################
@@ -692,69 +348,30 @@
     // ############################################################
 
-    /**
-    @brief
-        Public interface. Only reloads immediately if the call stack doesn't
-        include the update() method.
-    @param joyStickSupport
-        Whether or not to initialise joy sticks as well.
-    */
-    void InputManager::reloadInputSystem(bool joyStickSupport)
+    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 backtrace would then
+            // 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;
-            // Misuse of internalState_: We can easily store the joyStickSupport bool.
-            // use Uninitialised as 0 value in order to make use of the overloaded |= operator
-            internalState_ |= joyStickSupport ? JoyStickSupport : Uninitialised;
-        }
-        else if (internalState_ & OISReady)
-        {
-            _reload(joyStickSupport);
-        }
+        }
+        else if (internalState_ & Calibrating)
+            CCOUT(2) << "Warning: Cannot reload input system. Joy sticks are currently being calibrated." << std::endl;
         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_ &= ~OISReady;
-
-            // 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;
-        }
+            reloadInternal();
+    }
+
+    //! Internal reload method. Destroys the OIS devices and loads them again.
+    void InputManager::reloadInternal()
+    {
+        CCOUT(3) << "Reloading ..." << std::endl;
+
+        this->destroyDevices();
+        this->loadDevices(windowHnd_);
+
+        internalState_ &= ~Bad;
+        internalState_ &= ~ReloadRequest;
+        CCOUT(3) << "Reloading complete." << std::endl;
     }
 
@@ -764,20 +381,11 @@
     // ############################################################
 
-    /**
-    @brief
-        Updates the states and the InputState situation.
-    @param time
-        Clock holding the current time.
-    */
     void InputManager::update(const Clock& time)
     {
-        if (internalState_ == Uninitialised)
-            return;
+        if (internalState_ & Bad)
+            ThrowException(General, "InputManager was not correctly reloaded.");
+
         else if (internalState_ & ReloadRequest)
-        {
-            _reload(internalState_ & JoyStickSupport);
-            internalState_ &= ~ReloadRequest;
-            internalState_ &= ~JoyStickSupport;
-        }
+            reloadInternal();
 
         // check for states to leave
@@ -787,12 +395,12 @@
                 it != stateLeaveRequests_.end(); ++it)
             {
-                (*it)->onLeave();
+                (*it)->left();
                 // just to be sure that the state actually is registered
-                assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());
+                assert(statesByName_.find((*it)->getName()) != statesByName_.end());
 
                 activeStates_.erase((*it)->getPriority());
                 if ((*it)->getPriority() < InputStatePriority::HighPriority)
                     (*it)->setPriority(0);
-                _updateActiveStates();
+                updateActiveStates();
             }
             stateLeaveRequests_.clear();
@@ -806,16 +414,11 @@
             {
                 // just to be sure that the state actually is registered
-                assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());
+                assert(statesByName_.find((*it)->getName()) != statesByName_.end());
 
                 if ((*it)->getPriority() == 0)
                 {
                     // Get smallest possible priority between 1 and maxStateStackSize_s
-#if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator
                     for(std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
                         rit != activeStates_.rend(); ++rit)
-#else
-                    for(std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin();
-                        rit != activeStates_.rend(); ++rit)
-#endif
                     {
                         if (rit->first < InputStatePriority::HighPriority)
@@ -830,6 +433,6 @@
                 }
                 activeStates_[(*it)->getPriority()] = (*it);
-                _updateActiveStates();
-                (*it)->onEnter();
+                updateActiveStates();
+                (*it)->entered();
             }
             stateEnterRequests_.clear();
@@ -842,70 +445,33 @@
                 it != stateDestroyRequests_.end(); ++it)
             {
-                _destroyState((*it));
+                destroyStateInternal((*it));
             }
             stateDestroyRequests_.clear();
         }
 
-        // check whether a state has changed its EMPTY_HANDLER situation
+        // check whether a state has changed its EMPTY situation
         bool bUpdateRequired = false;
         for (std::map<int, InputState*>::iterator it = activeStates_.begin(); it != activeStates_.end(); ++it)
         {
-            if (it->second->handlersChanged())
-            {
-                it->second->resetHandlersChanged();
+            if (it->second->hasExpired())
+            {
+                it->second->resetExpiration();
                 bUpdateRequired = true;
             }
         }
         if (bUpdateRequired)
-            _updateActiveStates();
+            updateActiveStates();
 
         // mark that we now start capturing and distributing input
         internalState_ |= Ticking;
 
-        // Capture all the input. This calls the event handlers in InputManager.
-        if (keyboard_)
-            keyboard_->capture();
-        if (mouse_)
-            mouse_->capture();
-        for (unsigned  int i = 0; i < joySticksSize_; i++)
-            joySticks_[i]->capture();
-
-        if (!(internalState_ & Calibrating))
-        {
-            // call all the handlers for the held key events
-            for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
-            {
-                KeyEvent kEvt(keysDown_[iKey], keyboardModifiers_);
-
-                for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
-                    activeStatesTriggered_[Keyboard][iState]->keyHeld(kEvt);
-            }
-
-            // call all the handlers for the held mouse button events
-            for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
-            {
-                for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
-                    activeStatesTriggered_[Mouse][iState]->mouseButtonHeld(mouseButtonsDown_[iButton]);
-            }
-
-            // call all the handlers for the held joy stick button events
-            for (unsigned int iJoyStick  = 0; iJoyStick < joySticksSize_; iJoyStick++)
-                for (unsigned int iButton   = 0; iButton   < joyStickButtonsDown_[iJoyStick].size(); iButton++)
-                {
-                    for (unsigned int iState = 0; iState < activeStatesTriggered_[JoyStick0 + iJoyStick].size(); ++iState)
-                        activeStatesTriggered_[JoyStick0 + iJoyStick][iState]->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
-                }
-
-            // update the handlers for each active handler
-            for (unsigned int i = 0; i < devicesNum_; ++i)
-            {
-                for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState)
-                    activeStatesTriggered_[i][iState]->updateInput(time.getDeltaTime(), i);
-            }
-
-            // update the handler with a general tick afterwards
-            for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
-                activeStatesTicked_[i]->updateInput(time.getDeltaTime());
-        }
+        // Capture all the input and handle it
+        BOOST_FOREACH(InputDevice* device, devices_)
+            if (device != NULL)
+                device->update(time);
+
+        // Update the states
+        for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
+            activeStatesTicked_[i]->update(time.getDeltaTime());
 
         internalState_ &= ~Ticking;
@@ -917,20 +483,19 @@
         Also, a list of all active states (no duplicates!) is compiled for the general update().
     */
-    void InputManager::_updateActiveStates()
-    {
-        for (unsigned int i = 0; i < devicesNum_; ++i)
-        {
+    void InputManager::updateActiveStates()
+    {
+        // temporary resize
+        for (unsigned int i = 0; i < devices_.size(); ++i)
+        {
+            if (devices_[i] == NULL)
+                continue;
+            std::vector<InputState*>& states = devices_[i]->getStateListRef();
             bool occupied = false;
-            activeStatesTriggered_[i].clear();
-#if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator
+            states.clear();
             for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
             {
-#else
-            for (std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
-            {
-#endif
                 if (rit->second->isInputDeviceEnabled(i) && (!occupied || rit->second->bAlwaysGetsInput_))
                 {
-                    activeStatesTriggered_[i].push_back(rit->second);
+                    states.push_back(rit->second);
                     if (!rit->second->bTransparent_)
                         occupied = true;
@@ -942,7 +507,8 @@
         // Using a std::set to avoid duplicates
         std::set<InputState*> tempSet;
-        for (unsigned int i = 0; i < devicesNum_; ++i)
-            for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState)
-                tempSet.insert(activeStatesTriggered_[i][iState]);
+        for (unsigned int i = 0; i < devices_.size(); ++i)
+            if (devices_[i] != NULL)
+                for (unsigned int iState = 0; iState < devices_[i]->getStateListRef().size(); ++iState)
+                    tempSet.insert(devices_[i]->getStateListRef()[iState]);
 
         // copy the content of the std::set back to the actual vector
@@ -950,457 +516,89 @@
         for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
             activeStatesTicked_.push_back(*it);
-
-        this->mouseButtonsDown_.clear();
-    }
-
-    /**
-    @brief
-        Clears all buffers that store what keys/buttons are being pressed at the moment.
-    */
+    }
+
     void InputManager::clearBuffers()
     {
-        this->keysDown_.clear();
-        this->mouseButtonsDown_.clear();
-        for (unsigned int i = 0; i < this->joySticksSize_; ++i)
-            this->joyStickButtonsDown_[i].clear();
-    }
-
-
-    // ############################################################
-    // #####                    OIS events                    #####
+        BOOST_FOREACH(InputDevice* device, devices_)
+            if (device != NULL)
+                device->clearBuffers();
+    }
+
+    void InputManager::calibrate()
+    {
+        COUT(0) << "Move all joy stick axes fully in all directions." << std::endl
+                << "When done, put the axex in the middle position and press enter." << std::endl;
+
+        BOOST_FOREACH(InputDevice* device, devices_)
+            if (device != NULL)
+                device->startCalibration();
+
+        internalState_ |= Calibrating;
+        enterState("calibrator");
+    }
+
+    //! Tells all devices to stop the calibration and evaluate it. Buffers are being cleared as well!
+    void InputManager::stopCalibration()
+    {
+        BOOST_FOREACH(InputDevice* device, devices_)
+            if (device != NULL)
+                device->stopCalibration();
+
+        // restore old input state
+        leaveState("calibrator");
+        internalState_ &= ~Calibrating;
+        // Clear buffers to prevent button hold events
+        this->clearBuffers();
+
+        COUT(0) << "Calibration has been stored." << std::endl;
+    }
+
+    //! Gets called by WindowEventListener upon focus change --> clear buffers 
+    void InputManager::windowFocusChanged()
+    {
+        this->clearBuffers();
+    }
+
+    // ############################################################
+    // #####                    Iput States                   #####
     // ##########                                        ##########
     // ############################################################
 
-    // ###### Key Events ######
-
-    /**
-    @brief
-        Event handler for the keyPressed Event.
-    @param e
-        Event information
-    */
-    bool InputManager::keyPressed(const OIS::KeyEvent &e)
-    {
-        // check whether the key already is in the list (can happen when focus was lost)
-        unsigned int iKey = 0;
-        while (iKey < keysDown_.size() && keysDown_[iKey].key != (KeyCode::ByEnum)e.key)
-            iKey++;
-        if (iKey == keysDown_.size())
-            keysDown_.push_back(Key(e));
-        else
-        {
-            // This happens when XAutoRepeat is set under linux. The KeyPressed event gets then sent
-            // continuously.
-            return true;
-        }
-
-        // update modifiers
-        if(e.key == OIS::KC_RMENU    || e.key == OIS::KC_LMENU)
-            keyboardModifiers_ |= KeyboardModifier::Alt;   // alt key
-        if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL)
-            keyboardModifiers_ |= KeyboardModifier::Ctrl;  // ctrl key
-        if(e.key == OIS::KC_RSHIFT   || e.key == OIS::KC_LSHIFT)
-            keyboardModifiers_ |= KeyboardModifier::Shift; // shift key
-
-        KeyEvent kEvt(e, keyboardModifiers_);
-        for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
-            activeStatesTriggered_[Keyboard][iState]->keyPressed(kEvt);
-
-        return true;
-    }
-
-    /**
-    @brief
-        Event handler for the keyReleased Event.
-    @param e
-        Event information
-    */
-    bool InputManager::keyReleased(const OIS::KeyEvent &e)
-    {
-        // remove the key from the keysDown_ list
-        for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
-        {
-            if (keysDown_[iKey].key == (KeyCode::ByEnum)e.key)
-            {
-                keysDown_.erase(keysDown_.begin() + iKey);
-                break;
-            }
-        }
-
-        // update modifiers
-        if(e.key == OIS::KC_RMENU    || e.key == OIS::KC_LMENU)
-            keyboardModifiers_ &= ~KeyboardModifier::Alt;   // alt key
-        if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL)
-            keyboardModifiers_ &= ~KeyboardModifier::Ctrl;  // ctrl key
-        if(e.key == OIS::KC_RSHIFT   || e.key == OIS::KC_LSHIFT)
-            keyboardModifiers_ &= ~KeyboardModifier::Shift; // shift key
-
-        KeyEvent kEvt(e, keyboardModifiers_);
-        for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
-            activeStatesTriggered_[Keyboard][iState]->keyReleased(kEvt);
-
-        return true;
-    }
-
-
-    // ###### Mouse Events ######
-
-    /**
-    @brief
-        Event handler for the mouseMoved Event.
-    @param e
-        Event information
-    */
-    bool InputManager::mouseMoved(const OIS::MouseEvent &e)
-    {
-        // check for actual moved event
-        if (e.state.X.rel != 0 || e.state.Y.rel != 0)
-        {
-            IntVector2 abs(e.state.X.abs, e.state.Y.abs);
-            IntVector2 rel(e.state.X.rel, e.state.Y.rel);
-            IntVector2 clippingSize(e.state.width, e.state.height);
-            for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
-                activeStatesTriggered_[Mouse][iState]->mouseMoved(abs, rel, clippingSize);
-        }
-
-        // check for mouse scrolled event
-        if (e.state.Z.rel != 0)
-        {
-            for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
-                activeStatesTriggered_[Mouse][iState]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
-        }
-
-        return true;
-    }
-
-    /**
-    @brief
-        Event handler for the mousePressed Event.
-    @param e
-        Event information
-    @param id
-        The ID of the mouse button
-    */
-    bool InputManager::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id)
-    {
-        // check whether the button already is in the list (can happen when focus was lost)
-        unsigned int iButton = 0;
-        while (iButton < mouseButtonsDown_.size() && mouseButtonsDown_[iButton] != (MouseButtonCode::ByEnum)id)
-            iButton++;
-        if (iButton == mouseButtonsDown_.size())
-            mouseButtonsDown_.push_back((MouseButtonCode::ByEnum)id);
-
-        for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
-            activeStatesTriggered_[Mouse][iState]->mouseButtonPressed((MouseButtonCode::ByEnum)id);
-
-        return true;
-    }
-
-    /**
-    @brief
-        Event handler for the mouseReleased Event.
-    @param e
-        Event information
-    @param id
-        The ID of the mouse button
-    */
-    bool InputManager::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id)
-    {
-        // remove the button from the keysDown_ list
-        for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
-        {
-            if (mouseButtonsDown_[iButton] == (MouseButtonCode::ByEnum)id)
-            {
-                mouseButtonsDown_.erase(mouseButtonsDown_.begin() + iButton);
-                break;
-            }
-        }
-
-        for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
-            activeStatesTriggered_[Mouse][iState]->mouseButtonReleased((MouseButtonCode::ByEnum)id);
-
-        return true;
-    }
-
-
-    // ###### Joy Stick Events ######
-
-    /**
-    @brief
-        Returns the joy stick ID (orxonox) according to a OIS::JoyStickEvent
-    */
-    inline unsigned int InputManager::_getJoystick(const OIS::JoyStickEvent& arg)
-    {
-        // use the device to identify which one called the method
-        OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device;
-        unsigned int iJoyStick = 0;
-        while (joySticks_[iJoyStick] != joyStick)
-            iJoyStick++;
-        // assert: Unknown joystick fired an event.
-        assert(iJoyStick != joySticksSize_);
-        return iJoyStick;
-    }
-
-    bool InputManager::buttonPressed(const OIS::JoyStickEvent &arg, int button)
-    {
-        unsigned int iJoyStick = _getJoystick(arg);
-
-        // check whether the button already is in the list (can happen when focus was lost)
-        std::vector<JoyStickButtonCode::ByEnum>& buttonsDown = joyStickButtonsDown_[iJoyStick];
-        unsigned int iButton = 0;
-        while (iButton < buttonsDown.size() && buttonsDown[iButton] != button)
-            iButton++;
-        if (iButton == buttonsDown.size())
-            buttonsDown.push_back((JoyStickButtonCode::ByEnum)button);
-
-        for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
-            activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
-
-        return true;
-    }
-
-    bool InputManager::buttonReleased(const OIS::JoyStickEvent &arg, int button)
-    {
-        unsigned int iJoyStick = _getJoystick(arg);
-
-        // remove the button from the joyStickButtonsDown_ list
-        std::vector<JoyStickButtonCode::ByEnum>& buttonsDown = joyStickButtonsDown_[iJoyStick];
-        for (unsigned int iButton = 0; iButton < buttonsDown.size(); iButton++)
-        {
-            if (buttonsDown[iButton] == button)
-            {
-                buttonsDown.erase(buttonsDown.begin() + iButton);
-                break;
-            }
-        }
-
-        for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
-            activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
-
-        return true;
-    }
-
-    /**
-    @brief
-        Calls the states for a particular axis with our enumeration.
-        Used by OIS sliders and OIS axes.
-    */
-    void InputManager::_fireAxis(unsigned int iJoyStick, int axis, int value)
-    {
-        if (internalState_ & Calibrating)
-        {
-            if (value < joyStickMinValues_[iJoyStick][axis])
-                joyStickMinValues_[iJoyStick][axis] = value;
-            if (value > joyStickMaxValues_[iJoyStick][axis])
-                joyStickMaxValues_[iJoyStick][axis] = value;
-        }
-        else
-        {
-            float fValue = static_cast<float>(value - joyStickCalibrations_[iJoyStick].middleValue[axis]);
-            if (fValue > 0.0f)
-                fValue *= joyStickCalibrations_[iJoyStick].positiveCoeff[axis];
-            else
-                fValue *= joyStickCalibrations_[iJoyStick].negativeCoeff[axis];
-
-            for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
-                activeStatesTriggered_[2 + iJoyStick][iState]->joyStickAxisMoved(iJoyStick, axis, fValue);
-        }
-    }
-
-    bool InputManager::axisMoved(const OIS::JoyStickEvent &arg, int axis)
-    {
-        unsigned int iJoyStick = _getJoystick(arg);
-
-        // keep in mind that the first 8 axes are reserved for the sliders
-        _fireAxis(iJoyStick, axis + sliderAxes, arg.state.mAxes[axis].abs);
-
-        return true;
-    }
-
-    bool InputManager::sliderMoved(const OIS::JoyStickEvent &arg, int id)
-    {
-        unsigned int iJoyStick = _getJoystick(arg);
-
-        if (sliderStates_[iJoyStick].sliderStates[id].x != arg.state.mSliders[id].abX)
-            _fireAxis(iJoyStick, id * 2, arg.state.mSliders[id].abX);
-        else if (sliderStates_[iJoyStick].sliderStates[id].y != arg.state.mSliders[id].abY)
-            _fireAxis(iJoyStick, id * 2 + 1, arg.state.mSliders[id].abY);
-
-        return true;
-    }
-
-    bool InputManager::povMoved(const OIS::JoyStickEvent &arg, int id)
-    {
-        unsigned int iJoyStick = _getJoystick(arg);
-
-        // translate the POV into 8 simple buttons
-
-        int lastState = povStates_[iJoyStick][id];
-        if (lastState & OIS::Pov::North)
-            buttonReleased(arg, 32 + id * 4 + 0);
-        if (lastState & OIS::Pov::South)
-            buttonReleased(arg, 32 + id * 4 + 1);
-        if (lastState & OIS::Pov::East)
-            buttonReleased(arg, 32 + id * 4 + 2);
-        if (lastState & OIS::Pov::West)
-            buttonReleased(arg, 32 + id * 4 + 3);
-
-        povStates_[iJoyStick].povStates[id] = arg.state.mPOV[id].direction;
-
-        int currentState = povStates_[iJoyStick][id];
-        if (currentState & OIS::Pov::North)
-            buttonPressed(arg, 32 + id * 4 + 0);
-        if (currentState & OIS::Pov::South)
-            buttonPressed(arg, 32 + id * 4 + 1);
-        if (currentState & OIS::Pov::East)
-            buttonPressed(arg, 32 + id * 4 + 2);
-        if (currentState & OIS::Pov::West)
-            buttonPressed(arg, 32 + id * 4 + 3);
-
-        return true;
-    }
-
-
-    // ############################################################
-    // #####         Other Public Interface Methods           #####
-    // ##########                                        ##########
-    // ############################################################
-
-    /**
-    @brief
-        Adjusts the mouse window metrics.
-        This method has to be called every time the size of the window changes.
-    @param width
-        The new width of the render window
-    @param^height
-        The new height of the render window
-    */
-    void InputManager::setWindowExtents(const int width, const int height)
-    {
-        if (mouse_)
-        {
-            // Set mouse region (if window resizes, we should alter this to reflect as well)
-            mouse_->getMouseState().width  = width;
-            mouse_->getMouseState().height = height;
-        }
-    }
-
-    /**
-    @brief
-        Sets the the name of the command used by the KeyDetector as callback.
-    @param command
-        Command name as string
-    */
-    void InputManager::setKeyDetectorCallback(const std::string& command)
-    {
-        this->keyDetector_->setCallbackCommand(command);
-    }
-
-    // ###### InputStates ######
-
-    /**
-    @brief
-        Adds a new key handler.
-    @param handler
-        Pointer to the handler object.
-    @param name
-        Unique name of the handler.
-    @param priority
-        Determines which InputState gets the input. Higher is better.
-        Use 0 to handle it implicitely by the order of activation.
-        Otherwise numbers larger than maxStateStackSize_s have to be used!
-    @return
-        True if added, false if name or priority already existed.
-    */
-    bool InputManager::_configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority)
+    InputState* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
     {
         if (name == "")
-            return false;
-        if (!state)
-            return false;
-        if (inputStatesByName_.find(name) == inputStatesByName_.end())
+            return 0;
+        if (statesByName_.find(name) == statesByName_.end())
         {
             if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
             {
                 // Make sure we don't add two high priority states with the same priority
-                for (std::map<std::string, InputState*>::const_iterator it = this->inputStatesByName_.begin();
-                    it != this->inputStatesByName_.end(); ++it)
+                for (std::map<std::string, InputState*>::const_iterator it = this->statesByName_.begin();
+                    it != this->statesByName_.end(); ++it)
                 {
                     if (it->second->getPriority() == priority)
                     {
                         COUT(2) << "Warning: Could not add an InputState with the same priority '"
-                            << priority << "' != 0." << std::endl;
-                        return false;
+                            << static_cast<int>(priority) << "' != 0." << std::endl;
+                        return 0;
                     }
                 }
             }
-            inputStatesByName_[name] = state;
-            state->setNumOfJoySticks(numberOfJoySticks());
-            state->setName(name);
-            state->bAlwaysGetsInput_ = bAlwaysGetsInput;
-            state->bTransparent_ = bTransparent;
-            if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
-                state->setPriority(priority);
-            return true;
+            InputState* state = new InputState(name, bAlwaysGetsInput, bTransparent, priority);
+            statesByName_[name] = state;
+
+            return state;
         }
         else
         {
             COUT(2) << "Warning: Could not add an InputState with the same name '" << name << "'." << std::endl;
-            return false;
-        }
-    }
-
-    /**
-    @brief
-        Removes and destroys an input state internally.
-    @param name
-        Name of the handler.
-    @return
-        True if removal was successful, false if name was not found.
-    @remarks
-        You can't remove the internal states "empty", "calibrator" and "detector".
-        The removal process is being postponed if InputManager::update() is currently running.
-    */
-    bool InputManager::requestDestroyState(const std::string& name)
-    {
-        if (name == "empty")
-        {
-            COUT(2) << "InputManager: Removing the empty state is not allowed!" << std::endl;
-            return false;
-        }
-        std::map<std::string, InputState*>::iterator it = inputStatesByName_.find(name);
-        if (it != inputStatesByName_.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
-                _destroyState(it->second);
-
-            return true;
-        }
-        return false;
-    }
-
-    /**
-    @brief
-        Returns the pointer to the requested InputState.
-    @param name
-        Unique name of the state.
-    @return
-        Pointer to the instance, 0 if name was not found.
-    */
+            return 0;
+        }
+    }
+
     InputState* InputManager::getState(const std::string& name)
     {
-        std::map<std::string, InputState*>::iterator it = inputStatesByName_.find(name);
-        if (it != inputStatesByName_.end())
+        std::map<std::string, InputState*>::iterator it = statesByName_.find(name);
+        if (it != statesByName_.end())
             return it->second;
         else
@@ -1408,29 +606,9 @@
     }
 
-    /**
-    @brief
-        Returns the current input state (there might be others active too!)
-    @return
-        The current highest prioritised active input state.
-    */
-    InputState* InputManager::getCurrentState()
-    {
-        return (*activeStates_.rbegin()).second;
-    }
-
-    /**
-    @brief
-        Activates a specific input state.
-        It might not be really activated if the priority is too low!
-    @param name
-        Unique name of the state.
-    @return
-        False if name was not found, true otherwise.
-    */
-    bool InputManager::requestEnterState(const std::string& name)
+    bool InputManager::enterState(const std::string& name)
     {
         // get pointer from the map with all stored handlers
-        std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name);
-        if (it != inputStatesByName_.end())
+        std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name);
+        if (it != statesByName_.end())
         {
             // exists
@@ -1450,13 +628,5 @@
     }
 
-    /**
-    @brief
-        Deactivates a specific input state.
-    @param name
-        Unique name of the state.
-    @return
-        False if name was not found, true otherwise.
-    */
-    bool InputManager::requestLeaveState(const std::string& name)
+    bool InputManager::leaveState(const std::string& name)
     {
         if (name == "empty")
@@ -1466,6 +636,6 @@
         }
         // get pointer from the map with all stored handlers
-        std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name);
-        if (it != inputStatesByName_.end())
+        std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name);
+        if (it != statesByName_.end())
         {
             // exists
@@ -1480,51 +650,45 @@
     }
 
-
-    // ############################################################
-    // #####                Console Commands                  #####
-    // ##########                                        ##########
-    // ############################################################
-
-    /**
-    @brief
-        Starts joy stick calibration.
-    */
-    void InputManager::calibrate()
-    {
-        COUT(0) << "Move all joy stick axes fully in all directions." << std::endl
-                << "When done, put the axex in the middle position and press enter." << std::endl;
-
-        getInstance()._startCalibration();
-    }
-
-    /**
-    @brief
-        Reloads the input system
-    */
-    void InputManager::reload(bool joyStickSupport)
-    {
-        getInstance().reloadInputSystem(joyStickSupport);
-    }
-
-
-    // ############################################################
-    // #####                   ugly hacks                     #####
-    // ##########                                        ##########
-    // ############################################################
-
-#ifdef ORXONOX_PLATFORM_LINUX
-    void InputManager::grabMouse()
-    {
-        OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(singletonRef_s->mouse_);
-        assert(linuxMouse);
-        linuxMouse->grab(true);
-    }
-
-    void InputManager::ungrabMouse()
-    {
-        OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(singletonRef_s->mouse_);
-        assert(linuxMouse);
-        linuxMouse->grab(false);
-    }
-#endif
+    bool InputManager::destroyState(const std::string& name)
+    {
+        if (name == "empty")
+        {
+            COUT(2) << "InputManager: Removing the empty state is not allowed!" << std::endl;
+            return false;
+        }
+        std::map<std::string, InputState*>::iterator it = statesByName_.find(name);
+        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);
+
+            return true;
+        }
+        return false;
+    }
+
+    //! Destroys an InputState internally.
+    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();
+        }
+        statesByName_.erase(state->getName());
+        delete state;
+    }
 }
Index: code/trunk/src/core/input/InputManager.h
===================================================================
--- code/trunk/src/core/input/InputManager.h	(revision 3326)
+++ code/trunk/src/core/input/InputManager.h	(revision 3327)
@@ -27,15 +27,8 @@
  */
 
-/**
-@file
-@brief
-    Implementation of a little Input handler that distributes everything
-    coming from OIS.
-*/
-
 #ifndef _InputManager_H__
 #define _InputManager_H__
 
-#include "core/CorePrereqs.h"
+#include "InputPrereqs.h"
 
 #include <map>
@@ -43,12 +36,7 @@
 #include <string>
 #include <vector>
-#include <ois/OISKeyboard.h>
-#include <ois/OISMouse.h>
-#include <ois/OISJoyStick.h>
-
-#include "util/Math.h"
-#include "util/OrxEnum.h"
-#include "core/OrxonoxClass.h"
-#include "InputInterfaces.h"
+
+#include "core/WindowEventListener.h"
+#include "InputState.h"
 
 namespace orxonox
@@ -56,230 +44,173 @@
     /**
     @brief
-        Helper class to realise a vector<int[4]>
+        Manages the input devices (mouse, keyboard, joy sticks) and the input states.
+
+        Every input device has its own wrapper class which does the actualy input event
+        distribution. The InputManager only creates reloads (on request) those devices.
+
+        The other functionality concerns handling InputStates. They act as a layer
+        between InputHandlers (like the KeyBinder or the GUIManager) and InputDevices.
+        InputStates are memory managed by the IputManager. You cannot create or destroy
+        them on your own. Therefore all states get destroyed with the InputManager d'tor.
+    @note
+        - The actual lists containing all the InputStates for a specific device are stored
+          in the InputDevices themselves.
+        - The devices_ vector always has at least two elements: Keyboard (first) and mouse.
+          You best access them intenally with InputDeviceEnumerator::Keyboard/Mouse
+          The first joy stick is accessed with InputDeviceEnumerator::FirstJoyStick.
+        - Keyboard construction is mandatory , mouse and joy sticks are not.
+          If the OIS::InputManager or the Keyboard fail, an exception is thrown.
     */
-    class POVStates
+    class _CoreExport InputManager : public WindowEventListener
     {
     public:
-        int& operator[](unsigned int index) { return povStates[index]; }
-        int povStates[4];
-    };
-
-    /**
-    @brief
-        Helper class to realise a vector< {int[4], int[4]} >
-    */
-    class SliderStates
-    {
-    public:
-        IntVector2 sliderStates[4];
-    };
-
-    struct JoyStickCalibration
-    {
-        int middleValue[24];
-        float positiveCoeff[24];
-        float negativeCoeff[24];
-    };
-
-    struct InputStatePriority : OrxEnum<InputStatePriority>
-    {
-        OrxEnumConstructors(InputStatePriority);
-
-        static const int Empty        = -1;
-        static const int Dynamic      = 0;
-
-        static const int HighPriority = 1000;
-        static const int Console      = HighPriority + 0;
-        static const int Calibrator   = HighPriority + 1;
-        static const int Detector     = HighPriority + 2;
-    };
-
-    /**
-    @brief
-        Captures and distributes mouse and keyboard input.
-    */
-    class _CoreExport InputManager
-        : public OrxonoxClass,
-        public OIS::KeyListener, public OIS::MouseListener, public OIS::JoyStickListener
-    {
-        // --> setConfigValues is private
-        friend class ClassIdentifier<InputManager>;
-
-    public:
-        enum InputManagerState
+        //! Represents internal states of the InputManager.
+        enum State
         {
-            Uninitialised    = 0x00,
-            OISReady         = 0x01,
-            InternalsReady   = 0x02,
-            Ticking          = 0x04,
-            Calibrating      = 0x08,
-            ReloadRequest    = 0x10,
-            JoyStickSupport  = 0x20 // used with ReloadRequest to store a bool
+            Nothing       = 0x00,
+            Bad           = 0x02,
+            Ticking       = 0x04,
+            Calibrating   = 0x08,
+            ReloadRequest = 0x10,
         };
 
-        InputManager ();
+        /**
+        @brief
+            Loads the devices and initialises the KeyDetector and the Calibrator.
+            
+            If either the OIS input system and/or the keyboard could not be created,
+            the constructor fails with an std::exception.
+        */
+        InputManager(size_t windowHnd);
+        //! Destroys all devices AND all input states!
         ~InputManager();
-
-        void initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport = true);
-
-        void reloadInputSystem(bool joyStickSupport = true);
-
+        void setConfigValues();
+
+        /**
+        @brief
+            Updates the devices (which distribute the input events) and the input states.
+
+            Any InpuStates changes (destroy, enter, leave) and happens here. If a reload request
+            was submitted while updating, the request wil be postponed until the next update call.
+        */
+        void update(const Clock& time);
+        //! Clears all input device buffers. This usually only includes the pressed button list.
         void clearBuffers();
-
-        unsigned int  numberOfKeyboards() { return keyboard_ ? 1 : 0; }
-        unsigned int  numberOfMice()      { return mouse_    ? 1 : 0; }
-        unsigned int  numberOfJoySticks() { return joySticksSize_; }
-
-        void setWindowExtents(const int width, const int height);
+        //! Starts joy stick calibration.
+        void calibrate();
+        /**
+        @brief
+            Reloads all the input devices. Use this method to initialise new joy sticks.
+        @note
+            Only reloads immediately if the call stack doesn't include the update() method.
+        */
+        void reload();
+
+        //-------------------------------
+        // Input States
+        //-------------------------------
+        /**
+        @brief
+            Creates a new InputState that gets managed by the InputManager.
+        @remarks
+            The InputManager will take care of the state completely. That also
+            means it gets deleted when the InputManager is destroyed!
+        @param name
+            Unique name of the InputState when referenced as string
+        @param priority
+            Priority matters when multiple states are active. You can specify any
+            number, but 1 - 99 is preferred (99 means high priority).
+        */
+        InputState* createInputState(const std::string& name, bool bAlwaysGetsInput = false, bool bTransparent = false, InputStatePriority priority = InputStatePriority::Dynamic);
+        /**
+        @brief
+            Returns a pointer to a InputState referenced by name.
+        @return
+            Returns NULL if state was not found.
+        */
+        InputState* getState(const std::string& name);
+        /**
+        @brief
+            Activates a specific input state.
+            It might not be actually activated if the priority is too low!
+        @return
+            False if name was not found, true otherwise.
+        */
+        bool enterState(const std::string& name);
+        /**
+        @brief
+            Deactivates a specific input state.
+        @return
+            False if name was not found, true otherwise.
+        */
+        bool leaveState(const std::string& name);
+        /**
+        @brief
+            Removes and destroys an input state.
+        @return
+            True if removal was successful, false if name was not found.
+        @remarks
+            - You can't remove the internal states "empty", "calibrator" and "detector".
+            - The removal process is being postponed if InputManager::update() is currently running.
+        */
+        bool destroyState(const std::string& name);
+
+        //-------------------------------
+        // Various getters and setters
+        //-------------------------------
+        //! Sets the the name of the command used by the KeyDetector as callback.
         void setKeyDetectorCallback(const std::string& command);
-
-        template <class T>
-        T* createInputState(const std::string& name, bool bAlwaysGetsInput = false, bool bTransparent = false, InputStatePriority priority = InputStatePriority::Dynamic);
-
-        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);
-
-#ifdef ORXONOX_PLATFORM_LINUX
-        // HACK!
-        static void grabMouse();
-        static void ungrabMouse();
-#endif
-
-        void update(const Clock& time);
-
-        static InputManager& getInstance()    { assert(singletonRef_s); return *singletonRef_s; }
-        static InputManager* getInstancePtr() { return singletonRef_s; }
-
-        // console commands
-        static void calibrate();
-        static void reload(bool joyStickSupport = true);
-
-    public: // variables
-        static EmptyHandler                 EMPTY_HANDLER;
-        static const unsigned int           sliderAxes = 8;
+        //! Returns the number of joy stick that have been created since the c'tor or last call to reload().
+        unsigned int getJoyStickQuantity() const
+            { return devices_.size() - InputDeviceEnumerator::FirstJoyStick; }
+        //! Returns a pointer to the OIS InputManager. Only you if you know what you're doing!
+        OIS::InputManager* getOISInputManager()
+            { return this->oisInputManager_; }
+
+        //! Returns a reference to the singleton instance
+        static InputManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
 
     private: // functions
         // don't mess with a Singleton
-        InputManager (const InputManager&);
+        InputManager(const InputManager&);
 
         // Intenal methods
-        void _initialiseKeyboard();
-        void _initialiseMouse();
-        void _initialiseJoySticks();
-        void _configureJoySticks();
-
-        void _loadCalibration();
-        void _startCalibration();
-        void _completeCalibration();
-        void _evaluateCalibration();
-
-        void _destroyKeyboard();
-        void _destroyMouse();
-        void _destroyJoySticks();
-        void _destroyState(InputState* state);
-        void _clearBuffers();
-
-        void _reload(bool joyStickSupport);
-
-        void _fireAxis(unsigned int iJoyStick, int axis, int value);
-        unsigned int _getJoystick(const OIS::JoyStickEvent& arg);
-
-        void _updateActiveStates();
-        bool _configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority);
-
-        // input events
-        bool mousePressed  (const OIS::MouseEvent    &arg, OIS::MouseButtonID id);
-        bool mouseReleased (const OIS::MouseEvent    &arg, OIS::MouseButtonID id);
-        bool mouseMoved    (const OIS::MouseEvent    &arg);
-        bool keyPressed    (const OIS::KeyEvent      &arg);
-        bool keyReleased   (const OIS::KeyEvent      &arg);
-        bool buttonPressed (const OIS::JoyStickEvent &arg, int button);
-        bool buttonReleased(const OIS::JoyStickEvent &arg, int button);
-        bool axisMoved     (const OIS::JoyStickEvent &arg, int axis);
-        bool sliderMoved   (const OIS::JoyStickEvent &arg, int id);
-        bool povMoved      (const OIS::JoyStickEvent &arg, int id);
-        // don't remove that! Or else add OIS as dependency library to orxonox.
-        bool vector3Moved  (const OIS::JoyStickEvent &arg, int id) { return true; }
-
-        void setConfigValues();
-        void _calibrationFileCallback();
+        void loadDevices(size_t windowHnd);
+        void loadMouse();
+        void loadJoySticks();
+        void destroyDevices();
+
+        void stopCalibration();
+        void reloadInternal();
+
+        void destroyStateInternal(InputState* state);
+        void updateActiveStates();
+
+        // From WindowEventListener
+        void windowFocusChanged();
 
     private: // variables
-        OIS::InputManager*                  inputSystem_;          //!< OIS input manager
-        OIS::Keyboard*                      keyboard_;             //!< OIS mouse
-        OIS::Mouse*                         mouse_;                //!< OIS keyboard
-        std::vector<OIS::JoyStick*>         joySticks_;            //!< OIS joy sticks
-        unsigned int                        joySticksSize_;
-        std::vector<std::string>            joyStickIDs_;          //!< Execution unique identification strings for the joy sticks
-        unsigned int                        devicesNum_;
-        size_t                              windowHnd_;            //!< Render window handle
-        InputManagerState                   internalState_;        //!< Current internal state
+        State                               internalState_;        //!< Current internal state
+        OIS::InputManager*                  oisInputManager_;      //!< OIS input manager
+        std::vector<InputDevice*>           devices_;              //!< List of all input devices (keyboard, mouse, joy sticks)
+        // TODO: Get this from the GraphicsManager during reload
+        size_t                              windowHnd_;            //!< Render window handle (used to reload the InputManager)
 
         // some internally handled states and handlers
-        SimpleInputState*                   stateEmpty_;
+        InputState*                         emptyState_;           //!< Lowest priority states (makes handling easier)
         KeyDetector*                        keyDetector_;          //!< KeyDetector instance
-        InputBuffer*                        calibratorCallbackBuffer_;
-
-        std::map<std::string, InputState*>  inputStatesByName_;
-
-        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_;
-        std::vector<std::vector<InputState*> > activeStatesTriggered_;
-        std::vector<InputState*>            activeStatesTicked_;
-
-        // joystick calibration
-        std::vector<std::vector<int> >      joyStickMinValues_;
-        std::vector<std::vector<int> >      joyStickMaxValues_;
-        std::vector<std::vector<int> >      joyStickMiddleValues_;
-        std::vector<ConfigValueContainer*>  calibrationConfigValueContainers_;
-        std::vector<JoyStickCalibration>    joyStickCalibrations_; 
-
-        unsigned int                        keyboardModifiers_;    //!< Bit mask representing keyboard modifiers.
-        std::vector<POVStates>              povStates_;            //!< Keeps track of the joy stick POV states.
-        std::vector<SliderStates>           sliderStates_;         //!< Keeps track of the possibly two slider axes.
-
-        std::vector<Key>                    keysDown_;
-        std::vector<MouseButtonCode::ByEnum>      mouseButtonsDown_;
-        std::vector<std::vector<JoyStickButtonCode::ByEnum> >  joyStickButtonsDown_;
-
-        // ConfigValues
-        std::string                         calibrationFilename_;  //!< Joy stick calibration ini filename
-
-        static InputManager*                singletonRef_s;
+        //! InputBuffer that reacts to the Enter key when calibrating the joy sticks
+        InputBuffer*                        calibratorCallbackHandler_;
+
+        std::map<std::string, InputState*>  statesByName_;         //!< Contains all the created input states by name
+        std::map<int, InputState*>          activeStates_;         //!< Contains all active input states by priority (std::map is sorted!)
+        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
+
+        static InputManager*                singletonRef_s;        //!< Pointer reference to the singleton
     };
-
-    /**
-    @brief
-        Creates a new InputState by type, name and priority.
-        
-        You will have to use this method because the
-        c'tors and d'tors are private.
-    @remarks
-        The InputManager will take care of the state completely. That also
-        means it gets deleted when the InputManager is destroyed!
-    @param name
-        Name of the InputState when referenced as string
-    @param priority
-        Priority matters when multiple states are active. You can specify any
-        number, but 1 - 99 is preferred (99 means high).
-    */
-    template <class T>
-    T* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
-    {
-        T* state = new T;
-        if (_configureInputState(state, name, bAlwaysGetsInput, bTransparent, priority))
-            return state;
-        else
-        {
-            delete state;
-            return 0;
-        }
-    }
 }
 
Index: code/trunk/src/core/input/InputPrereqs.h
===================================================================
--- code/trunk/src/core/input/InputPrereqs.h	(revision 3327)
+++ code/trunk/src/core/input/InputPrereqs.h	(revision 3327)
@@ -0,0 +1,452 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Declarations of all key/button/axis code enumeration and string literals
+    and an input device enumeration.
+*/
+
+#ifndef _InputPrereqs_H__
+#define _InputPrereqs_H__
+
+#include "core/CorePrereqs.h"
+
+#include <ois/OISKeyboard.h>
+#include <ois/OISMouse.h>
+#include <ois/OISJoyStick.h>
+
+namespace orxonox
+{
+    //-----------------------------------------------------------------------
+    // Code enumerations
+    //-----------------------------------------------------------------------
+
+    namespace KeyCode
+    {
+        const unsigned int numberOfKeys = 0xEE; // 238
+
+        //! Key codes as enumeration
+        enum ByEnum
+        {
+            Unassigned    = OIS::KC_UNASSIGNED,
+            Escape        = OIS::KC_ESCAPE,
+            NumRow1       = OIS::KC_1,
+            NumRow2       = OIS::KC_2,
+            NumRow3       = OIS::KC_3,
+            NumRow4       = OIS::KC_4,
+            NumRow5       = OIS::KC_5,
+            NumRow6       = OIS::KC_6,
+            NumRow7       = OIS::KC_7,
+            NumRow8       = OIS::KC_8,
+            NumRow9       = OIS::KC_9,
+            NumRow0       = OIS::KC_0,
+            Minus         = OIS::KC_MINUS,           // - on main keyboard
+            Equals        = OIS::KC_EQUALS,
+            Back          = OIS::KC_BACK,            // backspace
+            Tab           = OIS::KC_TAB,
+            Q             = OIS::KC_Q,
+            W             = OIS::KC_W,
+            E             = OIS::KC_E,
+            R             = OIS::KC_R,
+            T             = OIS::KC_T,
+            Y             = OIS::KC_Y,
+            U             = OIS::KC_U,
+            I             = OIS::KC_I,
+            O             = OIS::KC_O,
+            P             = OIS::KC_P,
+            LeftBracket   = OIS::KC_LBRACKET,
+            RightBracket  = OIS::KC_RBRACKET,
+            Return        = OIS::KC_RETURN,          // Enter on main keyboard
+            LeftControl   = OIS::KC_LCONTROL,
+            A             = OIS::KC_A,
+            S             = OIS::KC_S,
+            D             = OIS::KC_D,
+            F             = OIS::KC_F,
+            G             = OIS::KC_G,
+            H             = OIS::KC_H,
+            J             = OIS::KC_J,
+            K             = OIS::KC_K,
+            L             = OIS::KC_L,
+            Semicolon     = OIS::KC_SEMICOLON,
+            Apostrophe    = OIS::KC_APOSTROPHE,
+            Grave         = OIS::KC_GRAVE,           // accent
+            LeftShift     = OIS::KC_LSHIFT,
+            Backslash     = OIS::KC_BACKSLASH,
+            Z             = OIS::KC_Z,
+            X             = OIS::KC_X,
+            C             = OIS::KC_C,
+            V             = OIS::KC_V,
+            B             = OIS::KC_B,
+            N             = OIS::KC_N,
+            M             = OIS::KC_M,
+            Comma         = OIS::KC_COMMA,
+            Period        = OIS::KC_PERIOD,          // . on main keyboard
+            Slash         = OIS::KC_SLASH,           // / on main keyboard
+            RightShift    = OIS::KC_RSHIFT,
+            Multiply      = OIS::KC_MULTIPLY,        // * on numeric keypad
+            LeftAlt       = OIS::KC_LMENU,           // left Alt
+            Space         = OIS::KC_SPACE,
+            CapsLock      = OIS::KC_CAPITAL,
+            F1            = OIS::KC_F1,
+            F2            = OIS::KC_F2,
+            F3            = OIS::KC_F3,
+            F4            = OIS::KC_F4,
+            F5            = OIS::KC_F5,
+            F6            = OIS::KC_F6,
+            F7            = OIS::KC_F7,
+            F8            = OIS::KC_F8,
+            F9            = OIS::KC_F9,
+            F10           = OIS::KC_F10,
+            NumLock       = OIS::KC_NUMLOCK,
+            ScrollLock    = OIS::KC_SCROLL,          // Scroll Lock
+            Numpad7       = OIS::KC_NUMPAD7,
+            Numpad8       = OIS::KC_NUMPAD8,
+            Numpad9       = OIS::KC_NUMPAD9,
+            NumpadSubtract= OIS::KC_SUBTRACT,        // - on numeric keypad
+            Numpad4       = OIS::KC_NUMPAD4,
+            Numpad5       = OIS::KC_NUMPAD5,
+            Numpad6       = OIS::KC_NUMPAD6,
+            NumpadAdd     = OIS::KC_ADD,             // + on numeric keypad
+            Numpad1       = OIS::KC_NUMPAD1,
+            Numpad2       = OIS::KC_NUMPAD2,
+            Numpad3       = OIS::KC_NUMPAD3,
+            Numpad0       = OIS::KC_NUMPAD0,
+            NumpadPeriod  = OIS::KC_DECIMAL,         // . on numeric keypad
+            LessThan      = OIS::KC_OEM_102,         // < > | on UK/Germany keyboards
+            F11           = OIS::KC_F11,
+            F12           = OIS::KC_F12,
+            F13           = OIS::KC_F13,             //                     (NEC PC98)
+            F14           = OIS::KC_F14,             //                     (NEC PC98)
+            F15           = OIS::KC_F15,             //                     (NEC PC98)
+            Kana          = OIS::KC_KANA,            // (Japanese keyboard)
+            ABNT_C1       = OIS::KC_ABNT_C1,         // / ? on Portugese (Brazilian) keyboards
+            Convert       = OIS::KC_CONVERT,         // (Japanese keyboard)
+            NoConvert     = OIS::KC_NOCONVERT,       // (Japanese keyboard)
+            Yen           = OIS::KC_YEN,             // (Japanese keyboard)
+            ABNT_C2       = OIS::KC_ABNT_C2,         // Numpad . on Portugese (Brazilian) keyboards
+            NumpadEquals  = OIS::KC_NUMPADEQUALS,    // = on numeric keypad (NEC PC98)
+            PreviousTrack = OIS::KC_PREVTRACK,       // Previous Track (KC_CIRCUMFLEX on Japanese keyboard)
+            AT            = OIS::KC_AT,              //                     (NEC PC98)
+            Colon         = OIS::KC_COLON,           //                     (NEC PC98)
+            Underline     = OIS::KC_UNDERLINE,       //                     (NEC PC98)
+            Kanji         = OIS::KC_KANJI,           // (Japanese keyboard)
+            Stop          = OIS::KC_STOP,            //                     (NEC PC98)
+            AX            = OIS::KC_AX,              //                     (Japan AX)
+            Unlabeled     = OIS::KC_UNLABELED,       //                        (J3100)
+            NextTrack     = OIS::KC_NEXTTRACK,       // Next Track
+            NumpadEnter   = OIS::KC_NUMPADENTER,     // Enter on numeric keypad
+            RightControl  = OIS::KC_RCONTROL,
+            Mute          = OIS::KC_MUTE,            // Mute
+            Calculator    = OIS::KC_CALCULATOR,      // Calculator
+            PlayPause     = OIS::KC_PLAYPAUSE,       // Play / Pause
+            MediaStop     = OIS::KC_MEDIASTOP,       // Media Stop
+            VolumeDown    = OIS::KC_VOLUMEDOWN,      // Volume -
+            VolumeUp      = OIS::KC_VOLUMEUP,        // Volume +
+            WebHome       = OIS::KC_WEBHOME,         // Web home
+            NumpadComma   = OIS::KC_NUMPADCOMMA,     // , on numeric keypad (NEC PC98)
+            Divide        = OIS::KC_DIVIDE,          // / on numeric keypad
+            SystemRequest = OIS::KC_SYSRQ,
+            RightAlt      = OIS::KC_RMENU,           // right Alt
+            Pause         = OIS::KC_PAUSE,           // Pause
+            Home          = OIS::KC_HOME,            // Home on arrow keypad
+            Up            = OIS::KC_UP,              // UpArrow on arrow keypad
+            PageUp        = OIS::KC_PGUP,            // PgUp on arrow keypad
+            Left          = OIS::KC_LEFT,            // LeftArrow on arrow keypad
+            Right         = OIS::KC_RIGHT,           // RightArrow on arrow keypad
+            End           = OIS::KC_END,             // End on arrow keypad
+            Down          = OIS::KC_DOWN,            // DownArrow on arrow keypad
+            PageDown      = OIS::KC_PGDOWN,          // PgDn on arrow keypad
+            Insert        = OIS::KC_INSERT,          // Insert on arrow keypad
+            Delete        = OIS::KC_DELETE,          // Delete on arrow keypad
+            LeftWindows   = OIS::KC_LWIN,            // Left Windows key
+            RightWindows  = OIS::KC_RWIN,            // Right Windows key
+            Apps          = OIS::KC_APPS,            // AppMenu key
+            Power         = OIS::KC_POWER,           // System Power
+            Sleep         = OIS::KC_SLEEP,           // System Sleep
+            Wake          = OIS::KC_WAKE,            // System Wake
+            WebSearch     = OIS::KC_WEBSEARCH,       // Web Search
+            WebFavorites  = OIS::KC_WEBFAVORITES,    // Web Favorites
+            WebRefresh    = OIS::KC_WEBREFRESH,      // Web Refresh
+            WebStop       = OIS::KC_WEBSTOP,         // Web Stop
+            WebForward    = OIS::KC_WEBFORWARD,      // Web Forward
+            WebBack       = OIS::KC_WEBBACK,         // Web Back
+            MyComputer    = OIS::KC_MYCOMPUTER,      // My Computer
+            Mail          = OIS::KC_MAIL,            // Mail
+            MediaSelect   = OIS::KC_MEDIASELECT      // Media Select
+        };
+        
+        //! Key codes as strings
+        const char* const ByString[] =
+        {
+            "Unassigned",
+            "Escape",
+            "NumRow1", "NumRow2", "NumRow3", "NumRow4", "NumRow5",
+            "NumRow6", "NumRow7", "NumRow8", "NumRow9", "NumRow0",
+            "Minus", "Equals", "Back", "Tab",
+            "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
+            "LeftBracket", "RightBracket",
+            "Return", "LeftControl",
+            "A", "S", "D", "F", "G", "H", "J", "K", "L",
+            "Semicolon", "Apostrophe", "Grave",
+            "LeftShift", "Backslash",
+            "Z", "X", "C", "V", "B", "N", "M",
+            "Comma", "Period", "Slash",
+            "RightShift",
+            "Multiply",
+            "LeftAlt",
+            "Space",
+            "CapsLock",
+            "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
+            "NumLock", "ScrollLock",
+            "Numpad7", "Numpad8", "Numpad9",
+            "NumpadSubtract",
+            "Numpad4", "Numpad5", "Numpad6",
+            "NumpadAdd",
+            "Numpad1", "Numpad2", "Numpad3", "Numpad0",
+            "NumpadPeriod",
+            "","",
+            "LessThan",
+            "F11", "F12",
+            "","","","","","","","","","","",
+            "F13", "F14", "F15",
+            "","","","","","","","","","",
+            "Kana",
+            "","",
+            "ABNT_C1",
+            "","","","","",
+            "Convert",
+            "",
+            "NoConvert",
+            "",
+            "Yen",
+            "ABNT_C2",
+            "","","","","","","","","","","","","","",
+            "NumpadEquals",
+            "","",
+            "PreviousTrack",
+            "AT",
+            "Colon", "Underline",
+            "Kanji",
+            "Stop",
+            "AX",
+            "Unlabeled",
+            "NextTrack",
+            "","",
+            "NumpadEnter",
+            "RightControl",
+            "","",
+            "Mute",
+            "Calculator",
+            "PlayPause",
+            "",
+            "MediaStop",
+            "","","","","","","","","",
+            "VolumeDown",
+            "",
+            "VolumeUp",
+            "",
+            "WebHome",
+            "NumpadComma",
+            "",
+            "Divide",
+            "",
+            "SystemRequest",
+            "RightAlt",
+            "","","","","","","","","","","","",
+            "Pause",
+            "",
+            "Home",
+            "UP",
+            "PageUp",
+            "",
+            "Left",
+            "",
+            "Right",
+            "",
+            "End", "Down", "PageDown", "Insert", "Delete",
+            "","","","","","","",
+            "LeftWindows", "RightWindows", "Apps",
+            "Power", "Sleep",
+            "","","",
+            "Wake",
+            "",
+            "WebSearch", "WebFavorites", "WebRefresh", "WebStop", "WebForward", "WebBack",
+            "MyComputer", "Mail", "MediaSelect"
+        };
+    }
+
+
+    namespace MouseButtonCode
+    {
+        const unsigned int numberOfButtons = 8;
+
+        //! Mouse button codes as enumeration
+        enum ByEnum
+        {
+            Left    = OIS::MB_Left,
+            Right   = OIS::MB_Right,
+            Middle  = OIS::MB_Middle,
+            Button3 = OIS::MB_Button3,
+            Button4 = OIS::MB_Button4,
+            Button5 = OIS::MB_Button5,
+            Button6 = OIS::MB_Button6,
+            Button7 = OIS::MB_Button7,
+        };
+
+        // Mouse button codes as strings
+        const char* const ByString[] =
+        {
+            "Left",
+            "Right",
+            "Middle",
+            "Button3",
+            "Button4",
+            "Button5",
+            "Button6",
+            "Button7",
+        };
+    }
+
+    namespace MouseAxisCode
+    {
+        const unsigned int numberOfAxes = 2;
+
+        // Mouse axis codes as enumeration
+        enum ByEnum
+        {
+            X,
+            Y
+        };
+
+        // Mouse axis codes as strings
+        const char* const ByString[] =
+        {
+            "X",
+            "Y"
+        };
+    }
+
+
+    namespace JoyStickButtonCode
+    {
+        const unsigned int numberOfButtons = 64;
+
+        // Joy stick button codes as enumeration
+        enum ByEnum
+        {
+            Button0       =  0, Button1       =  1, Button2       =  2, Button3       =  3,
+            Button4       =  4, Button5       =  5, Button6       =  6, Button7       =  7,
+            Button8       =  8, Button9       =  9, Button10      = 10, Button11      = 11,
+            Button12      = 12, Button13      = 13, Button14      = 14, Button15      = 15,
+            Button16      = 16, Button17      = 17, Button18      = 18, Button19      = 19,
+            Button20      = 20, Button21      = 21, Button22      = 22, Button23      = 23,
+            Button24      = 24, Button25      = 25, Button26      = 26, Button27      = 27,
+            Button28      = 28, Button29      = 29, Button30      = 30, Button31      = 31,
+
+            POV0North     = 32, POV0South     = 33, POV0East      = 34, POV0West      = 35,
+            POV0NorthEast = 36, POV0SouthEast = 37, POV0NorthWest = 38, POV0SouthWest = 39,
+
+            POV1North     = 40, POV1South     = 41, POV1East      = 42, POV1West      = 43,
+            POV1NorthEast = 44, POV1SouthEast = 45, POV1NorthWest = 46, POV1SouthWest = 47,
+
+            POV2North     = 48, POV2South     = 49, POV2East      = 50, POV2West      = 51,
+            POV2NorthEast = 52, POV2SouthEast = 53, POV2NorthWest = 54, POV2SouthWest = 55,
+
+            POV3North     = 56, POV3South     = 57, POV3East      = 58, POV3West      = 59,
+            POV3NorthEast = 60, POV3SouthEast = 61, POV3NorthWest = 62, POV3SouthWest = 63,
+        };
+
+        // Joy stick button codes as strings
+        const char* const ByString[] =
+        {
+            "Button00",      "Button01",      "Button02",      "Button03",
+            "Button04",      "Button05",      "Button06",      "Button07",
+            "Button08",      "Button09",      "Button10",      "Button11",
+            "Button12",      "Button13",      "Button14",      "Button15",
+            "Button16",      "Button17",      "Button18",      "Button19",
+            "Button20",      "Button21",      "Button22",      "Button23",
+            "Button24",      "Button25",      "Button26",      "Button27",
+            "Button28",      "Button29",      "Button30",      "Button31",
+            "POV0North",     "POV0South",     "POV0East",      "POV0West",
+            "POV0NorthEast", "POV0SouthEast", "POV0NorthWest", "POV0SouthWest",
+            "POV1North",     "POV1South",     "POV1East",      "POV1West",
+            "POV1NorthEast", "POV1SouthEast", "POV1NorthWest", "POV1SouthWest",
+            "POV2North",     "POV2South",     "POV2East",      "POV2West",
+            "POV2NorthEast", "POV2SouthEast", "POV2NorthWest", "POV2SouthWest",
+            "POV3North",     "POV3South",     "POV3East",      "POV3West",
+            "POV3NorthEast", "POV3SouthEast", "POV3NorthWest", "POV3SouthWest"
+        };
+    }
+
+    namespace JoyStickAxisCode
+    {
+        const unsigned int numberOfAxes = 24;
+
+        // Joy stick axis codes as enumeration
+        enum ByEnum
+        {
+            Slider0 =  0, Slider1 =  1, Slider2 =  2, Slider3 =  3,
+            Slider4 =  4, Slider5 =  5, Slider6 =  6, Slider7 =  7,
+            Axis0   =  8, Axis1   =  9, Axis2   = 10, Axis3   = 11,
+            Axis4   = 12, Axis5   = 13, Axis6   = 14, Axis7   = 15,
+            Axis8   = 16, Axis9   = 17, Axis10  = 18, Axis11  = 19,
+            Axis12  = 20, Axis13  = 21, Axis14  = 22, Axis15  = 23
+        };
+
+        // Joy stick axis codes as strings
+        const char* const ByString[] =
+        {
+            "Slider0", "Slider1", "Slider2", "Slider3",
+            "Slider4", "Slider5", "Slider6", "Slider7",
+            "Axis00",  "Axis01",  "Axis02",  "Axis03",
+            "Axis04",  "Axis05",  "Axis06",  "Axis07",
+            "Axis08",  "Axis09",  "Axis10",  "Axis11",
+            "Axis12",  "Axis13",  "Axis14",  "Axis15"
+        };
+    }
+
+
+    //-----------------------------------------------------------------------
+    // Miscellaneous
+    //-----------------------------------------------------------------------
+
+    namespace InputDeviceEnumerator
+    {
+        //! Used to access the devices in an array
+        enum Value
+        {
+            Keyboard = 0,
+            Mouse = 1,
+            FirstJoyStick = 2
+        };
+    }
+}
+
+#endif /* _InputPrereqs_H__ */
Index: code/trunk/src/core/input/InputState.cc
===================================================================
--- code/trunk/src/core/input/InputState.cc	(revision 3327)
+++ code/trunk/src/core/input/InputState.cc	(revision 3327)
@@ -0,0 +1,111 @@
+/*
+ *   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 "InputState.h"
+#include "core/Functor.h"
+
+namespace orxonox
+{
+    //! Sets priority of it's a high priority and resizes the handler list
+    InputState::InputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
+        : name_(name)
+        , bAlwaysGetsInput_(bAlwaysGetsInput)
+        , bTransparent_(bTransparent)
+        , bExpired_(true)
+        , handlers_(2)
+        , joyStickHandlerAll_(0)
+        , enterFunctor_(0)
+        , leaveFunctor_(0)
+    {
+        if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
+            priority_ = priority;
+        else
+            priority_ = 0;
+
+        handlers_.resize(InputDeviceEnumerator::FirstJoyStick + this->getJoyStickList().size(), NULL);
+    }
+
+    bool InputState::isInputDeviceEnabled(unsigned int device)
+    {
+        if (device < handlers_.size())
+            return handlers_[device] != NULL;
+        else
+            return false;
+    }
+
+    //! Called by JoyStickQuantityListener upon joy stick adding/removal
+    void InputState::JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList)
+    {
+        unsigned int oldSize = handlers_.size();
+        handlers_.resize(InputDeviceEnumerator::FirstJoyStick + joyStickList.size(), NULL);
+
+        for (unsigned int i = oldSize; i < handlers_.size(); ++i)
+            handlers_[i] = joyStickHandlerAll_;
+
+        bExpired_ = true;
+    }
+
+    bool InputState::setJoyStickHandler(InputHandler* handler, unsigned int joyStick)
+    {
+        unsigned device = joyStick + firstJoyStickIndex_s;
+        if (joyStick >= handlers_.size() - device)
+            return false;
+
+        handlers_[device] = handler;
+        bExpired_ = true;
+        return true;
+    }
+
+    void InputState::setJoyStickHandler(InputHandler* handler)
+    {
+        joyStickHandlerAll_ = handler;
+        for (unsigned int i = firstJoyStickIndex_s; i < handlers_.size(); ++i)
+            handlers_[i] = handler;
+        bExpired_ = true;
+    }
+
+    void InputState::setHandler(InputHandler* handler)
+    {
+        setKeyHandler(handler);
+        setMouseHandler(handler);
+        setJoyStickHandler(handler);
+    }
+
+    void InputState::entered()
+    {
+        if (enterFunctor_)
+            (*enterFunctor_)();
+            
+    }
+
+    void InputState::left()
+    {
+        if (leaveFunctor_)
+            (*leaveFunctor_)();
+    }
+}
Index: code/trunk/src/core/input/InputState.h
===================================================================
--- code/trunk/src/core/input/InputState.h	(revision 3326)
+++ code/trunk/src/core/input/InputState.h	(revision 3327)
@@ -27,102 +27,205 @@
  */
 
-/**
-@file
-@brief 
-*/
-
 #ifndef _InputState_H__
 #define _InputState_H__
 
-#include "core/CorePrereqs.h"
-
+#include "InputPrereqs.h"
+
+#include <cassert>
 #include <string>
 #include <vector>
-#include "InputInterfaces.h"
+
+#include "util/OrxEnum.h"
+#include "InputHandler.h"
+#include "JoyStickQuantityListener.h"
 
 namespace orxonox
 {
-    class _CoreExport InputState
+    //! 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;
+    };
+
+    /**
+    @brief
+        InputStates allow you to customise the input event targets at runtime.
+
+        The general idea is a stack: Every activated InputState will be pushed on
+        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
+        steer a ship with the mouse.
+        There are two exceptions to this behaviour though:
+        - If an InputState is created with the 'Transparent' parameter on, the
+          state will not prevent input from getting to the state below it on the stack.
+          This can be useful for instance if you need to deploy input to multiple
+          handlers: Simply create two InputStates and make the high priority one transparent.
+        - If an InputState is created with the 'AlwaysGetsInput' parameter on, then
+          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.
+
+        Priorities
+        **********
+        Every InputState has a priority when on the stack, but mostly this
+        priority is dynamic (InputStatePriority::Dynamic) which means that a state
+        pushed onto the stack will simply have a higher priority than the top one.
+        This behaviour really only applies to normal states that don't have
+        a high priority (InputStatePriority::HighPriority). These 'special' ones
+        are used for features like the KeyDetector or the console. Use with care!
+    */
+    class _CoreExport InputState : public JoyStickQuantityListener
     {
         friend class InputManager;
 
+        //! Marks the index in the handler vector for the keyboard handler
+        static const InputDeviceEnumerator::Value keyboardIndex_s = InputDeviceEnumerator::Keyboard;
+        //! Marks the index in the handler vector for the mouse handler
+        static const InputDeviceEnumerator::Value mouseIndex_s = InputDeviceEnumerator::Mouse;
+        //! Marks the index in the handler vector for the first joy stick handler
+        static const InputDeviceEnumerator::Value firstJoyStickIndex_s = InputDeviceEnumerator::FirstJoyStick;
+
     public:
+        //! Sets the keyboard event handler (overwrites if there already was one!)
+        void setKeyHandler     (InputHandler* handler)
+            { handlers_[keyboardIndex_s] = handler; bExpired_ = true; }
+        //! Sets the mouse event handler (overwrites if there already was one!)
+        void setMouseHandler   (InputHandler* handler)
+            { handlers_[mouseIndex_s]    = handler; bExpired_ = true; }
+        /**
+        @brief
+            Sets the joy stick event handler for one specific joy stick (overwrites if there already was one!)
+        @return
+            Returns false if the specified device was not found
+        */
+        bool setJoyStickHandler(InputHandler* handler, unsigned int joyStick);
+        //! Sets the joy stick event handler for all joy sticks (overwrites if there already was one!)
+        void setJoyStickHandler(InputHandler* handler);
+        //! Sets an InputHandler to be used for all devices
+        void setHandler        (InputHandler* handler);
+
+        //! Returns the name of the state (which is unique!)
         const std::string& getName() const { return name_; }
+        //! Returns the priority of the state (which is unique if != 0)
         int getPriority()            const { return priority_; }
 
-        bool isInputDeviceEnabled(unsigned int device)
+        //! Tells whether there a handler installed for a specific device
+        bool isInputDeviceEnabled(unsigned int device);
+
+        //! Returns true if the handler situation has changed
+        bool hasExpired()      { return this->bExpired_; }
+        //! Call this if you have applied the changes resulting from changed handlers
+        void resetExpiration() { bExpired_ = false; }
+
+        //! Updates one specific device handler with #device#Updated
+        void update(float dt, unsigned int device);
+        //! Updates all handlers with allDevicesUpdated
+        void update(float dt);
+
+        //! Generic function that distributes all 9 button events
+        template <typename EventType, class Traits>
+        void buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button);
+
+        //! Event handler
+        void mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
+        //! Event handler
+        void mouseScrolled(int abs, int rel);
+        //! Event handler
+        void joyStickAxisMoved(unsigned int device, unsigned int axis, float value);
+
+        // Functors
+        //! Called when the state is being activated (even if it doesn't get any events afterwards!)
+        void entered();
+        //! Called upon deactivation of the state
+        void left();
+        //! Sets a functor to be called upon activation of the state
+        void setEnterFunctor(Functor* functor) { this->enterFunctor_ = functor; }
+        //! Sets a functor to be called upon deactivation of the state
+        void setLeaveFunctor(Functor* functor) { this->leaveFunctor_ = functor; }
+
+    private:
+        InputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority);
+        ~InputState() { }
+
+        void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList);
+
+        //! Sets the priority (only to be used by the InputManager!)
+        void setPriority(int priority) { priority_ = priority; }
+
+        const std::string           name_;                  //!< Name of the state
+        const bool                  bAlwaysGetsInput_;      //!< See class declaration for explanation
+        const bool                  bTransparent_;          //!< See class declaration for explanation
+        int                         priority_;              //!< Current priority (might change)
+        bool                        bExpired_;              //!< See hasExpired()
+        std::vector<InputHandler*>  handlers_;              //!< Vector with all handlers where the index is the device ID
+        //! Handler to be used for all joy sticks (needs to be saved in case another joy stick gets attached)
+        InputHandler*               joyStickHandlerAll_;
+        Functor*                    enterFunctor_;          //!< Functor to be executed on enter
+        Functor*                    leaveFunctor_;          //!< Functor to be executed on leave
+    };
+
+    FORCEINLINE void InputState::update(float dt)
+    {
+        for (unsigned int i = 0; i < handlers_.size(); ++i)
+            if (handlers_[i] != NULL)
+                handlers_[i]->allDevicesUpdated(dt);
+    }
+
+    FORCEINLINE void InputState::update(float dt, unsigned int device)
+    {
+        switch (device)
         {
-            if (device < bInputDeviceEnabled_.size())
-                return bInputDeviceEnabled_[device];
-            else
-                return false;
+        case InputDeviceEnumerator::Keyboard:
+            if (handlers_[keyboardIndex_s] != NULL)
+                handlers_[keyboardIndex_s]->keyboardUpdated(dt);
+            break;
+
+        case InputDeviceEnumerator::Mouse:
+            if (handlers_[mouseIndex_s] != NULL)
+                handlers_[mouseIndex_s]->mouseUpdated(dt);
+            break;
+
+        default: // joy sticks
+            if (handlers_[device] != NULL)
+                handlers_[device]->joyStickUpdated(device - firstJoyStickIndex_s, dt);
+            break;
         }
-
-        bool handlersChanged() { return this->bHandlersChanged_; }
-        void resetHandlersChanged() { bHandlersChanged_ = false; }
-
-        virtual void onEnter() = 0;
-        virtual void onLeave() = 0;
-
-        virtual void registerOnEnter(Executor* executor)      { executorOnEnter_ = executor; }
-        virtual void unRegisterOnEnter()                      { executorOnEnter_ = 0; }
-        virtual void registerOnLeave(Executor* executor)      { executorOnLeave_ = executor; }
-        virtual void unRegisterOnLeave()                      { executorOnLeave_ = 0; }
-
-        virtual void updateInput(float dt, unsigned int device) = 0;
-        virtual void updateInput(float dt) = 0;
-
-        virtual void keyPressed (const KeyEvent& evt) = 0;
-        virtual void keyReleased(const KeyEvent& evt) = 0;
-        virtual void keyHeld    (const KeyEvent& evt) = 0;
-
-        virtual void mouseButtonPressed (MouseButtonCode::ByEnum id) = 0;
-        virtual void mouseButtonReleased(MouseButtonCode::ByEnum id) = 0;
-        virtual void mouseButtonHeld    (MouseButtonCode::ByEnum id) = 0;
-        virtual void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0;
-        virtual void mouseScrolled      (int abs, int rel) = 0;
-
-        virtual void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
-        virtual void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
-        virtual void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
-        virtual void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) = 0;
-
-    protected:
-        InputState()
-            : bHandlersChanged_(false)
-            , executorOnEnter_(0)
-            , executorOnLeave_(0)
-            , priority_(0)
-            , bAlwaysGetsInput_(false)
-            , bTransparent_(false)
-        { }
-        virtual ~InputState() { }
-
-        virtual void numberOfJoySticksChanged(unsigned int n) = 0;
-        void setInputDeviceEnabled(unsigned int device, bool bEnabled)
-        {
-            if (device < bInputDeviceEnabled_.size())
-                bInputDeviceEnabled_[device] = bEnabled;
-        }
-
-        bool bHandlersChanged_;
-        Executor*                                   executorOnEnter_;
-        Executor*                                   executorOnLeave_;
-
-    private:
-        void setNumOfJoySticks(unsigned int n)
-        {
-            bInputDeviceEnabled_.resize(n + 2);
-            numberOfJoySticksChanged(n);
-        }
-        void setName(const std::string& name)  { name_ = name; }
-        void setPriority(int priority)         { priority_ = priority; }
-
-        std::string                                 name_;
-        int                                         priority_;
-        std::vector<bool>                           bInputDeviceEnabled_;
-        bool                                        bAlwaysGetsInput_;
-        bool                                        bTransparent_;
-    };
+    }
+
+    template <typename EventType, class Traits>
+    FORCEINLINE void InputState::buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button)
+    {
+        assert(device < handlers_.size());
+        if (handlers_[device] != NULL)
+            handlers_[device]->buttonEvent(device, button, EventType());
+    }
+
+    FORCEINLINE void InputState::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
+    {
+        if (handlers_[mouseIndex_s] != NULL)
+            handlers_[mouseIndex_s]->mouseMoved(abs, rel, clippingSize);
+    }
+
+    FORCEINLINE void InputState::mouseScrolled(int abs, int rel)
+    {
+        if (handlers_[mouseIndex_s] != NULL)
+            handlers_[mouseIndex_s]->mouseScrolled(abs, rel);
+    }
+
+    FORCEINLINE void InputState::joyStickAxisMoved(unsigned int device, unsigned int axis, float value)
+    {
+        assert(device < handlers_.size());
+        if (handlers_[device] != NULL)
+            handlers_[device]->axisMoved(device - firstJoyStickIndex_s, axis, value);
+    }
 }
 
Index: code/trunk/src/core/input/JoyStick.cc
===================================================================
--- code/trunk/src/core/input/JoyStick.cc	(revision 3327)
+++ code/trunk/src/core/input/JoyStick.cc	(revision 3327)
@@ -0,0 +1,260 @@
+/*
+ *   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 "JoyStick.h"
+
+#include <ois/OISJoyStick.h>
+#include <boost/foreach.hpp>
+
+#include "core/ConfigFileManager.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/CoreIncludes.h"
+#include "util/Convert.h"
+#include "InputState.h"
+
+namespace orxonox
+{
+    //! Helper function that loads the config value vector of one coefficient
+    void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue);
+
+    std::vector<std::string> JoyStick::deviceNames_s;
+
+    JoyStick::JoyStick(unsigned int id, OIS::InputManager* oisInputManager)
+        : super(id, oisInputManager)
+    {
+        RegisterRootObject(JoyStick);
+        this->setConfigValues();
+        // Initialise POV and Slider states
+        this->clearBuffersImpl();
+
+        // Generate unique name
+        if (oisDevice_->vendor().empty())
+            deviceName_ = "Unknown_";
+        else
+        {
+            std::string name = oisDevice_->vendor();
+            replaceCharacters(name, ' ', '_');
+            deviceName_ = name + "_";
+        }
+        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Button))  + "_";
+        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis))    + "_";
+        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Slider))  + "_";
+        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_POV));
+        //deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Vector3));
+
+        BOOST_FOREACH(std::string& idString, deviceNames_s)
+        {
+            if (deviceName_ == idString)
+            {
+                // Make the ID unique for this execution time.
+                deviceName_ += "_" + multi_cast<std::string>(this->getDeviceName());
+                break;
+            }
+        }
+
+        COUT(4) << "Created OIS joy stick with ID " << deviceName_ << std::endl;
+
+        // Load calibration
+        size_t axes = sliderAxes_s + static_cast<size_t>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis));
+        loadCalibration(configMinValues_,  deviceName_, "MinValue",  axes,  -32768);
+        loadCalibration(configMaxValues_,  deviceName_, "MaxValue",  axes,   32768);
+        loadCalibration(configZeroValues_, deviceName_, "ZeroValue", axes, 0);
+        this->evaluateCalibration();
+    }
+
+    //! Callback for the joy stick calibration config file.
+    void JoyStick::calibrationFileCallback()
+    {
+        ConfigFileManager::getInstance().setFilename(ConfigFileType::JoyStickCalibration, calibrationFilename_);
+    }
+
+    void JoyStick::setConfigValues()
+    {
+        SetConfigValue(calibrationFilename_, "joystick_calibration.ini")
+            .description("Ini filename for the the joy stick calibration data.")
+            .callback(this, &JoyStick::calibrationFileCallback);
+    }
+
+    void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue)
+    {
+        list.resize(size);
+        unsigned int configValueVectorSize = ConfigFileManager::getInstance().getVectorSize(ConfigFileType::JoyStickCalibration, sectionName, valueName);
+        if (configValueVectorSize > size)
+            configValueVectorSize = size;
+
+        for (unsigned int i = 0; i < configValueVectorSize; ++i)
+        {
+            list[i] = multi_cast<int>(ConfigFileManager::getInstance().getValue(
+                ConfigFileType::JoyStickCalibration, sectionName, valueName, i, multi_cast<std::string>(defaultValue), false));
+        }
+
+        // fill the rest with default values
+        for (unsigned int i = configValueVectorSize; i < size; ++i)
+            list[i] = defaultValue;
+    }
+
+    //! Called by InputDevice when calibration mode has started
+    void JoyStick::calibrationStarted()
+    {
+        // Set initial values
+        BOOST_FOREACH(int& minVal, configMinValues_)
+            minVal = INT_MAX;
+        BOOST_FOREACH(int& minVal, configMaxValues_)
+            minVal = INT_MIN;
+        BOOST_FOREACH(int& zeroVal, configZeroValues_)
+            zeroVal = 0;
+    }
+
+    //! Called by InputDevice when calibration mode has stopped
+    void JoyStick::calibrationStopped()
+    {
+        // Get the middle positions now
+        unsigned int iAxis = 0;
+        for (unsigned int i = 0; i < sliderAxes_s/2; ++i)
+        {
+            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mSliders[i].abX;
+            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mSliders[i].abY;
+        }
+        // Note: joyStickZeroValues_[iJoyStick] was already correctly resised in loadCalibration()
+        assert(oisDevice_->getJoyStickState().mAxes.size() == configZeroValues_.size() - sliderAxes_s);
+        for (unsigned int i = 0; i < configZeroValues_.size() - sliderAxes_s; ++i)
+            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mAxes[i].abs;
+
+        for (unsigned int i = 0; i < configMinValues_.size(); ++i)
+        {
+            // Minimum values
+            if (configMinValues_[i] == INT_MAX)
+                configMinValues_[i] = -32768;
+            ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
+                deviceName_, "MinValue", i, multi_cast<std::string>(configMinValues_[i]), false);
+
+            // Maximum values
+            if (configMaxValues_[i] == INT_MIN)
+                configMaxValues_[i] = 32767;
+            ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
+                deviceName_, "MaxValue", i, multi_cast<std::string>(configMaxValues_[i]), false);
+
+            // Middle values
+            ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
+                deviceName_, "ZeroValue", i, multi_cast<std::string>(configZeroValues_[i]), false);
+        }
+
+        this->evaluateCalibration();
+    }
+
+    //! Evaluates the accumulated values during calibration
+    void JoyStick::evaluateCalibration()
+    {
+        for (unsigned int i = 0; i < configMinValues_.size(); i++)
+        {
+            zeroValues_[i] = configZeroValues_[i];
+            negativeCoeffs_[i] = - 1.0f / (configMinValues_[i] - configZeroValues_[i]);
+            positiveCoeffs_[i] =   1.0f / (configMaxValues_[i] - configZeroValues_[i]);
+        }
+    }
+
+    //! Resets the pov states
+    void JoyStick::clearBuffersImpl()
+    {
+        for (int j = 0; j < 4; ++j)
+            povStates_[j] = 0;
+    }
+
+    //! Generic method to forward axis events
+    void JoyStick::fireAxis(int axis, int value)
+    {
+        if (this->isCalibrating())
+        {
+            if (value < configMinValues_[axis])
+                configMinValues_[axis] = value;
+            if (value > configMaxValues_[axis])
+                configMaxValues_[axis] = value;
+        }
+        else
+        {
+            float fValue = static_cast<float>(value - zeroValues_[axis]);
+            if (fValue > 0.0f)
+                fValue *= positiveCoeffs_[axis];
+            else
+                fValue *= negativeCoeffs_[axis];
+
+            BOOST_FOREACH(InputState* state, inputStates_)
+                state->joyStickAxisMoved(this->getDeviceID(), axis, fValue);
+        }
+    }
+
+    //! OIS joy stick axis event handler
+    bool JoyStick::axisMoved(const OIS::JoyStickEvent &arg, int axis)
+    {
+        // keep in mind that the first 8 axes are reserved for the sliders
+        this->fireAxis(axis + sliderAxes_s, arg.state.mAxes[axis].abs);
+
+        return true;
+    }
+
+    //! A Slider always has an X and an Y direction!
+    bool JoyStick::sliderMoved(const OIS::JoyStickEvent &arg, int id)
+    {
+        if (sliderStates_[id][0] != arg.state.mSliders[id].abX)
+            fireAxis(id * 2, arg.state.mSliders[id].abX);
+        else if (sliderStates_[id][1] != arg.state.mSliders[id].abY)
+            fireAxis(id * 2 + 1, arg.state.mSliders[id].abY);
+
+        return true;
+    }
+
+    //! A POV is the big button that can point in all directions (but only in one at once)
+    bool JoyStick::povMoved(const OIS::JoyStickEvent &arg, int id)
+    {
+        // translate the POV into 8 simple buttons
+
+        int lastState = povStates_[id];
+        if (lastState & OIS::Pov::North)
+            buttonReleased(arg, 32 + id * 4 + 0);
+        if (lastState & OIS::Pov::South)
+            buttonReleased(arg, 32 + id * 4 + 1);
+        if (lastState & OIS::Pov::East)
+            buttonReleased(arg, 32 + id * 4 + 2);
+        if (lastState & OIS::Pov::West)
+            buttonReleased(arg, 32 + id * 4 + 3);
+
+        povStates_[id] = arg.state.mPOV[id].direction;
+
+        int currentState = povStates_[id];
+        if (currentState & OIS::Pov::North)
+            buttonPressed(arg, 32 + id * 4 + 0);
+        if (currentState & OIS::Pov::South)
+            buttonPressed(arg, 32 + id * 4 + 1);
+        if (currentState & OIS::Pov::East)
+            buttonPressed(arg, 32 + id * 4 + 2);
+        if (currentState & OIS::Pov::West)
+            buttonPressed(arg, 32 + id * 4 + 3);
+
+        return true;
+    }
+}
Index: code/trunk/src/core/input/JoyStick.h
===================================================================
--- code/trunk/src/core/input/JoyStick.h	(revision 3327)
+++ code/trunk/src/core/input/JoyStick.h	(revision 3327)
@@ -0,0 +1,132 @@
+/*
+ *   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 _Core_JoyStick_H__
+#define _Core_JoyStick_H__
+
+#include "InputPrereqs.h"
+
+#include <string>
+#include <vector>
+#include "InputDevice.h"
+
+namespace orxonox
+{
+    //! Template parameter collection for the base class
+    struct JoyStickTraits
+    {
+        typedef JoyStick DeviceClass;
+        typedef OIS::JoyStick OISDeviceClass;
+        typedef JoyStickButtonCode::ByEnum ButtonType;
+        typedef JoyStickButtonCode::ByEnum ButtonTypeParam;
+        static const OIS::Type OISDeviceValue = OIS::OISJoyStick;
+    };
+
+    /**
+    @brief
+        Wraps around an OIS::JoyStick and forwards the input events to
+        a list of input states.
+
+        The class also supports joy stick calibration and stores the values
+        in an ini-file.
+    */
+    class _CoreExport JoyStick
+        : public OrxonoxClass
+        , public InputDeviceTemplated<JoyStickTraits>
+        , public OIS::JoyStickListener
+    {
+        friend class InputDeviceTemplated<JoyStickTraits>;
+        //! Super class alias
+        typedef InputDeviceTemplated<JoyStickTraits> super;
+
+    public:
+        //! Assigns a generated ID string and loads the calibration (if present)
+        JoyStick(unsigned int id, OIS::InputManager* oisInputManager);
+        ~JoyStick() { }
+        void setConfigValues();
+
+        //! Returns the name generated from the number of knobs and the device name
+        const std::string& getDeviceName() const { return this->deviceName_; }
+
+    private:
+        void calibrationStarted();
+        void calibrationStopped();
+        void evaluateCalibration();
+
+        void clearBuffersImpl();
+        void calibrationFileCallback();
+        void fireAxis(int axis, int value);
+
+        //! OIS event handler
+        bool buttonPressed (const OIS::JoyStickEvent &arg, int button)
+        {
+            super::buttonPressed(static_cast<JoyStickButtonCode::ByEnum>(button));
+            return true;
+        }
+
+        //! OIS event handler
+        bool buttonReleased(const OIS::JoyStickEvent &arg, int button)
+        {
+            super::buttonReleased(static_cast<JoyStickButtonCode::ByEnum>(button));
+            return true;
+        }
+
+        bool axisMoved     (const OIS::JoyStickEvent &arg, int axis);
+        bool sliderMoved   (const OIS::JoyStickEvent &arg, int id);
+        bool povMoved      (const OIS::JoyStickEvent &arg, int id);
+        //! OIS event handler (don't remove that because of OIS version issues!)
+        bool vector3Moved  (const OIS::JoyStickEvent &arg, int id) { return true; }
+
+        //! Returns the class name as string
+        static std::string getClassNameImpl() { return "JoyStick"; }
+
+        std::string deviceName_;              //!< Name generated by the number of knobs and the device name
+        int povStates_[4];                    //!< Internal states for the POVs
+        int sliderStates_[4][2];              //!< Internal states for the Sliders (each slider has X and Y!)
+
+        // calibration
+        int zeroValues_[24];                  //!< Axes values when the knob is in the middle
+        float positiveCoeffs_[24];            //!< Maps the negative part of an axis to a 0.0 to 1.0 floating range
+        float negativeCoeffs_[24];            //!< Maps the positive part of an axis to a 0.0 to 1.0 floating range
+
+        std::vector<int> configZeroValues_;   //!< Config file stored axis values when the knob is in the middle
+        std::vector<int> configMinValues_;    //!< Config file stored minimum axis values
+        std::vector<int> configMaxValues_;    //!< Config file stored maximum axis values
+
+        // ConfigValues
+        std::string calibrationFilename_;     //!< Joy stick calibration ini filename
+
+        //! Contains a list of all names to avoid duplicates
+        static std::vector<std::string> deviceNames_s;
+
+        //!< Maximum number of slider axes
+        static const unsigned int sliderAxes_s = 8;
+    };
+}
+
+#endif /* _Core_JoyStick_H__ */
Index: code/trunk/src/core/input/JoyStickDeviceNumberListener.cc
===================================================================
--- code/trunk/src/core/input/JoyStickDeviceNumberListener.cc	(revision 3326)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation; either version 2
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Reto Grieder
- *   Co-authors:
- *      ...
- *
- */
-
-/**
-@file
-@brief
-    Implementation of the JoyStickDeviceNumberListener class.
-*/
-
-#include "JoyStickDeviceNumberListener.h"
-#include "core/CoreIncludes.h"
-
-namespace orxonox
-{
-    JoyStickDeviceNumberListener::JoyStickDeviceNumberListener()
-    {
-        RegisterObject(JoyStickDeviceNumberListener);
-    }
-}
Index: code/trunk/src/core/input/JoyStickDeviceNumberListener.h
===================================================================
--- code/trunk/src/core/input/JoyStickDeviceNumberListener.h	(revision 3326)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation; either version 2
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Reto Grieder
- *   Co-authors:
- *      ...
- *
- */
-
-/**
-@file
-@brief 
-*/
-
-#ifndef _JoyStickDeviceNumberListener_H__
-#define _JoyStickDeviceNumberListener_H__
-
-#include "core/CorePrereqs.h"
-#include "core/OrxonoxClass.h"
-
-namespace orxonox
-{
-    class _CoreExport JoyStickDeviceNumberListener : virtual public OrxonoxClass
-    {
-    public:
-        JoyStickDeviceNumberListener();
-        virtual ~JoyStickDeviceNumberListener() { }
-
-        virtual void JoyStickDeviceNumberChanged(unsigned int value) = 0;
-    };
-}
-
-#endif /* _JoyStickDeviceNumberListener_H__ */
Index: code/trunk/src/core/input/JoyStickQuantityListener.cc
===================================================================
--- code/trunk/src/core/input/JoyStickQuantityListener.cc	(revision 3327)
+++ code/trunk/src/core/input/JoyStickQuantityListener.cc	(revision 3327)
@@ -0,0 +1,50 @@
+/*
+ *   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 "JoyStickQuantityListener.h"
+
+#include "core/CoreIncludes.h"
+#include "core/ObjectList.h"
+
+namespace orxonox
+{
+    std::vector<JoyStick*> JoyStickQuantityListener::joyStickList_s;
+
+    JoyStickQuantityListener::JoyStickQuantityListener()
+    {
+        RegisterObject(JoyStickQuantityListener);
+    }
+
+    //! Calls all registered objects and sets the static variable
+    /*static*/ void JoyStickQuantityListener::changeJoyStickQuantity(const std::vector<JoyStick*>& joyStickList)
+    {
+        joyStickList_s = joyStickList;
+        for (ObjectList<JoyStickQuantityListener>::iterator it = ObjectList<JoyStickQuantityListener>::begin(); it; ++it)
+            it->JoyStickQuantityChanged(joyStickList);
+    }
+}
Index: code/trunk/src/core/input/JoyStickQuantityListener.h
===================================================================
--- code/trunk/src/core/input/JoyStickQuantityListener.h	(revision 3327)
+++ code/trunk/src/core/input/JoyStickQuantityListener.h	(revision 3327)
@@ -0,0 +1,64 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief 
+*/
+
+#ifndef _JoyStickQuantityListener_H__
+#define _JoyStickQuantityListener_H__
+
+#include "InputPrereqs.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    //! Derive from this class to get informed when joy sticks get added/removed
+    class _CoreExport JoyStickQuantityListener : virtual public OrxonoxClass
+    {
+        friend class InputManager;
+    protected:
+        JoyStickQuantityListener();
+        virtual ~JoyStickQuantityListener() { }
+
+        //! Returns a list with all JoySticks currently loaded
+        const std::vector<JoyStick*>& getJoyStickList() const { return joyStickList_s; }
+
+    private:
+        //! Called whenever joy sticks get added/removed
+        virtual void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList) = 0;
+
+        static void changeJoyStickQuantity(const std::vector<JoyStick*>& joyStickList);
+
+        //! Static variable that holds the latest distributed information
+        static std::vector<JoyStick*> joyStickList_s;
+    };
+}
+
+#endif /* _JoyStickQuantityListener_H__ */
Index: code/trunk/src/core/input/KeyBinder.cc
===================================================================
--- code/trunk/src/core/input/KeyBinder.cc	(revision 3326)
+++ code/trunk/src/core/input/KeyBinder.cc	(revision 3327)
@@ -40,5 +40,5 @@
 #include "core/ConfigFileManager.h"
 #include "InputCommands.h"
-#include "InputManager.h"
+#include "JoyStick.h"
 
 namespace orxonox
@@ -49,6 +49,5 @@
     */
     KeyBinder::KeyBinder()
-        : numberOfJoySticks_(0)
-        , deriveTime_(0.0f)
+        : deriveTime_(0.0f)
     {
         mouseRelative_[0] = 0;
@@ -56,4 +55,7 @@
         mousePosition_[0] = 0;
         mousePosition_[1] = 0;
+
+        joyStickButtons_.reserve(1000);
+        joyStickAxes_.reserve(1000);
 
         RegisterRootObject(KeyBinder);
@@ -80,5 +82,5 @@
             else
                 nameSuffix = mouseWheelNames[i - MouseButtonCode::numberOfButtons];
-            mouseButtons_[i].name_ = std::string("Mouse") + nameSuffix;
+            mouseButtons_[i].name_ = nameSuffix;
             mouseButtons_[i].paramCommandBuffer_ = &paramCommandBuffer_;
             mouseButtons_[i].groupName_ = "MouseButtons";
@@ -87,5 +89,5 @@
         for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
         {
-            mouseAxes_[i].name_ = std::string("Mouse") + MouseAxisCode::ByString[i / 2];
+            mouseAxes_[i].name_ = MouseAxisCode::ByString[i / 2];
             if (i & 1)
                 mouseAxes_[i].name_ += "Pos";
@@ -100,9 +102,5 @@
 
         // initialise joy sticks separatly to allow for reloading
-        numberOfJoySticks_ = InputManager::getInstance().numberOfJoySticks();
-        initialiseJoyStickBindings();
-
-        // collect all Buttons and HalfAxes
-        compilePointerLists();
+        this->JoyStickQuantityChanged(this->getJoyStickList());
 
         // set them here to use allHalfAxes_
@@ -152,8 +150,8 @@
     }
 
-    void KeyBinder::JoyStickDeviceNumberChanged(unsigned int value)
-    {
-        unsigned int oldValue = numberOfJoySticks_;
-        numberOfJoySticks_ = value;
+    void KeyBinder::JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList)
+    {
+        unsigned int oldValue = joySticks_.size();
+        joySticks_ = joyStickList;
 
         // initialise joy stick bindings
@@ -166,5 +164,5 @@
         if (configFile_ != ConfigFileType::NoType)
         {
-            for (unsigned int iDev = oldValue; iDev < numberOfJoySticks_; ++iDev)
+            for (unsigned int iDev = oldValue; iDev < joySticks_.size(); ++iDev)
             {
                 for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; ++i)
@@ -181,22 +179,22 @@
     void KeyBinder::initialiseJoyStickBindings()
     {
-        this->joyStickAxes_.resize(numberOfJoySticks_);
-        this->joyStickButtons_.resize(numberOfJoySticks_);
+        this->joyStickAxes_.resize(joySticks_.size());
+        this->joyStickButtons_.resize(joySticks_.size());
 
         // reinitialise all joy stick binings (doesn't overwrite the old ones)
-        for (unsigned int iDev = 0; iDev < numberOfJoySticks_; iDev++)
-        {
-            std::string deviceNumber = multi_cast<std::string>(iDev);
+        for (unsigned int iDev = 0; iDev < joySticks_.size(); iDev++)
+        {
+            std::string deviceName = joySticks_[iDev]->getDeviceName();
             // joy stick buttons
             for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
             {
-                joyStickButtons_[iDev][i].name_ = std::string("JoyStick") + deviceNumber + JoyStickButtonCode::ByString[i];
+                joyStickButtons_[iDev][i].name_ = JoyStickButtonCode::ByString[i];
                 joyStickButtons_[iDev][i].paramCommandBuffer_ = &paramCommandBuffer_;
-                joyStickButtons_[iDev][i].groupName_ = std::string("JoyStick") + deviceNumber + "Buttons";
+                joyStickButtons_[iDev][i].groupName_ = "JoyStickButtons_" + deviceName;
             }
             // joy stick axes
             for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
             {
-                joyStickAxes_[iDev][i].name_ = std::string("JoyStick") + deviceNumber + JoyStickAxisCode::ByString[i >> 1];
+                joyStickAxes_[iDev][i].name_ = JoyStickAxisCode::ByString[i / 2];
                 if (i & 1)
                     joyStickAxes_[iDev][i].name_ += "Pos";
@@ -204,5 +202,5 @@
                     joyStickAxes_[iDev][i].name_ += "Neg";
                 joyStickAxes_[iDev][i].paramCommandBuffer_ = &paramCommandBuffer_;
-                joyStickAxes_[iDev][i].groupName_ = std::string("JoyStick") + deviceNumber + "Axes";
+                joyStickAxes_[iDev][i].groupName_ = "JoyStickAxes_" + deviceName;
             }
         }
@@ -217,19 +215,19 @@
         for (unsigned int i = 0; i < KeyCode::numberOfKeys; i++)
             if (!keys_[i].name_.empty())
-                allButtons_[keys_[i].name_] = keys_ + i;
+                allButtons_[keys_[i].groupName_ + "." + keys_[i].name_] = keys_ + i;
         for (unsigned int i = 0; i < numberOfMouseButtons_; i++)
-            allButtons_[mouseButtons_[i].name_] = mouseButtons_ + i;
+            allButtons_[mouseButtons_[i].groupName_ + "." + mouseButtons_[i].name_] = mouseButtons_ + i;
         for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
         {
-            allButtons_[mouseAxes_[i].name_] = mouseAxes_ + i;
+            allButtons_[mouseAxes_[i].groupName_ + "." + mouseAxes_[i].name_] = mouseAxes_ + i;
             allHalfAxes_.push_back(mouseAxes_ + i);
         }
-        for (unsigned int iDev = 0; iDev < numberOfJoySticks_; iDev++)
+        for (unsigned int iDev = 0; iDev < joySticks_.size(); iDev++)
         {
             for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
-                allButtons_[joyStickButtons_[iDev][i].name_] = &(joyStickButtons_[iDev][i]);
+                allButtons_[joyStickButtons_[iDev][i].groupName_ + "." + joyStickButtons_[iDev][i].name_] = &(joyStickButtons_[iDev][i]);
             for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
             {
-                allButtons_[joyStickAxes_[iDev][i].name_] = &(joyStickAxes_[iDev][i]);
+                allButtons_[joyStickAxes_[iDev][i].groupName_ + "." + joyStickAxes_[iDev][i].name_] = &(joyStickAxes_[iDev][i]);
                 allHalfAxes_.push_back(&(joyStickAxes_[iDev][i]));
             }
@@ -301,5 +299,5 @@
     void KeyBinder::resetJoyStickAxes()
     {
-        for (unsigned int iDev = 0; iDev < numberOfJoySticks_; ++iDev)
+        for (unsigned int iDev = 0; iDev < joySticks_.size(); ++iDev)
         {
             for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
@@ -311,5 +309,5 @@
     }
 
-    void KeyBinder::updateMouse(float dt)
+    void KeyBinder::mouseUpdated(float dt)
     {
         if (bDeriveMouseInput_)
@@ -364,5 +362,5 @@
     }
 
-    void KeyBinder::updateJoyStick(float dt, unsigned int joyStick)
+    void KeyBinder::joyStickUpdated(unsigned int joyStick, float dt)
     {
         for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
@@ -480,29 +478,30 @@
     }
 
-    void KeyBinder::joyStickAxisMoved(unsigned int joyStickID, unsigned int axis, float value)
-    {
-        int i = axis * 2;
+    void KeyBinder::axisMoved(unsigned int device, unsigned int axisID, float value)
+    {
+        int i = axisID * 2;
+        JoyStickAxisVector& axis = joyStickAxes_[device];
         if (value < 0)
         {
-            joyStickAxes_[joyStickID][i].absVal_ = -value;
-            joyStickAxes_[joyStickID][i].relVal_ = -value;
-            joyStickAxes_[joyStickID][i].hasChanged_ = true;
-            if (joyStickAxes_[joyStickID][i + 1].absVal_ > 0.0f)
-            {
-                joyStickAxes_[joyStickID][i + 1].absVal_ = -0.0f;
-                joyStickAxes_[joyStickID][i + 1].relVal_ = -0.0f;
-                joyStickAxes_[joyStickID][i + 1].hasChanged_ = true;
+            axis[i].absVal_ = -value;
+            axis[i].relVal_ = -value;
+            axis[i].hasChanged_ = true;
+            if (axis[i + 1].absVal_ > 0.0f)
+            {
+                axis[i + 1].absVal_ = -0.0f;
+                axis[i + 1].relVal_ = -0.0f;
+                axis[i + 1].hasChanged_ = true;
             }
         }
         else
         {
-            joyStickAxes_[joyStickID][i + 1].absVal_ = value;
-            joyStickAxes_[joyStickID][i + 1].relVal_ = value;
-            joyStickAxes_[joyStickID][i + 1].hasChanged_ = true;
-            if (joyStickAxes_[joyStickID][i].absVal_ > 0.0f)
-            {
-                joyStickAxes_[joyStickID][i].absVal_ = -0.0f;
-                joyStickAxes_[joyStickID][i].relVal_ = -0.0f;
-                joyStickAxes_[joyStickID][i].hasChanged_ = true;
+            axis[i + 1].absVal_ = value;
+            axis[i + 1].relVal_ = value;
+            axis[i + 1].hasChanged_ = true;
+            if (axis[i].absVal_ > 0.0f)
+            {
+                axis[i].absVal_ = -0.0f;
+                axis[i].relVal_ = -0.0f;
+                axis[i].hasChanged_ = true;
             }
         }
Index: code/trunk/src/core/input/KeyBinder.h
===================================================================
--- code/trunk/src/core/input/KeyBinder.h	(revision 3326)
+++ code/trunk/src/core/input/KeyBinder.h	(revision 3327)
@@ -36,5 +36,5 @@
 #define _KeyBinder_H__
 
-#include "core/CorePrereqs.h"
+#include "InputPrereqs.h"
 
 #include <cassert>
@@ -42,9 +42,9 @@
 #include <vector>
 
-#include "InputInterfaces.h"
+#include "InputHandler.h"
 #include "Button.h"
 #include "HalfAxis.h"
 #include "InputCommands.h"
-#include "JoyStickDeviceNumberListener.h"
+#include "JoyStickQuantityListener.h"
 
 namespace orxonox
@@ -55,6 +55,5 @@
         Manages the key bindings.
     */
-    class _CoreExport KeyBinder : public KeyHandler, public MouseHandler, public JoyStickHandler,
-                                  public JoyStickDeviceNumberListener
+    class _CoreExport KeyBinder : public InputHandler, public JoyStickQuantityListener
     {
     public:
@@ -69,35 +68,34 @@
 
     protected: // functions
-        void updateInput(float dt);
-        void updateKey(float dt) { }
-        void updateMouse(float dt);
-        void updateJoyStick(float dt, unsigned int joyStick);
+        void allDevicesUpdated(float dt);
+        void mouseUpdated(float dt);
+        void joyStickUpdated(unsigned int joyStick, float dt);
         // internal
         void tickHalfAxis(HalfAxis& halfAxis);
 
         void buttonThresholdChanged();
-        // from JoyStickDeviceNumberListener interface
-        virtual void JoyStickDeviceNumberChanged(unsigned int value);
+        // from JoyStickQuantityListener interface
+        virtual void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList);
         void initialiseJoyStickBindings();
         void compilePointerLists();
 
-        void keyPressed (const KeyEvent& evt);
-        void keyReleased(const KeyEvent& evt);
-        void keyHeld    (const KeyEvent& evt);
-
-        void mouseButtonPressed (MouseButtonCode::ByEnum id);
-        void mouseButtonReleased(MouseButtonCode::ByEnum id);
-        void mouseButtonHeld    (MouseButtonCode::ByEnum id);
-        void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
-        void mouseScrolled      (int abs, int rel);
-
-        void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
-        void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
-        void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
-        void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value);
+        void buttonPressed (const KeyEvent& evt);
+        void buttonReleased(const KeyEvent& evt);
+        void buttonHeld    (const KeyEvent& evt);
+
+        void buttonPressed (MouseButtonCode::ByEnum button);
+        void buttonReleased(MouseButtonCode::ByEnum button);
+        void buttonHeld    (MouseButtonCode::ByEnum button);
+        void mouseMoved    (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
+        void mouseScrolled (int abs, int rel);
+
+        void buttonPressed (unsigned int device, JoyStickButtonCode::ByEnum button);
+        void buttonReleased(unsigned int device, JoyStickButtonCode::ByEnum button);
+        void buttonHeld    (unsigned int device, JoyStickButtonCode::ByEnum button);
+        void axisMoved     (unsigned int device, unsigned int axis, float value);
 
     protected: // variables
         //! Currently active joy sticks
-        unsigned int numberOfJoySticks_;
+        std::vector<JoyStick*>  joySticks_;
 
         //! Actual key bindings for keys on the keyboard
@@ -172,34 +170,34 @@
     };
 
-    inline void KeyBinder::keyPressed (const KeyEvent& evt)
-    { assert(!keys_[evt.key].name_.empty()); keys_[evt.key].execute(KeybindMode::OnPress); }
-
-    inline void KeyBinder::keyReleased(const KeyEvent& evt)
-    { assert(!keys_[evt.key].name_.empty()); keys_[evt.key].execute(KeybindMode::OnRelease); }
-
-    inline void KeyBinder::keyHeld    (const KeyEvent& evt)
-    { assert(!keys_[evt.key].name_.empty()); keys_[evt.key].execute(KeybindMode::OnHold); }
-
-
-    inline void KeyBinder::mouseButtonPressed (MouseButtonCode::ByEnum id)
-    { mouseButtons_[id].execute(KeybindMode::OnPress); }
-
-    inline void KeyBinder::mouseButtonReleased(MouseButtonCode::ByEnum id)
-    { mouseButtons_[id].execute(KeybindMode::OnRelease); }
-
-    inline void KeyBinder::mouseButtonHeld    (MouseButtonCode::ByEnum id)
-    { mouseButtons_[id].execute(KeybindMode::OnHold); }
-
-
-    inline void KeyBinder::joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
-    { joyStickButtons_[joyStickID][id].execute(KeybindMode::OnPress); }
-
-    inline void KeyBinder::joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
-    { joyStickButtons_[joyStickID][id].execute(KeybindMode::OnRelease); }
-
-    inline void KeyBinder::joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
-    { joyStickButtons_[joyStickID][id].execute(KeybindMode::OnHold); }
-
-    inline void KeyBinder::updateInput(float dt)
+    inline void KeyBinder::buttonPressed (const KeyEvent& evt)
+    { assert(!keys_[evt.getKeyCode()].name_.empty()); keys_[evt.getKeyCode()].execute(KeybindMode::OnPress); }
+
+    inline void KeyBinder::buttonReleased(const KeyEvent& evt)
+    { assert(!keys_[evt.getKeyCode()].name_.empty()); keys_[evt.getKeyCode()].execute(KeybindMode::OnRelease); }
+
+    inline void KeyBinder::buttonHeld    (const KeyEvent& evt)
+    { assert(!keys_[evt.getKeyCode()].name_.empty()); keys_[evt.getKeyCode()].execute(KeybindMode::OnHold); }
+
+
+    inline void KeyBinder::buttonPressed (MouseButtonCode::ByEnum button)
+    { mouseButtons_[button].execute(KeybindMode::OnPress); }
+
+    inline void KeyBinder::buttonReleased(MouseButtonCode::ByEnum button)
+    { mouseButtons_[button].execute(KeybindMode::OnRelease); }
+
+    inline void KeyBinder::buttonHeld    (MouseButtonCode::ByEnum button)
+    { mouseButtons_[button].execute(KeybindMode::OnHold); }
+
+
+    inline void KeyBinder::buttonPressed (unsigned int device, JoyStickButtonCode::ByEnum button)
+    { joyStickButtons_[device][button].execute(KeybindMode::OnPress); }
+
+    inline void KeyBinder::buttonReleased(unsigned int device, JoyStickButtonCode::ByEnum button)
+    { joyStickButtons_[device][button].execute(KeybindMode::OnRelease); }
+
+    inline void KeyBinder::buttonHeld    (unsigned int device, JoyStickButtonCode::ByEnum button)
+    { joyStickButtons_[device][button].execute(KeybindMode::OnHold); }
+
+    inline void KeyBinder::allDevicesUpdated(float dt)
     {
         // execute all buffered bindings (additional parameter)
Index: code/trunk/src/core/input/KeyDetector.cc
===================================================================
--- code/trunk/src/core/input/KeyDetector.cc	(revision 3326)
+++ code/trunk/src/core/input/KeyDetector.cc	(revision 3327)
@@ -26,10 +26,4 @@
  *
  */
-
-/**
-@file
-@brief
-    Implementation of the different input handlers.
-*/
 
 #include "KeyDetector.h"
@@ -68,12 +62,12 @@
         for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
         {
-            it->second->bindingString_ = callbackCommand_ + it->second->name_;
+            it->second->bindingString_ = callbackCommand_ + it->second->groupName_ + "." + it->second->name_;
             it->second->parse();
         }
     }
 
-    void KeyDetector::JoyStickDeviceNumberChanged(unsigned int value)
+    void KeyDetector::JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList)
     {
-        KeyBinder::JoyStickDeviceNumberChanged(value);
+        KeyBinder::JoyStickQuantityChanged(joyStickList);
         setCallbackCommand(callbackCommand_);
     }
Index: code/trunk/src/core/input/KeyDetector.h
===================================================================
--- code/trunk/src/core/input/KeyDetector.h	(revision 3326)
+++ code/trunk/src/core/input/KeyDetector.h	(revision 3327)
@@ -27,14 +27,8 @@
  */
 
-/**
-@file
-@brief
-    Different definitions of input processing.
-*/
-
 #ifndef _KeyDetector_H__
 #define _KeyDetector_H__
 
-#include "core/CorePrereqs.h"
+#include "InputPrereqs.h"
 
 #include <string>
@@ -49,5 +43,5 @@
         ~KeyDetector();
         void setCallbackCommand(const std::string& command);
-        void JoyStickDeviceNumberChanged(unsigned int value);
+        void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList);
 
     private:
Index: code/trunk/src/core/input/Keyboard.cc
===================================================================
--- code/trunk/src/core/input/Keyboard.cc	(revision 3327)
+++ code/trunk/src/core/input/Keyboard.cc	(revision 3327)
@@ -0,0 +1,65 @@
+/*
+ *   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 "Keyboard.h"
+#include "InputState.h"
+
+namespace orxonox
+{
+    //! OIS event handler
+    bool Keyboard::keyPressed(const OIS::KeyEvent& arg)
+    {
+        // update modifiers
+        if(arg.key == OIS::KC_RMENU    || arg.key == OIS::KC_LMENU)
+            modifiers_ |= KeyboardModifier::Alt;   // alt key
+        if(arg.key == OIS::KC_RCONTROL || arg.key == OIS::KC_LCONTROL)
+            modifiers_ |= KeyboardModifier::Ctrl;  // ctrl key
+        if(arg.key == OIS::KC_RSHIFT   || arg.key == OIS::KC_LSHIFT)
+            modifiers_ |= KeyboardModifier::Shift; // shift key
+
+        KeyEvent evt(arg);
+        super::buttonPressed(evt);
+        return true;
+    }
+
+    //! OIS event handler
+    bool Keyboard::keyReleased(const OIS::KeyEvent& arg)
+    {
+        // update modifiers
+        if(arg.key == OIS::KC_RMENU    || arg.key == OIS::KC_LMENU)
+            modifiers_ &= ~KeyboardModifier::Alt;   // alt key
+        if(arg.key == OIS::KC_RCONTROL || arg.key == OIS::KC_LCONTROL)
+            modifiers_ &= ~KeyboardModifier::Ctrl;  // ctrl key
+        if(arg.key == OIS::KC_RSHIFT   || arg.key == OIS::KC_LSHIFT)
+            modifiers_ &= ~KeyboardModifier::Shift; // shift key
+
+        KeyEvent evt(arg);
+        super::buttonReleased(evt);
+        return true;
+    }
+}
Index: code/trunk/src/core/input/Keyboard.h
===================================================================
--- code/trunk/src/core/input/Keyboard.h	(revision 3327)
+++ code/trunk/src/core/input/Keyboard.h	(revision 3327)
@@ -0,0 +1,90 @@
+/*
+ *   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 _Core_Keyboard_H__
+#define _Core_Keyboard_H__
+
+#include "InputPrereqs.h"
+
+#include "InputHandler.h"
+#include "InputDevice.h"
+
+namespace orxonox
+{
+    //! Template parameter collection for the base class
+    struct KeyboardTraits
+    {
+        typedef Keyboard DeviceClass;
+        typedef OIS::Keyboard OISDeviceClass;
+        typedef KeyEvent ButtonType;
+        typedef KeyEvent& ButtonTypeParam;
+        static const OIS::Type OISDeviceValue = OIS::OISKeyboard;
+    };
+
+    /**
+    @brief
+        Wraps around an OIS::Mouse and forwards the input events to
+        a list of input states.
+
+        It also saves the state of the keyboard modifiers (like shift, etc.)
+    */
+    class _CoreExport Keyboard
+        : public InputDeviceTemplated<KeyboardTraits>
+        , public OIS::KeyListener
+    {
+        friend class InputDeviceTemplated<KeyboardTraits>;
+        //! Super class alias
+        typedef InputDeviceTemplated<KeyboardTraits> super;
+
+    public:
+        //! Only resets the keyboard modifiers. Initialising is done in the base class.
+        Keyboard(unsigned int id, OIS::InputManager* oisInputManager) : super(id, oisInputManager), modifiers_(0) { }
+        ~Keyboard() { }
+
+    private:
+        //! Resets the keyboard modifiers
+        void clearBuffersImpl() { this->modifiers_ = 0; }
+        //! Translates the KeyHandle to a KeyEvent
+        KeyEvent& getButtonEventArg(KeyEvent& button)
+        {
+            button.setModifiers(modifiers_);
+            return button;
+        }
+
+        bool keyPressed(const OIS::KeyEvent& arg);
+        bool keyReleased(const OIS::KeyEvent& arg);
+
+        //! Returns the class name as string
+        static std::string getClassNameImpl() { return "Keyboard"; }
+
+        //! Bit mask representing keyboard modifiers
+        int modifiers_;
+    };
+}
+
+#endif /* _Core_Keyboard_H__ */
Index: code/trunk/src/core/input/Mouse.cc
===================================================================
--- code/trunk/src/core/input/Mouse.cc	(revision 3327)
+++ code/trunk/src/core/input/Mouse.cc	(revision 3327)
@@ -0,0 +1,109 @@
+/*
+ *   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 "Mouse.h"
+
+#include <ois/OISMouse.h>
+#include "core/ConsoleCommand.h"
+#include "core/CoreIncludes.h"
+#include "InputState.h"
+
+#ifdef ORXONOX_PLATFORM_LINUX
+// include this as last, X11 seems to define some macros...
+#include <ois/linux/LinuxMouse.h>
+#endif
+
+namespace orxonox
+{
+    Mouse::Mouse(unsigned int id, OIS::InputManager* oisInputManager)
+        : super(id, oisInputManager)
+    {
+        RegisterRootObject(Mouse);
+        this->windowResized(this->getWindowWidth(), this->getWindowHeight());
+
+#ifdef ORXONOX_PLATFORM_LINUX
+        {
+            // Mouse grab console command
+            FunctorMember<Mouse>* functor = createFunctor(&Mouse::grab);
+            functor->setObject(this);
+            this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "grab"), false);
+        }
+        {
+            // Mouse ungrab console command
+            FunctorMember<Mouse>* functor = createFunctor(&Mouse::ungrab);
+            functor->setObject(this);
+            this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "ungrab"), false);
+        }
+#endif
+    }
+
+    //! OIS event handler
+    bool Mouse::mouseMoved(const OIS::MouseEvent &e)
+    {
+        // check for actual moved event
+        if (e.state.X.rel != 0 || e.state.Y.rel != 0)
+        {
+            IntVector2 abs(e.state.X.abs, e.state.Y.abs);
+            IntVector2 rel(e.state.X.rel, e.state.Y.rel);
+            IntVector2 clippingSize(e.state.width, e.state.height);
+            for (unsigned int i = 0; i < inputStates_.size(); ++i)
+                inputStates_[i]->mouseMoved(abs, rel, clippingSize);
+        }
+
+        // check for mouse scrolled event
+        if (e.state.Z.rel != 0)
+        {
+            for (unsigned int i = 0; i < inputStates_.size(); ++i)
+                inputStates_[i]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
+        }
+
+        return true;
+    }
+
+    void Mouse::windowResized(unsigned int newWidth, unsigned int newHeight)
+    {
+        oisDevice_->getMouseState().width  = newWidth;
+        oisDevice_->getMouseState().height = newHeight;
+    }
+
+#ifdef ORXONOX_PLATFORM_LINUX
+    void Mouse::grab()
+    {
+        OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(oisDevice_);
+        assert(linuxMouse);
+        linuxMouse->grab(true);
+    }
+
+    void Mouse::ungrab()
+    {
+        OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(oisDevice_);
+        assert(linuxMouse);
+        linuxMouse->grab(false);
+    }
+#endif
+}
Index: code/trunk/src/core/input/Mouse.h
===================================================================
--- code/trunk/src/core/input/Mouse.h	(revision 3327)
+++ code/trunk/src/core/input/Mouse.h	(revision 3327)
@@ -0,0 +1,98 @@
+/*
+ *   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 _Core_Mouse_H__
+#define _Core_Mouse_H__
+
+#include "InputPrereqs.h"
+
+#include "InputDevice.h"
+#include "core/WindowEventListener.h"
+
+namespace orxonox
+{
+    //! Template parameter collection for the base class
+    struct MouseTraits
+    {
+        typedef Mouse DeviceClass;
+        typedef OIS::Mouse OISDeviceClass;
+        typedef MouseButtonCode::ByEnum ButtonType;
+        typedef MouseButtonCode::ByEnum ButtonTypeParam;
+        static const OIS::Type OISDeviceValue = OIS::OISMouse;
+    };
+
+    /**
+    @brief
+        Wraps around an OIS::Mouse and forwards the input events to
+        a list of input states.
+    */
+    class _CoreExport Mouse
+        : public InputDeviceTemplated<MouseTraits>
+        , public OIS::MouseListener
+        , public WindowEventListener
+    {
+        friend class InputDeviceTemplated<MouseTraits>;
+        //! Super class alias
+        typedef InputDeviceTemplated<MouseTraits> super;
+
+    public:
+        //! Only sets the clipping size. Initialising is done in the base class.
+        Mouse(unsigned int id, OIS::InputManager* oisInputManager);
+        ~Mouse() { }
+
+#ifdef ORXONOX_PLATFORM_LINUX
+        // TODO: Make this a feature rather than a hack
+        void grab();
+        void ungrab();
+#endif
+
+    private:
+        //! OIS event handler
+        bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
+        {
+            super::buttonPressed(static_cast<MouseButtonCode::ByEnum>(id));
+            return true;
+        }
+
+        //! OIS event handler
+        bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
+        {
+            super::buttonReleased(static_cast<MouseButtonCode::ByEnum>(id));
+            return true;
+        }
+
+        bool mouseMoved(const OIS::MouseEvent &arg);
+
+        void windowResized(unsigned int newWidth, unsigned int newHeight);
+
+        // Returns the class name as string
+        static std::string getClassNameImpl() { return "Mouse"; }
+    };
+}
+
+#endif /* _Core_Mouse_H__ */
Index: code/trunk/src/core/input/SimpleInputState.cc
===================================================================
--- code/trunk/src/core/input/SimpleInputState.cc	(revision 3326)
+++ 	(revision )
@@ -1,163 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation; either version 2
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Reto Grieder
- *   Co-authors:
- *      ...
- *
- */
-
-/**
-@file
-@brief
-    Implementation of the SimpleInputState class.
-*/
-
-#include "SimpleInputState.h"
-#include "core/Executor.h"
-
-namespace orxonox
-{
-    SimpleInputState::SimpleInputState()
-        : keyHandler_(0)
-        , mouseHandler_(0)
-        , joyStickHandlerAll_(0)
-    {
-    }
-
-    void SimpleInputState::numberOfJoySticksChanged(unsigned int n)
-    {
-        unsigned int oldSize = joyStickHandler_.size();
-        joyStickHandler_.resize(n);
-
-        if (n > oldSize)
-        {
-            // we have to add the handler in joyStickHandlerAll_ to the joyStickHandler_[>n]
-            for (unsigned int i = oldSize; i < n; ++i)
-            {
-                joyStickHandler_[i] = joyStickHandlerAll_;
-            }
-        }
-        update();
-    }
-
-    void SimpleInputState::keyPressed(const KeyEvent& evt)
-    {
-        if (keyHandler_)
-            keyHandler_->keyPressed(evt);
-    }
-
-    /**
-    @brief
-        Adds a joy stick handler.
-    @param handler
-        Pointer to the handler object.
-    @param joyStickID
-        ID of the joy stick
-    @return
-        True if added, false otherwise.
-    */
-    bool SimpleInputState::setJoyStickHandler(JoyStickHandler* handler, unsigned int joyStickID)
-    {
-        if (joyStickID >= joyStickHandler_.size())
-            return false;
-
-        joyStickHandler_[joyStickID] = handler;
-        update();
-        return true;
-    }
-
-    /**
-    @brief
-        Adds a joy stick handler.
-    @param handler
-        Pointer to the handler object.
-    @return
-        True if added, false if handler already existed.
-    */
-    bool SimpleInputState::setJoyStickHandler(JoyStickHandler* handler)
-    {
-        if (handler == joyStickHandlerAll_)
-            return false;
-
-        joyStickHandlerAll_ = handler;
-        for (unsigned int iJoyStick = 0; iJoyStick < joyStickHandler_.size(); ++iJoyStick)
-            setJoyStickHandler(handler, iJoyStick);
-        update();
-        return true;
-    }
-
-    /**
-    @brief
-        Adds a handler of any kind. dynamic_cast determines to which list it is added.
-    @param handler
-        Pointer to the handler object.
-    @return
-        True if added, false if handler already existed.
-    */
-    bool SimpleInputState::setHandler(InputHandler* handler)
-    {
-        setKeyHandler(dynamic_cast<KeyHandler*>(handler));
-        setMouseHandler(dynamic_cast<MouseHandler*>(handler));
-        return setJoyStickHandler(dynamic_cast<JoyStickHandler*>(handler));
-    }
-
-    void SimpleInputState::update()
-    {
-        // we can use a set to have a list of unique pointers (an object can implement all 3 handlers)
-        std::set<InputHandler*> tempSet;
-        if (keyHandler_)
-            tempSet.insert(keyHandler_);
-        if (mouseHandler_)
-            tempSet.insert(mouseHandler_);
-        for (unsigned int iJoyStick = 0; iJoyStick < joyStickHandler_.size(); iJoyStick++)
-            if (joyStickHandler_[iJoyStick])
-                tempSet.insert(joyStickHandler_[iJoyStick]);
-
-        // copy the content of the map back to the actual vector
-        allHandlers_.clear();
-        for (std::set<InputHandler*>::const_iterator itHandler = tempSet.begin();
-            itHandler != tempSet.end(); itHandler++)
-            allHandlers_.push_back(*itHandler);
-
-        // update the deviceEnabled options
-        setInputDeviceEnabled(InputDevice::Keyboard, (keyHandler_ != 0));
-        setInputDeviceEnabled(InputDevice::Mouse, (mouseHandler_ != 0));
-        for (unsigned int i = 0; i < joyStickHandler_.size(); ++i)
-            setInputDeviceEnabled(2 + i, (joyStickHandler_[i] != 0));
-
-        // inform InputManager that there might be changes in EMPTY_HANDLER situation
-        bHandlersChanged_ = true;
-    }
-
-    void SimpleInputState::onEnter()
-    {
-        if (executorOnEnter_)
-            (*executorOnEnter_)();
-    }
-
-    void SimpleInputState::onLeave()
-    {
-        if (executorOnLeave_)
-            (*executorOnLeave_)();
-    }
-}
Index: code/trunk/src/core/input/SimpleInputState.h
===================================================================
--- code/trunk/src/core/input/SimpleInputState.h	(revision 3326)
+++ 	(revision )
@@ -1,192 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation; either version 2
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Reto Grieder
- *   Co-authors:
- *      ...
- *
- */
-
-/**
-@file
-@brief 
-*/
-
-#ifndef _SimpleInputState_H__
-#define _SimpleInputState_H__
-
-#include "core/CorePrereqs.h"
-
-#include <vector>
-#include <cassert>
-#include "InputInterfaces.h"
-#include "InputState.h"
-
-namespace orxonox
-{
-    class _CoreExport SimpleInputState : public InputState
-    {
-        friend class InputManager;
-
-    public:
-        void setKeyHandler        (KeyHandler* handler) { keyHandler_ = handler; update(); }
-        void setMouseHandler      (MouseHandler* handler) { mouseHandler_ = handler; update(); }
-        bool setJoyStickHandler   (JoyStickHandler* handler, unsigned int joyStickID);
-        bool setJoyStickHandler   (JoyStickHandler* handler);
-        bool setHandler(InputHandler* handler);
-
-    private:
-        SimpleInputState();
-        ~SimpleInputState() { }
-
-        void updateInput(float dt);
-        void updateInput(float dt, unsigned int device);
-
-        void keyPressed (const KeyEvent& evt);
-        void keyReleased(const KeyEvent& evt);
-        void keyHeld    (const KeyEvent& evt);
-
-        void mouseButtonPressed (MouseButtonCode::ByEnum id);
-        void mouseButtonReleased(MouseButtonCode::ByEnum id);
-        void mouseButtonHeld    (MouseButtonCode::ByEnum id);
-        void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
-        void mouseScrolled      (int abs, int rel);
-
-        void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
-        void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
-        void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
-        void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value);
-
-        void update();
-        void numberOfJoySticksChanged(unsigned int n);
-
-        void onEnter();
-        void onLeave();
-
-        KeyHandler*                   keyHandler_;
-        MouseHandler*                 mouseHandler_;
-        std::vector<JoyStickHandler*> joyStickHandler_;
-        JoyStickHandler*              joyStickHandlerAll_;
-        std::vector<InputHandler*>    allHandlers_;
-    };
-
-    inline void SimpleInputState::updateInput(float dt)
-    {
-        for (unsigned int i = 0; i < allHandlers_.size(); ++i)
-        {
-            allHandlers_[i]->updateInput(dt);
-        }
-    }
-
-    inline void SimpleInputState::updateInput(float dt, unsigned int device)
-    {
-        switch (device)
-        {
-        case InputDevice::Keyboard:
-            if (keyHandler_)
-                keyHandler_->updateKey(dt);
-            break;
-
-        case InputDevice::Mouse:
-            if (mouseHandler_)
-                mouseHandler_->updateMouse(dt);
-            break;
-
-        default: // joy sticks
-            if (joyStickHandler_[device - 2])
-                joyStickHandler_[device - 2]->updateJoyStick(dt, device - 2);
-            break;
-        }
-    }
-
-    inline void SimpleInputState::keyReleased(const KeyEvent& evt)
-    {
-        if (keyHandler_)
-            keyHandler_->keyReleased(evt);
-    }
-
-    inline void SimpleInputState::keyHeld(const KeyEvent& evt)
-    {
-        if (keyHandler_)
-            keyHandler_->keyHeld(evt);
-    }
-
-    inline void SimpleInputState::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
-    {
-        if (mouseHandler_)
-            mouseHandler_->mouseMoved(abs, rel, clippingSize);
-    }
-
-    inline void SimpleInputState::mouseScrolled(int abs, int rel)
-    {
-        if (mouseHandler_)
-            mouseHandler_->mouseScrolled(abs, rel);
-    }
-
-    inline void SimpleInputState::mouseButtonPressed(MouseButtonCode::ByEnum id)
-    {
-        if (mouseHandler_)
-            mouseHandler_->mouseButtonPressed(id);
-    }
-
-    inline void SimpleInputState::mouseButtonReleased(MouseButtonCode::ByEnum id)
-    {
-        if (mouseHandler_)
-            mouseHandler_->mouseButtonReleased(id);
-    }
-
-    inline void SimpleInputState::mouseButtonHeld(MouseButtonCode::ByEnum id)
-    {
-        if (mouseHandler_)
-            mouseHandler_->mouseButtonHeld(id);
-    }
-
-    inline void SimpleInputState::joyStickAxisMoved(unsigned int joyStickID, unsigned int axis, float value)
-    {
-        assert(joyStickID < joyStickHandler_.size());
-        if (joyStickHandler_[joyStickID])
-            joyStickHandler_[joyStickID]->joyStickAxisMoved(joyStickID, axis, value);
-    }
-
-    inline void SimpleInputState::joyStickButtonPressed(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
-    {
-        assert(joyStickID < joyStickHandler_.size());
-        if (joyStickHandler_[joyStickID])
-            joyStickHandler_[joyStickID]->joyStickButtonPressed(joyStickID, id);
-    }
-
-    inline void SimpleInputState::joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
-    {
-        assert(joyStickID < joyStickHandler_.size());
-        if (joyStickHandler_[joyStickID])
-            joyStickHandler_[joyStickID]->joyStickButtonReleased(joyStickID, id);
-    }
-
-    inline void SimpleInputState::joyStickButtonHeld(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
-    {
-        assert(joyStickID < joyStickHandler_.size());
-        if (joyStickHandler_[joyStickID])
-            joyStickHandler_[joyStickID]->joyStickButtonHeld(joyStickID, id);
-    }
-}
-
-#endif /* _SimpleInputState_H__ */
Index: code/trunk/src/orxonox/GraphicsManager.cc
===================================================================
--- code/trunk/src/orxonox/GraphicsManager.cc	(revision 3326)
+++ code/trunk/src/orxonox/GraphicsManager.cc	(revision 3327)
@@ -63,6 +63,6 @@
 #include "core/Game.h"
 #include "core/GameMode.h"
+#include "core/WindowEventListener.h"
 #include "tools/ParticleInterface.h"
-#include "interfaces/WindowEventListener.h"
 
 // HACK!
@@ -73,10 +73,15 @@
     using boost::shared_ptr;
 
-    class _OrxonoxExport OgreWindowEventListener : public Ogre::WindowEventListener
-    {
-        void windowResized     (Ogre::RenderWindow* rw);
-        void windowFocusChange (Ogre::RenderWindow* rw);
-        void windowClosed      (Ogre::RenderWindow* rw);
-        //void windowMoved       (Ogre::RenderWindow* rw);
+    class OgreWindowEventListener : public Ogre::WindowEventListener
+    {
+    public:
+        void windowResized     (Ogre::RenderWindow* rw)
+            { orxonox::WindowEventListener::resizeWindow(rw->getWidth(), rw->getHeight()); }
+        void windowFocusChange (Ogre::RenderWindow* rw)
+            { orxonox::WindowEventListener::changeWindowFocus(); }
+        void windowClosed      (Ogre::RenderWindow* rw)
+            { orxonox::Game::getInstance().stop(); }
+        void windowMoved       (Ogre::RenderWindow* rw)
+            { orxonox::WindowEventListener::moveWindow(); }
     };
 
@@ -347,4 +352,5 @@
 
         this->renderWindow_ = ogreRoot_->initialise(true, "Orxonox");
+        this->ogreWindowEventListener_->windowResized(renderWindow_);
 
         Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, ogreWindowEventListener_);
@@ -418,23 +424,3 @@
         this->renderWindow_->writeContentsToTimestampedFile(Core::getLogPathString() + "screenShot_", ".jpg");
     }
-
-
-    /****** OgreWindowEventListener ******/
-
-    void OgreWindowEventListener::windowResized(Ogre::RenderWindow* rw)
-    {
-        for (ObjectList<orxonox::WindowEventListener>::iterator it
-            = ObjectList<orxonox::WindowEventListener>::begin(); it; ++it)
-            it->windowResized(rw->getWidth(), rw->getHeight());
-    }
-    void OgreWindowEventListener::windowFocusChange(Ogre::RenderWindow* rw)
-    {
-        for (ObjectList<orxonox::WindowEventListener>::iterator it
-            = ObjectList<orxonox::WindowEventListener>::begin(); it; ++it)
-            it->windowFocusChanged();
-    }
-    void OgreWindowEventListener::windowClosed(Ogre::RenderWindow* rw)
-    {
-        Game::getInstance().stop();
-    }
 }
Index: code/trunk/src/orxonox/OrxonoxPrereqs.h
===================================================================
--- code/trunk/src/orxonox/OrxonoxPrereqs.h	(revision 3326)
+++ code/trunk/src/orxonox/OrxonoxPrereqs.h	(revision 3327)
@@ -92,4 +92,5 @@
     class Level;
     class Scene;
+    class Tickable;
 
     class AddQuest;
Index: code/trunk/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSGraphics.cc	(revision 3326)
+++ code/trunk/src/orxonox/gamestates/GSGraphics.cc	(revision 3327)
@@ -38,14 +38,14 @@
 #include <OgreRenderWindow.h>
 
-#include "core/ConfigValueIncludes.h"
+#include "util/Convert.h"
 #include "core/Clock.h"
+#include "core/CommandExecutor.h"
 #include "core/ConsoleCommand.h"
 #include "core/Core.h"
-#include "core/CoreIncludes.h"
 #include "core/Game.h"
 #include "core/GameMode.h"
 #include "core/input/InputManager.h"
 #include "core/input/KeyBinder.h"
-#include "core/input/SimpleInputState.h"
+#include "core/input/InputState.h"
 #include "core/Loader.h"
 #include "core/XMLFile.h"
@@ -70,18 +70,7 @@
         , debugOverlay_(0)
     {
-        RegisterRootObject(GSGraphics);
     }
 
     GSGraphics::~GSGraphics()
-    {
-    }
-
-    /**
-    @brief
-        this function does nothing
-
-        Indeed. Here goes nothing.
-    */
-    void GSGraphics::setConfigValues()
     {
     }
@@ -106,6 +95,4 @@
         GameMode::setShowsGraphics(true);
 
-        setConfigValues();
-
         // Load OGRE including the render window
         this->graphicsManager_ = new GraphicsManager();
@@ -122,9 +109,8 @@
 
         // Calls the InputManager which sets up the input devices.
-        inputManager_ = new InputManager();
-        inputManager_->initialise(windowHnd, renderWindow->getWidth(), renderWindow->getHeight(), true);
+        inputManager_ = new InputManager(windowHnd);
 
         // load master key bindings
-        masterInputState_ = InputManager::getInstance().createInputState<SimpleInputState>("master", true);
+        masterInputState_ = InputManager::getInstance().createInputState("master", true);
         masterKeyBinder_ = new KeyBinder();
         masterKeyBinder_->loadBindings("masterKeybindings.ini");
@@ -136,5 +122,5 @@
         // Load the InGameConsole
         console_ = new InGameConsole();
-        console_->initialise(renderWindow->getWidth(), renderWindow->getHeight());
+        console_->initialise();
 
         // load the CEGUI interface
@@ -149,5 +135,5 @@
 
         // enable master input
-        InputManager::getInstance().requestEnterState("master");
+        InputManager::getInstance().enterState("master");
     }
 
@@ -169,5 +155,5 @@
 
         masterInputState_->setHandler(0);
-        InputManager::getInstance().requestDestroyState("master");
+        InputManager::getInstance().destroyState("master");
         delete this->masterKeyBinder_;
 
@@ -232,33 +218,3 @@
         this->graphicsManager_->update(time);
     }
-
-    /**
-    @brief
-        Window has resized.
-    @param rw
-        The render window it occured in
-    @note
-        GraphicsManager has a render window stored itself. This is the same
-        as rw. But we have to be careful when using multiple render windows!
-    */
-    void GSGraphics::windowResized(unsigned int newWidth, unsigned int newHeight)
-    {
-        // OIS needs this under linux even if we only use relative input measurement.
-        if (this->inputManager_)
-            this->inputManager_->setWindowExtents(newWidth, newHeight);
-    }
-
-    /**
-    @brief
-        Window focus has changed.
-    @param rw
-        The render window it occured in
-    */
-    void GSGraphics::windowFocusChanged()
-    {
-        // instruct InputManager to clear the buffers (core library so we cannot use the interface)
-        if (this->inputManager_)
-            this->inputManager_->clearBuffers();
-    }
-
 }
Index: code/trunk/src/orxonox/gamestates/GSGraphics.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSGraphics.h	(revision 3326)
+++ code/trunk/src/orxonox/gamestates/GSGraphics.h	(revision 3327)
@@ -37,7 +37,5 @@
 
 #include "OrxonoxPrereqs.h"
-
 #include "core/GameState.h"
-#include "interfaces/WindowEventListener.h"
 
 namespace orxonox
@@ -49,10 +47,9 @@
         This game state is only left out if we start a dedicated server where no graphics are present.
     */
-    class _OrxonoxExport GSGraphics : public GameState, public WindowEventListener
+    class _OrxonoxExport GSGraphics : public GameState
     {
     public:
         GSGraphics(const GameStateConstrParams& params);
         ~GSGraphics();
-        void setConfigValues();
 
         void activate();
@@ -63,8 +60,4 @@
 
     private:
-        // Window events from WindowEventListener
-        void windowResized(unsigned int newWidth, unsigned int newHeight);
-        void windowFocusChanged();
-
         // managed singletons
         InputManager*         inputManager_;        //!< Reference to input management
@@ -75,5 +68,5 @@
 
         KeyBinder*            masterKeyBinder_;     //!< Key binder for master key bindings
-        SimpleInputState*     masterInputState_;    //!< Special input state for master input
+        InputState*           masterInputState_;    //!< Special input state for master input
         XMLFile*              debugOverlay_;
         ConsoleCommand*       ccToggleGUI_;         //!< Console command to toggle GUI
Index: code/trunk/src/orxonox/gamestates/GSLevel.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSLevel.cc	(revision 3326)
+++ code/trunk/src/orxonox/gamestates/GSLevel.cc	(revision 3327)
@@ -31,5 +31,5 @@
 
 #include "core/input/InputManager.h"
-#include "core/input/SimpleInputState.h"
+#include "core/input/InputState.h"
 #include "core/input/KeyBinder.h"
 #include "core/Clock.h"
@@ -90,13 +90,13 @@
         if (GameMode::showsGraphics())
         {
-            gameInputState_ = InputManager::getInstance().createInputState<SimpleInputState>("game");
+            gameInputState_ = InputManager::getInstance().createInputState("game");
             keyBinder_ = new KeyBinder();
             keyBinder_->loadBindings("keybindings.ini");
             gameInputState_->setHandler(keyBinder_);
 
-            guiMouseOnlyInputState_ = InputManager::getInstance().createInputState<SimpleInputState>("guiMouseOnly");
+            guiMouseOnlyInputState_ = InputManager::getInstance().createInputState("guiMouseOnly");
             guiMouseOnlyInputState_->setMouseHandler(GUIManager::getInstancePtr());
 
-            guiKeysOnlyInputState_ = InputManager::getInstance().createInputState<SimpleInputState>("guiKeysOnly");
+            guiKeysOnlyInputState_ = InputManager::getInstance().createInputState("guiKeysOnly");
             guiKeysOnlyInputState_->setKeyHandler(GUIManager::getInstancePtr());
 
@@ -134,5 +134,5 @@
 
             // level is loaded: we can start capturing the input
-            InputManager::getInstance().requestEnterState("game");
+            InputManager::getInstance().enterState("game");
         }
     }
@@ -144,5 +144,5 @@
             GUIManager::getInstance().showGUI("inGameTest");
             GUIManager::getInstance().executeCode("showCursor()");
-            InputManager::getInstance().requestEnterState("guiMouseOnly");
+            InputManager::getInstance().enterState("guiMouseOnly");
         }
         else
@@ -150,5 +150,5 @@
             GUIManager::getInstance().executeCode("hideGUI(\"inGameTest\")");
             GUIManager::getInstance().executeCode("hideCursor()");
-            InputManager::getInstance().requestLeaveState("guiMouseOnly");
+            InputManager::getInstance().leaveState("guiMouseOnly");
         }
     }
@@ -178,5 +178,5 @@
 
         if (GameMode::showsGraphics())
-            InputManager::getInstance().requestLeaveState("game");
+            InputManager::getInstance().leaveState("game");
 
         if (GameMode::isMaster())
@@ -218,5 +218,5 @@
             guiMouseOnlyInputState_->setHandler(0);
             guiKeysOnlyInputState_->setHandler(0);
-            InputManager::getInstance().requestDestroyState("game");
+            InputManager::getInstance().destroyState("game");
             if (this->keyBinder_)
             {
@@ -286,5 +286,5 @@
                 {
                     COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl;
-                    InputManager::getInstance().requestEnterState("detector");
+                    InputManager::getInstance().enterState("detector");
                     bindingString = command;
                     bTemporarySaved = bTemporary;
@@ -301,5 +301,5 @@
                     COUT(0) << "Binding string \"" << bindingString << "\" on key '" << name << "'" << std::endl;
                     this->keyBinder_->setBinding(bindingString, name, bTemporarySaved);
-                    InputManager::getInstance().requestLeaveState("detector");
+                    InputManager::getInstance().leaveState("detector");
                     bound = true;
                 }
Index: code/trunk/src/orxonox/gamestates/GSLevel.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSLevel.h	(revision 3326)
+++ code/trunk/src/orxonox/gamestates/GSLevel.h	(revision 3327)
@@ -63,7 +63,7 @@
 
         KeyBinder*            keyBinder_;               //!< tool that loads and manages the input bindings
-        SimpleInputState*     gameInputState_;          //!< input state for normal ingame playing
-        SimpleInputState*     guiMouseOnlyInputState_;  //!< input state if we only need the mouse to use the GUI
-        SimpleInputState*     guiKeysOnlyInputState_;   //!< input state if we only need the keys to use the GUI
+        InputState*           gameInputState_;          //!< input state for normal ingame playing
+        InputState*           guiMouseOnlyInputState_;  //!< input state if we only need the mouse to use the GUI
+        InputState*           guiKeysOnlyInputState_;   //!< input state if we only need the keys to use the GUI
         Radar*                radar_;                   //!< represents the Radar (not the HUD part)
         CameraManager*        cameraManager_;           //!< camera manager for this level
Index: code/trunk/src/orxonox/gamestates/GSMainMenu.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSMainMenu.cc	(revision 3326)
+++ code/trunk/src/orxonox/gamestates/GSMainMenu.cc	(revision 3327)
@@ -32,5 +32,5 @@
 
 #include "core/input/InputManager.h"
-#include "core/input/SimpleInputState.h"
+#include "core/input/InputState.h"
 #include "core/Game.h"
 #include "core/Clock.h"
@@ -57,7 +57,7 @@
     void GSMainMenu::activate()
     {
-        inputState_ = InputManager::getInstance().createInputState<SimpleInputState>("mainMenu");
+        inputState_ = InputManager::getInstance().createInputState("mainMenu");
         inputState_->setHandler(GUIManager::getInstancePtr());
-        inputState_->setJoyStickHandler(&InputManager::EMPTY_HANDLER);
+        inputState_->setJoyStickHandler(&InputHandler::EMPTY);
 
         // create an empty Scene
@@ -96,5 +96,5 @@
         }
 
-        InputManager::getInstance().requestEnterState("mainMenu");
+        InputManager::getInstance().enterState("mainMenu");
 
         this->ambient_ = new SoundMainMenu();
@@ -106,6 +106,6 @@
         delete this->ambient_;
 
-        InputManager::getInstance().requestLeaveState("mainMenu");
-        InputManager::getInstance().requestDestroyState("mainMenu");
+        InputManager::getInstance().leaveState("mainMenu");
+        InputManager::getInstance().destroyState("mainMenu");
 
         GUIManager::getInstance().setCamera(0);
Index: code/trunk/src/orxonox/gamestates/GSMainMenu.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSMainMenu.h	(revision 3326)
+++ code/trunk/src/orxonox/gamestates/GSMainMenu.h	(revision 3327)
@@ -53,5 +53,5 @@
 
     private:
-        SimpleInputState* inputState_;
+        InputState*       inputState_;
         Scene*            scene_;
         Ogre::Camera*     camera_;
Index: code/trunk/src/orxonox/gui/GUIManager.cc
===================================================================
--- code/trunk/src/orxonox/gui/GUIManager.cc	(revision 3326)
+++ code/trunk/src/orxonox/gui/GUIManager.cc	(revision 3327)
@@ -69,5 +69,5 @@
 	    void logEvent(const CEGUI::String& message, CEGUI::LoggingLevel level = CEGUI::Standard)
         {
-            int orxonoxLevel;
+            int orxonoxLevel = CEGUI::Standard;
             switch (level)
             {
@@ -366,9 +366,10 @@
     void GUIManager::keyPressed(const KeyEvent& evt)
     {
-        guiSystem_->injectKeyDown(evt.key); guiSystem_->injectChar(evt.text);
+        guiSystem_->injectKeyDown(evt.getKeyCode());
+        guiSystem_->injectChar(evt.getText());
     }
     void GUIManager::keyReleased(const KeyEvent& evt)
     {
-        guiSystem_->injectKeyUp(evt.key);
+        guiSystem_->injectKeyUp(evt.getKeyCode());
     }
 
@@ -382,5 +383,5 @@
         It is for CEGUI to process the event.
     */
-    void GUIManager::mouseButtonPressed(MouseButtonCode::ByEnum id)
+    void GUIManager::buttonPressed(MouseButtonCode::ByEnum id)
     {
         try
@@ -404,5 +405,5 @@
         It is for CEGUI to process the event.
     */
-    void GUIManager::mouseButtonReleased(MouseButtonCode::ByEnum id)
+    void GUIManager::buttonReleased(MouseButtonCode::ByEnum id)
     {
         try
Index: code/trunk/src/orxonox/gui/GUIManager.h
===================================================================
--- code/trunk/src/orxonox/gui/GUIManager.h	(revision 3326)
+++ code/trunk/src/orxonox/gui/GUIManager.h	(revision 3327)
@@ -44,5 +44,5 @@
 
 #include "util/OgreForwardRefs.h"
-#include "core/input/InputInterfaces.h"
+#include "core/input/InputHandler.h"
 
 // tolua_begin
@@ -62,5 +62,5 @@
     class _OrxonoxExport GUIManager
 // tolua_end
-        : public KeyHandler, public MouseHandler
+        : public InputHandler
 // tolua_begin
     {
@@ -106,16 +106,10 @@
         void keyPressed (const KeyEvent& evt);
         void keyReleased(const KeyEvent& evt);
-        void keyHeld    (const KeyEvent& evt) { }
 
         // mouseHandler functions
-        void mouseButtonPressed (MouseButtonCode::ByEnum id);
-        void mouseButtonReleased(MouseButtonCode::ByEnum id);
-        void mouseButtonHeld    (MouseButtonCode::ByEnum id) { }
-        void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
-        void mouseScrolled      (int abs, int rel);
-
-        void updateInput(float dt)  { }
-        void updateKey  (float dt)  { }
-        void updateMouse(float dt)  { }
+        void buttonPressed (MouseButtonCode::ByEnum id);
+        void buttonReleased(MouseButtonCode::ByEnum id);
+        void mouseMoved    (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
+        void mouseScrolled (int abs, int rel);
 
         Ogre::RenderWindow*         renderWindow_;      //!< Ogre's render window to give CEGUI access to it
Index: code/trunk/src/orxonox/interfaces/InterfaceCompilation.cc
===================================================================
--- code/trunk/src/orxonox/interfaces/InterfaceCompilation.cc	(revision 3326)
+++ code/trunk/src/orxonox/interfaces/InterfaceCompilation.cc	(revision 3327)
@@ -40,5 +40,4 @@
 #include "Tickable.h"
 #include "TimeFactorListener.h"
-#include "WindowEventListener.h"
 
 #include "core/CoreIncludes.h"
@@ -103,15 +102,4 @@
 
     //----------------------------
-    // WindowEventListener
-    //----------------------------
-    /**
-        @brief Constructor for the WindowEventListener.
-    */
-    WindowEventListener::WindowEventListener()
-    {
-        RegisterRootObject(WindowEventListener);
-    }
-
-    //----------------------------
     // Rewardable
     //----------------------------
Index: code/trunk/src/orxonox/interfaces/WindowEventListener.h
===================================================================
--- code/trunk/src/orxonox/interfaces/WindowEventListener.h	(revision 3326)
+++ 	(revision )
@@ -1,57 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation; either version 2
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Reto Grieder
- *   Co-authors:
- *      ...
- *
- */
-
-#ifndef _WindowEventListener_H__
-#define _WindowEventListener_H__
-
-#include "OrxonoxPrereqs.h"
-#include "core/OrxonoxClass.h"
-
-namespace orxonox
-{
-    /**
-        @brief Interface for receiving window events.
-    */
-    class _OrxonoxExport WindowEventListener : virtual public OrxonoxClass
-    {
-        public:
-            WindowEventListener();
-            virtual ~WindowEventListener() { }
-
-            /** Window has moved position */
-            virtual void windowMoved() { }
-
-            /** Window has resized */
-            virtual void windowResized(unsigned int newWidth, unsigned int newHeight) { }
-
-            /** Window has lost/gained focus */
-            virtual void windowFocusChanged() { }
-    };
-}
-
-#endif /* _WindowEventListener_H__ */
Index: code/trunk/src/orxonox/objects/pickup/PickupInventory.cc
===================================================================
--- code/trunk/src/orxonox/objects/pickup/PickupInventory.cc	(revision 3326)
+++ code/trunk/src/orxonox/objects/pickup/PickupInventory.cc	(revision 3327)
@@ -88,5 +88,5 @@
             GUIManager::getInstance().executeCode("hideGUI(\"PickupInventory\")");
             GUIManager::getInstance().executeCode("hideCursor()");
-            InputManager::getInstance().requestLeaveState("guiMouseOnly");
+            InputManager::getInstance().leaveState("guiMouseOnly");
         }
         else
@@ -94,5 +94,5 @@
             GUIManager::getInstance().showGUI("PickupInventory");
             GUIManager::getInstance().executeCode("showCursor()");
-            InputManager::getInstance().requestEnterState("guiMouseOnly");
+            InputManager::getInstance().enterState("guiMouseOnly");
         }
         PickupInventory::getSingleton()->setVisible(!PickupInventory::getSingleton()->isVisible());
Index: code/trunk/src/orxonox/overlays/GUIOverlay.cc
===================================================================
--- code/trunk/src/orxonox/overlays/GUIOverlay.cc	(revision 3326)
+++ code/trunk/src/orxonox/overlays/GUIOverlay.cc	(revision 3327)
@@ -70,5 +70,5 @@
             str = out.str();
             GUIManager::getInstance().executeCode("showCursor()");
-            InputManager::getInstance().requestEnterState("guiMouseOnly");
+            InputManager::getInstance().enterState("guiMouseOnly");
             GUIManager::getInstance().executeCode("showGUI(\"" + this->guiName_ + "\", " + str + ")");
         }
@@ -77,5 +77,5 @@
             GUIManager::getInstance().executeCode("hideGUI(\"" + this->guiName_ + "\")");
             GUIManager::getInstance().executeCode("hideCursor()");
-            InputManager::getInstance().requestLeaveState("guiMouseOnly");
+            InputManager::getInstance().leaveState("guiMouseOnly");
         }
     }
Index: code/trunk/src/orxonox/overlays/OrxonoxOverlay.cc
===================================================================
--- code/trunk/src/orxonox/overlays/OrxonoxOverlay.cc	(revision 3326)
+++ code/trunk/src/orxonox/overlays/OrxonoxOverlay.cc	(revision 3327)
@@ -47,5 +47,4 @@
 #include "core/XMLPort.h"
 #include "core/ConsoleCommand.h"
-#include "GraphicsManager.h"
 
 namespace orxonox
@@ -81,6 +80,5 @@
 
         // Get aspect ratio from the render window. Later on, we get informed automatically
-        Ogre::RenderWindow* defaultWindow = GraphicsManager::getInstance().getRenderWindow();
-        this->windowAspectRatio_ = static_cast<float>(defaultWindow->getWidth()) / defaultWindow->getHeight();
+        this->windowAspectRatio_ = static_cast<float>(this->getWindowWidth()) / this->getWindowHeight();
         this->sizeCorrectionChanged();
 
Index: code/trunk/src/orxonox/overlays/OrxonoxOverlay.h
===================================================================
--- code/trunk/src/orxonox/overlays/OrxonoxOverlay.h	(revision 3326)
+++ code/trunk/src/orxonox/overlays/OrxonoxOverlay.h	(revision 3327)
@@ -42,5 +42,5 @@
 #include "util/OgreForwardRefs.h"
 #include "core/BaseObject.h"
-#include "interfaces/WindowEventListener.h"
+#include "core/WindowEventListener.h"
 
 namespace orxonox
Index: code/trunk/src/orxonox/overlays/console/InGameConsole.cc
===================================================================
--- code/trunk/src/orxonox/overlays/console/InGameConsole.cc	(revision 3326)
+++ code/trunk/src/orxonox/overlays/console/InGameConsole.cc	(revision 3327)
@@ -49,5 +49,5 @@
 #include "core/ConsoleCommand.h"
 #include "core/input/InputManager.h"
-#include "core/input/SimpleInputState.h"
+#include "core/input/InputState.h"
 #include "core/input/InputBuffer.h"
 
@@ -98,5 +98,5 @@
 
         // destroy the input state previously created (InputBuffer gets destroyed by the Shell)
-        InputManager::getInstance().requestDestroyState("console");
+        InputManager::getInstance().destroyState("console");
 
         Ogre::OverlayManager* ovMan = Ogre::OverlayManager::getSingletonPtr();
@@ -158,6 +158,6 @@
             if (bHidesAllInput_)
             {
-                inputState_->setMouseHandler(&InputManager::EMPTY_HANDLER);
-                inputState_->setJoyStickHandler(&InputManager::EMPTY_HANDLER);
+                inputState_->setMouseHandler(&InputHandler::EMPTY);
+                inputState_->setJoyStickHandler(&InputHandler::EMPTY);
             }
             else
@@ -172,8 +172,8 @@
         @brief Initializes the InGameConsole.
     */
-    void InGameConsole::initialise(int windowWidth, int windowHeight)
+    void InGameConsole::initialise()
     {
         // create the corresponding input state
-        inputState_ = InputManager::getInstance().createInputState<SimpleInputState>("console", false, false, InputStatePriority::Console);
+        inputState_ = InputManager::getInstance().createInputState("console", false, false, InputStatePriority::Console);
         inputState_->setKeyHandler(Shell::getInstance().getInputBuffer());
         bHidesAllInputChanged();
@@ -248,5 +248,5 @@
         this->consoleOverlayContainer_->addChild(this->consoleOverlayNoise_);
 
-        this->windowResized(windowWidth, windowHeight);
+        this->windowResized(this->getWindowWidth(), this->getWindowWidth());
 
         // move overlay "above" the top edge of the screen
@@ -507,5 +507,5 @@
         {
             this->bActive_ = true;
-            InputManager::getInstance().requestEnterState("console");
+            InputManager::getInstance().enterState("console");
             Shell::getInstance().registerListener(this);
 
@@ -529,5 +529,5 @@
         {
             this->bActive_ = false;
-            InputManager::getInstance().requestLeaveState("console");
+            InputManager::getInstance().leaveState("console");
             Shell::getInstance().unregisterListener(this);
 
Index: code/trunk/src/orxonox/overlays/console/InGameConsole.h
===================================================================
--- code/trunk/src/orxonox/overlays/console/InGameConsole.h	(revision 3326)
+++ code/trunk/src/orxonox/overlays/console/InGameConsole.h	(revision 3327)
@@ -36,5 +36,5 @@
 #include "util/OgreForwardRefs.h"
 #include "core/Shell.h"
-#include "interfaces/WindowEventListener.h"
+#include "core/WindowEventListener.h"
 
 namespace orxonox
@@ -46,5 +46,5 @@
         ~InGameConsole();
 
-        void initialise(int windowWidth, int windowHeight);
+        void initialise();
         void destroy();
         void setConfigValues();
@@ -101,5 +101,5 @@
 
         // input related
-        SimpleInputState* inputState_;
+        InputState* inputState_;
 
         // config values
Index: code/trunk/src/util/StringUtils.cc
===================================================================
--- code/trunk/src/util/StringUtils.cc	(revision 3326)
+++ code/trunk/src/util/StringUtils.cc	(revision 3327)
@@ -490,3 +490,24 @@
         return std::string::npos;
     }
+
+    /**
+        @brief Replaces individual charaters
+        @param str String to be manipulated
+        @param target Character to be replaced
+        @param replacement Replacement character
+        @return Number of replacements
+    */
+    _UtilExport size_t replaceCharacters(std::string& str, char target, char replacement)
+    {
+        size_t j = 0;
+        for (size_t i = 0; i < str.size(); ++i)
+        {
+            if (str[i] == target)
+            {
+                str[i] = replacement;
+                ++j;
+            }
+        }
+        return j;
+    }
 }
Index: code/trunk/src/util/StringUtils.h
===================================================================
--- code/trunk/src/util/StringUtils.h	(revision 3326)
+++ code/trunk/src/util/StringUtils.h	(revision 3327)
@@ -77,4 +77,6 @@
     _UtilExport size_t      getCommentPosition(const std::string& str);
     _UtilExport size_t      getNextCommentPosition(const std::string& str, size_t start = 0);
+
+    _UtilExport size_t      replaceCharacters(std::string& str, char target, char replacement);
 }
 
