Index: code/trunk/src/core/input/CalibratorCallback.h
===================================================================
--- code/trunk/src/core/input/CalibratorCallback.h	(revision 2773)
+++ code/trunk/src/core/input/CalibratorCallback.h	(revision 2896)
@@ -52,5 +52,5 @@
         void keyHeld    (const KeyEvent& evt) { }
 
-        void tickInput(float dt) { }
+        void updateInput(float dt) { }
     };
 }
Index: code/trunk/src/core/input/ExtendedInputState.cc
===================================================================
--- code/trunk/src/core/input/ExtendedInputState.cc	(revision 2773)
+++ code/trunk/src/core/input/ExtendedInputState.cc	(revision 2896)
@@ -402,13 +402,13 @@
     }
 
-    void ExtendedInputState::tickInput(float dt)
+    void ExtendedInputState::updateInput(float dt)
     {
         for (unsigned int i = 0; i < allHandlers_.size(); ++i)
         {
-            allHandlers_[i]->tickInput(dt);
-        }
-    }
-
-    void ExtendedInputState::tickInput(float dt, unsigned int device)
+            allHandlers_[i]->updateInput(dt);
+        }
+    }
+
+    void ExtendedInputState::updateInput(float dt, unsigned int device)
     {
         switch (device)
@@ -416,15 +416,15 @@
         case Keyboard:
             for (unsigned int i = 0; i < keyHandlers_.size(); ++i)
-                keyHandlers_[i]->tickKey(dt);
+                keyHandlers_[i]->updateKey(dt);
             break;
 
         case Mouse:
             for (unsigned int i = 0; i < mouseHandlers_.size(); ++i)
-                mouseHandlers_[i]->tickMouse(dt);
+                mouseHandlers_[i]->updateMouse(dt);
             break;
 
         default: // joy sticks
             for (unsigned int i = 0; i < joyStickHandlers_[device - 2].size(); ++i)
-                joyStickHandlers_[device - 2][i]->tickJoyStick(dt, device - 2);
+                joyStickHandlers_[device - 2][i]->updateJoyStick(dt, device - 2);
             break;
         }
Index: code/trunk/src/core/input/ExtendedInputState.h
===================================================================
--- code/trunk/src/core/input/ExtendedInputState.h	(revision 2773)
+++ code/trunk/src/core/input/ExtendedInputState.h	(revision 2896)
@@ -68,6 +68,6 @@
         ~ExtendedInputState() { }
 
-        void tickInput(float dt);
-        void tickInput(float dt, unsigned int device);
+        void updateInput(float dt);
+        void updateInput(float dt, unsigned int device);
 
         void keyPressed (const KeyEvent& evt);
Index: code/trunk/src/core/input/InputBuffer.cc
===================================================================
--- code/trunk/src/core/input/InputBuffer.cc	(revision 2773)
+++ code/trunk/src/core/input/InputBuffer.cc	(revision 2896)
@@ -224,8 +224,8 @@
 
     /**
-        @brief This tick() function is called by the InputManager if the InputBuffer is active.
+        @brief This update() function is called by the InputManager if the InputBuffer is active.
         @param dt Delta time
     */
-    void InputBuffer::tickInput(float dt)
+    void InputBuffer::updateInput(float dt)
     {
         timeSinceKeyPressed_ += dt;
Index: code/trunk/src/core/input/InputBuffer.h
===================================================================
--- code/trunk/src/core/input/InputBuffer.h	(revision 2773)
+++ code/trunk/src/core/input/InputBuffer.h	(revision 2896)
@@ -127,5 +127,5 @@
                 for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); )
                 {
-                    InputBufferListenerTuple<T>* refListener = dynamic_cast<InputBufferListenerTuple<T>*>(*it);
+                    InputBufferListenerTuple<T>* refListener = static_cast<InputBufferListenerTuple<T>*>(*it);
                     if (refListener && refListener->listener_ == listener)
                         this->listeners_.erase(it++);
@@ -171,6 +171,6 @@
             void processKey (const KeyEvent &e);
 
-            void tickInput(float dt);
-            void tickKey(float dt) { }
+            void updateInput(float dt);
+            void updateKey(float dt) { }
 
             std::string buffer_;
Index: code/trunk/src/core/input/InputInterfaces.h
===================================================================
--- code/trunk/src/core/input/InputInterfaces.h	(revision 2773)
+++ code/trunk/src/core/input/InputInterfaces.h	(revision 2896)
@@ -474,5 +474,5 @@
     public:
         virtual ~InputHandler() { }
-        virtual void tickInput(float dt) = 0;
+        virtual void updateInput(float dt) = 0;
     };
 
