Index: code/trunk/bin/def_keybindings.ini
===================================================================
--- code/trunk/bin/def_keybindings.ini	(revision 1881)
+++ code/trunk/bin/def_keybindings.ini	(revision 1887)
@@ -1,63 +1,35 @@
-[KeyBinder]
-KeyUNASSIGNED=openConsole
-KeyESCAPE=exit
-Key1=
-Key2=
-Key3=
-Key4=
-Key5=
-Key6=
-Key7=
-Key8=
-Key9=
-Key0=
-KeyMINUS=
-KeyEQUALS=openConsole
-KeyBACK=
-KeyTAB=cycleNavigationFocus
-KeyQ=moveRoll
-KeyW=moveLongitudinal
-KeyE=scale -1 moveRoll
-KeyR=
-KeyT=
-KeyY=
-KeyU=
-KeyI=
-KeyO=
-KeyP=
-KeyLBRACKET=
-KeyRBRACKET=
-KeyRETURN=
-KeyLCONTROL=
-KeyA=scale -1 moveLateral
-KeyS=scale -1 moveLongitudinal
-KeyD=moveLateral
+[Keys]
+KeyA="scale -1 moveLateral"
+KeyABNT_C1=
+KeyABNT_C2=
+KeyAT=
+KeyAX=
+KeyApostrophe=
+KeyApps=
+KeyB=
+KeyBack=
+KeyBackslash=
+KeyC=
+KeyCalculator=
+KeyCapsLock=
+KeyColon=
+KeyComma=
+KeyConvert=
+KeyD="scale 1 moveLateral"
+KeyDelete=
+KeyDivide=
+KeyDown=
+KeyE="scale -1 moveRoll"
+KeyEnd=
+KeyEquals=
+KeyEscape="exit"
 KeyF=
-KeyG=
-KeyH=scale -0.3 moveYaw
-KeyJ=scale -0.3 movePitch
-KeyK=scale  0.3 movePitch
-KeyL=scale  0.3 moveYaw
-KeySEMICOLON=
-KeyAPOSTROPHE=
-KeyGRAVE=openConsole
-KeyLSHIFT=
-KeyBACKSLASH=
-KeyZ=
-KeyX=
-KeyC=
-KeyV=
-KeyB=
-KeyN=
-KeyM=
-KeyCOMMA=
-KeyPERIOD=
-KeySLASH=
-KeyRSHIFT=
-KeyMULTIPLY=
-KeyLMENU=
-KeySPACE=
-KeyCAPITAL=
-KeyF1=Overlaygroup toggleVisibility Debug
+KeyF1="OverlayGroup toggleVisibility Debug"
+KeyF10=
+KeyF11=
+KeyF12=
+KeyF13=
+KeyF14=
+KeyF15=
 KeyF2=
 KeyF3=
@@ -68,85 +40,204 @@
 KeyF8=
 KeyF9=
-KeyF10=
-KeyNUMLOCK=
-KeySCROLL=
-KeyNUMPAD7=
-KeyNUMPAD8=
-KeyNUMPAD9=
-KeySUBTRACT=
-KeyNUMPAD4=
-KeyNUMPAD5=
-KeyNUMPAD6=
-KeyADD=
-KeyNUMPAD1=
-KeyNUMPAD2=
-KeyNUMPAD3=
-KeyNUMPAD0=
-KeyDECIMAL=
-Key=
-KeyOEM_102=
-KeyF11=
-KeyF12=
-KeyF13=
-KeyF14=
-KeyF15=
-KeyKANA=
-KeyABNT_C1=
-KeyCONVERT=
-KeyNOCONVERT=
-KeyYEN=
-KeyABNT_C2=
-KeyNUMPADEQUALS=
-KeyPREVTRACK=
-KeyAT=
-KeyCOLON=
-KeyUNDERLINE=
-KeyKANJI=
-KeySTOP=
-KeyAX=
-KeyUNLABELED=
-KeyNEXTTRACK=
-KeyNUMPADENTER=openConsole
-KeyRCONTROL=
-KeyMUTE=
-KeyCALCULATOR=
-KeyPLAYPAUSE=
-KeyMEDIASTOP=
-KeyVOLUMEDOWN=
-KeyVOLUMEUP=
-KeyWEBHOME=
-KeyNUMPADCOMMA=
-KeyDIVIDE=
-KeySYSRQ=
-KeyRMENU=
-KeyPAUSE=
-KeyHOME=
+KeyG=
+KeyGrave="openConsole"
+KeyH=
+KeyHome=
+KeyI=
+KeyInsert=
+KeyJ=
+KeyK=
+KeyKana=
+KeyKanji=
+KeyL=
+KeyLeft=
+KeyLeftAlt=
+KeyLeftBracket=
+KeyLeftControl=
+KeyLeftShift=
+KeyLeftWindows=
+KeyLessThan=
+KeyM=
+KeyMail=
+KeyMediaSelect=
+KeyMediaStop=
+KeyMinus=
+KeyMultiply=
+KeyMute=
+KeyMyComputer=
+KeyN=
+KeyNextTrack=
+KeyNoConvert=
+KeyNumLock=
+KeyNumRow0=
+KeyNumRow1=
+KeyNumRow2=
+KeyNumRow3=
+KeyNumRow4=
+KeyNumRow5=
+KeyNumRow6=
+KeyNumRow7=
+KeyNumRow8=
+KeyNumRow9=
+KeyNumpad0=
+KeyNumpad1=
+KeyNumpad2=
+KeyNumpad3=
+KeyNumpad4=
+KeyNumpad5=
+KeyNumpad6=
+KeyNumpad7=
+KeyNumpad8=
+KeyNumpad9=
+KeyNumpadAdd=
+KeyNumpadComma=
+KeyNumpadEnter=
+KeyNumpadEquals=
+KeyNumpadPeriod=
+KeyNumpadSubtract=
+KeyO=
+KeyP=
+KeyPageDown=
+KeyPageUp=
+KeyPause=
+KeyPeriod=
+KeyPlayPause=
+KeyPower=
+KeyPreviousTrack=
+KeyQ="scale 1 moveRoll"
+KeyR=
+KeyReturn=
+KeyRight=
+KeyRightAlt=
+KeyRightBracket=
+KeyRightControl=
+KeyRightShift=
+KeyRightWindows=
+KeyS="scale -1 moveLongitudinal"
+KeyScrollLock=
+KeySemicolon=
+KeySlash=
+KeySleep=
+KeySpace=
+KeyStop=
+KeySystemRequest=
+KeyT=
+KeyTab="cycleNavigationFocus"
+KeyU=
 KeyUP=
-KeyPGUP=
-KeyLEFT=
-KeyRIGHT=
-KeyEND=
-KeyDOWN=
-KeyPGDOWN=
-KeyINSERT=
-KeyDELETE=
-KeyLWIN=
-KeyRWIN=
-KeyAPPS=
-KeyPOWER=
-KeySLEEP=
-KeyWAKE=
-KeyWEBSEARCH=
-KeyWEBFAVORITES=
-KeyWEBREFRESH=
-KeyWEBSTOP=exit
-KeyWEBFORWARD=
-KeyWEBBACK=
-KeyMYCOMPUTER=
-KeyMAIL=
-KeyMEDIASELECT=
-MouseLeft=fire
-MouseRight=
-MouseMiddle=
+KeyUnassigned=
+KeyUnderline=
+KeyUnlabeled=
+KeyV=
+KeyVolumeDown=
+KeyVolumeUp=
+KeyW="scale 1 moveLongitudinal"
+KeyWake=
+KeyWebBack=
+KeyWebFavorites=
+KeyWebForward=
+KeyWebHome=
+KeyWebRefresh=
+KeyWebSearch=
+KeyWebStop=
+KeyX=
+KeyY=
+KeyYen=
+KeyZ=
+Key_084=
+Key_085=
+Key_089=
+Key_090=
+Key_091=
+Key_092=
+Key_093=
+Key_094=
+Key_095=
+Key_096=
+Key_097=
+Key_098=
+Key_099=
+Key_103=
+Key_104=
+Key_105=
+Key_106=
+Key_107=
+Key_108=
+Key_109=
+Key_110=
+Key_111=
+Key_112=
+Key_114=
+Key_115=
+Key_117=
+Key_118=
+Key_119=
+Key_120=
+Key_121=
+Key_123=
+Key_125=
+Key_128=
+Key_129=
+Key_130=
+Key_131=
+Key_132=
+Key_133=
+Key_134=
+Key_135=
+Key_136=
+Key_137=
+Key_138=
+Key_139=
+Key_140=
+Key_141=
+Key_143=
+Key_144=
+Key_154=
+Key_155=
+Key_158=
+Key_159=
+Key_163=
+Key_165=
+Key_166=
+Key_167=
+Key_168=
+Key_169=
+Key_170=
+Key_171=
+Key_172=
+Key_173=
+Key_175=
+Key_177=
+Key_180=
+Key_182=
+Key_185=
+Key_186=
+Key_187=
+Key_188=
+Key_189=
+Key_190=
+Key_191=
+Key_192=
+Key_193=
+Key_194=
+Key_195=
+Key_196=
+Key_198=
+Key_202=
+Key_204=
+Key_206=
+Key_212=
+Key_213=
+Key_214=
+Key_215=
+Key_216=
+Key_217=
+Key_218=
+Key_224=
+Key_225=
+Key_226=
+Key_228=
+
+[MouseButtons]
 MouseButton3=
 MouseButton4=
@@ -154,111 +245,16 @@
 MouseButton6=
 MouseButton7=
+MouseLeft="fire"
+MouseMiddle=
+MouseRight=
+MouseWheel1Down=
 MouseWheel1Up=
-MouseWheel1Down=
+MouseWheel2Down=
 MouseWheel2Up=
-MouseWheel2Down=
-MouseXPos=scale  1 moveYaw
-MouseXNeg=scale -1 moveYaw
-MouseYPos=scale  1 movePitch
-MouseYNeg=scale -1 movePitch
-Empty1Pos=
-Empty1Neg=
-Empty2Pos=
-Empty2Neg=
-JoyAxis1Pos=scale -1 movePitch
-JoyAxis1Neg=scale  1 movePitch
-JoyAxis2Pos=
-JoyAxis2Neg=
-JoyAxis3Pos=
-JoyAxis3Neg=
-JoyAxis4Pos=
-JoyAxis4Neg=
-JoyAxis5Pos=
-JoyAxis5Neg=
-JoyAxis6Pos=
-JoyAxis6Neg=
-JoyAxis7Pos=
-JoyAxis7Neg=
-JoyAxis8Pos=
-JoyAxis8Neg=
-JoyAxis9Pos=scale   1 moveYaw
-JoyAxis9Neg=scale  -1 moveYaw
-JoyAxis10Pos=
-JoyAxis10Neg=
-JoyAxis11Pos=scale -1 moveLongitudinal
-JoyAxis11Neg=scale  1 moveLongitudinal
-JoyAxis12Pos=scale  1 moveLateral
-JoyAxis12Neg=scale -1 moveLateral
-JoyAxis13Pos=
-JoyAxis13Neg=
-JoyAxis14Pos=
-JoyAxis14Neg=
-JoyAxis15Pos=
-JoyAxis15Neg=
-JoyAxis16Pos=
-JoyAxis16Neg=
-JoyAxis17Pos=
-JoyAxis17Neg=
-JoyAxis18Pos=
-JoyAxis18Neg=
-JoyAxis19Pos=
-JoyAxis19Neg=
-JoyAxis20Pos=
-JoyAxis20Neg=
-JoyAxis21Pos=
-JoyAxis21Neg=
-JoyAxis22Pos=
-JoyAxis22Neg=
-JoyAxis23Pos=
-JoyAxis23Neg=
-JoyAxis24Pos=
-JoyAxis24Neg=
-JoyButton0=cycleNavigationFocus
-JoyButton1=
-JoyButton2=
-JoyButton3=
-JoyButton4=
-JoyButton5=
-JoyButton6=scale  1 moveRoll
-JoyButton7=scale -1 moveRoll
-JoyButton8=
-JoyButton9=fire
-JoyButton10=
-JoyButton11=
-JoyButton12=
-JoyButton13=
-JoyButton14=
-JoyButton15=
-JoyButton16=
-JoyButton17=
-JoyButton18=
-JoyButton19=
-JoyButton20=
-JoyButton21=
-JoyButton22=
-JoyButton23=
-JoyButton24=
-JoyButton25=
-JoyButton26=
-JoyButton27=
-JoyButton28=
-JoyButton29=
-JoyButton30=
-JoyButton31=
-JoyPOV1North=
-JoyPOV1South=
-JoyPOV1East=
-JoyPOV1West=
-JoyPOV2North=
-JoyPOV2South=
-JoyPOV2East=
-JoyPOV2West=
-JoyPOV3North=
-JoyPOV3South=
-JoyPOV3East=
-JoyPOV3West=
-JoyPOV4North=
-JoyPOV4South=
-JoyPOV4East=
-JoyPOV4West=
 
+[MouseAxes]
+MouseXNeg="scale 1 moveYaw"
+MouseXPos="scale -1 moveYaw"
+MouseYNeg="scale 1 movePitch"
+MouseYPos="scale -1 movePitch"
+
Index: code/trunk/src/core/ArgumentCompletionFunctions.h
===================================================================
--- code/trunk/src/core/ArgumentCompletionFunctions.h	(revision 1881)
+++ code/trunk/src/core/ArgumentCompletionFunctions.h	(revision 1887)
@@ -35,5 +35,5 @@
 
 #define ARGUMENT_COMPLETION_FUNCTION_DECLARATION(functionname) \
-    ArgumentCompleter* functionname(); \
+    _CoreExport ArgumentCompleter* functionname(); \
     _CoreExport ArgumentCompletionList acf_##functionname
 
Index: code/trunk/src/core/CMakeLists.txt
===================================================================
--- code/trunk/src/core/CMakeLists.txt	(revision 1881)
+++ code/trunk/src/core/CMakeLists.txt	(revision 1887)
@@ -47,4 +47,5 @@
   input/InputCommands.cc
   input/InputManager.cc
+  input/JoyStickDeviceNumberListener.cc
   input/KeyBinder.cc
   input/KeyDetector.cc
