Index: code/branches/core4/src/core/input/InputManager.cc
===================================================================
--- code/branches/core4/src/core/input/InputManager.cc	(revision 3272)
+++ code/branches/core4/src/core/input/InputManager.cc	(revision 3274)
@@ -50,11 +50,14 @@
 #include "core/ConsoleCommand.h"
 #include "core/CommandLine.h"
+#include "core/Functor.h"
 
 #include "InputBuffer.h"
 #include "KeyDetector.h"
+#include "InputHandler.h"
 #include "InputState.h"
-#include "SimpleInputState.h"
-#include "JoyStickDeviceNumberListener.h"
+#include "JoyStickQuantityListener.h"
 #include "JoyStick.h"
+#include "Mouse.h"
+#include "Keyboard.h"
 
 // HACK (include this as last, X11 seems to define some macros...)
@@ -73,8 +76,6 @@
     SetCommandLineSwitch(keyboard_no_grab).information("Whether not to exclusively grab the keyboard");
 
-    EmptyHandler InputManager::EMPTY_HANDLER;
+    InputHandler InputHandler::EMPTY;
     InputManager* InputManager::singletonRef_s = 0;
-
-    using namespace InputDevice;
 
     /**
@@ -109,7 +110,5 @@
     InputManager::InputManager(size_t windowHnd, unsigned int windowWidth, unsigned int windowHeight)
         : inputSystem_(0)
-        , keyboard_(0)
-        , mouse_(0)
-        , devicesNum_(0)
+        , devices_(2)
         , windowHnd_(0)
         , internalState_(Uninitialised)
@@ -117,5 +116,4 @@
         , keyDetector_(0)
         , calibratorCallbackBuffer_(0)
-        , keyboardModifiers_(0)
     {
         RegisterRootObject(InputManager);
@@ -182,4 +180,5 @@
 #endif
 
+            // TODO: clean this up
             try
             {
@@ -199,4 +198,5 @@
             }
 
+            // TODO: Remove the two parameters
             _initialiseMouse(windowWidth, windowHeight);
 
@@ -220,18 +220,21 @@
 
             // Lowest priority empty InputState
-            stateEmpty_ = createInputState<SimpleInputState>("empty", false, false, InputStatePriority::Empty);
-            stateEmpty_->setHandler(&EMPTY_HANDLER);
+            stateEmpty_ = createInputState("empty", false, false, InputStatePriority::Empty);
+            stateEmpty_->setHandler(&InputHandler::EMPTY);
             activeStates_[stateEmpty_->getPriority()] = stateEmpty_;
 
             // KeyDetector to evaluate a pressed key's name
-            SimpleInputState* detector = createInputState<SimpleInputState>("detector", false, false, InputStatePriority::Detector);
+            InputState* detector = createInputState("detector", false, false, InputStatePriority::Detector);
+            FunctorMember<InputManager>* bufferFunctor = createFunctor(&InputManager::clearBuffers);
+            bufferFunctor->setObject(this);
+            detector->setLeaveFunctor(bufferFunctor);
             keyDetector_ = new KeyDetector();
             detector->setHandler(keyDetector_);
 
             // Joy stick calibration helper callback
-            SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", false, false, InputStatePriority::Calibrator);
-            calibrator->setHandler(&EMPTY_HANDLER);
+            InputState* calibrator = createInputState("calibrator", false, false, InputStatePriority::Calibrator);
+            calibrator->setHandler(&InputHandler::EMPTY);
             calibratorCallbackBuffer_ = new InputBuffer();
-            calibratorCallbackBuffer_->registerListener(this, &InputManager::_completeCalibration, '\r', true);
+            calibratorCallbackBuffer_->registerListener(this, &InputManager::_stopCalibration, '\r', true);
             calibrator->setKeyHandler(calibratorCallbackBuffer_);
 
@@ -246,67 +249,30 @@
     }
 
-    /**
-    @brief
-        Creates a keyboard and sets the event handler.
-    @return
-        False if keyboard stays uninitialised, true otherwise.
-    */
     void InputManager::_initialiseKeyboard()
     {
-        if (keyboard_ != 0)
-        {
-            CCOUT(2) << "Warning: Keyboard already initialised, skipping." << std::endl;
-            return;
-        }
+        assert(devices_[InputDeviceEnumerator::Keyboard] == 0);
         if (inputSystem_->getNumberOfDevices(OIS::OISKeyboard) > 0)
-        {
-            keyboard_ = (OIS::Keyboard*)inputSystem_->createInputObject(OIS::OISKeyboard, true);
-            // register our listener in OIS.
-            keyboard_->setEventCallback(this);
-            // note: OIS will not detect keys that have already been down when the keyboard was created.
-            CCOUT(ORX_DEBUG) << "Created OIS keyboard" << std::endl;
-        }
+            devices_[InputDeviceEnumerator::Keyboard] = new Keyboard(InputDeviceEnumerator::Keyboard);
         else
-        {
             ThrowException(InitialisationFailed, "InputManager: No keyboard found, cannot proceed!");
-        }
-    }
-
-    /**
-    @brief
-        Creates a mouse and sets the event handler.
-    @return
-        False if mouse stays uninitialised, true otherwise.
-    */
+    }
+
     void InputManager::_initialiseMouse(unsigned int windowWidth, unsigned int windowHeight)
     {
-        if (mouse_ != 0)
-        {
-            CCOUT(2) << "Warning: Mouse already initialised, skipping." << std::endl;
-            return;
-        }
-        try
-        {
-            if (inputSystem_->getNumberOfDevices(OIS::OISMouse) > 0)
-            {
-                mouse_ = static_cast<OIS::Mouse*>(inputSystem_->createInputObject(OIS::OISMouse, true));
-                // register our listener in OIS.
-                mouse_->setEventCallback(this);
-                CCOUT(ORX_DEBUG) << "Created OIS mouse" << std::endl;
-
-                // Set mouse region
-                setWindowExtents(windowWidth, windowHeight);
-            }
-            else
-            {
-                CCOUT(ORX_WARNING) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
-            }
-        }
-        catch (OIS::Exception ex)
-        {
-            CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS mouse\n"
-                << "OIS error message: \"" << ex.eText << "\"\n Proceeding without mouse support." << std::endl;
-            mouse_ = 0;
-        }
+        assert(devices_[InputDeviceEnumerator::Mouse] == 0);
+        if (inputSystem_->getNumberOfDevices(OIS::OISMouse) > 0)
+        {
+            try
+            {
+                devices_[InputDeviceEnumerator::Mouse] = new Mouse(InputDeviceEnumerator::Mouse, windowWidth, windowHeight);
+            }
+            catch (const OIS::Exception& ex)
+            {
+                CCOUT(2) << "Warning: Failed to create Mouse:" << ex.eText << std::endl
+                         << "Proceeding without mouse support." << std::endl;
+            }
+        }
+        else
+            CCOUT(ORX_WARNING) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
     }
 
