Index: code/branches/gamestate/src/libraries/core/ConfigFileManager.cc
===================================================================
--- code/branches/gamestate/src/libraries/core/ConfigFileManager.cc	(revision 6436)
+++ code/branches/gamestate/src/libraries/core/ConfigFileManager.cc	(revision 6437)
@@ -33,5 +33,4 @@
 #include "util/Convert.h"
 #include "util/Math.h"
-#include "util/StringUtils.h"
 #include "ConsoleCommand.h"
 #include "ConfigValueContainer.h"
@@ -116,12 +115,22 @@
     }
 
-    std::list<ConfigFileEntry*>::const_iterator ConfigFileSection::getEntryIterator(const std::string& name) const
+    ConfigFileEntry* ConfigFileSection::getEntry(const std::string& name) const
     {
         for (std::list<ConfigFileEntry*>::const_iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)
         {
             if ((*it)->getName() == name)
-                return it;
-        }
-        return this->entries_.end();
+                return *it;
+        }
+        return NULL;
+    }
+
+    ConfigFileEntry* ConfigFileSection::getEntry(const std::string& name, unsigned int index) const
+    {
+        for (std::list<ConfigFileEntry*>::const_iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)
+        {
+            if (((*it)->getName() == name) && ((*it)->getIndex() == index))
+                return *it;
+        }
+        return NULL;
     }
 
@@ -140,14 +149,4 @@
 
         return this->entries_.insert(this->entries_.end(), new ConfigFileEntryValue(name, fallback, bString));
-    }
-
-    std::list<ConfigFileEntry*>::const_iterator ConfigFileSection::getEntryIterator(const std::string& name, unsigned int index) const
-    {
-        for (std::list<ConfigFileEntry*>::const_iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)
-        {
-            if (((*it)->getName() == name) && ((*it)->getIndex() == index))
-                return it;
-        }
-        return this->entries_.end();
     }
 
@@ -175,6 +174,10 @@
     // ConfigFile //
     ////////////////
-    ConfigFile::ConfigFile(const std::string& filename)
+
+    const char* ConfigFile::DEFAULT_CONFIG_FOLDER = "defaultConfig";
+
+    ConfigFile::ConfigFile(const std::string& filename, bool bCopyFallbackFile)
         : filename_(filename)