Index: code/trunk/src/core/ConfigFileManager.h
===================================================================
--- code/trunk/src/core/ConfigFileManager.h	(revision 1881)
+++ code/trunk/src/core/ConfigFileManager.h	(revision 1887)
@@ -45,6 +45,5 @@
         CFT_Settings,
         CFT_Keybindings,
-        CFT_JoyStickCalibration,
-        CFT_KeyNames
+        CFT_JoyStickCalibration
     };
 
Index: code/trunk/src/core/ConfigValueContainer.cc
===================================================================
--- code/trunk/src/core/ConfigValueContainer.cc	(revision 1881)
+++ code/trunk/src/core/ConfigValueContainer.cc	(revision 1887)
@@ -50,9 +50,9 @@
         @brief Initializes the ConfigValueContainer with defaultvalues.
     */
-    void ConfigValueContainer::init(ConfigFileType type, Identifier* identifier, const std::string& varname)
+    void ConfigValueContainer::init(ConfigFileType type, Identifier* identifier, const std::string& sectionname, const std::string& varname)
     {
         this->type_ = type;
         this->identifier_ = identifier;
-        this->sectionname_ = identifier->getName();
+        this->sectionname_ = sectionname;
         this->varname_ = varname;
         this->callback_ = 0;
@@ -331,5 +331,5 @@
         if (!this->bAddedDescription_)
         {
-            this->description_ = std::string("ConfigValueDescription::" + this->identifier_->getName() + "::" + this->varname_);
+            this->description_ = std::string("ConfigValueDescription::" + this->sectionname_ + "::" + this->varname_);
             AddLanguageEntry(this->description_, description);
             this->bAddedDescription_ = true;
Index: code/trunk/src/core/ConfigValueContainer.h
===================================================================
--- code/trunk/src/core/ConfigValueContainer.h	(revision 1881)
+++ code/trunk/src/core/ConfigValueContainer.h	(revision 1887)
@@ -99,4 +99,5 @@
                 @param type The type of the corresponding config-file
                 @param identifier The identifier of the class the variable belongs to
+                @param sectionname Name of the section the configValue should be put in.
                 @param varname The name of the variable
                 @param defvalue The default-value
@@ -104,7 +105,7 @@
             */
             template <class D, class V>
-            ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& varname, const D& defvalue, const V& value)
-            {
-                this->init(type, identifier, varname);
+            ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& sectionname, const std::string& varname, const D& defvalue, const V& value)
+            {
+                this->init(type, identifier, sectionname, varname);
                 this->initValue((V)defvalue);
             }
@@ -118,7 +119,7 @@
             */
             template <class V>
-            ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& varname, const std::vector<V>& defvalue)
-            {
-                this->init(type, identifier, varname);
+            ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& sectionname, const std::string& varname, const std::vector<V>& defvalue)
+            {
+                this->init(type, identifier, sectionname, varname);
 
                 this->value_ = V();
@@ -266,5 +267,5 @@
 
         private:
-            void init(ConfigFileType type, Identifier* identifier, const std::string& varname);
+            void init(ConfigFileType type, Identifier* identifier, const std::string& sectionname, const std::string& varname);
             void initValue(const MultiType& defvalue);
             void initVector();
Index: code/trunk/src/core/ConfigValueIncludes.h
===================================================================
--- code/trunk/src/core/ConfigValueIncludes.h	(revision 1881)
+++ code/trunk/src/core/ConfigValueIncludes.h	(revision 1887)
@@ -52,5 +52,5 @@
     if (!container##varname) \
     { \
-        container##varname = new orxonox::ConfigValueContainer(CFT_Settings, identifier##varname, #varname, defvalue, varname); \
+        container##varname = new orxonox::ConfigValueContainer(CFT_Settings, identifier##varname, identifier##varname->getName(), #varname, defvalue, varname); \
         identifier##varname->addConfigValueContainer(#varname, container##varname); \
     } \
@@ -71,5 +71,5 @@
     if (!container##varname) \
     { \
-        container##varname = new orxonox::ConfigValueContainer(CFT_Settings, identifier##varname, #varname, defvalue); \
+        container##varname = new orxonox::ConfigValueContainer(CFT_Settings, identifier##varname, identifier##varname->getName(), #varname, defvalue); \
         identifier##varname->addConfigValueContainer(#varname, container##varname); \
     } \
Index: code/trunk/src/core/input/Button.cc
===================================================================
--- code/trunk/src/core/input/Button.cc	(revision 1881)
+++ code/trunk/src/core/input/Button.cc	(revision 1887)
@@ -34,4 +34,5 @@
 
 #include "Button.h"
+
 #include "util/Convert.h"
 #include "util/SubString.h"
@@ -41,8 +42,24 @@
 #include "core/CommandEvaluation.h"
 #include "core/CommandExecutor.h"
-#include "InputCommands.h"
+#include "core/ConfigValueContainer.h"
 
 namespace orxonox
 {
+    /**
+    @note
+        bButtonThresholdUser_: We set it to true so that setConfigValues in KeyBinder sets the value
+        correctly the first time. It is then set to false first and changed later in Button::parse().
+    */
+    Button::Button()
+        : configContainer_(0)
+        , bButtonThresholdUser_(false)
+        , paramCommandBuffer_(0)
+    {
+        nCommands_[0]=0;
+        nCommands_[1]=0;
+        nCommands_[2]=0;
+        clear();
+    }
+
     void Button::clear()
     {
@@ -65,15 +82,28 @@
     }
 
-    void Button::parse(std::vector<BufferedParamCommand*>& paramCommandBuffer)
-    {
+    void Button::readConfigValue()
+    {
+        // create/get ConfigValueContainer
+        if (!configContainer_)
+        {
+            configContainer_ = new ConfigValueContainer(CFT_Keybindings, 0, groupName_, name_, "", name_);
+            configContainer_->callback(this, &Button::parse);
+        }
+        configContainer_->getValue(&bindingString_, this);
+    }
+
+    void Button::parse()
+    {
+        // delete all commands
+        clear();
+
         if (isEmpty(bindingString_))
-        {
-            clear();
             return;
-        }
+
+        // reset this to false first when parsing (was true before when parsing for the first time)
+        bButtonThresholdUser_ = false;
 
         // use std::vector for a temporary dynamic array
         std::vector<BaseCommand*> commands[3];
-
 
         // separate the commands
@@ -112,4 +142,6 @@
                             parseError("Could not parse 'ButtonThreshold' argument. \
                                 Switching to default value.", true);
+                        else
+                            this->bButtonThresholdUser_ = true;
                     }
                     else if (token == "scale")
@@ -152,11 +184,11 @@
 
                     // add command to the buffer if not yet existing
-                    for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer.size(); iParamCmd++)
-                    {
-                        if (getLowercase(paramCommandBuffer[iParamCmd]->evaluation_.getOriginalCommand())
+                    for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer_->size(); iParamCmd++)
+                    {
+                        if (getLowercase((*paramCommandBuffer_)[iParamCmd]->evaluation_.getOriginalCommand())
                             == getLowercase(commandStr))
                         {
                             // already in list
-                            cmd->paramCommand_ = paramCommandBuffer[iParamCmd];
+                            cmd->paramCommand_ = (*paramCommandBuffer_)[iParamCmd];
                             break;
                         }
@@ -165,5 +197,5 @@
                     {
                         cmd->paramCommand_ = new BufferedParamCommand();
-                        paramCommandBuffer.push_back(cmd->paramCommand_);
+                        paramCommandBuffer_->push_back(cmd->paramCommand_);
                         cmd->paramCommand_->evaluation_ = eval;
                         cmd->paramCommand_->paramIndex_ = paramIndex;
@@ -208,12 +240,4 @@
     }
 
-    bool Button::execute(KeybindMode::Enum mode, float abs, float rel)
-    {
-        // execute all the parsed commands in the string
-        for (unsigned int iCommand = 0; iCommand < nCommands_[mode]; iCommand++)
-            commands_[mode][iCommand]->execute(abs, rel);
-        return true;
-    }
-
     inline void Button::parseError(std::string message, bool serious)
     {
Index: code/trunk/src/core/input/Button.h
===================================================================
--- code/trunk/src/core/input/Button.h	(revision 1881)
+++ code/trunk/src/core/input/Button.h	(revision 1887)
@@ -40,4 +40,5 @@
 #include <string>
 #include <vector>
+#include "InputCommands.h"
 
 namespace orxonox
@@ -46,15 +47,20 @@
     {
     public:
-        Button() { nCommands_[0]=0; nCommands_[1]=0; nCommands_[2]=0; clear(); }
+        Button();
         virtual ~Button() { clear(); }
         virtual void clear();
         virtual bool addParamCommand(ParamCommand* command) { return false; }
-        void parse(std::vector<BufferedParamCommand*>& paramCommandBuffer);
+        void parse();
+        void readConfigValue();
         bool execute(KeybindMode::Enum mode, float abs = 1.0f, float rel = 1.0f);
 
+        //! Container to allow for better configValue support
+        ConfigValueContainer* configContainer_;
         //! The configured string value
         std::string bindingString_;
         //! Name of the trigger as strings
         std::string name_;
+        //! Name of the group of input triggers
+        std::string groupName_;
         //! Basic commands for OnPress, OnHold and OnRelease
         BaseCommand** commands_[3];
@@ -64,8 +70,20 @@
         //! Note: This variable is here to have only one parse() function.
         float buttonThreshold_;
+        bool bButtonThresholdUser_;
+        //! Pointer to the list of parametrised commands
+        std::vector<BufferedParamCommand*>* paramCommandBuffer_;
 
     private:
         void parseError(std::string message, bool serious);
     };
+
+    inline bool Button::execute(KeybindMode::Enum mode, float abs, float rel)
+    {
+        // execute all the parsed commands in the string
+        for (unsigned int iCommand = 0; iCommand < nCommands_[mode]; iCommand++)
+            commands_[mode][iCommand]->execute(abs, rel);
+        return true;
+    }
+
 }
 
Index: code/trunk/src/core/input/ExtendedInputState.cc
===================================================================
--- code/trunk/src/core/input/ExtendedInputState.cc	(revision 1881)
+++ code/trunk/src/core/input/ExtendedInputState.cc	(revision 1887)
@@ -92,5 +92,5 @@
     }
 
-    void ExtendedInputState::mouseButtonPressed(MouseButton::Enum id)
+    void ExtendedInputState::mouseButtonPressed(MouseButtonCode::ByEnum id)
     {
         for (unsigned int i = 0; i < mouseHandlers_.size(); i++)
@@ -98,5 +98,5 @@
     }
 
-    void ExtendedInputState::mouseButtonReleased(MouseButton::Enum id)
+    void ExtendedInputState::mouseButtonReleased(MouseButtonCode::ByEnum id)
     {
         for (unsigned int i = 0; i < mouseHandlers_.size(); i++)
@@ -104,5 +104,5 @@
     }
 
-    void ExtendedInputState::mouseButtonHeld(MouseButton::Enum id)
+    void ExtendedInputState::mouseButtonHeld(MouseButtonCode::ByEnum id)
     {
         for (unsigned int i = 0; i < mouseHandlers_.size(); i++)
@@ -118,5 +118,5 @@
     }
 
-    void ExtendedInputState::joyStickButtonPressed(unsigned int joyStickID, JoyStickButton::Enum id)
+    void ExtendedInputState::joyStickButtonPressed(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
     {
         assert(joyStickID < joyStickHandlers_.size());
@@ -125,5 +125,5 @@
     }
 
-    void ExtendedInputState::joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id)
+    void ExtendedInputState::joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
     {
         assert(joyStickID < joyStickHandlers_.size());
@@ -132,5 +132,5 @@
     }
 
-    void ExtendedInputState::joyStickButtonHeld(unsigned int joyStickID, JoyStickButton::Enum id)
+    void ExtendedInputState::joyStickButtonHeld(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
     {
         assert(joyStickID < joyStickHandlers_.size());
Index: code/trunk/src/core/input/ExtendedInputState.h
===================================================================
--- code/trunk/src/core/input/ExtendedInputState.h	(revision 1881)
+++ code/trunk/src/core/input/ExtendedInputState.h	(revision 1887)
@@ -75,13 +75,13 @@
         void keyHeld    (const KeyEvent& evt);
 
-        void mouseButtonPressed (MouseButton::Enum id);
-        void mouseButtonReleased(MouseButton::Enum id);
-        void mouseButtonHeld    (MouseButton::Enum id);
+        void mouseButtonPressed (MouseButtonCode::ByEnum id);
+        void mouseButtonReleased(MouseButtonCode::ByEnum id);
+        void mouseButtonHeld    (MouseButtonCode::ByEnum id);
         void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
         void mouseScrolled      (int abs, int rel);
 
-        void joyStickButtonPressed (unsigned int joyStickID, JoyStickButton::Enum id);
-        void joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id);
-        void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButton::Enum id);
+        void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
+        void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
+        void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
         void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value);        void updateTickables();
 
Index: code/trunk/src/core/input/HalfAxis.cc
===================================================================
--- code/trunk/src/core/input/HalfAxis.cc	(revision 1881)
+++ code/trunk/src/core/input/HalfAxis.cc	(revision 1887)
@@ -35,5 +35,4 @@
 #include "HalfAxis.h"
 #include "core/CommandEvaluation.h"
-#include "InputCommands.h"
 
 namespace orxonox
@@ -68,11 +67,3 @@
         return true;
     }
-
-    bool HalfAxis::execute()
-    {
-        bool success = true;
-        for (unsigned int i = 0; i < nParamCommands_; i++)
-            success = success && paramCommands_[i]->execute(absVal_, relVal_);
-        return success;
-    }
 }
Index: code/trunk/src/core/input/HalfAxis.h
===================================================================
--- code/trunk/src/core/input/HalfAxis.h	(revision 1881)
+++ code/trunk/src/core/input/HalfAxis.h	(revision 1887)
@@ -38,4 +38,5 @@
 #include "core/CorePrereqs.h"
 #include "Button.h"
+#include "InputCommands.h"
 
 namespace orxonox
@@ -67,4 +68,12 @@
         bool hasChanged_;
     };
+
+    inline bool HalfAxis::execute()
+    {
+        bool success = true;
+        for (unsigned int i = 0; i < nParamCommands_; i++)
+            success = paramCommands_[i]->execute(absVal_, relVal_) && success;
+        return success;
+    }
 }
 