@@ -319,13 +285,5 @@
     void InputManager::_initialiseJoySticks()
     {
-        if (!this->joySticks_.empty())
-        {
-            CCOUT(2) << "Warning: Joy sticks already initialised, skipping." << std::endl;
-            return;
-        }
-
-        devicesNum_ = 2 + inputSystem_->getNumberOfDevices(OIS::OISJoyStick);
-        // state management
-        activeStatesTriggered_.resize(devicesNum_);
+        assert(devices_.size() == InputDeviceEnumerator::FirstJoyStick);
 
         for (int i = 0; i < inputSystem_->getNumberOfDevices(OIS::OISJoyStick); i++)
@@ -333,5 +291,5 @@
             try
             {
-                joySticks_.push_back(new JoyStick(activeStatesTriggered_[2 + i], i));
+                devices_.push_back(new JoyStick(InputDeviceEnumerator::FirstJoyStick + i));
             }
             catch (std::exception ex)
@@ -342,12 +300,12 @@
 
         // inform all JoyStick Device Number Listeners
-        for (ObjectList<JoyStickDeviceNumberListener>::iterator it = ObjectList<JoyStickDeviceNumberListener>::begin(); it; ++it)
-            it->JoyStickDeviceNumberChanged(joySticks_.size());
+        for (ObjectList<JoyStickQuantityListener>::iterator it = ObjectList<JoyStickQuantityListener>::begin(); it; ++it)
+            it->JoyStickQuantityChanged(devices_.size() - InputDeviceEnumerator::FirstJoyStick);
     }
 
     void InputManager::_startCalibration()
     {
-        BOOST_FOREACH(JoyStick* stick, joySticks_)
-            stick->startCalibration();
+        BOOST_FOREACH(InputDevice* device, devices_)
+            device->startCalibration();
 
         getInstance().internalState_ |= Calibrating;
@@ -355,12 +313,14 @@
     }
 