@@ -488,5 +488,5 @@
         virtual void keyReleased(const KeyEvent& evt) = 0;
         virtual void keyHeld    (const KeyEvent& evt) = 0;
-        virtual void tickKey    (float dt) = 0;
+        virtual void updateKey    (float dt) = 0;
     };
 
@@ -504,5 +504,5 @@
         virtual void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0;
         virtual void mouseScrolled      (int abs, int rel)     = 0;
-        virtual void tickMouse          (float dt) = 0;
+        virtual void updateMouse          (float dt) = 0;
     };
 
@@ -520,5 +520,5 @@
         virtual void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
         virtual void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) = 0;
-        virtual void tickJoyStick          (float dt, unsigned int joyStick) = 0;
+        virtual void updateJoyStick          (float dt, unsigned int joyStick) = 0;
     };
 
@@ -531,8 +531,8 @@
         virtual ~EmptyHandler() { }
 
-        void tickInput(float dt) { }
-        void tickJoyStick(float dt, unsigned int joyStick) { }
-        void tickMouse(float dt) { }
-        void tickKey(float dt) { }
+        void updateInput(float dt) { }
+        void updateJoyStick(float dt, unsigned int joyStick) { }
+        void updateMouse(float dt) { }
+        void updateKey(float dt) { }
 
         void keyPressed (const KeyEvent& evt) { }
Index: code/trunk/src/core/input/InputManager.cc
===================================================================
--- code/trunk/src/core/input/InputManager.cc	(revision 2773)
+++ code/trunk/src/core/input/InputManager.cc	(revision 2896)
@@ -43,4 +43,5 @@
 
 #include "util/Exception.h"
+#include "core/Clock.h"
 #include "core/CoreIncludes.h"
 #include "core/ConfigValueIncludes.h"
@@ -108,5 +109,4 @@
         , internalState_(Uninitialised)
         , stateEmpty_(0)
-        , stateMaster_(0)
         , keyDetector_(0)
         , calibratorCallbackBuffer_(0)
@@ -173,5 +173,5 @@
             //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
             //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
-#if defined OIS_LINUX_PLATFORM
+#if defined ORXONOX_PLATFORM_LINUX
             paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
             paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true"));
@@ -218,20 +218,15 @@
 
             // Lowest priority empty InputState
-            stateEmpty_ = createInputState<SimpleInputState>("empty", -1);
+            stateEmpty_ = createInputState<SimpleInputState>("empty", false, false, InputStatePriority::Empty);
             stateEmpty_->setHandler(&EMPTY_HANDLER);
             activeStates_[stateEmpty_->getPriority()] = stateEmpty_;
 
-            // Always active master InputState
-            stateMaster_ = new ExtendedInputState();
-            stateMaster_->setName("master");
-            stateMaster_->setNumOfJoySticks(joySticksSize_);
-
             // KeyDetector to evaluate a pressed key's name
-            SimpleInputState* detector = createInputState<SimpleInputState>("detector", 101);
+            SimpleInputState* detector = createInputState<SimpleInputState>("detector", false, false, InputStatePriority::Detector);
             keyDetector_ = new KeyDetector();
             detector->setHandler(keyDetector_);
 
             // Joy stick calibration helper callback
-            SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", 100);
+            SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", false, false, InputStatePriority::Calibrator);
             calibrator->setHandler(&EMPTY_HANDLER);
             calibratorCallbackBuffer_ = new InputBuffer();
@@ -424,15 +419,12 @@
 
         // state management
-        activeStatesTop_.resize(devicesNum_);
+        activeStatesTriggered_.resize(devicesNum_);
 
         // inform all states
-        for (std::map<int, InputState*>::const_iterator it = inputStatesByPriority_.begin();
-            it != inputStatesByPriority_.end(); ++it)
+        for (std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.begin();
+            it != inputStatesByName_.end(); ++it)
         {
             it->second->setNumOfJoySticks(joySticksSize_);
         }
-        // inform master state
-        if (stateMaster_)
-            this->stateMaster_->setNumOfJoySticks(joySticksSize_);
 
         // inform all JoyStick Device Number Listeners
@@ -454,5 +446,5 @@
         }
     }
-    
+
     void InputManager::_startCalibration()
     {
@@ -549,11 +541,8 @@
                 // destroy the empty InputState
                 _destroyState(this->stateEmpty_);
-                // destroy the master input state. This might trigger a memory leak
-                // because the user has forgotten to destroy the KeyBinder or any Handler!
-                delete stateMaster_;
 
                 // destroy all user InputStates
-                while (inputStatesByPriority_.size() > 0)
-                    _destroyState((*inputStatesByPriority_.rbegin()).second);
+                while (inputStatesByName_.size() > 0)
+                    _destroyState((*inputStatesByName_.rbegin()).second);
 
                 // destroy the devices
@@ -639,5 +628,4 @@
             _updateActiveStates();
         }
-        inputStatesByPriority_.erase(state->getPriority());
         inputStatesByName_.erase(state->getName());
         delete state;
@@ -670,5 +658,5 @@
     @brief
         Public interface. Only reloads immediately if the call stack doesn't
-        include the tick() method.
+        include the update() method.
     @param joyStickSupport
         Whether or not to initialise joy sticks as well.
@@ -742,8 +730,8 @@
     @brief
         Updates the states and the InputState situation.
-    @param dt
-        Delta time
-    */
-    void InputManager::tick(float dt)
+    @param time
+        Clock holding the current time.
+    */
+    void InputManager::update(const Clock& time)
     {
         if (internalState_ == Uninitialised)
@@ -759,12 +747,14 @@
         if (!stateLeaveRequests_.empty())
         {
-            for (std::set<InputState*>::reverse_iterator rit = stateLeaveRequests_.rbegin();
-                rit != stateLeaveRequests_.rend(); ++rit)
-            {
-                (*rit)->onLeave();
+            for (std::set<InputState*>::iterator it = stateLeaveRequests_.begin();
+                it != stateLeaveRequests_.end(); ++it)
+            {
+                (*it)->onLeave();
                 // just to be sure that the state actually is registered
-                assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end());
-
-                activeStates_.erase((*rit)->getPriority());
+                assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());
+
+                activeStates_.erase((*it)->getPriority());
+                if ((*it)->getPriority() < InputStatePriority::HighPriority)
+                    (*it)->setPriority(0);
                 _updateActiveStates();
             }
@@ -775,13 +765,34 @@
         if (!stateEnterRequests_.empty())
         {
-            for (std::set<InputState*>::reverse_iterator rit = stateEnterRequests_.rbegin();
-                rit != stateEnterRequests_.rend(); ++rit)
+            for (std::set<InputState*>::const_iterator it = stateEnterRequests_.begin();
+                it != stateEnterRequests_.end(); ++it)
             {
                 // just to be sure that the state actually is registered
-                assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end());
-
-                activeStates_[(*rit)->getPriority()] = (*rit);
+                assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());
+
+                if ((*it)->getPriority() == 0)
+                {
+                    // Get smallest possible priority between 1 and maxStateStackSize_s
+#if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator
+                    for(std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
+                        rit != activeStates_.rend(); ++rit)
+#else
+                    for(std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin();
+                        rit != activeStates_.rend(); ++rit)
+#endif
+                    {
+                        if (rit->first < InputStatePriority::HighPriority)
+                        {
+                            (*it)->setPriority(rit->first + 1);
+                            break;
+                        }
+                    }
+                    // In case no normal handler was on the stack
+                    if ((*it)->getPriority() == 0)
+                        (*it)->setPriority(1);
+                }
+                activeStates_[(*it)->getPriority()] = (*it);
                 _updateActiveStates();
-                (*rit)->onEnter();
+                (*it)->onEnter();
             }
             stateEnterRequests_.clear();
@@ -791,8 +802,8 @@
         if (!stateDestroyRequests_.empty())
         {
-            for (std::set<InputState*>::reverse_iterator rit = stateDestroyRequests_.rbegin();
-                rit != stateDestroyRequests_.rend(); ++rit)
-            {
-                _destroyState((*rit));
+            for (std::set<InputState*>::iterator it = stateDestroyRequests_.begin();
+                it != stateDestroyRequests_.end(); ++it)
+            {
+                _destroyState((*it));
             }
             stateDestroyRequests_.clear();
@@ -812,5 +823,5 @@
             _updateActiveStates();
 
-        // mark that we capture and distribute input
+        // mark that we now start capturing and distributing input
         internalState_ |= Ticking;
 
@@ -829,6 +840,7 @@
             {
                 KeyEvent kEvt(keysDown_[iKey], keyboardModifiers_);
-                activeStatesTop_[Keyboard]->keyHeld(kEvt);
-                stateMaster_->keyHeld(kEvt);
+
+                for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
+                    activeStatesTriggered_[Keyboard][iState]->keyHeld(kEvt);
             }
 
@@ -836,6 +848,6 @@
             for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
             {
-                activeStatesTop_[Mouse]->mouseButtonHeld(mouseButtonsDown_[iButton]);
-                stateMaster_->mouseButtonHeld(mouseButtonsDown_[iButton]);
+                for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
+                    activeStatesTriggered_[Mouse][iState]->mouseButtonHeld(mouseButtonsDown_[iButton]);
             }
 
@@ -844,21 +856,18 @@
                 for (unsigned int iButton   = 0; iButton   < joyStickButtonsDown_[iJoyStick].size(); iButton++)
                 {
-                    activeStatesTop_[JoyStick0 + iJoyStick]
-                        ->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
-                    stateMaster_->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
+                    for (unsigned int iState = 0; iState < activeStatesTriggered_[JoyStick0 + iJoyStick].size(); ++iState)
+                        activeStatesTriggered_[JoyStick0 + iJoyStick][iState]->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
                 }
 
-            // tick the handlers for each active handler
+            // update the handlers for each active handler
             for (unsigned int i = 0; i < devicesNum_; ++i)
             {
-                activeStatesTop_[i]->tickInput(dt, i);
-                if (stateMaster_->isInputDeviceEnabled(i))
-                    stateMaster_->tickInput(dt, i);
-            }
-
-            // tick the handler with a general tick afterwards
+                for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState)
+                    activeStatesTriggered_[i][iState]->updateInput(time.getDeltaTime(), i);
+            }
+
+            // update the handler with a general tick afterwards
             for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
-                activeStatesTicked_[i]->tickInput(dt);
-            stateMaster_->tickInput(dt);
+                activeStatesTicked_[i]->updateInput(time.getDeltaTime());
         }
 
@@ -869,12 +878,27 @@
     @brief
         Updates the currently active states (according to activeStates_) for each device.
-        Also, a list of all active states (no duplicates!) is compiled for the general tick.
+        Also, a list of all active states (no duplicates!) is compiled for the general update().
     */
     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;
+        for (unsigned int i = 0; i < devicesNum_; ++i)
+        {
+            bool occupied = false;
+            activeStatesTriggered_[i].clear();
+#if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator
+            for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
+            {
+#else
+            for (std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
+            {
+#endif
+                if (rit->second->isInputDeviceEnabled(i) && (!occupied || rit->second->bAlwaysGetsInput_))
+                {
+                    activeStatesTriggered_[i].push_back(rit->second);
+                    if (!rit->second->bTransparent_)
+                        occupied = true;
+                }
+            }
+        }
 
         // update tickables (every state will only appear once)
@@ -882,7 +906,8 @@
         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
+            for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState)
+                tempSet.insert(activeStatesTriggered_[i][iState]);
+
+        // copy the content of the std::set back to the actual vector
         activeStatesTicked_.clear();
         for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
@@ -942,6 +967,6 @@
 
         KeyEvent kEvt(e, keyboardModifiers_);
-        activeStatesTop_[Keyboard]->keyPressed(kEvt);
-        stateMaster_->keyPressed(kEvt);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
+            activeStatesTriggered_[Keyboard][iState]->keyPressed(kEvt);
 
         return true;
@@ -975,6 +1000,6 @@
 
         KeyEvent kEvt(e, keyboardModifiers_);
-        activeStatesTop_[Keyboard]->keyReleased(kEvt);
-        stateMaster_->keyReleased(kEvt);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
+            activeStatesTriggered_[Keyboard][iState]->keyReleased(kEvt);
 
         return true;
@@ -998,6 +1023,6 @@
             IntVector2 rel(e.state.X.rel, e.state.Y.rel);
             IntVector2 clippingSize(e.state.width, e.state.height);
-            activeStatesTop_[Mouse]->mouseMoved(abs, rel, clippingSize);
-            stateMaster_->mouseMoved(abs, rel, clippingSize);
+            for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
+                activeStatesTriggered_[Mouse][iState]->mouseMoved(abs, rel, clippingSize);
         }
 
@@ -1005,6 +1030,6 @@
         if (e.state.Z.rel != 0)
         {
-            activeStatesTop_[Mouse]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
-            stateMaster_->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
+            for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
+                activeStatesTriggered_[Mouse][iState]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
         }
 
@@ -1029,6 +1054,6 @@
             mouseButtonsDown_.push_back((MouseButtonCode::ByEnum)id);
 
-        activeStatesTop_[Mouse]->mouseButtonPressed((MouseButtonCode::ByEnum)id);
-        stateMaster_->mouseButtonPressed((MouseButtonCode::ByEnum)id);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
+            activeStatesTriggered_[Mouse][iState]->mouseButtonPressed((MouseButtonCode::ByEnum)id);
 
         return true;
@@ -1055,6 +1080,6 @@
         }
 
-        activeStatesTop_[Mouse]->mouseButtonReleased((MouseButtonCode::ByEnum)id);
-        stateMaster_->mouseButtonReleased((MouseButtonCode::ByEnum)id);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
+            activeStatesTriggered_[Mouse][iState]->mouseButtonReleased((MouseButtonCode::ByEnum)id);
 
         return true;
@@ -1092,6 +1117,6 @@
             buttonsDown.push_back((JoyStickButtonCode::ByEnum)button);
 
-        activeStatesTop_[2 + iJoyStick]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
-        stateMaster_->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
+            activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
 
         return true;
@@ -1113,6 +1138,6 @@
         }
 
-        activeStatesTop_[2 + iJoyStick]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
-        stateMaster_->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
+        for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
+            activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
 
         return true;
@@ -1141,6 +1166,6 @@
                 fValue *= joyStickCalibrations_[iJoyStick].negativeCoeff[axis];
 
-            activeStatesTop_[2 + iJoyStick]->joyStickAxisMoved(iJoyStick, axis, fValue);
-            stateMaster_->joyStickAxisMoved(iJoyStick, axis, fValue);
+            for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
+                activeStatesTriggered_[2 + iJoyStick][iState]->joyStickAxisMoved(iJoyStick, axis, fValue);
         }
     }
@@ -1245,9 +1270,11 @@
         Unique name of the handler.
     @param priority
-        Unique integer number. Higher means more prioritised.
+        Determines which InputState gets the input. Higher is better.
+        Use 0 to handle it implicitely by the order of activation.
+        Otherwise numbers larger than maxStateStackSize_s have to be used!
     @return
         True if added, false if name or priority already existed.
     */
-    bool InputManager::_configureInputState(InputState* state, const std::string& name, int priority)
+    bool InputManager::_configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority)
     {
         if (name == "")
@@ -1257,20 +1284,26 @@
         if (inputStatesByName_.find(name) == inputStatesByName_.end())
         {
-            if (inputStatesByPriority_.find(priority)
-                == inputStatesByPriority_.end())
-            {
-                inputStatesByName_[name] = state;
-                inputStatesByPriority_[priority] = state;
-                state->setNumOfJoySticks(numberOfJoySticks());
-                state->setName(name);
+            if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
+            {
+                // Make sure we don't add two high priority states with the same priority
+                for (std::map<std::string, InputState*>::const_iterator it = this->inputStatesByName_.begin();
+                    it != this->inputStatesByName_.end(); ++it)
+                {
+                    if (it->second->getPriority() == priority)
+                    {
+                        COUT(2) << "Warning: Could not add an InputState with the same priority '"
+                            << priority << "' != 0." << std::endl;
+                        return false;
+                    }
+                }
+            }
+            inputStatesByName_[name] = state;
+            state->setNumOfJoySticks(numberOfJoySticks());
+            state->setName(name);
+            state->bAlwaysGetsInput_ = bAlwaysGetsInput;
+            state->bTransparent_ = bTransparent;
+            if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
                 state->setPriority(priority);
-                return true;
-            }
-            else
-            {
-                COUT(2) << "Warning: Could not add an InputState with the same priority '"
-                    << priority << "'." << std::endl;
-                return false;
-            }
+            return true;
         }
         else
@@ -1290,5 +1323,5 @@
     @remarks
         You can't remove the internal states "empty", "calibrator" and "detector".
-        The removal process is being postponed if InputManager::tick() is currently running.
+        The removal process is being postponed if InputManager::update() is currently running.
     */
     bool InputManager::requestDestroyState(const std::string& name)
@@ -1371,5 +1404,5 @@
                 {
                     // not scheduled for destruction
-                    // set prevents a state being added multiple times
+                    // prevents a state being added multiple times
                     stateEnterRequests_.insert(it->second);
                     return true;
@@ -1390,4 +1423,9 @@
     bool InputManager::requestLeaveState(const std::string& name)
     {
+        if (name == "empty")
+        {
+            COUT(2) << "InputManager: Leaving the empty state is not allowed!" << std::endl;
+            return false;
+        }
         // get pointer from the map with all stored handlers
         std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name);
Index: code/trunk/src/core/input/InputManager.h
===================================================================
--- code/trunk/src/core/input/InputManager.h	(revision 2773)
+++ code/trunk/src/core/input/InputManager.h	(revision 2896)
@@ -43,4 +43,5 @@
 #include <stack>
 #include "util/Math.h"
+#include "util/OrxEnum.h"
 #include "core/OrxonoxClass.h"
 #include "InputInterfaces.h"
@@ -74,4 +75,17 @@
         float positiveCoeff[24];
         float negativeCoeff[24];
+    };
+
+    struct InputStatePriority : OrxEnum<InputStatePriority>
+    {
+        OrxEnumConstructors(InputStatePriority);
+
+        static const int Empty        = -1;
+        static const int Dynamic      = 0;
+
+        static const int HighPriority = 1000;
+        static const int Console      = HighPriority + 0;
+        static const int Calibrator   = HighPriority + 1;
+        static const int Detector     = HighPriority + 2;
     };
 
@@ -116,14 +130,13 @@
 
         template <class T>
-        T* createInputState(const std::string& name, int priority);
+        T* createInputState(const std::string& name, bool bAlwaysGetsInput = false, bool bTransparent = false, InputStatePriority priority = InputStatePriority::Dynamic);
 
         InputState* getState       (const std::string& name);
         InputState* getCurrentState();
-        ExtendedInputState* getMasterInputState() { return this->stateMaster_; }
         bool requestDestroyState   (const std::string& name);
         bool requestEnterState     (const std::string& name);
         bool requestLeaveState     (const std::string& name);
 
-        void tick(float dt);
+        void update(const Clock& time);
 
         static InputManager& getInstance()    { assert(singletonRef_s); return *singletonRef_s; }
@@ -165,5 +178,5 @@
 
         void _updateActiveStates();
-        bool _configureInputState(InputState* state, const std::string& name, int priority);
+        bool _configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority);
 
         // input events
@@ -197,10 +210,8 @@
         // some internally handled states and handlers
         SimpleInputState*                   stateEmpty_;
-        ExtendedInputState*                 stateMaster_;          //!< Always active master input state
         KeyDetector*                        keyDetector_;          //!< KeyDetector instance
         InputBuffer*                        calibratorCallbackBuffer_;
 
         std::map<std::string, InputState*>  inputStatesByName_;
-        std::map<int, InputState*>          inputStatesByPriority_;
 
         std::set<InputState*>               stateEnterRequests_;   //!< Request to enter a new state
@@ -209,6 +220,6 @@
 
         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.
+        std::vector<std::vector<InputState*> > activeStatesTriggered_;
+        std::vector<InputState*>            activeStatesTicked_;
 
         // joystick calibration
@@ -249,8 +260,8 @@
     */
     template <class T>
-    T* InputManager::createInputState(const std::string& name, int priority)
+    T* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
     {
         T* state = new T;
-        if (_configureInputState(state, name, priority))
+        if (_configureInputState(state, name, bAlwaysGetsInput, bTransparent, priority))
             return state;
         else
Index: code/trunk/src/core/input/InputState.h
===================================================================
--- code/trunk/src/core/input/InputState.h	(revision 2773)
+++ code/trunk/src/core/input/InputState.h	(revision 2896)
@@ -71,6 +71,6 @@
         virtual void unRegisterOnLeave()                      { executorOnLeave_ = 0; }
 
-        virtual void tickInput(float dt, unsigned int device) = 0;
-        virtual void tickInput(float dt) = 0;
+        virtual void updateInput(float dt, unsigned int device) = 0;
+        virtual void updateInput(float dt) = 0;
 
         virtual void keyPressed (const KeyEvent& evt) = 0;
@@ -90,5 +90,12 @@
 
     protected:
-        InputState() : bHandlersChanged_(false), priority_(0), executorOnEnter_(0), executorOnLeave_(0) { }
+        InputState()
+            : bHandlersChanged_(false)
+            , priority_(0)
+            , bAlwaysGetsInput_(false)
+            , bTransparent_(false)
+            , executorOnEnter_(0)
+            , executorOnLeave_(0)
+        { }
         virtual ~InputState() { }
 
@@ -114,4 +121,6 @@
         int                                         priority_;
         std::vector<bool>                           bInputDeviceEnabled_;
+        bool                                        bAlwaysGetsInput_;
+        bool                                        bTransparent_;
 
         Executor*                                   executorOnEnter_;
Index: code/trunk/src/core/input/KeyBinder.cc
===================================================================
--- code/trunk/src/core/input/KeyBinder.cc	(revision 2773)
+++ code/trunk/src/core/input/KeyBinder.cc	(revision 2896)
@@ -42,5 +42,4 @@
 #include "core/CoreIncludes.h"
 #include "core/ConfigFileManager.h"
-#include "core/Core.h"
 #include "InputCommands.h"
 #include "InputManager.h"
@@ -309,5 +308,5 @@
     }
 
-    void KeyBinder::tickMouse(float dt)
+    void KeyBinder::updateMouse(float dt)
     {
         if (bDeriveMouseInput_)
@@ -349,5 +348,5 @@
             // Why dividing relative value by dt? The reason lies in the simple fact, that when you
             // press a button that has relative movement, that value has to be multiplied by dt to be
-            // frame rate independent. This can easily (and only) be done in tickInput(float).
+            // frame rate independent. This can easily (and only) be done in updateInput(float).
             // Hence we need to divide by dt here for the mouse to compensate, because the relative
             // move movements have nothing to do with dt.
@@ -362,5 +361,5 @@
     }
 
-    void KeyBinder::tickJoyStick(float dt, unsigned int joyStick)
+    void KeyBinder::updateJoyStick(float dt, unsigned int joyStick)
     {
         for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
Index: code/trunk/src/core/input/KeyBinder.h
===================================================================
--- code/trunk/src/core/input/KeyBinder.h	(revision 2773)
+++ code/trunk/src/core/input/KeyBinder.h	(revision 2896)
@@ -68,8 +68,8 @@
 
     protected: // functions
-        void tickInput(float dt);
-        void tickKey(float dt) { }
-        void tickMouse(float dt);
-        void tickJoyStick(float dt, unsigned int joyStick);
+        void updateInput(float dt);
+        void updateKey(float dt) { }
+        void updateMouse(float dt);
+        void updateJoyStick(float dt, unsigned int joyStick);
         // internal
         void tickHalfAxis(HalfAxis& halfAxis);
@@ -134,5 +134,5 @@
         @brief
             Commands that have additional parameters (axes) are executed at the end of
-            the tick() so that all values can be buffered for single execution.
+            update() so that all values can be buffered for single execution.
         */
         std::vector<BufferedParamCommand*> paramCommandBuffer_;
@@ -200,5 +200,5 @@
     { joyStickButtons_[joyStickID][id].execute(KeybindMode::OnHold); }
 
-    inline void KeyBinder::tickInput(float dt)
+    inline void KeyBinder::updateInput(float dt)
     {
         // execute all buffered bindings (additional parameter)
Index: code/trunk/src/core/input/SimpleInputState.h
===================================================================
--- code/trunk/src/core/input/SimpleInputState.h	(revision 2773)
+++ code/trunk/src/core/input/SimpleInputState.h	(revision 2896)
@@ -59,6 +59,6 @@
         ~SimpleInputState() { }
 
-        void tickInput(float dt);
-        void tickInput(float dt, unsigned int device);
+        void updateInput(float dt);
+        void updateInput(float dt, unsigned int device);
 
         void keyPressed (const KeyEvent& evt);
@@ -87,13 +87,13 @@
     };
 
-    inline void SimpleInputState::tickInput(float dt)
+    inline void SimpleInputState::updateInput(float dt)
     {
         for (unsigned int i = 0; i < allHandlers_.size(); ++i)
         {
-            allHandlers_[i]->tickInput(dt);
+            allHandlers_[i]->updateInput(dt);
         }
     }
 
-    inline void SimpleInputState::tickInput(float dt, unsigned int device)
+    inline void SimpleInputState::updateInput(float dt, unsigned int device)
     {
         switch (device)
@@ -101,15 +101,15 @@
         case InputDevice::Keyboard:
             if (keyHandler_)
-                keyHandler_->tickKey(dt);
+                keyHandler_->updateKey(dt);
             break;
 
         case InputDevice::Mouse:
             if (mouseHandler_)
-                mouseHandler_->tickMouse(dt);
+                mouseHandler_->updateMouse(dt);
             break;
 
         default: // joy sticks
             if (joyStickHandler_[device - 2])
-                joyStickHandler_[device - 2]->tickJoyStick(dt, device - 2);
+                joyStickHandler_[device - 2]->updateJoyStick(dt, device - 2);
             break;
         }