+        , bCopyFallbackFile_(bCopyFallbackFile)
         , bUpdated_(false)
     {
@@ -191,14 +194,26 @@
         this->clear();
 
-        // Get default file if necessary and available
-        boost::filesystem::path filepath(PathConfig::getConfigPath() / this->filename_);
-        if (!boost::filesystem::exists(filepath))
-        {
-            // Try to get default one from the data folder
-            boost::filesystem::path defaultFilepath(PathConfig::getDataPath() / "defaultConfig" / this->filename_);
-            if (boost::filesystem::exists(defaultFilepath))
-            {
-                COUT(3) << "Copied " << this->filename_ << " from the defaultConfig folder." << std::endl;
-                boost::filesystem::copy_file(defaultFilepath, filepath);
+        boost::filesystem::path filepath(this->filename_);
+        if (!filepath.is_complete())
+        {
+            filepath = PathConfig::getConfigPath() / filepath;
+            if (this->bCopyFallbackFile_)
+            {
+                // Look for default file in the data folder
+                if (!boost::filesystem::exists(filepath))
+                {
+                    boost::filesystem::path defaultFilepath(PathConfig::getDataPath() / DEFAULT_CONFIG_FOLDER / this->filename_);
+                    if (boost::filesystem::exists(defaultFilepath))
+                    {
+                        // Try to copy default file from the data folder
+                        try
+                        {
+                            boost::filesystem::copy_file(defaultFilepath, filepath);
+                            COUT(3) << "Copied " << this->filename_ << " from the default config folder." << std::endl;
+                        }
+                        catch (const boost::filesystem::filesystem_error& ex)
+                        { COUT(1) << "Error in ConfigFile: " << ex.what() << std::endl; }
+                    }
+                }
             }
         }
@@ -295,6 +310,5 @@
             COUT(3) << "Loaded config file \"" << this->filename_ << "\"." << std::endl;
 
-            // Save the file in case something changed (like stripped white space)
-            this->save();
+            // DO NOT save the file --> we can open supposedly read only config files
         } // end file.is_open()
     }
@@ -307,6 +321,9 @@
     void ConfigFile::saveAs(const std::string& filename) const
     {
+        boost::filesystem::path filepath(filename);
+        if (!filepath.is_complete())
+            filepath = PathConfig::getConfigPath() / filename;
         std::ofstream file;
-        file.open((PathConfig::getConfigPathString() + filename).c_str(), std::fstream::out);
+        file.open(filepath.string().c_str(), std::fstream::out);
         file.setf(std::ios::fixed, std::ios::floatfield);
         file.precision(6);
Index: code/branches/gamestate/src/libraries/core/ConfigFileManager.h
===================================================================
--- code/branches/gamestate/src/libraries/core/ConfigFileManager.h	(revision 6436)
+++ code/branches/gamestate/src/libraries/core/ConfigFileManager.h	(revision 6437)
@@ -39,4 +39,5 @@
 
 #include "util/Singleton.h"
+#include "util/StringUtils.h"
 
 namespace orxonox // tolua_export
@@ -191,8 +192,13 @@
             inline void setValue(const std::string& name, const std::string& value, bool bString)
                 { this->getOrCreateEntry(name, value, bString)->setValue(value); }
-            inline const std::string& getValue(const std::string& name, const std::string& fallback, bool bString) const
+            inline const std::string& getValue(const std::string& name, bool bString)
             {
                 ConfigFileEntry* entry = this->getEntry(name);
-                return (entry ? entry->getValue() : BLANKSTRING);
+                if (entry)
+                {
+                    entry->setString(bString);
+                    return entry->getValue();
+                }
+                return BLANKSTRING;
             }
             inline const std::string& getOrCreateValue(const std::string& name, const std::string& fallback, bool bString)
@@ -201,8 +207,13 @@
             inline void setValue(const std::string& name, unsigned int index, const std::string& value, bool bString)
                 { this->getOrCreateEntry(name, index, value, bString)->setValue(value); }
-            inline const std::string& getValue(const std::string& name, unsigned int index) const
+            inline const std::string& getValue(const std::string& name, unsigned int index, bool bString)
             {
                 ConfigFileEntry* entry = this->getEntry(name, index);
-                return (entry ? entry->getValue() : BLANKSTRING);
+                if (entry)
+                {
+                    entry->setString(bString);
+                    return entry->getValue();
+                }
+                return BLANKSTRING;
             }
             inline const std::string& getOrCreateValue(const std::string& name, unsigned int index, const std::string& fallback, bool bString)
@@ -222,15 +233,11 @@
                 { return this->entries_.end(); }
 
-            std::list<ConfigFileEntry*>::const_iterator getEntryIterator(const std::string& name) const;
-            std::list<ConfigFileEntry*>::iterator       getOrCreateEntryIterator(const std::string& name, const std::string& fallback, bool bString);
-            std::list<ConfigFileEntry*>::const_iterator getEntryIterator(const std::string& name, unsigned int index) const;
-            std::list<ConfigFileEntry*>::iterator       getOrCreateEntryIterator(const std::string& name, unsigned int index, const std::string& fallback, bool bString);
-
-            inline ConfigFileEntry* getEntry(const std::string& name) const
-                { return (*this->getEntryIterator(name)); }
+            std::list<ConfigFileEntry*>::iterator getOrCreateEntryIterator(const std::string& name, const std::string& fallback, bool bString);
+            std::list<ConfigFileEntry*>::iterator getOrCreateEntryIterator(const std::string& name, unsigned int index, const std::string& fallback, bool bString);
+
+            ConfigFileEntry* getEntry(const std::string& name) const;
             inline ConfigFileEntry* getOrCreateEntry(const std::string& name, const std::string& fallback, bool bString)
                 { return (*this->getOrCreateEntryIterator(name, fallback, bString)); }
-            inline ConfigFileEntry* getEntry(const std::string& name, unsigned int index) const
-                { return (*this->getEntryIterator(name, index)); }
+            ConfigFileEntry* getEntry(const std::string& name, unsigned int index) const;
             inline ConfigFileEntry* getOrCreateEntry(const std::string& name, unsigned int index, const std::string& fallback, bool bString)
                 { return (*this->getOrCreateEntryIterator(name, index, fallback, bString)); }
@@ -249,5 +256,5 @@
     {
         public:
-            ConfigFile(const std::string& filename);
+            ConfigFile(const std::string& filename, bool bCopyFallbackFile = true);
             virtual ~ConfigFile();
 
@@ -265,5 +272,5 @@
                 this->save();
             }
-            inline const std::string& getValue(const std::string& section, const std::string& name, bool bString) const
+            inline const std::string& getValue(const std::string& section, const std::string& name, bool bString)
             {
                 ConfigFileSection* sectionPtr = this->getSection(section);
@@ -274,11 +281,11 @@
             inline void setValue(const std::string& section, const std::string& name, unsigned int index, const std::string& value, bool bString)
             {
-                this->getSection(section)->setValue(name, index, value, bString);
+                this->getOrCreateSection(section)->setValue(name, index, value, bString);
                 this->save();
             }
-            inline const std::string& getValue(const std::string& section, const std::string& name, unsigned int index) const
+            inline const std::string& getValue(const std::string& section, const std::string& name, unsigned int index, bool bString)
             {
                 ConfigFileSection* sectionPtr = this->getSection(section);
-                return (sectionPtr ? sectionPtr->getValue(name, index) : BLANKSTRING);
+                return (sectionPtr ? sectionPtr->getValue(name, index, bString) : BLANKSTRING);
             }
             const std::string& getOrCreateValue(const std::string& section, const std::string& name, unsigned int index, const std::string& fallback, bool bString);
@@ -290,4 +297,6 @@
                 return (sectionPtr ? sectionPtr->getVectorSize(name) : 0);
             }
+
+            static const char* DEFAULT_CONFIG_FOLDER;
 
         protected:
@@ -300,4 +309,5 @@
             void saveIfUpdated();
             const std::string filename_;
+            const bool bCopyFallbackFile_;
             bool bUpdated_;
     };
Index: code/branches/gamestate/src/libraries/core/input/Button.cc
===================================================================
--- code/branches/gamestate/src/libraries/core/input/Button.cc	(revision 6436)
+++ code/branches/gamestate/src/libraries/core/input/Button.cc	(revision 6437)
@@ -82,11 +82,13 @@
     }
 