Index: code/trunk/src/core/input/InputBuffer.h
===================================================================
--- code/trunk/src/core/input/InputBuffer.h	(revision 1881)
+++ code/trunk/src/core/input/InputBuffer.h	(revision 1887)
@@ -44,5 +44,5 @@
     public:
         BaseInputBufferListenerTuple(bool bListenToAllChanges, bool bOnlySingleInput,
-            bool trueKeyFalseChar, char _char, KeyCode::Enum key)
+            bool trueKeyFalseChar, char _char, KeyCode::ByEnum key)
             : bListenToAllChanges_(bListenToAllChanges), bOnlySingleInput_(bOnlySingleInput),
               trueKeyFalseChar_(trueKeyFalseChar), char_(_char), key_(key)
@@ -54,5 +54,5 @@
         bool trueKeyFalseChar_;
         char char_;
-        KeyCode::Enum key_;
+        KeyCode::ByEnum key_;
     };
 
@@ -62,5 +62,5 @@
     public:
         InputBufferListenerTuple(T* listener, void (T::*function)(), bool bListenToAllChanges,
-            bool bOnlySingleInput, bool trueKeyFalseChar, char _char, KeyCode::Enum key)
+            bool bOnlySingleInput, bool trueKeyFalseChar, char _char, KeyCode::ByEnum key)
             : BaseInputBufferListenerTuple(bListenToAllChanges, bOnlySingleInput, trueKeyFalseChar, _char, key),
               listener_(listener), function_(function)
@@ -109,5 +109,5 @@
 
             template <class T>
-            void registerListener(T* listener, void (T::*function)(), KeyCode::Enum key)
+            void registerListener(T* listener, void (T::*function)(), KeyCode::ByEnum key)
             {
                 InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, false, true, true, '\0', key);
@@ -115,5 +115,5 @@
             }
             template <class T>
-            void registerListener(T* listener, void (T::*function)() const, KeyCode::Enum key)
+            void registerListener(T* listener, void (T::*function)() const, KeyCode::ByEnum key)
             {
                 InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, false, true, true, '\0', key);
@@ -178,5 +178,5 @@
             unsigned int cursor_;
 
-            KeyCode::Enum lastKey_;
+            KeyCode::ByEnum lastKey_;
             float timeSinceKeyPressed_;
             float timeSinceKeyRepeated_;
Index: code/trunk/src/core/input/InputCommands.cc
===================================================================
--- code/trunk/src/core/input/InputCommands.cc	(revision 1881)
+++ code/trunk/src/core/input/InputCommands.cc	(revision 1887)
@@ -65,19 +65,4 @@
 
     // ###############################
-    // #####    SimpleCommand    #####
-    // ###############################
-
-    /**
-    @brief
-        Executes a simple command with no additional paramters.
-    @return 
-        True if command execution was successful, false otherwise.
-    */
-    bool SimpleCommand::execute(float abs, float rel)
-    {
-        return evaluation_.execute();
-    }
-
-    // ###############################
     // #####    ParamCommand     #####
     // ###############################
Index: code/trunk/src/core/input/InputCommands.h
===================================================================
--- code/trunk/src/core/input/InputCommands.h	(revision 1881)
+++ code/trunk/src/core/input/InputCommands.h	(revision 1887)
@@ -68,4 +68,15 @@
     };
 
+    /**
+    @brief
+        Executes a simple command with no additional paramters.
+    @return 
+        True if command execution was successful, false otherwise.
+    */
+    inline bool SimpleCommand::execute(float abs, float rel)
+    {
+        return evaluation_.execute();
+    }
+
     class _CoreExport ParamCommand : public BaseCommand
     {
Index: code/trunk/src/core/input/InputInterfaces.h
===================================================================
--- code/trunk/src/core/input/InputInterfaces.h	(revision 1881)
+++ code/trunk/src/core/input/InputInterfaces.h	(revision 1887)
@@ -47,6 +47,8 @@
     namespace KeyCode
     {
+        const unsigned int numberOfKeys = 0xEE; // 238
+
         // note: KeyCode comments were directly copied from OISKeyboard.h
-        enum Enum
+        enum ByEnum
         {
             Unassigned    = OIS::KC_UNASSIGNED,
@@ -119,6 +121,6 @@
             F9            = OIS::KC_F9,
             F10           = OIS::KC_F10,
-            Numlock       = OIS::KC_NUMLOCK,
-            Scrolllock    = OIS::KC_SCROLL,          // Scroll Lock
+            NumLock       = OIS::KC_NUMLOCK,
+            ScrollLock    = OIS::KC_SCROLL,          // Scroll Lock
             Numpad7       = OIS::KC_NUMPAD7,
             Numpad8       = OIS::KC_NUMPAD8,
@@ -167,5 +169,5 @@
             NumpadComma   = OIS::KC_NUMPADCOMMA,     // , on numeric keypad (NEC PC98)
             Divide        = OIS::KC_DIVIDE,          // / on numeric keypad
-            SYSRQ         = OIS::KC_SYSRQ,
+            SystemRequest = OIS::KC_SYSRQ,
             RightAlt      = OIS::KC_RMENU,           // right Alt
             Pause         = OIS::KC_PAUSE,           // Pause
@@ -196,9 +198,110 @@
             MediaSelect   = OIS::KC_MEDIASELECT      // Media Select
         };
-    }
-
-    namespace MouseButton
-    {
-        enum Enum
+        
+        // Names as string. Has no real linkage!
+        const char* const ByString[] =
+        {
+            "Unassigned",
+            "Escape",
+            "NumRow1", "NumRow2", "NumRow3", "NumRow4", "NumRow5",
+            "NumRow6", "NumRow7", "NumRow8", "NumRow9", "NumRow0",
+            "Minus", "Equals", "Back", "Tab",
+            "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
+            "LeftBracket", "RightBracket",
+            "Return", "LeftControl",
+            "A", "S", "D", "F", "G", "H", "J", "K", "L",
+            "Semicolon", "Apostrophe", "Grave",
+            "LeftShift", "Backslash",
+            "Z", "X", "C", "V", "B", "N", "M",
+            "Comma", "Period", "Slash",
+            "RightShift",
+            "Multiply",
+            "LeftAlt",
+            "Space",
+            "CapsLock",
+            "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
+            "NumLock", "ScrollLock",
+            "Numpad7", "Numpad8", "Numpad9",
+            "NumpadSubtract",
+            "Numpad4", "Numpad5", "Numpad6",
+            "NumpadAdd",
+            "Numpad1", "Numpad2", "Numpad3", "Numpad0",
+            "NumpadPeriod",
+            "","",
+            "LessThan",
+            "F11", "F12",
+            "","","","","","","","","","","",
+            "F13", "F14", "F15",
+            "","","","","","","","","","",
+            "Kana",
+            "","",
+            "ABNT_C1",
+            "","","","","",
+            "Convert",
+            "",
+            "NoConvert",
+            "",
+            "Yen",
+            "ABNT_C2",
+            "","","","","","","","","","","","","","",
+            "NumpadEquals",
+            "","",
+            "PreviousTrack",
+            "AT",
+            "Colon", "Underline",
+            "Kanji",
+            "Stop",
+            "AX",
+            "Unlabeled",
+            "NextTrack",
+            "","",
+            "NumpadEnter",
+            "RightControl",
+            "","",
+            "Mute",
+            "Calculator",
+            "PlayPause",
+            "",
+            "MediaStop",
+            "","","","","","","","","",
+            "VolumeDown",
+            "",
+            "VolumeUp",
+            "",
+            "WebHome",
+            "NumpadComma",
+            "",
+            "Divide",
+            "",
+            "SystemRequest",
+            "RightAlt",
+            "","","","","","","","","","","","",
+            "Pause",
+            "",
+            "Home",
+            "UP",
+            "PageUp",
+            "",
+            "Left",
+            "",
+            "Right",
+            "",
+            "End", "Down", "PageDown", "Insert", "Delete",
+            "","","","","","","",
+            "LeftWindows", "RightWindows", "Apps",
+            "Power", "Sleep",
+            "","","",
+            "Wake",
+            "",
+            "WebSearch", "WebFavorites", "WebRefresh", "WebStop", "WebForward", "WebBack",
+            "MyComputer", "Mail", "MediaSelect"
+        };
+    }
+
+    namespace MouseButtonCode
+    {
+        const unsigned int numberOfButtons = 8;
+
+        enum ByEnum
         {
             Left    = OIS::MB_Left,
@@ -209,11 +312,44 @@
             Button5 = OIS::MB_Button5,
             Button6 = OIS::MB_Button6,
-            Button7 = OIS::MB_Button7
-        };
-    }
-
-    namespace JoyStickButton
-    {
-        enum Enum
+            Button7 = OIS::MB_Button7,
+        };
+
+        // Names as string. Has no real linkage!
+        const char* const ByString[] =
+        {
+            "Left",
+            "Right",
+            "Middle",
+            "Button3",
+            "Button4",
+            "Button5",
+            "Button6",
+            "Button7",
+        };
+    }
+
+    namespace MouseAxisCode
+    {
+        const unsigned int numberOfAxes = 2;
+
+        enum ByEnum
+        {
+            X,
+            Y
+        };
+
+        // Names as string. Has no real linkage!
+        const char* const ByString[] =
+        {
+            "X",
+            "Y"
+        };
+    }
+
+    namespace JoyStickButtonCode
+    {
+        const unsigned int numberOfButtons = 64;
+
+        enum ByEnum
         {
             Button0       =  0, Button1       =  1, Button2       =  2, Button3       =  3,
@@ -238,4 +374,51 @@
             POV3NorthEast = 60, POV3SouthEast = 61, POV3NorthWest = 62, POV3SouthWest = 63,
         };
+
+        // Names as string. Has no real linkage!
+        const char* const ByString[] =
+        {
+            "Button0",       "Button1",       "Button2",       "Button3",
+            "Button4",       "Button5",       "Button6",       "Button7",
+            "Button8",       "Button9",       "Button10",      "Button11",
+            "Button12",      "Button13",      "Button14",      "Button15",
+            "Button16",      "Button17",      "Button18",      "Button19",
+            "Button20",      "Button21",      "Button22",      "Button23",
+            "Button24",      "Button25",      "Button26",      "Button27",
+            "Button28",      "Button29",      "Button30",      "Button31",
+            "POV0North",     "POV0South",     "POV0East",      "POV0West",
+            "POV0NorthEast", "POV0SouthEast", "POV0NorthWest", "POV0SouthWest",
+            "POV1North",     "POV1South",     "POV1East",      "POV1West",
+            "POV1NorthEast", "POV1SouthEast", "POV1NorthWest", "POV1SouthWest",
+            "POV2North",     "POV2South",     "POV2East",      "POV2West",
+            "POV2NorthEast", "POV2SouthEast", "POV2NorthWest", "POV2SouthWest",
+            "POV3North",     "POV3South",     "POV3East",      "POV3West",
+            "POV3NorthEast", "POV3SouthEast", "POV3NorthWest", "POV3SouthWest"
+        };
+    }
+
+    namespace JoyStickAxisCode
+    {
+        const unsigned int numberOfAxes = 24;
+
+        enum ByEnum
+        {
+            Slider0 =  0, Slider1 =  1, Slider2 =  2, Slider3 =  3,
+            Slider4 =  4, Slider5 =  5, Slider6 =  6, Slider7 =  7,
+            Axis0   =  8, Axis1   =  9, Axis2   = 10, Axis3   = 11,
+            Axis4   = 12, Axis5   = 13, Axis6   = 14, Axis7   = 15,
+            Axis8   = 16, Axis9   = 17, Axis10  = 18, Axis11  = 19,
+            Axis12  = 20, Axis13  = 21, Axis14  = 22, Axis15  = 23
+        };
+
+        // Names as string. Has no real linkage!
+        const char* const ByString[] =
+        {
+            "Slider0", "Slider1", "Slider2", "Slider3",
+            "Slider4", "Slider5", "Slider6", "Slider7",
+            "Axis0",   "Axis1",   "Axis2",   "Axis3",
+            "Axis4",   "Axis5",   "Axis6",   "Axis7",
+            "Axis8",   "Axis9",   "Axis10",  "Axis11",
+            "Axis12",  "Axis13",  "Axis14",  "Axis15"
+        };
     }
 
@@ -259,5 +442,5 @@
             JoyStick1,
             JoyStick2,
-            JoyStick3,
+            JoyStick3
             // note: No problem if there are more joy sticks. This enum is just for convenience.
         };
@@ -266,6 +449,6 @@
     struct _CoreExport Key
     {
-        Key(const OIS::KeyEvent& evt) : key((KeyCode::Enum)evt.key), text(evt.text) { }
-        KeyCode::Enum key;
+        Key(const OIS::KeyEvent& evt) : key((KeyCode::ByEnum)evt.key), text(evt.text) { }
+        KeyCode::ByEnum key;
         unsigned int text;
     };
@@ -274,12 +457,12 @@
     {
     public:
-        KeyEvent(KeyCode::Enum key, unsigned int text) : key(key), text(text) { }
+        KeyEvent(KeyCode::ByEnum key, unsigned int text) : key(key), text(text) { }
         KeyEvent(const OIS::KeyEvent& evt, unsigned int mod)
-            : key((KeyCode::Enum)evt.key), text(evt.text), modifiers(mod) { }
+            : key((KeyCode::ByEnum)evt.key), text(evt.text), modifiers(mod) { }
         KeyEvent(const Key& key, unsigned int mod) : key(key.key), text(key.text), modifiers(mod) { }
         bool isModifierDown(KeyboardModifier::Enum modifier) const
             { return (KeyboardModifier::Enum)modifier&modifiers; }
 
-        const KeyCode::Enum key;
+        const KeyCode::ByEnum key;
         unsigned int text;
         unsigned int modifiers;
@@ -316,7 +499,7 @@
     public:
         virtual ~MouseHandler() { }
-        virtual void mouseButtonPressed (MouseButton::Enum id) = 0;
-        virtual void mouseButtonReleased(MouseButton::Enum id) = 0;
-        virtual void mouseButtonHeld    (MouseButton::Enum id) = 0;
+        virtual void mouseButtonPressed (MouseButtonCode::ByEnum id) = 0;
+        virtual void mouseButtonReleased(MouseButtonCode::ByEnum id) = 0;
+        virtual void mouseButtonHeld    (MouseButtonCode::ByEnum id) = 0;
         virtual void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0;
         virtual void mouseScrolled      (int abs, int rel)     = 0;
@@ -333,7 +516,7 @@
     public:
         virtual ~JoyStickHandler() { }
-        virtual void joyStickButtonPressed (unsigned int joyStickID, JoyStickButton::Enum id) = 0;
-        virtual void joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id) = 0;
-        virtual void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButton::Enum id) = 0;
+        virtual void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
+        virtual void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
+        virtual void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
         virtual void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) = 0;
         virtual void tickJoyStick          (float dt, unsigned int joyStick) = 0;
