Index: code/branches/input/src/core/CMakeLists.txt
===================================================================
--- code/branches/input/src/core/CMakeLists.txt	(revision 1636)
+++ code/branches/input/src/core/CMakeLists.txt	(revision 1637)
@@ -41,4 +41,5 @@
   input/Button.cc
   input/CalibratorCallback.cc
+  input/ExtendedInputState.cc
   input/HalfAxis.cc
   input/InputBuffer.cc
@@ -47,4 +48,5 @@
   input/KeyBinder.cc
   input/KeyDetector.cc
+  input/SimpleInputState.cc
 
   tolua/tolua_bind.cc
Index: code/branches/input/src/core/CorePrereqs.h
===================================================================
--- code/branches/input/src/core/CorePrereqs.h	(revision 1636)
+++ code/branches/input/src/core/CorePrereqs.h	(revision 1637)
@@ -158,12 +158,13 @@
 
   // input
-  //class GUIInputHandler;
   class BaseCommand;
   class BufferedParamCommand;
   class Button;
   class CalibratorCallback;
+  class ExtendedInputState;
   class HalfAxis;
   class InputBuffer;
   class InputManager;
+  class InputState;
   class JoyStickHandler;
   class MouseHandler;
@@ -173,4 +174,5 @@
   class ParamCommand;
   class SimpleCommand;
+  class SimpleInputState;
 }
 
Index: code/branches/input/src/core/Shell.cc
===================================================================
--- code/branches/input/src/core/Shell.cc	(revision 1636)
+++ code/branches/input/src/core/Shell.cc	(revision 1637)
@@ -34,4 +34,6 @@
 #include "ConsoleCommand.h"
 #include "input/InputInterfaces.h"
+#include "input/SimpleInputState.h"
+#include "input/InputManager.h"
 
 #define SHELL_UPDATE_LISTENERS(function) \
@@ -57,10 +59,21 @@
         this->clearLines();
 
-        this->inputBuffer_ = 0;
-        this->setInputBuffer(new InputBuffer());
+        this->inputBuffer_ = new InputBuffer();
+        this->configureInputBuffer();
+        InputManager::createSimpleInputState("console", 40)->setKeyHandler(this->inputBuffer_);
 
         this->outputBuffer_.registerListener(this);
 
         this->setConfigValues();
+    }
+
+    Shell::~Shell()
+    {
+        SimpleInputState * inputState = dynamic_cast<SimpleInputState*>(InputManager::getState("console"));
+        if (inputState)
+        {
+            inputState->removeAndDestroyAllHandlers();
+            InputManager::destroyState("console");
+        }
     }
 
@@ -97,14 +110,6 @@
     }
 
-    void Shell::setInputBuffer(InputBuffer* buffer)
-    {
-        if (this->inputBuffer_)
-        {
-            this->inputBuffer_->unregisterListener(this);
-            // TODO: may be very dangerous. InputManager already deletes InputBuffer instance!!!
-            delete this->inputBuffer_;
-        }
-
-        this->inputBuffer_ = buffer;
+    void Shell::configureInputBuffer()
+    {
         this->inputBuffer_->registerListener(this, &Shell::inputChanged, true);
         this->inputBuffer_->registerListener(this, &Shell::execute, '\r', false);
Index: code/branches/input/src/core/Shell.h
===================================================================
--- code/branches/input/src/core/Shell.h	(revision 1636)
+++ code/branches/input/src/core/Shell.h	(revision 1637)
@@ -71,5 +71,4 @@
             void unregisterListener(ShellListener* listener);
 
-            void setInputBuffer(InputBuffer* buffer);
             inline InputBuffer& getInputBuffer()
                 { return (*this->inputBuffer_); }
@@ -105,5 +104,7 @@
             Shell();
             Shell(const Shell& other);
-            virtual ~Shell() {}
+            virtual ~Shell();
+
+            void configureInputBuffer();
 
             void addToHistory(const std::string& command);
Index: code/branches/input/src/core/input/Button.cc
===================================================================
--- code/branches/input/src/core/input/Button.cc	(revision 1636)
+++ code/branches/input/src/core/input/Button.cc	(revision 1637)
@@ -88,57 +88,57 @@
                     '\\', false, '"', false, '(', ')', false, '\0');
 
-                unsigned int iToken = 0;
-
-                // for real axes, we can feed a ButtonThreshold argument as entire command
-                if (getLowercase(tokens[0]) == "buttonthreshold")
-                {
-                    if (tokens.size() == 1)
-                        continue;
-                    // may fail, but doesn't matter
-                    convertValue(&buttonThreshold_, tokens[1]);
-                    continue;
-                }
-
-                // first argument can be OnPress, OnHold OnRelease or nothing
                 KeybindMode::Enum mode = KeybindMode::None;
-                if (getLowercase(tokens[iToken]) == "onpress")
-                    mode = KeybindMode::OnPress,   iToken++;
-                if (getLowercase(tokens[iToken]) == "onrelease")
-                    mode = KeybindMode::OnRelease, iToken++;
-                if (getLowercase(tokens[iToken]) == "onhold")
-                    mode = KeybindMode::OnHold,    iToken++;
-
-                if (iToken == tokens.size())
-                    continue;
-
-                // second argument can be the amplitude for the case it as an axis command
-                // default amplitude is 1.0f
                 float paramModifier = 1.0f;
-                if (getLowercase(tokens[iToken]) == "scale")
-                {
-                    iToken++;
-                    if (iToken == tokens.size() || !convertValue(&paramModifier, tokens[iToken]))
-                    {
-                        COUT(2) << "Error while parsing key binding " << name_
-                                << ". Numeric expression expected afer 'AxisAmp', switching to default value"
-                                << std::endl;
+                std::string commandStr = "";
+
+                for (unsigned int iToken = 0; iToken < tokens.size(); ++iToken)
+                {
+                    std::string token = getLowercase(tokens[iToken]);
+
+                    if (token == "onpress")
+                        mode = KeybindMode::OnPress;
+                    else if (token == "onrelease")
+                        mode = KeybindMode::OnRelease;
+                    else if (token == "onhold")
+                        mode = KeybindMode::OnHold;
+                    else if (token == "buttonthreshold")
+                    {
+                        // for real axes, we can feed a ButtonThreshold argument
+                        ++iToken;
                         if (iToken == tokens.size())
                             continue;
-                    }
-                    iToken++;
-                }
-
-                // no more arguments expected except for the actual command
-                if (iToken == tokens.size())
+                        // may fail, but doesn't matter (default value already set)
+                        if (!convertValue(&buttonThreshold_, tokens[iToken + 1]))
+                            parseError("Could not parse 'ButtonThreshold' argument. \
+                                Switching to default value.", true);
+                    }
+                    else if (token == "scale")
+                    {
+                        ++iToken;
+                        if (iToken == tokens.size() || !convertValue(&paramModifier, tokens[iToken]))
+                            parseError("Could not parse 'scale' argument. Switching to default value.", true);
+                    }
+                    else
+                    {
+                        // no input related argument
+                        // we interpret everything from here as a command string
+                        while (iToken != tokens.size())
+                            commandStr += tokens[iToken++] + " ";
+                    }
+                }
+
+                if (commandStr == "")
+                {
+                    parseError("No command string given.", false);
                     continue;
-
-                std::string commandStr;
-                while (iToken != tokens.size())
-                    commandStr += tokens[iToken++] + " ";
+                }
 
                 // evaluate the command
                 CommandEvaluation eval = CommandExecutor::evaluate(commandStr);
                 if (!eval.isValid())
+                {
+                    parseError("Command evaluation failed.", true);
                     continue;
+                }
 
                 // check for param command
@@ -215,3 +215,17 @@
         return true;
     }
+
+    inline void Button::parseError(std::string message, bool serious)
+    {
+        if (serious)
+        {
+            COUT(2) << "Error while parsing binding for button/axis" << this->name_ << ". "
+                << message << std::endl;
+        }
+        else
+        {
+            COUT(3) << "Warning while parsing binding for button/axis" << this->name_ << ". "
+                << message << std::endl;
+        }
+    }
 }
Index: code/branches/input/src/core/input/Button.h
===================================================================
--- code/branches/input/src/core/input/Button.h	(revision 1636)
+++ code/branches/input/src/core/input/Button.h	(revision 1637)
@@ -64,4 +64,7 @@
         //! Note: This variable is here to have only one parse() function.
         float buttonThreshold_;
+
+    private:
+        void parseError(std::string message, bool serious);
     };
 }
Index: code/branches/input/src/core/input/CalibratorCallback.cc
===================================================================
--- code/branches/input/src/core/input/CalibratorCallback.cc	(revision 1636)
+++ code/branches/input/src/core/input/CalibratorCallback.cc	(revision 1637)
@@ -42,5 +42,5 @@
         if (evt.key == KeyCode::Return)
         {
-            InputManager::setInputState(InputManager::IS_NOCALIBRATE);
+            //InputManager::setInputState(InputManager::IS_NOCALIBRATE);
         }
     }
Index: code/branches/input/src/core/input/CalibratorCallback.h
===================================================================
--- code/branches/input/src/core/input/CalibratorCallback.h	(revision 1636)
+++ code/branches/input/src/core/input/CalibratorCallback.h	(revision 1637)
@@ -52,5 +52,5 @@
         void keyHeld    (const KeyEvent& evt) { }
 
-        void tickInput(float dt, const HandlerState &state) { }
+        void tickInput(float dt) { }
     };
 }