-    void InputManager::_completeCalibration()
-    {
-        BOOST_FOREACH(JoyStick* stick, joySticks_)
-            stick->stopCalibration();
+    void InputManager::_stopCalibration()
+    {
+        BOOST_FOREACH(InputDevice* device, devices_)
+            device->stopCalibration();
 
         // restore old input state
         requestLeaveState("calibrator");
         internalState_ &= ~Calibrating;
+        // Clear buffers to prevent button hold events
+        this->clearBuffers();
     }
 
@@ -374,4 +334,5 @@
         Destroys all the created input devices and states.
     */
+    // TODO: export this to be used with reload()
     InputManager::~InputManager()
     {
@@ -379,11 +340,4 @@
         {
             CCOUT(3) << "Destroying ..." << std::endl;
-
-            // kick all active states 'nicely'
-            for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
-                rit != activeStates_.rend(); ++rit)
-            {
-                (*rit).second->onLeave();
-            }
 
             // Destroy calibrator helper handler and state
@@ -401,7 +355,20 @@
 
             // destroy the devices
-            _destroyKeyboard();
-            _destroyMouse();
-            _destroyJoySticks();
+            BOOST_FOREACH(InputDevice*& device, devices_)
+            {
+                std::string className = device->getClassName();
+                try
+                {
+                    if (device)
+                        delete device;
+                    device = 0;
+                    CCOUT(4) << className << " destroyed." << std::endl;
+                }
+                catch (...)
+                {
+                    CCOUT(1) << className << " destruction failed! Potential resource leak!" << std::endl;
+                }
+            }
+            devices_.resize(InputDeviceEnumerator::FirstJoyStick);
 
             try
@@ -416,67 +383,4 @@
 
         singletonRef_s = 0;
-    }
-
-    /**
-    @brief
-        Destroys the keyboard and sets it to 0.
-    */
-    void InputManager::_destroyKeyboard()
-    {
-        assert(inputSystem_);
-        try
-        {
-            if (keyboard_)
-                inputSystem_->destroyInputObject(keyboard_);
-            keyboard_ = 0;
-            CCOUT(4) << "Keyboard destroyed." << std::endl;
-        }
-        catch (...)
-        {
-            CCOUT(1) << "Keyboard destruction failed! Potential resource leak!" << std::endl;
-        }
-    }
-
-    /**
-    @brief
-        Destroys the mouse and sets it to 0.
-    */
-    void InputManager::_destroyMouse()
-    {
-        assert(inputSystem_);
-        try
-        {
-            if (mouse_)
-                inputSystem_->destroyInputObject(mouse_);
-            mouse_ = 0;
-            CCOUT(4) << "Mouse destroyed." << std::endl;
-        }
-        catch (...)
-        {
-            CCOUT(1) << "Mouse destruction failed! Potential resource leak!" << std::endl;
-        }
-    }
-
-    /**
-    @brief
-        Destroys all the joy sticks and resizes the lists to 0.
-    */
-    void InputManager::_destroyJoySticks()
-    {
-        assert(inputSystem_);
-        while (!joySticks_.empty())
-        {
-            try
-            {
-                delete joySticks_.back();
-            }
-            catch (...)
-            {
-                CCOUT(1) << "Joy stick destruction failed! Potential resource leak!" << std::endl;
-            }
-            joySticks_.pop_back();
-            devicesNum_ = 2;
-        }
-        CCOUT(4) << "Joy sticks destroyed." << std::endl;
     }
 
@@ -539,13 +443,26 @@
 
             // Save mouse clipping size
-            int mouseWidth  = mouse_->getMouseState().width;
-            int mouseHeight = mouse_->getMouseState().height;
+            int mouseWidth  = static_cast<Mouse*>(devices_[InputDeviceEnumerator::Mouse])->getClippingWidth();
+            int mouseHeight = static_cast<Mouse*>(devices_[InputDeviceEnumerator::Mouse])->getClippingHeight();
 
             internalState_ &= ~OISReady;
 
             // destroy the devices
-            _destroyKeyboard();
-            _destroyMouse();
-            _destroyJoySticks();
+            // destroy the devices
+            BOOST_FOREACH(InputDevice*& device, devices_)
+            {
+                try
+                {
+                    if (device)
+                        delete device;
+                    device = 0;
+                    CCOUT(4) << device->getClassName() << " destroyed." << std::endl;
+                }
+                catch (...)
+                {
+                    CCOUT(1) << device->getClassName() << " destruction failed! Potential resource leak!" << std::endl;
+                }
+            }
+            devices_.resize(InputDeviceEnumerator::FirstJoyStick);
 
             OIS::InputManager::destroyInputSystem(inputSystem_);
@@ -592,5 +509,5 @@
                 it != stateLeaveRequests_.end(); ++it)
             {
-                (*it)->onLeave();
+                (*it)->left();
                 // just to be sure that the state actually is registered
                 assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());
