Index: /code/branches/core4/src/core/CorePrereqs.h
===================================================================
--- /code/branches/core4/src/core/CorePrereqs.h	(revision 3273)
+++ /code/branches/core4/src/core/CorePrereqs.h	(revision 3274)
@@ -176,15 +176,18 @@
     class HalfAxis;
     class InputBuffer;
+    class InputDevice;
+    template <class Traits>
+    class InputDeviceTemplated;
+    class InputHandler;
     class InputManager;
     class InputState;
     class JoyStick;
-    class JoyStickHandler;
-    class MouseHandler;
+    class Mouse;
+    class Keyboard;
     class KeyBinder;
     class KeyDetector;
-    class KeyHandler;
     class ParamCommand;
     class SimpleCommand;
-    class SimpleInputState;
+
 }
 
Index: /code/branches/core4/src/core/OrxonoxClass.h
===================================================================
--- /code/branches/core4/src/core/OrxonoxClass.h	(revision 3273)
+++ /code/branches/core4/src/core/OrxonoxClass.h	(revision 3274)
@@ -40,4 +40,5 @@
 #include "CorePrereqs.h"
 #include <set>
+#include <vector>
 
 namespace orxonox
Index: /code/branches/core4/src/core/input/Button.h
===================================================================
--- /code/branches/core4/src/core/input/Button.h	(revision 3273)
+++ /code/branches/core4/src/core/input/Button.h	(revision 3274)
@@ -36,5 +36,5 @@
 #define _Button_H__
 
-#include "core/CorePrereqs.h"
+#include "InputPrereqs.h"
 
 #include <string>
Index: /code/branches/core4/src/core/input/CMakeLists.txt
===================================================================
--- /code/branches/core4/src/core/input/CMakeLists.txt	(revision 3273)
+++ /code/branches/core4/src/core/input/CMakeLists.txt	(revision 3274)
@@ -5,8 +5,10 @@
   InputCommands.cc
   InputManager.cc
+  InputState.cc
   JoyStick.cc
-  JoyStickDeviceNumberListener.cc
+  JoyStickQuantityListener.cc
   KeyBinder.cc
+  Keyboard.cc
   KeyDetector.cc
-  SimpleInputState.cc
+  Mouse.cc
 )
Index: /code/branches/core4/src/core/input/HalfAxis.h
===================================================================
--- /code/branches/core4/src/core/input/HalfAxis.h	(revision 3273)
+++ /code/branches/core4/src/core/input/HalfAxis.h	(revision 3274)
@@ -36,5 +36,5 @@
 #define _HalfAxis_H__
 
-#include "core/CorePrereqs.h"
+#include "InputPrereqs.h"
 
 #include "Button.h"