Index: code/branches/input/src/core/input/ExtendedInputState.cc
===================================================================
--- code/branches/input/src/core/input/ExtendedInputState.cc	(revision 1637)
+++ code/branches/input/src/core/input/ExtendedInputState.cc	(revision 1637)
@@ -0,0 +1,472 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of the ExtendedInputState class.
+*/
+
+#include "ExtendedInputState.h"
+
+#include <assert.h>
+#include "core/Debug.h"
+
+namespace orxonox
+{
+    using namespace InputDevice;
+
+    void ExtendedInputState::numberOfJoySticksChanged(unsigned int n)
+    {
+        unsigned int oldSize = joyStickHandlers_.size();
+        joyStickHandlers_.resize(n);
+
+        if (oldSize > n)
+        {
+            // we have to add all the handlers in joyStickHandlersAll_ to the joyStickHandlers_[>n]
+            for (unsigned int j = 0; j < joyStickHandlersAll_.size(); ++j)
+            {
+                for (unsigned int i = oldSize; i < n; ++i)
+                {
+                    joyStickHandlers_[i].push_back(joyStickHandlersAll_[j]);
+                }
+            }
+        }
+        update();
+    }
+
+    void ExtendedInputState::keyPressed(const KeyEvent& evt)
+    {
+        for (unsigned int i = 0; i < keyHandlers_.size(); i++)
+            keyHandlers_[i]->keyPressed(evt);
+    }
+
+    void ExtendedInputState::keyReleased(const KeyEvent& evt)
+    {
+        for (unsigned int i = 0; i < keyHandlers_.size(); i++)
+            keyHandlers_[i]->keyReleased(evt);
+    }
+
+    void ExtendedInputState::keyHeld(const KeyEvent& evt)
+    {
+        for (unsigned int i = 0; i < keyHandlers_.size(); i++)
+            keyHandlers_[i]->keyHeld(evt);
+    }
+
+
+    void ExtendedInputState::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
+    {
+        for (unsigned int i = 0; i < mouseHandlers_.size(); i++)
+            mouseHandlers_[i]->mouseMoved(abs, rel, clippingSize);
+    }
+
+    void ExtendedInputState::mouseScrolled(int abs, int rel)
+    {
+        for (unsigned int i = 0; i < mouseHandlers_.size(); i++)
+            mouseHandlers_[i]->mouseScrolled(abs, rel);
+    }
+
+    void ExtendedInputState::mouseButtonPressed(MouseButton::Enum id)
+    {
+        for (unsigned int i = 0; i < mouseHandlers_.size(); i++)
+            mouseHandlers_[i]->mouseButtonPressed(id);
+    }
+
+    void ExtendedInputState::mouseButtonReleased(MouseButton::Enum id)
+    {
+        for (unsigned int i = 0; i < mouseHandlers_.size(); i++)
+            mouseHandlers_[i]->mouseButtonReleased(id);
+    }
+
+    void ExtendedInputState::mouseButtonHeld(MouseButton::Enum id)
+    {
+        for (unsigned int i = 0; i < mouseHandlers_.size(); i++)
+            mouseHandlers_[i]->mouseButtonHeld(id);
+    }
+
+
+    void ExtendedInputState::joyStickAxisMoved(unsigned int joyStickID, unsigned int axis, float value)
+    {
+        assert(joyStickID < joyStickHandlers_.size());
+        for (unsigned int i = 0; i < joyStickHandlers_[joyStickID].size(); i++)
+            joyStickHandlers_[joyStickID][i]->joyStickAxisMoved(joyStickID, axis, value);
+    }
+
+    void ExtendedInputState::joyStickButtonPressed(unsigned int joyStickID, unsigned int button)
+    {
+        assert(joyStickID < joyStickHandlers_.size());
+        for (unsigned int i = 0; i < joyStickHandlers_[joyStickID].size(); i++)
+            joyStickHandlers_[joyStickID][i]->joyStickButtonPressed(joyStickID, button);
+    }
+
+    void ExtendedInputState::joyStickButtonReleased(unsigned int joyStickID, unsigned int button)
+    {
+        assert(joyStickID < joyStickHandlers_.size());
+        for (unsigned int i = 0; i < joyStickHandlers_[joyStickID].size(); i++)
+            joyStickHandlers_[joyStickID][i]->joyStickButtonReleased(joyStickID, button);
+    }
+
+    void ExtendedInputState::joyStickButtonHeld(unsigned int joyStickID, unsigned int button)
+    {
+        assert(joyStickID < joyStickHandlers_.size());
+        for (unsigned int i = 0; i < joyStickHandlers_[joyStickID].size(); i++)
+            joyStickHandlers_[joyStickID][i]->joyStickButtonHeld(joyStickID, button);
+    }
+
+
+    /**
+    @brief
+        Adds a key handler.
+    @param handler
+        Pointer to the handler object.
+    @return
+        True if added, false if handler already existed.
+    */
+    bool ExtendedInputState::addKeyHandler(KeyHandler* handler)
+    {
+        if (!handler)
+            return false;
+
+        // see whether the handler already is in the list
+        for (std::vector<KeyHandler*>::iterator it = keyHandlers_.begin(); it != keyHandlers_.end(); it++)
+        {
+            if ((*it) == handler)
+            {
+                return false;
+            }
+        }
+        keyHandlers_.push_back(handler);
+        update();
+        return true;
+    }
+
+    /**
+    @brief
+        Removes a Key handler from the state.
+    @param handler
+        Pointer to the handler.
+    @return
+        True if removal was successful, false if handler was not found.
+    */
+    bool ExtendedInputState::removeKeyHandler(KeyHandler* handler)
+    {
+        if (!handler)
+            return false;
+
+        for (std::vector<KeyHandler*>::iterator it = keyHandlers_.begin(); it != keyHandlers_.end(); it++)
+        {
+            if ((*it) == handler)
+            {
+                keyHandlers_.erase(it);
+                update();
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    /**
+    @brief
+        Adds a mouse handler.
+    @param handler
+        Pointer to the handler object.
+    @return
+        True if added, false if handler already existed.
+    */
+    bool ExtendedInputState::addMouseHandler(MouseHandler* handler)
+    {
+        if (!handler)
+            return false;
+
+        // see whether the handler already is in the list
+        for (std::vector<MouseHandler*>::iterator it = mouseHandlers_.begin(); it != mouseHandlers_.end(); it++)
+        {
+            if ((*it) == handler)
+            {
+                return false;
+            }
+        }
+        mouseHandlers_.push_back(handler);
+        update();
+        return true;
+    }
+
+    /**
+    @brief
+        Removes a mouse handler from the state.
+    @param handler
+        Pointer to the handler.
+    @return
+        True if removal was successful, false if handler was not found.
+    */
+    bool ExtendedInputState::removeMouseHandler(MouseHandler* handler)
+    {
+        if (!handler)
+            return false;
+
+        for (std::vector<MouseHandler*>::iterator it = mouseHandlers_.begin(); it != mouseHandlers_.end(); it++)
+        {
+            if ((*it) == handler)
+            {
+                mouseHandlers_.erase(it);
+                update();
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    /**
+    @brief
+        Adds a joy stick handler.
+    @param handler
+        Pointer to the handler object.
+    @param joyStickID
+        ID of the joy stick
+    @return
+        True if added, false if handler already existed.
+    */
+    bool ExtendedInputState::addJoyStickHandler(JoyStickHandler* handler, unsigned int joyStickID)
+    {
+        if (!handler || joyStickID >= joyStickHandlers_.size())
+            return false;
+
+        // see whether the handler already is in the list
+        for (std::vector<JoyStickHandler*>::iterator it = joyStickHandlers_[joyStickID].begin();
+            it != joyStickHandlers_[joyStickID].end(); it++)
+        {
+            if ((*it) == handler)
+            {
+                return false;
+            }
+        }
+        joyStickHandlers_[joyStickID].push_back(handler);
+        update();
+        return true;
+    }
+
+    /**
+    @brief
+        Removes a joy stick handler from the state.
+    @param handler
+        Pointer to the handler.
+    @param joyStickID
+        ID of the joy stick
+    @return
+        True if removal was successful, false if handler was not found.
+    */
+    bool ExtendedInputState::removeJoyStickHandler(JoyStickHandler* handler, unsigned int joyStickID)
+    {
+        if (!handler || joyStickID >= joyStickHandlers_.size())
+            return false;
+
+        // remove it from the list of all-joystick handlers if present
+        for (std::vector<JoyStickHandler*>::iterator it = joyStickHandlersAll_.begin();
+            it != joyStickHandlersAll_.end(); it++)
+        {
+            if ((*it) == handler)
+            {
+                joyStickHandlersAll_.erase(it);
+            }
+        }
+
+        // remove handler from the list of seperate lists of handlers
+        for (std::vector<JoyStickHandler*>::iterator it = joyStickHandlers_[joyStickID].begin();
+            it != joyStickHandlers_[joyStickID].end(); it++)
+        {
+            if ((*it) == handler)
+            {
+                joyStickHandlers_[joyStickID].erase(it);
+                update();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+    @brief
+        Adds a joy stick handler.
+    @param handler
+        Pointer to the handler object.
+    @return
+        True if added, false if handler already existed.
+    */
+    bool ExtendedInputState::addJoyStickHandler(JoyStickHandler* handler)
+    {
+        if (!handler)
+            return false;
+
+        // see whether the handler already is in the big list
+        for (std::vector<JoyStickHandler*>::iterator it = joyStickHandlersAll_.begin();
+            it != joyStickHandlersAll_.end(); it++)
+        {
+            if ((*it) == handler)
+            {
+                return false;
+            }
+        }
+        joyStickHandlersAll_.push_back(handler);
+        update();
+
+        // now, we have to add it to all the separate lists
+        for (unsigned int iJoyStick = 0; iJoyStick < joyStickHandlers_.size(); ++iJoyStick)
+            addJoyStickHandler(handler, iJoyStick);
+        return true;
+    }
+
+    /**
+    @brief
+        Removes a joy stick handler from the state.
+    @param handler
+        Pointer to the handler.
+    @return
+        True if removal was successful, false if handler was not found.
+    */
+    bool ExtendedInputState::removeJoyStickHandler(JoyStickHandler* handler)
+    {
+        if (!handler)
+            return false;
+
+        bool success = false;
+        // remove from all lists in a loop (also removes it from the big list)
+        for (unsigned int iJoyStick = 0; iJoyStick < joyStickHandlers_.size(); ++iJoyStick)
+            success |= removeJoyStickHandler(handler, iJoyStick);
+
+        return success;
+    }
+
+    void ExtendedInputState::removeAndDestroyAllHandlers()
+    {
+        for (std::vector<InputTickable*>::iterator it = allHandlers_.begin();
+            it != allHandlers_.end(); ++it)
+            delete *it;
+
+        allHandlers_.clear();
+        keyHandlers_.clear();
+        mouseHandlers_.clear();
+        joyStickHandlersAll_.clear();
+        for (unsigned int iJoyStick = 0; iJoyStick < joyStickHandlers_.size(); ++iJoyStick)
+            joyStickHandlers_[iJoyStick].clear();
+        update();
+    }
+
+    /**
+    @brief
+        Adds a handler of any kind. dynamic_cast determines to which list it is added.
+    @param handler
+        Pointer to the handler object.
+    @return
+        True if added, false if handler already existed.
+    */
+    bool ExtendedInputState::addHandler(InputTickable* handler)
+    {
+        bool success = false;
+
+        success |= addKeyHandler(dynamic_cast<KeyHandler*>(handler));
+        success |= addMouseHandler(dynamic_cast<MouseHandler*>(handler));
+        success |= addJoyStickHandler(dynamic_cast<JoyStickHandler*>(handler));
+
+        return success;
+    }
+
+    /**
+    @brief
+        Removes a handler from all lists.
+    @param handler
+        Pointer to the handler.
+    @return
+        True if removal was successful, false if handler was not found.
+    */
+    bool ExtendedInputState::removeHandler(InputTickable* handler)
+    {
+        bool success = false;
+
+        success |= removeKeyHandler(dynamic_cast<KeyHandler*>(handler));
+        success |= removeMouseHandler(dynamic_cast<MouseHandler*>(handler));
+        success |= removeJoyStickHandler(dynamic_cast<JoyStickHandler*>(handler));
+
+        return success;
+    }
+
+    void ExtendedInputState::tickInput(float dt)
+    {
+        for (unsigned int i = 0; i < allHandlers_.size(); ++i)
+        {
+            allHandlers_[i]->tickInput(dt);
+        }
+    }
+
+    void ExtendedInputState::tickInput(float dt, unsigned int device)
+    {
+        switch (device)
+        {
+        case Keyboard:
+            for (unsigned int i = 0; i < keyHandlers_.size(); ++i)
+                keyHandlers_[i]->tickKey(dt);
+            break;
+
+        case Mouse:
+            for (unsigned int i = 0; i < mouseHandlers_.size(); ++i)
+                mouseHandlers_[i]->tickMouse(dt);
+            break;
+
+        default: // joy sticks
+            for (unsigned int i = 0; i < joyStickHandlers_[device - 2].size(); ++i)
+                joyStickHandlers_[device - 2][i]->tickJoyStick(dt, device - 2);
+            break;
+        }
+    }
+
+    void ExtendedInputState::update()
+    {
+        // we can use a set to have a list of unique pointers (an object can implement all 3 handlers)
+        std::set<InputTickable*> tempSet;
+        for (unsigned int iHandler = 0; iHandler < keyHandlers_.size(); iHandler++)
+            tempSet.insert(keyHandlers_[iHandler]);
+        for (unsigned int iHandler = 0; iHandler < mouseHandlers_.size(); iHandler++)
+            tempSet.insert(mouseHandlers_[iHandler]);
+        for (unsigned int iJoyStick = 0; iJoyStick < joyStickHandlers_.size(); iJoyStick++)
+            for (unsigned int iHandler = 0; iHandler < joyStickHandlers_[iJoyStick].size(); iHandler++)
+                tempSet.insert(joyStickHandlers_[iJoyStick][iHandler]);
+
+        // copy the content of the map back to the actual vector
+        allHandlers_.clear();
+        for (std::set<InputTickable*>::const_iterator itHandler = tempSet.begin();
+            itHandler != tempSet.end(); itHandler++)
+            allHandlers_.push_back(*itHandler);
+
+        // update the deviceEnabled options
+        setInputDeviceEnabled(Keyboard, (keyHandlers_.size() != 0));
+        setInputDeviceEnabled(Mouse, (mouseHandlers_.size() != 0));
+        for (unsigned int i = 0; i < joyStickHandlers_.size(); ++i)
+            setInputDeviceEnabled(2 + i, (joyStickHandlers_[i].size() != 0));
+    }
+}
Index: code/branches/input/src/core/input/ExtendedInputState.h
===================================================================
--- code/branches/input/src/core/input/ExtendedInputState.h	(revision 1637)
+++ code/branches/input/src/core/input/ExtendedInputState.h	(revision 1637)
@@ -0,0 +1,100 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief 
+*/
+
+#ifndef _ExtendedInputState_H__
+#define _ExtendedInputState_H__
+
+#include "core/CorePrereqs.h"
+
+#include <vector>
+
+#include "InputInterfaces.h"
+#include "InputState.h"
+
+namespace orxonox
+{
+
+    class _CoreExport ExtendedInputState : public InputState
+    {
+    public:
+        ExtendedInputState() { }
+        ~ExtendedInputState() { }
+
+        bool addKeyHandler        (KeyHandler* handler);
+        bool removeKeyHandler     (KeyHandler* handler);
+
+        bool addMouseHandler      (MouseHandler* handler);
+        bool removeMouseHandler   (MouseHandler* handler);
+
+        bool addJoyStickHandler   (JoyStickHandler* handler, unsigned int joyStickID);
+        bool removeJoyStickHandler(JoyStickHandler* handler, unsigned int joyStickID);
+        bool addJoyStickHandler   (JoyStickHandler* handler);
+        bool removeJoyStickHandler(JoyStickHandler* handler);
+
+        bool addHandler(InputTickable* handler);
+        bool removeHandler(InputTickable* handler);
+
+        void removeAndDestroyAllHandlers();
+
+    private:
+        void tickInput(float dt);
+        void tickInput(float dt, unsigned int device);
+
+        void keyPressed (const KeyEvent& evt);
+        void keyReleased(const KeyEvent& evt);
+        void keyHeld    (const KeyEvent& evt);
+
+        void mouseButtonPressed (MouseButton::Enum id);
+        void mouseButtonReleased(MouseButton::Enum id);
+        void mouseButtonHeld    (MouseButton::Enum id);
+        void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
+        void mouseScrolled      (int abs, int rel);
+
+        void joyStickButtonPressed (unsigned int joyStickID, unsigned int button);
+        void joyStickButtonReleased(unsigned int joyStickID, unsigned int button);
+        void joyStickButtonHeld    (unsigned int joyStickID, unsigned int button);
+        void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value);        void updateTickables();
+
+        void numberOfJoySticksChanged(unsigned int n);
+        void update();
+
+        std::vector<KeyHandler*>                    keyHandlers_;
+        std::vector<MouseHandler*>                  mouseHandlers_;
+        std::vector<std::vector<JoyStickHandler*> > joyStickHandlers_;
+        std::vector<JoyStickHandler*>               joyStickHandlersAll_;
+
+        std::vector<InputTickable*> allHandlers_;
+    };
+}
+
+#endif /* _ExtendedInputState_H__ */
Index: code/branches/input/src/core/input/InputBuffer.cc
===================================================================
--- code/branches/input/src/core/input/InputBuffer.cc	(revision 1636)
+++ code/branches/input/src/core/input/InputBuffer.cc	(revision 1637)
@@ -220,5 +220,5 @@
         @param dt Delta time
     */
-    void InputBuffer::tickInput(float dt, const HandlerState& state)
+    void InputBuffer::tickInput(float dt)
     {
         timeSinceKeyPressed_ += dt;
Index: code/branches/input/src/core/input/InputBuffer.h
===================================================================
--- code/branches/input/src/core/input/InputBuffer.h	(revision 1636)
+++ code/branches/input/src/core/input/InputBuffer.h	(revision 1637)
@@ -170,5 +170,6 @@
             void processKey (const KeyEvent &e);
 
-            void tickInput(float dt, const HandlerState& state);
+            void tickInput(float dt);
+            void tickInput(float dt, int device) { }
 
             std::string buffer_;
Index: code/branches/input/src/core/input/InputInterfaces.h
===================================================================
--- code/branches/input/src/core/input/InputInterfaces.h	(revision 1636)
+++ code/branches/input/src/core/input/InputInterfaces.h	(revision 1637)
@@ -38,7 +38,7 @@
 #include "core/CorePrereqs.h"
 
-#include "src/ois/OISKeyboard.h"
-#include "src/ois/OISMouse.h"
-#include "src/ois/OISJoyStick.h"
+#include "ois/OISKeyboard.h"
+#include "ois/OISMouse.h"
+#include "ois/OISJoyStick.h"
 #include "util/Math.h"
 
@@ -222,4 +222,18 @@
         };
     }
+    
+    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
@@ -265,11 +279,11 @@
         multiple handlers) are active.
     */
-    struct HandlerState
-    {
-        HandlerState() : key(false), mouse(false), joyStick(false) { }
-        bool key;
-        bool mouse;
-        bool joyStick;
-    };
+    //struct HandlerState
+    //{
+    //    HandlerState() : keyboard(false), mouse(false) { }
+    //    bool keyboard;
+    //    bool mouse;
+    //    std::vector<bool> joySticks;
+    //};
 
     class _CoreExport InputTickable
@@ -277,5 +291,6 @@
     public:
         virtual ~InputTickable() { }
-        virtual void tickInput(float dt, const HandlerState& state) = 0;
+        virtual void tickInput(float dt) = 0;
+        //virtual void tickInput(float dt, unsigned int device) = 0;
     };
 
@@ -291,5 +306,5 @@
         virtual void keyReleased(const KeyEvent& evt) = 0;
         virtual void keyHeld    (const KeyEvent& evt) = 0;
-        //virtual void tickKey    (float dt) { }
+        virtual void tickKey    (float dt) { }
     };
 
@@ -307,5 +322,5 @@
         virtual void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0;
         virtual void mouseScrolled      (int abs, int rel)     = 0;
-        //virtual void tickMouse          (float dt) { }
+        virtual void tickMouse          (float dt) { }
     };
 
@@ -319,10 +334,32 @@
     public:
         virtual ~JoyStickHandler() { }
-        virtual void joyStickButtonPressed (int joyStickID, int button) = 0;
-        virtual void joyStickButtonReleased(int joyStickID, int button) = 0;
-        virtual void joyStickButtonHeld    (int joyStickID, int button) = 0;
-        virtual void joyStickAxisMoved     (int joyStickID, int axis, float value) = 0;
-        //virtual bool joyStickVector3Moved  (int joyStickID, int index /*, fill list*/) {return true;}
-        //virtual void tickJoyStick          (float dt) { }
+        virtual void joyStickButtonPressed (unsigned int joyStickID, unsigned int button) = 0;
+        virtual void joyStickButtonReleased(unsigned int joyStickID, unsigned int button) = 0;
+        virtual void joyStickButtonHeld    (unsigned int joyStickID, unsigned int button) = 0;
+        virtual void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) = 0;
+        //virtual bool joyStickVector3Moved  (unsigned int joyStickID, unsigned int index /*, fill list*/) {return true;}
+        virtual void tickJoyStick          (float dt, unsigned int device) { }
+    };
+
+    class _CoreExport EmptyHandler : public KeyHandler, public MouseHandler, public JoyStickHandler
+    {
+    private:
+        void tickInput(float dt) { }
+        void tickInput(float dt, unsigned int device) { }
+
+        void keyPressed (const KeyEvent& evt) { }
+        void keyReleased(const KeyEvent& evt) { }
+        void keyHeld    (const KeyEvent& evt) { }
+
+        void mouseButtonPressed (MouseButton::Enum id) { }
+        void mouseButtonReleased(MouseButton::Enum id) { }
+        void mouseButtonHeld    (MouseButton::Enum id) { }
+        void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) { }
+        void mouseScrolled      (int abs, int rel) { }
+
+        void joyStickButtonPressed (unsigned int joyStickID, unsigned int button) { }
+        void joyStickButtonReleased(unsigned int joyStickID, unsigned int button) { }
+        void joyStickButtonHeld    (unsigned int joyStickID, unsigned int button) { }
+        void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) { }
     };
 