-    void Button::readBinding(ConfigFile* configFile)
-    {
-        const std::string& binding = configFile->getOrCreateValue(groupName_, name_, "", true);
+    void Button::readBinding(ConfigFile* configFile, ConfigFile* fallbackFile)
+    {
+        std::string binding = configFile->getOrCreateValue(groupName_, name_, "", true);
+        if (binding.empty() && fallbackFile)
+            binding = fallbackFile->getValue(groupName_, name_, true);
         this->parse(binding);
     }
 
-    void Button::setBinding(ConfigFile* configFile, const std::string& binding, bool bTemporary)
+    void Button::setBinding(ConfigFile* configFile, ConfigFile* fallbackFile, const std::string& binding, bool bTemporary)
     {
         if (!bTemporary)
@@ -104,5 +106,5 @@
         this->bindingString_ = binding;
 
-        if (isEmpty(bindingString_))
+        if (isEmpty(bindingString_) || removeTrailingWhitespaces(getLowercase(binding)) == "nobinding")
             return;
 
Index: code/branches/gamestate/src/libraries/core/input/Button.h
===================================================================
--- code/branches/gamestate/src/libraries/core/input/Button.h	(revision 6436)
+++ code/branches/gamestate/src/libraries/core/input/Button.h	(revision 6437)
@@ -52,6 +52,6 @@
         virtual bool addParamCommand(ParamCommand* command) { return false; }
         void parse(const std::string& binding);
-        void readBinding(ConfigFile* configFile);
-        void setBinding(ConfigFile* configFile, const std::string& binding, bool bTemporary);
+        void readBinding(ConfigFile* configFile, ConfigFile* fallbackFile);
+        void setBinding(ConfigFile* configFile, ConfigFile* fallbackFile, const std::string& binding, bool bTemporary);
         bool execute(KeybindMode::Value mode, float abs = 1.0f, float rel = 1.0f);
 
Index: code/branches/gamestate/src/libraries/core/input/KeyBinder.cc
===================================================================
--- code/branches/gamestate/src/libraries/core/input/KeyBinder.cc	(revision 6436)
+++ code/branches/gamestate/src/libraries/core/input/KeyBinder.cc	(revision 6437)
@@ -37,4 +37,5 @@
 #include "core/CoreIncludes.h"
 #include "core/ConfigFileManager.h"
+#include "core/PathConfig.h"
 #include "InputCommands.h"
 #include "JoyStick.h"
@@ -50,4 +51,5 @@
         , filename_(filename)
         , configFile_(NULL)
+        , fallbackConfigFile_(NULL)
     {
         mouseRelative_[0] = 0;
@@ -114,4 +116,8 @@
         // almost no destructors required because most of the arrays are static.
         clearBindings(); // does some destruction work
+        if (this->configFile_)
+            delete this->configFile_;
+        if (this->fallbackConfigFile_)
+            delete this->fallbackConfigFile_;
     }
 
@@ -166,7 +172,7 @@
             {
                 for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; ++i)
-                    (*joyStickButtons_[iDev])[i].readBinding(this->configFile_);
+                    (*joyStickButtons_[iDev])[i].readBinding(this->configFile_, this->fallbackConfigFile_);
                 for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; ++i)
-                    (*joyStickAxes_[iDev])[i].readBinding(this->configFile_);
+                    (*joyStickAxes_[iDev])[i].readBinding(this->configFile_, this->fallbackConfigFile_);
             }
         }