Index: /code/branches/core4/src/core/input/InputBuffer.cc
===================================================================
--- /code/branches/core4/src/core/input/InputBuffer.cc	(revision 3273)
+++ /code/branches/core4/src/core/input/InputBuffer.cc	(revision 3274)
@@ -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((char)evt.text);
+        this->insert((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/branches/core4/src/core/input/InputBuffer.h
===================================================================
--- /code/branches/core4/src/core/input/InputBuffer.h	(revision 3273)
+++ /code/branches/core4/src/core/input/InputBuffer.h	(revision 3274)
@@ -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/branches/core4/src/core/input/InputCommands.h
===================================================================
--- /code/branches/core4/src/core/input/InputCommands.h	(revision 3273)
+++ /code/branches/core4/src/core/input/InputCommands.h	(revision 3274)
@@ -36,5 +36,5 @@
 #define _InputCommands_H__
 
-#include "core/CorePrereqs.h"
+#include "InputPrereqs.h"
 #include "core/CommandEvaluation.h"
 
Index: /code/branches/core4/src/core/input/InputDevice.h
===================================================================
--- /code/branches/core4/src/core/input/InputDevice.h	(revision 3274)
+++ /code/branches/core4/src/core/input/InputDevice.h	(revision 3274)
@@ -0,0 +1,215 @@
+/*
+ *   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 _InputDevice_H__
+#define _InputDevice_H__
+
+#include "InputPrereqs.h"
+
+#include <vector>
+#include <boost/foreach.hpp>
+#include <ois/OISInputManager.h>
+
+#include "util/Debug.h"
+#include "core/Clock.h"
+// TODO: Try to remove this
+#include "InputManager.h"
+#include "InputState.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+    */
+    class InputDevice
+    {
+        friend class InputManager;
+
+    public:
+        InputDevice(unsigned int id) : bCalibrating_(false), id_(id) { }
+        virtual ~InputDevice() { }
+        virtual std::string getClassName() = 0;
+        virtual void update(const Clock& time) = 0;
+        virtual void clearBuffers() = 0;
+
+        void startCalibration()
+        {
+            bCalibrating_ = true;
+            this->calibrationStarted();
+        }
+
+        void stopCalibration()
+        {
+            this->calibrationStopped();
+            bCalibrating_ = false;
+        }
+
+        unsigned int getDeviceID() { return this->id_; }
+
+    protected:
+        virtual void calibrationStarted() { }
+        virtual void calibrationStopped() { }
+        bool isCalibrating() { return bCalibrating_; }
+
+        // InputState handling
+        std::vector<InputState*> inputStates_;
+
+    private:
+        InputDevice(const InputDevice& rhs);
+
+        std::vector<InputState*>& getStateListRef()
+        {
+            return this->inputStates_;
+        }
+
+        bool bCalibrating_;
+        const unsigned int id_;
+    };
+
+    /**
+    @brief
+    */
+    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:
+        InputDeviceTemplated(unsigned int id)
+            : InputDevice(id)
+        {
+            OIS::InputManager* system = InputManager::getInstance().getInputSystem();
+            oisDevice_ = static_cast<OISDeviceClass*>(system->createInputObject(OISDeviceValue, true));
+            oisDevice_->setEventCallback(static_cast<DeviceClass*>(this));
+            COUT(4) << "Instantiated a " << this->getClassName() << std::endl;
+        }
+
+        virtual ~InputDeviceTemplated()
+        {
+            try
+            {
+                InputManager::getInstance().getInputSystem()->destroyInputObject(oisDevice_);
+            }
+            catch (...)
+            {
+                COUT(1) << this->getClassName() << " destruction failed! Potential resource leak!" << std::endl;
+            }
+        }
+
+        OISDeviceClass* getOISDevice()
+        {
+            return this->oisDevice_;
+        }
+
+        std::string getClassName()
+        {
+            return InputDeviceNames::values[OISDeviceValue];
+        }
+
+        void update(const Clock& time)
+        {
+            oisDevice_->capture();
+
+            if (!this->isCalibrating())
+            {
+                // 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);
+        }
+
+        void clearBuffers()
+        {
+            pressedButtons_.clear();
+            static_cast<DeviceClass*>(this)->clearBuffersImpl();
+        }
+
+    protected:
+        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));
+        }
+
+        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));
+        }
+
+        OISDeviceClass* oisDevice_;
+
+    private:
+        void clearBuffersImpl() { } //!< Fallback dummy function for static polymorphism
+        void updateImpl(const Clock& time) { } //!< Fallback dummy function for static polymorphism
+        //!< Fallback dummy function for static polymorphism
+        ButtonType& getButtonEventArg(ButtonType& button) { return button; }
+
+        std::vector<ButtonType> pressedButtons_;
+    };
+}
+
+#endif /* _InputDevice_H__ */
Index: /code/branches/core4/src/core/input/InputHandler.h
===================================================================
--- /code/branches/core4/src/core/input/InputHandler.h	(revision 3274)
+++ /code/branches/core4/src/core/input/InputHandler.h	(revision 3274)
@@ -0,0 +1,89 @@
+/*
+ *   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 _InputHandler_H__
+#define _InputHandler_H__
+
+#include "InputPrereqs.h"
+#include "util/Math.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+    */
+    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) { }
+
+        static InputHandler EMPTY;
+    };
+}
+
+#endif /* _InputHandler_H__ */
Index: de/branches/core4/src/core/input/InputInterfaces.h
===================================================================
--- /code/branches/core4/src/core/input/InputInterfaces.h	(revision 3273)
+++ 	(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/branches/core4/src/core/input/InputManager.cc
===================================================================
--- /code/branches/core4/src/core/input/InputManager.cc	(revision 3273)
+++ /code/branches/core4/src/core/input/InputManager.cc	(revision 3274)
@@ -50,11 +50,14 @@
 #include "core/ConsoleCommand.h"
 #include "core/CommandLine.h"
+#include "core/Functor.h"
 
 #include "InputBuffer.h"
 #include "KeyDetector.h"
+#include "InputHandler.h"
 #include "InputState.h"
-#include "SimpleInputState.h"
-#include "JoyStickDeviceNumberListener.h"
+#include "JoyStickQuantityListener.h"
 #include "JoyStick.h"
+#include "Mouse.h"
+#include "Keyboard.h"
 
 // HACK (include this as last, X11 seems to define some macros...)
@@ -73,8 +76,6 @@
     SetCommandLineSwitch(keyboard_no_grab).information("Whether not to exclusively grab the keyboard");
 
-    EmptyHandler InputManager::EMPTY_HANDLER;
+    InputHandler InputHandler::EMPTY;
     InputManager* InputManager::singletonRef_s = 0;
-
-    using namespace InputDevice;
 
     /**
@@ -109,7 +110,5 @@
     InputManager::InputManager(size_t windowHnd, unsigned int windowWidth, unsigned int windowHeight)
         : inputSystem_(0)
-        , keyboard_(0)
-        , mouse_(0)
-        , devicesNum_(0)
+        , devices_(2)
         , windowHnd_(0)
         , internalState_(Uninitialised)
@@ -117,5 +116,4 @@
         , keyDetector_(0)
         , calibratorCallbackBuffer_(0)
-        , keyboardModifiers_(0)
     {
         RegisterRootObject(InputManager);
@@ -182,4 +180,5 @@
 #endif
 
+            // TODO: clean this up
             try
             {
@@ -199,4 +198,5 @@
             }
 
+            // TODO: Remove the two parameters
             _initialiseMouse(windowWidth, windowHeight);
 
@@ -220,18 +220,21 @@
 
             // Lowest priority empty InputState
-            stateEmpty_ = createInputState<SimpleInputState>("empty", false, false, InputStatePriority::Empty);
-            stateEmpty_->setHandler(&EMPTY_HANDLER);
+            stateEmpty_ = createInputState("empty", false, false, InputStatePriority::Empty);
+            stateEmpty_->setHandler(&InputHandler::EMPTY);
             activeStates_[stateEmpty_->getPriority()] = stateEmpty_;
 
             // KeyDetector to evaluate a pressed key's name
-            SimpleInputState* detector = createInputState<SimpleInputState>("detector", false, false, InputStatePriority::Detector);
+            InputState* detector = createInputState("detector", false, false, InputStatePriority::Detector);
+            FunctorMember<InputManager>* bufferFunctor = createFunctor(&InputManager::clearBuffers);
+            bufferFunctor->setObject(this);
+            detector->setLeaveFunctor(bufferFunctor);
             keyDetector_ = new KeyDetector();
             detector->setHandler(keyDetector_);
 
             // Joy stick calibration helper callback
-            SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", false, false, InputStatePriority::Calibrator);
-            calibrator->setHandler(&EMPTY_HANDLER);
+            InputState* calibrator = createInputState("calibrator", false, false, InputStatePriority::Calibrator);
+            calibrator->setHandler(&InputHandler::EMPTY);
             calibratorCallbackBuffer_ = new InputBuffer();
-            calibratorCallbackBuffer_->registerListener(this, &InputManager::_completeCalibration, '\r', true);
+            calibratorCallbackBuffer_->registerListener(this, &InputManager::_stopCalibration, '\r', true);
             calibrator->setKeyHandler(calibratorCallbackBuffer_);
 
@@ -246,67 +249,30 @@
     }
 
-    /**
-    @brief
-        Creates a keyboard and sets the event handler.
-    @return
-        False if keyboard stays uninitialised, true otherwise.
-    */
     void InputManager::_initialiseKeyboard()
     {
-        if (keyboard_ != 0)
-        {
-            CCOUT(2) << "Warning: Keyboard already initialised, skipping." << std::endl;
-            return;
-        }
+        assert(devices_[InputDeviceEnumerator::Keyboard] == 0);
         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;
-        }
+            devices_[InputDeviceEnumerator::Keyboard] = new Keyboard(InputDeviceEnumerator::Keyboard);
         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(unsigned int windowWidth, unsigned int windowHeight)
     {
-        if (mouse_ != 0)
-        {
-            CCOUT(2) << "Warning: Mouse already initialised, skipping." << std::endl;
-            return;
-        }
-        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;
-
-                // Set mouse region
-                setWindowExtents(windowWidth, windowHeight);
-            }
-            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;
-        }
+        assert(devices_[InputDeviceEnumerator::Mouse] == 0);
+        if (inputSystem_->getNumberOfDevices(OIS::OISMouse) > 0)
+        {
+            try
+            {
+                devices_[InputDeviceEnumerator::Mouse] = new Mouse(InputDeviceEnumerator::Mouse, windowWidth, windowHeight);
+            }
+            catch (const OIS::Exception& ex)
+            {
+                CCOUT(2) << "Warning: Failed to create Mouse:" << ex.eText << std::endl
+                         << "Proceeding without mouse support." << std::endl;
+            }
+        }
+        else
+            CCOUT(ORX_WARNING) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
     }
 
@@ -319,13 +285,5 @@
     void InputManager::_initialiseJoySticks()
     {
-        if (!this->joySticks_.empty())
-        {
-            CCOUT(2) << "Warning: Joy sticks already initialised, skipping." << std::endl;
-            return;
-        }
-
-        devicesNum_ = 2 + inputSystem_->getNumberOfDevices(OIS::OISJoyStick);
-        // state management
-        activeStatesTriggered_.resize(devicesNum_);
+        assert(devices_.size() == InputDeviceEnumerator::FirstJoyStick);
 
         for (int i = 0; i < inputSystem_->getNumberOfDevices(OIS::OISJoyStick); i++)
@@ -333,5 +291,5 @@
             try
             {
-                joySticks_.push_back(new JoyStick(activeStatesTriggered_[2 + i], i));
+                devices_.push_back(new JoyStick(InputDeviceEnumerator::FirstJoyStick + i));
             }
             catch (std::exception ex)
@@ -342,12 +300,12 @@
 
         // inform all JoyStick Device Number Listeners
-        for (ObjectList<JoyStickDeviceNumberListener>::iterator it = ObjectList<JoyStickDeviceNumberListener>::begin(); it; ++it)
-            it->JoyStickDeviceNumberChanged(joySticks_.size());
+        for (ObjectList<JoyStickQuantityListener>::iterator it = ObjectList<JoyStickQuantityListener>::begin(); it; ++it)
+            it->JoyStickQuantityChanged(devices_.size() - InputDeviceEnumerator::FirstJoyStick);
     }
 
     void InputManager::_startCalibration()
     {
-        BOOST_FOREACH(JoyStick* stick, joySticks_)
-            stick->startCalibration();
+        BOOST_FOREACH(InputDevice* device, devices_)
+            device->startCalibration();
 
         getInstance().internalState_ |= Calibrating;
@@ -355,12 +313,14 @@
     }
 