@@ -631,5 +548,5 @@
                 activeStates_[(*it)->getPriority()] = (*it);
                 _updateActiveStates();
-                (*it)->onEnter();
+                (*it)->entered();
             }
             stateEnterRequests_.clear();
@@ -647,11 +564,11 @@
         }
 
-        // check whether a state has changed its EMPTY_HANDLER situation
+        // check whether a state has changed its EMPTY situation
         bool bUpdateRequired = false;
         for (std::map<int, InputState*>::iterator it = activeStates_.begin(); it != activeStates_.end(); ++it)
         {
-            if (it->second->handlersChanged())
-            {
-                it->second->resetHandlersChanged();
+            if (it->second->hasExpired())
+            {
+                it->second->resetExpiration();
                 bUpdateRequired = true;
             }
@@ -664,39 +581,12 @@
 
         // Capture all the input. This calls the event handlers in InputManager.
-        if (keyboard_)
-            keyboard_->capture();
-        if (mouse_)
-            mouse_->capture();
-        BOOST_FOREACH(JoyStick* stick, joySticks_)
-            stick->capture();
+        BOOST_FOREACH(InputDevice* device, devices_)
+            device->update(time);
 
         if (!(internalState_ & Calibrating))
         {
-            // call all the handlers for the held key events
-            for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
-            {
-                KeyEvent kEvt(keysDown_[iKey], keyboardModifiers_);
-
-                for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
-                    activeStatesTriggered_[Keyboard][iState]->keyHeld(kEvt);
-            }
-
-            // call all the handlers for the held mouse button events
-            for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
-            {
-                for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
-                    activeStatesTriggered_[Mouse][iState]->mouseButtonHeld(mouseButtonsDown_[iButton]);
-            }
-
-            // update the handlers for each active handler
-            for (unsigned int i = 0; i < devicesNum_; ++i)
-            {
-                for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState)
-                    activeStatesTriggered_[i][iState]->updateInput(time.getDeltaTime(), i);
-            }
-
-            // update the handler with a general tick afterwards
+            // update the states with a general tick afterwards
             for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
-                activeStatesTicked_[i]->updateInput(time.getDeltaTime());
+                activeStatesTicked_[i]->update(time.getDeltaTime());
         }
 
@@ -711,13 +601,15 @@
     void InputManager::_updateActiveStates()
     {
-        for (unsigned int i = 0; i < devicesNum_; ++i)
-        {
+        // temporary resize
+        for (unsigned int i = 0; i < devices_.size(); ++i)
+        {
+            std::vector<InputState*>& states = devices_[i]->getStateListRef();
             bool occupied = false;
-            activeStatesTriggered_[i].clear();
-            for (std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
+            states.clear();
+            for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
             {
                 if (rit->second->isInputDeviceEnabled(i) && (!occupied || rit->second->bAlwaysGetsInput_))
                 {
-                    activeStatesTriggered_[i].push_back(rit->second);
+                    states.push_back(rit->second);
                     if (!rit->second->bTransparent_)
                         occupied = true;
@@ -729,7 +621,7 @@
         // Using a std::set to avoid duplicates
         std::set<InputState*> tempSet;
-        for (unsigned int i = 0; i < devicesNum_; ++i)
-            for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState)
-                tempSet.insert(activeStatesTriggered_[i][iState]);
+        for (unsigned int i = 0; i < devices_.size(); ++i)
+            for (unsigned int iState = 0; iState < devices_[i]->getStateListRef().size(); ++iState)
+                tempSet.insert(devices_[i]->getStateListRef()[iState]);
 
         // copy the content of the std::set back to the actual vector
@@ -737,6 +629,4 @@
         for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
             activeStatesTicked_.push_back(*it);
-
-        this->mouseButtonsDown_.clear();
     }
 
@@ -747,166 +637,6 @@
     void InputManager::clearBuffers()
     {
-        keysDown_.clear();
-        keyboardModifiers_ = 0;
-        mouseButtonsDown_.clear();
-        BOOST_FOREACH(JoyStick* stick, joySticks_)
-            stick->clearBuffer();
-    }
-
-
-    // ############################################################
-    // #####                    OIS events                    #####
-    // ##########                                        ##########
-    // ############################################################
-
-    // ###### Key Events ######
-
-    /**
-    @brief
-        Event handler for the keyPressed Event.
-    @param e
-        Event information
-    */
-    bool InputManager::keyPressed(const OIS::KeyEvent &e)
-    {
-        // check whether the key already is in the list (can happen when focus was lost)
-        unsigned int iKey = 0;
-        while (iKey < keysDown_.size() && keysDown_[iKey].key != (KeyCode::ByEnum)e.key)
-            iKey++;
-        if (iKey == keysDown_.size())
-            keysDown_.push_back(Key(e));
-        else
-        {
-            // This happens when XAutoRepeat is set under linux. The KeyPressed event gets then sent
-            // continuously.
-            return true;
-        }
-
-        // update modifiers
-        if(e.key == OIS::KC_RMENU    || e.key == OIS::KC_LMENU)
-            keyboardModifiers_ |= KeyboardModifier::Alt;   // alt key
-        if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL)
-            keyboardModifiers_ |= KeyboardModifier::Ctrl;  // ctrl key
-        if(e.key == OIS::KC_RSHIFT   || e.key == OIS::KC_LSHIFT)
-            keyboardModifiers_ |= KeyboardModifier::Shift; // shift key
-
-        KeyEvent kEvt(e, keyboardModifiers_);
-        for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
-            activeStatesTriggered_[Keyboard][iState]->keyPressed(kEvt);
-
-        return true;
-    }
-
-    /**
-    @brief
-        Event handler for the keyReleased Event.
-    @param e
-        Event information
-    */
-    bool InputManager::keyReleased(const OIS::KeyEvent &e)
-    {
-        // remove the key from the keysDown_ list
-        for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
-        {
-            if (keysDown_[iKey].key == (KeyCode::ByEnum)e.key)
-            {
-                keysDown_.erase(keysDown_.begin() + iKey);
-                break;
-            }
-        }
-
-        // update modifiers
-        if(e.key == OIS::KC_RMENU    || e.key == OIS::KC_LMENU)
-            keyboardModifiers_ &= ~KeyboardModifier::Alt;   // alt key
-        if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL)
-            keyboardModifiers_ &= ~KeyboardModifier::Ctrl;  // ctrl key
-        if(e.key == OIS::KC_RSHIFT   || e.key == OIS::KC_LSHIFT)
-            keyboardModifiers_ &= ~KeyboardModifier::Shift; // shift key
-
-        KeyEvent kEvt(e, keyboardModifiers_);
-        for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
-            activeStatesTriggered_[Keyboard][iState]->keyReleased(kEvt);
-
-        return true;
-    }
-
-
-    // ###### Mouse Events ######
-
-    /**
-    @brief
-        Event handler for the mouseMoved Event.
-    @param e
-        Event information
-    */
-    bool InputManager::mouseMoved(const OIS::MouseEvent &e)
-    {
-        // check for actual moved event
-        if (e.state.X.rel != 0 || e.state.Y.rel != 0)
-        {
-            IntVector2 abs(e.state.X.abs, e.state.Y.abs);
-            IntVector2 rel(e.state.X.rel, e.state.Y.rel);
-            IntVector2 clippingSize(e.state.width, e.state.height);
-            for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
-                activeStatesTriggered_[Mouse][iState]->mouseMoved(abs, rel, clippingSize);
-        }
-
-        // check for mouse scrolled event
-        if (e.state.Z.rel != 0)
-        {
-            for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
-                activeStatesTriggered_[Mouse][iState]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
-        }
-
-        return true;
-    }
-
-    /**
-    @brief
-        Event handler for the mousePressed Event.
-    @param e
-        Event information
-    @param id
-        The ID of the mouse button
-    */
-    bool InputManager::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id)
-    {
-        // check whether the button already is in the list (can happen when focus was lost)
-        unsigned int iButton = 0;
-        while (iButton < mouseButtonsDown_.size() && mouseButtonsDown_[iButton] != (MouseButtonCode::ByEnum)id)
-            iButton++;
-        if (iButton == mouseButtonsDown_.size())
-            mouseButtonsDown_.push_back((MouseButtonCode::ByEnum)id);
-
-        for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
-            activeStatesTriggered_[Mouse][iState]->mouseButtonPressed((MouseButtonCode::ByEnum)id);
-
-        return true;
-    }
-
-    /**
-    @brief
-        Event handler for the mouseReleased Event.
-    @param e
-        Event information
-    @param id
-        The ID of the mouse button
-    */
-    bool InputManager::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id)
-    {
-        // remove the button from the keysDown_ list
-        for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
-        {
-            if (mouseButtonsDown_[iButton] == (MouseButtonCode::ByEnum)id)
-            {
-                mouseButtonsDown_.erase(mouseButtonsDown_.begin() + iButton);
-                break;
-            }
-        }
-
-        for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
-            activeStatesTriggered_[Mouse][iState]->mouseButtonReleased((MouseButtonCode::ByEnum)id);
-
-        return true;
+        BOOST_FOREACH(InputDevice* device, devices_)
+            device->clearBuffers();
     }
 
@@ -923,11 +653,9 @@
         Returns true if ID is ok (unique), false otherwise.
     */
-    bool InputManager::checkJoyStickID(const std::string& idString)
-    {
-        BOOST_FOREACH(JoyStick* stick, joySticks_)
-        {
-            if (stick->getIDString() == idString)
+    bool InputManager::checkJoyStickID(const std::string& idString) const
+    {
+        for (unsigned int i = InputDeviceEnumerator::FirstJoyStick; i < devices_.size(); ++i)
+            if (static_cast<JoyStick*>(devices_[i])->getIDString() == idString)
                 return false;
-        }
         return true;
     }
@@ -938,23 +666,4 @@
     // ##########                                        ##########
     // ############################################################
-
-    /**
-    @brief
-        Adjusts the mouse window metrics.
-        This method has to be called every time the size of the window changes.
-    @param width
-        The new width of the render window
-    @param^height
-        The new height of the render window
-    */
-    void InputManager::setWindowExtents(const int width, const int height)
-    {
-        if (mouse_)
-        {
-            // Set mouse region (if window resizes, we should alter this to reflect as well)
-            mouse_->getMouseState().width  = width;
-            mouse_->getMouseState().height = height;
-        }
-    }
 
     /**
@@ -970,4 +679,31 @@
 
     // ###### InputStates ######
+
+    /**
+    @brief
+        Creates a new InputState by type, name and priority.
+        
+        You will have to use this method because the
+        c'tors and d'tors are private.
+    @remarks
+        The InputManager will take care of the state completely. That also
+        means it gets deleted when the InputManager is destroyed!
+    @param name
+        Name of the InputState when referenced as string
+    @param priority
+        Priority matters when multiple states are active. You can specify any
+        number, but 1 - 99 is preferred (99 means high).
+    */
+    InputState* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
+    {
+        InputState* state = new InputState;
+        if (_configureInputState(state, name, bAlwaysGetsInput, bTransparent, priority))
+            return state;
+        else
+        {
+            delete state;
+            return 0;
+        }
+    }
 
     /**
@@ -1008,5 +744,5 @@
             }
             inputStatesByName_[name] = state;
-            state->JoyStickDeviceNumberChanged(numberOfJoySticks());
+            state->JoyStickQuantityChanged(devices_.size() - InputDeviceEnumerator::FirstJoyStick);
             state->setName(name);
             state->bAlwaysGetsInput_ = bAlwaysGetsInput;