@@ -357,13 +540,13 @@
         void keyHeld    (const KeyEvent& evt) { }
 
-        void mouseButtonPressed (MouseButton::Enum id) { }
-        void mouseButtonReleased(MouseButton::Enum id) { }
-        void mouseButtonHeld    (MouseButton::Enum id) { }
+        void mouseButtonPressed (MouseButtonCode::ByEnum id) { }
+        void mouseButtonReleased(MouseButtonCode::ByEnum id) { }
+        void mouseButtonHeld    (MouseButtonCode::ByEnum id) { }
         void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) { }
         void mouseScrolled      (int abs, int rel) { }
 
-        void joyStickButtonPressed (unsigned int joyStickID, JoyStickButton::Enum id) { }
-        void joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id) { }
-        void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButton::Enum id) { }
+        void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) { }
+        void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id) { }
+        void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) { }
         void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) { }
     };
Index: code/trunk/src/core/input/InputManager.cc
===================================================================
--- code/trunk/src/core/input/InputManager.cc	(revision 1881)
+++ code/trunk/src/core/input/InputManager.cc	(revision 1887)
@@ -56,9 +56,8 @@
 #include "SimpleInputState.h"
 #include "ExtendedInputState.h"
+#include "JoyStickDeviceNumberListener.h"
 
 namespace orxonox
 {
-    SetConsoleCommand(InputManager, keyBind, true);
-    SetConsoleCommand(InputManager, storeKeyStroke, true);
     SetConsoleCommand(InputManager, calibrate, true);
     SetConsoleCommand(InputManager, reload, false);
@@ -165,4 +164,6 @@
             if (joyStickSupport)
                 _initialiseJoySticks();
+            // Do this anyway to also inform everyone if a joystick was detached.
+            _configureNumberOfJoySticks();
 
             // Set mouse/joystick region
@@ -197,9 +198,9 @@
             stateMaster_ = new ExtendedInputState();
             stateMaster_->setName("master");
+            stateMaster_->setNumOfJoySticks(joySticksSize_);
 
             // KeyDetector to evaluate a pressed key's name
             SimpleInputState* detector = createInputState<SimpleInputState>("detector", 101);
             keyDetector_ = new KeyDetector();
-            keyDetector_->loadBindings("storeKeyStroke");
             detector->setHandler(keyDetector_);
 
@@ -320,5 +321,4 @@
             //CCOUT(ORX_WARNING) << "Warning: Joy stick support requested, but no joy stick was found" << std::endl;
         }
-        _redimensionLists();
     }
 
@@ -331,5 +331,5 @@
         occupy 2 places in the device number dependent lists.
     */
-    void InputManager::_redimensionLists()
+    void InputManager::_configureNumberOfJoySticks()
     {
         joySticksSize_ = joySticks_.size();
@@ -357,5 +357,15 @@
         for (std::map<int, InputState*>::const_iterator it = inputStatesByPriority_.begin();
             it != inputStatesByPriority_.end(); ++it)
+        {
             it->second->setNumOfJoySticks(joySticksSize_);
+        }
+        // inform master state
+        if (stateMaster_)
+            this->stateMaster_->setNumOfJoySticks(joySticksSize_);
+
+        // inform all JoyStick Device Number Listeners
+        for (ObjectList<JoyStickDeviceNumberListener>::iterator it = ObjectList<JoyStickDeviceNumberListener>::begin(); it; ++it)
+            it->JoyStickDeviceNumberChanged(joySticksSize_);
+
     }
 
@@ -385,5 +395,5 @@
             if (!cont)
             {
-                cont = new ConfigValueContainer(CFT_Settings, getIdentifier(), "CoeffPos", coeffPos);
+                cont = new ConfigValueContainer(CFT_Settings, getIdentifier(), getIdentifier()->getName(), "CoeffPos", coeffPos);
                 getIdentifier()->addConfigValueContainer("CoeffPos", cont);
             }
@@ -393,5 +403,5 @@
             if (!cont)
             {
-                cont = new ConfigValueContainer(CFT_Settings, getIdentifier(), "CoeffNeg", coeffNeg);
+                cont = new ConfigValueContainer(CFT_Settings, getIdentifier(), getIdentifier()->getName(), "CoeffNeg", coeffNeg);
                 getIdentifier()->addConfigValueContainer("CoeffNeg", cont);
             }
@@ -401,5 +411,5 @@
             if (!cont)
             {
-                cont = new ConfigValueContainer(CFT_Settings, getIdentifier(), "Zero", zero);
+                cont = new ConfigValueContainer(CFT_Settings, getIdentifier(), getIdentifier()->getName(), "Zero", zero);
                 getIdentifier()->addConfigValueContainer("Zero", cont);
             }
@@ -515,7 +525,7 @@
 
             joySticks_.clear();
-            // don't use _redimensionLists(), might mess with registered handler if
+            // don't use _configureNumberOfJoySticks(), might mess with registered handler if
             // downgrading from 2 to 1 joystick
-            //_redimensionLists();
+            //_configureNumberOfJoySticks();
             joySticksSize_ = 0;
         }
@@ -875,5 +885,5 @@
         // 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::Enum)e.key)
+        while (iKey < keysDown_.size() && keysDown_[iKey].key != (KeyCode::ByEnum)e.key)
             iKey++;
         if (iKey == keysDown_.size())
@@ -912,5 +922,5 @@
         for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
         {
-            if (keysDown_[iKey].key == (KeyCode::Enum)e.key)
+            if (keysDown_[iKey].key == (KeyCode::ByEnum)e.key)
             {
                 keysDown_.erase(keysDown_.begin() + iKey);
@@ -977,11 +987,11 @@
         // 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] != (MouseButton::Enum)id)
+        while (iButton < mouseButtonsDown_.size() && mouseButtonsDown_[iButton] != (MouseButtonCode::ByEnum)id)
             iButton++;
         if (iButton == mouseButtonsDown_.size())
-            mouseButtonsDown_.push_back((MouseButton::Enum)id);
-
-        activeStatesTop_[Mouse]->mouseButtonPressed((MouseButton::Enum)id);
-        stateMaster_->mouseButtonPressed((MouseButton::Enum)id);
+            mouseButtonsDown_.push_back((MouseButtonCode::ByEnum)id);
+
+        activeStatesTop_[Mouse]->mouseButtonPressed((MouseButtonCode::ByEnum)id);
+        stateMaster_->mouseButtonPressed((MouseButtonCode::ByEnum)id);
 
         return true;
@@ -1001,5 +1011,5 @@
         for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
         {
-            if (mouseButtonsDown_[iButton] == (MouseButton::Enum)id)
+            if (mouseButtonsDown_[iButton] == (MouseButtonCode::ByEnum)id)
             {
                 mouseButtonsDown_.erase(mouseButtonsDown_.begin() + iButton);
@@ -1008,6 +1018,6 @@
         }
 
-        activeStatesTop_[Mouse]->mouseButtonReleased((MouseButton::Enum)id);
-        stateMaster_->mouseButtonReleased((MouseButton::Enum)id);
+        activeStatesTop_[Mouse]->mouseButtonReleased((MouseButtonCode::ByEnum)id);
+        stateMaster_->mouseButtonReleased((MouseButtonCode::ByEnum)id);
 
         return true;
@@ -1038,13 +1048,13 @@
 
         // check whether the button already is in the list (can happen when focus was lost)
-        std::vector<JoyStickButton::Enum>& buttonsDown = joyStickButtonsDown_[iJoyStick];
+        std::vector<JoyStickButtonCode::ByEnum>& buttonsDown = joyStickButtonsDown_[iJoyStick];
         unsigned int iButton = 0;
         while (iButton < buttonsDown.size() && buttonsDown[iButton] != button)
             iButton++;
         if (iButton == buttonsDown.size())
-            buttonsDown.push_back((JoyStickButton::Enum)button);
-
-        activeStatesTop_[2 + iJoyStick]->joyStickButtonPressed(iJoyStick, (JoyStickButton::Enum)button);
-        stateMaster_->joyStickButtonPressed(iJoyStick, (JoyStickButton::Enum)button);
+            buttonsDown.push_back((JoyStickButtonCode::ByEnum)button);
+
+        activeStatesTop_[2 + iJoyStick]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
+        stateMaster_->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
 
         return true;
@@ -1056,5 +1066,5 @@
 
         // remove the button from the joyStickButtonsDown_ list
-        std::vector<JoyStickButton::Enum>& buttonsDown = joyStickButtonsDown_[iJoyStick];
+        std::vector<JoyStickButtonCode::ByEnum>& buttonsDown = joyStickButtonsDown_[iJoyStick];
         for (unsigned int iButton = 0; iButton < buttonsDown.size(); iButton++)
         {
@@ -1066,6 +1076,6 @@
         }
 
-        activeStatesTop_[2 + iJoyStick]->joyStickButtonReleased(iJoyStick, (JoyStickButton::Enum)button);
-        stateMaster_->joyStickButtonReleased(iJoyStick, (JoyStickButton::Enum)button);
+        activeStatesTop_[2 + iJoyStick]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
+        stateMaster_->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
 
         return true;
@@ -1177,4 +1187,14 @@
     }
 
+    /**
+    @brief
+        Sets the the name of the command used by the KeyDetector as callback.
+    @param command
+        Command name as string
+    */
+    void InputManager::setKeyDetectorCallback(const std::string& command)
+    {
+        this->keyDetector_->setCallbackCommand(command);
+    }
 
     // ###### InputStates ######
@@ -1356,35 +1376,4 @@
     /**
     @brief
-        Method for easily storing a string with the command executor. It is used by the
-        KeyDetector to get assign commands. The KeyDetector simply executes
-        the command 'storeKeyStroke myName' for each button/axis.
-    @remarks
-        This is only a temporary hack until we thourouhgly support multiple KeyBinders.
-    @param name
-        The name of the button/axis.
-    */
-    void InputManager::storeKeyStroke(const std::string& name)
-    {
-        getInstance().requestLeaveState("detector");
-        COUT(0) << "Binding string \"" << bindingCommmandString_s << "\" on key '" << name << "'" << std::endl;
-        CommandExecutor::execute("config KeyBinder " + name + " " + bindingCommmandString_s, false);
-    }
-
-    /**
-    @brief
-        Assigns a command string to a key/button/axis. The name is determined via KeyDetector
-        and InputManager::storeKeyStroke(.).
-    @param command
-        Command string that can be executed by the CommandExecutor
-    */
-    void InputManager::keyBind(const std::string& command)
-    {
-        bindingCommmandString_s = command;
-        getInstance().requestEnterState("detector");
-        COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl;
-    }
-
-    /**
-    @brief
         Starts joy stick calibration.
     */
Index: code/trunk/src/core/input/InputManager.h
===================================================================
--- code/trunk/src/core/input/InputManager.h	(revision 1881)
+++ code/trunk/src/core/input/InputManager.h	(revision 1887)
@@ -110,9 +110,10 @@
         void clearBuffers();
 
-        int  numberOfKeyboards() { return keyboard_ ? 1 : 0; }
-        int  numberOfMice()      { return mouse_    ? 1 : 0; }
-        int  numberOfJoySticks() { return joySticksSize_; }
+        unsigned int  numberOfKeyboards() { return keyboard_ ? 1 : 0; }
+        unsigned int  numberOfMice()      { return mouse_    ? 1 : 0; }
+        unsigned int  numberOfJoySticks() { return joySticksSize_; }
 
         void setWindowExtents(const int width, const int height);
+        void setKeyDetectorCallback(const std::string& command);
 
         template <class T>
@@ -132,6 +133,4 @@
 
         // console commands
-        static void storeKeyStroke(const std::string& name);
-        static void keyBind(const std::string& command);
         static void calibrate();
         static void reload(bool joyStickSupport = true);
@@ -148,5 +147,5 @@
         void _initialiseMouse();
         void _initialiseJoySticks();
-        void _redimensionLists();
+        void _configureNumberOfJoySticks();
 
         void _destroyKeyboard();
@@ -223,6 +222,6 @@
 
         std::vector<Key>                    keysDown_;
-        std::vector<MouseButton::Enum>      mouseButtonsDown_;
-        std::vector<std::vector<JoyStickButton::Enum> >  joyStickButtonsDown_;
+        std::vector<MouseButtonCode::ByEnum>      mouseButtonsDown_;
+        std::vector<std::vector<JoyStickButtonCode::ByEnum> >  joyStickButtonsDown_;
 
         static std::string                  bindingCommmandString_s;
Index: code/trunk/src/core/input/InputState.h
===================================================================
--- code/trunk/src/core/input/InputState.h	(revision 1881)
+++ code/trunk/src/core/input/InputState.h	(revision 1887)
@@ -78,13 +78,13 @@
         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 mouseButtonPressed (MouseButtonCode::ByEnum id) = 0;
+        virtual void mouseButtonReleased(MouseButtonCode::ByEnum id) = 0;
+        virtual void mouseButtonHeld    (MouseButtonCode::ByEnum id) = 0;
         virtual void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0;
         virtual void mouseScrolled      (int abs, int rel) = 0;
 
-        virtual void joyStickButtonPressed (unsigned int joyStickID, JoyStickButton::Enum id) = 0;
-        virtual void joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id) = 0;
-        virtual void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButton::Enum id) = 0;
+        virtual void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
+        virtual void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
+        virtual void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
         virtual void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) = 0;
 
Index: code/trunk/src/core/input/JoyStickDeviceNumberListener.cc
===================================================================
--- code/trunk/src/core/input/JoyStickDeviceNumberListener.cc	(revision 1887)
+++ code/trunk/src/core/input/JoyStickDeviceNumberListener.cc	(revision 1887)
@@ -0,0 +1,44 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of the JoyStickDeviceNumberListener class.
+*/
+
+#include "JoyStickDeviceNumberListener.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    JoyStickDeviceNumberListener::JoyStickDeviceNumberListener()
+    {
+        RegisterObject(JoyStickDeviceNumberListener);
+    }
+}
Index: code/trunk/src/core/input/JoyStickDeviceNumberListener.h
===================================================================
--- code/trunk/src/core/input/JoyStickDeviceNumberListener.h	(revision 1887)
+++ code/trunk/src/core/input/JoyStickDeviceNumberListener.h	(revision 1887)
@@ -0,0 +1,52 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief 
+*/
+
+#ifndef _JoyStickDeviceNumberListener_H__
+#define _JoyStickDeviceNumberListener_H__
+
+#include "core/CorePrereqs.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _CoreExport JoyStickDeviceNumberListener : virtual public OrxonoxClass
+    {
+    public:
+        JoyStickDeviceNumberListener();
+        virtual ~JoyStickDeviceNumberListener() { }
+
+        virtual void JoyStickDeviceNumberChanged(unsigned int value) = 0;
+    };
+}
+
+#endif /* _JoyStickDeviceNumberListener_H__ */
Index: code/trunk/src/core/input/KeyBinder.cc
===================================================================
--- code/trunk/src/core/input/KeyBinder.cc	(revision 1881)
+++ code/trunk/src/core/input/KeyBinder.cc	(revision 1887)
@@ -41,4 +41,5 @@
 #include "core/ConfigFileManager.h"
 #include "InputCommands.h"
+#include "InputManager.h"
 
 namespace orxonox
@@ -49,5 +50,6 @@
     */
     KeyBinder::KeyBinder()
-        : deriveTime_(0.0f)
+        : numberOfJoySticks_(0)
+        , deriveTime_(0.0f)
     {
         mouseRelative_[0] = 0;
@@ -58,141 +60,59 @@
         RegisterRootObject(KeyBinder);
 
+        // intialise all buttons and half axes to avoid creating everything with 'new'
         // keys
-        std::string keyNames[] = {
-        "UNASSIGNED",
-        "ESCAPE",
-        "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
-        "MINUS", "EQUALS", "BACK", "TAB",
-        "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
-        "LBRACKET", "RBRACKET",
-        "RETURN", "LCONTROL",
-        "A", "S", "D", "F", "G", "H", "J", "K", "L",
-        "SEMICOLON", "APOSTROPHE", "GRAVE",
-        "LSHIFT", "BACKSLASH",
-        "Z", "X", "C", "V", "B", "N", "M",
-        "COMMA", "PERIOD", "SLASH",
-        "RSHIFT",
-        "MULTIPLY",
-        "LMENU",
-        "SPACE",
-        "CAPITAL",
-        "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
-        "NUMLOCK", "SCROLL",
-        "NUMPAD7", "NUMPAD8", "NUMPAD9",
-        "SUBTRACT",
-        "NUMPAD4", "NUMPAD5", "NUMPAD6",
-        "ADD",
-        "NUMPAD1", "NUMPAD2", "NUMPAD3", "NUMPAD0",
-        "DECIMAL",
-        "","",
-        "OEM_102",
-        "F11", "F12",
-        "","","","","","","","","","","",
-        "F13", "F14", "F15",
-        "","","","","","","","","","",
-        "KANA",
-        "","",
-        "ABNT_C1",
-        "","","","","",
-        "CONVERT",
-        "",
-        "NOCONVERT",
-        "",
-        "YEN",
-        "ABNT_C2",
-        "","","","","","","","","","","","","","",
-        "NUMPADEQUALS",
-        "","",
-        "PREVTRACK",
-        "AT",
-        "COLON", "UNDERLINE",
-        "KANJI",
-        "STOP",
-        "AX",
-        "UNLABELED",
-        "NEXTTRACK",
-        "","",
-        "NUMPADENTER",
-        "RCONTROL",
-        "","",
-        "MUTE",
-        "CALCULATOR",
-        "PLAYPAUSE",
-        "",
-        "MEDIASTOP",
-        "","","","","","","","","",
-        "VOLUMEDOWN",
-        "",
-        "VOLUMEUP",
-        "",
-        "WEBHOME",
-        "NUMPADCOMMA",
-        "",
-        "DIVIDE",
-        "",
-        "SYSRQ",
-        "RMENU",
-        "","","","","","","","","","","","",
-        "PAUSE",
-        "",
-        "HOME",
-        "UP",
-        "PGUP",
-        "",
-        "LEFT",
-        "",
-        "RIGHT",
-        "",
-        "END", "DOWN", "PGDOWN", "INSERT", "DELETE",
-        "","","","","","","",
-        "LWIN", "RWIN", "APPS",
-        "POWER", "SLEEP",
-        "","","",
-        "WAKE",
-        "",
-        "WEBSEARCH", "WEBFAVORITES", "WEBREFRESH", "WEBSTOP", "WEBFORWARD", "WEBBACK",
-        "MYCOMPUTER", "MAIL", "MEDIASELECT"
-        };
-        for (unsigned int i = 0; i < nKeys_s; i++)
-            keys_[i].name_ = "Key" + keyNames[i];
-
-        // mouse buttons
-        std::string mouseButtonNames[] = {
-            "MouseLeft",     "MouseRight",   "MouseMiddle",
-            "MouseButton3",  "MouseButton4", "MouseButton5",
-            "MouseButton6",  "MouseButton7",
-            "MouseWheel1Up", "MouseWheel1Down",
-            "MouseWheel2Up", "MouseWheel2Down"
-        };
-        for (unsigned int i = 0; i < nMouseButtons_s; i++)
-            mouseButtons_[i].name_ = mouseButtonNames[i];
-
-        // joy stick buttons
-        for (unsigned int i = 0; i < 32; i++)
-            joyStickButtons_[i].name_ = "JoyButton" + getConvertedValue<int, std::string>(i);
-        for (unsigned int i = 32; i < nJoyStickButtons_s; i += 4)
-        {
-            joyStickButtons_[i + 0].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "North";
-            joyStickButtons_[i + 1].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "South";
-            joyStickButtons_[i + 2].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "East";
-            joyStickButtons_[i + 3].name_ = "JoyPOV" + convertToString((i - 32)/4 + 1) + "West";
-        }
-
-        // half axes
-        std::string rawNames[nHalfAxes_s/2];
-        rawNames[0] = "MouseX";
-        rawNames[1] = "MouseY";
-        rawNames[2] = "Empty1";
-        rawNames[3] = "Empty2";
-        for (unsigned int i = 4; i < nHalfAxes_s/2; i++)
-            rawNames[i] = "JoyAxis" + convertToString(i - 3);
-        for (unsigned int i = 0; i < nHalfAxes_s/2; i++)
-        {
-            halfAxes_[i * 2 + 0].name_ = rawNames[i] + "Pos";
-            halfAxes_[i * 2 + 1].name_ = rawNames[i] + "Neg";
-        }
-
-        for (unsigned int i = 0; i < this->nHalfAxes_s; i++)
-            halfAxes_[i].buttonThreshold_ = buttonThreshold_;
+        for (unsigned int i = 0; i < KeyCode::numberOfKeys; i++)
+        {
+            std::string keyname = KeyCode::ByString[i];
+            if (!keyname.empty())
+            {
+                keys_[i].name_ = std::string("Key") + keyname;
+            }
+            else
+            {
+                // some keys have name "" because the code is not occupied by OIS
+                // Use "Key_" plus the number as name to put it at the end of the config file section
+                std::string number = convertToString(i);
+                if (i < 100)
+                    number.insert(0, "0");
+                keys_[i].name_ = std::string("Key_") + number;
+            }
+            keys_[i].paramCommandBuffer_ = &paramCommandBuffer_;
+            keys_[i].groupName_ = "Keys";
+        }
+        // mouse buttons plus 4 mouse wheel buttons only 'generated' by KeyBinder
+        const char* const mouseWheelNames[] = { "Wheel1Down", "Wheel1Up", "Wheel2Down", "Wheel2Up" };
+        for (unsigned int i = 0; i < numberOfMouseButtons_; i++)
+        {
+            std::string nameSuffix;
+            if (i < MouseButtonCode::numberOfButtons)
+                nameSuffix = MouseButtonCode::ByString[i];
+            else
+                nameSuffix = mouseWheelNames[i - MouseButtonCode::numberOfButtons];
+            mouseButtons_[i].name_ = std::string("Mouse") + nameSuffix;
+            mouseButtons_[i].paramCommandBuffer_ = &paramCommandBuffer_;
+            mouseButtons_[i].groupName_ = "MouseButtons";
+        }
+        // mouse axes
+        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
+        {
+            mouseAxes_[i].name_ = std::string("Mouse") + MouseAxisCode::ByString[i >> 1];
+            if (i & 1)
+                mouseAxes_[i].name_ += "Pos";
+            else
+                mouseAxes_[i].name_ += "Neg";
+            mouseAxes_[i].paramCommandBuffer_ = &paramCommandBuffer_;
+            mouseAxes_[i].groupName_ = "MouseAxes";
+        }
+
+        // initialise joy sticks separatly to allow for reloading
+        numberOfJoySticks_ = InputManager::getInstance().numberOfJoySticks();
+        initialiseJoyStickBindings();
+
+        // collect all Buttons and HalfAxes
+        compilePointerLists();
+
+        // set them here to use allHalfAxes_
+        setConfigValues();
     }
 
@@ -209,37 +129,10 @@
     /**
     @brief
-        Loads the key and button bindings.
-    @return
-        True if loading succeeded.
-    */
-    void KeyBinder::loadBindings()
-    {
-        COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
-
-        clearBindings();
-
-        std::ifstream infile;
-        infile.open("keybindings.ini");
-        if (!infile)
-        {
-            ConfigFileManager::getInstance().setFile(CFT_Keybindings, "def_keybindings.ini");
-            ConfigFileManager::getInstance().save(CFT_Keybindings, "keybindings.ini");
-        }
-        else
-            infile.close();
-        ConfigFileManager::getInstance().setFile(CFT_Keybindings, "keybindings.ini");
-
-        // parse key bindings
-        setConfigValues();
-
-        COUT(3) << "KeyBinder: Loading key bindings done." << std::endl;
-    }
-
-    /**
-    @brief
         Loader for the key bindings, managed by config values.
     */
     void KeyBinder::setConfigValues()
     {
+        SetConfigValue(defaultKeybindings_, "def_keybindings.ini")
+            .description("Filename of default keybindings.");
         SetConfigValue(analogThreshold_, 0.05f)
             .description("Threshold for analog axes until which the state is 0.");
@@ -252,51 +145,151 @@
         SetConfigValue(mouseSensitivityDerived_, 1.0f)
             .description("Mouse sensitivity if mouse input is derived.");
-        SetConfigValue(bClipMouse_, true)
-            .description("Whether or not to clip absolute value of mouse in non derive mode.");
-
-        float oldThresh = buttonThreshold_;
+        SetConfigValue(mouseWheelStepSize_, 120.0f)
+            .description("Equals one step of the mousewheel.");
         SetConfigValue(buttonThreshold_, 0.80f)
-            .description("Threshold for analog axes until which the button is not pressed.");
-        if (oldThresh != buttonThreshold_)
-            for (unsigned int i = 0; i < nHalfAxes_s; i++)
-                if (halfAxes_[i].buttonThreshold_ == oldThresh)
-                    halfAxes_[i].buttonThreshold_ = buttonThreshold_;
-
-        // keys
-        for (unsigned int i = 0; i < nKeys_s; i++)
-            readTrigger(keys_[i]);
-        // mouse buttons
-        for (unsigned int i = 0; i < nMouseButtons_s; i++)
-            readTrigger(mouseButtons_[i]);
-        // joy stick buttons
-        for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
-            readTrigger(joyStickButtons_[i]);
-        // half axes
-        for (unsigned int i = 0; i < nHalfAxes_s; i++)
-            readTrigger(halfAxes_[i]);
-    }
-
-    void KeyBinder::readTrigger(Button& button)
-    {
-        // config value stuff
-        ConfigValueContainer* cont
-            = ClassIdentifier<KeyBinder>::getIdentifier()->getConfigValueContainer(button.name_);
-        if (!cont)
-        {
-            cont = new ConfigValueContainer
-                (CFT_Keybindings, ClassIdentifier<KeyBinder>::getIdentifier(), button.name_, "", button.name_);
-            ClassIdentifier<KeyBinder>::getIdentifier()->addConfigValueContainer(button.name_, cont);
-        }
-        std::string old = button.bindingString_;
-        cont->getValue(&button.bindingString_, this);
-
-        // keybinder stuff
-        if (old != button.bindingString_)
-        {
-            // clear everything so we don't get old axis ParamCommands mixed up
-            button.clear();
-
-            // binding has changed
-            button.parse(paramCommandBuffer_);
+            .description("Threshold for analog axes until which the button is not pressed.")
+            .callback(this, &KeyBinder::buttonThresholdChanged);
+    }
+
+    void KeyBinder::buttonThresholdChanged()
+    {
+        for (unsigned int i = 0; i < allHalfAxes_.size(); i++)
+            if (!allHalfAxes_[i]->bButtonThresholdUser_)
+                allHalfAxes_[i]->buttonThreshold_ = this->buttonThreshold_;
+    }
+
+    void KeyBinder::JoyStickDeviceNumberChanged(unsigned int value)
+    {
+        unsigned int oldValue = numberOfJoySticks_;
+        numberOfJoySticks_ = value;
+
+        // initialise joy stick bindings
+        initialiseJoyStickBindings();
+
+        // collect all Buttons and HalfAxes again
+        compilePointerLists();
+
+        // load the bindings if required
+        if (!configFile_.empty())
+        {
+            for (unsigned int iDev = oldValue; iDev < numberOfJoySticks_; ++iDev)
+            {
+                for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; ++i)
+                    joyStickButtons_[iDev][i].readConfigValue();
+                for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; ++i)
+                    joyStickAxes_[iDev][i].readConfigValue();
+            }
+        }
+
+        // Set the button threshold for potential new axes
+        buttonThresholdChanged();
+    }
+
+    void KeyBinder::initialiseJoyStickBindings()
+    {
+        this->joyStickAxes_.resize(numberOfJoySticks_);
+        this->joyStickButtons_.resize(numberOfJoySticks_);
+
+        // reinitialise all joy stick binings (doesn't overwrite the old ones)
+        for (unsigned int iDev = 0; iDev < numberOfJoySticks_; iDev++)
+        {
+            std::string deviceNumber = convertToString(iDev);
+            // joy stick buttons
+            for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
+            {
+                joyStickButtons_[iDev][i].name_ = std::string("JoyStick") + deviceNumber + JoyStickButtonCode::ByString[i];
+                joyStickButtons_[iDev][i].paramCommandBuffer_ = &paramCommandBuffer_;
+                joyStickButtons_[iDev][i].groupName_ = std::string("JoyStick") + deviceNumber + "Buttons";
+            }
+            // joy stick axes
+            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
+            {
+                joyStickAxes_[iDev][i].name_ = std::string("JoyStick") + deviceNumber + JoyStickAxisCode::ByString[i >> 1];
+                if (i & 1)
+                    joyStickAxes_[iDev][i].name_ += "Pos";
+                else
+                    joyStickAxes_[iDev][i].name_ += "Neg";
+                joyStickAxes_[iDev][i].paramCommandBuffer_ = &paramCommandBuffer_;
+                joyStickAxes_[iDev][i].groupName_ = std::string("JoyStick") + deviceNumber + "Axes";
+            }
+        }
+    }
+
+    void KeyBinder::compilePointerLists()
+    {
+        allButtons_.clear();
+        allHalfAxes_.clear();
+
+        for (unsigned int i = 0; i < KeyCode::numberOfKeys; i++)
+            allButtons_[keys_[i].name_] = keys_ + i;
+        for (unsigned int i = 0; i < numberOfMouseButtons_; i++)
+            allButtons_[mouseButtons_[i].name_] = mouseButtons_ + i;
+        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
+        {
+            allButtons_[mouseAxes_[i].name_] = mouseAxes_ + i;
+            allHalfAxes_.push_back(mouseAxes_ + i);
+        }
+        for (unsigned int iDev = 0; iDev < numberOfJoySticks_; iDev++)
+        {
+            for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
+                allButtons_[joyStickButtons_[iDev][i].name_] = &(joyStickButtons_[iDev][i]);
+            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
+            {
+                allButtons_[joyStickAxes_[iDev][i].name_] = &(joyStickAxes_[iDev][i]);
+                allHalfAxes_.push_back(&(joyStickAxes_[iDev][i]));
+            }
+        }
+    }
+
+    /**
+    @brief
+        Loads the key and button bindings.
+    @return
+        True if loading succeeded.
+    */
+    void KeyBinder::loadBindings(const std::string& filename)
+    {
+        COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
+
+        configFile_ = filename;
+        if (configFile_.empty())
+            return;
+
+        // get bindings from default file if filename doesn't exist.
+        std::ifstream infile;
+        infile.open(configFile_.c_str());
+        if (!infile)
+        {
+            ConfigFileManager::getInstance().setFile(CFT_Keybindings, defaultKeybindings_);
+            ConfigFileManager::getInstance().save(CFT_Keybindings, configFile_);
+        }
+        else
+            infile.close();
+        ConfigFileManager::getInstance().setFile(CFT_Keybindings, configFile_);
+
+        // Parse bindings and create the ConfigValueContainers if necessary
+        clearBindings();
+        for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
+            it->second->readConfigValue();
+
+        COUT(3) << "KeyBinder: Loading key bindings done." << std::endl;
+    }
+
+    bool KeyBinder::setBinding(const std::string& binding, const std::string& name, bool bTemporary)
+    {
+        std::map<std::string, Button*>::iterator it = allButtons_.find(name);
+        if (it != allButtons_.end())
+        {
+            if (bTemporary)
+                it->second->configContainer_->tset(binding);
+            else
+                it->second->configContainer_->set(binding);
+            it->second->configContainer_->getValue(&(it->second->bindingString_), it->second);
+            return true;
+        }
+        else
+        {
+            COUT(2) << "Could not find key/button/axis with name '" << name << "'." << std::endl;
+            return false;
         }
     }
@@ -308,15 +301,6 @@
     void KeyBinder::clearBindings()
     {
-        for (unsigned int i = 0; i < nKeys_s; i++)
-            keys_[i].clear();
-
-        for (unsigned int i = 0; i < nMouseButtons_s; i++)
-            mouseButtons_[i].clear();
-
-        for (unsigned int i = 0; i < nJoyStickButtons_s; i++)
-            joyStickButtons_[i].clear();
-
-        for (unsigned int i = 0; i < nHalfAxes_s; i++)
-            halfAxes_[i].clear();
+        for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
+            it->second->clear();
 
         for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
@@ -327,8 +311,11 @@
     void KeyBinder::resetJoyStickAxes()
     {
-        for (unsigned int i = 8; i < nHalfAxes_s; i++)
-        {
-            halfAxes_[i].absVal_ = 0.0f;
-            halfAxes_[i].relVal_ = 0.0f;
+        for (unsigned int iDev = 0; iDev < numberOfJoySticks_; ++iDev)
+        {
+            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
+            {
+                joyStickAxes_[iDev][i].absVal_ = 0.0f;
+                joyStickAxes_[iDev][i].relVal_ = 0.0f;
+            }
         }
     }
@@ -336,5 +323,5 @@
     void KeyBinder::tickMouse(float dt)
     {
-        tickDevices(0, 8);
+        tickDevices(mouseAxes_, mouseAxes_ + MouseAxisCode::numberOfAxes * 2);
 
         if (bDeriveMouseInput_)
@@ -342,31 +329,28 @@
             if (deriveTime_ > derivePeriod_)
             {
-                //CCOUT(3) << "mouse abs: ";
                 for (int i = 0; i < 2; i++)
                 {
                     if (mouseRelative_[i] > 0)
                     {
-                        halfAxes_[2*i + 0].absVal_
+                        mouseAxes_[2*i + 0].absVal_
                             =  mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
-                        halfAxes_[2*i + 1].absVal_ = 0.0f;
+                        mouseAxes_[2*i + 1].absVal_ = 0.0f;
                     }
                     else if (mouseRelative_[i] < 0)
                     {
-                        halfAxes_[2*i + 0].absVal_ = 0.0f;
-                        halfAxes_[2*i + 1].absVal_
+                        mouseAxes_[2*i + 0].absVal_ = 0.0f;
+                        mouseAxes_[2*i + 1].absVal_
                             = -mouseRelative_[i] / deriveTime_ * 0.0005 * mouseSensitivityDerived_;
                     }
                     else
                     {
-                        halfAxes_[2*i + 0].absVal_ = 0.0f;
-                        halfAxes_[2*i + 1].absVal_ = 0.0f;
+                        mouseAxes_[2*i + 0].absVal_ = 0.0f;
+                        mouseAxes_[2*i + 1].absVal_ = 0.0f;
                     }
-                    //COUT(3) << mouseRelative_[i] << " | ";
                     mouseRelative_[i] = 0;
-                    halfAxes_[2*i + 0].hasChanged_ = true;
-                    halfAxes_[2*i + 1].hasChanged_ = true;
+                    mouseAxes_[2*i + 0].hasChanged_ = true;
+                    mouseAxes_[2*i + 1].hasChanged_ = true;
                 }
                 deriveTime_ = 0.0f;
-                //COUT(3) << std::endl;
             }
             else
@@ -375,86 +359,40 @@
     }
 
-    void KeyBinder::tickJoyStick(float dt, unsigned int joyStick)
-    {
-        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
-        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++)
+    void KeyBinder::tickDevices(HalfAxis* begin, HalfAxis* end)
+    {
+        for (HalfAxis* current = begin; current < end; ++current) // pointer arithmetic
         {
             // 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_)
+            if (current->hasChanged_)
+            {
+                if (!current->wasDown_ && current->absVal_ > current->buttonThreshold_)
                 {
-                    halfAxes_[i].wasDown_ = true;
-                    if (halfAxes_[i].nCommands_[KeybindMode::OnPress])
-                        halfAxes_[i].execute(KeybindMode::OnPress);
+                    current->wasDown_ = true;
+                    if (current->nCommands_[KeybindMode::OnPress])
+                        current->execute(KeybindMode::OnPress);
                 }
-                else if (halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ < halfAxes_[i].buttonThreshold_)
+                else if (current->wasDown_ && current->absVal_ < current->buttonThreshold_)
                 {
-                    halfAxes_[i].wasDown_ = false;
-                    if (halfAxes_[i].nCommands_[KeybindMode::OnRelease])
-                        halfAxes_[i].execute(KeybindMode::OnRelease);
+                    current->wasDown_ = false;
+                    if (current->nCommands_[KeybindMode::OnRelease])
+                        current->execute(KeybindMode::OnRelease);
                 }
-                halfAxes_[i].hasChanged_ = false;
-            }
-
-            if (halfAxes_[i].wasDown_)
-            {
-                if (halfAxes_[i].nCommands_[KeybindMode::OnHold])
-                    halfAxes_[i].execute(KeybindMode::OnHold);
+                current->hasChanged_ = false;
+            }
+
+            if (current->wasDown_)
+            {
+                if (current->nCommands_[KeybindMode::OnHold])
+                    current->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();
-            }
-        }
-    }
-
-    void KeyBinder::keyPressed (const KeyEvent& evt)
-    { keys_[evt.key].execute(KeybindMode::OnPress); }
-
-    void KeyBinder::keyReleased(const KeyEvent& evt)
-    { keys_[evt.key].execute(KeybindMode::OnRelease); }
-
-    void KeyBinder::keyHeld    (const KeyEvent& evt)
-    { keys_[evt.key].execute(KeybindMode::OnHold); }
-
-
-    void KeyBinder::mouseButtonPressed (MouseButton::Enum id)
-    { mouseButtons_[id].execute(KeybindMode::OnPress); }
-
-    void KeyBinder::mouseButtonReleased(MouseButton::Enum id)
-    { mouseButtons_[id].execute(KeybindMode::OnRelease); }
-
-    void KeyBinder::mouseButtonHeld    (MouseButton::Enum id)
-    { mouseButtons_[id].execute(KeybindMode::OnHold); }
-
-
-    void KeyBinder::joyStickButtonPressed (unsigned int joyStickID, JoyStickButton::Enum id)
-    { joyStickButtons_[id].execute(KeybindMode::OnPress); }
-
-    void KeyBinder::joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id)
-    { joyStickButtons_[id].execute(KeybindMode::OnRelease); }
-
-    void KeyBinder::joyStickButtonHeld    (unsigned int joyStickID, JoyStickButton::Enum id)
-    { joyStickButtons_[id].execute(KeybindMode::OnHold); }
+            if (current->relVal_ > analogThreshold_ || current->absVal_ > analogThreshold_)
+            {
+                current->execute();
+            }
+        }
+    }
 
     /**
@@ -473,28 +411,26 @@
             for (int i = 0; i < 2; i++)
             {
-                if (rel[i])
+                if (rel[i]) // performance opt. if rel[i] == 0
                 {
-                    // absolute
-                    halfAxes_[2*i + 0].hasChanged_ = true;
-                    halfAxes_[2*i + 1].hasChanged_ = true;
+                    // write absolute values
+                    mouseAxes_[2*i + 0].hasChanged_ = true;
+                    mouseAxes_[2*i + 1].hasChanged_ = true;
                     mousePosition_[i] += rel[i];
 
-                    if (bClipMouse_)
-                    {
-                        if (mousePosition_[i] > 1024)
-                            mousePosition_[i] =  1024;
-                        if (mousePosition_[i] < -1024)
-                            mousePosition_[i] = -1024;
-                    }
+                    // clip absolute position
+                    if (mousePosition_[i] > mouseClippingSize_)
+                        mousePosition_[i] =  mouseClippingSize_;
+                    if (mousePosition_[i] < -mouseClippingSize_)
+                        mousePosition_[i] = -mouseClippingSize_;
 
                     if (mousePosition_[i] >= 0)
                     {
-                        halfAxes_[2*i + 0].absVal_ =   mousePosition_[i]/1024.0f * mouseSensitivity_;
-                        halfAxes_[2*i + 1].absVal_ =  0.0f;
+                        mouseAxes_[2*i + 0].absVal_ =   mousePosition_[i]/(float)mouseClippingSize_ * mouseSensitivity_;
+                        mouseAxes_[2*i + 1].absVal_ =  0.0f;
                     }
                     else
                     {
-                        halfAxes_[2*i + 0].absVal_ =  0.0f;
-                        halfAxes_[2*i + 1].absVal_ =  -mousePosition_[i]/1024.0f * mouseSensitivity_;
+                        mouseAxes_[2*i + 0].absVal_ =  0.0f;
+                        mouseAxes_[2*i + 1].absVal_ =  -mousePosition_[i]/(float)mouseClippingSize_ * mouseSensitivity_;
                     }
                 }
@@ -511,7 +447,7 @@
         {
             if (rel[i] > 0)
-                halfAxes_[0 + 2*i].relVal_ =  ((float)rel[i])/1024 * mouseSensitivity_;
-            else
-                halfAxes_[1 + 2*i].relVal_ = -((float)rel[i])/1024 * mouseSensitivity_;
+                mouseAxes_[0 + 2*i].relVal_ =  ((float)rel[i])/(float)mouseClippingSize_ * mouseSensitivity_;
+            else
+                mouseAxes_[1 + 2*i].relVal_ = -((float)rel[i])/(float)mouseClippingSize_ * mouseSensitivity_;
         }
     }
@@ -523,45 +459,37 @@
     void KeyBinder::mouseScrolled(int abs, int rel)
     {
-        //COUT(3) << mouseButtons_[8].name_ << "   " << abs << " | " << rel << std::endl;
-
         if (rel > 0)
-            for (int i = 0; i < rel/120; i++)
-                mouseButtons_[8].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
+            for (int i = 0; i < rel/mouseWheelStepSize_; i++)
+                mouseButtons_[8].execute(KeybindMode::OnPress, ((float)abs)/mouseWheelStepSize_);
         else
-            for (int i = 0; i < -rel/120; i++)
-                mouseButtons_[9].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
+            for (int i = 0; i < -rel/mouseWheelStepSize_; i++)
+                mouseButtons_[9].execute(KeybindMode::OnPress, ((float)abs)/mouseWheelStepSize_);
     }
 
     void KeyBinder::joyStickAxisMoved(unsigned int joyStickID, unsigned int axis, float value)
     {
-        int i = 8 + axis * 2;
+        int i = axis * 2;
         if (value >= 0)
         {
-            //if (value > 10000)
-            //{ CCOUT(3) << halfAxes_[i].name_ << std::endl; }
-
-            halfAxes_[i].absVal_ = value;
-            halfAxes_[i].relVal_ = value;
-            halfAxes_[i].hasChanged_ = true;
-            if (halfAxes_[i + 1].absVal_ > 0.0f)
-            {
-                halfAxes_[i + 1].absVal_ = -0.0f;
-                halfAxes_[i + 1].relVal_ = -0.0f;
-                halfAxes_[i + 1].hasChanged_ = true;
+            joyStickAxes_[joyStickID][i].absVal_ = value;
+            joyStickAxes_[joyStickID][i].relVal_ = value;
+            joyStickAxes_[joyStickID][i].hasChanged_ = true;
+            if (joyStickAxes_[joyStickID][i + 1].absVal_ > 0.0f)
+            {
+                joyStickAxes_[joyStickID][i + 1].absVal_ = -0.0f;
+                joyStickAxes_[joyStickID][i + 1].relVal_ = -0.0f;
+                joyStickAxes_[joyStickID][i + 1].hasChanged_ = true;
             }
         }
         else
         {
-            //if (value < -10000)
-            //{ CCOUT(3) << halfAxes_[i + 1].name_ << std::endl; }
-
-            halfAxes_[i + 1].absVal_ = -value;
-            halfAxes_[i + 1].relVal_ = -value;
-            halfAxes_[i + 1].hasChanged_ = true;
-            if (halfAxes_[i].absVal_ > 0.0f)
-            {
-                halfAxes_[i].absVal_ = -0.0f;
-                halfAxes_[i].relVal_ = -0.0f;
-                halfAxes_[i].hasChanged_ = true;
+            joyStickAxes_[joyStickID][i + 1].absVal_ = -value;
+            joyStickAxes_[joyStickID][i + 1].relVal_ = -value;
+            joyStickAxes_[joyStickID][i + 1].hasChanged_ = true;
+            if (joyStickAxes_[joyStickID][i].absVal_ > 0.0f)
+            {
+                joyStickAxes_[joyStickID][i].absVal_ = -0.0f;
+                joyStickAxes_[joyStickID][i].relVal_ = -0.0f;
+                joyStickAxes_[joyStickID][i].hasChanged_ = true;
             }
         }
Index: code/trunk/src/core/input/KeyBinder.h
===================================================================
--- code/trunk/src/core/input/KeyBinder.h	(revision 1881)
+++ code/trunk/src/core/input/KeyBinder.h	(revision 1887)
@@ -39,9 +39,9 @@
 
 #include <vector>
-
-#include "core/OrxonoxClass.h"
 #include "InputInterfaces.h"
 #include "Button.h"
 #include "HalfAxis.h"
+#include "InputCommands.h"
+#include "JoyStickDeviceNumberListener.h"
 
 namespace orxonox
@@ -52,5 +52,6 @@
         Manages the key bindings.
     */
-    class _CoreExport KeyBinder : public KeyHandler, public MouseHandler, public JoyStickHandler, public OrxonoxClass
+    class _CoreExport KeyBinder : public KeyHandler, public MouseHandler, public JoyStickHandler,
+                                  public JoyStickDeviceNumberListener
     {
     public:
@@ -58,6 +59,7 @@
         virtual ~KeyBinder();
 
-        void loadBindings();
+        void loadBindings(const std::string& filename);
         void clearBindings();
+        bool setBinding(const std::string& binding, const std::string& name, bool bTemporary = false);
         void setConfigValues();
         void resetJoyStickAxes();
@@ -65,11 +67,15 @@
     protected: // functions
         void tickInput(float dt);
-        //void tickInput(float dt, int device);
         void tickKey(float dt) { }
         void tickMouse(float dt);
         void tickJoyStick(float dt, unsigned int joyStick);
-        void tickDevices(unsigned int begin, unsigned int end);
-
-        virtual void readTrigger(Button& button);
+        // internal
+        void tickDevices(HalfAxis* begin, HalfAxis* end);
+
+        void buttonThresholdChanged();
+        // from JoyStickDeviceNumberListener interface
+        virtual void JoyStickDeviceNumberChanged(unsigned int value);
+        void initialiseJoyStickBindings();
+        void compilePointerLists();
 
         void keyPressed (const KeyEvent& evt);
@@ -77,44 +83,49 @@
         void keyHeld    (const KeyEvent& evt);
 
-        void mouseButtonPressed (MouseButton::Enum id);
-        void mouseButtonReleased(MouseButton::Enum id);
-        void mouseButtonHeld    (MouseButton::Enum id);
+        void mouseButtonPressed (MouseButtonCode::ByEnum id);
+        void mouseButtonReleased(MouseButtonCode::ByEnum id);
+        void mouseButtonHeld    (MouseButtonCode::ByEnum id);
         void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
         void mouseScrolled      (int abs, int rel);
 
-        void joyStickButtonPressed (unsigned int joyStickID, JoyStickButton::Enum id);
-        void joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id);
-        void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButton::Enum id);
+        void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
+        void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
+        void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
         void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value);
 
     protected: // variables
-        //! denotes the number of different keys there are in OIS.
-        static const unsigned int nKeys_s = 0xEE;
-        //! Actual key bindings as bundle for Press, Hold and Release
-        Button keys_ [nKeys_s];
-
-        //! denotes the number of different mouse buttons there are in OIS.
-        static const unsigned int nMouseButtons_s = 8 + 2*2; // 8 buttons and 2 scroll wheels
-        //! Actual key bindings as bundle for Press, Hold and Release
-        Button mouseButtons_ [nMouseButtons_s];
-
-        //! denotes the number of different joy stick buttons there are in OIS.
-        static const unsigned int nJoyStickButtons_s = 32 + 4 * 4; // 32 buttons and 4 POVs with 4 buttons
-        //! Actual key bindings as bundle for Press, Hold and Release
-        Button joyStickButtons_ [nJoyStickButtons_s];
-
-        //! denotes the number of half axes (every axis twice) there can be.
-        static const unsigned int nHalfAxes_s = 56;
-        /**
-        * Array with all the half axes for mouse and joy sticks.
-        * Keep in mind that the positions are fixed and that the first entry is the
-        * positive one and the second is negative.
-        * Sequence is as follows:
-        *  0 -  3: Mouse x and y
-        *  4 -  7: empty
-        *  8 - 23: joy stick slider axes 1 to 8
-        * 24 - 55: joy stick axes 1 - 16
-        */
-        HalfAxis halfAxes_[nHalfAxes_s];
+        //! Currently active joy sticks
+        unsigned int numberOfJoySticks_;
+
+        //! Actual key bindings for keys on the keyboard
+        Button keys_            [KeyCode::numberOfKeys];
+        //! Number of mouse buttons in KeyBinder (+4)
+        static const int numberOfMouseButtons_ = MouseButtonCode::numberOfButtons + 4;
+        //! Actual key bindings for mouse buttons including the wheel(s)
+        Button mouseButtons_    [numberOfMouseButtons_];
+        //! Actual key bindings for mouse axes
+        HalfAxis mouseAxes_     [MouseAxisCode::numberOfAxes * 2];
+
+        //! Helper class to use something like std:vector<Button[64]>
+        struct JoyStickButtonVector
+        {
+            Button& operator[](unsigned int index) { return buttons[index]; }
+            Button buttons[JoyStickButtonCode::numberOfButtons];
+        };
+        //! Actual key bindings for joy stick buttons
+        std::vector<JoyStickButtonVector> joyStickButtons_;
+        //! Helper class to use something like std:vector<HalfAxis[48]>
+        struct JoyStickAxisVector
+        {
+            HalfAxis& operator[](unsigned int index) { return halfAxes[index]; }
+            HalfAxis halfAxes[JoyStickAxisCode::numberOfAxes * 2];
+        };
+        //! Actual key bindings for joy stick axes (and sliders)
+        std::vector<JoyStickAxisVector> joyStickAxes_;
+
+        //! Pointer map with all Buttons, including half axes
+        std::map<std::string, Button*> allButtons_;
+        //! Pointer list with all half axes
+        std::vector<HalfAxis*> allHalfAxes_;
 
         /**
@@ -131,7 +142,11 @@
         float deriveTime_;
 
-
+        //! Config file used. "" in case of KeyDetector. Also indicates whether we've already loaded.
+        std::string configFile_;
+
+    private:
         //##### ConfigValues #####
-
+        //! Filename of default keybindings.
+        std::string defaultKeybindings_;
         //! Threshold for analog triggers until which the state is 0.
         float analogThreshold_;
@@ -146,7 +161,56 @@
         //! mouse sensitivity if mouse input is derived
         float mouseSensitivityDerived_;
-        //! Whether or not to clip abslute mouse values to 1024
-        bool bClipMouse_;
+        //! Equals one step of the mousewheel
+        float mouseWheelStepSize_;
+
+        //##### Constant config variables #####
+        // Use some value at about 1000. This can be configured with mouseSensitivity_ anyway.
+        static const int mouseClippingSize_ = 1024;
     };
+
+    inline void KeyBinder::keyPressed (const KeyEvent& evt)
+    { keys_[evt.key].execute(KeybindMode::OnPress); }
+
+    inline void KeyBinder::keyReleased(const KeyEvent& evt)
+    { keys_[evt.key].execute(KeybindMode::OnRelease); }
+
+    inline void KeyBinder::keyHeld    (const KeyEvent& evt)
+    { keys_[evt.key].execute(KeybindMode::OnHold); }
+
+
+    inline void KeyBinder::mouseButtonPressed (MouseButtonCode::ByEnum id)
+    { mouseButtons_[id].execute(KeybindMode::OnPress); }
+
+    inline void KeyBinder::mouseButtonReleased(MouseButtonCode::ByEnum id)
+    { mouseButtons_[id].execute(KeybindMode::OnRelease); }
+
+    inline void KeyBinder::mouseButtonHeld    (MouseButtonCode::ByEnum id)
+    { mouseButtons_[id].execute(KeybindMode::OnHold); }
+
+
+    inline void KeyBinder::joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
+    { joyStickButtons_[joyStickID][id].execute(KeybindMode::OnPress); }
+
+    inline void KeyBinder::joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
+    { joyStickButtons_[joyStickID][id].execute(KeybindMode::OnRelease); }
+
+    inline void KeyBinder::joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
+    { joyStickButtons_[joyStickID][id].execute(KeybindMode::OnHold); }
+
+    inline void KeyBinder::tickJoyStick(float dt, unsigned int joyStick)
+    {
+        tickDevices(&joyStickAxes_[joyStick][0], &joyStickAxes_[joyStick][JoyStickAxisCode::numberOfAxes * 2]);
+    }
+
+    inline 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
+        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
+            mouseAxes_[i].relVal_ = 0.0f;
+    }
 }
 
Index: code/trunk/src/core/input/KeyDetector.cc
===================================================================
--- code/trunk/src/core/input/KeyDetector.cc	(revision 1881)
+++ code/trunk/src/core/input/KeyDetector.cc	(revision 1887)
@@ -62,22 +62,21 @@
     /**
     @brief
-        Loads the key and button bindings.
-    @return
-        True if loading succeeded.
+        Assigns all the buttons 'command' plus the button's name.
     */
-    void KeyDetector::loadBindings(const std::string& command)
+    void KeyDetector::setCallbackCommand(const std::string& command)
     {
-        this->command_ = command;
+        callbackCommand_ = command;
         clearBindings();
-        setConfigValues();
+        for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
+        {
+            it->second->bindingString_ = callbackCommand_ + it->second->name_;
+            it->second->parse();
+        }
     }
 
-    void KeyDetector::readTrigger(Button& button)
+    void KeyDetector::JoyStickDeviceNumberChanged(unsigned int value)
     {
-        SimpleCommand* cmd = new SimpleCommand();
-        cmd->evaluation_ = CommandExecutor::evaluate(this->command_ + " " + button.name_);
-        button.commands_[KeybindMode::OnPress] = new BaseCommand*[1];
-        button.commands_[KeybindMode::OnPress][0] = cmd;
-        button.nCommands_[KeybindMode::OnPress] = 1;
+        KeyBinder::JoyStickDeviceNumberChanged(value);
+        setCallbackCommand(callbackCommand_);
     }
 }
Index: code/trunk/src/core/input/KeyDetector.h
===================================================================
--- code/trunk/src/core/input/KeyDetector.h	(revision 1881)
+++ code/trunk/src/core/input/KeyDetector.h	(revision 1887)
@@ -47,11 +47,9 @@
         KeyDetector();
         ~KeyDetector();
-        void loadBindings(const std::string& command);
-
-    protected:
-        void readTrigger(Button& button);
+        void setCallbackCommand(const std::string& command);
+        void JoyStickDeviceNumberChanged(unsigned int value);
 
     private:
-        std::string command_;
+        std::string callbackCommand_;
     };
 }
Index: code/trunk/src/core/input/SimpleInputState.cc
===================================================================
--- code/trunk/src/core/input/SimpleInputState.cc	(revision 1881)
+++ code/trunk/src/core/input/SimpleInputState.cc	(revision 1887)
@@ -35,12 +35,6 @@
 #include "SimpleInputState.h"
 
-#include <assert.h>
-#include "util/Debug.h"
-#include "core/Executor.h"
-
 namespace orxonox
 {
-    using namespace InputDevice;
-
     SimpleInputState::SimpleInputState()
         : keyHandler_(0)
@@ -70,76 +64,4 @@
         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, JoyStickButton::Enum id)
-    {
-        assert(joyStickID < joyStickHandler_.size());
-        if (joyStickHandler_[joyStickID])
-            joyStickHandler_[joyStickID]->joyStickButtonPressed(joyStickID, id);
-    }
-
-    void SimpleInputState::joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id)
-    {
-        assert(joyStickID < joyStickHandler_.size());
-        if (joyStickHandler_[joyStickID])
-            joyStickHandler_[joyStickID]->joyStickButtonReleased(joyStickID, id);
-    }
-
-    void SimpleInputState::joyStickButtonHeld(unsigned int joyStickID, JoyStickButton::Enum id)
-    {
-        assert(joyStickID < joyStickHandler_.size());
-        if (joyStickHandler_[joyStickID])
-            joyStickHandler_[joyStickID]->joyStickButtonHeld(joyStickID, id);
     }
 