-    void InputManager::_completeCalibration()
-    {
-        BOOST_FOREACH(JoyStick* stick, joySticks_)
-            stick->stopCalibration();
+    void InputManager::_stopCalibration()
+    {
+        BOOST_FOREACH(InputDevice* device, devices_)
+            device->stopCalibration();
 
         // restore old input state
         requestLeaveState("calibrator");
         internalState_ &= ~Calibrating;
+        // Clear buffers to prevent button hold events
+        this->clearBuffers();
     }
 
@@ -374,4 +334,5 @@
         Destroys all the created input devices and states.
     */
+    // TODO: export this to be used with reload()
     InputManager::~InputManager()
     {
@@ -379,11 +340,4 @@
         {
             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
@@ -401,7 +355,20 @@
 
             // destroy the devices
-            _destroyKeyboard();
-            _destroyMouse();
-            _destroyJoySticks();
+            BOOST_FOREACH(InputDevice*& device, devices_)
+            {
+                std::string className = device->getClassName();
+                try
+                {
+                    if (device)
+                        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);
 
             try
@@ -416,67 +383,4 @@
 
         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;
-        }
-        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()
-    {
-        assert(inputSystem_);
-        while (!joySticks_.empty())
-        {
-            try
-            {
-                delete joySticks_.back();
-            }
-            catch (...)
-            {
-                CCOUT(1) << "Joy stick destruction failed! Potential resource leak!" << std::endl;
-            }
-            joySticks_.pop_back();
-            devicesNum_ = 2;
-        }
-        CCOUT(4) << "Joy sticks destroyed." << std::endl;
     }
 
@@ -539,13 +443,26 @@
 
             // Save mouse clipping size
-            int mouseWidth  = mouse_->getMouseState().width;
-            int mouseHeight = mouse_->getMouseState().height;
+            int mouseWidth  = static_cast<Mouse*>(devices_[InputDeviceEnumerator::Mouse])->getClippingWidth();
+            int mouseHeight = static_cast<Mouse*>(devices_[InputDeviceEnumerator::Mouse])->getClippingHeight();
 
             internalState_ &= ~OISReady;
 
             // destroy the devices
-            _destroyKeyboard();
-            _destroyMouse();
-            _destroyJoySticks();
+            // destroy the devices
+            BOOST_FOREACH(InputDevice*& device, devices_)
+            {
+                try
+                {
+                    if (device)
+                        delete device;
+                    device = 0;
+                    CCOUT(4) << device->getClassName() << " destroyed." << std::endl;
+                }
+                catch (...)
+                {
+                    CCOUT(1) << device->getClassName() << " destruction failed! Potential resource leak!" << std::endl;
+                }
+            }
+            devices_.resize(InputDeviceEnumerator::FirstJoyStick);
 
             OIS::InputManager::destroyInputSystem(inputSystem_);
@@ -592,5 +509,5 @@
                 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());
@@ -631,5 +548,5 @@
                 activeStates_[(*it)->getPriority()] = (*it);
                 _updateActiveStates();
-                (*it)->onEnter();
+                (*it)->entered();
             }
             stateEnterRequests_.clear();
@@ -647,11 +564,11 @@
         }
 
-        // 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;
             }
@@ -664,39 +581,12 @@
 
         // Capture all the input. This calls the event handlers in InputManager.
-        if (keyboard_)
-            keyboard_->capture();
-        if (mouse_)
-            mouse_->capture();
-        BOOST_FOREACH(JoyStick* stick, joySticks_)
-            stick->capture();
+        BOOST_FOREACH(InputDevice* device, devices_)
+            device->update(time);
 
         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]);
-            }
-
-            // 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
+            // update the states with a general tick afterwards
             for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
-                activeStatesTicked_[i]->updateInput(time.getDeltaTime());
+                activeStatesTicked_[i]->update(time.getDeltaTime());
         }
 