Index: code/branches/input/src/core/input/InputManager.cc
===================================================================
--- code/branches/input/src/core/input/InputManager.cc	(revision 1636)
+++ code/branches/input/src/core/input/InputManager.cc	(revision 1637)
@@ -38,4 +38,7 @@
 #include <limits.h>
 
+#include "ois/OISException.h"
+#include "ois/OISInputManager.h"
+
 #include "core/CoreIncludes.h"
 #include "core/ConfigValueIncludes.h"
@@ -43,5 +46,4 @@
 #include "core/CommandExecutor.h"
 #include "core/ConsoleCommand.h"
-#include "core/Shell.h"               // hack!
 
 #include "InputBuffer.h"
@@ -49,7 +51,7 @@
 #include "KeyDetector.h"
 #include "CalibratorCallback.h"
-
-#include "src/ois/OISException.h"
-#include "src/ois/OISInputManager.h"
+#include "InputState.h"
+#include "SimpleInputState.h"
+#include "ExtendedInputState.h"
 
 namespace orxonox
@@ -59,4 +61,6 @@
     SetConsoleCommandShortcut(InputManager, calibrate);
 
+    using namespace InputDevice;
+
     // ###############################
     // ###    Internal Methods     ###
@@ -74,12 +78,10 @@
         , mouse_(0)
         , joySticksSize_(0)
-        , keyBinder_(0)
-        , keyDetector_(0)
-        , buffer_(0)
-        , calibratorCallback_(0)
-        , state_(IS_UNINIT)
-        , stateRequest_(IS_UNINIT)
-        , savedState_(IS_UNINIT)
+        , devicesNum_(0)
+        , stateDetector_(0)
+        , stateCalibrator_(0)
+        , stateEmpty_(0)
         , keyboardModifiers_(0)