@@ -247,11 +253,25 @@
         COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
 
-        this->configFile_ = new ConfigFile(this->filename_);
+        this->configFile_ = new ConfigFile(this->filename_, !PathConfig::isDevelopmentRun());
         this->configFile_->load();
+
+        if (PathConfig::isDevelopmentRun())
+        {
+            // Dev users should have combined key bindings files
+            std::string defaultFilepath(PathConfig::getDataPathString() + ConfigFile::DEFAULT_CONFIG_FOLDER + '/' + this->filename_);
+            std::ifstream file(defaultFilepath.c_str());
+            if (file.is_open())
+            {
+                file.close();
+                // Open the default file for later use (use absolute path!)
+                this->fallbackConfigFile_ = new ConfigFile(defaultFilepath, false);
+                this->fallbackConfigFile_->load();
+            }
+        }
 
         // Parse bindings and create the ConfigValueContainers if necessary
         for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
         {
-            it->second->readBinding(this->configFile_);
+            it->second->readBinding(this->configFile_, this->fallbackConfigFile_);
             addButtonToCommand(it->second->bindingString_, it->second);
         }
@@ -266,5 +286,8 @@
         {
             addButtonToCommand(binding, it->second);
-            it->second->setBinding(this->configFile_, binding, bTemporary);
+            std::string str = binding;
+            if (PathConfig::isDevelopmentRun() && binding.empty())
+                str = "NoBinding";
+            it->second->setBinding(this->configFile_, this->fallbackConfigFile_, binding, bTemporary);
             return true;
         }
Index: code/branches/gamestate/src/libraries/core/input/KeyBinder.h
===================================================================
--- code/branches/gamestate/src/libraries/core/input/KeyBinder.h	(revision 6436)
+++ code/branches/gamestate/src/libraries/core/input/KeyBinder.h	(revision 6437)
@@ -158,4 +158,6 @@
         //! Config file used. NULL in case of KeyDetector. Also indicates whether we've already loaded.
         ConfigFile* configFile_;
+        //! Config file from the data directory that only serves as fallback
+        ConfigFile* fallbackConfigFile_;
 
     private:
