Index: code/trunk/src/core/CommandExecutor.cc
===================================================================
--- code/trunk/src/core/CommandExecutor.cc	(revision 1293)
+++ code/trunk/src/core/CommandExecutor.cc	(revision 1349)
@@ -31,4 +31,5 @@
 #include "util/String.h"
 #include "util/Convert.h"
+#include "util/SubString.h"
 #include "Identifier.h"
 #include "Language.h"
@@ -173,5 +174,5 @@
     }
 
-    KeybindMode CommandEvaluation::getKeybindMode()
+    KeybindMode::Enum CommandEvaluation::getKeybindMode()
     {
         if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished)
@@ -198,5 +199,5 @@
         }
         // FIXME: Had to insert a return statement
-        return (KeybindMode)0;
+        return (KeybindMode::Enum)0;
     }
 
Index: code/trunk/src/core/CommandExecutor.h
===================================================================
--- code/trunk/src/core/CommandExecutor.h	(revision 1293)
+++ code/trunk/src/core/CommandExecutor.h	(revision 1349)
@@ -70,6 +70,4 @@
     std::string read(const std::string& filename);
 
-    enum KeybindMode {}; // temporary
-
     ///////////////////////
     // CommandEvaluation //
@@ -82,5 +80,5 @@
             CommandEvaluation();
 
-            KeybindMode getKeybindMode();
+            KeybindMode::Enum getKeybindMode();
             bool isValid() const;
 
@@ -89,5 +87,6 @@
             inline std::string getAdditionalParameter() const
                 { return (this->additionalParameter_ != "") ? (" " + this->additionalParameter_) : ""; }
-            inline std::string getCommandString() const { return this->processedCommand_; }
+            inline ExecutorStatic* getEvaluatedExecutor() { return evaluatedExecutor_; }
+            inline std::string getCommandString() { return this->processedCommand_; }
 
             void setEvaluatedParameter(unsigned int index, MultiTypeMath param);
Index: code/trunk/src/core/CorePrereqs.h
===================================================================
--- code/trunk/src/core/CorePrereqs.h	(revision 1293)
+++ code/trunk/src/core/CorePrereqs.h	(revision 1349)
@@ -78,4 +78,15 @@
 #endif
 
+  namespace KeybindMode
+  {
+    enum Enum
+    {
+      OnPress,
+      OnHold,
+      OnRelease,
+      None
+    };
+  };
+
   typedef std::string LanguageEntryLabel;
 
Index: code/trunk/src/core/Executor.cc
===================================================================
--- code/trunk/src/core/Executor.cc	(revision 1293)
+++ code/trunk/src/core/Executor.cc	(revision 1349)
@@ -39,4 +39,7 @@
         this->name_ = name;
         this->accessLevel_ = level;
+        this->keybindMode_ = KeybindMode::OnPress;
+        this->axisParamIndex_ = -1;
+        this->bAxisRelative_ = false;
 
         this->bAddedDescription_ = false;
Index: code/trunk/src/core/Executor.h
===================================================================
--- code/trunk/src/core/Executor.h	(revision 1293)
+++ code/trunk/src/core/Executor.h	(revision 1349)
@@ -204,4 +204,19 @@
                 { return this->accessLevel_; }
 
+            inline Executor& setKeybindMode(KeybindMode::Enum mode)
+                { this->keybindMode_ = mode; return *this; }
+            inline KeybindMode::Enum getKeybindMode() const
+                { return this->keybindMode_; }
+
+            inline Executor& setAxisParamIndex(int index)
+                { this->axisParamIndex_ = index; return *this; }
+            inline int getAxisParamIndex() const
+                { return this->axisParamIndex_; }
+
+            inline Executor& setIsAxisRelative(bool val)
+                { this->bAxisRelative_ = val; return *this; }
+            inline int getIsAxisRelative() const
+                { return this->bAxisRelative_; }
+
             Executor& setDefaultValues(const MultiTypeMath& param1);
             Executor& setDefaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2);
@@ -233,4 +248,8 @@
             MultiTypeMath defaultValue_[MAX_FUNCTOR_ARGUMENTS];
             bool bAddedDefaultValue_[MAX_FUNCTOR_ARGUMENTS];
+
+            KeybindMode::Enum keybindMode_;
+            int axisParamIndex_;
+            bool bAxisRelative_;
 
         private:
Index: code/trunk/src/core/InputBuffer.cc
===================================================================
--- code/trunk/src/core/InputBuffer.cc	(revision 1293)
+++ code/trunk/src/core/InputBuffer.cc	(revision 1349)
@@ -173,4 +173,8 @@
   }
 
+  /**
+  * This tick() function is called by the InputManager if the InputBuffer is active.
+  * @param dt Delta time
+  */
   void InputBuffer::tick(float dt)
   {
@@ -187,5 +191,5 @@
   }
 
-  bool InputBuffer::keyPressed(const KeyEvent &evt)
+  void InputBuffer::keyPressed(const KeyEvent &evt)
   {
     lastKey_ = evt.key;
@@ -195,8 +199,7 @@
 
     processKey(evt);
-    return true;
-  }
-
-  bool InputBuffer::keyHeld(const KeyEvent& evt)
+  }
+
+  void InputBuffer::keyHeld(const KeyEvent& evt)
   {
     if (evt.key == lastKey_)
@@ -208,5 +211,4 @@
       }
     }
-    return true;
   }
 
Index: code/trunk/src/core/InputBuffer.h
===================================================================
--- code/trunk/src/core/InputBuffer.h	(revision 1293)
+++ code/trunk/src/core/InputBuffer.h	(revision 1349)
@@ -43,5 +43,5 @@
   {};
 
-  class _CoreExport InputBuffer : public KeyHandler, public TickableReal
+  class _CoreExport InputBuffer : public KeyHandler, public OrxonoxClass
   {
     struct InputBufferListenerTuple
@@ -101,7 +101,7 @@
     bool charIsAllowed(const char& input);
 
-    bool keyPressed (const KeyEvent& evt);
-    bool keyReleased(const KeyEvent& evt) { return true; }
-    bool keyHeld    (const KeyEvent& evt);
+    void keyPressed (const KeyEvent& evt);
+    void keyReleased(const KeyEvent& evt) { }
+    void keyHeld    (const KeyEvent& evt);
     void processKey (const KeyEvent &e);
 
Index: code/trunk/src/core/InputHandler.cc
===================================================================
--- code/trunk/src/core/InputHandler.cc	(revision 1293)
+++ code/trunk/src/core/InputHandler.cc	(revision 1349)
@@ -34,12 +34,269 @@
 #include "InputHandler.h"
 #include "util/Convert.h"
+#include "util/SubString.h"
+#include "util/String.h"
 #include "Debug.h"
 #include "ConfigValueIncludes.h"
 #include "CoreIncludes.h"
 #include "CommandExecutor.h"
+#include "Executor.h"
 
 namespace orxonox
 {
   // ###############################
+  // ######      Button       ######
+  // ###############################
+
+  bool BufferedParamCommand::execute()
+  {
+    if (nValuesAdded_)
+    {
+      BufferedParamCommand& cmd = *this;
+      cmd.evaluation_.setEvaluatedParameter(cmd.paramIndex_, cmd.value_);
+      // reset
+      cmd.nValuesAdded_ = 0;
+      cmd.value_ = 0;
+      return CommandExecutor::execute(cmd.evaluation_);
+    }
+    else
+      return true;
+  }
+
+  bool SimpleCommand::execute(float abs, float rel)
+  {
+    return CommandExecutor::execute(evaluation_);
+  }
+
+  bool ParamCommand::execute(float abs, float rel)
+  {
+    BufferedParamCommand& paramCommand = *paramCommand_;
+    // command has an additional parameter
+    if (bRelative_ && (rel > 0 || rel < 0))
+    {
+      // we have to calculate a relative movement.
+      // paramModifier_ says how much one keystroke is
+      paramCommand.value_ += paramModifier_ * rel;
+    }
+    else if (abs > 0 || abs < 0)
+    {
+      // we have to calculate absolute position of the axis.
+      // Since there might be another axis that is affected, we have to wait and
+      // store the result in a temporary place
+      paramCommand.value_ = (paramCommand.value_ * paramCommand.nValuesAdded_ + paramModifier_ * abs)
+                            /++paramCommand.nValuesAdded_;
+    }
+    return true;
+  }
+
+  void Button::clear()
+  {
+    for (unsigned int j = 0; j < 3; j++)
+    {
+      if (nCommands_[j])
+      {
+        // delete all commands and the command pointer array
+        for (unsigned int i = 0; i < nCommands_[j]; i++)
+          delete commands_[j][i];
+        delete[] commands_[j];
+        commands_[j] = 0;
+        nCommands_[j] = 0;
+      }
+      else
+      {
+        commands_[j] = 0;
+      }
+    }
+  }
+
+  void Button::parse(std::vector<BufferedParamCommand*>& paramCommandBuffer)
+  {
+    if (isEmpty(bindingString_))
+    {
+      clear();
+      return;
+    }
+
+    // use std::vector for a temporary dynamic array
+    std::vector<BaseCommand*> commands[3];
+
+
+    // separate the commands
+    SubString commandStrings(bindingString_, "|", SubString::WhiteSpaces, false,
+        '\\', false, '"', false, '(', ')', false, '\0');
+
+    for (unsigned int iCommand = 0; iCommand < commandStrings.size(); iCommand++)
+    {
+      if (commandStrings[iCommand] != "")
+      {
+        SubString tokens(commandStrings[iCommand], " ", SubString::WhiteSpaces, false,
+            '\\', false, '"', false, '(', ')', false, '\0');
+        
+        unsigned int iToken = 0;
+
+        // for real axes, we can feed a ButtonThreshold argument as entire command
+        if (getLowercase(tokens[0]) == "buttonthreshold")
+        {
+          if (tokens.size() == 1)
+            continue;
+          // may fail, but doesn't matter
+          convertValue(&buttonThreshold_, tokens[1]);
+          continue;
+        }
+
+        // first argument can be OnPress, OnHold OnRelease or nothing
+        KeybindMode::Enum mode = KeybindMode::None;
+        if (getLowercase(tokens[iToken]) == "onpress")
+          mode = KeybindMode::OnPress,   iToken++;
+        if (getLowercase(tokens[iToken]) == "onrelease")
+          mode = KeybindMode::OnRelease, iToken++;
+        if (getLowercase(tokens[iToken]) == "onhold")
+          mode = KeybindMode::OnHold,    iToken++;
+
+        if (iToken == tokens.size())
+          continue;
+
+        // second argument can be the amplitude for the case it as an axis command
+        // default amplitude is 1.0f
+        float paramModifier = 1.0f;
+        if (getLowercase(tokens[iToken]) == "axisamp")
+        {
+          iToken++;
+          if (iToken == tokens.size() || !convertValue(&paramModifier, tokens[iToken]))
+          {
+            COUT(2) << "Error while parsing key binding " << name_
+                << ". Numeric expression expected afer 'AxisAmp', switching to default value" << std::endl;
+            if (iToken == tokens.size())
+              continue;
+          }
+          iToken++;
+        }
+
+        // no more arguments expected except for the actual command
+        if (iToken == tokens.size())
+          continue;
+
+        std::string commandStr;
+        while (iToken != tokens.size())
+          commandStr += tokens[iToken++] + " ";
+
+        // evaluate the command
+        CommandEvaluation eval = CommandExecutor::evaluate(commandStr);
+        if (!eval.isValid())
+          continue;
+
+        // check for param command
+        int paramIndex = eval.getEvaluatedExecutor()->getAxisParamIndex();
+        // TODO: check in Executor for correct paramIndex
+        if (paramIndex >= 0)
+        {
+          // parameter supported command
+          ParamCommand* cmd = new ParamCommand();
+          cmd->paramModifier_ = paramModifier;
+          cmd->bRelative_ = eval.getEvaluatedExecutor()->getIsAxisRelative();
+
+          // add command to the buffer if not yet existing
+          for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer.size(); iParamCmd++)
+          {
+            if (getLowercase(paramCommandBuffer[iParamCmd]->evaluation_.getCommandString())
+                == getLowercase(commandStr))
+            {
+              // already in list
+              cmd->paramCommand_ = paramCommandBuffer[iParamCmd];
+              break;
+            }
+          }
+          if (cmd->paramCommand_ == 0)
+          {
+            cmd->paramCommand_ = new BufferedParamCommand();
+            paramCommandBuffer.push_back(cmd->paramCommand_);
+            cmd->paramCommand_->evaluation_ = eval;
+            cmd->paramCommand_->paramIndex_ = paramIndex;
+          }
+
+
+          // we don't know whether this is an actual axis or just a button
+          if (mode == KeybindMode::None)
+          {
+            if (!addParamCommand(cmd))
+            {
+              mode = eval.getEvaluatedExecutor()->getKeybindMode();
+              commands[mode].push_back(cmd);
+            }
+          }
+        }
+        else
+        {
+          SimpleCommand* cmd = new SimpleCommand();
+          cmd->evaluation_ = eval;
+
+          //TODO: check CommandEvaluation for correct KeybindMode
+          if (mode == KeybindMode::None)
+            mode = eval.getEvaluatedExecutor()->getKeybindMode();
+
+          commands[mode].push_back(cmd);
+        }
+      }
+    }
+
+    for (unsigned int j = 0; j < 3; j++)
+    {
+      nCommands_[j] = commands[j].size();
+      if (nCommands_[j])
+      {
+        commands_[j] = new BaseCommand*[nCommands_[j]];
+        for (unsigned int i = 0; i < commands[j].size(); i++)
+          commands_[j][i] = commands[j][i];
+      }
+      else
+        commands_[j] = 0;
+    }
+  }
+
+  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;
+  }
+
+  void HalfAxis::clear()
+  {
+    Button::clear();
+    if (nParamCommands_)
+    {
+      // delete all commands and the command pointer array
+      for (unsigned int i = 0; i < nParamCommands_; i++)
+        delete paramCommands_[i];
+      delete[] paramCommands_;
+    }
+    else
+    {
+      nParamCommands_ = 0; nParamCommands_ = 0;
+    }
+  }
+  
+  bool HalfAxis::addParamCommand(ParamCommand* command)
+  {
+    ParamCommand** cmds = paramCommands_;
+    paramCommands_ = new ParamCommand*[++nParamCommands_];
+    unsigned int i;
+    for (i = 0; i < nParamCommands_ - 1; i++)
+      paramCommands_[i] = cmds[i];
+    paramCommands_[i] = command;
+    delete[] cmds;
+    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;
+  }
+
+
+  // ###############################
   // ######     KeyBinder     ######
   // ###############################
@@ -48,193 +305,144 @@
     @brief Constructor that does as little as necessary.
   */
-  KeyBinder::KeyBinder()
+  KeyBinder::KeyBinder() : deriveTime_(0.0f)
   {
     RegisterObject(KeyBinder);
-    clearBindings();
-
+
+    // 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"
+      "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 (int i = 0; i < numberOfKeys_s; i++)
-      keyNames_[i] = keyNames[i];
-
+    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" };
-    for (int i = 0; i < numberOfMouseButtons_s; i++)
-      mouseButtonNames_[i] = mouseButtonNames[i];
-
-    for (int i = 0; i < numberOfJoyStickButtons_s; i++)
-      joyStickButtonNames_[i] = "JoyStick" + getConvertedValue<int, std::string>(i);
+      "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" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "North";
+		  joyStickButtons_[i + 1].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "South";
+		  joyStickButtons_[i + 2].name_ = "JoyPOV" + getConvertedValue<int, std::string>((i - 32)/4 + 1) + "East";
+		  joyStickButtons_[i + 3].name_ = "JoyPOV" + getConvertedValue<int, std::string>((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" + getConvertedValue<int, std::string>(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_;
   }
 
@@ -244,4 +452,21 @@
   KeyBinder::~KeyBinder()
   {
+    // almost no destructors required because most of the arrays are static.
+    clearBindings(); // does some destruction work
+  }
+
+  /**
+    @brief Loads the key and button bindings.
+    @return True if loading succeeded.
+  */
+  void KeyBinder::loadBindings()
+  {
+    COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
+
+    ConfigFileManager::getSingleton()->setFile(CFT_Keybindings, "keybindings.ini");
+    clearBindings();
+    setConfigValues();
+
+    COUT(3) << "KeyBinder: Loading key bindings done." << std::endl;
   }
 
@@ -251,80 +476,47 @@
   void KeyBinder::setConfigValues()
   {
-    ConfigValueContainer* cont;
-    std::string modes[] = {"P_", "R_", "H_"};
+    SetConfigValue(analogThreshold_, 0.01f)  .description("Threshold for analog axes until which the state is 0.");
+    SetConfigValue(bDeriveMouseInput_, false).description("Whether or not to derive moues movement for the absolute value.");
+    SetConfigValue(derivePeriod_, 0.1f)      .description("Accuracy of the mouse input deriver. The higher the more precise, but laggier.");
+    SetConfigValue(mouseSensitivity_, 1.0f)  .description("Mouse sensitivity.");
+
+    float oldThresh = buttonThreshold_;
+    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 (int i = 0; i < numberOfKeys_s; i++)
-    {
-      for (int j = 0; j < 3; j++)
-      {
-        cont = getIdentifier()->getConfigValueContainer(modes[j] + keyNames_[i]);
-        if (!cont)
-        {
-          cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), modes[j] + keyNames_[i], "");
-          getIdentifier()->addConfigValueContainer(modes[j] + keyNames_[i], cont);
-        }
-        switch (j)
-        {
-          case 0:
-            cont->getValue(&bindingsKeyPress_[i].commandStr);
-            break;
-          case 1:
-            cont->getValue(&bindingsKeyRelease_[i].commandStr);
-            break;
-          case 2:
-            cont->getValue(&bindingsKeyHold_[i].commandStr);
-        }
-      }
-    }
-
+    for (unsigned int i = 0; i < nKeys_s; i++)
+      readTrigger(keys_[i]);
     // mouse buttons
-    for (int i = 0; i < numberOfMouseButtons_s; i++)
-    {
-      for (int j = 0; j < 3; j++)
-      {
-        cont = getIdentifier()->getConfigValueContainer(modes[j] + mouseButtonNames_[i]);
-        if (!cont)
-        {
-          cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), modes[j] + mouseButtonNames_[i], "");
-          getIdentifier()->addConfigValueContainer(modes[j] + mouseButtonNames_[i], cont);
-        }
-        switch (j)
-        {
-          case 0:
-            cont->getValue(&bindingsMouseButtonPress_[i].commandStr);
-            break;
-          case 1:
-            cont->getValue(&bindingsMouseButtonRelease_[i].commandStr);
-            break;
-          case 2:
-            cont->getValue(&bindingsMouseButtonHold_[i].commandStr);
-        }
-      }
-    }
-
+    for (unsigned int i = 0; i < nMouseButtons_s; i++)
+      readTrigger(mouseButtons_[i]);
     // joy stick buttons
-    for (int i = 0; i < numberOfJoyStickButtons_s; i++)
-    {
-      for (int j = 0; j < 3; j++)
-      {
-        cont = getIdentifier()->getConfigValueContainer(modes[j] + joyStickButtonNames_[i]);
-        if (!cont)
-        {
-          cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), modes[j] + joyStickButtonNames_[i], "");
-          getIdentifier()->addConfigValueContainer(modes[j] + joyStickButtonNames_[i], cont);
-        }
-        switch (j)
-        {
-          case 0:
-            cont->getValue(&bindingsJoyStickButtonPress_[i].commandStr);
-            break;
-          case 1:
-            cont->getValue(&bindingsJoyStickButtonRelease_[i].commandStr);
-            break;
-          case 2:
-            cont->getValue(&bindingsJoyStickButtonHold_[i].commandStr);
-        }
-      }
+    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 = getIdentifier()->getConfigValueContainer(button.name_);
+    if (!cont)
+    {
+      cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), button.name_, "");
+      getIdentifier()->addConfigValueContainer(button.name_, cont);
+    }
+    std::string old = button.bindingString_;
+    cont->getValue(&button.bindingString_);
+
+    // keybinder stuff
+    if (old != button.bindingString_)
+    {
+      // binding has changed
+      button.parse(paramCommandBuffer_);
     }
   }
@@ -333,105 +525,121 @@
     @brief Overwrites all bindings with ""
   */
-  void KeyBinder::clearBindings()
-  {
-    for (int i = 0; i < numberOfKeys_s; i++)
-    {
-      bindingsKeyPress_  [i].commandStr = "";
-      bindingsKeyRelease_[i].commandStr = "";
-      bindingsKeyHold_   [i].commandStr = "";
-    }
-    for (int i = 0; i < numberOfMouseButtons_s; i++)
-    {
-      bindingsMouseButtonPress_  [i].commandStr = "";
-      bindingsMouseButtonRelease_[i].commandStr = "";
-      bindingsMouseButtonHold_   [i].commandStr = "";
-    }
-    for (int i = 0; i < numberOfJoyStickButtons_s; i++)
-    {
-      bindingsJoyStickButtonPress_  [i].commandStr = "";
-      bindingsJoyStickButtonRelease_[i].commandStr = "";
-      bindingsJoyStickButtonHold_   [i].commandStr = "";
-    }
-  }
-
-  /**
-    @brief Loads the key and button bindings.
-    @return True if loading succeeded.
-  */
-  bool KeyBinder::loadBindings()
-  {
-    COUT(ORX_DEBUG) << "KeyBinder: Loading key bindings..." << std::endl;
-
-    ConfigFileManager::getSingleton()->setFile(CFT_Keybindings, "keybindings.ini");
-    setConfigValues();
-
-    // evaluate the key bindings
-    // TODO: what if binding is invalid?
-    for (int i = 0; i < numberOfKeys_s; i++)
-    {
-      if (bindingsKeyPress_[i].commandStr != "")
+  void KeyBinder::clearBindings(bool bInit)
+  {
+    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 (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
+      delete paramCommandBuffer_[i];
+    paramCommandBuffer_.clear();
+  }
+
+  void KeyBinder::tick(float dt)
+  {
+    // we have to process all the analog input since there is e.g. no 'mouseDoesntMove' event.
+    for (unsigned int i = 0; i < nHalfAxes_s; i++)
+    {
+      if (halfAxes_[i].hasChanged_)
       {
-        bindingsKeyPress_[i].evaluation = CommandExecutor::evaluate(bindingsKeyPress_[i].commandStr);
-        bindingsKeyPress_[i].commandStr = bindingsKeyPress_[i].evaluation.getCommandString();
+        if (!halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ > halfAxes_[i].buttonThreshold_)
+        {
+          halfAxes_[i].wasDown_ = true;
+          if (halfAxes_[i].nCommands_[KeybindMode::OnPress])
+            halfAxes_[i].execute(KeybindMode::OnPress);
+        }
+        else if (halfAxes_[i].wasDown_ && halfAxes_[i].absVal_ < halfAxes_[i].buttonThreshold_)
+        {
+          halfAxes_[i].wasDown_ = false;
+          if (halfAxes_[i].nCommands_[KeybindMode::OnRelease])
+            halfAxes_[i].execute(KeybindMode::OnRelease);
+        }
+        if (halfAxes_[i].wasDown_)
+        {
+          if (halfAxes_[i].nCommands_[KeybindMode::OnHold])
+            halfAxes_[i].execute(KeybindMode::OnHold);
+        }
+        halfAxes_[i].hasChanged_ = false;
       }
-    }
-
-    COUT(ORX_DEBUG) << "KeyBinder: Loading key bindings done." << std::endl;
-    return true;
-  }
-
-  bool KeyBinder::executeSimpleBinding(KeyBinding& binding)
-  {
-    if (binding.commandStr != "")
-    {
-      if (binding.commandStr != binding.evaluation.getCommandString())
+
+      // these are the actually useful axis bindings for analog input AND output
+      if (halfAxes_[i].relVal_ > analogThreshold_ || halfAxes_[i].absVal_ > analogThreshold_)
       {
-        // key binding has changed, reevaluate the command string.
-        binding.evaluation = CommandExecutor::evaluate(binding.commandStr);
-        binding.commandStr = binding.evaluation.getCommandString();
+        halfAxes_[i].execute();
       }
-      COUT(ORX_DEBUG) << "Keybinding: Executing command: " << binding.commandStr << std::endl;
-      CommandExecutor::execute(binding.commandStr);
-    }
-
-    return true;
-  }
-
-
-  /**
-    @brief Event handler for the keyPressed Event.
-    @param e Event information
-  */
-  bool KeyBinder::keyPressed(const KeyEvent& evt)
-  {
-    // find the appropriate key binding
-    executeSimpleBinding(bindingsKeyPress_[int(evt.key)]);
-
-    return true;
-  }
-
-  /**
-    @brief Event handler for the keyReleased Event.
-    @param e Event information
-  */
-  bool KeyBinder::keyReleased(const KeyEvent& evt)
-  {
-    // find the appropriate key binding
-    executeSimpleBinding(bindingsKeyRelease_[int(evt.key)]);
-
-    return true;
-  }
-
-  /**
-    @brief Event handler for the keyHeld Event.
-    @param e Mouse state information
-  */
-  bool KeyBinder::keyHeld(const KeyEvent& evt)
-  {
-    // find the appropriate key binding
-    executeSimpleBinding(bindingsKeyHold_[int(evt.key)]);
-
-    return true;
-  }
+    }
+
+    if (bDeriveMouseInput_)
+    {
+      if (deriveTime_ > derivePeriod_)
+      {
+        deriveTime_ = 0.0f;
+        //CCOUT(3) << "mouse abs: ";
+        for (int i = 0; i < 2; i++)
+        {
+          if (mouseRelative_[i] > 0)
+          {
+            halfAxes_[2*i + 0].absVal_ = mouseRelative_[i] * derivePeriod_ / 500 * mouseSensitivity_;
+            halfAxes_[2*i + 1].absVal_ = 0.0f;
+          }
+          else if (mouseRelative_[0] < 0)
+          {
+            halfAxes_[2*i + 0].absVal_ = 0.0f;
+            halfAxes_[2*i + 1].absVal_ = -mouseRelative_[i] * derivePeriod_ / 500 * mouseSensitivity_;
+          }
+          //COUT(3) << mouseRelative_[i] << " | ";
+          mouseRelative_[i] = 0;
+        }
+        //COUT(3) << std::endl;
+      }
+      else
+        deriveTime_ += dt;
+    }
+
+    // execute all buffered bindings (addional 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::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 (int joyStickID, int button)
+  { joyStickButtons_[button].execute(KeybindMode::OnPress); }
+
+  void KeyBinder::joyStickButtonReleased(int joyStickID, int button)
+  { joyStickButtons_[button].execute(KeybindMode::OnRelease); }
+
+  void KeyBinder::joyStickButtonHeld    (int joyStickID, int button)
+  { joyStickButtons_[button].execute(KeybindMode::OnHold); }
 
   /**
@@ -439,21 +647,58 @@
     @param e Mouse state information
   */
-  bool KeyBinder::mouseMoved(const MouseState &evt)
-  {
-    /*if (bindingMouseMoved_.commandStr != "")
-    {
-      if (bindingMouseMoved_.commandStr != bindingMouseMoved_.evaluation.getCommandString())
+  void KeyBinder::mouseMoved(IntVector2 abs_, IntVector2 rel_, IntVector2 clippingSize)
+  {
+    if (!bDeriveMouseInput_)
+    {
+      // y axis of mouse input is inverted
+      int rel[] = { rel_.x, -rel_.y };
+
+      //COUT(3) << rel[0] << " | " << rel[1] << std::endl;
+
+      for (int i = 0; i < 2; i++)
       {
-        // key binding has changed, reevaluate the command string.
-        bindingMouseMoved_.evaluation = CommandExecutor::evaluate(bindingMouseMoved_.commandStr);
-        bindingMouseMoved_.commandStr = bindingMouseMoved_.evaluation.getCommandString();
+        if (rel[i])
+        {
+          // absolute
+          if (mousePosition_[i] >= 0)
+          {
+            mousePosition_[i] += rel[i];
+            halfAxes_[0 + 2*i].hasChanged_ = true;
+            if (mousePosition_[i] < 0)
+            {
+              halfAxes_[1 + 2*i].hasChanged_ = true;
+              halfAxes_[1 + 2*i].absVal_ = -((float)mousePosition_[i])/1024 * mouseSensitivity_;
+              halfAxes_[0 + 2*i].absVal_ =  0.0f;
+            }
+            else
+              halfAxes_[1 + 2*i].absVal_ =  ((float)mousePosition_[i])/1024 * mouseSensitivity_;
+          }
+          else
+          {
+            mousePosition_[i] += rel[i];
+            halfAxes_[1 + 2*i].hasChanged_ = true;
+            if (mousePosition_[i] > 0)
+            {
+              halfAxes_[0 + 2*i].hasChanged_ = true;
+              halfAxes_[0 + 2*i].absVal_ =  ((float)mousePosition_[i])/1024 * mouseSensitivity_;
+              halfAxes_[1 + 2*i].absVal_ =  0.0f;
+            }
+            else
+              halfAxes_[1 + 2*i].absVal_ = -((float)mousePosition_[i])/1024 * mouseSensitivity_;
+          }
+
+          // relative
+          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_;
+        }
       }
-      COUT(3) << "Executing command: " << bindingMouseMoved_.commandStr << std::endl;
-
-      bindingMouseMoved_.evaluation.setEvaluatedParameter(
-      CommandExecutor::execute(bindingMouseMoved_.commandStr);
-    }*/
-
-    return true;
+    }
+    else
+    {
+      mouseRelative_[0] += rel_.x;
+      mouseRelative_[1] -= rel_.y;
+    }
   }
 
@@ -462,92 +707,33 @@
     @param e Mouse state information
   */
-  bool KeyBinder::mouseScrolled(const MouseState &evt)
-  {
-    return true;
-  }
-
-  /**
-    @brief Event handler for the mousePressed Event.
-    @param e Event information
-    @param id The ID of the mouse button
-  */
-  bool KeyBinder::mouseButtonPressed(const MouseState& state, MouseButton::Enum id)
-  {
-    // find the appropriate key binding
-    executeSimpleBinding(bindingsMouseButtonPress_[int(id)]);
-
-    return true;
-  }
-
-  /**
-    @brief Event handler for the mouseReleased Event.
-    @param e Event information
-    @param id The ID of the mouse button
-  */
-  bool KeyBinder::mouseButtonReleased(const MouseState& state, MouseButton::Enum id)
-  {
-    // find the appropriate key binding
-    executeSimpleBinding(bindingsMouseButtonRelease_[int(id)]);
-
-    return true;
-  }
-
-  /**
-    @brief Event handler for the mouseHeld Event.
-    @param e Event information
-    @param id The ID of the mouse button
-  */
-  bool KeyBinder::mouseButtonHeld(const MouseState& state, MouseButton::Enum id)
-  {
-    // find the appropriate key binding
-    executeSimpleBinding(bindingsMouseButtonHold_[int(id)]);
-
-    return true;
-  }
-
-  bool KeyBinder::joyStickButtonPressed(const JoyStickState& state, int button)
-  {
-    // find the appropriate key binding
-    executeSimpleBinding(bindingsJoyStickButtonPress_[button]);
-
-    return true;
-  }
-
-  bool KeyBinder::joyStickButtonReleased(const JoyStickState& state, int button)
-  {
-    // find the appropriate key binding
-    executeSimpleBinding(bindingsJoyStickButtonRelease_[button]);
-
-    return true;
-  }
-
-  bool KeyBinder::joyStickButtonHeld(const JoyStickState& state, int button)
-  {
-    // find the appropriate key binding
-    executeSimpleBinding(bindingsJoyStickButtonHold_[button]);
-
-    return true;
-  }
-
-  bool KeyBinder::joyStickAxisMoved(const JoyStickState& state, int axis)
-  {
-    return true;
-  }
-
-  bool KeyBinder::joyStickSliderMoved(const JoyStickState& state, int index)
-  {
-    return true;
-  }
-
-  bool KeyBinder::joyStickPovMoved(const JoyStickState& state, int index)
-  {
-    return true;
-  }
-
-  bool KeyBinder::joyStickVector3Moved(const JoyStickState& state, int index)
-  {
-    return true;
-  }
-
+  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);
+    else
+      for (int i = 0; i < -rel/120; i++)
+        mouseButtons_[9].execute(KeybindMode::OnPress, ((float)abs)/120.0f);
+  }
+
+  void KeyBinder::joyStickAxisMoved(int joyStickID, int axis, int value)
+  {
+    // TODO: check whether 16 bit integer as general axis value is a good idea (works under windows)
+    CCOUT(3) << halfAxes_[8 + axis].name_ << std::endl;
+    if (value >= 0)
+    {
+      halfAxes_[8 + axis].absVal_ = ((float)value)/0x8000;
+      halfAxes_[8 + axis].relVal_ = ((float)value)/0x8000;
+      halfAxes_[8 + axis].hasChanged_ = true;
+    }
+    else
+    {
+      halfAxes_[8 + axis + 1].absVal_ = -((float)value)/0x8000;
+      halfAxes_[8 + axis + 1].relVal_ = -((float)value)/0x8000;
+      halfAxes_[8 + axis + 1].hasChanged_ = true;
+    }
+  }
 
 
Index: code/trunk/src/core/InputHandler.h
===================================================================
--- code/trunk/src/core/InputHandler.h	(revision 1293)
+++ code/trunk/src/core/InputHandler.h	(revision 1349)
@@ -38,6 +38,8 @@
 
 #include <string>
+#include <vector>
 
 #include "ois/OIS.h"
+#include "util/Math.h"
 #include "OrxonoxClass.h"
 #include "CommandExecutor.h"
@@ -46,24 +48,91 @@
 namespace orxonox
 {
-  namespace KeybindSetting
-  {
-    enum KeybindSetting
-    {
-      None,
-      OnPress,
-      OnRelease,
-      Continuous,
-    };
-  }
-
-  struct _CoreExport KeyBinding
-  {
-    std::string commandStr;
-    CommandEvaluation evaluation;
-  };
- 
+  class _CoreExport BaseCommand
+  {
+  public:
+    virtual ~BaseCommand() { }
+    virtual bool execute(float abs = 1.0f, float rel = 1.0f) = 0;
+  };
+
+  class _CoreExport BufferedParamCommand
+  {
+  public:
+    BufferedParamCommand() : value_(0.0f), nValuesAdded_(0), paramIndex_(-1) { }
+    bool execute();
+
+    float value_;
+    unsigned int nValuesAdded_;
+    int paramIndex_;
+    CommandEvaluation evaluation_;
+  };
+
+  class _CoreExport SimpleCommand : public BaseCommand
+  {
+  public:
+    bool execute(float abs = 1.0f, float rel = 1.0f);
+
+    CommandEvaluation evaluation_;
+  };
+
+  class _CoreExport ParamCommand : public BaseCommand
+  {
+  public:
+    ParamCommand() : bRelative_(false), paramModifier_(1.0f), paramCommand_(0) { }
+    bool execute(float abs = 1.0f, float rel = 1.0f);
+
+    bool bRelative_;
+    float paramModifier_;
+    BufferedParamCommand* paramCommand_;
+  };
+
+  class _CoreExport Button
+  {
+  public:
+    Button() { nCommands_[0]=0; nCommands_[1]=0; nCommands_[2]=0; clear(); }
+    virtual ~Button() { clear(); }
+    virtual void clear();
+    virtual bool addParamCommand(ParamCommand* command) { return false; }
+    void parse(std::vector<BufferedParamCommand*>& paramCommandBuffer);
+    bool execute(KeybindMode::Enum mode, float abs = 1.0f, float rel = 1.0f);
+
+    //! The configured string value
+    std::string bindingString_;
+    //! Name of the trigger as strings
+    std::string name_;
+    //! Basic commands for OnPress, OnHold and OnRelease
+    BaseCommand** commands_[3];
+    //! Number of basic commands
+    unsigned int nCommands_[3];
+    //! Says how much it takes for an analog axis to trigger a button
+    //! Note: This variable is here to have only one parse() function.
+    float buttonThreshold_;
+  };
+
+
+  class _CoreExport HalfAxis : public Button
+  {
+  public:
+    HalfAxis() : relVal_(0.0f), absVal_(0.0f), paramCommands_(0), nParamCommands_(0),
+                 wasDown_(false), hasChanged_(false) { }
+    using Button::execute;
+    bool execute();
+    //bool execute(KeybindMode::Enum mode) { return Button::execute(mode); }
+    bool addParamCommand(ParamCommand* command);
+    void clear();
+
+    // axis related
+    float relVal_;
+    float absVal_;
+    ParamCommand** paramCommands_;
+    unsigned int nParamCommands_;
+
+    // button related
+    bool wasDown_;
+    bool hasChanged_;
+  };
+
 
   /**
-    @brief Captures mouse, keyboard and joy stick input while in the actual game mode.
+    @brief Handles mouse, keyboard and joy stick input while in the actual game mode.
            Manages the key bindings.
   */
@@ -74,70 +143,85 @@
     ~KeyBinder();
 
-    bool loadBindings();
-    void clearBindings();
+    void loadBindings();
+    void clearBindings(bool bInit = false);
 
     void setConfigValues();
 
   private: // functions
-
-    bool executeSimpleBinding(KeyBinding &binding);
-
-    bool keyPressed (const KeyEvent& evt);
-    bool keyReleased(const KeyEvent& evt);
-    bool keyHeld    (const KeyEvent& evt);
-
-    bool mouseButtonPressed (const MouseState& state, MouseButton::Enum id);
-    bool mouseButtonReleased(const MouseState& state, MouseButton::Enum id);
-    bool mouseButtonHeld    (const MouseState& state, MouseButton::Enum id);
-    bool mouseMoved         (const MouseState& state);
-    bool mouseScrolled      (const MouseState& state);
-
-    bool joyStickButtonPressed (const JoyStickState& state, int button);
-    bool joyStickButtonReleased(const JoyStickState& state, int button);
-    bool joyStickButtonHeld    (const JoyStickState& state, int button);
-    bool joyStickAxisMoved     (const JoyStickState& state, int axis)  ;
-    bool joyStickSliderMoved   (const JoyStickState& state, int index) ;
-    bool joyStickPovMoved      (const JoyStickState& state, int index) ;
-    bool joyStickVector3Moved  (const JoyStickState& state, int index) ;
+    void readTrigger(Button& button);
+
+    //static void clearBundle(KeyBindingBundle& bundle, bool bInit);
+    //static void redimensionBinding(KeyBinding& binding);
+
+    void tick(float dt);
+
+    void keyPressed (const KeyEvent& evt);
+    void keyReleased(const KeyEvent& evt);
+    void keyHeld    (const KeyEvent& evt);
+
+    void mouseButtonPressed (MouseButton::Enum id);
+    void mouseButtonReleased(MouseButton::Enum id);
+    void mouseButtonHeld    (MouseButton::Enum id);
+    void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
+    void mouseScrolled      (int abs, int rel);
+
+    void joyStickButtonPressed (int joyStickID, int button);
+    void joyStickButtonReleased(int joyStickID, int button);
+    void joyStickButtonHeld    (int joyStickID, int button);
+    void joyStickAxisMoved     (int joyStickID, int axis, int value);
 
   private: // variables
-
     //! denotes the number of different keys there are in OIS.
-    static const int numberOfKeys_s = 0xEE;
-    //! Array of input events for every pressed key
-    KeyBinding bindingsKeyPress_  [numberOfKeys_s];
-    //! Array of input events for every released key
-    KeyBinding bindingsKeyRelease_[numberOfKeys_s];
-    //! Array of input events for every held key
-    KeyBinding bindingsKeyHold_   [numberOfKeys_s];
-    //! Names of the keys as strings
-    std::string keyNames_[numberOfKeys_s];
+    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 int numberOfMouseButtons_s = 8;
-    //! Array of input events for every pressed mouse button
-    KeyBinding bindingsMouseButtonPress_  [numberOfMouseButtons_s];
-    //! Array of input events for every released mouse button
-    KeyBinding bindingsMouseButtonRelease_[numberOfMouseButtons_s];
-    //! Array of input events for every held mouse button
-    KeyBinding bindingsMouseButtonHold_   [numberOfMouseButtons_s];
-    //! Key binding for mouse moved event
-    KeyBinding bindingMouseMoved_;
-    //! Key binding for mouse scrolled event
-    KeyBinding bindingMouseScrolled_;
-    //! Names of the mouse buttons as strings
-    std::string mouseButtonNames_[numberOfMouseButtons_s];
+    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 int numberOfJoyStickButtons_s = 32;
-    //! Array of input events for every pressed joy stick button
-    KeyBinding bindingsJoyStickButtonPress_  [numberOfJoyStickButtons_s];
-    //! Array of input events for every released joy stick button
-    KeyBinding bindingsJoyStickButtonRelease_[numberOfJoyStickButtons_s];
-    //! Array of input events for every held joy stick button
-    KeyBinding bindingsJoyStickButtonHold_   [numberOfJoyStickButtons_s];
-    //! Names of the joy stick buttons as strings
-    std::string joyStickButtonNames_[numberOfJoyStickButtons_s];
-
+    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];
+
+    /**
+    * Commands that have additional parameters (axes) are executed at the end of
+    * the tick() so that all values can be buffered for single execution.
+    */
+    std::vector<BufferedParamCommand*> paramCommandBuffer_;
+
+    //! Keeps track of the absolute mouse value (incl. scroll wheel)
+    int mousePosition_[3];
+    //! Used to derive mouse input if requested
+    int mouseRelative_[2];
+    float deriveTime_;
+
+    //##### ConfigValues #####
+    //! Threshold for analog triggers until which the state is 0.
+    float analogThreshold_;
+    //! Threshold for analog triggers until which the button is not pressed.
+    float buttonThreshold_;
+    //! Derive mouse input for absolute values?
+    bool bDeriveMouseInput_;
+    //! Accuracy of the mouse input deriver. The higher the more precise, but laggier.
+    float derivePeriod_;
+    //! mouse sensitivity
+    float mouseSensitivity_;
   };
 
Index: code/trunk/src/core/InputInterfaces.h
===================================================================
--- code/trunk/src/core/InputInterfaces.h	(revision 1293)
+++ code/trunk/src/core/InputInterfaces.h	(revision 1349)
@@ -38,4 +38,5 @@
 
 #include "ois/OIS.h"
+#include "util/Math.h"
 
 namespace orxonox
@@ -239,7 +240,7 @@
   };
 
-  typedef OIS::MouseState MouseState;
-
-  class _CoreExport JoyStickState : OIS::JoyStickState
+  //typedef OIS::MouseState MouseState;
+
+  /*class _CoreExport JoyStickState
   {
   public:
@@ -247,4 +248,16 @@
     JoyStickState() { clear(); }
     int mJoyStickID;
+		JoyStickState() { clear(); }
+
+		std::vector<bool> mButtons;
+		int axes[16];
+		std::vector<Vector3> mVectors;
+  };*/
+
+  class _CoreExport InputTickable
+  {
+  public:
+    virtual ~InputTickable() { }
+    virtual void tick(float dt) = 0;
   };
 
@@ -252,11 +265,11 @@
     @brief Interface class used for key input listeners.
   */
-  class _CoreExport KeyHandler
+  class _CoreExport KeyHandler : virtual public InputTickable
   {
   public:
     virtual ~KeyHandler() { }
-    virtual bool keyPressed (const KeyEvent& evt) = 0;
-    virtual bool keyReleased(const KeyEvent& evt) = 0;
-    virtual bool keyHeld    (const KeyEvent& evt) = 0;
+    virtual void keyPressed (const KeyEvent& evt) = 0;
+    virtual void keyReleased(const KeyEvent& evt) = 0;
+    virtual void keyHeld    (const KeyEvent& evt) = 0;
   };
 
@@ -264,13 +277,13 @@
     @brief Interface class used for mouse input listeners.
   */
-  class _CoreExport MouseHandler 
+  class _CoreExport MouseHandler : virtual public InputTickable
   {
   public:
     virtual ~MouseHandler() { }
-    virtual bool mouseButtonPressed (const MouseState& state, MouseButton::Enum id) = 0;
-    virtual bool mouseButtonReleased(const MouseState& state, MouseButton::Enum id) = 0;
-    virtual bool mouseButtonHeld    (const MouseState& state, MouseButton::Enum id) = 0;
-    virtual bool mouseMoved         (const MouseState& state) = 0;
-    virtual bool mouseScrolled      (const MouseState& state) = 0;
+    virtual void mouseButtonPressed (MouseButton::Enum id) = 0;
+    virtual void mouseButtonReleased(MouseButton::Enum id) = 0;
+    virtual void mouseButtonHeld    (MouseButton::Enum id) = 0;
+    virtual void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0;
+    virtual void mouseScrolled      (int abs, int rel)     = 0;
   };
 
@@ -279,15 +292,13 @@
     @brief Interface class used for joy stick input listeners.
   */
-  class _CoreExport JoyStickHandler
+  class _CoreExport JoyStickHandler : virtual public InputTickable
   {
   public:
     virtual ~JoyStickHandler() { }
-    virtual bool joyStickButtonPressed (const JoyStickState& state, int button) = 0;
-    virtual bool joyStickButtonReleased(const JoyStickState& state, int button) = 0;
-    virtual bool joyStickButtonHeld    (const JoyStickState& state, int button) = 0;
-    virtual bool joyStickAxisMoved     (const JoyStickState& state, int axis)   = 0;
-    virtual bool joyStickSliderMoved   (const JoyStickState& state, int index) {return true;}
-    virtual bool joyStickPovMoved      (const JoyStickState& state, int index) {return true;}
-    virtual bool joyStickVector3Moved  (const JoyStickState& state, int index) {return true;}
+    virtual void joyStickButtonPressed (int joyStickID, int button) = 0;
+    virtual void joyStickButtonReleased(int joyStickID, int button) = 0;
+    virtual void joyStickButtonHeld    (int joyStickID, int button) = 0;
+    virtual void joyStickAxisMoved     (int joyStickID, int axis, int value) = 0;
+    //virtual bool joyStickVector3Moved  (int joyStickID, int index /*, fill list*/) {return true;}
   };
 
Index: code/trunk/src/core/InputManager.cc
===================================================================
--- code/trunk/src/core/InputManager.cc	(revision 1293)
+++ code/trunk/src/core/InputManager.cc	(revision 1349)
@@ -98,5 +98,6 @@
       windowHndStr << (unsigned int)windowHnd;
       paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
-
+      //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
+      //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
 //#if defined OIS_LINUX_PLATFORM
 //      paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
@@ -126,5 +127,11 @@
 
       // Set mouse/joystick region
-      setWindowExtents(windowWidth, windowHeight);
+      if (mouse_)
+      {
+        //// hack the mouse position
+        //((OIS::MouseState&)mouse_->getMouseState()).X.abs = windowWidth/2;
+        //((OIS::MouseState&)mouse_->getMouseState()).Y.abs = windowHeight/2;
+        setWindowExtents(windowWidth, windowHeight);
+      }
 
       state_ = IS_NONE;
@@ -267,4 +274,6 @@
     activeJoyStickHandlers_.resize(joySticksSize_);
     joyStickButtonsDown_.resize(joySticksSize_);
+    povStates_.resize(joySticksSize_);
+    sliderStates_.resize(joySticksSize_);
     return success;
   }
@@ -350,4 +359,22 @@
   }
 
+  void InputManager::_updateTickables()
+  {
+    // we can use a set to have a list of unique pointers (an object can implement all 3 handlers)
+    std::set<InputTickable*> tempSet;
+    for (unsigned int iHandler = 0; iHandler < activeKeyHandlers_.size(); iHandler++)
+      tempSet.insert(activeKeyHandlers_[iHandler]);
+    for (unsigned int iHandler = 0; iHandler < activeMouseHandlers_.size(); iHandler++)
+      tempSet.insert(activeMouseHandlers_[iHandler]);
+    for (unsigned int iJoyStick  = 0; iJoyStick < joySticksSize_; iJoyStick++)
+      for (unsigned int iHandler = 0; iHandler  < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
+        tempSet.insert(activeJoyStickHandlers_[iJoyStick][iHandler]);
+
+    // copy the content of the set back to the actual vector
+    activeHandlers_.clear();
+    for (std::set<InputTickable*>::const_iterator itHandler = tempSet.begin(); itHandler != tempSet.end(); itHandler++)
+      activeHandlers_.push_back(*itHandler);
+  }
+
 
   // #################################
@@ -380,24 +407,19 @@
           // normal play mode
           // note: we assume that the handlers exist since otherwise, something's wrong anyway.
-          activeKeyHandlers_.push_back(keyHandlers_["keybinder"]);
-          activeMouseHandlers_.push_back(mouseHandlers_["keybinder"]);
-          if (getMouseHandler("SpaceShip"))
-            activeMouseHandlers_.push_back(mouseHandlers_["SpaceShip"]);
-          for (unsigned int i = 0; i < joySticksSize_; i++)
-            activeJoyStickHandlers_[i].push_back(joyStickHandlers_["keybinder"]);
+          enableKeyHandler("keybinder");
+          enableMouseHandler("keybinder");
+          enableMouseHandler("SpaceShip");
+          enableJoyStickHandler("keybinder", 0);
           break;
 
         case IS_GUI:
-          // FIXME: do stuff
+          // TODO: do stuff
           break;
 
         case IS_CONSOLE:
-          activeMouseHandlers_.push_back(mouseHandlers_["keybinder"]);
-          if (getMouseHandler("SpaceShip"))
-            activeMouseHandlers_.push_back(mouseHandlers_["SpaceShip"]);
-          for (unsigned int i = 0; i < joySticksSize_; i++)
-            activeJoyStickHandlers_[i].push_back(joyStickHandlers_["keybinder"]);
-
-          activeKeyHandlers_.push_back(keyHandlers_["buffer"]);
+          enableMouseHandler("keybinder");
+          enableMouseHandler("SpaceShip");
+          enableJoyStickHandler("keybinder", 0);
+          enableKeyHandler("buffer");
           break;
 
@@ -426,5 +448,5 @@
     for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
       for (unsigned int iHandler = 0; iHandler < activeMouseHandlers_.size(); iHandler++)
-        activeMouseHandlers_[iHandler]->mouseButtonHeld(mouse_->getMouseState(), mouseButtonsDown_[iButton]);
+        activeMouseHandlers_[iHandler]->mouseButtonHeld(mouseButtonsDown_[iButton]);
 
     // call all the handlers for the held joy stick button events
@@ -432,6 +454,10 @@
       for (unsigned int iButton   = 0; iButton   < joyStickButtonsDown_[iJoyStick].size(); iButton++)
         for (unsigned int iHandler = 0; iHandler  < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
-          activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonHeld(
-              JoyStickState(joySticks_[iJoyStick]->getJoyStickState(), iJoyStick), joyStickButtonsDown_[iJoyStick][iButton]);
+          activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
+
+
+    // call the ticks
+    for (unsigned int iHandler = 0; iHandler < activeHandlers_.size(); iHandler++)
+      activeHandlers_[iHandler]->tick(dt);
   }
 
@@ -508,5 +534,6 @@
     {
       for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++)
-        activeMouseHandlers_[i]->mouseMoved(e.state);
+        activeMouseHandlers_[i]->mouseMoved(IntVector2(e.state.X.abs, e.state.Y.abs),
+            IntVector2(e.state.X.rel, e.state.Y.rel), IntVector2(e.state.width, e.state.height));
     }
 
@@ -515,5 +542,5 @@
     {
       for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++)
-        activeMouseHandlers_[i]->mouseScrolled(e.state);
+        activeMouseHandlers_[i]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
     }
 
@@ -536,5 +563,5 @@
 
     for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++)
-      activeMouseHandlers_[i]->mouseButtonPressed(e.state, (MouseButton::Enum)id);
+      activeMouseHandlers_[i]->mouseButtonPressed((MouseButton::Enum)id);
 
     return true;
@@ -559,5 +586,5 @@
 
     for (unsigned int i = 0; i < activeMouseHandlers_.size(); i++)
-      activeMouseHandlers_[i]->mouseButtonReleased(e.state, (MouseButton::Enum)id);
+      activeMouseHandlers_[i]->mouseButtonReleased((MouseButton::Enum)id);
 
     return true;
@@ -584,5 +611,5 @@
 
     for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
-      activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonPressed(JoyStickState(arg.state, iJoyStick), button);
+      activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonPressed(iJoyStick, button);
 
     return true;
@@ -609,5 +636,5 @@
 
     for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
-      activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonReleased(JoyStickState(arg.state, iJoyStick), button);
+      activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonReleased(iJoyStick, button);
 
     return true;
@@ -616,4 +643,5 @@
   bool InputManager::axisMoved(const OIS::JoyStickEvent &arg, int axis)
   {
+    //CCOUT(3) << arg.state.mAxes[axis].abs << std::endl;
     // use the device to identify which one called the method
     OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device;
@@ -622,6 +650,7 @@
       iJoyStick++;
 
+    // keep in mind that the first 8 axes are reserved for the sliders
     for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
-      activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickAxisMoved(JoyStickState(arg.state, iJoyStick), axis);
+      activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickAxisMoved(iJoyStick, axis + 8, arg.state.mAxes[axis].abs);
 
     return true;
@@ -630,4 +659,5 @@
   bool InputManager::sliderMoved(const OIS::JoyStickEvent &arg, int id)
   {
+    //CCOUT(3) << arg.state.mSliders[id].abX << "\t |" << arg.state.mSliders[id].abY << std::endl;
     // use the device to identify which one called the method
     OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device;
@@ -636,6 +666,18 @@
       iJoyStick++;
 
-    for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
-      activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickSliderMoved(JoyStickState(arg.state, iJoyStick), id);
+    if (sliderStates_[iJoyStick].sliderStates[id].x != arg.state.mSliders[id].abX)
+    {
+      // slider X axis changed
+      sliderStates_[iJoyStick].sliderStates[id].x = arg.state.mSliders[id].abX;
+      for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
+        activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickAxisMoved(iJoyStick, id * 2, arg.state.mSliders[id].abX);
+    }
+    else if (sliderStates_[iJoyStick].sliderStates[id].y != arg.state.mSliders[id].abY)
+    {
+      // slider Y axis changed
+      sliderStates_[iJoyStick].sliderStates[id].y = arg.state.mSliders[id].abY;
+      for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
+        activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickAxisMoved(iJoyStick, id * 2 + 1, arg.state.mSliders[id].abY);
+    }
 
     return true;
@@ -650,11 +692,30 @@
       iJoyStick++;
 
-    for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
-      activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickPovMoved(JoyStickState(arg.state, iJoyStick), id);
-
-    return true;
-  }
-
-  bool InputManager::vector3Moved(const OIS::JoyStickEvent &arg, int id)
+    // translate the POV into 8 simple buttons
+    int lastState = povStates_[iJoyStick][id];
+    if (lastState & OIS::Pov::North)
+      buttonReleased(arg, 32 + id * 4 + 0);
+    if (lastState & OIS::Pov::South)
+      buttonReleased(arg, 32 + id * 4 + 1);
+    if (lastState & OIS::Pov::East)
+      buttonReleased(arg, 32 + id * 4 + 2);
+    if (lastState & OIS::Pov::West)
+      buttonReleased(arg, 32 + id * 4 + 3);
+    
+    povStates_[iJoyStick].povStates[id] = arg.state.mPOV[id].direction;
+    int currentState = povStates_[iJoyStick][id];
+    if (currentState & OIS::Pov::North)
+      buttonPressed(arg, 32 + id * 4 + 0);
+    if (currentState & OIS::Pov::South)
+      buttonPressed(arg, 32 + id * 4 + 1);
+    if (currentState & OIS::Pov::East)
+      buttonPressed(arg, 32 + id * 4 + 2);
+    if (currentState & OIS::Pov::West)
+      buttonPressed(arg, 32 + id * 4 + 3);
+
+    return true;
+  }
+
+  /*bool InputManager::vector3Moved(const OIS::JoyStickEvent &arg, int id)
   {
     // use the device to identify which one called the method
@@ -668,5 +729,5 @@
 
     return true;
-  }
+  }*/
 
 
@@ -735,5 +796,5 @@
   }
 
-  const MouseState InputManager::getMouseState()
+  /*const MouseState InputManager::getMouseState()
   {
     if (_getSingleton().mouse_)
@@ -741,7 +802,7 @@
     else
       return MouseState();
-  }
-
-  const JoyStickState InputManager::getJoyStickState(unsigned int ID)
+  }*/
+
+  /*const JoyStickState InputManager::getJoyStickState(unsigned int ID)
   {
     if (ID < _getSingleton().joySticksSize_)
@@ -749,5 +810,5 @@
     else
       return JoyStickState();
-  }
+  }*/
 
 
@@ -882,5 +943,4 @@
       if ((*it) == (*mapIt).second)
       {
-        _getSingleton().stateRequest_ = IS_CUSTOM;
         return true;
       }
@@ -888,4 +948,5 @@
     _getSingleton().activeKeyHandlers_.push_back((*mapIt).second);
     _getSingleton().stateRequest_ = IS_CUSTOM;
+    _getSingleton()._updateTickables();
     return true;
   }
@@ -910,8 +971,8 @@
         _getSingleton().activeKeyHandlers_.erase(it);
         _getSingleton().stateRequest_ = IS_CUSTOM;
+        _getSingleton()._updateTickables();
         return true;
       }
     }
-    _getSingleton().stateRequest_ = IS_CUSTOM;
     return true;
   }
@@ -1010,5 +1071,4 @@
       if ((*it) == (*mapIt).second)
       {
-        _getSingleton().stateRequest_ = IS_CUSTOM;
         return true;
       }
@@ -1016,4 +1076,5 @@
     _getSingleton().activeMouseHandlers_.push_back((*mapIt).second);
     _getSingleton().stateRequest_ = IS_CUSTOM;
+    _getSingleton()._updateTickables();
     return true;
   }
@@ -1038,8 +1099,8 @@
         _getSingleton().activeMouseHandlers_.erase(it);
         _getSingleton().stateRequest_ = IS_CUSTOM;
+        _getSingleton()._updateTickables();
         return true;
       }
     }
-    _getSingleton().stateRequest_ = IS_CUSTOM;
     return true;
   }
@@ -1147,5 +1208,4 @@
       if ((*it) == (*handlerIt).second)
       {
-        _getSingleton().stateRequest_ = IS_CUSTOM;
         return true;
       }
@@ -1153,4 +1213,5 @@
     _getSingleton().activeJoyStickHandlers_[ID].push_back((*handlerIt).second);
     _getSingleton().stateRequest_ = IS_CUSTOM;
+    _getSingleton()._updateTickables();
     return true;
   }
@@ -1180,4 +1241,5 @@
         _getSingleton().activeJoyStickHandlers_[ID].erase(it);
         _getSingleton().stateRequest_ = IS_CUSTOM;
+        _getSingleton()._updateTickables();
         return true;
       }
Index: code/trunk/src/core/InputManager.h
===================================================================
--- code/trunk/src/core/InputManager.h	(revision 1293)
+++ code/trunk/src/core/InputManager.h	(revision 1349)
@@ -42,4 +42,5 @@
 
 #include "ois/OIS.h"
+#include "util/Math.h"
 #include "Tickable.h"
 #include "InputInterfaces.h"
@@ -47,4 +48,23 @@
 namespace orxonox
 {
+  /**
+  * Helper class to realise a vector<int[4]>
+  */
+  class POVStates
+  {
+  public:
+    int operator[](unsigned int index) { return povStates[index]; }
+    int povStates[4];
+  };
+
+  /**
+  * Helper class to realise a vector< {int[4], int[4]} >
+  */
+  class SliderStates
+  {
+  public:
+    IntVector2 sliderStates[4];
+  };
+
   /**
     @brief Captures and distributes mouse and keyboard input.
@@ -85,6 +105,6 @@
     static bool isModifierDown(KeyboardModifier::Enum modifier);
     static bool isKeyDown(KeyCode::Enum key);
-    static const MouseState getMouseState();
-    static const JoyStickState getJoyStickState(unsigned int ID);
+    //static const MouseState getMouseState();
+    //static const JoyStickState getJoyStickState(unsigned int ID);
 
     static void setWindowExtents(const int width, const int height);
@@ -130,4 +150,6 @@
     void _destroyMouse();
     void _destroyJoySticks();
+
+    void _updateTickables();
 
     void tick(float dt);
@@ -144,5 +166,5 @@
     bool sliderMoved   (const OIS::JoyStickEvent &arg, int id);
     bool povMoved      (const OIS::JoyStickEvent &arg, int id);
-    bool vector3Moved  (const OIS::JoyStickEvent &arg, int id);
+    //bool vector3Moved  (const OIS::JoyStickEvent &arg, int id);
 
     static InputManager& _getSingleton();
@@ -160,4 +182,9 @@
     unsigned int keyboardModifiers_;
 
+    //! Keeps track of the joy stick POV states
+    std::vector<POVStates>                      povStates_;
+    //! Keeps track of the possibly two slider axes
+    std::vector<SliderStates>                   sliderStates_;
+
     std::map<std::string, KeyHandler*>          keyHandlers_;
     std::map<std::string, MouseHandler*>        mouseHandlers_;
@@ -167,4 +194,5 @@
     std::vector<MouseHandler*>                  activeMouseHandlers_;
     std::vector<std::vector<JoyStickHandler*> > activeJoyStickHandlers_;
+    std::vector<InputTickable*>                 activeHandlers_;
 
     std::vector<Key>                            keysDown_;
Index: code/trunk/src/core/SignalHandler.cc
===================================================================
--- code/trunk/src/core/SignalHandler.cc	(revision 1293)
+++ code/trunk/src/core/SignalHandler.cc	(revision 1349)
@@ -150,9 +150,9 @@
   {
     std::cout << "Trying to restore XAutoKeyRepeat" << std::endl;
-	Display* display;
-	  if ((display = XOpenDisplay(0)))
-    {
-			XAutoRepeatOn(display);
-		  XCloseDisplay(display);
+    Display* display;
+    if ((display = XOpenDisplay(0)))
+    {
+      XAutoRepeatOn(display);
+      XCloseDisplay(display);
     }
   }
@@ -320,7 +320,7 @@
 
   std::string timeString = "\n\n\n\n"
-	                   "=======================================================\n"
-	                   "= time: " + std::string(ctime(&now)) +
-			   "=======================================================\n";
+                     "=======================================================\n"
+                     "= time: " + std::string(ctime(&now)) +
+         "=======================================================\n";
   bt.insert(0, timeString);
 