+        , bCalibrating_(false)
     {
         RegisterRootObject(InputManager);
@@ -92,5 +94,5 @@
         A reference to the only instance of the InputManager
     */
-    InputManager& InputManager::_getSingleton()
+    InputManager& InputManager::_getInstance()
     {
         static InputManager theOnlyInstance;
@@ -106,4 +108,10 @@
         _destroy();
     }
+
+
+    // ############################################################
+    // #####                  Initialisation                  #####
+    // ##########                                        ##########
+    // ############################################################
 
     /**
@@ -121,5 +129,5 @@
                                    bool createKeyboard, bool createMouse, bool createJoySticks)
     {
-        if (state_ == IS_UNINIT)
+        if (inputSystem_ == 0)
         {
             CCOUT(3) << "Initialising Input System..." << std::endl;
@@ -160,4 +168,7 @@
                 _initialiseJoySticks();
 
+            // set all the std::vector list sizes now that the devices have been created
+            _redimensionLists();
+
             // Set mouse/joystick region
             if (mouse_)
@@ -166,28 +177,29 @@
             }
 
-            state_ = IS_NONE;
             CCOUT(ORX_DEBUG) << "Initialising OIS components done." << std::endl;
 
             // InputManager holds the input buffer --> create one and add it.
-            buffer_ = new InputBuffer();
-            addKeyHandler(buffer_, "buffer");
-            Shell::getInstance().setInputBuffer(buffer_);
-
-            keyBinder_ = new KeyBinder();
-            keyBinder_->loadBindings();
-            addKeyHandler(keyBinder_, "keybinder");
-            addMouseHandler(keyBinder_, "keybinder");
-            addJoyStickHandler(keyBinder_, "keybinder");
-
-            keyDetector_ = new KeyDetector();
-            keyDetector_->loadBindings();
-            addKeyHandler(keyDetector_, "keydetector");
-            addMouseHandler(keyDetector_, "keydetector");
-            addJoyStickHandler(keyDetector_, "keydetector");
-
-            calibratorCallback_ = new CalibratorCallback();
-            addKeyHandler(calibratorCallback_, "calibratorcallback");
+            //buffer_ = new InputBuffer();
+            //addKeyHandler(buffer_, "buffer");
+            //Shell::getInstance().setInputBuffer(buffer_);
 
             setConfigValues();
+
+            stateEmpty_ = createSimpleInputState("empty", -1);
+            stateEmpty_->setHandler(new EmptyHandler());
+            activeStates_[stateEmpty_->getPriority()] = stateEmpty_;
+
+            stateDetector_ = createSimpleInputState("detector", 101);
+            KeyDetector* temp = new KeyDetector();
+            temp->loadBindings("storeKeyStroke");
+            stateDetector_->setHandler(temp);
+
+            stateCalibrator_ = createSimpleInputState("calibrator", 100);
+            stateCalibrator_->setHandler(new EmptyHandler());
+            InputBuffer* buffer = new InputBuffer();
+            buffer->registerListener(this, &InputManager::_completeCalibration, '\r', true);
+            stateCalibrator_->setKeyHandler(buffer);
+
+            _updateActiveStates();
 
             CCOUT(ORX_DEBUG) << "Initialising complete." << std::endl;
@@ -232,5 +244,4 @@
         catch (OIS::Exception ex)
         {
-            // TODO: Test this output regarding formatting
             CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS keyboard\n"
                 << "OIS error message: \"" << ex.eText << "\"" << std::endl;
@@ -300,8 +311,8 @@
                     OIS::JoyStick* stig = static_cast<OIS::JoyStick*>
                         (inputSystem_->createInputObject(OIS::OISJoyStick, true));
+                    CCOUT(ORX_DEBUG) << "Created OIS joy stick with ID " << stig->getID() << std::endl;
                     joySticks_.push_back(stig);
                     // register our listener in OIS.
                     stig->setEventCallback(this);
-                    CCOUT(ORX_DEBUG) << "Created OIS joy stick with ID " << stig->getID() << std::endl;
                     success = true;
                 }
@@ -318,10 +329,16 @@
             return false;
         }
+        return success;
+    }
+
+    void InputManager::_redimensionLists()
+    {
         joySticksSize_ = joySticks_.size();
-        activeJoyStickHandlers_.resize(joySticksSize_);
-        joyStickButtonsDown_.resize(joySticksSize_);
-        povStates_.resize(joySticksSize_);
-        sliderStates_.resize(joySticksSize_);
+        devicesNum_ = 2 + joySticksSize_;
+        joyStickButtonsDown_ .resize(joySticksSize_);
+        povStates_           .resize(joySticksSize_);
+        sliderStates_        .resize(joySticksSize_);
         joySticksCalibration_.resize(joySticksSize_);
+
         for (unsigned int iJoyStick = 0; iJoyStick < joySticksSize_; iJoyStick++)
         {
@@ -334,5 +351,12 @@
             }
         }
-        return success;
+
+        // state management
+        activeStatesTop_.resize(devicesNum_);
+
+        // inform all registered states
+        for (std::map<int, InputState*>::const_iterator it = inputStatesByPriority_.begin();
+            it != inputStatesByPriority_.end(); ++it)
+            (*it).second->setNumOfJoySticks(joySticksSize_);
     }
 
@@ -392,4 +416,10 @@
     }
 
+
+    // ############################################################
+    // #####                    Destruction                   #####
+    // ##########                                        ##########
+    // ############################################################
+
     /**
     @brief
@@ -398,35 +428,40 @@
     void InputManager::_destroy()
     {
-        if (state_ != IS_UNINIT)
+        if (inputSystem_)
         {
             CCOUT(ORX_DEBUG) << "Destroying ..." << std::endl;
 
-            if (buffer_)
-                delete buffer_;
-
-            if (keyBinder_)
-                delete keyBinder_;
-
-            if (keyDetector_)
-                delete keyDetector_;
-
-            if (calibratorCallback_)
-                delete calibratorCallback_;
-
-            keyHandlers_.clear();
-            mouseHandlers_.clear();
-            joyStickHandlers_.clear();
-
+            // kick all active states 'nicely'
+            for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
+                rit != activeStates_.rend(); ++rit)
+                (*rit).second->onLeave();
+            activeStates_.clear();
+
+            // destroy our own states
+            stateEmpty_->removeAndDestroyAllHandlers();
+            stateCalibrator_->removeAndDestroyAllHandlers();
+            stateDetector_->removeAndDestroyAllHandlers();
+            _destroyState(stateEmpty_);
+            _destroyState(stateCalibrator_);
+            _destroyState(stateDetector_);
+            stateEmpty_ = 0;
+            stateCalibrator_ = 0;
+            stateDetector_ = 0;
+
+            // we don't remove the other states yet because the singleton might still exist.
+            // So people can still removeAndDestroy their states
+            //inputStatesByName_.clear();
+            //inputStatesByPriority_.clear();
+
+            // destroy the devices
             _destroyKeyboard();
             _destroyMouse();
             _destroyJoySticks();
 
-            activeHandlers_.clear();
-
-            // inputSystem_ can never be 0, or else the code is mistaken
+            _redimensionLists();
+
             OIS::InputManager::destroyInputSystem(inputSystem_);
             inputSystem_ = 0;
 
-            state_ = IS_UNINIT;
             CCOUT(ORX_DEBUG) << "Destroying done." << std::endl;
         }
@@ -442,5 +477,4 @@
             inputSystem_->destroyInputObject(keyboard_);
         keyboard_ = 0;
-        activeKeyHandlers_.clear();
         keysDown_.clear();
         CCOUT(ORX_DEBUG) << "Keyboard destroyed." << std::endl;
@@ -456,5 +490,4 @@
             inputSystem_->destroyInputObject(mouse_);
         mouse_ = 0;
-        activeMouseHandlers_.clear();
         mouseButtonsDown_.clear();
         CCOUT(ORX_DEBUG) << "Mouse destroyed." << std::endl;
@@ -475,58 +508,25 @@
 
             joySticks_.clear();
-            joySticksSize_ = 0;
-            activeJoyStickHandlers_.clear();
-            joyStickButtonsDown_.clear();
-            povStates_.clear();
-            sliderStates_.clear();
-            joySticksCalibration_.clear();
         }
         CCOUT(ORX_DEBUG) << "Joy sticks destroyed." << std::endl;
     }
 
-    void InputManager::_saveState()
-    {
-        savedHandlers_.activeHandlers_ = activeHandlers_;
-        savedHandlers_.activeJoyStickHandlers_ = activeJoyStickHandlers_;
-        savedHandlers_.activeKeyHandlers_ = activeKeyHandlers_;
-        savedHandlers_.activeMouseHandlers_ = activeMouseHandlers_;
-    }
-
-    void InputManager::_restoreState()
-    {
-        activeHandlers_ = savedHandlers_.activeHandlers_;
-        activeJoyStickHandlers_ = savedHandlers_.activeJoyStickHandlers_;
-        activeKeyHandlers_ = savedHandlers_.activeKeyHandlers_;
-        activeMouseHandlers_ = savedHandlers_.activeMouseHandlers_;
-    }
-
-    void InputManager::_updateTickables()
-    {
-        // we can use a map to have a list of unique pointers (an object can implement all 3 handlers)
-        std::map<InputTickable*, HandlerState> tempSet;
-        for (unsigned int iHandler = 0; iHandler < activeKeyHandlers_.size(); iHandler++)
-            tempSet[activeKeyHandlers_[iHandler]].joyStick = true;
-        for (unsigned int iHandler = 0; iHandler < activeMouseHandlers_.size(); iHandler++)
-            tempSet[activeMouseHandlers_[iHandler]].mouse = true;
-        for (unsigned int iJoyStick  = 0; iJoyStick < joySticksSize_; iJoyStick++)
-            for (unsigned int iHandler = 0; iHandler  < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
-                tempSet[activeJoyStickHandlers_[iJoyStick][iHandler]].joyStick = true;
-
-        // copy the content of the map back to the actual vector
-        activeHandlers_.clear();
-        for (std::map<InputTickable*, HandlerState>::const_iterator itHandler = tempSet.begin();
-            itHandler != tempSet.end(); itHandler++)
-            activeHandlers_.push_back(std::pair<InputTickable*, HandlerState>((*itHandler).first, (*itHandler).second));
-    }
-
-
-    // #################################
-    // ### Private Interface Methods ###
-    // #################################
-    // #################################
-
-    /**
-    @brief
-        Updates the InputManager. Tick is called by Orxonox.
+    void InputManager::_destroyState(InputState* state)
+    {
+        assert(state);
+        inputStatesByPriority_.erase(state->getPriority());
+        inputStatesByName_.erase(state->getName());
+        delete state;
+    }
+
+
+    // ############################################################
+    // #####                  Runtime Methods                 #####
+    // ##########                                        ##########
+    // ############################################################
+
+    /**
+    @brief
+        Updates the InputManager. Tick is called by the Core class.
     @param dt
         Delta time
@@ -534,155 +534,83 @@
     void InputManager::_tick(float dt)
     {
-        if (state_ == IS_UNINIT)
+        if (inputSystem_ == 0)
             return;
 
-        if (state_ != stateRequest_)
-        {
-            InputState sr = stateRequest_;
-            switch (sr)
-            {
-            case IS_NORMAL:
-                activeKeyHandlers_.clear();
-                activeMouseHandlers_.clear();
-                for (unsigned int i = 0; i < joySticksSize_; i++)
-                    activeJoyStickHandlers_[i].clear();
-
-                // normal play mode
-                // note: we assume that the handlers exist since otherwise, something's wrong anyway.
-                enableKeyHandler("keybinder");
-                enableMouseHandler("keybinder");
-                enableJoyStickHandler("keybinder", 0);
-                stateRequest_ = IS_NORMAL;
-                state_ = IS_NORMAL;
-                break;
-
-            case IS_GUI:
-                state_ = IS_GUI;
-                break;
-
-            case IS_CONSOLE:
-                activeKeyHandlers_.clear();
-                activeMouseHandlers_.clear();
-                for (unsigned int i = 0; i < joySticksSize_; i++)
-                    activeJoyStickHandlers_[i].clear();
-
-                enableMouseHandler("keybinder");
-                enableJoyStickHandler("keybinder", 0);
-                enableKeyHandler("buffer");
-                stateRequest_ = IS_CONSOLE;
-                state_ = IS_CONSOLE;
-                break;
-
-            case IS_DETECT:
-                savedState_ = state_;
-                _saveState();
-
-                activeKeyHandlers_.clear();
-                activeMouseHandlers_.clear();
-                for (unsigned int i = 0; i < joySticksSize_; i++)
-                    activeJoyStickHandlers_[i].clear();
-
-                enableKeyHandler("keydetector");
-                enableMouseHandler("keydetector");
-                enableJoyStickHandler("keydetector", 0);
-
-                stateRequest_ = IS_DETECT;
-                state_ = IS_DETECT;
-                break;
-
-            case IS_NODETECT:
-                _restoreState();
-                keysDown_.clear();
-                mouseButtonsDown_.clear();
-                for (unsigned int i = 0; i < joySticksSize_; i++)
-                    joyStickButtonsDown_[i].clear();
-                state_ = IS_NODETECT;
-                stateRequest_ = savedState_;
-                break;
-
-            case IS_CALIBRATE:
-                if (joySticksSize_)
-                {
-                    savedState_ = _getSingleton().state_;
-                    for (unsigned int i = 0; i < 24; i++)
-                    {
-                        marginalsMax_[i] = INT_MIN;
-                        marginalsMin_[i] = INT_MAX;
-                    }
-                    COUT(0) << "Move all joy stick axes in all directions a few times. "
-                            << "Then put all axes in zero state and hit enter." << std::endl;
-
-                    savedState_ = state_;
-                    _saveState();
-
-                    activeKeyHandlers_.clear();
-                    activeMouseHandlers_.clear();
-                    for (unsigned int i = 0; i < joySticksSize_; i++)
-                        activeJoyStickHandlers_[i].clear();
-
-                    enableKeyHandler("calibratorcallback");
-                    stateRequest_ = IS_CALIBRATE;
-                    state_ = IS_CALIBRATE;
-                }
-                else
-                {
-                    COUT(3) << "Connot calibrate, no joy stick found!" << std::endl;
-                    stateRequest_ = state_;
-                }
-                break;
-
-            case IS_NOCALIBRATE:
-                _completeCalibration();
-                _restoreState();
-                keyBinder_->resetJoyStickAxes();
-                state_ = IS_NOCALIBRATE;
-                stateRequest_ = savedState_;
-                break;
-
-            case IS_NONE:
-                activeKeyHandlers_.clear();
-                activeMouseHandlers_.clear();
-                for (unsigned int i = 0; i < joySticksSize_; i++)
-                    activeJoyStickHandlers_[i].clear();
-                state_ = IS_NONE;
-
-            default:
-                break;
-            }
+        // check for states to leave (don't use unsigned int!)
+        for (int i = stateLeaveRequests_.size() - 1; i >= 0; --i)
+        {
+            stateLeaveRequests_[i]->onLeave();
+            // just to be sure that the state actually is registered
+            assert(inputStatesByName_.find(stateLeaveRequests_[i]->getName()) != inputStatesByName_.end());
+            
+            activeStates_.erase(stateLeaveRequests_[i]->getPriority());
+            _updateActiveStates();
+            stateLeaveRequests_.pop_back();
+        }
+
+
+        // check for states to enter (don't use unsigned int!)
+        for (int i = stateEnterRequests_.size() - 1; i >= 0; --i)
+        {
+            // just to be sure that the state actually is registered
+            assert(inputStatesByName_.find(stateEnterRequests_[i]->getName()) != inputStatesByName_.end());
+            
+            activeStates_[stateEnterRequests_[i]->getPriority()] = stateEnterRequests_[i];
+            _updateActiveStates();
+            stateEnterRequests_[i]->onEnter();
+            stateEnterRequests_.pop_back();
         }
 
         // Capture all the input. This calls the event handlers in InputManager.
+        if (keyboard_)
+            keyboard_->capture();
         if (mouse_)
             mouse_->capture();
-        if (keyboard_)
-            keyboard_->capture();
         for (unsigned  int i = 0; i < joySticksSize_; i++)
             joySticks_[i]->capture();
 
-        if (state_ != IS_CALIBRATE)
+        if (!bCalibrating_)
         {
             // call all the handlers for the held key events
             for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
-                for (unsigned int iHandler = 0; iHandler < activeKeyHandlers_.size(); iHandler++)
-                    activeKeyHandlers_[iHandler]->keyHeld(KeyEvent(keysDown_[iKey], keyboardModifiers_));
+                activeStatesTop_[Keyboard]->keyHeld(KeyEvent(keysDown_[iKey], keyboardModifiers_));
 
             // call all the handlers for the held mouse button events
             for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
-                for (unsigned int iHandler = 0; iHandler < activeMouseHandlers_.size(); iHandler++)
-                    activeMouseHandlers_[iHandler]->mouseButtonHeld(mouseButtonsDown_[iButton]);
+                activeStatesTop_[Mouse]->mouseButtonHeld(mouseButtonsDown_[iButton]);
 
             // call all the handlers for the held joy stick button events
             for (unsigned int iJoyStick  = 0; iJoyStick < joySticksSize_; iJoyStick++)
                 for (unsigned int iButton   = 0; iButton   < joyStickButtonsDown_[iJoyStick].size(); iButton++)
-                    for (unsigned int iHandler = 0; iHandler  < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
-                    {
-                        activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonHeld(
-                            iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
-                    }
-        }
-
-        // call the ticks for the handlers (need to be treated specially)
-        for (unsigned int iHandler = 0; iHandler < activeHandlers_.size(); iHandler++)
-            activeHandlers_[iHandler].first->tickInput(dt, activeHandlers_[iHandler].second);
+                    activeStatesTop_[JoyStick0 + iJoyStick]
+                        ->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
+
+            // tick the handlers for each active handler
+            for (unsigned int i = 0; i < devicesNum_; ++i)
+                activeStatesTop_[i]->tickInput(dt, i);
+
+            // tick the handler with a general tick afterwards
+            for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
+                activeStatesTicked_[i]->tickInput(dt);
+        }
+    }
+
+    void InputManager::_updateActiveStates()
+    {
+        for (std::map<int, InputState*>::const_iterator it = activeStates_.begin(); it != activeStates_.end(); ++it)
+            for (unsigned int i = 0; i < devicesNum_; ++i)
+                if ((*it).second->isInputDeviceEnabled(i))
+                    activeStatesTop_[i] = (*it).second;
+
+        // update tickables (every state will only appear once)
+        // Using a std::set to avoid duplicates
+        std::set<InputState*> tempSet;
+        for (unsigned int i = 0; i < devicesNum_; ++i)
+            tempSet.insert(activeStatesTop_[i]);
+
+        // copy the content of the set back to the actual vector
+        activeStatesTicked_.clear();
+        for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
+            activeStatesTicked_.push_back(*it);
     }
 
@@ -744,5 +672,14 @@
             cont->set(i, joySticksCalibration_[0].zeroStates[i]);
         }
-    }
+
+        // restore old input state
+        requestLeaveState("calibrator");
+    }
+
+
+    // ############################################################
+    // #####                    OIS events                    #####
+    // ##########                                        ##########
+    // ############################################################
 
     // ###### Key Events ######
@@ -771,6 +708,5 @@
             keyboardModifiers_ |= KeyboardModifier::Shift; // shift key
 
-        for (unsigned int i = 0; i < activeKeyHandlers_.size(); i++)
-            activeKeyHandlers_[i]->keyPressed(KeyEvent(e, keyboardModifiers_));
+        activeStatesTop_[Keyboard]->keyPressed(KeyEvent(e, keyboardModifiers_));
 
         return true;
@@ -803,6 +739,5 @@
             keyboardModifiers_ &= ~KeyboardModifier::Shift; // shift key
 
-        for (unsigned int i = 0; i < activeKeyHandlers_.size(); i++)
-            activeKeyHandlers_[i]->keyReleased(KeyEvent(e, keyboardModifiers_));
+        activeStatesTop_[Keyboard]->keyReleased(KeyEvent(e, keyboardModifiers_));
 
         return true;
@@ -823,9 +758,6 @@
         if (e.state.X.rel != 0 || e.state.Y.rel != 0)
         {
-            for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++)
-            {
-                activeMouseHandlers_[i]->mouseMoved(IntVector2(e.state.X.abs, e.state.Y.abs),
+            activeStatesTop_[Mouse]->mouseMoved(IntVector2(e.state.X.abs, e.state.Y.abs),
                     IntVector2(e.state.X.rel, e.state.Y.rel), IntVector2(e.state.width, e.state.height));
-            }
         }
 
@@ -833,6 +765,5 @@
         if (e.state.Z.rel != 0)
         {
-            for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++)
-                activeMouseHandlers_[i]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
+            activeStatesTop_[Mouse]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
         }
 
@@ -857,6 +788,5 @@
             mouseButtonsDown_.push_back((MouseButton::Enum)id);
 
-        for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++)
-            activeMouseHandlers_[i]->mouseButtonPressed((MouseButton::Enum)id);
+        activeStatesTop_[Mouse]->mouseButtonPressed((MouseButton::Enum)id);
 
         return true;
@@ -883,6 +813,5 @@
         }
 
-        for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++)
-            activeMouseHandlers_[i]->mouseButtonReleased((MouseButton::Enum)id);
+        activeStatesTop_[Mouse]->mouseButtonReleased((MouseButton::Enum)id);
 
         return true;
@@ -898,12 +827,7 @@
         unsigned int iJoyStick = 0;
         while (joySticks_[iJoyStick] != joyStick)
-        {
             iJoyStick++;
-            if (iJoyStick == joySticksSize_)
-            {
-                CCOUT(3) << "Unknown joystick fired an event. This means there is a bug somewhere! Aborting." << std::endl;
-                abort();
-            }
-        }
+        // assert: Unknown joystick fired an event.
+        assert(iJoyStick != joySticksSize_);
         return iJoyStick;
     }
@@ -921,6 +845,5 @@
             buttonsDown.push_back(button);
 
-        for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
-            activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonPressed(iJoyStick, button);
+        activeStatesTop_[2 + iJoyStick]->joyStickButtonPressed(iJoyStick, button);
 
         return true;
@@ -942,6 +865,5 @@
         }
 
-        for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
-            activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonReleased(iJoyStick, button);
+        activeStatesTop_[2 + iJoyStick]->joyStickButtonReleased(iJoyStick, button);
 
         return true;
@@ -950,5 +872,5 @@
     void InputManager::_fireAxis(unsigned int iJoyStick, int axis, int value)
     {
-        if (state_ == IS_CALIBRATE)
+        if (bCalibrating_)
         {
             if (value > marginalsMax_[axis])
@@ -965,6 +887,5 @@
                 fValue *= joySticksCalibration_[iJoyStick].negativeCoeff[axis];
 
-            for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
-                activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickAxisMoved(iJoyStick, axis, fValue);
+            activeStatesTop_[2 + iJoyStick]->joyStickAxisMoved(iJoyStick, axis, fValue);
         }
     }
@@ -972,7 +893,4 @@
     bool InputManager::axisMoved(const OIS::JoyStickEvent &arg, int axis)
     {
-        //if (arg.state.mAxes[axis].abs > 10000 || arg.state.mAxes[axis].abs < -10000)
-        //{ CCOUT(3) << "axis " << axis << " moved" << arg.state.mAxes[axis].abs << std::endl;}
-
         unsigned int iJoyStick = _getJoystick(arg);
 
@@ -985,8 +903,4 @@
     bool InputManager::sliderMoved(const OIS::JoyStickEvent &arg, int id)
     {
-        //if (arg.state.mSliders[id].abX > 10000 || arg.state.mSliders[id].abX < -10000)
-        //{CCOUT(3) << "slider " << id << " moved" << arg.state.mSliders[id].abX << std::endl;}
-        //CCOUT(3) << arg.state.mSliders[id].abX << "\t |" << arg.state.mSliders[id].abY << std::endl;
-
         unsigned int iJoyStick = _getJoystick(arg);
 
@@ -1029,22 +943,9 @@
     }
 
-    /*bool InputManager::vector3Moved(const OIS::JoyStickEvent &arg, int id)
-    {
-        unsigned int iJoyStick = _getJoystick(arg);
-
-        for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
-        {
-            activeJoyStickHandlers_[iJoyStick][iHandler]
-                ->joyStickVector3Moved(JoyStickState(arg.state, iJoyStick), id);
-            }
-
-        return true;
-    }*/
-
-
-    // ################################
-    // ### Static Interface Methods ###
-    // ################################
-    // ################################
+
+    // ############################################################
+    // #####            Static Interface Methods              #####
+    // ##########                                        ##########
+    // ############################################################
 
     std::string InputManager::bindingCommmandString_s = "";
@@ -1053,5 +954,5 @@
         bool createKeyboard, bool createMouse, bool createJoySticks)
     {
-        return _getSingleton()._initialise(windowHnd, windowWidth, windowHeight,
+        return _getInstance()._initialise(windowHnd, windowWidth, windowHeight,
             createKeyboard, createMouse, createJoySticks);
     }
@@ -1059,20 +960,20 @@
     bool InputManager::initialiseKeyboard()
     {
-        return _getSingleton()._initialiseKeyboard();
+        return _getInstance()._initialiseKeyboard();
     }
 
     bool InputManager::initialiseMouse()
     {
-        return _getSingleton()._initialiseMouse();
+        return _getInstance()._initialiseMouse();
     }
 
     bool InputManager::initialiseJoySticks()
     {
-        return _getSingleton()._initialiseJoySticks();
+        return _getInstance()._initialiseJoySticks();
     }
 
     int InputManager::numberOfKeyboards()
     {
-        if (_getSingleton().keyboard_ != 0)
+        if (_getInstance().keyboard_ != 0)
             return 1;
         else
@@ -1082,5 +983,5 @@
     int InputManager::numberOfMice()
     {
-        if (_getSingleton().mouse_ != 0)
+        if (_getInstance().mouse_ != 0)
             return 1;
         else
@@ -1090,11 +991,11 @@
     int InputManager::numberOfJoySticks()
     {
-        return _getSingleton().joySticksSize_;
+        return _getInstance().joySticksSize_;
     }
 
     /*bool InputManager::isKeyDown(KeyCode::Enum key)
     {
-    if (_getSingleton().keyboard_)
-        return _getSingleton().keyboard_->isKeyDown((OIS::KeyCode)key);
+    if (_getInstance().keyboard_)
+        return _getInstance().keyboard_->isKeyDown((OIS::KeyCode)key);
     else
         return false;
@@ -1103,5 +1004,5 @@
     /*bool InputManager::isModifierDown(KeyboardModifier::Enum modifier)
     {
-    if (_getSingleton().keyboard_)
+    if (_getInstance().keyboard_)
         return isModifierDown(modifier);
     else
@@ -1111,6 +1012,6 @@
     /*const MouseState InputManager::getMouseState()
     {
-    if (_getSingleton().mouse_)
-        return _getSingleton().mouse_->getMouseState();
+    if (_getInstance().mouse_)
+        return _getInstance().mouse_->getMouseState();
     else
         return MouseState();
@@ -1119,6 +1020,6 @@
     /*const JoyStickState InputManager::getJoyStickState(unsigned int ID)
     {
-    if (ID < _getSingleton().joySticksSize_)
-        return JoyStickState(_getSingleton().joySticks_[ID]->getJoyStickState(), ID);
+    if (ID < _getInstance().joySticksSize_)
+        return JoyStickState(_getInstance().joySticks_[ID]->getJoyStickState(), ID);
     else
         return JoyStickState();
@@ -1127,20 +1028,20 @@
     void InputManager::destroy()
     {
-        _getSingleton()._destroy();
+        _getInstance()._destroy();
     }
 
     void InputManager::destroyKeyboard()
     {
-        return _getSingleton()._destroyKeyboard();
+        return _getInstance()._destroyKeyboard();
     }
 
     void InputManager::destroyMouse()
     {
-        return _getSingleton()._destroyMouse();
+        return _getInstance()._destroyMouse();
     }
 
     void InputManager::destroyJoySticks()
     {
-        return _getSingleton()._destroyJoySticks();
+        return _getInstance()._destroyJoySticks();
     }
 
@@ -1157,8 +1058,8 @@
     void InputManager::setWindowExtents(const int width, const int height)
     {
-        if (_getSingleton().mouse_)
+        if (_getInstance().mouse_)
         {
             // Set mouse region (if window resizes, we should alter this to reflect as well)
-            const OIS::MouseState &mouseState = _getSingleton().mouse_->getMouseState();
+            const OIS::MouseState &mouseState = _getInstance().mouse_->getMouseState();
             mouseState.width  = width;
             mouseState.height = height;
@@ -1166,31 +1067,7 @@
     }
 
-    /**
-    @brief
-        Sets the input mode to either GUI, inGame or Buffer
-    @param mode
-        The new input mode
-    @remarks
-        Only has an affect if the mode actually changes
-    */
-    void InputManager::setInputState(const InputState state)
-    {
-        _getSingleton().stateRequest_ = state;
-    }
-
-    /**
-    @brief
-        Returns the current input handling method
-    @return
-        The current input mode.
-    */
-    InputManager::InputState InputManager::getInputState()
-    {
-        return _getSingleton().state_;
-    }
-
     void InputManager::storeKeyStroke(const std::string& name)
     {
-        setInputState(IS_NODETECT);
+        requestLeaveState("detector");
         COUT(0) << "Binding string \"" << bindingCommmandString_s << "\" on key '" << name << "'" << std::endl;
         CommandExecutor::execute("config KeyBinder " + name + " " + bindingCommmandString_s, false);
@@ -1200,5 +1077,5 @@
     {
         bindingCommmandString_s = command;
-        setInputState(IS_DETECT);
+        requestEnterState("detector");
         COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl;
     }
@@ -1206,13 +1083,13 @@
     void InputManager::calibrate()
     {
-        _getSingleton().setInputState(IS_CALIBRATE);
+        requestEnterState("calibrator");
     }
 
     void InputManager::tick(float dt)
     {
-        _getSingleton()._tick(dt);
-    }
-
-    // ###### KeyHandler ######
+        _getInstance()._tick(dt);
+    }
+
+    // ###### InputStates ######
 
     /**
@@ -1226,15 +1103,56 @@
         True if added, false if name already existed.
     */
-    bool InputManager::addKeyHandler(KeyHandler* handler, const std::string& name)
-    {
-        if (!handler)
+    bool InputManager::_configureInputState(InputState* state, const std::string& name, int priority)
+    {
+        if (name == "")
             return false;
-        if (_getSingleton().keyHandlers_.find(name) == _getSingleton().keyHandlers_.end())
-        {
-            _getSingleton().keyHandlers_[name] = handler;
-            return true;
+        if (_getInstance().inputStatesByName_.find(name) == _getInstance().inputStatesByName_.end())
+        {
+            if (_getInstance().inputStatesByPriority_.find(priority)
+                == _getInstance().inputStatesByPriority_.end())
+            {
+                _getInstance().inputStatesByName_[name] = state;
+                _getInstance().inputStatesByPriority_[priority] = state;
+                state->setNumOfJoySticks(numberOfJoySticks());
+                state->setName(name);
+                state->setPriority(priority);
+                return true;
+            }
+            else
+            {
+                COUT(2) << "Warning: Could not add an InputState with the same priority '"
+                    << priority << "'." << std::endl;
+                return false;
+            }
         }
         else
+        {
+            COUT(2) << "Warning: Could not add an InputState with the same name '" << name << "'." << std::endl;
             return false;
+        }
+    }
+
+    SimpleInputState* InputManager::createSimpleInputState(const std::string &name, int priority)
+    {
+        SimpleInputState* state = new SimpleInputState();
+        if (_getInstance()._configureInputState(state, name, priority))
+            return state;
+        else
+        {
+            delete state;
+            return 0;
+        }
+    }
+
+    ExtendedInputState* InputManager::createExtendedInputState(const std::string &name, int priority)
+    {
+        ExtendedInputState* state = new ExtendedInputState();
+        if (_getInstance()._configureInputState(state, name, priority))
+            return state;
+        else
+        {
+            delete state;
+            return 0;
+        }
     }
 
@@ -1247,15 +1165,18 @@
         True if removal was successful, false if name was not found.
     */
-    bool InputManager::removeKeyHandler(const std::string &name)
-    {
-        disableKeyHandler(name);
-        std::map<std::string, KeyHandler*>::iterator it = _getSingleton().keyHandlers_.find(name);
-        if (it != _getSingleton().keyHandlers_.end())
-        {
-            _getSingleton().keyHandlers_.erase(it);
+    bool InputManager::destroyState(const std::string& name)
+    {
+        if (name == "empty" || name == "calibrator" || name == "detector")
+        {
+            COUT(2) << "InputManager: Removing the '" << name << "' state is not allowed!" << std::endl;
+            return false;
+        }
+        std::map<std::string, InputState*>::iterator it = _getInstance().inputStatesByName_.find(name);
+        if (it != _getInstance().inputStatesByName_.end())
+        {
+            _getInstance()._destroyState((*it).second);
             return true;
         }
-        else
-            return false;
+        return false;
     }
 
@@ -1268,11 +1189,22 @@
         Pointer to the instance, 0 if name was not found.
     */
-    KeyHandler* InputManager::getKeyHandler(const std::string& name)
-    {
-        std::map<std::string, KeyHandler*>::iterator it = _getSingleton().keyHandlers_.find(name);
-        if (it != _getSingleton().keyHandlers_.end())
+    InputState* InputManager::getState(const std::string& name)
+    {
+        std::map<std::string, InputState*>::iterator it = _getInstance().inputStatesByName_.find(name);
+        if (it != _getInstance().inputStatesByName_.end())
             return (*it).second;
         else
             return 0;
+    }
+
+    /**
+    @brief
+        Returns the current input handling method
+    @return
+        The current input mode.
+    */
+    InputState* InputManager::getCurrentState()
+    {
+        return (*_getInstance().activeStates_.rbegin()).second;
     }
 
@@ -1285,390 +1217,26 @@
         False if name was not found, true otherwise.
     */
-    bool InputManager::enableKeyHandler(const std::string& name)
+    bool InputManager::requestEnterState(const std::string& name)
     {
         // get pointer from the map with all stored handlers
-        std::map<std::string, KeyHandler*>::const_iterator mapIt = _getSingleton().keyHandlers_.find(name);
-        if (mapIt == _getSingleton().keyHandlers_.end())
-            return false;
-        // see whether the handler already is in the list
-        for (std::vector<KeyHandler*>::iterator it = _getSingleton().activeKeyHandlers_.begin();
-            it != _getSingleton().activeKeyHandlers_.end(); it++)
-        {
-            if ((*it) == (*mapIt).second)
-            {
-                return true;
-            }
-        }
-        _getSingleton().activeKeyHandlers_.push_back((*mapIt).second);
-        _getSingleton().stateRequest_ = IS_CUSTOM;
-        _getSingleton()._updateTickables();
-        return true;
-    }
-
-    /**
-    @brief
-        Disables a specific key handler.
-    @param name
-        Unique name of the handler.
-    @return
-        False if name was not found, true otherwise.
-    */
-    bool InputManager::disableKeyHandler(const std::string &name)
+        std::map<std::string, InputState*>::const_iterator it = _getInstance().inputStatesByName_.find(name);
+        if (it != _getInstance().inputStatesByName_.end())
+        {
+            _getInstance().stateEnterRequests_.push_back((*it).second);
+            return true;
+        }
+        return false;
+    }
+
+    bool InputManager::requestLeaveState(const std::string& name)
     {
         // get pointer from the map with all stored handlers
-        std::map<std::string, KeyHandler*>::const_iterator mapIt = _getSingleton().keyHandlers_.find(name);
-        if (mapIt == _getSingleton().keyHandlers_.end())
-            return false;
-        // look for the handler in the list
-        for (std::vector<KeyHandler*>::iterator it = _getSingleton().activeKeyHandlers_.begin();
-            it != _getSingleton().activeKeyHandlers_.end(); it++)
-        {
-            if ((*it) == (*mapIt).second)
-            {
-                _getSingleton().activeKeyHandlers_.erase(it);
-                _getSingleton().stateRequest_ = IS_CUSTOM;
-                _getSingleton()._updateTickables();
-                return true;
-            }
-        }
-        return true;
-    }
-
-    /**
-    @brief
-        Checks whether a key handler is active
-    @param name
-        Unique name of the handler.
-    @return
-        False if key handler is not active or doesn't exist, true otherwise.
-    */
-    bool InputManager::isKeyHandlerActive(const std::string& name)
-    {
-        // get pointer from the map with all stored handlers
-        std::map<std::string, KeyHandler*>::const_iterator mapIt = _getSingleton().keyHandlers_.find(name);
-        if (mapIt == _getSingleton().keyHandlers_.end())
-            return false;
-        // see whether the handler already is in the list
-        for (std::vector<KeyHandler*>::iterator it = _getSingleton().activeKeyHandlers_.begin();
-            it != _getSingleton().activeKeyHandlers_.end(); it++)
-        {
-            if ((*it) == (*mapIt).second)
-                return true;
+        std::map<std::string, InputState*>::const_iterator it = _getInstance().inputStatesByName_.find(name);
+        if (it != _getInstance().inputStatesByName_.end())
+        {
+            _getInstance().stateLeaveRequests_.push_back((*it).second);
+            return true;
         }
         return false;
     }
-
-
-    // ###### MouseHandler ######
-    /**
-    @brief
-        Adds a new mouse handler.
-    @param handler
-        Pointer to the handler object.
-    @param name
-        Unique name of the handler.
-    @return
-        True if added, false if name already existed.
-    */
-    bool InputManager::addMouseHandler(MouseHandler* handler, const std::string& name)
-    {
-        if (!handler)
-            return false;
-        if (_getSingleton().mouseHandlers_.find(name) == _getSingleton().mouseHandlers_.end())
-        {
-            _getSingleton().mouseHandlers_[name] = handler;
-            return true;
-        }
-        else
-            return false;
-    }
-
-    /**
-    @brief
-        Removes a Mouse handler from the list.
-    @param name
-        Unique name of the handler.
-    @return
-        True if removal was successful, false if name was not found.
-    */
-    bool InputManager::removeMouseHandler(const std::string &name)
-    {
-        disableMouseHandler(name);
-        std::map<std::string, MouseHandler*>::iterator it = _getSingleton().mouseHandlers_.find(name);
-        if (it != _getSingleton().mouseHandlers_.end())
-        {
-            _getSingleton().mouseHandlers_.erase(it);
-            return true;
-        }
-        else
-            return false;
-    }
-
-    /**
-    @brief
-        Returns the pointer to a handler.
-    @param name
-        Unique name of the handler.
-    @return
-        Pointer to the instance, 0 if name was not found.
-    */
-    MouseHandler* InputManager::getMouseHandler(const std::string& name)
-    {
-        std::map<std::string, MouseHandler*>::iterator it = _getSingleton().mouseHandlers_.find(name);
-        if (it != _getSingleton().mouseHandlers_.end())
-        {
-            return (*it).second;
-        }
-        else
-            return 0;
-    }
-
-    /**
-    @brief
-        Enables a specific mouse handler that has already been added.
-    @param name
-        Unique name of the handler.
-    @return
-        False if name was not found, true otherwise.
-    */
-    bool InputManager::enableMouseHandler(const std::string& name)
-    {
-        // get pointer from the map with all stored handlers
-        std::map<std::string, MouseHandler*>::const_iterator mapIt = _getSingleton().mouseHandlers_.find(name);
-        if (mapIt == _getSingleton().mouseHandlers_.end())
-            return false;
-        // see whether the handler already is in the list
-        for (std::vector<MouseHandler*>::iterator it = _getSingleton().activeMouseHandlers_.begin();
-            it != _getSingleton().activeMouseHandlers_.end(); it++)
-        {
-            if ((*it) == (*mapIt).second)
-            {
-                return true;
-            }
-        }
-        _getSingleton().activeMouseHandlers_.push_back((*mapIt).second);
-        _getSingleton().stateRequest_ = IS_CUSTOM;
-        _getSingleton()._updateTickables();
-        return true;
-    }
-
-    /**
-    @brief
-        Disables a specific mouse handler.
-    @param name
-        Unique name of the handler.
-    @return
-        False if name was not found, true otherwise.
-    */
-    bool InputManager::disableMouseHandler(const std::string &name)
-    {
-        // get pointer from the map with all stored handlers
-        std::map<std::string, MouseHandler*>::const_iterator mapIt = _getSingleton().mouseHandlers_.find(name);
-        if (mapIt == _getSingleton().mouseHandlers_.end())
-            return false;
-        // look for the handler in the list
-        for (std::vector<MouseHandler*>::iterator it = _getSingleton().activeMouseHandlers_.begin();
-            it != _getSingleton().activeMouseHandlers_.end(); it++)
-        {
-            if ((*it) == (*mapIt).second)
-            {
-                _getSingleton().activeMouseHandlers_.erase(it);
-                _getSingleton().stateRequest_ = IS_CUSTOM;
-                _getSingleton()._updateTickables();
-                return true;
-            }
-        }
-        return true;
-    }
-
-    /**
-    @brief
-        Checks whether a mouse handler is active
-    @param name
-        Unique name of the handler.
-    @return
-        False if key handler is not active or doesn't exist, true otherwise.
-    */
-    bool InputManager::isMouseHandlerActive(const std::string& name)
-    {
-        // get pointer from the map with all stored handlers
-        std::map<std::string, MouseHandler*>::const_iterator mapIt = _getSingleton().mouseHandlers_.find(name);
-        if (mapIt == _getSingleton().mouseHandlers_.end())
-            return false;
-        // see whether the handler already is in the list
-        for (std::vector<MouseHandler*>::iterator it = _getSingleton().activeMouseHandlers_.begin();
-            it != _getSingleton().activeMouseHandlers_.end(); it++)
-        {
-            if ((*it) == (*mapIt).second)
-                return true;
-        }
-        return false;
-    }
-
-
-    // ###### JoyStickHandler ######
-
-    /**
-    @brief
-        Adds a new joy stick handler.
-    @param handler
-        Pointer to the handler object.
-    @param name
-        Unique name of the handler.
-    @return
-        True if added, false if name already existed.
-    */
-    bool InputManager::addJoyStickHandler(JoyStickHandler* handler, const std::string& name)
-    {
-        if (!handler)
-            return false;
-        if (_getSingleton().joyStickHandlers_.find(name) == _getSingleton().joyStickHandlers_.end())
-        {
-            _getSingleton().joyStickHandlers_[name] = handler;
-            return true;
-        }
-        else
-            return false;
-    }
-
-    /**
-    @brief
-        Removes a JoyStick handler from the list.
-    @param name
-        Unique name of the handler.
-    @return
-        True if removal was successful, false if name was not found.
-    */
-    bool InputManager::removeJoyStickHandler(const std::string &name)
-    {
-        for (std::vector<OIS::JoyStick*>::iterator itstick = _getSingleton().joySticks_.begin();
-            itstick != _getSingleton().joySticks_.end(); itstick++)
-            disableJoyStickHandler(name, itstick - _getSingleton().joySticks_.begin());
-
-        std::map<std::string, JoyStickHandler*>::iterator it = _getSingleton().joyStickHandlers_.find(name);
-        if (it != _getSingleton().joyStickHandlers_.end())
-        {
-            _getSingleton().joyStickHandlers_.erase(it);
-            return true;
-        }
-        else
-            return false;
-    }
-
-    /**
-    @brief
-        Returns the pointer to a handler.
-    @param name
-        Unique name of the handler.
-    @return
-        Pointer to the instance, 0 if name was not found.
-    */
-    JoyStickHandler* InputManager::getJoyStickHandler(const std::string& name)
-    {
-        std::map<std::string, JoyStickHandler*>::iterator it = _getSingleton().joyStickHandlers_.find(name);
-        if (it != _getSingleton().joyStickHandlers_.end())
-        {
-            return (*it).second;
-        }
-        else
-            return 0;
-    }
-
-    /**
-    @brief
-        Enables a specific joy stick handler that has already been added.
-    @param name
-        Unique name of the handler.
-    @return
-        False if name or id was not found, true otherwise.
-    */
-    bool InputManager::enableJoyStickHandler(const std::string& name, unsigned int ID)
-    {
-        // get handler pointer from the map with all stored handlers
-        std::map<std::string, JoyStickHandler*>::const_iterator handlerIt = _getSingleton().joyStickHandlers_.find(name);
-        if (handlerIt == _getSingleton().joyStickHandlers_.end())
-            return false;
-
-        // check for existence of the ID
-        if (ID >= _getSingleton().joySticksSize_)
-            return false;
-
-        // see whether the handler already is in the list
-        for (std::vector<JoyStickHandler*>::iterator it = _getSingleton().activeJoyStickHandlers_[ID].begin();
-            it != _getSingleton().activeJoyStickHandlers_[ID].end(); it++)
-        {
-            if ((*it) == (*handlerIt).second)
-            {
-                return true;
-            }
-        }
-        _getSingleton().activeJoyStickHandlers_[ID].push_back((*handlerIt).second);
-        _getSingleton().stateRequest_ = IS_CUSTOM;
-        _getSingleton()._updateTickables();
-        return true;
-    }
-
-    /**
-    @brief
-        Disables a specific joy stick handler.
-    @param name
-        Unique name of the handler.
-    @return
-        False if name or id was not found, true otherwise.
-    */
-    bool InputManager::disableJoyStickHandler(const std::string &name, unsigned int ID)
-    {
-        // get handler pointer from the map with all stored handlers
-        std::map<std::string, JoyStickHandler*>::const_iterator handlerIt = _getSingleton().joyStickHandlers_.find(name);
-        if (handlerIt == _getSingleton().joyStickHandlers_.end())
-            return false;
-
-        // check for existence of the ID
-        if (ID >= _getSingleton().joySticksSize_)
-            return false;
-
-        // look for the handler in the list
-        for (std::vector<JoyStickHandler*>::iterator it = _getSingleton().activeJoyStickHandlers_[ID].begin();
-            it != _getSingleton().activeJoyStickHandlers_[ID].end(); it++)
-        {
-            if ((*it) == (*handlerIt).second)
-            {
-                _getSingleton().activeJoyStickHandlers_[ID].erase(it);
-                _getSingleton().stateRequest_ = IS_CUSTOM;
-                _getSingleton()._updateTickables();
-                return true;
-            }
-        }
-        return true;
-    }
-
-    /**
-    @brief
-        Checks whether a joy stick handler is active
-    @param name
-        Unique name of the handler.
-    @return
-        False if key handler is not active or doesn't exist, true otherwise.
-    */
-    bool InputManager::isJoyStickHandlerActive(const std::string& name, unsigned int ID)
-    {
-        // get handler pointer from the map with all stored handlers
-        std::map<std::string, JoyStickHandler*>::const_iterator handlerIt = _getSingleton().joyStickHandlers_.find(name);
-        if (handlerIt == _getSingleton().joyStickHandlers_.end())
-            return false;
-
-        // check for existence of the ID
-        if (ID >= _getSingleton().joySticksSize_)
-            return false;
-
-        // see whether the handler already is in the list
-        for (std::vector<JoyStickHandler*>::iterator it = _getSingleton().activeJoyStickHandlers_[ID].begin();
-            it != _getSingleton().activeJoyStickHandlers_[ID].end(); it++)
-        {
-            if ((*it) == (*handlerIt).second)
-                return true;
-        }
-        return false;
-    }
-
 }
Index: code/branches/input/src/core/input/InputManager.h
===================================================================
--- code/branches/input/src/core/input/InputManager.h	(revision 1636)
+++ code/branches/input/src/core/input/InputManager.h	(revision 1637)
@@ -41,4 +41,5 @@
 #include <map>
 #include <vector>
+#include <stack>
 #include "util/Math.h"
 #include "core/OrxonoxClass.h"
@@ -68,16 +69,4 @@
     };
 
-    /**
-    @brief
-        Struct for storing a custom input state
-    */
-    struct StoredState
-    {
-        std::vector<KeyHandler*>                    activeKeyHandlers_;
-        std::vector<MouseHandler*>                  activeMouseHandlers_;
-        std::vector<std::vector<JoyStickHandler*> > activeJoyStickHandlers_;
-        std::vector<std::pair<InputTickable*, HandlerState> > activeHandlers_;
-    };
-
     struct JoyStickCalibration
     {
@@ -95,25 +84,6 @@
         public OIS::KeyListener, public OIS::MouseListener, public OIS::JoyStickListener
     {
-    public: // enumerations
-        /**
-        @brief
-            Designates the way input is handled and redirected.
-        */
-        enum InputState
-        {
-            IS_UNINIT,    //!< InputManager has not yet been initialised.
-            IS_NONE,      //!< Input is discarded.
-            IS_NORMAL,    //!< Normal play state. Key and button bindings are active.
-            IS_GUI,       //!< All OIS input events are passed to CEGUI.
-            IS_CONSOLE,   //!< Keyboard input is redirected to the InputBuffer.
-            IS_DETECT,    //!< All the input additionally goes to the KeyDetector
-            IS_NODETECT,  //!< remove KeyDetector
-            IS_NOCALIBRATE,
-            IS_CALIBRATE,
-            IS_CUSTOM     //!< Any possible configuration.
-        };
-
-    public: // member functions
-        void setConfigValues();
+        // --> setConfigValues is private
+        friend ClassIdentifier<InputManager>;
 
     public: // static functions
@@ -139,7 +109,4 @@
         static void setWindowExtents(const int width, const int height);
 
-        static void setInputState(const InputState state);
-        static InputState getInputState();
-
         static void storeKeyStroke(const std::string& name);
         static void keyBind(const std::string& command);
@@ -149,24 +116,12 @@
         static void tick(float dt);
 
-        static bool addKeyHandler                 (KeyHandler* handler, const std::string& name);
-        static bool removeKeyHandler              (const std::string& name);
-        static KeyHandler* getKeyHandler          (const std::string& name);
-        static bool enableKeyHandler              (const std::string& name);
-        static bool disableKeyHandler             (const std::string& name);
-        static bool isKeyHandlerActive            (const std::string& name);
-
-        static bool addMouseHandler               (MouseHandler* handler, const std::string& name);
-        static bool removeMouseHandler            (const std::string& name);
-        static MouseHandler* getMouseHandler      (const std::string& name);
-        static bool enableMouseHandler            (const std::string& name);
-        static bool disableMouseHandler           (const std::string& name);
-        static bool isMouseHandlerActive          (const std::string& name);
-
-        static bool addJoyStickHandler            (JoyStickHandler* handler, const std::string& name);
-        static bool removeJoyStickHandler         (const std::string& name);
-        static JoyStickHandler* getJoyStickHandler(const std::string& name);
-        static bool enableJoyStickHandler         (const std::string& name, unsigned int id);
-        static bool disableJoyStickHandler        (const std::string& name, unsigned int id);
-        static bool isJoyStickHandlerActive       (const std::string& name, unsigned int id);
+        static SimpleInputState*   createSimpleInputState  (const std::string& name, int priority);
+        static ExtendedInputState* createExtendedInputState(const std::string& name, int priority);
+        static bool destroyState (const std::string& name);
+        //static bool removeState (const std::string& name);
+        static InputState* getState       (const std::string& name);
+        static InputState* getCurrentState();
+        static bool requestEnterState     (const std::string& name);
+        static bool requestLeaveState     (const std::string& name);
 
     private: // functions
@@ -181,4 +136,5 @@
         bool _initialiseMouse();
         bool _initialiseJoySticks();
+        void _redimensionLists();
 
         void _destroy();
@@ -186,9 +142,5 @@
         void _destroyMouse();
         void _destroyJoySticks();
-
-        void _updateTickables();
-
-        void _saveState();
-        void _restoreState();
+        void _destroyState(InputState* state);
 
         void _completeCalibration();
@@ -198,4 +150,7 @@
 
         void _tick(float dt);
+
+        void _updateActiveStates();
+        bool _configureInputState(InputState* state, const std::string& name, int priority);
 
         // input events
@@ -210,8 +165,8 @@
         bool sliderMoved   (const OIS::JoyStickEvent &arg, int id);
         bool povMoved      (const OIS::JoyStickEvent &arg, int id);
-        //bool vector3Moved  (const OIS::JoyStickEvent &arg, int id);
-
-        static InputManager& _getSingleton();
-        static InputManager* _getSingletonPtr() { return &_getSingleton(); }
+
+        void setConfigValues();
+
+        static InputManager& _getInstance();
 
     private: // variables
@@ -221,15 +176,20 @@
         std::vector<OIS::JoyStick*>                 joySticks_;       //!< OIS joy sticks
         unsigned int                                joySticksSize_;
-
-        KeyBinder*                                  keyBinder_;       //!< KeyBinder instance
-        KeyDetector*                                keyDetector_;     //!< KeyDetector instance
-        InputBuffer*                                buffer_;          //!< InputBuffer instance
-        CalibratorCallback*                         calibratorCallback_;
-
-        InputState state_;
-        InputState stateRequest_;
-        InputState savedState_;
-        unsigned int keyboardModifiers_;
-        StoredState savedHandlers_;
+        unsigned int                                devicesNum_;
+
+        // some internally handled states
+        SimpleInputState*                                 stateDetector_;   //!< KeyDetector instance
+        SimpleInputState*                                 stateCalibrator_;
+        SimpleInputState*                                 stateEmpty_;
+
+        std::map<std::string, InputState*>          inputStatesByName_;
+        std::map<int, InputState*>                  inputStatesByPriority_;
+
+        std::vector<InputState*> stateEnterRequests_;                  //!< Request to enter a new state
+        std::vector<InputState*> stateLeaveRequests_;                    //!< Request to leave the current state
+
+        std::map<int, InputState*> activeStates_;
+        std::vector<InputState*>   activeStatesTop_;    //!< Current input states for joy stick events.
+        std::vector<InputState*>   activeStatesTicked_;    //!< Current input states for joy stick events.
 
         // joystick calibration
@@ -239,5 +199,7 @@
         int marginalsMin_[24];
         bool bCalibrated_;
-
+        bool bCalibrating_;
+
+        unsigned int keyboardModifiers_;           //!< Bit mask representing keyboard modifiers
         //! Keeps track of the joy stick POV states
         std::vector<POVStates>                      povStates_;
@@ -246,13 +208,4 @@
         std::vector<JoyStickCalibration>            joySticksCalibration_;
 
-        std::map<std::string, KeyHandler*>          keyHandlers_;
-        std::map<std::string, MouseHandler*>        mouseHandlers_;
-        std::map<std::string, JoyStickHandler*>     joyStickHandlers_;
-
-        std::vector<KeyHandler*>                    activeKeyHandlers_;
-        std::vector<MouseHandler*>                  activeMouseHandlers_;
-        std::vector<std::vector<JoyStickHandler*> > activeJoyStickHandlers_;
-        std::vector<std::pair<InputTickable*, HandlerState> > activeHandlers_;
-
         std::vector<Key>                            keysDown_;
         std::vector<MouseButton::Enum>              mouseButtonsDown_;
Index: code/branches/input/src/core/input/InputState.h
===================================================================
--- code/branches/input/src/core/input/InputState.h	(revision 1637)
+++ code/branches/input/src/core/input/InputState.h	(revision 1637)
@@ -0,0 +1,117 @@
+/*
+ *   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 _InputState_H__
+#define _InputState_H__
+
+#include "core/CorePrereqs.h"
+
+#include <string>
+#include <vector>
+#include "core/Executor.h"
+#include "InputInterfaces.h"
+
+namespace orxonox
+{
+    class _CoreExport InputState
+    {
+        friend class InputManager;
+
+    public:
+        InputState() : priority_(0), executorOnEnter_(0), executorOnLeave_(0) { }
+        virtual ~InputState() { }
+
+        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;
+        }
+
+        virtual void onEnter() { if (executorOnEnter_) (*executorOnEnter_)(); }
+        virtual void onLeave() { if (executorOnLeave_) (*executorOnLeave_)(); }
+
+        virtual void registerOnEnter(Executor* executor)      { executorOnEnter_ = executor; }
+        virtual void unRegisterOnEnter()                      { executorOnEnter_ = 0; }
+        virtual void registerOnLeave(Executor* executor)      { executorOnLeave_ = executor; }
+        virtual void unRegisterOnLeave()                      { executorOnLeave_ = 0; }
+
+        virtual void tickInput(float dt, unsigned int device) = 0;
+        virtual void tickInput(float dt) = 0;
+
+        virtual void keyPressed (const KeyEvent& evt) = 0;
+        virtual void keyReleased(const KeyEvent& evt) = 0;
+        virtual void keyHeld    (const KeyEvent& evt) = 0;
+
+        virtual void mouseButtonPressed (MouseButton::Enum id) = 0;
+        virtual void mouseButtonReleased(MouseButton::Enum id) = 0;
+        virtual void mouseButtonHeld    (MouseButton::Enum 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, unsigned int button) = 0;
+        virtual void joyStickButtonReleased(unsigned int joyStickID, unsigned int button) = 0;
+        virtual void joyStickButtonHeld    (unsigned int joyStickID, unsigned int button) = 0;
+        virtual void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) = 0;
+
+    protected:
+        virtual void numberOfJoySticksChanged(unsigned int n) = 0;
+        void setInputDeviceEnabled(unsigned int device, bool bEnabled)
+        {
+            if (device < bInputDeviceEnabled_.size())
+                bInputDeviceEnabled_[device] = bEnabled;
+        }
+
+    private:
+        void setNumOfJoySticks(unsigned int n)
+        {
+            bInputDeviceEnabled_.resize(n + 2);
+            numberOfJoySticksChanged(n);
+        }
+        void setName(const std::string& name)  { name_ = name; }
+        void setPriority(int priority)         { priority_ = priority; }
+
+        std::string                                 name_;
+        int                                         priority_;
+        std::vector<bool>                           bInputDeviceEnabled_;
+
+        Executor*                                   executorOnEnter_;
+        Executor*                                   executorOnLeave_;
+    };
+}
+
+#endif /* _InputState_H__ */
Index: code/branches/input/src/core/input/KeyBinder.cc
===================================================================
--- code/branches/input/src/core/input/KeyBinder.cc	(revision 1636)
+++ code/branches/input/src/core/input/KeyBinder.cc	(revision 1637)
@@ -333,47 +333,9 @@
     }
 
-    void KeyBinder::tickInput(float dt, const HandlerState& state)
-    {
-        // we have to process all the analog input since there is e.g. no 'mouseDoesntMove' event.
-        unsigned int iBegin = 8;
-        unsigned int iEnd   = 8;
-        if (state.joyStick)
-            iEnd = nHalfAxes_s;
-        if (state.mouse)
-            iBegin = 0;
-        for (unsigned int i = iBegin; i < iEnd; i++)
-        {
-            if (halfAxes_[i].hasChanged_)
-            {
-                if (!halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ > halfAxes_[i].buttonThreshold_)
-                {
-                    halfAxes_[i].wasDown_ = true;
-                    if (halfAxes_[i].nCommands_[KeybindMode::OnPress])
-                        halfAxes_[i].execute(KeybindMode::OnPress);
-                }
-                else if (halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ < halfAxes_[i].buttonThreshold_)
-                {
-                    halfAxes_[i].wasDown_ = false;
-                    if (halfAxes_[i].nCommands_[KeybindMode::OnRelease])
-                        halfAxes_[i].execute(KeybindMode::OnRelease);
-                }
-                halfAxes_[i].hasChanged_ = false;
-            }
-
-            if (halfAxes_[i].wasDown_)
-            {
-                if (halfAxes_[i].nCommands_[KeybindMode::OnHold])
-                    halfAxes_[i].execute(KeybindMode::OnHold);
-            }
-
-            // these are the actually useful axis bindings for analog input AND output
-            if (halfAxes_[i].relVal_ > analogThreshold_ || halfAxes_[i].absVal_ > analogThreshold_)
-            {
-                //COUT(3) << halfAxes_[i].name_ << "\t" << halfAxes_[i].absVal_ << std::endl;
-                halfAxes_[i].execute();
-            }
-        }
-
-        if (bDeriveMouseInput_ && state.mouse)
+    void KeyBinder::tickMouse(float dt)
+    {
+        tickDevices(0, 8);
+
+        if (bDeriveMouseInput_)
         {
             if (deriveTime_ > derivePeriod_)
@@ -410,13 +372,58 @@
                 deriveTime_ += dt;
         }
-
-        // execute all buffered bindings (addional parameter)
+    }
+
+    void KeyBinder::tickJoyStick(float dt, int device)
+    {
+        tickDevices(8, nHalfAxes_s);
+    }
+
+    void KeyBinder::tickInput(float dt)
+    {
+        // execute all buffered bindings (additional parameter)
         for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
             paramCommandBuffer_[i]->execute();
 
         // always reset the relative movement of the mouse
-        if (state.mouse)
-            for (unsigned int i = 0; i < 8; i++)
-                halfAxes_[i].relVal_ = 0.0f;
+        for (unsigned int i = 0; i < 8; i++)
+            halfAxes_[i].relVal_ = 0.0f;
+    }
+
+    void KeyBinder::tickDevices(unsigned int begin, unsigned int end)
+    {
+        for (unsigned int i = begin; i < end; i++)
+        {
+            // button mode
+            // TODO: optimize out all the half axes that don't act as a button at the moment
+            if (halfAxes_[i].hasChanged_)
+            {
+                if (!halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ > halfAxes_[i].buttonThreshold_)
+                {
+                    halfAxes_[i].wasDown_ = true;
+                    if (halfAxes_[i].nCommands_[KeybindMode::OnPress])
+                        halfAxes_[i].execute(KeybindMode::OnPress);
+                }
+                else if (halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ < halfAxes_[i].buttonThreshold_)
+                {
+                    halfAxes_[i].wasDown_ = false;
+                    if (halfAxes_[i].nCommands_[KeybindMode::OnRelease])
+                        halfAxes_[i].execute(KeybindMode::OnRelease);
+                }
+                halfAxes_[i].hasChanged_ = false;
+            }
+
+            if (halfAxes_[i].wasDown_)
+            {
+                if (halfAxes_[i].nCommands_[KeybindMode::OnHold])
+                    halfAxes_[i].execute(KeybindMode::OnHold);
+            }
+
+            // these are the actually useful axis bindings for analog input
+            if (halfAxes_[i].relVal_ > analogThreshold_ || halfAxes_[i].absVal_ > analogThreshold_)
+            {
+                //COUT(3) << halfAxes_[i].name_ << "\t" << halfAxes_[i].absVal_ << std::endl;
+                halfAxes_[i].execute();
+            }
+        }
     }
 
@@ -441,11 +448,11 @@
 
 
-    void KeyBinder::joyStickButtonPressed (int joyStickID, int button)
+    void KeyBinder::joyStickButtonPressed (unsigned int joyStickID, unsigned int button)
     { joyStickButtons_[button].execute(KeybindMode::OnPress); }
 
-    void KeyBinder::joyStickButtonReleased(int joyStickID, int button)
+    void KeyBinder::joyStickButtonReleased(unsigned int joyStickID, unsigned int button)
     { joyStickButtons_[button].execute(KeybindMode::OnRelease); }
 
-    void KeyBinder::joyStickButtonHeld    (int joyStickID, int button)
+    void KeyBinder::joyStickButtonHeld    (unsigned int joyStickID, unsigned int button)
     { joyStickButtons_[button].execute(KeybindMode::OnHold); }
 
@@ -525,7 +532,6 @@
     }
 
-    void KeyBinder::joyStickAxisMoved(int joyStickID, int axis, float value)
-    {
-        // TODO: Use proper calibration values instead of generally 16-bit integer
+    void KeyBinder::joyStickAxisMoved(unsigned int joyStickID, unsigned int axis, float value)
+    {
         int i = 8 + axis * 2;
         if (value >= 0)
Index: code/branches/input/src/core/input/KeyBinder.h
===================================================================
--- code/branches/input/src/core/input/KeyBinder.h	(revision 1636)
+++ code/branches/input/src/core/input/KeyBinder.h	(revision 1637)
@@ -64,5 +64,10 @@
 
     protected: // functions
-        void tickInput(float dt, const HandlerState& state);
+        void tickInput(float dt);
+        //void tickInput(float dt, int device);
+        void tickKey(float dt) { }
+        void tickMouse(float dt);
+        void tickJoyStick(float dt, int device);
+        void tickDevices(unsigned int begin, unsigned int end);
 
         virtual void readTrigger(Button& button);
@@ -78,8 +83,8 @@
         void mouseScrolled      (int abs, int rel);
 
-        void joyStickButtonPressed (int joyStickID, int button);
-        void joyStickButtonReleased(int joyStickID, int button);
-        void joyStickButtonHeld    (int joyStickID, int button);
-        void joyStickAxisMoved     (int joyStickID, int axis, float value);
+        void joyStickButtonPressed (unsigned int joyStickID, unsigned int button);
+        void joyStickButtonReleased(unsigned int joyStickID, unsigned int button);
+        void joyStickButtonHeld    (unsigned int joyStickID, unsigned int button);
+        void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value);
 
     protected: // variables
Index: code/branches/input/src/core/input/KeyDetector.cc
===================================================================
--- code/branches/input/src/core/input/KeyDetector.cc	(revision 1636)
+++ code/branches/input/src/core/input/KeyDetector.cc	(revision 1637)
@@ -66,8 +66,9 @@
         True if loading succeeded.
     */
-    void KeyDetector::loadBindings()
+    void KeyDetector::loadBindings(const std::string& command)
     {
         clearBindings();
         setConfigValues();
+        this->command_ = command;
     }
 
@@ -75,5 +76,5 @@
     {
         SimpleCommand* cmd = new SimpleCommand();
-        cmd->evaluation_ = CommandExecutor::evaluate("storeKeyStroke " + button.name_);
+        cmd->evaluation_ = CommandExecutor::evaluate(this->command_ + " " + button.name_);
         button.commands_[KeybindMode::OnPress] = new BaseCommand*[1];
         button.commands_[KeybindMode::OnPress][0] = cmd;
Index: code/branches/input/src/core/input/KeyDetector.h
===================================================================
--- code/branches/input/src/core/input/KeyDetector.h	(revision 1636)
+++ code/branches/input/src/core/input/KeyDetector.h	(revision 1637)
@@ -47,8 +47,11 @@
         KeyDetector();
         ~KeyDetector();
-        void loadBindings();
+        void loadBindings(const std::string& command);
 
     protected:
         void readTrigger(Button& button);
+
+    private:
+        std::string command_;
     };
 }
Index: code/branches/input/src/core/input/SimpleInputState.cc
===================================================================
--- code/branches/input/src/core/input/SimpleInputState.cc	(revision 1637)
+++ code/branches/input/src/core/input/SimpleInputState.cc	(revision 1637)
@@ -0,0 +1,270 @@
+/*
+ *   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 <assert.h>
+#include "core/Debug.h"
+#include "core/Executor.h"
+
+namespace orxonox
+{
+    using namespace InputDevice;
+
+    SimpleInputState::SimpleInputState()
+        : keyHandler_(0)
+        , mouseHandler_(0)
+        , joyStickHandlerAll_(0)
+    {
+    }
+
+    void SimpleInputState::numberOfJoySticksChanged(unsigned int n)
+    {
+        unsigned int oldSize = joyStickHandler_.size();
+        joyStickHandler_.resize(n);
+
+        if (oldSize > n)
+        {
+            // we have to add the handler in joyStickHandlerAll_ to the joyStickHandler_[>n]
+            for (unsigned int i = oldSize; i < n; ++i)
+            {
+                joyStickHandler_[i] = joyStickHandlerAll_;
+            }
+        }
+        update();
+    }
+
+    void SimpleInputState::keyPressed(const KeyEvent& evt)
+    {
+        if (keyHandler_)
+            keyHandler_->keyPressed(evt);
+    }
+
+    void SimpleInputState::keyReleased(const KeyEvent& evt)
+    {
+        if (keyHandler_)
+            keyHandler_->keyReleased(evt);
+    }
+
+    void SimpleInputState::keyHeld(const KeyEvent& evt)
+    {
+        if (keyHandler_)
+            keyHandler_->keyHeld(evt);
+    }
+
+
+    void SimpleInputState::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
+    {
+        if (mouseHandler_)
+            mouseHandler_->mouseMoved(abs, rel, clippingSize);
+    }
+
+    void SimpleInputState::mouseScrolled(int abs, int rel)
+    {
+        if (mouseHandler_)
+            mouseHandler_->mouseScrolled(abs, rel);
+    }
+
+    void SimpleInputState::mouseButtonPressed(MouseButton::Enum id)
+    {
+        if (mouseHandler_)
+            mouseHandler_->mouseButtonPressed(id);
+    }
+
+    void SimpleInputState::mouseButtonReleased(MouseButton::Enum id)
+    {
+        if (mouseHandler_)
+            mouseHandler_->mouseButtonReleased(id);
+    }
+
+    void SimpleInputState::mouseButtonHeld(MouseButton::Enum id)
+    {
+        if (mouseHandler_)
+            mouseHandler_->mouseButtonHeld(id);
+    }
+
+
+    void SimpleInputState::joyStickAxisMoved(unsigned int joyStickID, unsigned int axis, float value)
+    {
+        assert(joyStickID < joyStickHandler_.size());
+        if (joyStickHandler_[joyStickID])
+            joyStickHandler_[joyStickID]->joyStickAxisMoved(joyStickID, axis, value);
+    }
+
+    void SimpleInputState::joyStickButtonPressed(unsigned int joyStickID, unsigned int button)
+    {
+        assert(joyStickID < joyStickHandler_.size());
+        if (joyStickHandler_[joyStickID])
+            joyStickHandler_[joyStickID]->joyStickButtonPressed(joyStickID, button);
+    }
+
+    void SimpleInputState::joyStickButtonReleased(unsigned int joyStickID, unsigned int button)
+    {
+        assert(joyStickID < joyStickHandler_.size());
+        if (joyStickHandler_[joyStickID])
+            joyStickHandler_[joyStickID]->joyStickButtonReleased(joyStickID, button);
+    }
+
+    void SimpleInputState::joyStickButtonHeld(unsigned int joyStickID, unsigned int button)
+    {
+        assert(joyStickID < joyStickHandler_.size());
+        if (joyStickHandler_[joyStickID])
+            joyStickHandler_[joyStickID]->joyStickButtonHeld(joyStickID, button);
+    }
+
+    /**
+    @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;
+    }
+
+    void SimpleInputState::removeAndDestroyAllHandlers()
+    {
+        for (std::vector<InputTickable*>::iterator it = allHandlers_.begin();
+            it != allHandlers_.end(); ++it)
+            delete *it;
+
+        allHandlers_.clear();
+        keyHandler_ = 0;
+        mouseHandler_ = 0;
+        joyStickHandlerAll_ = 0;
+        for (unsigned int iJoyStick = 0; iJoyStick < joyStickHandler_.size(); ++iJoyStick)
+            joyStickHandler_[iJoyStick] = 0;
+
+        update();
+    }
+
+    /**
+    @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(InputTickable* handler)
+    {
+        setKeyHandler(dynamic_cast<KeyHandler*>(handler));
+        setMouseHandler(dynamic_cast<MouseHandler*>(handler));
+        return setJoyStickHandler(dynamic_cast<JoyStickHandler*>(handler));
+    }
+
+    void SimpleInputState::tickInput(float dt)
+    {
+        for (unsigned int i = 0; i < allHandlers_.size(); ++i)
+        {
+            allHandlers_[i]->tickInput(dt);
+        }
+    }
+
+    void SimpleInputState::tickInput(float dt, unsigned int device)
+    {
+        switch (device)
+        {
+        case Keyboard:
+            if (keyHandler_)
+                keyHandler_->tickKey(dt);
+            break;
+
+        case Mouse:
+            if (mouseHandler_)
+                mouseHandler_->tickMouse(dt);
+            break;
+
+        default: // joy sticks
+            if (joyStickHandler_[device - 2])
+                joyStickHandler_[device - 2]->tickJoyStick(dt, device - 2);
+            break;
+        }
+    }
+
+    void SimpleInputState::update()
+    {
+        // we can use a set to have a list of unique pointers (an object can implement all 3 handlers)
+        std::set<InputTickable*> 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<InputTickable*>::const_iterator itHandler = tempSet.begin();
+            itHandler != tempSet.end(); itHandler++)
+            allHandlers_.push_back(*itHandler);
+
+        // update the deviceEnabled options
+        setInputDeviceEnabled(Keyboard, (keyHandler_ != 0));
+        setInputDeviceEnabled(Mouse, (mouseHandler_ != 0));
+        for (unsigned int i = 0; i < joyStickHandler_.size(); ++i)
+            setInputDeviceEnabled(2 + i, (joyStickHandler_[i] != 0));
+    }
+}
Index: code/branches/input/src/core/input/SimpleInputState.h
===================================================================
--- code/branches/input/src/core/input/SimpleInputState.h	(revision 1637)
+++ code/branches/input/src/core/input/SimpleInputState.h	(revision 1637)
@@ -0,0 +1,90 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief 
+*/
+
+#ifndef _SimpleInputState_H__
+#define _SimpleInputState_H__
+
+#include "core/CorePrereqs.h"
+
+#include <vector>
+#include "InputInterfaces.h"
+#include "InputState.h"
+
+namespace orxonox
+{
+
+    class _CoreExport SimpleInputState : public InputState
+    {
+
+    public:
+        SimpleInputState();
+        ~SimpleInputState() { }
+
+        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(InputTickable* handler);
+        void removeAndDestroyAllHandlers();
+
+    private:
+        void tickInput(float dt);
+        void tickInput(float dt, unsigned int device);
+
+        void keyPressed (const KeyEvent& evt);
+        void keyReleased(const KeyEvent& evt);
+        void keyHeld    (const KeyEvent& evt);
+
+        void mouseButtonPressed (MouseButton::Enum id);
+        void mouseButtonReleased(MouseButton::Enum id);
+        void mouseButtonHeld    (MouseButton::Enum id);
+        void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
+        void mouseScrolled      (int abs, int rel);
+
+        void joyStickButtonPressed (unsigned int joyStickID, unsigned int button);
+        void joyStickButtonReleased(unsigned int joyStickID, unsigned int button);
+        void joyStickButtonHeld    (unsigned int joyStickID, unsigned int button);
+        void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value);
+
+        void update();
+        void numberOfJoySticksChanged(unsigned int n);
+
+        KeyHandler*                   keyHandler_;
+        MouseHandler*                 mouseHandler_;
+        std::vector<JoyStickHandler*> joyStickHandler_;
+        JoyStickHandler*              joyStickHandlerAll_;
+        std::vector<InputTickable*>   allHandlers_;
+    };
+}
+
+#endif /* _SimpleInputState_H__ */
Index: code/branches/input/src/orxonox/Orxonox.cc
===================================================================
--- code/branches/input/src/orxonox/Orxonox.cc	(revision 1636)
+++ code/branches/input/src/orxonox/Orxonox.cc	(revision 1637)
@@ -58,4 +58,6 @@
 #include "core/Loader.h"
 #include "core/input/InputManager.h"
+#include "core/input/SimpleInputState.h"
+#include "core/input/KeyBinder.h"
 #include "core/TclBind.h"
 #include "core/Core.h"
@@ -135,4 +137,5 @@
     if (this->timer_)
       delete this->timer_;
+    dynamic_cast<SimpleInputState*>(InputManager::getState("game"))->removeAndDestroyAllHandlers();
     InputManager::destroy();
     GraphicsEngine::getSingleton().destroy();
@@ -290,13 +293,15 @@
             ogre_->getWindowWidth(), ogre_->getWindowHeight(), true, true, true))
         return false;
+      KeyBinder* keyBinder = new KeyBinder();
+      InputManager::createSimpleInputState("game", 20)->setHandler(keyBinder);
 
       // TOOD: load the GUI here
       // set InputManager to GUI mode
-      InputManager::setInputState(InputManager::IS_GUI);
       // TODO: run GUI here
 
       // The following lines depend very much on the GUI output, so they're probably misplaced here..
 
-      InputManager::setInputState(InputManager::IS_NONE);
+      keyBinder->loadBindings();
+      InputManager::requestEnterState("game");
 
       // create Ogre SceneManager
@@ -325,6 +330,4 @@
         return false;
     }
-
-    InputManager::setInputState(InputManager::IS_NORMAL);
 
     return startRenderLoop();
Index: code/branches/input/src/orxonox/overlays/console/InGameConsole.cc
===================================================================
--- code/branches/input/src/orxonox/overlays/console/InGameConsole.cc	(revision 1636)
+++ code/branches/input/src/orxonox/overlays/console/InGameConsole.cc	(revision 1637)
@@ -463,5 +463,5 @@
         {
             this->bActive_ = true;
-            InputManager::setInputState(InputManager::IS_CONSOLE);
+            InputManager::requestEnterState("console");
             Shell::getInstance().registerListener(this);
 
@@ -485,5 +485,5 @@
         {
             this->bActive_ = false;
-            InputManager::setInputState(InputManager::IS_NORMAL);
+            InputManager::requestLeaveState("console");
             Shell::getInstance().unregisterListener(this);
 
Index: code/branches/input/visual_studio/base_properties.vsprops
===================================================================
--- code/branches/input/visual_studio/base_properties.vsprops	(revision 1636)
+++ code/branches/input/visual_studio/base_properties.vsprops	(revision 1637)
@@ -8,4 +8,5 @@
 	<Tool
 		Name="VCCLCompilerTool"
+		AdditionalOptions="/MP2"
 		AdditionalIncludeDirectories="&quot;$(RootDir)&quot;;&quot;$(RootDir)src&quot;;&quot;$(RootDir)src\orxonox&quot;;&quot;$(RootDir)src\tolua&quot;;&quot;$(RootDir)src\ois&quot;;&quot;$(LibDir)ogre-1.4.8\OgreMain\include&quot;;&quot;$(LibDir)boost-1.35.0&quot;;&quot;$(LibDir)enet-1.2\include&quot;;&quot;$(LibDir)libogg-1.1.3\include&quot;;&quot;$(LibDir)libvorbis-1.2.0\include&quot;;&quot;$(LibDir)lua-5.1.3\src&quot;;&quot;$(LibDir)openal-1.1\include&quot;;&quot;$(LibDir)openal-1.1\alut\include&quot;;&quot;$(LibDir)tcl-8.5.\generic&quot;;&quot;$(LibDir)zlib-1.2.3&quot;"
 		PreprocessorDefinitions="WIN32;__WIN32__;_WIN32;BOOST_ALL_DYN_LINK;OIS_DYNAMIC_LIB; ZLIB_WINAPI"
Index: code/branches/input/visual_studio/vc8/core.vcproj
===================================================================
--- code/branches/input/visual_studio/vc8/core.vcproj	(revision 1636)
+++ code/branches/input/visual_studio/vc8/core.vcproj	(revision 1637)
@@ -280,4 +280,8 @@
 				</File>
 				<File
+					RelativePath="..\..\src\core\input\ExtendedInputState.cc"
+					>
+				</File>
+				<File
 					RelativePath="..\..\src\core\input\HalfAxis.cc"
 					>
@@ -301,4 +305,8 @@
 				<File
 					RelativePath="..\..\src\core\input\KeyDetector.cc"
+					>
+				</File>
+				<File
+					RelativePath="..\..\src\core\input\SimpleInputState.cc"
 					>
 				</File>
@@ -398,4 +406,8 @@
 				</File>
 				<File
+					RelativePath="..\..\src\core\input\ExtendedInputState.h"
+					>
+				</File>
+				<File
 					RelativePath="..\..\src\core\input\HalfAxis.h"
 					>
@@ -418,4 +430,8 @@
 				</File>
 				<File
+					RelativePath="..\..\src\core\input\InputState.h"
+					>
+				</File>
+				<File
 					RelativePath="..\..\src\core\input\KeyBinder.h"
 					>
@@ -423,4 +439,8 @@
 				<File
 					RelativePath="..\..\src\core\input\KeyDetector.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\src\core\input\SimpleInputState.h"
 					>
 				</File>
Index: code/branches/input/visual_studio/vc8/ois.vcproj
===================================================================
--- code/branches/input/visual_studio/vc8/ois.vcproj	(revision 1636)
+++ code/branches/input/visual_studio/vc8/ois.vcproj	(revision 1637)
@@ -43,4 +43,5 @@
 			<Tool
 				Name="VCCLCompilerTool"
+				AdditionalOptions="/MP2"
 				Optimization="2"
 				InlineFunctionExpansion="1"
@@ -128,4 +129,5 @@
 			<Tool
 				Name="VCCLCompilerTool"
+				AdditionalOptions="/MP2"
 				Optimization="0"
 				AdditionalIncludeDirectories="$(RootDir)\src\ois"