@@ -711,13 +601,15 @@
     void InputManager::_updateActiveStates()
     {
-        for (unsigned int i = 0; i < devicesNum_; ++i)
-        {
+        // temporary resize
+        for (unsigned int i = 0; i < devices_.size(); ++i)
+        {
+            std::vector<InputState*>& states = devices_[i]->getStateListRef();
             bool occupied = false;
-            activeStatesTriggered_[i].clear();
-            for (std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
+            states.clear();
+            for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
             {
                 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;
@@ -729,7 +621,7 @@
         // 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)
+            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
@@ -737,6 +629,4 @@
         for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
             activeStatesTicked_.push_back(*it);
-
-        this->mouseButtonsDown_.clear();
     }
 
@@ -747,166 +637,6 @@
     void InputManager::clearBuffers()
     {
-        keysDown_.clear();
-        keyboardModifiers_ = 0;
-        mouseButtonsDown_.clear();
-        BOOST_FOREACH(JoyStick* stick, joySticks_)
-            stick->clearBuffer();
-    }
-
-
-    // ############################################################
-    // #####                    OIS events                    #####
-    // ##########                                        ##########
-    // ############################################################
-
-    // ###### 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;
+        BOOST_FOREACH(InputDevice* device, devices_)
+            device->clearBuffers();
     }
 
@@ -923,11 +653,9 @@
         Returns true if ID is ok (unique), false otherwise.
     */
-    bool InputManager::checkJoyStickID(const std::string& idString)
-    {
-        BOOST_FOREACH(JoyStick* stick, joySticks_)
-        {
-            if (stick->getIDString() == idString)
+    bool InputManager::checkJoyStickID(const std::string& idString) const
+    {
+        for (unsigned int i = InputDeviceEnumerator::FirstJoyStick; i < devices_.size(); ++i)
+            if (static_cast<JoyStick*>(devices_[i])->getIDString() == idString)
                 return false;
-        }
         return true;
     }
@@ -938,23 +666,4 @@
     // ##########                                        ##########
     // ############################################################
-
-    /**
-    @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;
-        }
-    }
 
     /**
@@ -970,4 +679,31 @@
 
     // ###### InputStates ######
+
+    /**
+    @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).
+    */
+    InputState* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
+    {
+        InputState* state = new InputState;
+        if (_configureInputState(state, name, bAlwaysGetsInput, bTransparent, priority))
+            return state;
+        else
+        {
+            delete state;
+            return 0;
+        }
+    }
 
     /**
@@ -1008,5 +744,5 @@
             }
             inputStatesByName_[name] = state;
-            state->JoyStickDeviceNumberChanged(numberOfJoySticks());
+            state->JoyStickQuantityChanged(devices_.size() - InputDeviceEnumerator::FirstJoyStick);
             state->setName(name);
             state->bAlwaysGetsInput_ = bAlwaysGetsInput;
Index: /code/branches/core4/src/core/input/InputManager.h
===================================================================
--- /code/branches/core4/src/core/input/InputManager.h	(revision 3273)
+++ /code/branches/core4/src/core/input/InputManager.h	(revision 3274)
@@ -37,5 +37,5 @@
 #define _InputManager_H__
 
-#include "core/CorePrereqs.h"
+#include "InputPrereqs.h"
 
 #include <map>
@@ -43,12 +43,8 @@
 #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"
 
 namespace orxonox
@@ -71,11 +67,8 @@
         Captures and distributes mouse and keyboard input.
     */
-    class _CoreExport InputManager
-        : public OrxonoxClass,
-        public OIS::KeyListener, public OIS::MouseListener
+    class _CoreExport InputManager : public OrxonoxClass
     {
         // --> setConfigValues is private
         friend class ClassIdentifier<InputManager>;
-        friend class JoyStick;
 
     public:
@@ -99,13 +92,8 @@
         void clearBuffers();
 
-        unsigned int  numberOfKeyboards() { return keyboard_ ? 1 : 0; }
-        unsigned int  numberOfMice()      { return mouse_    ? 1 : 0; }
-        unsigned int  numberOfJoySticks() { return joySticks_.size(); }
-
         void setWindowExtents(const int width, const int height);
         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* createInputState(const std::string& name, bool bAlwaysGetsInput = false, bool bTransparent = false, InputStatePriority priority = InputStatePriority::Dynamic);
 
         InputState* getState       (const std::string& name);
@@ -114,4 +102,9 @@
         bool requestEnterState     (const std::string& name);
         bool requestLeaveState     (const std::string& name);
+
+        OIS::InputManager* getInputSystem() { return this->inputSystem_; }
+        bool checkJoyStickID(const std::string& idString) const;
+        unsigned int getJoyStickQuantity() const
+            { return devices_.size() - InputDeviceEnumerator::FirstJoyStick; }
 
 #ifdef ORXONOX_PLATFORM_LINUX
@@ -130,14 +123,7 @@
         static void reload();
 
-    public: // variables
-        static EmptyHandler                 EMPTY_HANDLER;
-
-    private: // functions for friends
-        OIS::InputManager* getInputSystem() { return this->inputSystem_; }
-        bool checkJoyStickID(const std::string&);
-
     private: // functions
         // don't mess with a Singleton
-        InputManager (const InputManager&);
+        InputManager(const InputManager&);
 
         // Intenal methods
@@ -145,45 +131,25 @@
         void _initialiseMouse(unsigned int windowWidth, unsigned int windowHeight);
         void _initialiseJoySticks();
-        void _configureJoySticks();
 
-        void _loadCalibration();
         void _startCalibration();
-        void _completeCalibration();
-        void _evaluateCalibration();
+        void _stopCalibration();
 
-        void _destroyKeyboard();
-        void _destroyMouse();
-        void _destroyJoySticks();
         void _destroyState(InputState* state);
 
         void _reload();
 
-        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);
-
         void setConfigValues();
-        void _calibrationFileCallback();
 
     private: // variables
         OIS::InputManager*                  inputSystem_;          //!< OIS input manager
-        OIS::Keyboard*                      keyboard_;             //!< OIS mouse
-        OIS::Mouse*                         mouse_;                //!< OIS keyboard
-        std::vector<JoyStick*>              joySticks_;            //!< Orxonox joy sticks
-        unsigned int                        devicesNum_;
+        std::vector<InputDevice*>           devices_;              //!< List of all input devices (keyboard, mouse, joy sticks)
         size_t                              windowHnd_;            //!< Render window handle
         InputManagerState                   internalState_;        //!< Current internal state
 
         // some internally handled states and handlers
-        SimpleInputState*                   stateEmpty_;
+        InputState*                         stateEmpty_;
         KeyDetector*                        keyDetector_;          //!< KeyDetector instance
         InputBuffer*                        calibratorCallbackBuffer_;
@@ -196,42 +162,8 @@
 
         std::map<int, InputState*>          activeStates_;
-        std::vector<std::vector<InputState*> > activeStatesTriggered_;
         std::vector<InputState*>            activeStatesTicked_;
-
-        unsigned int                        keyboardModifiers_;    //!< Bit mask representing keyboard modifiers.
-
-        std::vector<Key>                    keysDown_;
-        std::vector<MouseButtonCode::ByEnum> mouseButtonsDown_;
 
         static InputManager*                singletonRef_s;
     };
-
-    /**
-    @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/branches/core4/src/core/input/InputPrereqs.h
===================================================================
--- /code/branches/core4/src/core/input/InputPrereqs.h	(revision 3274)
+++ /code/branches/core4/src/core/input/InputPrereqs.h	(revision 3274)
@@ -0,0 +1,538 @@
+/*
+ *   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 _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
+
+        // 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"
+        };
+    }
+
+
+    //-----------------------------------------------------------------------
+    // Miscellaneous
+    //-----------------------------------------------------------------------
+
+    namespace InputDeviceEnumerator
+    {
+        enum Value
+        {
+            Keyboard = 0,
+            Mouse = 1,
+            FirstJoyStick = 2
+        };
+    }
+
+    namespace ButtonEvent
+    {
+        enum Value
+        {
+            Press,
+            Release,
+            Hold
+        };
+
+        template <ButtonEvent::Value Event>
+        struct EnumToType { };
+        typedef EnumToType<Press>   TPress;
+        typedef EnumToType<Release> TRelease;
+        typedef EnumToType<Hold>    THold;
+    }
+
+
+    namespace KeyboardModifier
+    {
+        enum Enum
+        {
+            Shift = 0x0000001,
+            Ctrl  = 0x0000010,
+            Alt   = 0x0000100
+        };
+    }
+
+    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_;
+    };
+
+
+    //-----------------------------------------------------------------------
+    // Device type traits
+    //-----------------------------------------------------------------------
+
+    struct KeyboardTraits
+    {
+        typedef Keyboard DeviceClass;
+        typedef OIS::Keyboard OISDeviceClass;
+        typedef KeyEvent ButtonType;
+        typedef KeyEvent& ButtonTypeParam;
+        static const OIS::Type OISDeviceValue = OIS::OISKeyboard;
+    };
+
+    struct MouseTraits
+    {
+        typedef Mouse DeviceClass;
+        typedef OIS::Mouse OISDeviceClass;
+        typedef MouseButtonCode::ByEnum ButtonType;
+        typedef MouseButtonCode::ByEnum ButtonTypeParam;
+        static const OIS::Type OISDeviceValue = OIS::OISMouse;
+    };
+
+    struct JoyStickTraits
+    {
+        typedef JoyStick DeviceClass;
+        typedef OIS::JoyStick OISDeviceClass;
+        typedef JoyStickButtonCode::ByEnum ButtonType;
+        typedef JoyStickButtonCode::ByEnum ButtonTypeParam;
+        static const OIS::Type OISDeviceValue = OIS::OISJoyStick;
+    };
+
+    // Note: Entries correspond to OIS::Type enum
+    namespace InputDeviceNames
+    {
+        const char* const values[] = { "", "Keyboard", "Mouse", "JoyStick" };
+    }
+}
+
+#endif /* _InputPrereqs_H__ */
Index: /code/branches/core4/src/core/input/InputState.cc
===================================================================
--- /code/branches/core4/src/core/input/InputState.cc	(revision 3274)
+++ /code/branches/core4/src/core/input/InputState.cc	(revision 3274)
@@ -0,0 +1,130 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "InputState.h"
+#include "core/Functor.h"
+
+namespace orxonox
+{
+    InputState::InputState()
+        : priority_(0)
+        , bAlwaysGetsInput_(false)
+        , bTransparent_(false)
+        , bExpired_(true)
+        , handlers_(2)
+        , joyStickHandlerAll_(0)
+        , enterFunctor_(0)
+        , leaveFunctor_(0)
+    {
+    }
+
+    bool InputState::isInputDeviceEnabled(unsigned int device)
+    {
+        if (device < handlers_.size())
+            return handlers_[device] != NULL;
+        else
+            return false;
+    }
+
+    void InputState::JoyStickQuantityChanged(unsigned int n)
+    {
+        unsigned int oldSize = handlers_.size();
+        handlers_.resize(InputDeviceEnumerator::FirstJoyStick + n, NULL);
+
+        for (unsigned int i = oldSize; i < handlers_.size(); ++i)
+            handlers_[i] = joyStickHandlerAll_;
+
+        bExpired_ = true;
+    }
+
+    /**
+    @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 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;
+    }
+
+    /**
+    @brief
+        Adds a joy stick handler.
+    @param handler
+        Pointer to the handler object.
+    @return
+        True if added, false if handler already existed.
+    */
+    bool InputState::setJoyStickHandler(InputHandler* handler)
+    {
+        joyStickHandlerAll_ = handler;
+        for (unsigned int i = firstJoyStickIndex_s; i < handlers_.size(); ++i)
+            handlers_[i] = handler;
+        bExpired_ = true;
+        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 InputState::setHandler(InputHandler* handler)
+    {
+        setKeyHandler(handler);
+        setMouseHandler(handler);
+        return setJoyStickHandler(handler);
+    }
+
+    void InputState::entered()
+    {
+        if (enterFunctor_)
+            (*enterFunctor_)();
+            
+    }
+
+    void InputState::left()
+    {
+        if (leaveFunctor_)
+            (*leaveFunctor_)();
+    }
+}
Index: /code/branches/core4/src/core/input/InputState.h
===================================================================
--- /code/branches/core4/src/core/input/InputState.h	(revision 3273)
+++ /code/branches/core4/src/core/input/InputState.h	(revision 3274)
@@ -27,103 +27,133 @@
  */
 
-/**
-@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 "JoyStickDeviceNumberListener.h"
+
+#include "InputHandler.h"
+#include "JoyStickQuantityListener.h"
 
 namespace orxonox
 {
-    class _CoreExport InputState : public JoyStickDeviceNumberListener
+    class _CoreExport InputState : public JoyStickQuantityListener
     {
         friend class InputManager;
 
+        static const InputDeviceEnumerator::Value keyboardIndex_s      = InputDeviceEnumerator::Keyboard;
+        static const InputDeviceEnumerator::Value mouseIndex_s         = InputDeviceEnumerator::Mouse;
+        static const InputDeviceEnumerator::Value firstJoyStickIndex_s = InputDeviceEnumerator::FirstJoyStick;
+
     public:
+        void setKeyHandler     (InputHandler* handler)
+            { handlers_[keyboardIndex_s] = handler; bExpired_ = true; }
+        void setMouseHandler   (InputHandler* handler)
+            { handlers_[mouseIndex_s]    = handler; bExpired_ = true; }
+        bool setJoyStickHandler(InputHandler* handler, unsigned int joyStick);
+        bool setJoyStickHandler(InputHandler* handler);
+        bool setHandler        (InputHandler* handler);
+
         const std::string& getName() const { return name_; }
         int getPriority()            const { return priority_; }
 
-        bool isInputDeviceEnabled(unsigned int device)
-        {
-            if (device < bInputDeviceEnabled_.size())
-                return bInputDeviceEnabled_[device];
-            else
-                return false;
-        }
+        bool isInputDeviceEnabled(unsigned int device);
 
-        bool handlersChanged() { return this->bHandlersChanged_; }
-        void resetHandlersChanged() { bHandlersChanged_ = false; }
+        bool hasExpired()      { return this->bExpired_; }
+        void resetExpiration() { bExpired_ = false; }
 
-        virtual void onEnter() = 0;
-        virtual void onLeave() = 0;
+        void update(float dt, unsigned int device);
+        void update(float dt);
 
-        virtual void registerOnEnter(Executor* executor)      { executorOnEnter_ = executor; }
-        virtual void unRegisterOnEnter()                      { executorOnEnter_ = 0; }
-        virtual void registerOnLeave(Executor* executor)      { executorOnLeave_ = executor; }
-        virtual void unRegisterOnLeave()                      { executorOnLeave_ = 0; }
+        template <typename EventType, class Traits>
+        void buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button);
 
-        virtual void updateInput(float dt, unsigned int device) = 0;
-        virtual void updateInput(float dt) = 0;
+        void mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
+        void mouseScrolled(int abs, int rel);
+        void joyStickAxisMoved(unsigned int device, unsigned int axis, float value);
 
-        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_;
+        // Functors
+        void entered();
+        void left();
+        void setEnterFunctor(Functor* functor) { this->enterFunctor_ = functor; }
+        void setLeaveFunctor(Functor* functor) { this->leaveFunctor_ = functor; }
 
     private:
-        void JoyStickDeviceNumberChanged(unsigned int n)
+        InputState();
+        ~InputState() { }
+
+        void JoyStickQuantityChanged(unsigned int n);
+
+        void setName(const std::string& name) { name_ = name; }
+        void setPriority(int priority)        { priority_ = priority; }
+
+        std::string                 name_;
+        int                         priority_;
+        bool                        bAlwaysGetsInput_;
+        bool                        bTransparent_;
+        bool                        bExpired_;
+        std::vector<InputHandler*>  handlers_;
+        InputHandler*               joyStickHandlerAll_;
+        Functor*                    enterFunctor_;
+        Functor*                    leaveFunctor_;
+    };
+
+    inline void InputState::update(float dt)
+    {
+        for (unsigned int i = 0; i < handlers_.size(); ++i)
+            if (handlers_[i] != NULL)
+                handlers_[i]->allDevicesUpdated(dt);
+    }
+
+    inline void InputState::update(float dt, unsigned int device)
+    {
+        switch (device)
         {
-            bInputDeviceEnabled_.resize(n + 2);
-            numberOfJoySticksChanged(n);
+        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;
         }
-        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>
+    inline 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());
+    }
+
+    inline void InputState::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
+    {
+        if (handlers_[mouseIndex_s] != NULL)
+            handlers_[mouseIndex_s]->mouseMoved(abs, rel, clippingSize);
+    }
+
+    inline void InputState::mouseScrolled(int abs, int rel)
+    {
+        if (handlers_[mouseIndex_s] != NULL)
+            handlers_[mouseIndex_s]->mouseScrolled(abs, rel);
+    }
+
+    inline 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/branches/core4/src/core/input/JoyStick.cc
===================================================================
--- /code/branches/core4/src/core/input/JoyStick.cc	(revision 3273)
+++ /code/branches/core4/src/core/input/JoyStick.cc	(revision 3274)
@@ -26,10 +26,4 @@
  *
  */
-
-/**
-@file
-@brief
-    Implementation of the JoyStick wrapper class.
-*/
 
 #include "JoyStick.h"
@@ -54,30 +48,26 @@
     void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue);
 
-    JoyStick::JoyStick(const std::vector<InputState*>& states, unsigned int id)
-        : id_(id)
-        , bCalibrating_(false)
-        , inputStates_(states)
+    JoyStick::JoyStick(unsigned int id)
+        : super(id)
     {
         RegisterRootObject(JoyStick);
         this->setConfigValues();
-
-        OIS::InputManager* system = InputManager::getInstance().getInputSystem();
-        oisJoyStick_ = static_cast<OIS::JoyStick*>(system->createInputObject(OIS::OISJoyStick, true));
-        oisJoyStick_->setEventCallback(this);
+        // Initialise POV and Slider states
+        this->clearBuffersImpl();
 
         idString_ = "JoyStick_";
-        std::string name = oisJoyStick_->vendor();
+        std::string name = oisDevice_->vendor();
         replaceCharacters(name, ' ', '_');
         idString_ += name + "_";
-        idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Button))  + "_";
-        idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Axis))    + "_";
-        idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Slider))  + "_";
-        idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_POV));
-        //idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Vector3));
+        idString_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Button))  + "_";
+        idString_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis))    + "_";
+        idString_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Slider))  + "_";
+        idString_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_POV));
+        //idString_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Vector3));
 
         if (InputManager::getInstance().checkJoyStickID(idString_) == false)
         {
             // Make the ID unique for this execution time.
-            idString_ += "_" + multi_cast<std::string>(id_);
+            idString_ += "_" + multi_cast<std::string>(this->getDeviceID());
         }
 
@@ -85,5 +75,5 @@
 
         // Load calibration
-        size_t axes = sliderAxes_s + static_cast<size_t>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Axis));
+        size_t axes = sliderAxes_s + static_cast<size_t>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis));
         loadCalibration(configMinValues_,  idString_, "MinValue",  axes,  -32768);
         loadCalibration(configMaxValues_,  idString_, "MaxValue",  axes,   32768);
@@ -92,21 +82,5 @@
     }
 
-    JoyStick::~JoyStick()
-    {
-        try
-        {
-            OIS::InputManager* system = InputManager::getInstance().getInputSystem();
-            system->destroyInputObject(oisJoyStick_);
-        }
-        catch (...)
-        {
-            COUT(1) << "Joy stick destruction failed! Potential resource leak!" << std::endl;
-        }
-    }
-
-    /**
-    @brief
-        Callback for the joy stick calibration config file. @see setConfigValues.
-    */
+    //!< Callback for the joy stick calibration config file.
     void JoyStick::calibrationFileCallback()
     {
@@ -114,8 +88,4 @@
     }
 
-    /**
-    @brief
-        Sets the configurable values.
-    */
     void JoyStick::setConfigValues()
     {
@@ -140,13 +110,10 @@
         // fill the rest with default values
         for (unsigned int i = configValueVectorSize; i < size; ++i)
-        {
             list[i] = defaultValue;
-        }
-    }
-
-    void JoyStick::startCalibration()
-    {
-        bCalibrating_ = true;
-
+    }
+
+    //! Called by InputDevice when calibration mode has started
+    void JoyStick::calibrationStarted()
+    {
         // Set initial values
         BOOST_FOREACH(int& minVal, configMinValues_)
@@ -158,5 +125,6 @@
     }
 
-    void JoyStick::stopCalibration()
+    //! Called by InputDevice when calibration mode has stopped
+    void JoyStick::calibrationStopped()
     {
         // Get the middle positions now
@@ -164,11 +132,11 @@
         for (unsigned int i = 0; i < sliderAxes_s/2; ++i)
         {
-            configZeroValues_[iAxis++] = oisJoyStick_->getJoyStickState().mSliders[i].abX;
-            configZeroValues_[iAxis++] = oisJoyStick_->getJoyStickState().mSliders[i].abY;
-        }
-        // Note: joyStickMiddleValues_[iJoyStick] was already correctly resised in loadCalibration()
-        assert(oisJoyStick_->getJoyStickState().mAxes.size() == configZeroValues_.size() - sliderAxes_s);
+            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++] = oisJoyStick_->getJoyStickState().mAxes[i].abs;
+            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mAxes[i].abs;
 
         for (unsigned int i = 0; i < configMinValues_.size(); ++i)
@@ -192,8 +160,7 @@
 
         this->evaluateCalibration();
-
-        bCalibrating_ = false;
-    }
-
+    }
+
+    //! Evaluates the accumulated values during calibration
     void JoyStick::evaluateCalibration()
     {
@@ -206,7 +173,7 @@
     }
 
-    void JoyStick::clearBuffer()
-    {
-        pressedButtons_.clear();
+    // TODO: What do we really need to reset here?
+    void JoyStick::clearBuffersImpl()
+    {
         for (int j = 0; j < 4; ++j)
         {
@@ -217,60 +184,8 @@
     }
 
-
-    // ###### Events ######
-
-    void JoyStick::capture()
-    {
-        oisJoyStick_->capture();
-
-        // call all the handlers for the held joy stick button events
-        for (unsigned int iButton = 0; iButton < pressedButtons_.size(); iButton++)
-        {
-            BOOST_FOREACH(InputState* state, inputStates_)
-                state->joyStickButtonHeld(id_, pressedButtons_[iButton]);
-        }
-    }
-
-    bool JoyStick::buttonPressed(const OIS::JoyStickEvent &arg, int 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(static_cast<JoyStickButtonCode::ByEnum>(button));
-
-        BOOST_FOREACH(InputState* state, inputStates_)
-            state->joyStickButtonPressed(id_, static_cast<JoyStickButtonCode::ByEnum>(button));
-
-        return true;
-    }
-
-    bool JoyStick::buttonReleased(const OIS::JoyStickEvent &arg, int button)
-    {
-        // remove the button from the pressedButtons_ list
-        for (unsigned int iButton = 0; iButton < pressedButtons_.size(); iButton++)
-        {
-            if (static_cast<int>(pressedButtons_[iButton]) == button)
-            {
-                pressedButtons_.erase(pressedButtons_.begin() + iButton);
-                break;
-            }
-        }
-
-        BOOST_FOREACH(InputState* state, inputStates_)
-            state->joyStickButtonPressed(id_, static_cast<JoyStickButtonCode::ByEnum>(button));
-
-        return true;
-    }
-
-    /**
-    @brief
-        Calls the states for a particular axis with our enumeration.
-        Used by OIS sliders and OIS axes.
-    */
+    //! Generic method to forward axis events
     void JoyStick::fireAxis(int axis, int value)
     {
-        if (bCalibrating_)
+        if (this->isCalibrating())
         {
             if (value < configMinValues_[axis])
@@ -288,8 +203,9 @@
 
             BOOST_FOREACH(InputState* state, inputStates_)
-                state->joyStickAxisMoved(id_, axis, fValue);
-        }
-    }
-
+                state->joyStickAxisMoved(this->getDeviceID(), axis, fValue);
+        }
+    }
+
+    //! OIS joy stick axis event handler
     bool JoyStick::axisMoved(const OIS::JoyStickEvent &arg, int axis)
     {
@@ -300,4 +216,5 @@
     }
 
+    //! A Slider always has an X and an Y direction!
     bool JoyStick::sliderMoved(const OIS::JoyStickEvent &arg, int id)
     {
@@ -310,4 +227,5 @@
     }
 
+    //! 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)
     {
Index: /code/branches/core4/src/core/input/JoyStick.h
===================================================================
--- /code/branches/core4/src/core/input/JoyStick.h	(revision 3273)
+++ /code/branches/core4/src/core/input/JoyStick.h	(revision 3274)
@@ -27,82 +27,90 @@
  */
 
-/**
-@file
-@brief 
-*/
+#ifndef _Core_JoyStick_H__
+#define _Core_JoyStick_H__
 
-#ifndef _JoyStick_H__
-#define _JoyStick_H__
-
-#include "core/CorePrereqs.h"
+#include "InputPrereqs.h"
 
 #include <string>
 #include <vector>
-#include "InputInterfaces.h"
+#include "InputDevice.h"
 
 namespace orxonox
 {
-    class _CoreExport JoyStick : public OrxonoxClass, public OIS::JoyStickListener
+    /**
+    @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
     {
-    private:
-        struct JoyStickCalibration
-        {
-        };
+        friend class InputDeviceTemplated<JoyStickTraits>;
+        //! Super class alias
+        typedef InputDeviceTemplated<JoyStickTraits> super;
 
     public:
-        JoyStick(const std::vector<InputState*>& states, unsigned int id);
-        ~JoyStick();
-
+        //! Assigns a generated ID string and loads the calibration (if present)
+        JoyStick(unsigned int id);
+        ~JoyStick() { }
         void setConfigValues();
 
-        OIS::JoyStick* getOISJoyStick() { return this->oisJoyStick_; }
+        //! Returns the generated (from the number of knobs and the device name) ID string
         const std::string& getIDString() const { return this->idString_; }
 
-        void startCalibration();
-        void stopCalibration();
+    private:
+        void calibrationStarted();
+        void calibrationStopped();
+        void evaluateCalibration();
 
-        void capture();
-        void clearBuffer();
-
-    private:
+        void clearBuffersImpl();
         void calibrationFileCallback();
-        void evaluateCalibration();
         void fireAxis(int axis, int value);
 
-        bool buttonPressed (const OIS::JoyStickEvent &arg, int button);
-        bool buttonReleased(const OIS::JoyStickEvent &arg, int button);
+        //! 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);
-        // don't remove that! Or else add OIS as dependency library to orxonox (it actually is..)
+        //!< OIS event handler (don't remove that because of OIS version issues!)
         bool vector3Moved  (const OIS::JoyStickEvent &arg, int id) { return true; }
 
-        static const unsigned int sliderAxes_s = 8;
-
-        OIS::JoyStick* oisJoyStick_;
-        const unsigned int id_;
-        std::string idString_;
+        std::string idString_;                //!< ID string 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
-        bool bCalibrating_;
-        int zeroValues_[24];
-        float positiveCoeffs_[24];
-        float negativeCoeffs_[24];
+        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> configMinValues_;
-        std::vector<int> configMaxValues_;
-        std::vector<int> configZeroValues_;
-
-        int povStates_[4];
-        int sliderStates_[4][2];
-        std::vector<JoyStickButtonCode::ByEnum> pressedButtons_;
-
-        // InputState handling
-        const std::vector<InputState*>& inputStates_;
+        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
+        std::string calibrationFilename_;     //!< Joy stick calibration ini filename
+
+        //!< Maximum number of slider axes
+        static const unsigned int sliderAxes_s = 8;
     };
 }
 
-#endif /* _JoyStick_H__ */
+#endif /* _Core_JoyStick_H__ */
Index: de/branches/core4/src/core/input/JoyStickDeviceNumberListener.cc
===================================================================
--- /code/branches/core4/src/core/input/JoyStickDeviceNumberListener.cc	(revision 3273)
+++ 	(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: de/branches/core4/src/core/input/JoyStickDeviceNumberListener.h
===================================================================
--- /code/branches/core4/src/core/input/JoyStickDeviceNumberListener.h	(revision 3273)
+++ 	(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/branches/core4/src/core/input/JoyStickQuantityListener.cc
===================================================================
--- /code/branches/core4/src/core/input/JoyStickQuantityListener.cc	(revision 3274)
+++ /code/branches/core4/src/core/input/JoyStickQuantityListener.cc	(revision 3274)
@@ -0,0 +1,44 @@
+/*
+ *   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 JoyStickQuantityListener class.
+*/
+
+#include "JoyStickQuantityListener.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    JoyStickQuantityListener::JoyStickQuantityListener()
+    {
+        RegisterObject(JoyStickQuantityListener);
+    }
+}
Index: /code/branches/core4/src/core/input/JoyStickQuantityListener.h
===================================================================
--- /code/branches/core4/src/core/input/JoyStickQuantityListener.h	(revision 3274)
+++ /code/branches/core4/src/core/input/JoyStickQuantityListener.h	(revision 3274)
@@ -0,0 +1,52 @@
+/*
+ *   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
+{
+    class _CoreExport JoyStickQuantityListener : virtual public OrxonoxClass
+    {
+    public:
+        JoyStickQuantityListener();
+        virtual ~JoyStickQuantityListener() { }
+
+        virtual void JoyStickQuantityChanged(unsigned int value) = 0;
+    };
+}
+
+#endif /* _JoyStickQuantityListener_H__ */
Index: /code/branches/core4/src/core/input/KeyBinder.cc
===================================================================
--- /code/branches/core4/src/core/input/KeyBinder.cc	(revision 3273)
+++ /code/branches/core4/src/core/input/KeyBinder.cc	(revision 3274)
@@ -100,5 +100,5 @@
 
         // initialise joy sticks separatly to allow for reloading
-        numberOfJoySticks_ = InputManager::getInstance().numberOfJoySticks();
+        numberOfJoySticks_ = InputManager::getInstance().getJoyStickQuantity();
         initialiseJoyStickBindings();
 
@@ -152,5 +152,5 @@
     }
 
-    void KeyBinder::JoyStickDeviceNumberChanged(unsigned int value)
+    void KeyBinder::JoyStickQuantityChanged(unsigned int value)
     {
         unsigned int oldValue = numberOfJoySticks_;
@@ -311,5 +311,5 @@
     }
 
-    void KeyBinder::updateMouse(float dt)
+    void KeyBinder::mouseUpdated(float dt)
     {
         if (bDeriveMouseInput_)
@@ -364,5 +364,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 +480,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/branches/core4/src/core/input/KeyBinder.h
===================================================================
--- /code/branches/core4/src/core/input/KeyBinder.h	(revision 3273)
+++ /code/branches/core4/src/core/input/KeyBinder.h	(revision 3274)
@@ -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,31 +68,30 @@
 
     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(unsigned int value);
         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
@@ -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/branches/core4/src/core/input/KeyDetector.cc
===================================================================
--- /code/branches/core4/src/core/input/KeyDetector.cc	(revision 3273)
+++ /code/branches/core4/src/core/input/KeyDetector.cc	(revision 3274)
@@ -73,7 +73,7 @@
     }
 
-    void KeyDetector::JoyStickDeviceNumberChanged(unsigned int value)
+    void KeyDetector::JoyStickQuantityChanged(unsigned int value)
     {
-        KeyBinder::JoyStickDeviceNumberChanged(value);
+        KeyBinder::JoyStickQuantityChanged(value);
         setCallbackCommand(callbackCommand_);
     }
Index: /code/branches/core4/src/core/input/KeyDetector.h
===================================================================
--- /code/branches/core4/src/core/input/KeyDetector.h	(revision 3273)
+++ /code/branches/core4/src/core/input/KeyDetector.h	(revision 3274)
@@ -36,5 +36,5 @@
 #define _KeyDetector_H__
 
-#include "core/CorePrereqs.h"
+#include "InputPrereqs.h"
 
 #include <string>
@@ -49,5 +49,5 @@
         ~KeyDetector();
         void setCallbackCommand(const std::string& command);
-        void JoyStickDeviceNumberChanged(unsigned int value);
+        void JoyStickQuantityChanged(unsigned int value);
 
     private:
Index: /code/branches/core4/src/core/input/Keyboard.cc
===================================================================
--- /code/branches/core4/src/core/input/Keyboard.cc	(revision 3274)
+++ /code/branches/core4/src/core/input/Keyboard.cc	(revision 3274)
@@ -0,0 +1,63 @@
+/*
+ *   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
+
+        super::buttonPressed(KeyEvent(arg));
+        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
+
+        super::buttonReleased(KeyEvent(arg));
+        return true;
+    }
+}
Index: /code/branches/core4/src/core/input/Keyboard.h
===================================================================
--- /code/branches/core4/src/core/input/Keyboard.h	(revision 3274)
+++ /code/branches/core4/src/core/input/Keyboard.h	(revision 3274)
@@ -0,0 +1,70 @@
+/*
+ *   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 "InputDevice.h"
+
+namespace orxonox
+{
+    /**
+    @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 InputDeviceTemplated<KeyboardTraits>;
+        //! Super class alias
+        typedef InputDeviceTemplated<KeyboardTraits> super;
+
+    public:
+        Keyboard(unsigned int id) : super(id), modifiers_(0) { }
+        ~Keyboard() { }
+
+    private:
+        // TODO: Do we need to reset the modifiers?
+        void clearBuffersImpl() { }
+        //! 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);
+
+        //! Bit mask representing keyboard modifiers
+        int modifiers_;
+    };
+}
+
+#endif /* _Core_Keyboard_H__ */
Index: /code/branches/core4/src/core/input/Mouse.cc
===================================================================
--- /code/branches/core4/src/core/input/Mouse.cc	(revision 3274)
+++ /code/branches/core4/src/core/input/Mouse.cc	(revision 3274)
@@ -0,0 +1,88 @@
+/*
+ *   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 <boost/foreach.hpp>
+#include "InputState.h"
+#include "core/ConsoleCommand.h"
+
+namespace orxonox
+{
+    // HACK:
+    SetConsoleCommand(Mouse, setMouseClipping_s, false);
+    Mouse* Mouse::instancePointer_s = NULL;
+
+    Mouse::Mouse(unsigned int id, unsigned int windowWidth, unsigned int windowHeight)
+        : super(id)
+    {
+        this->setMouseClipping(windowWidth, windowHeight);
+        // HACK:
+        instancePointer_s = this;
+    }
+
+    void Mouse::setMouseClipping(unsigned int width, unsigned int height)
+    {
+        oisDevice_->getMouseState().width  = width;
+        oisDevice_->getMouseState().height = height;
+    }
+
+    unsigned int Mouse::getClippingWidth() const
+    {
+        return oisDevice_->getMouseState().width;
+    }
+
+    unsigned int Mouse::getClippingHeight() const
+    {
+        return oisDevice_->getMouseState().height;
+    }
+
+    //! 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);
+            BOOST_FOREACH(InputState* state, inputStates_)
+                state->mouseMoved(abs, rel, clippingSize);
+        }
+
+        // check for mouse scrolled event
+        if (e.state.Z.rel != 0)
+        {
+            BOOST_FOREACH(InputState* state, inputStates_)
+                state->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
+        }
+
+        return true;
+    }
+}
Index: /code/branches/core4/src/core/input/Mouse.h
===================================================================
--- /code/branches/core4/src/core/input/Mouse.h	(revision 3274)
+++ /code/branches/core4/src/core/input/Mouse.h	(revision 3274)
@@ -0,0 +1,94 @@
+/*
+ *   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"
+
+namespace orxonox
+{
+    /**
+    @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
+    {
+        friend InputDeviceTemplated<MouseTraits>;
+        //! Super class alias
+        typedef InputDeviceTemplated<MouseTraits> super;
+
+    public:
+        Mouse(unsigned int id, unsigned int windowWidth, unsigned int windowHeight);
+        ~Mouse() { }
+
+        /**
+        @brief
+            Adjusts the mouse window metrics.
+
+            This method has to be called every time the size of the window changes.
+        */
+        void setMouseClipping(unsigned int width, unsigned int height);
+        unsigned int getClippingWidth() const;
+        unsigned int getClippingHeight() const;
+
+        // HACK:
+        static void setMouseClipping_s(unsigned int width, unsigned int height)
+            { instancePointer_s->setMouseClipping(width, height); }
+        void setConfigValues() { }
+
+    private:
+        // TODO: Do we need to reset the mouse position?
+        void clearBuffersImpl() { }
+
+        //! 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);
+
+        // HACK:
+        static Mouse* instancePointer_s;
+    };
+}
+
+#endif /* _Core_Mouse_H__ */
Index: de/branches/core4/src/core/input/SimpleInputState.cc
===================================================================
--- /code/branches/core4/src/core/input/SimpleInputState.cc	(revision 3273)
+++ 	(revision )
@@ -1,157 +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();
-    }
-
-    /**
-    @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: de/branches/core4/src/core/input/SimpleInputState.h
===================================================================
--- /code/branches/core4/src/core/input/SimpleInputState.h	(revision 3273)
+++ 	(revision )
@@ -1,198 +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::keyPressed(const KeyEvent& evt)
-    {
-        if (keyHandler_)
-            keyHandler_->keyPressed(evt);
-    }
-
-    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/branches/core4/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- /code/branches/core4/src/orxonox/gamestates/GSGraphics.cc	(revision 3273)
+++ /code/branches/core4/src/orxonox/gamestates/GSGraphics.cc	(revision 3274)
@@ -38,6 +38,8 @@
 #include <OgreRenderWindow.h>
 
+#include "util/Convert.h"
 #include "core/ConfigValueIncludes.h"
 #include "core/Clock.h"
+#include "core/CommandExecutor.h"
 #include "core/ConsoleCommand.h"
 #include "core/Core.h"
@@ -47,5 +49,5 @@
 #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"
@@ -125,5 +127,5 @@
 
         // load master key bindings
-        masterInputState_ = InputManager::getInstance().createInputState<SimpleInputState>("master", true);
+        masterInputState_ = InputManager::getInstance().createInputState("master", true);
         masterKeyBinder_ = new KeyBinder();
         masterKeyBinder_->loadBindings("masterKeybindings.ini");
@@ -244,6 +246,6 @@
     {
         // OIS needs this under linux even if we only use relative input measurement.
-        if (this->inputManager_)
-            this->inputManager_->setWindowExtents(newWidth, newHeight);
+        // HACK:
+        CommandExecutor::execute("setWindowExtents_s " + multi_cast<std::string>(newWidth) + " " + multi_cast<std::string>(newHeight));
     }
 
Index: /code/branches/core4/src/orxonox/gamestates/GSGraphics.h
===================================================================
--- /code/branches/core4/src/orxonox/gamestates/GSGraphics.h	(revision 3273)
+++ /code/branches/core4/src/orxonox/gamestates/GSGraphics.h	(revision 3274)
@@ -75,5 +75,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/branches/core4/src/orxonox/gamestates/GSLevel.cc
===================================================================
--- /code/branches/core4/src/orxonox/gamestates/GSLevel.cc	(revision 3273)
+++ /code/branches/core4/src/orxonox/gamestates/GSLevel.cc	(revision 3274)
@@ -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());
 
Index: /code/branches/core4/src/orxonox/gamestates/GSLevel.h
===================================================================
--- /code/branches/core4/src/orxonox/gamestates/GSLevel.h	(revision 3273)
+++ /code/branches/core4/src/orxonox/gamestates/GSLevel.h	(revision 3274)
@@ -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/branches/core4/src/orxonox/gamestates/GSMainMenu.cc
===================================================================
--- /code/branches/core4/src/orxonox/gamestates/GSMainMenu.cc	(revision 3273)
+++ /code/branches/core4/src/orxonox/gamestates/GSMainMenu.cc	(revision 3274)
@@ -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
Index: /code/branches/core4/src/orxonox/gamestates/GSMainMenu.h
===================================================================
--- /code/branches/core4/src/orxonox/gamestates/GSMainMenu.h	(revision 3273)
+++ /code/branches/core4/src/orxonox/gamestates/GSMainMenu.h	(revision 3274)
@@ -53,5 +53,5 @@
 
     private:
-        SimpleInputState* inputState_;
+        InputState*       inputState_;
         Scene*            scene_;
         Ogre::Camera*     camera_;
Index: /code/branches/core4/src/orxonox/gui/GUIManager.cc
===================================================================
--- /code/branches/core4/src/orxonox/gui/GUIManager.cc	(revision 3273)
+++ /code/branches/core4/src/orxonox/gui/GUIManager.cc	(revision 3274)
@@ -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/branches/core4/src/orxonox/gui/GUIManager.h
===================================================================
--- /code/branches/core4/src/orxonox/gui/GUIManager.h	(revision 3273)
+++ /code/branches/core4/src/orxonox/gui/GUIManager.h	(revision 3274)
@@ -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/branches/core4/src/orxonox/overlays/console/InGameConsole.cc
===================================================================
--- /code/branches/core4/src/orxonox/overlays/console/InGameConsole.cc	(revision 3273)
+++ /code/branches/core4/src/orxonox/overlays/console/InGameConsole.cc	(revision 3274)
@@ -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"
 
@@ -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
@@ -175,5 +175,5 @@
     {
         // 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();
Index: /code/branches/core4/src/orxonox/overlays/console/InGameConsole.h
===================================================================
--- /code/branches/core4/src/orxonox/overlays/console/InGameConsole.h	(revision 3273)
+++ /code/branches/core4/src/orxonox/overlays/console/InGameConsole.h	(revision 3274)
@@ -101,5 +101,5 @@
 
         // input related
-        SimpleInputState* inputState_;
+        InputState* inputState_;
 
         // config values