@@ -199,33 +121,4 @@
     }
 
-    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()
     {
@@ -247,6 +140,6 @@
 
         // update the deviceEnabled options
-        setInputDeviceEnabled(Keyboard, (keyHandler_ != 0));
-        setInputDeviceEnabled(Mouse, (mouseHandler_ != 0));
+        setInputDeviceEnabled(InputDevice::Keyboard, (keyHandler_ != 0));
+        setInputDeviceEnabled(InputDevice::Mouse, (mouseHandler_ != 0));
         for (unsigned int i = 0; i < joyStickHandler_.size(); ++i)
             setInputDeviceEnabled(2 + i, (joyStickHandler_[i] != 0));
Index: code/trunk/src/core/input/SimpleInputState.h
===================================================================
--- code/trunk/src/core/input/SimpleInputState.h	(revision 1881)
+++ code/trunk/src/core/input/SimpleInputState.h	(revision 1887)
@@ -38,4 +38,5 @@
 
 #include <vector>
+#include <cassert>
 #include "InputInterfaces.h"
 #include "InputState.h"
@@ -65,13 +66,13 @@
         void keyHeld    (const KeyEvent& evt);
 
-        void mouseButtonPressed (MouseButton::Enum id);
-        void mouseButtonReleased(MouseButton::Enum id);
-        void mouseButtonHeld    (MouseButton::Enum id);
+        void mouseButtonPressed (MouseButtonCode::ByEnum id);
+        void mouseButtonReleased(MouseButtonCode::ByEnum id);
+        void mouseButtonHeld    (MouseButtonCode::ByEnum id);
         void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
         void mouseScrolled      (int abs, int rel);
 
-        void joyStickButtonPressed (unsigned int joyStickID, JoyStickButton::Enum id);
-        void joyStickButtonReleased(unsigned int joyStickID, JoyStickButton::Enum id);
-        void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButton::Enum id);
+        void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
+        void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
+        void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
         void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value);
 
@@ -83,6 +84,105 @@
         std::vector<JoyStickHandler*> joyStickHandler_;
         JoyStickHandler*              joyStickHandlerAll_;
-        std::vector<InputHandler*>   allHandlers_;
+        std::vector<InputHandler*>    allHandlers_;
     };
+
+    inline void SimpleInputState::tickInput(float dt)
+    {
+        for (unsigned int i = 0; i < allHandlers_.size(); ++i)
+        {
+            allHandlers_[i]->tickInput(dt);
+        }
+    }
+
+    inline void SimpleInputState::tickInput(float dt, unsigned int device)
+    {
+        switch (device)
+        {
+        case InputDevice::Keyboard:
+            if (keyHandler_)
+                keyHandler_->tickKey(dt);
+            break;
+
+        case InputDevice::Mouse:
+            if (mouseHandler_)
+                mouseHandler_->tickMouse(dt);
+            break;
+
+        default: // joy sticks
+            if (joyStickHandler_[device - 2])
+                joyStickHandler_[device - 2]->tickJoyStick(dt, device - 2);
+            break;
+        }
+    }
+
+    inline void SimpleInputState::keyReleased(const KeyEvent& evt)
+    {
+        if (keyHandler_)
+            keyHandler_->keyReleased(evt);
+    }
+
+    inline void SimpleInputState::keyHeld(const KeyEvent& evt)
+    {
+        if (keyHandler_)
+            keyHandler_->keyHeld(evt);
+    }
+
+    inline void SimpleInputState::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
+    {
+        if (mouseHandler_)
+            mouseHandler_->mouseMoved(abs, rel, clippingSize);
+    }
+
+    inline void SimpleInputState::mouseScrolled(int abs, int rel)
+    {
+        if (mouseHandler_)
+            mouseHandler_->mouseScrolled(abs, rel);
+    }
+
+    inline void SimpleInputState::mouseButtonPressed(MouseButtonCode::ByEnum id)
+    {
+        if (mouseHandler_)
+            mouseHandler_->mouseButtonPressed(id);
+    }
+
+    inline void SimpleInputState::mouseButtonReleased(MouseButtonCode::ByEnum id)
+    {
+        if (mouseHandler_)
+            mouseHandler_->mouseButtonReleased(id);
+    }
+
+    inline void SimpleInputState::mouseButtonHeld(MouseButtonCode::ByEnum id)
+    {
+        if (mouseHandler_)
+            mouseHandler_->mouseButtonHeld(id);
+    }
+
+    inline void SimpleInputState::joyStickAxisMoved(unsigned int joyStickID, unsigned int axis, float value)
+    {
+        assert(joyStickID < joyStickHandler_.size());
+        if (joyStickHandler_[joyStickID])
+            joyStickHandler_[joyStickID]->joyStickAxisMoved(joyStickID, axis, value);
+    }
+
+    inline void SimpleInputState::joyStickButtonPressed(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
+    {
+        assert(joyStickID < joyStickHandler_.size());
+        if (joyStickHandler_[joyStickID])
+            joyStickHandler_[joyStickID]->joyStickButtonPressed(joyStickID, id);
+    }
+
+    inline void SimpleInputState::joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
+    {
+        assert(joyStickID < joyStickHandler_.size());
+        if (joyStickHandler_[joyStickID])
+            joyStickHandler_[joyStickID]->joyStickButtonReleased(joyStickID, id);
+    }
+
+    inline void SimpleInputState::joyStickButtonHeld(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
+    {
+        assert(joyStickID < joyStickHandler_.size());
+        if (joyStickHandler_[joyStickID])
+            joyStickHandler_[joyStickID]->joyStickButtonHeld(joyStickID, id);
+    }
 }
 
Index: code/trunk/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSGraphics.cc	(revision 1881)
+++ code/trunk/src/orxonox/gamestates/GSGraphics.cc	(revision 1887)
@@ -114,4 +114,5 @@
         // Configure master input state with a KeyBinder
         //masterKeyBinder_ = new KeyBinder();
+        //masterKeyBinder_->loadBindings("master_keybindings.ini");
         //inputManager_->getMasterInputState()->addKeyHandler(masterKeyBinder_);
 
Index: code/trunk/src/orxonox/gamestates/GSLevel.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSLevel.cc	(revision 1881)
+++ code/trunk/src/orxonox/gamestates/GSLevel.cc	(revision 1887)
@@ -36,4 +36,8 @@
 #include "core/input/KeyBinder.h"
 #include "core/Loader.h"
+#include "core/CommandExecutor.h"
+#include "core/ConsoleCommand.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/CoreIncludes.h"
 #include "objects/Backlight.h"
 #include "objects/Tickable.h"
@@ -55,8 +59,15 @@
         , hud_(0)
     {
+        RegisterObject(GSLevel);
+        setConfigValues();
     }
 
     GSLevel::~GSLevel()
     {
+    }
+
+    void GSLevel::setConfigValues()
+    {
+        SetConfigValue(keyDetectorCallbackCode_, "KeybindBindingStringKeyName=");
     }
 
@@ -65,5 +76,5 @@
         inputState_ = InputManager::getInstance().createInputState<SimpleInputState>("game", 20);
         keyBinder_ = new KeyBinder();
-        keyBinder_->loadBindings();
+        keyBinder_->loadBindings("keybindings.ini");
         inputState_->setHandler(keyBinder_);
 
@@ -88,4 +99,14 @@
         // TODO: insert slomo console command with
         // .accessLevel(AccessLevel::Offline).defaultValue(0, 1.0).axisParamIndex(0).isAxisRelative(false);
+
+        // keybind console command
+        FunctorMember<GSLevel>* functor1 = createFunctor(&GSLevel::keybind);
+        functor1->setObject(this);
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor1, "keybind"));
+        FunctorMember<GSLevel>* functor2 = createFunctor(&GSLevel::tkeybind);
+        functor2->setObject(this);
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor2, "tkeybind"));
+        // set our console command as callback for the key detector
+        InputManager::getInstance().setKeyDetectorCallback(std::string("keybind ") + keyDetectorCallbackCode_);
     }
 
@@ -145,3 +166,55 @@
         delete this->startLevel_;
     }
+
+    void GSLevel::keybind(const std::string &command)
+    {
+        this->keybindInternal(command, false);
+    }
+
+    void GSLevel::tkeybind(const std::string &command)
+    {
+        this->keybindInternal(command, true);
+    }
+
+    /**
+    @brief
+        Assigns a command string to a key/button/axis. The name is determined via KeyDetector.
+    @param command
+        Command string that can be executed by the CommandExecutor
+        OR: Internal string "KeybindBindingStringKeyName=" used for the second call to identify
+        the key/button/axis that has been activated. This is configured above in enter().
+    */
+    void GSLevel::keybindInternal(const std::string& command, bool bTemporary)
+    {
+        static std::string bindingString = "";
+        static bool bTemporarySaved = false;
+        static bool bound = true;
+        // note: We use a long name to make 'sure' that the user doesn't use it accidentally.
+        // Howerver there will be no real issue if it happens anyway.
+        if (command.find(keyDetectorCallbackCode_) != 0)
+        {
+            if (bound)
+            {
+                COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl;
+                InputManager::getInstance().requestEnterState("detector");
+                bindingString = command;
+                bTemporarySaved = bTemporary;
+                bound = false;
+            }
+            //else:  We're still in a keybind command. ignore this call.
+        }
+        else
+        {
+            if (!bound)
+            {
+                // user has pressed the key
+                std::string name = command.substr(this->keyDetectorCallbackCode_.size());
+                COUT(0) << "Binding string \"" << bindingString << "\" on key '" << name << "'" << std::endl;
+                this->keyBinder_->setBinding(bindingString, name, bTemporarySaved);
+                InputManager::getInstance().requestLeaveState("detector");
+                bound = true;
+            }
+            // else: A key was pressed within the same tick, ignore it.
+        }
+    }
 }
Index: code/trunk/src/orxonox/gamestates/GSLevel.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSLevel.h	(revision 1881)
+++ code/trunk/src/orxonox/gamestates/GSLevel.h	(revision 1887)
@@ -37,6 +37,7 @@
 namespace orxonox
 {
-    class _OrxonoxExport GSLevel : public GameState<GSGraphics>
+    class _OrxonoxExport GSLevel : public GameState<GSGraphics>, public OrxonoxClass
     {
+        friend class ClassIdentifier<GSLevel>;
     public:
         GSLevel(const std::string& name);
@@ -58,4 +59,9 @@
         float timeFactor_;       //!< A factor to change the gamespeed
 
+        // console commands
+        void keybind(const std::string& command);
+        void tkeybind(const std::string& command);
+        void keybindInternal(const std::string& command, bool bTemporary);
+
         Ogre::SceneManager*   sceneManager_;
         KeyBinder*            keyBinder_;        //!< tool that loads and manages the input bindings
@@ -64,4 +70,11 @@
         Level*                startLevel_;       //!< current hard coded default level
         Level*                hud_;              //!< 'level' object fo the HUD
+
+        // config values
+        std::string           keyDetectorCallbackCode_;
+        
+    private:
+        void setConfigValues();
+
     };
 }
Index: code/trunk/src/orxonox/gui/GUIManager.cc
===================================================================
--- code/trunk/src/orxonox/gui/GUIManager.cc	(revision 1881)
+++ code/trunk/src/orxonox/gui/GUIManager.cc	(revision 1887)
@@ -279,5 +279,5 @@
     }
 
-    void GUIManager::mouseButtonPressed(MouseButton::Enum id)
+    void GUIManager::mouseButtonPressed(MouseButtonCode::ByEnum id)
     {
         try
@@ -292,5 +292,5 @@
     }
 
-    void GUIManager::mouseButtonReleased(MouseButton::Enum id)
+    void GUIManager::mouseButtonReleased(MouseButtonCode::ByEnum id)
     {
         try
@@ -306,21 +306,21 @@
 
 
-    inline CEGUI::MouseButton GUIManager::convertButton(MouseButton::Enum button)
+    inline CEGUI::MouseButton GUIManager::convertButton(MouseButtonCode::ByEnum button)
     {
         switch (button)
         {
-        case MouseButton::Left:
+        case MouseButtonCode::Left:
             return CEGUI::LeftButton;
 
-        case MouseButton::Right:
+        case MouseButtonCode::Right:
             return CEGUI::RightButton;
 
-        case MouseButton::Middle:
+        case MouseButtonCode::Middle:
             return CEGUI::MiddleButton;
 
-        case MouseButton::Button3:
+        case MouseButtonCode::Button3:
             return CEGUI::X1Button;
 
-        case MouseButton::Button4:
+        case MouseButtonCode::Button4:
             return CEGUI::X2Button;
 
Index: code/trunk/src/orxonox/gui/GUIManager.h
===================================================================
--- code/trunk/src/orxonox/gui/GUIManager.h	(revision 1881)
+++ code/trunk/src/orxonox/gui/GUIManager.h	(revision 1887)
@@ -93,7 +93,7 @@
         { }
 
-        void mouseButtonPressed (MouseButton::Enum id);
-        void mouseButtonReleased(MouseButton::Enum id);
-        void mouseButtonHeld    (MouseButton::Enum id)
+        void mouseButtonPressed (MouseButtonCode::ByEnum id);
+        void mouseButtonReleased(MouseButtonCode::ByEnum id);
+        void mouseButtonHeld    (MouseButtonCode::ByEnum id)
         { }
         void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
@@ -123,5 +123,5 @@
         State state_;
 
-        static CEGUI::MouseButton convertButton(MouseButton::Enum button);
+        static CEGUI::MouseButton convertButton(MouseButtonCode::ByEnum button);
 
         static GUIManager*        singletonRef_s;
Index: code/trunk/visual_studio/vc8/core.vcproj
===================================================================
--- code/trunk/visual_studio/vc8/core.vcproj	(revision 1881)
+++ code/trunk/visual_studio/vc8/core.vcproj	(revision 1887)
@@ -330,4 +330,8 @@
 				</File>
 				<File
+					RelativePath="..\..\src\core\input\JoyStickDeviceNumberListener.cc"
+					>
+				</File>
+				<File
 					RelativePath="..\..\src\core\input\KeyBinder.cc"
 					>
@@ -460,4 +464,8 @@
 				</File>
 				<File
+					RelativePath="..\..\src\core\input\JoyStickDeviceNumberListener.h"
+					>
+				</File>
+				<File
 					RelativePath="..\..\src\core\input\KeyBinder.h"
 					>
